fix .desktop file
[gconf-editor] / src / gconf-search.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3  * Copyright (C) 2004 Fernando Herrera <fherrera@onirica.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include <gtk/gtk.h>
21
22 #include "gconf-search.h"
23 #include "gconf-search-dialog.h"
24 #include "gconf-editor-window.h"
25 #include "gconf-tree-model.h"
26 #include "gconf-list-model.h"
27
28 typedef struct _Node Node;
29
30 struct _Node {
31         gint ref_count;
32         gint offset;
33         gchar *path;
34
35         Node *parent;
36         Node *children;
37         Node *next;
38         Node *prev;
39 };      
40
41 static
42 gboolean
43 gconf_tree_model_search_iter_foreach (GtkTreeModel *model, GtkTreePath *path,
44                                       GtkTreeIter *iter, gpointer data)
45 {
46         Node    *node;
47         SearchIter *st;
48         gchar *found;
49         GSList *values, *list;
50
51         st = (SearchIter *) data;
52
53         if (st->searching == NULL) {
54                 return TRUE;
55         }
56
57         if (st->res >= 1) {
58                 gtk_widget_show (GTK_WIDGET (st->output_window));
59         }
60         while (gtk_events_pending ())
61                 gtk_main_iteration ();
62
63         node = iter->user_data;
64         found = g_strrstr ((char*) node->path, (char*) st->pattern);
65
66         if (found != NULL) {
67                 /* We found the pattern in the tree */
68                 gchar *key = gconf_tree_model_get_gconf_path (GCONF_TREE_MODEL (model), iter);
69                 gedit_output_window_append_line (st->output_window, key, FALSE);
70                 g_free (key);
71                 st->res++;
72                 return FALSE;
73         }
74
75         if (!st->search_keys && !st->search_values) {
76                 return FALSE;
77         }
78         values = gconf_client_all_entries (GCONF_TREE_MODEL (model)->client, (const char*) node->path , NULL);
79         for (list = values; list; list = list->next) {
80                 const gchar *key;
81                 GConfEntry *entry = list->data;
82                 key = gconf_entry_get_key (entry);
83                 /* Search in the key names */
84                 if (st->search_keys) {
85                         found = g_strrstr (key, (char*) st->pattern);
86                         if (found != NULL) {
87                                 /* We found the pattern in the final key name */
88                                 gedit_output_window_append_line (st->output_window, key, FALSE);
89                                 st->res++;
90                                 gconf_entry_free (entry);
91                                 /* After finding an entry continue the list to find other matches */
92                                 continue;
93                         }
94                 }
95
96                 /* Search in the values */
97                 if (st->search_values) {
98                         const char *gconf_string;
99                         GConfValue *gconf_value = gconf_entry_get_value (entry);
100
101                         /* FIXME: We are only looking into strings... should we do in
102                          * int's? */
103                         if (gconf_value != NULL && gconf_value->type == GCONF_VALUE_STRING)
104                                 gconf_string = gconf_value_get_string (gconf_value);
105                         else {
106                                 gconf_entry_free (entry);
107                                 continue;
108                         }
109
110                         found = g_strrstr (gconf_string, (char*) st->pattern);
111                         if (found != NULL) {
112                                 /* We found the pattern in the key value */
113                                 gedit_output_window_append_line (st->output_window, key, FALSE);
114                                 st->res++;
115                                 gconf_entry_free (entry);
116                                 continue;
117                         }
118                 }
119                 gconf_entry_free (entry);
120         }
121
122         return FALSE;
123 }
124
125 int
126 gconf_tree_model_build_match_list (GConfTreeModel *tree_model, GeditOutputWindow *output_window,
127                                    const char *pattern, gboolean search_keys, gboolean search_values,
128                                    GObject *dialog)
129 {
130         GtkTreeIter iter_root;
131         int res;
132         SearchIter *st;
133
134         st = g_new0 (SearchIter, 1);
135         st->pattern = pattern;
136         st->search_keys = search_keys;
137         st->search_values = search_values;
138         st->output_window = output_window; 
139         st->res = 0;
140         st->searching = dialog;
141
142         g_object_add_weak_pointer (st->searching, (gpointer)&st->searching);
143
144         if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree_model), &iter_root)) {
145
146                 /* Ugh, something is terribly wrong */
147                 return 0;
148         }
149
150         gtk_tree_model_foreach (GTK_TREE_MODEL (tree_model),
151                                 gconf_tree_model_search_iter_foreach, st);
152
153         res = st->res;
154 #if 0
155         g_free (st); /* This causes invalid memory access according to valgrind */
156 #endif               /* FIXME: This introduces a small leak (24 bytes) */
157         return res;
158
159 }
160