1/*
2 * Copyright (C) 2015 Red Hat, Inc
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: Matthias Clasen <mclasen@redhat.com>
18 */
19
20#include "config.h"
21
22#include <gio/gio.h>
23
24#include <gdk/gdk.h>
25
26#include "gtksearchenginemodelprivate.h"
27#include "gtkprivate.h"
28
29#include <string.h>
30
31struct _GtkSearchEngineModel
32{
33 GtkSearchEngine parent;
34
35 GtkFileSystemModel *model;
36 GtkQuery *query;
37
38 guint idle;
39};
40
41struct _GtkSearchEngineModelClass
42{
43 GtkSearchEngineClass parent_class;
44};
45
46G_DEFINE_TYPE (GtkSearchEngineModel, _gtk_search_engine_model, GTK_TYPE_SEARCH_ENGINE)
47
48static void
49gtk_search_engine_model_dispose (GObject *object)
50{
51 GtkSearchEngineModel *model = GTK_SEARCH_ENGINE_MODEL (object);
52
53 g_clear_object (&model->query);
54 g_clear_object (&model->model);
55
56 G_OBJECT_CLASS (_gtk_search_engine_model_parent_class)->dispose (object);
57}
58
59static gboolean
60info_matches_query (GtkQuery *query,
61 GFileInfo *info)
62{
63 const char *display_name;
64
65 display_name = g_file_info_get_display_name (info);
66 if (display_name == NULL)
67 return FALSE;
68
69 if (g_file_info_get_is_hidden (info))
70 return FALSE;
71
72 if (!gtk_query_matches_string (query, string: display_name))
73 return FALSE;
74
75 return TRUE;
76}
77
78static gboolean
79do_search (gpointer data)
80{
81 GtkSearchEngineModel *model = data;
82 GtkTreeIter iter;
83 GList *hits = NULL;
84 gboolean got_results = FALSE;
85
86 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model->model), iter: &iter))
87 {
88 do
89 {
90 GFileInfo *info;
91
92 info = _gtk_file_system_model_get_info (model: model->model, iter: &iter);
93 if (info_matches_query (query: model->query, info))
94 {
95 GFile *file;
96 GtkSearchHit *hit;
97
98 file = _gtk_file_system_model_get_file (model: model->model, iter: &iter);
99 hit = g_new (GtkSearchHit, 1);
100 hit->file = g_object_ref (file);
101 hit->info = g_object_ref (info);
102 hits = g_list_prepend (list: hits, data: hit);
103 }
104 }
105 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model->model), iter: &iter));
106
107 if (hits)
108 {
109 _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (model), hits);
110 g_list_free_full (list: hits, free_func: (GDestroyNotify)_gtk_search_hit_free);
111 got_results = TRUE;
112 }
113 }
114
115 model->idle = 0;
116
117 _gtk_search_engine_finished (GTK_SEARCH_ENGINE (model), got_results);
118
119 return G_SOURCE_REMOVE;
120}
121
122static void
123gtk_search_engine_model_start (GtkSearchEngine *engine)
124{
125 GtkSearchEngineModel *model;
126
127 model = GTK_SEARCH_ENGINE_MODEL (engine);
128
129 if (model->query == NULL)
130 return;
131
132 model->idle = g_idle_add (function: do_search, data: engine);
133 gdk_source_set_static_name_by_id (tag: model->idle, name: "[gtk] gtk_search_engine_model_start");
134}
135
136static void
137gtk_search_engine_model_stop (GtkSearchEngine *engine)
138{
139 GtkSearchEngineModel *model;
140
141 model = GTK_SEARCH_ENGINE_MODEL (engine);
142
143 if (model->idle != 0)
144 {
145 g_source_remove (tag: model->idle);
146 model->idle = 0;
147 }
148}
149
150static void
151gtk_search_engine_model_set_query (GtkSearchEngine *engine,
152 GtkQuery *query)
153{
154 GtkSearchEngineModel *model = GTK_SEARCH_ENGINE_MODEL (engine);
155
156 g_set_object (&model->query, query);
157}
158
159static void
160_gtk_search_engine_model_class_init (GtkSearchEngineModelClass *class)
161{
162 GObjectClass *gobject_class;
163 GtkSearchEngineClass *engine_class;
164
165 gobject_class = G_OBJECT_CLASS (class);
166 gobject_class->dispose = gtk_search_engine_model_dispose;
167
168 engine_class = GTK_SEARCH_ENGINE_CLASS (class);
169 engine_class->set_query = gtk_search_engine_model_set_query;
170 engine_class->start = gtk_search_engine_model_start;
171 engine_class->stop = gtk_search_engine_model_stop;
172}
173
174static void
175_gtk_search_engine_model_init (GtkSearchEngineModel *engine)
176{
177}
178
179GtkSearchEngine *
180_gtk_search_engine_model_new (GtkFileSystemModel *model)
181{
182 GtkSearchEngineModel *engine;
183
184 engine = GTK_SEARCH_ENGINE_MODEL (g_object_new (GTK_TYPE_SEARCH_ENGINE_MODEL, NULL));
185 engine->model = g_object_ref (model);
186
187 return GTK_SEARCH_ENGINE (engine);
188}
189

source code of gtk/gtk/gtksearchenginemodel.c