initial commit
[gconf-editor] / src / gconf-bookmarks.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3  * Copyright (C) 2001, 2002 Anders Carlsson <andersca@gnu.org>
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 "gconf-bookmarks.h"
21
22 #include "gconf-stock-icons.h"
23 #include "gconf-tree-model.h"
24 #include <gconf/gconf-client.h>
25 #include <gtk/gtk.h>
26 #include <string.h>
27
28
29 static void
30 gconf_bookmarks_bookmark_activated (GtkWidget *menuitem, GConfEditorWindow *window)
31 {
32         gconf_editor_window_go_to (window,
33                                    g_object_get_data (G_OBJECT (menuitem), "gconf-key"));
34 }
35
36 static void
37 gconf_bookmarks_set_item_has_icon (GtkWidget *item,
38                                    gboolean   have_icons)
39 {
40         GtkWidget *image;
41
42         image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (item));
43         if (image && !g_object_get_data (G_OBJECT (item), "gconf-editor-icon"))
44                 g_object_set_data_full (G_OBJECT (item), "gconf-editor-icon",
45                                         g_object_ref (image), g_object_unref);
46
47         if (!image)
48                 image = g_object_get_data (G_OBJECT (item), "gconf-editor-icon");
49
50         if (!image)
51                 return;
52
53         if (have_icons)
54                 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
55         else
56                 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), NULL);
57 }
58
59 static void
60 gconf_bookmarks_set_have_icons (GtkWidget *menu, gboolean have_icons)
61 {
62         GList *items, *n;
63
64         items = GTK_MENU_SHELL (menu)->children;
65
66         for (n = items; n != NULL; n = n->next) 
67                 if (GTK_IS_IMAGE_MENU_ITEM (n->data))
68                         gconf_bookmarks_set_item_has_icon (GTK_WIDGET (n->data), have_icons);
69 }
70
71 static void
72 gconf_bookmarks_have_icons_notify (GConfClient       *client,
73                                    guint              cnxn_id,
74                                    GConfEntry        *entry,
75                                    gpointer           data)
76 {
77         GtkWidget *menu;
78         gboolean have_icons;
79
80         menu = GTK_WIDGET (data);
81
82         if (entry->value->type != GCONF_VALUE_BOOL)
83                 return;
84
85         have_icons = gconf_value_get_bool (entry->value);
86
87         gconf_bookmarks_set_have_icons (menu, have_icons);
88 }
89
90 static void
91 gconf_bookmarks_update_menu (GtkWidget *menu)
92 {
93         GSList *list, *tmp;
94         GtkWidget *menuitem, *window;
95         GConfClient *client;
96
97         window = g_object_get_data (G_OBJECT (menu), "editor-window");
98         client = gconf_client_get_default ();
99         
100         /* Get the old list and then set it */
101         list = gconf_client_get_list (client,
102                                      "/apps/gconf-editor/bookmarks", GCONF_VALUE_STRING, NULL);
103
104         if (list != NULL) {
105                 menuitem = gtk_separator_menu_item_new ();
106                 gtk_widget_show (menuitem);
107                 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
108         }
109
110         for (tmp = list; tmp; tmp = tmp->next) {
111                 menuitem = gtk_image_menu_item_new_with_label (tmp->data);
112                 g_signal_connect (menuitem, "activate",
113                                   G_CALLBACK (gconf_bookmarks_bookmark_activated), window);
114                 g_object_set_data_full (G_OBJECT (menuitem), "gconf-key", g_strdup (tmp->data), g_free);
115                 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), gtk_image_new_from_stock (STOCK_BOOKMARK,
116                                                                                                          GTK_ICON_SIZE_MENU));
117                 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
118                 gtk_widget_show_all (menuitem);
119
120                 g_free (tmp->data);
121         }
122
123         g_object_unref (client);
124         g_slist_free (list);
125 }
126
127 static void
128 gconf_bookmarks_key_changed (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data)
129 {
130         GList *child_list, *tmp;
131         GtkWidget *menu_item;
132         
133         child_list = gtk_container_get_children (GTK_CONTAINER (user_data));
134
135         for (tmp = child_list; tmp; tmp = tmp->next) {
136                 menu_item = tmp->data;
137
138                 if (g_object_get_data (G_OBJECT (menu_item), "gconf-key") != NULL ||
139                         GTK_IS_SEPARATOR_MENU_ITEM (menu_item)) {
140                         gtk_widget_destroy (menu_item);
141                 }
142         }
143
144         gconf_bookmarks_update_menu (GTK_WIDGET (user_data));
145         
146         g_list_free (child_list);
147 }
148
149 void
150 gconf_bookmarks_add_bookmark (const char *path)
151 {
152         GSList *list, *tmp;
153         GConfClient *client;
154
155         client = gconf_client_get_default ();
156
157         /* Get the old list and then set it */
158         list = gconf_client_get_list (client,
159                                      "/apps/gconf-editor/bookmarks", GCONF_VALUE_STRING, NULL);
160
161         /* FIXME: We need error handling here, also this function leaks memory */
162
163         /* Check that the bookmark hasn't been added already */
164         for (tmp = list; tmp; tmp = tmp->next) {
165                 if (strcmp (tmp->data, path) == 0) {
166                         g_slist_free (list);
167                         return;
168                 }
169         }
170
171         /* Append the new bookmark */
172         list = g_slist_append (list, g_strdup (path));
173         
174         gconf_client_set_list (client,
175                                "/apps/gconf-editor/bookmarks", GCONF_VALUE_STRING, list, NULL);
176         g_slist_free (list);
177         g_object_unref (client);
178 }
179
180 static void
181 remove_notify_id (gpointer data)
182 {
183         GConfClient *client;
184
185         client = gconf_client_get_default ();
186         gconf_client_notify_remove (client, GPOINTER_TO_INT (data));
187
188         g_object_unref (client);
189 }
190
191 void
192 gconf_bookmarks_hook_up_menu (GConfEditorWindow *window,
193                               GtkWidget *menu,
194                               GtkWidget *add_bookmark,
195                               GtkWidget *edit_bookmarks)
196 {
197         GConfClient *client;
198         guint notify_id;
199
200         g_object_set_data (G_OBJECT (menu), "editor-window", window);
201
202         client = gconf_client_get_default ();
203         
204         /* Add a notify function */
205         gconf_client_add_dir (client, "/apps/gconf-editor/bookmarks",
206                               GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
207         notify_id = gconf_client_notify_add (client, "/apps/gconf-editor/bookmarks",
208                                              gconf_bookmarks_key_changed, menu, NULL, NULL);
209         g_object_set_data_full (G_OBJECT (menu), "notify-id", GINT_TO_POINTER (notify_id),
210                                 remove_notify_id);
211
212
213         notify_id = gconf_client_notify_add (client, "/desktop/gnome/interface/menus_have_icons",
214                                              gconf_bookmarks_have_icons_notify, menu, NULL, NULL); 
215         g_object_set_data_full (G_OBJECT (menu), "notify-id-x", GINT_TO_POINTER (notify_id),
216                                 remove_notify_id);
217
218         gconf_bookmarks_update_menu (menu);
219
220         {
221                 gboolean have_icons;
222                 GConfValue *value;
223                 GError *err;
224
225                 err = NULL;
226                 value = gconf_client_get (client, "/desktop/gnome/interface/menus_have_icons", &err);
227
228                 if (err != NULL || value == NULL || value->type != GCONF_VALUE_BOOL)
229                         return;
230
231                 have_icons = gconf_value_get_bool (value);
232                 gconf_bookmarks_set_have_icons (menu, have_icons);
233
234                 gconf_value_free (value);
235         }
236
237         if ( ! gconf_client_key_is_writable (client, "/apps/gconf-editor/bookmarks", NULL)) {
238                 gtk_widget_set_sensitive (add_bookmark, FALSE);
239                 gtk_widget_set_sensitive (edit_bookmarks, FALSE);
240         }
241
242         g_object_unref (client);
243 }