initial commit
[gconf-editor] / src / gconf-bookmarks-dialog.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 #include "gconf-bookmarks-dialog.h"
20 #include <gconf/gconf-client.h>
21 #include <glib/gi18n.h>
22 #include <gtk/gtk.h>
23
24 #include "gconf-stock-icons.h"
25
26 #define BOOKMARKS_KEY "/apps/gconf-editor/bookmarks"
27
28 G_DEFINE_TYPE(GConfBookmarksDialog, gconf_bookmarks_dialog, GTK_TYPE_DIALOG)
29
30 static void
31 gconf_bookmarks_dialog_response (GtkDialog *dialog, gint response_id)
32 {
33         gtk_widget_destroy (GTK_WIDGET (dialog));
34 }
35
36 static void
37 gconf_bookmarks_dialog_destroy (GtkObject *object)
38 {
39         GConfClient *client;
40         GConfBookmarksDialog *dialog;
41         
42         client = gconf_client_get_default ();
43         dialog = GCONF_BOOKMARKS_DIALOG (object);
44         
45         if (dialog->notify_id != 0) {
46                 gconf_client_notify_remove (client, dialog->notify_id);
47                 gconf_client_remove_dir (client, BOOKMARKS_KEY, NULL);
48                 dialog->notify_id = 0;
49         }
50
51         g_object_unref (client);
52         
53         if (GTK_OBJECT_CLASS (gconf_bookmarks_dialog_parent_class)->destroy) {
54                 (* GTK_OBJECT_CLASS (gconf_bookmarks_dialog_parent_class)->destroy) (object);
55         }
56 }
57
58 static void
59 gconf_bookmarks_dialog_class_init (GConfBookmarksDialogClass *klass)
60 {
61         GtkDialogClass *dialog_class;
62         GtkObjectClass *object_class;
63
64         object_class = (GtkObjectClass *)klass;
65         dialog_class = (GtkDialogClass *)klass;
66
67         object_class->destroy = gconf_bookmarks_dialog_destroy;
68         dialog_class->response = gconf_bookmarks_dialog_response;
69 }
70
71 static void
72 gconf_bookmarks_dialog_populate_model (GConfBookmarksDialog *dialog)
73 {
74         GConfClient *client;
75         GSList *value_list, *p;
76         GtkTreeIter iter;
77         
78         client = gconf_client_get_default ();
79         
80         /* First clear the list store */
81         dialog->changing_model = TRUE;
82         gtk_list_store_clear (dialog->list_store);
83
84         value_list = gconf_client_get_list (client, BOOKMARKS_KEY,
85                                             GCONF_VALUE_STRING, NULL);
86
87         for (p = value_list; p; p = p->next) {
88                 gtk_list_store_append (dialog->list_store, &iter);
89                 gtk_list_store_set (dialog->list_store, &iter,
90                                     0, p->data,
91                                     -1);
92                 g_free (p->data);
93         }
94
95         if (value_list)
96                 g_slist_free (value_list);
97
98         dialog->changing_model = FALSE;
99
100         g_object_unref (client);
101 }
102
103 static void
104 gconf_bookmarks_dialog_selection_changed (GtkTreeSelection *selection, GConfBookmarksDialog *dialog)
105 {
106         gtk_widget_set_sensitive (dialog->delete_button,
107                                   gtk_tree_selection_get_selected (selection, NULL, NULL));
108
109 }
110
111 static void
112 gconf_bookmarks_dialog_update_gconf_key (GConfBookmarksDialog *dialog)
113 {
114         GSList *list;
115         GtkTreeIter iter;
116         char *bookmark;
117         GConfClient *client;
118         
119         list = NULL;
120
121         if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->list_store), &iter)) {
122                 do {
123                         gtk_tree_model_get (GTK_TREE_MODEL (dialog->list_store), &iter,
124                                             0, &bookmark,
125                                             -1);
126                         list = g_slist_append (list, bookmark);
127                 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->list_store), &iter));
128         }
129
130         client = gconf_client_get_default ();
131
132         dialog->changing_key = TRUE;
133         gconf_client_set_list (client, BOOKMARKS_KEY,
134                                GCONF_VALUE_STRING, list, NULL);
135
136         g_object_unref (client);
137 }
138
139 static void
140 gconf_bookmarks_dialog_row_deleted (GtkTreeModel *tree_model, GtkTreePath *path,
141                                     GConfBookmarksDialog *dialog)
142 {
143         if (dialog->changing_model) {
144                 return;
145         }
146
147         gconf_bookmarks_dialog_update_gconf_key (dialog);
148
149 }
150
151 static void
152 gconf_bookmarks_dialog_delete_bookmark (GtkWidget *button, GConfBookmarksDialog *dialog)
153 {
154         GtkTreeIter iter;
155         
156         gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->tree_view)),
157                                          NULL, &iter);
158
159         dialog->changing_model = TRUE;
160         gtk_list_store_remove (dialog->list_store, &iter);
161         dialog->changing_model = FALSE;
162
163         gconf_bookmarks_dialog_update_gconf_key (dialog);
164 }
165
166 void
167 gconf_bookmarks_dialog_bookmarks_key_changed (GConfClient* client,
168                                               guint cnxn_id,
169                                               GConfEntry *entry,
170                                               gpointer user_data)
171 {
172         GConfBookmarksDialog *dialog;
173
174         dialog = user_data;
175
176         if (dialog->changing_key) {
177                 dialog->changing_key = FALSE;
178                 return;
179         }
180         
181         gconf_bookmarks_dialog_populate_model (dialog); 
182 }
183
184 static void
185 gconf_bookmarks_dialog_init (GConfBookmarksDialog *dialog)
186 {
187         GtkWidget *scrolled_window, *hbox, *vbox;
188         GtkCellRenderer *cell;
189         GtkTreeViewColumn *column;
190         GConfClient *client;
191        
192         hbox = gtk_hbox_new (FALSE, 6);
193         gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
194
195         gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
196         gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
197         gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
198         gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
199         gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 200);
200         
201         gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
202         gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Bookmarks"));
203
204         dialog->list_store = gtk_list_store_new (1, G_TYPE_STRING);
205         g_signal_connect (dialog->list_store, "row_deleted",
206                           G_CALLBACK (gconf_bookmarks_dialog_row_deleted), dialog);
207         scrolled_window = gtk_scrolled_window_new (NULL, NULL);
208         gtk_box_pack_start (GTK_BOX (hbox), scrolled_window, TRUE, TRUE, 0);
209         
210         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
211         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
212         dialog->tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (dialog->list_store));
213         gtk_tree_view_set_reorderable (GTK_TREE_VIEW (dialog->tree_view), TRUE);
214         
215         g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->tree_view)), "changed",
216                           G_CALLBACK (gconf_bookmarks_dialog_selection_changed), dialog);
217         gconf_bookmarks_dialog_populate_model (dialog);
218
219         column = gtk_tree_view_column_new ();
220
221         cell = gtk_cell_renderer_pixbuf_new ();
222         g_object_set (G_OBJECT (cell),
223                       "stock-id", STOCK_BOOKMARK,
224                       NULL);
225         gtk_tree_view_column_pack_start (column, cell, FALSE);
226         
227         cell = gtk_cell_renderer_text_new ();
228         gtk_tree_view_column_pack_start (column, cell, TRUE);
229         gtk_tree_view_column_set_attributes (column, cell,
230                                              "text", 0,
231                                              NULL);
232         gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->tree_view), column);
233
234         gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (dialog->tree_view), FALSE);
235         
236         g_object_unref (dialog->list_store);
237         gtk_container_add (GTK_CONTAINER (scrolled_window), dialog->tree_view);
238
239         vbox = gtk_vbox_new (FALSE, 0);
240         gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
241         dialog->delete_button = gtk_button_new_from_stock (GTK_STOCK_DELETE);
242         gtk_widget_set_sensitive (dialog->delete_button, FALSE);
243         g_signal_connect (dialog->delete_button, "clicked",
244                           G_CALLBACK (gconf_bookmarks_dialog_delete_bookmark), dialog);
245         
246         gtk_box_pack_start (GTK_BOX (vbox), dialog->delete_button, FALSE, FALSE, 0);
247
248         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0);
249         gtk_widget_show_all (hbox);
250
251         /* Listen for gconf changes */
252         client = gconf_client_get_default ();
253         gconf_client_add_dir (client, BOOKMARKS_KEY, GCONF_CLIENT_PRELOAD_NONE, NULL);
254
255         dialog->notify_id = gconf_client_notify_add (client, BOOKMARKS_KEY,
256                                                      gconf_bookmarks_dialog_bookmarks_key_changed,
257                                                      dialog,
258                                                      NULL,
259                                                      NULL);
260
261         g_object_unref (client);
262 }
263
264
265 GtkWidget *
266 gconf_bookmarks_dialog_new (GtkWindow *parent)
267 {
268         GtkWidget *dialog;
269
270         dialog = g_object_new (GCONF_TYPE_BOOKMARKS_DIALOG, NULL);
271         gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
272         gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
273
274         return dialog;
275 }