No issues found
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2008 Jonathan Matthew <jonathan@d14n.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * The Rhythmbox authors hereby grant permission for non-GPL compatible
11 * GStreamer plugins to be used and distributed together with GStreamer
12 * and Rhythmbox. This permission is above and beyond the permissions granted
13 * by the GPL license by which Rhythmbox is covered. If you modify this code
14 * you may extend this exception to your version of the code, but you are not
15 * obligated to do so. If you do not wish to do so, delete this exception
16 * statement from your version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 */
28
29 /**
30 * SECTION:rb-source-search
31 * @short_description: Base class for source search implementations
32 *
33 * These translate the text in the search entry box into a
34 * RhythmDBQuery. The basic implementation will return
35 * a query like RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_SEARCH_MATCH,
36 * text. Simple variants can restrict the search to single
37 * properties (artist, album, genre). More complicated searches
38 * could implement something like the Xesam User Query spec.
39 *
40 * The source header finds the search instance to use by looking
41 * for the 'rb-source-search' data item on the active search
42 * action.
43 */
44
45 #include "config.h"
46
47 #include "rb-source-search.h"
48
49 static void rb_source_search_class_init (RBSourceSearchClass *klass);
50 static void rb_source_search_init (RBSourceSearch *search);
51
52 G_DEFINE_TYPE (RBSourceSearch, rb_source_search, G_TYPE_OBJECT)
53
54 #define RB_SOURCE_SEARCH_DATA_ITEM "rb-source-search"
55
56 static gboolean
57 default_is_subset (RBSourceSearch *source, const char *current, const char *next)
58 {
59 /* the most common searches will return a strict subset if the
60 * next search is the current search with a suffix.
61 */
62 return (current != NULL && g_str_has_prefix (next, current));
63 }
64
65 static void
66 rb_source_search_class_init (RBSourceSearchClass *klass)
67 {
68 klass->is_subset = default_is_subset;
69 }
70
71 static void
72 rb_source_search_init (RBSourceSearch *search)
73 {
74 /* nothing */
75 }
76
77 /**
78 * rb_source_search_is_subset:
79 * @search: a #RBSourceSearch
80 * @current: the current search text (or NULL if the current search was done with a different
81 * search implementation and so cannot be considered)
82 * @next: the new search text
83 *
84 * Determines whether the new search text will result in a
85 * subset of entries matched by the previous search. This is
86 * used to optimise the search query.
87 *
88 * Return value: TRUE iff the new search text will match a subset of those matched by the current search.
89 */
90 gboolean
91 rb_source_search_is_subset (RBSourceSearch *search, const char *current, const char *next)
92 {
93 RBSourceSearchClass *klass = RB_SOURCE_SEARCH_GET_CLASS (search);
94 return klass->is_subset (search, current, next);
95 }
96
97 /**
98 * rb_source_search_create_query:
99 * @search: a #RBSourceSearch
100 * @db: the #RhythmDB
101 * @search_text: the search text
102 *
103 * Creates a #RhythmDBQuery from the user's search text.
104 *
105 * Return value: (transfer full): #RhythmDBQuery for the source to use
106 */
107 RhythmDBQuery *
108 rb_source_search_create_query (RBSourceSearch *search, RhythmDB *db, const char *search_text)
109 {
110 RBSourceSearchClass *klass = RB_SOURCE_SEARCH_GET_CLASS (search);
111 g_assert (klass->create_query);
112 return klass->create_query (search, db, search_text);
113 }
114
115 /**
116 * _rb_source_search_create_simple_query:
117 * @search: the #RBSourceSearch
118 * @db: the #RhythmDB
119 * @search_text: the search text such as RHYTHMDB_PROP_SEARCH_MATCH
120 * @search_prop: the search property
121 *
122 * Creates a basic search query.
123 *
124 * Return value: (transfer full): the #RhythmDBQuery for the search text and property, or NULL
125 * if no search text is specified.
126 */
127 RhythmDBQuery *
128 _rb_source_search_create_simple_query (RBSourceSearch *search, RhythmDB *db, const char *search_text, RhythmDBPropType search_prop)
129 {
130 if (search_text[0] == '\0')
131 return NULL;
132
133 return rhythmdb_query_parse (db,
134 RHYTHMDB_QUERY_PROP_LIKE,
135 search_prop,
136 search_text,
137 RHYTHMDB_QUERY_END);
138 }
139
140 /**
141 * rb_source_search_action_attach:
142 * @search: #RBSourceSearch to associate with the action
143 * @action: UI action to associate the search with
144 *
145 * Attaches a #RBSourceSearch to a UI action so that
146 * the search implementation will be used when the action is active.
147 */
148 void
149 rb_source_search_action_attach (RBSourceSearch *search, GObject *action)
150 {
151 g_object_set_data_full (action,
152 RB_SOURCE_SEARCH_DATA_ITEM,
153 g_object_ref (search),
154 (GDestroyNotify) g_object_unref);
155 }
156
157 /**
158 * rb_source_search_get_from_action:
159 * @action: the action to find the #RBSourceSearch for
160 *
161 * Returns the #RBSourceSearch associated with the
162 * specified UI action.
163 *
164 * Return value: (transfer none): associated #RBSourceSearch
165 */
166 RBSourceSearch *
167 rb_source_search_get_from_action (GObject *action)
168 {
169 gpointer data;
170 data = g_object_get_data (action, RB_SOURCE_SEARCH_DATA_ITEM);
171 return RB_SOURCE_SEARCH (data);
172 }