initial commit
[gconf-editor] / src / gconf-bookmarks.c
diff --git a/src/gconf-bookmarks.c b/src/gconf-bookmarks.c
new file mode 100644 (file)
index 0000000..ea7c71a
--- /dev/null
@@ -0,0 +1,243 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2001, 2002 Anders Carlsson <andersca@gnu.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gconf-bookmarks.h"
+
+#include "gconf-stock-icons.h"
+#include "gconf-tree-model.h"
+#include <gconf/gconf-client.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+
+static void
+gconf_bookmarks_bookmark_activated (GtkWidget *menuitem, GConfEditorWindow *window)
+{
+       gconf_editor_window_go_to (window,
+                                  g_object_get_data (G_OBJECT (menuitem), "gconf-key"));
+}
+
+static void
+gconf_bookmarks_set_item_has_icon (GtkWidget *item,
+                                  gboolean   have_icons)
+{
+       GtkWidget *image;
+
+       image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (item));
+       if (image && !g_object_get_data (G_OBJECT (item), "gconf-editor-icon"))
+               g_object_set_data_full (G_OBJECT (item), "gconf-editor-icon",
+                                       g_object_ref (image), g_object_unref);
+
+       if (!image)
+               image = g_object_get_data (G_OBJECT (item), "gconf-editor-icon");
+
+       if (!image)
+               return;
+
+       if (have_icons)
+               gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+       else
+               gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), NULL);
+}
+
+static void
+gconf_bookmarks_set_have_icons (GtkWidget *menu, gboolean have_icons)
+{
+        GList *items, *n;
+
+        items = GTK_MENU_SHELL (menu)->children;
+
+        for (n = items; n != NULL; n = n->next) 
+                if (GTK_IS_IMAGE_MENU_ITEM (n->data))
+                        gconf_bookmarks_set_item_has_icon (GTK_WIDGET (n->data), have_icons);
+}
+
+static void
+gconf_bookmarks_have_icons_notify (GConfClient       *client,
+                                  guint              cnxn_id,
+                                  GConfEntry        *entry,
+                                  gpointer           data)
+{
+        GtkWidget *menu;
+       gboolean have_icons;
+
+        menu = GTK_WIDGET (data);
+
+       if (entry->value->type != GCONF_VALUE_BOOL)
+               return;
+
+       have_icons = gconf_value_get_bool (entry->value);
+
+       gconf_bookmarks_set_have_icons (menu, have_icons);
+}
+
+static void
+gconf_bookmarks_update_menu (GtkWidget *menu)
+{
+       GSList *list, *tmp;
+       GtkWidget *menuitem, *window;
+       GConfClient *client;
+
+       window = g_object_get_data (G_OBJECT (menu), "editor-window");
+       client = gconf_client_get_default ();
+       
+       /* Get the old list and then set it */
+       list = gconf_client_get_list (client,
+                                    "/apps/gconf-editor/bookmarks", GCONF_VALUE_STRING, NULL);
+
+       if (list != NULL) {
+               menuitem = gtk_separator_menu_item_new ();
+               gtk_widget_show (menuitem);
+               gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+       }
+
+       for (tmp = list; tmp; tmp = tmp->next) {
+               menuitem = gtk_image_menu_item_new_with_label (tmp->data);
+               g_signal_connect (menuitem, "activate",
+                                 G_CALLBACK (gconf_bookmarks_bookmark_activated), window);
+               g_object_set_data_full (G_OBJECT (menuitem), "gconf-key", g_strdup (tmp->data), g_free);
+               gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), gtk_image_new_from_stock (STOCK_BOOKMARK,
+                                                                                                        GTK_ICON_SIZE_MENU));
+               gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+               gtk_widget_show_all (menuitem);
+
+               g_free (tmp->data);
+       }
+
+       g_object_unref (client);
+       g_slist_free (list);
+}
+
+static void
+gconf_bookmarks_key_changed (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data)
+{
+       GList *child_list, *tmp;
+       GtkWidget *menu_item;
+       
+       child_list = gtk_container_get_children (GTK_CONTAINER (user_data));
+
+       for (tmp = child_list; tmp; tmp = tmp->next) {
+               menu_item = tmp->data;
+
+               if (g_object_get_data (G_OBJECT (menu_item), "gconf-key") != NULL ||
+                       GTK_IS_SEPARATOR_MENU_ITEM (menu_item)) {
+                       gtk_widget_destroy (menu_item);
+               }
+       }
+
+       gconf_bookmarks_update_menu (GTK_WIDGET (user_data));
+       
+       g_list_free (child_list);
+}
+
+void
+gconf_bookmarks_add_bookmark (const char *path)
+{
+       GSList *list, *tmp;
+       GConfClient *client;
+
+       client = gconf_client_get_default ();
+
+       /* Get the old list and then set it */
+       list = gconf_client_get_list (client,
+                                    "/apps/gconf-editor/bookmarks", GCONF_VALUE_STRING, NULL);
+
+       /* FIXME: We need error handling here, also this function leaks memory */
+
+       /* Check that the bookmark hasn't been added already */
+       for (tmp = list; tmp; tmp = tmp->next) {
+               if (strcmp (tmp->data, path) == 0) {
+                       g_slist_free (list);
+                       return;
+               }
+       }
+
+       /* Append the new bookmark */
+       list = g_slist_append (list, g_strdup (path));
+       
+       gconf_client_set_list (client,
+                              "/apps/gconf-editor/bookmarks", GCONF_VALUE_STRING, list, NULL);
+       g_slist_free (list);
+       g_object_unref (client);
+}
+
+static void
+remove_notify_id (gpointer data)
+{
+       GConfClient *client;
+
+       client = gconf_client_get_default ();
+       gconf_client_notify_remove (client, GPOINTER_TO_INT (data));
+
+       g_object_unref (client);
+}
+
+void
+gconf_bookmarks_hook_up_menu (GConfEditorWindow *window,
+                             GtkWidget *menu,
+                             GtkWidget *add_bookmark,
+                             GtkWidget *edit_bookmarks)
+{
+       GConfClient *client;
+       guint notify_id;
+
+       g_object_set_data (G_OBJECT (menu), "editor-window", window);
+
+       client = gconf_client_get_default ();
+       
+       /* Add a notify function */
+       gconf_client_add_dir (client, "/apps/gconf-editor/bookmarks",
+                             GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+       notify_id = gconf_client_notify_add (client, "/apps/gconf-editor/bookmarks",
+                                            gconf_bookmarks_key_changed, menu, NULL, NULL);
+       g_object_set_data_full (G_OBJECT (menu), "notify-id", GINT_TO_POINTER (notify_id),
+                               remove_notify_id);
+
+
+       notify_id = gconf_client_notify_add (client, "/desktop/gnome/interface/menus_have_icons",
+                                            gconf_bookmarks_have_icons_notify, menu, NULL, NULL); 
+       g_object_set_data_full (G_OBJECT (menu), "notify-id-x", GINT_TO_POINTER (notify_id),
+                               remove_notify_id);
+
+       gconf_bookmarks_update_menu (menu);
+
+        {
+                gboolean have_icons;
+                GConfValue *value;
+                GError *err;
+
+                err = NULL;
+                value = gconf_client_get (client, "/desktop/gnome/interface/menus_have_icons", &err);
+
+                if (err != NULL || value == NULL || value->type != GCONF_VALUE_BOOL)
+                        return;
+
+                have_icons = gconf_value_get_bool (value);
+                gconf_bookmarks_set_have_icons (menu, have_icons);
+
+                gconf_value_free (value);
+        }
+
+       if ( ! gconf_client_key_is_writable (client, "/apps/gconf-editor/bookmarks", NULL)) {
+               gtk_widget_set_sensitive (add_bookmark, FALSE);
+               gtk_widget_set_sensitive (edit_bookmarks, FALSE);
+       }
+
+       g_object_unref (client);
+}