initial commit
[gconf-editor] / src / gconf-editor-window.c
1 /*
2  * Copyright (C) 2001, 2002 Anders Carlsson <andersca@gnu.org>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program 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  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <config.h>
20
21 #include "gconf-editor-window.h"
22
23 #include "gconf-bookmarks.h"
24 #include "gconf-bookmarks-dialog.h"
25 #include "gconf-list-model.h"
26 #include "gconf-tree-model.h"
27 #include "gconf-cell-renderer.h"
28 #include "gconf-editor-application.h"
29 #include "gconf-key-editor.h"
30 #include "gconf-policykit.h"
31 #include "gconf-stock-icons.h"
32 #include "gconf-util.h"
33 #include "gedit-output-window.h"
34 #include "gconf-search-dialog.h"
35
36 #include <gconf/gconf.h>
37 #include <glib/gi18n.h>
38 #include <gdk/gdkx.h>
39 #include <string.h>
40 #include <stdlib.h>
41
42 /* Property IDs */
43 enum
44 {
45   PROP_0,
46
47   PROP_TYPE
48 };
49
50 static void             gconf_editor_window_set_property        (GObject          *object,
51                                                                  guint             param_id,
52                                                                  const GValue     *value,
53                                                                  GParamSpec       *pspec);
54 static void             gconf_editor_window_get_property        (GObject          *object,
55                                                                  guint             param_id,
56                                                                  GValue           *value,
57                                                                  GParamSpec       *pspec);
58
59 static GConfClient*     gconf_editor_window_get_client          (int type);
60
61 G_DEFINE_TYPE(GConfEditorWindow, gconf_editor_window, GTK_TYPE_WINDOW)
62
63 void
64 gconf_editor_window_popup_error_dialog (GtkWindow   *parent,
65                                         const gchar *message,
66                                         GError      *error)
67 {
68         GtkWidget *dialog;
69
70         g_return_if_fail (error != NULL);
71
72         dialog = gtk_message_dialog_new (parent,
73                                          GTK_DIALOG_DESTROY_WITH_PARENT,
74                                          GTK_MESSAGE_ERROR,
75                                          GTK_BUTTONS_OK,
76                                          message,
77                                          error->message);
78         g_error_free (error);
79
80         gtk_dialog_run (GTK_DIALOG (dialog));
81         gtk_widget_destroy (dialog);
82 }
83
84 static void
85 gconf_editor_window_close_window (GtkAction *action G_GNUC_UNUSED,
86                                   GtkWidget *window)
87 {
88         gtk_object_destroy (GTK_OBJECT (window));
89 }
90
91 void
92 gconf_editor_window_go_to (GConfEditorWindow *window,
93                            const char        *location)
94 {
95         GtkTreePath *path, *child_path;
96         gint depth;
97         gint i, nchildren;
98         char *key;
99         
100         g_return_if_fail (location != NULL);
101         
102         child_path = gconf_tree_model_get_tree_path_from_gconf_path (
103                                 GCONF_TREE_MODEL (window->tree_model), location);
104         if (!child_path)
105                 return;
106
107         path = gtk_tree_model_sort_convert_child_path_to_path (
108                                 GTK_TREE_MODEL_SORT (window->sorted_tree_model),
109                                 child_path);
110
111         gtk_tree_path_free (child_path);
112         
113         /* kind of hackish, but it works! */
114         depth = gtk_tree_path_get_depth (path);
115         for (i = 0; i < depth; i++) {
116                 gint j;
117                 GtkTreePath *cpath = gtk_tree_path_copy (path);
118
119                 for (j = 0; j < (depth - i); j++)
120                         gtk_tree_path_up (cpath);
121
122                 gtk_tree_view_expand_row (GTK_TREE_VIEW (window->tree_view), cpath, FALSE);
123                 gtk_tree_path_free (cpath);
124         }
125
126         gtk_tree_view_expand_row (GTK_TREE_VIEW (window->tree_view), path, FALSE);
127
128         gtk_tree_selection_select_path (
129                         gtk_tree_view_get_selection (GTK_TREE_VIEW (window->tree_view)),
130                         path);
131         gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (window->tree_view),
132                                       path, NULL, TRUE, 0.5, 0.5);
133         gtk_tree_path_free (path);
134
135         /* check for key name in the list model */
136         key = strrchr (location, '/');
137         if (!key || strlen (key) < 2)
138                 return;
139         key++;
140         nchildren = gtk_tree_model_iter_n_children (window->list_model, NULL);
141         for (i = 0; i < nchildren; i++) {
142                 GtkTreeIter iter;
143                 char *name;
144                 gtk_tree_model_iter_nth_child (window->sorted_list_model,
145                                                 &iter, NULL, i);
146
147                 gtk_tree_model_get (window->sorted_list_model, &iter,
148                                     GCONF_LIST_MODEL_KEY_NAME_COLUMN, &name, -1);
149                 if (strcmp (key, name) == 0) {
150                         path = gtk_tree_model_get_path (window->sorted_list_model, &iter);
151                         gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->list_view)),
152                                                         path);
153                         gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (window->list_view),
154                                                       path, NULL, TRUE, 0.5, 0.5);
155                         gtk_tree_path_free (path);
156                         g_free (name);
157                         return;
158                 }
159                 g_free (name);
160         }
161 }
162
163 static void
164 gconf_editor_window_copy_key_name (GtkAction *action, GtkWidget *callback_data)
165 {
166         GConfEditorWindow *window = GCONF_EDITOR_WINDOW (callback_data);
167         char *path;
168         gchar *key;
169         GtkTreeIter iter;
170         GtkTreeIter child_iter;
171         
172         if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection
173                                              (GTK_TREE_VIEW (window->list_view)),
174                                              NULL, &iter) == TRUE) {
175                 gtk_tree_model_get (window->sorted_list_model, &iter,
176                                     GCONF_LIST_MODEL_KEY_PATH_COLUMN, &key,
177                                     -1);
178                 gtk_clipboard_set_text (gtk_clipboard_get
179                                         (GDK_SELECTION_CLIPBOARD), key, -1);
180                 g_free (key);
181                 return;
182         }
183                 
184         gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->tree_view)), NULL, &iter);
185
186         gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (window->sorted_tree_model), &child_iter, &iter);
187         path = gconf_tree_model_get_gconf_path (GCONF_TREE_MODEL (window->tree_model), &child_iter);
188
189         gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), path, -1);
190
191         g_free (path);
192 }
193
194 static void
195 gconf_editor_window_add_bookmark (GtkAction *action, GtkWidget *callback_data)
196 {
197         GConfEditorWindow *window = GCONF_EDITOR_WINDOW (callback_data);
198         GtkTreeIter iter;
199         char *path;
200         
201         if (!gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->tree_view)), NULL, &iter)) {
202                 return;
203         }
204         else {
205                 GtkTreeIter child_iter;
206
207                 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (window->sorted_tree_model), &child_iter, &iter);
208                 path = gconf_tree_model_get_gconf_path (GCONF_TREE_MODEL (window->tree_model), &child_iter);
209         }
210
211         gconf_bookmarks_add_bookmark (path);
212         
213         g_free (path);
214 }
215
216 static void
217 gconf_editor_window_recents_init (void)
218 {
219         GConfClient *client = gconf_client_get_default ();
220
221         gconf_client_add_dir (client, "/apps/gconf-editor/recents",
222                               GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
223
224         g_object_unref (client);
225 }
226
227 static void
228 gconf_add_recent_key (GConfEditorWindow *window, const char *key)
229 {
230         GSList *list, *tmp;
231         gboolean add = TRUE;
232
233         /* Get the old list and then set it */
234         list = gconf_client_get_list (window->client,
235                                       "/apps/gconf-editor/recents", GCONF_VALUE_STRING, NULL);
236
237         /* Check that the recent hasn't been added already */
238         for (tmp = list; tmp; tmp = tmp->next) {
239                 if (strcmp ((gchar*) tmp->data, key) == 0)
240                         add = FALSE;
241         }
242
243         /* Append the new key */
244         if (add == TRUE) {
245                 /* Keep list on a fixed size, remove the last */
246                 if (g_slist_length (list) > RECENT_LIST_MAX_SIZE - 1) {
247                         tmp = g_slist_last (list);
248                         g_free (tmp->data);
249                         list = g_slist_delete_link (list, tmp);
250                 }
251
252                 list = g_slist_prepend (list, g_strdup (key));
253
254                 gconf_client_set_list (window->client,
255                                        "/apps/gconf-editor/recents", GCONF_VALUE_STRING, list, NULL);
256
257                 if (GTK_WIDGET_VISIBLE (GTK_WIDGET (window->output_window)) &&
258                                         window->output_window_type == GCONF_EDITOR_WINDOW_OUTPUT_WINDOW_RECENTS) 
259                         gedit_output_window_prepend_line (GEDIT_OUTPUT_WINDOW (window->output_window),
260                                                           (gchar*) key, TRUE);
261         }
262
263
264         for (tmp = list; tmp; tmp = tmp->next) {
265                 g_free (tmp->data);
266         }
267
268         g_slist_free (list);
269 }
270
271
272 static void
273 gconf_editor_window_edit_bookmarks (GtkAction *action, GtkWidget *callback_data)
274 {
275         static GtkWidget *dialog = NULL;
276
277         if (dialog != NULL) {
278                 gtk_window_present (GTK_WINDOW (dialog));
279                 return;
280         }
281         
282         dialog = gconf_bookmarks_dialog_new (GTK_WINDOW (callback_data));
283         g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer)&dialog);
284         gtk_widget_show (dialog);
285 }
286
287
288 static void
289 gconf_editor_window_search (GtkAction *action, GtkWidget *callback_data)
290 {
291         static GtkWidget *dialog = NULL;
292
293         if (dialog != NULL) {
294                 gtk_window_present (GTK_WINDOW (dialog));
295                 return;
296         }
297
298         dialog = gconf_search_dialog_new (GTK_WINDOW (callback_data));
299         g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer)&dialog);
300         gtk_widget_show (dialog);
301 }
302
303 static void
304 gconf_editor_show_recent_keys (GtkAction *action, GtkWidget *window)
305 {
306         GSList *list, *tmp;
307         gedit_output_window_clear (GEDIT_OUTPUT_WINDOW (GCONF_EDITOR_WINDOW (window)->output_window));
308         list = gconf_client_get_list (GCONF_EDITOR_WINDOW (window)->client,
309                                      "/apps/gconf-editor/recents", GCONF_VALUE_STRING, NULL);
310         for (tmp = list; tmp; tmp = tmp->next) {
311                 gedit_output_window_append_line (GEDIT_OUTPUT_WINDOW (GCONF_EDITOR_WINDOW (window)->output_window),
312                                                  (gchar*) tmp->data, FALSE);
313                 g_free (tmp->data);
314         }
315
316         GCONF_EDITOR_WINDOW (window)->output_window_type = GCONF_EDITOR_WINDOW_OUTPUT_WINDOW_RECENTS;
317         gtk_widget_show (GTK_WIDGET (GCONF_EDITOR_WINDOW (window)->output_window));
318         
319         g_slist_free (list);
320 }
321
322 static void
323 gconf_editor_window_new_window (GtkAction *action, GtkWidget *callback_data)
324 {
325         GtkWidget *new_window;
326
327         new_window = gconf_editor_application_create_editor_window (GCONF_EDITOR_WINDOW_TYPE_NORMAL);
328         gtk_widget_show (new_window);
329 }
330
331 static void
332 gconf_editor_window_new_defaults_window (GtkAction *action, GtkWidget *callback_data)
333 {
334         GtkWidget *new_window;
335
336         new_window = gconf_editor_application_create_editor_window (GCONF_EDITOR_WINDOW_TYPE_DEFAULTS);
337         gtk_widget_show (new_window);
338 }
339
340 static void
341 gconf_editor_window_new_mandatory_window (GtkAction *action, GtkWidget *callback_data)
342 {
343         GtkWidget *new_window;
344
345         new_window = gconf_editor_application_create_editor_window (GCONF_EDITOR_WINDOW_TYPE_MANDATORY);
346         gtk_widget_show (new_window);
347 }
348
349 static void
350 help_cb (GtkAction *action, GtkWidget *callback_data)
351 {
352         GError *error = NULL;
353
354         gtk_show_uri (gtk_widget_get_screen (callback_data),
355                       "ghelp:gconf-editor", gtk_get_current_event_time (), &error);
356                                                                                 
357         if (error != NULL) {
358                 gconf_editor_window_popup_error_dialog (GTK_WINDOW (GCONF_EDITOR_WINDOW (callback_data)),
359                                                         _("Couldn't display help: %s"), error);
360         }
361 }
362
363 static void
364 gconf_editor_window_close_output_window (GtkWidget *widget, gpointer user_data)
365 {
366         gedit_output_window_clear (GEDIT_OUTPUT_WINDOW (widget));
367         gtk_widget_hide (widget);
368 }
369
370 static void
371 gconf_editor_window_output_window_changed (GtkWidget *widget, gchar *key, gpointer user_data)
372 {
373         GConfEditorWindow *window = (GConfEditorWindow*) user_data;
374         gconf_editor_window_go_to (window, key);
375 }
376
377 static void
378 gconf_editor_window_about_window (GtkAction *action, GtkWidget *callback_data)
379 {
380         const gchar *authors[] = {
381                 "Anders Carlsson <andersca@gnome.org>",
382                 "Fernando Herrera <fherrera@onirica.com>",
383                 NULL
384         };
385         const gchar *documenters[] = {
386                 "Sun Microsystems",
387                 "Shaun McCance <shaunm@gnome.org>",
388                 NULL
389         };
390
391         gtk_show_about_dialog (GTK_WINDOW (callback_data),
392 #if GTK_CHECK_VERSION (2, 11, 0)
393                               "program-name", _("Configuration Editor"),
394 #else
395                               "name", _("Configuration Editor"),
396 #endif
397                               "version", VERSION,
398                               "copyright", "Copyright \xc2\xa9 2001-2004 Anders Carlsson",
399                               "comments", _("An editor for the GConf configuration system."),
400                               "authors", authors,
401                               "documenters", documenters,
402                               "translator-credits", _("translator-credits"),
403                               "logo-icon-name", "gconf-editor",
404                               NULL);
405 }       
406
407 static void
408 gconf_editor_popup_window_unset_key (GtkAction *action, GtkWidget *callback_data)
409 {
410         GConfEditorWindow *window = GCONF_EDITOR_WINDOW (callback_data);
411         GtkTreeIter iter;
412         gchar *key;
413         GError *error = NULL;
414         
415         if (!gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->list_view)),
416                                          NULL, &iter)) {
417                 return;
418         }
419
420         gtk_tree_model_get (window->sorted_list_model, &iter,
421                             GCONF_LIST_MODEL_KEY_PATH_COLUMN, &key,
422                             -1);
423
424         gconf_client_unset (window->client, key, &error);
425         g_free (key);
426
427         if (error != NULL) {
428                 gconf_editor_window_popup_error_dialog (GTK_WINDOW (window),
429                                                         _("Couldn't unset key. Error was:\n%s"), error);
430         }
431 }
432
433 static void
434 gconf_editor_new_key_response (GtkDialog *editor,
435                                int        response,
436                                GConfEditorWindow *window)
437 {
438         if (response == GTK_RESPONSE_OK) {
439                 GConfValue *value;
440                 char       *full_path;
441                 char       *why_not_valid = NULL;
442                 
443                 full_path = gconf_key_editor_get_full_key_path (GCONF_KEY_EDITOR (editor));
444                 
445                 if (!gconf_valid_key (full_path, &why_not_valid)) {
446                         GtkWidget *message_dialog;
447
448                         g_assert (why_not_valid != NULL);
449
450                         message_dialog = gtk_message_dialog_new (GTK_WINDOW (editor),
451                                                                  GTK_DIALOG_MODAL,
452                                                                  GTK_MESSAGE_ERROR,
453                                                                  GTK_BUTTONS_OK,
454                                                                  _("Could not create key. The error is:\n%s"),
455                                                                  why_not_valid);
456                         gtk_dialog_set_default_response (GTK_DIALOG (message_dialog), GTK_RESPONSE_OK);
457                         gtk_dialog_run (GTK_DIALOG (message_dialog));
458                         gtk_widget_destroy (message_dialog);
459
460                         g_free (full_path);
461                         g_free (why_not_valid);
462
463                         /* leave the key editor in place */
464                         return;
465                 }
466                         
467                 /* Create the key */
468                 value = gconf_key_editor_get_value (GCONF_KEY_EDITOR (editor));
469
470                 gconf_client_set (window->client, full_path, value, NULL);
471                 gconf_add_recent_key (window, full_path);
472
473                 if(value)
474                   gconf_value_free (value);
475                 g_free (full_path);
476         }
477
478         gtk_widget_destroy (GTK_WIDGET (editor));
479 }
480
481 static void
482 gconf_editor_popup_window_new_key (GtkAction *action, GtkWidget *callback_data)
483 {
484         GConfEditorWindow *window = GCONF_EDITOR_WINDOW (callback_data);
485         GtkTreeIter iter;
486         GtkWidget *editor;
487         char *path;
488         
489         editor = gconf_key_editor_new (GCONF_KEY_EDITOR_NEW_KEY);
490
491         if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->tree_view)), NULL, &iter)) {
492                 GtkTreeIter child_iter;
493
494                 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (window->sorted_tree_model), &child_iter, &iter);
495                 path = gconf_tree_model_get_gconf_path (GCONF_TREE_MODEL (window->tree_model), &child_iter);
496         }
497         else {
498                 path = g_strdup ("/");
499         }
500         
501         gconf_key_editor_set_key_path (GCONF_KEY_EDITOR (editor), path);
502         gconf_key_editor_set_writable (GCONF_KEY_EDITOR (editor), TRUE);
503         g_free (path);
504
505         g_signal_connect (editor, "response",
506                           G_CALLBACK (gconf_editor_new_key_response), window);
507
508         gtk_widget_show (editor);
509 }
510
511 static void
512 gconf_editor_edit_key_response (GtkDialog *editor,
513                                 int        response,
514                                 GConfEditorWindow *window)
515 {
516         if (response == GTK_RESPONSE_OK) {
517                 GConfValue *value;
518                 GError     *error = NULL;
519                 const char *path;
520
521                 value = gconf_key_editor_get_value (GCONF_KEY_EDITOR (editor));
522
523                 path = gconf_key_editor_get_key_name (GCONF_KEY_EDITOR (editor));
524                 g_assert (gconf_valid_key (path, NULL));
525
526                 /* if not writable we weren't allowed to change things anyway */
527                 if (gconf_client_key_is_writable (window->client, path, &error)) {
528                         gconf_client_set (window->client, path, value, &error);
529                         gconf_add_recent_key (window, path);
530                 }
531
532                 gconf_value_free (value);
533
534                 if (error != NULL) {
535                         gconf_editor_window_popup_error_dialog (GTK_WINDOW (editor),
536                                                                 _("Could not change key value. Error message:\n%s"),
537                                                                 error);
538                         return;
539                 }
540         }
541
542         gtk_widget_destroy (GTK_WIDGET (editor));
543 }
544
545 static void
546 gconf_editor_popup_window_edit_key (GtkAction *action, GtkWidget *callback_data)
547 {
548         GConfEditorWindow *window = GCONF_EDITOR_WINDOW (callback_data);
549         GtkTreeIter iter;
550         GtkWidget *editor, *dialog;
551         GConfValue *value; 
552         char *path = NULL;
553         
554         if (!gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->list_view)),
555                                               NULL, &iter))
556                 return;
557         
558         gtk_tree_model_get (window->sorted_list_model, &iter,
559                             GCONF_LIST_MODEL_KEY_PATH_COLUMN, &path,
560                             GCONF_LIST_MODEL_VALUE_COLUMN, &value,
561                             -1);
562
563         if (value && (value->type == GCONF_VALUE_SCHEMA ||
564                       value->type == GCONF_VALUE_PAIR)) {
565                 dialog = gtk_message_dialog_new (GTK_WINDOW (window), 0,
566                                                  GTK_MESSAGE_INFO,
567                                                  GTK_BUTTONS_OK,
568                                                  _("Currently pairs and schemas can't "
569                                                    "be edited. This will be changed in a later "
570                                                    "version."));
571                 gtk_dialog_run (GTK_DIALOG (dialog));
572                 gtk_widget_destroy (dialog);
573                 gconf_value_free (value);
574                 g_free (path);
575                 return;
576         }
577         
578         editor = gconf_key_editor_new (GCONF_KEY_EDITOR_EDIT_KEY);
579
580         if(value) {
581           gconf_key_editor_set_value (GCONF_KEY_EDITOR (editor), value);
582           gconf_value_free (value);
583         }
584
585         gconf_key_editor_set_key_name (GCONF_KEY_EDITOR (editor), path);
586
587         gconf_key_editor_set_writable (GCONF_KEY_EDITOR (editor),
588                                        gconf_client_key_is_writable (window->client, path, NULL));
589
590         g_free (path);
591
592         g_signal_connect (editor, "response",
593                           G_CALLBACK (gconf_editor_edit_key_response), window);
594
595         gtk_widget_show (editor);
596 }
597
598 static void
599 gconf_editor_window_list_view_row_activated (GtkTreeView       *tree_view,
600                                              GtkTreePath       *path,
601                                              GtkTreeViewColumn *column,
602                                              GConfEditorWindow *window)
603 {
604         gconf_editor_popup_window_edit_key (NULL, GTK_WIDGET (window));
605 }
606
607 static gboolean
608 gconf_editor_window_test_expand_row (GtkTreeView       *tree_view,
609                                      GtkTreeIter       *iter,
610                                      GtkTreePath       *path,
611                                      gpointer           data)
612 {
613   GConfEditorWindow *gconfwindow = GCONF_EDITOR_WINDOW (data);
614   GdkCursor *cursor;
615
616   if (!GTK_WIDGET_REALIZED (gconfwindow))
617     return FALSE;
618
619   cursor = gdk_cursor_new (GDK_WATCH);
620   gdk_window_set_cursor (GTK_WIDGET (gconfwindow)->window, cursor);
621   gdk_cursor_unref (cursor);
622
623   gdk_display_flush (gtk_widget_get_display (GTK_WIDGET (gconfwindow)));
624
625   return FALSE;
626 }
627
628 static void
629 gconf_editor_window_row_expanded (GtkTreeView       *tree_view,
630                                   GtkTreeIter       *iter,
631                                   GtkTreePath       *path,
632                                   gpointer           data)
633 {
634   GConfEditorWindow *gconfwindow = GCONF_EDITOR_WINDOW (data);
635
636   if (!GTK_WIDGET_REALIZED (gconfwindow))
637     return;
638
639   gdk_window_set_cursor (GTK_WIDGET (gconfwindow)->window, NULL);
640   gdk_display_flush (gtk_widget_get_display (GTK_WIDGET (gconfwindow)));
641 }
642
643 static void
644 gconf_editor_popup_policykit_callback (GtkWindow *window, GError *error)
645 {
646   if (error)
647     gconf_editor_window_popup_error_dialog (window, _("Could not set value. Error was:\n%s"), error);
648 }
649
650 static void
651 gconf_editor_popup_window_set_as_default (GtkAction *action, GtkWidget *callback_data)
652 {
653   GConfEditorWindow *gconfwindow = GCONF_EDITOR_WINDOW (callback_data);
654
655   GtkTreeIter iter;
656   GConfValue *value;
657   char *path = NULL;
658   GtkWindow *window = GTK_WINDOW (callback_data);
659   gboolean can_use_pk;
660   
661   can_use_pk = (gconfwindow->type == GCONF_EDITOR_WINDOW_TYPE_NORMAL);
662   gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (gconfwindow->list_view)),
663                                    NULL, &iter);
664   gtk_tree_model_get (gconfwindow->sorted_list_model, &iter,
665                       GCONF_LIST_MODEL_KEY_PATH_COLUMN, &path,
666                       GCONF_LIST_MODEL_VALUE_COLUMN, &value,
667                       -1);
668
669   if (gconf_util_can_edit_defaults ()) {
670     GConfClient *client;
671
672     client = gconf_editor_window_get_client (GCONF_EDITOR_WINDOW_TYPE_DEFAULTS);
673     if (client != NULL) {
674       GError *error = NULL;
675
676       gconf_client_set (client, path, value, NULL);
677       gconf_client_suggest_sync (client, &error);
678       g_object_unref (client);
679
680       if (!error)
681         return;
682       if (!can_use_pk)
683         gconf_editor_window_popup_error_dialog (window, _("Could not sync value. Error was:\n%s"), error);
684     }
685   }
686   if (can_use_pk) {
687     gconf_client_suggest_sync (gconfwindow->client, NULL);
688     gconf_pk_set_default_async (path,
689                                 (GFunc) gconf_editor_popup_policykit_callback,
690                                 g_object_ref (window), g_object_unref);
691   }
692 }
693
694 static void
695 gconf_editor_popup_window_set_as_mandatory (GtkAction *action, GtkWidget *callback_data)
696 {
697   GConfEditorWindow *gconfwindow = GCONF_EDITOR_WINDOW (callback_data);
698
699   GtkTreeIter iter;
700   GConfValue *value;
701   char *path = NULL;
702   GtkWindow *window = GTK_WINDOW (callback_data);
703   gboolean can_use_pk;
704   
705   can_use_pk = (gconfwindow->type == GCONF_EDITOR_WINDOW_TYPE_NORMAL);
706   gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (gconfwindow->list_view)),
707                                    NULL, &iter);
708   gtk_tree_model_get (gconfwindow->sorted_list_model, &iter,
709                       GCONF_LIST_MODEL_KEY_PATH_COLUMN, &path,
710                       GCONF_LIST_MODEL_VALUE_COLUMN, &value,
711                       -1);
712
713   if (gconf_util_can_edit_mandatory ()) {
714     GConfClient *client;
715
716     client = gconf_editor_window_get_client (GCONF_EDITOR_WINDOW_TYPE_MANDATORY);
717     if (client != NULL) {
718       GError *error = NULL;
719
720       gconf_client_set (client, path, value, NULL);
721       gconf_client_suggest_sync (client, &error);
722       g_object_unref (client);
723
724       if (!error)
725         return;
726       if (!can_use_pk)
727         gconf_editor_window_popup_error_dialog (window, _("Could not sync value. Error was:\n%s"), error);
728     }
729   }
730   if (can_use_pk) {
731     gconf_client_suggest_sync (gconfwindow->client, NULL);
732     gconf_pk_set_mandatory_async (path,
733                                   (GFunc) gconf_editor_popup_policykit_callback,
734                                   g_object_ref (window), g_object_unref);
735   }
736 }
737
738 static GtkActionEntry entries[] = {
739         { "FileMenu", NULL, N_("_File"), NULL, NULL, NULL },
740         { "EditMenu", NULL, N_("_Edit"), NULL, NULL, NULL },
741         { "SearchMenu", NULL, N_("_Search"), NULL, NULL, NULL },
742         { "BookmarksMenu", NULL, N_("_Bookmarks"), NULL, NULL, NULL },
743         { "HelpMenu", NULL, N_("_Help"), NULL, NULL, NULL },
744
745         { "NewWindow", GTK_STOCK_NEW, N_("New _Settings Window"), "<control>S", 
746           N_("Open a new Configuration Editor window editing current settings"), 
747           G_CALLBACK (gconf_editor_window_new_window) },
748         { "NewDefaultsWindow", GTK_STOCK_NEW, N_("New _Defaults Window"), "<control>D", 
749           N_("Open a new Configuration Editor window editing system default settings"), 
750           G_CALLBACK (gconf_editor_window_new_defaults_window) },
751         { "NewMandatoryWindow", GTK_STOCK_NEW, N_("New _Mandatory Window"), "<control>M", 
752           N_("Open a new Configuration Editor window editing system mandatory settings"), 
753           G_CALLBACK (gconf_editor_window_new_mandatory_window) },
754         { "CloseWindow", GTK_STOCK_CLOSE, N_("_Close Window"), "<control>W", N_("Close this window"), 
755           G_CALLBACK (gconf_editor_window_close_window) },
756         { "QuitGConfEditor", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", N_("Quit the Configuration Editor"), 
757           G_CALLBACK (gtk_main_quit) },
758         
759         { "CopyKeyName", GTK_STOCK_COPY, N_("_Copy Key Name"), "<control>C", N_("Copy the name of the selected key"), 
760           G_CALLBACK (gconf_editor_window_copy_key_name) },
761         { "Find", GTK_STOCK_FIND, N_("_Find..."), "<control>F", N_("Find patterns in keys and values"), 
762           G_CALLBACK (gconf_editor_window_search) },
763         { "RecentKeys", NULL, N_("_List Recent Keys"), "<control>R", N_("Show recently modified keys"), 
764           G_CALLBACK (gconf_editor_show_recent_keys) },
765
766         { "AddBookmark", STOCK_ADD_BOOKMARK, N_("_Add Bookmark"), NULL, N_("Add a bookmark to the selected directory"), 
767           G_CALLBACK (gconf_editor_window_add_bookmark) },
768         { "EditBookmarks", STOCK_EDIT_BOOKMARK, N_("_Edit Bookmarks"), NULL, N_("Edit the bookmarks"), 
769         G_CALLBACK (gconf_editor_window_edit_bookmarks) },
770         
771         { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", N_("Open the help contents for the Configuration Editor"), 
772           G_CALLBACK (help_cb) },
773         { "AboutAction", GTK_STOCK_ABOUT, N_("_About"), NULL, N_("Show the about dialog for the Configuration Editor"), 
774           G_CALLBACK (gconf_editor_window_about_window) },
775
776         { "NewKey", GTK_STOCK_NEW, N_("_New Key..."), "<control>N", N_("Create a new key"),
777           G_CALLBACK (gconf_editor_popup_window_new_key) },
778         { "EditKey", NULL, N_("_Edit Key..."), NULL, N_("Edit the selected key"),
779           G_CALLBACK (gconf_editor_popup_window_edit_key) },
780         { "UnsetKey", GTK_STOCK_DELETE, N_("_Unset Key"), NULL, N_("Unset the selected key"),
781           G_CALLBACK (gconf_editor_popup_window_unset_key) },
782         { "DefaultKey", NULL, N_("Set as _Default"), NULL, N_("Set the selected key to be the default"),
783           G_CALLBACK (gconf_editor_popup_window_set_as_default) },
784         { "MandatoryKey", NULL, N_("Set as _Mandatory"), NULL, N_("Set the selected key to the mandatory"),
785           G_CALLBACK (gconf_editor_popup_window_set_as_mandatory) }     
786 };
787
788 static const char *ui_description = 
789         "<ui>"
790         "       <menubar name='GConfEditorMenu'>"
791         "               <menu action='FileMenu'>"
792         "                       <menuitem action='NewWindow'/>"
793         "                       <menuitem action='NewDefaultsWindow'/>"
794         "                       <menuitem action='NewMandatoryWindow'/>"
795         "                       <menuitem action='CloseWindow'/>"
796         "                       <separator/>"
797         "                       <menuitem action='QuitGConfEditor'/>"
798         "               </menu>"
799         "               <menu action='EditMenu'>"
800         "                       <menuitem action='CopyKeyName'/>"
801         "                       <separator/>"
802         "                       <menuitem action='RecentKeys'/>"
803         "                       <separator/>"
804         "                       <menuitem action='Find'/>"
805         "               </menu>"        
806         "               <menu action='BookmarksMenu'>"
807         "                       <menuitem action='AddBookmark'/>"
808         "                       <menuitem action='EditBookmarks'/>"
809         "               </menu>"
810         "               <menu action='HelpMenu'>"
811         "                       <menuitem action='HelpContents'/>"
812         "                       <menuitem action='AboutAction'/>"
813         "               </menu>"
814         "       </menubar>"
815         "       <popup name='GConfKeyPopupMenu'>"
816         "               <menuitem action='NewKey'/>"
817         "               <menuitem action='EditKey'/>"
818         "               <separator/>"
819         "               <menuitem action='UnsetKey'/>"
820         "               <separator/>"
821         "               <menuitem action='DefaultKey'/>"        
822         "               <separator/>"
823         "               <menuitem action='MandatoryKey'/>"      
824         "       </popup>"
825         "</ui>";
826
827 static gchar *image_menu_items_paths[] = {
828         "/GConfEditorMenu/FileMenu/NewWindow",
829         "/GConfEditorMenu/FileMenu/NewDefaultsWindow",
830         "/GConfEditorMenu/FileMenu/NewMandatoryWindow",
831         "/GConfEditorMenu/FileMenu/CloseWindow",
832         "/GConfEditorMenu/FileMenu/QuitGConfEditor",
833
834         "/GConfEditorMenu/EditMenu/CopyKeyName",
835         "/GConfEditorMenu/EditMenu/RecentKeys",
836         "/GConfEditorMenu/EditMenu/Find",
837
838         "/GConfEditorMenu/HelpMenu/HelpContents",
839         "/GConfEditorMenu/HelpMenu/AboutAction",
840
841         "/GConfKeyPopupMenu/NewKey",
842         "/GConfKeyPopupMenu/UnsetKey"
843 };
844
845 static void
846 gconf_editor_window_row_activated (GtkTreeView *treeview, 
847                                    GtkTreePath *path,
848                                    GtkTreeViewColumn *column,
849                                    GConfEditorWindow *window)
850 {
851         if (gtk_tree_view_row_expanded (treeview, path)) {
852                 gtk_tree_view_collapse_row (treeview, path);
853         } else {
854                 gtk_tree_view_expand_row (treeview, path, FALSE);
855         }
856 }
857
858 static void
859 gconf_editor_window_selection_changed (GtkTreeSelection *selection, GConfEditorWindow *window)
860 {
861         GtkTreeIter iter;
862         gchar *base_title;
863
864         switch (window->type) {
865         case GCONF_EDITOR_WINDOW_TYPE_DEFAULTS:
866                 base_title = _("Configuration Editor (Default settings)");
867                 break;
868         case GCONF_EDITOR_WINDOW_TYPE_MANDATORY:
869                 base_title = _("Configuration Editor (Mandatory settings)");
870                 break;
871         default:
872                 base_title = _("Configuration Editor");
873         }
874                 
875         if (selection == NULL)
876                 gtk_window_set_title (GTK_WINDOW (window), base_title);
877         else {
878                 gchar *name, *title, *path;
879                 GtkTreeIter child_iter;
880
881                 if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
882                         gtk_window_set_title (GTK_WINDOW (window), base_title);
883                         return;
884                 }
885
886                 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (window->sorted_tree_model), &child_iter, &iter);
887
888                 name = gconf_tree_model_get_gconf_name (GCONF_TREE_MODEL (window->tree_model), &child_iter);
889
890                 if (strlen (name) > 0) {
891                         title = g_strdup_printf ("%s - %s", base_title, name);
892                 }
893                 else {
894                         title = g_strdup (base_title);
895                 }
896                 
897                 gtk_window_set_title (GTK_WINDOW (window), title);
898                 g_free (title);
899                 g_free (name);
900
901                 path = gconf_tree_model_get_gconf_path (GCONF_TREE_MODEL (window->tree_model), &child_iter);
902                 gtk_statusbar_pop (GTK_STATUSBAR (window->statusbar), 0);
903                 gtk_statusbar_push (GTK_STATUSBAR (window->statusbar), 0, path);
904
905                 gconf_list_model_set_root_path (GCONF_LIST_MODEL (window->list_model), path);
906
907                 g_free (path);
908         }
909 }
910
911 static gboolean
912 list_view_button_press_event (GtkTreeView *tree_view, GdkEventButton *event, GConfEditorWindow *window)
913 {
914         GtkTreePath *path;
915
916         if (event->button == 3) {
917                 gtk_widget_grab_focus (GTK_WIDGET (tree_view));
918
919                 /* Select our row */
920                 if (gtk_tree_view_get_path_at_pos (tree_view, event->x, event->y, &path, NULL, NULL, NULL)) {
921                         gtk_tree_selection_select_path (gtk_tree_view_get_selection (tree_view), path);
922
923                         gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/EditKey"), 
924                                                   TRUE);
925                         gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/UnsetKey"), 
926                                                   window->type != GCONF_EDITOR_WINDOW_TYPE_DEFAULTS);
927                         gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/DefaultKey"), 
928                                                   (gconf_util_can_edit_defaults () && window->type != GCONF_EDITOR_WINDOW_TYPE_DEFAULTS) ||
929                                                   (gconf_pk_can_set_default ("/") && window->type == GCONF_EDITOR_WINDOW_TYPE_NORMAL));
930                         gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/MandatoryKey"), 
931                                                   (gconf_util_can_edit_mandatory () && window->type != GCONF_EDITOR_WINDOW_TYPE_MANDATORY) ||
932                                                   (gconf_pk_can_set_mandatory ("/") && window->type == GCONF_EDITOR_WINDOW_TYPE_NORMAL));
933                         
934                         gtk_tree_path_free (path);
935                 }
936                 else {
937                         gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/EditKey"), 
938                                                   FALSE);
939                         gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/UnsetKey"), 
940                                                   FALSE);
941                         gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/DefaultKey"), 
942                                                   FALSE);
943                         gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/MandatoryKey"), 
944                                                   FALSE);
945
946                 }
947                 
948                 gtk_menu_popup (GTK_MENU (window->popup_menu), NULL, NULL, NULL, NULL,
949                                 event->button, event->time);
950                 return TRUE;
951         }
952
953         return FALSE;
954 }
955
956 static void
957 gconf_editor_gconf_value_changed (GConfCellRenderer *cell, const gchar *path_str, GConfValue *new_value, GConfEditorWindow *window)
958 {
959         GtkTreeIter iter;
960         GtkTreePath *path;
961         gchar *key;
962         GConfValue *value;
963         
964         path = gtk_tree_path_new_from_string (path_str);
965
966         gtk_tree_model_get_iter (window->sorted_list_model, &iter, path);
967
968         gtk_tree_model_get (window->sorted_list_model, &iter,
969                             GCONF_LIST_MODEL_KEY_PATH_COLUMN, &key,
970                             GCONF_LIST_MODEL_VALUE_COLUMN, &value,
971                             -1);
972
973         /* We need to check this because the changed signal could come from an old
974          * cell in another list_model */ 
975         if (value->type == new_value->type) {
976                 gconf_client_set (window->client, key, new_value, NULL);
977                 gconf_add_recent_key (window, key);
978         }
979
980         gconf_value_free (value);
981         g_free (key);
982         gtk_tree_path_free (path);
983 }
984
985 static gboolean
986 gconf_editor_check_writable (GConfCellRenderer *cell, const gchar *path_str, GConfEditorWindow *window)
987 {
988         GtkTreeIter iter;
989         GtkTreePath *path;
990         gchar *key;
991         gboolean ret;
992         
993         path = gtk_tree_path_new_from_string (path_str);
994
995         gtk_tree_model_get_iter (window->sorted_list_model, &iter, path);
996
997         gtk_tree_model_get (window->sorted_list_model, &iter,
998                             GCONF_LIST_MODEL_KEY_PATH_COLUMN, &key,
999                             -1);
1000
1001         ret = gconf_client_key_is_writable (window->client, key, NULL);
1002
1003         g_free (key);
1004
1005         return ret;
1006 }
1007
1008 static void
1009 gconf_editor_window_list_view_popup_position (GtkMenu   *menu G_GNUC_UNUSED,
1010                                               gint      *x,
1011                                               gint      *y,
1012                                               gboolean  *push_in G_GNUC_UNUSED,
1013                                               GdkWindow *window)
1014 {
1015         gdk_window_get_origin (window, x, y);
1016 }
1017
1018 static void
1019 gconf_editor_window_list_view_popup_menu (GtkWidget *widget, GConfEditorWindow *window)
1020 {
1021         GtkTreeIter iter;
1022
1023         GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->list_view));
1024         /* Select our row */
1025         if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
1026                 gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/EditKey"), 
1027                                           TRUE);
1028                 gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/UnsetKey"), 
1029                                           window->type != GCONF_EDITOR_WINDOW_TYPE_DEFAULTS);
1030                 gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/DefaultKey"), 
1031                                           (gconf_util_can_edit_defaults () && window->type != GCONF_EDITOR_WINDOW_TYPE_DEFAULTS) ||
1032                                           (gconf_pk_can_set_default ("/") && window->type == GCONF_EDITOR_WINDOW_TYPE_NORMAL));
1033                 gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/MandatoryKey"), 
1034                                           (gconf_util_can_edit_mandatory () && window->type != GCONF_EDITOR_WINDOW_TYPE_MANDATORY) ||
1035                                           (gconf_pk_can_set_mandatory ("/") && window->type == GCONF_EDITOR_WINDOW_TYPE_NORMAL));
1036         }
1037         else {
1038                 gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/EditKey"), 
1039                                           FALSE);
1040                 gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/UnsetKey"), 
1041                                           FALSE);
1042                 gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/DefaultKey"), 
1043                                           FALSE);
1044                 gtk_widget_set_sensitive (gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu/MandatoryKey"), 
1045                                           FALSE);
1046
1047         }
1048         
1049         gtk_menu_popup (GTK_MENU (window->popup_menu), NULL, NULL,
1050                         (GtkMenuPositionFunc) gconf_editor_window_list_view_popup_position, 
1051                         widget->window,
1052                         0, gtk_get_current_event_time ());
1053 }
1054
1055 static char *
1056 strip_whitespace (const char *text)
1057 {
1058         const char *p;
1059         const char *end;
1060         GString *str;
1061
1062         p = text;
1063         end = text + strlen (text);
1064
1065         /* First skip the leading whitespace */
1066         while (p != end && g_unichar_isspace (g_utf8_get_char (p))) {
1067           p = g_utf8_next_char (p);
1068         }
1069           
1070         str = g_string_new (NULL);
1071         
1072         while (p != end) {
1073                 gunichar ch;
1074
1075                 ch = g_utf8_get_char (p);
1076
1077                 if (g_unichar_isspace (ch)) {
1078                         while (p != end && g_unichar_isspace (ch)) {
1079                                 p = g_utf8_next_char (p);
1080                                 ch = g_utf8_get_char (p);
1081                         }
1082
1083                         p = g_utf8_prev_char (p);
1084                         g_string_append_unichar (str, ' ');
1085                 }
1086                 else {
1087                         g_string_append_unichar (str, ch);
1088                 }
1089
1090                 p = g_utf8_next_char (p);
1091         }
1092
1093         return g_string_free (str, FALSE);
1094 }
1095
1096 static void
1097 set_label_and_strip_whitespace (GtkLabel *label, const char *text)
1098 {
1099         char *stripped_text;
1100
1101         stripped_text = strip_whitespace (text);
1102         gtk_label_set_text (GTK_LABEL (label), stripped_text);
1103         g_free (stripped_text);
1104 }
1105
1106 static void
1107 gconf_editor_window_update_list_selection (GtkTreeSelection *selection, GConfEditorWindow *window)
1108 {
1109         GtkTreeIter iter;
1110         GConfSchema *schema;
1111         char *path;
1112         
1113         if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
1114                 gtk_label_set_text (GTK_LABEL (window->key_name_label), _("(None)"));
1115                 gtk_label_set_text (GTK_LABEL (window->owner_label), _("(None)"));
1116                 gtk_label_set_text (GTK_LABEL (window->short_desc_label), _("(None)"));
1117                 gtk_text_buffer_set_text (window->long_desc_buffer, _("(None)"), -1);
1118                 gtk_widget_hide (window->non_writable_label);
1119                 gtk_widget_hide (window->no_schema_label);
1120                 
1121                 return;
1122         }
1123         
1124         gtk_tree_model_get (window->sorted_list_model, &iter,
1125                             GCONF_LIST_MODEL_KEY_PATH_COLUMN, &path,
1126                             -1);
1127         
1128         gtk_label_set_text (GTK_LABEL (window->key_name_label), path);
1129
1130         if (gconf_client_key_is_writable (window->client, path, NULL))
1131                 gtk_widget_hide (window->non_writable_label);
1132         else
1133                 gtk_widget_show (window->non_writable_label);
1134
1135         schema = gconf_client_get_schema_for_key (window->client, path);
1136
1137         if (schema != NULL && gconf_schema_get_long_desc (schema) != NULL) {
1138                 char *long_desc;
1139
1140                 long_desc = strip_whitespace (gconf_schema_get_long_desc (schema));
1141                 
1142                 gtk_text_buffer_set_text (window->long_desc_buffer, long_desc, -1);
1143                 g_free (long_desc);
1144         }
1145         else {
1146                 gtk_text_buffer_set_text (window->long_desc_buffer, _("(None)"), -1);
1147         }
1148
1149         if (schema != NULL && gconf_schema_get_short_desc (schema) != NULL) {
1150                 set_label_and_strip_whitespace (GTK_LABEL (window->short_desc_label),
1151                                                 gconf_schema_get_short_desc (schema));
1152         }
1153         else {
1154                 gtk_label_set_text (GTK_LABEL (window->short_desc_label), _("(None)"));
1155
1156         }
1157
1158         if (schema != NULL && gconf_schema_get_owner (schema) != NULL) {
1159                 set_label_and_strip_whitespace (GTK_LABEL (window->owner_label),
1160                                                 gconf_schema_get_owner (schema));
1161         }
1162         else {
1163                 gtk_label_set_text (GTK_LABEL (window->owner_label), _("(None)"));
1164
1165         }
1166
1167         if (schema == NULL) {
1168                 GConfValue *value = gconf_client_get (window->client, path, NULL);
1169                 if (value != NULL) {
1170                         if (value->type == GCONF_VALUE_SCHEMA) {
1171                                 gtk_widget_hide (window->no_schema_label);
1172                         }
1173                         else {
1174                                 gtk_widget_show (window->no_schema_label);
1175                         }
1176                         gconf_value_free (value);
1177                 }
1178         }
1179         else {
1180                 gtk_widget_hide (window->no_schema_label);
1181         }
1182
1183         if (schema != NULL)
1184                 gconf_schema_free (schema);
1185
1186         gtk_statusbar_pop (GTK_STATUSBAR (window->statusbar), 0);
1187         gtk_statusbar_push (GTK_STATUSBAR (window->statusbar), 0, path);
1188
1189         g_free (path);
1190 }
1191
1192 static void
1193 gconf_editor_window_have_tearoffs_notify (GConfClient       *client,
1194                                           guint              cnxn_id,
1195                                           GConfEntry        *entry,
1196                                           GConfEditorWindow *window)
1197 {
1198         gboolean have_tearoffs;
1199
1200         if (entry->value->type != GCONF_VALUE_BOOL)
1201                 return;
1202
1203         have_tearoffs = gconf_value_get_bool (entry->value);
1204
1205         gtk_ui_manager_set_add_tearoffs (window->ui_manager, have_tearoffs);
1206 }
1207
1208 static void
1209 gconf_editor_window_set_item_has_icon (GtkUIManager *ui_manager,
1210                                        const char     *path,
1211                                        gboolean        have_icons)
1212 {
1213         GtkWidget *item;
1214         GtkWidget *image;
1215
1216         item = gtk_ui_manager_get_widget (ui_manager, path);
1217
1218         image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (item));
1219         if (image && !g_object_get_data (G_OBJECT (item), "gconf-editor-icon"))
1220                 g_object_set_data_full (G_OBJECT (item), "gconf-editor-icon",
1221                                         g_object_ref (image), g_object_unref);
1222
1223         if (!image)
1224                 image = g_object_get_data (G_OBJECT (item), "gconf-editor-icon");
1225
1226         if (!image)
1227                 return;
1228
1229         if (have_icons)
1230                 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
1231         else
1232                 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), NULL);
1233 }
1234
1235 static void
1236 gconf_editor_window_set_have_icons (GConfEditorWindow *window,
1237                                     gboolean           have_icons)
1238 {
1239         int i;
1240
1241         for (i = 0; i < G_N_ELEMENTS (image_menu_items_paths); i++)
1242                 gconf_editor_window_set_item_has_icon (window->ui_manager, image_menu_items_paths [i], have_icons);
1243 }
1244
1245 static void
1246 gconf_editor_window_have_icons_notify (GConfClient       *client,
1247                                        guint              cnxn_id,
1248                                        GConfEntry        *entry,
1249                                        GConfEditorWindow *window)
1250 {
1251         gboolean have_icons;
1252
1253         if (entry->value->type != GCONF_VALUE_BOOL)
1254                 return;
1255
1256         have_icons = gconf_value_get_bool (entry->value);
1257
1258         gconf_editor_window_set_have_icons (window, have_icons);
1259 }
1260
1261 static void
1262 gconf_editor_window_setup_ui_prefs_handler (GConfEditorWindow *window)
1263 {
1264         GConfClient *client;
1265
1266         client = gconf_client_get_default ();
1267
1268         gtk_ui_manager_set_add_tearoffs (
1269                 window->ui_manager, gconf_client_get_bool (client, "/desktop/gnome/interface/menus_have_tearoff", 
1270                                                            NULL));
1271
1272         window->tearoffs_notify_id = gconf_client_notify_add (
1273                                                 client,
1274                                                 "/desktop/gnome/interface/menus_have_tearoff",
1275                                                 (GConfClientNotifyFunc) gconf_editor_window_have_tearoffs_notify,
1276                                                 window, NULL, NULL);
1277
1278         gconf_editor_window_set_have_icons (
1279                 window, gconf_client_get_bool (client, "/desktop/gnome/interface/menus_have_icons", NULL));
1280
1281         window->icons_notify_id = gconf_client_notify_add (
1282                                                 client,
1283                                                 "/desktop/gnome/interface/menus_have_icons",
1284                                                 (GConfClientNotifyFunc) gconf_editor_window_have_icons_notify,
1285                                                 window, NULL, NULL);
1286
1287         g_object_unref (client);
1288 }
1289
1290 static void
1291 gconf_editor_window_style_set (GtkWidget *widget, GtkStyle *prev_style, GtkWidget *text_view)
1292 {
1293         gtk_widget_modify_base (text_view, GTK_STATE_NORMAL,
1294                                 &GTK_WIDGET (widget)->style->bg[GTK_STATE_NORMAL]);
1295         gtk_widget_modify_text (text_view, GTK_STATE_NORMAL,
1296                                 &GTK_WIDGET (widget)->style->fg[GTK_STATE_NORMAL]);
1297 }
1298
1299 void
1300 gconf_editor_window_expand_first (GConfEditorWindow *window)
1301 {
1302         GtkTreePath *path;
1303
1304         path = gtk_tree_path_new_first ();
1305         gtk_tree_view_expand_row (GTK_TREE_VIEW (window->tree_view), path, FALSE);
1306         gtk_tree_path_free (path);
1307 }
1308
1309 static GConfClient*
1310 gconf_editor_window_get_client (int type)
1311 {
1312         GConfEngine *engine;
1313         GConfClient *client = NULL;
1314         GError *error = NULL;
1315
1316         switch (type) {
1317         case GCONF_EDITOR_WINDOW_TYPE_NORMAL:
1318                 client = gconf_client_get_default ();
1319                 break;
1320         case GCONF_EDITOR_WINDOW_TYPE_DEFAULTS:
1321                 engine = gconf_engine_get_for_address (GCONF_DEFAULTS_SOURCE, &error);
1322                 if (error) {
1323                         gconf_editor_window_popup_error_dialog (NULL,
1324                         _("Cannot create GConf engine. Error was:\n%s"), error);
1325                         return NULL;
1326                 }
1327                 client = gconf_client_get_for_engine (engine);
1328                 gconf_engine_unref (engine);
1329                 break;
1330         case GCONF_EDITOR_WINDOW_TYPE_MANDATORY:
1331                 engine = gconf_engine_get_for_address (GCONF_MANDATORY_SOURCE, &error);
1332                 if (error) {
1333                         gconf_editor_window_popup_error_dialog (NULL,
1334                         _("Cannot create GConf engine. Error was:\n%s"), error);
1335                         return NULL;
1336                 }
1337                 client = gconf_client_get_for_engine (engine);
1338                 gconf_engine_unref (engine);
1339                 break;
1340         default:
1341                 g_assert_not_reached ();
1342         }
1343
1344         return client;
1345 }
1346
1347 static void
1348 gconf_editor_window_set_property (GObject      *object,
1349                                   guint         param_id,
1350                                   const GValue *value,
1351                                   GParamSpec   *pspec)
1352 {
1353         GConfEditorWindow *gconfwindow = (GConfEditorWindow *) object;
1354
1355         switch (param_id) {
1356         case PROP_TYPE:
1357                 /* Construct-only */
1358                 gconfwindow->type = g_value_get_int (value);
1359                 gconfwindow->client = gconf_editor_window_get_client (gconfwindow->type);
1360                 switch (gconfwindow->type) {
1361                         case GCONF_EDITOR_WINDOW_TYPE_DEFAULTS:
1362                                 gtk_window_set_title (GTK_WINDOW (gconfwindow), _("Configuration Editor (Defaults settings)"));
1363                                 break;
1364                         case GCONF_EDITOR_WINDOW_TYPE_MANDATORY:
1365                                 gtk_window_set_title (GTK_WINDOW (gconfwindow), _("Configuration Editor (Mandatory settings)"));
1366                                 break;
1367                         default:
1368                                 gtk_window_set_title (GTK_WINDOW (gconfwindow), _("Configuration Editor"));
1369                         }
1370                 break;
1371         default:
1372                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
1373                 break;
1374         }
1375 }
1376
1377 static void
1378 gconf_editor_window_get_property (GObject      *object,
1379                                   guint         param_id,
1380                                   GValue       *value,
1381                                   GParamSpec   *pspec)
1382 {
1383
1384         GConfEditorWindow *gconfwindow = (GConfEditorWindow *) object;
1385
1386         switch (param_id) {
1387         case PROP_TYPE:
1388                 g_value_set_int (value, gconfwindow->type);
1389                 break;
1390         default:
1391                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
1392                 break;
1393         }
1394 }
1395
1396 static void
1397 gconf_editor_window_finalize (GObject *object)
1398 {
1399         GConfEditorWindow *window = GCONF_EDITOR_WINDOW(object);
1400         GConfClient       *client;
1401
1402         client = gconf_client_get_default ();
1403
1404         g_object_unref (window->ui_manager);
1405
1406         if (window->tearoffs_notify_id)
1407                 gconf_client_notify_remove (client, window->tearoffs_notify_id);
1408
1409         if (window->icons_notify_id)
1410                 gconf_client_notify_remove (client, window->icons_notify_id);
1411
1412         g_object_unref (client);
1413         g_object_unref (window->client);
1414
1415         G_OBJECT_CLASS (gconf_editor_window_parent_class)->finalize (object);
1416     
1417 }
1418
1419 static void
1420 gconf_editor_window_class_init (GConfEditorWindowClass *klass)
1421 {
1422         GObjectClass *object_class = G_OBJECT_CLASS(klass);
1423
1424         object_class->set_property = gconf_editor_window_set_property;
1425         object_class->get_property = gconf_editor_window_get_property;
1426         object_class->finalize = gconf_editor_window_finalize;
1427
1428         g_object_class_install_property (object_class, PROP_TYPE,
1429                                          g_param_spec_int ("type",
1430                                          "Type",
1431                                          "The Configuration Editor window type.",
1432                                          GCONF_EDITOR_WINDOW_TYPE_NORMAL, GCONF_EDITOR_WINDOW_TYPE_MANDATORY,
1433                                          GCONF_EDITOR_WINDOW_TYPE_NORMAL, 
1434                                          (G_PARAM_WRITABLE |
1435                                          G_PARAM_CONSTRUCT_ONLY)));
1436 }
1437
1438 static void
1439 tree_view_style_set_cb (GtkWidget *widget,
1440                         GtkStyle *previous_style,
1441                         GObject *cell)
1442 {
1443         GdkPixbuf *folder_open = NULL, *folder_closed = NULL;
1444         int w, h;
1445
1446         if (gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
1447                                                GTK_ICON_SIZE_MENU,
1448                                                &w, &h)) {
1449                 GtkIconTheme *theme;
1450
1451                 theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
1452                 
1453                 folder_open = gtk_icon_theme_load_icon (theme, "folder-open", w, GTK_ICON_LOOKUP_GENERIC_FALLBACK, NULL);
1454                 folder_closed = gtk_icon_theme_load_icon (theme, "folder", w, GTK_ICON_LOOKUP_GENERIC_FALLBACK, NULL);
1455         }
1456
1457         g_object_set (cell,
1458                       "pixbuf-expander-open", folder_open,
1459                       "pixbuf-expander-closed", folder_closed,
1460                       "pixbuf", folder_closed,
1461                       NULL);
1462         if (folder_open) {
1463                 g_object_unref (folder_open);
1464         }
1465         if (folder_closed) {
1466                 g_object_unref (folder_closed);
1467         }
1468 }
1469
1470 static void
1471 gconf_editor_window_init (GConfEditorWindow *window)
1472 {
1473         GtkWidget *hpaned, *vpaned, *scrolled_window, *vbox;
1474         GtkTreeViewColumn *column;
1475         GtkCellRenderer *cell;
1476         GtkAccelGroup *accel_group;
1477         GtkActionGroup *action_group;
1478         GtkWidget *menubar;
1479         GtkWidget *details_frame, *alignment, *table, *label, *text_view, *image;
1480         gchar *markup;
1481         GError *error;
1482         
1483         gtk_window_set_default_size (GTK_WINDOW (window), 700, 550);
1484
1485         vbox = gtk_vbox_new (FALSE, 0);
1486         gtk_container_add (GTK_CONTAINER (window), vbox);
1487
1488         action_group = gtk_action_group_new ("GConfEditorMenuActions");
1489         gtk_action_group_set_translation_domain (action_group, NULL);
1490         gtk_action_group_add_actions (action_group, entries, G_N_ELEMENTS (entries), window);
1491         
1492         window->ui_manager = gtk_ui_manager_new ();
1493         gtk_ui_manager_set_add_tearoffs (window->ui_manager, TRUE);
1494         gtk_ui_manager_insert_action_group (window->ui_manager, action_group, 0);
1495
1496         accel_group = gtk_ui_manager_get_accel_group (window->ui_manager);
1497         gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
1498
1499         error = NULL;
1500         if (!gtk_ui_manager_add_ui_from_string (window->ui_manager, ui_description, -1, &error)) {
1501                 g_message ("Building menus failed: %s", error->message);
1502                 g_error_free (error);
1503                 exit (EXIT_FAILURE);
1504         }
1505
1506         menubar = gtk_ui_manager_get_widget (window->ui_manager, "/GConfEditorMenu");
1507         gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
1508
1509         window->popup_menu = gtk_ui_manager_get_widget (window->ui_manager, "/GConfKeyPopupMenu");
1510
1511         /* Hook up bookmarks */
1512         gconf_bookmarks_hook_up_menu (window,
1513                                       gtk_menu_item_get_submenu (GTK_MENU_ITEM (gtk_ui_manager_get_widget (window->ui_manager,
1514                                                                                      "/GConfEditorMenu/BookmarksMenu/"))),
1515                                       gtk_ui_manager_get_widget (window->ui_manager, "/GConfEditorMenu/BookmarksMenu/AddBookmark"),
1516                                       gtk_ui_manager_get_widget (window->ui_manager, "/GConfEditorMenu/BookmarksMenu/EditBookmarks"));
1517
1518         /* Create content area */
1519         vpaned = gtk_vpaned_new ();
1520         gtk_paned_set_position (GTK_PANED (vpaned), 400);
1521         gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
1522
1523         hpaned = gtk_hpaned_new ();
1524         gtk_paned_set_position (GTK_PANED (hpaned), 250);
1525
1526         gtk_paned_pack1 (GTK_PANED (vpaned), hpaned, FALSE, FALSE);
1527
1528         /* Create ouput window */
1529         window->output_window = gedit_output_window_new ();
1530         window->output_window_type = GCONF_EDITOR_WINDOW_OUTPUT_WINDOW_NONE;
1531         gedit_output_window_set_select_multiple (GEDIT_OUTPUT_WINDOW (window->output_window),
1532                                                  GTK_SELECTION_SINGLE);
1533         gtk_paned_pack2 (GTK_PANED (vpaned), window->output_window, FALSE, FALSE);
1534         g_signal_connect (G_OBJECT (window->output_window), "close_requested",
1535                           G_CALLBACK (gconf_editor_window_close_output_window), window);
1536
1537         g_signal_connect (G_OBJECT (window->output_window), "selection_changed",
1538                           G_CALLBACK (gconf_editor_window_output_window_changed), window);
1539
1540         gconf_editor_window_recents_init ();
1541         
1542         /* Create status bar */
1543         window->statusbar = gtk_statusbar_new ();
1544         gtk_box_pack_start (GTK_BOX (vbox), window->statusbar, FALSE, FALSE, 0);
1545         
1546         /* Create tree model and tree view */
1547         window->tree_model = gconf_tree_model_new ();
1548         window->sorted_tree_model = gtk_tree_model_sort_new_with_model (window->tree_model);
1549         window->tree_view = gtk_tree_view_new_with_model (window->sorted_tree_model);
1550         gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (window->tree_view), FALSE);
1551         g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->tree_view))), "changed",
1552                           G_CALLBACK (gconf_editor_window_selection_changed), window);
1553         g_signal_connect (G_OBJECT (window->tree_view), "row-activated", 
1554                           G_CALLBACK (gconf_editor_window_row_activated),
1555                           window);
1556         g_signal_connect (window->tree_view, "test-expand-row",
1557                           G_CALLBACK (gconf_editor_window_test_expand_row),
1558                           window);
1559         g_signal_connect (window->tree_view, "row-expanded",
1560                           G_CALLBACK (gconf_editor_window_row_expanded),
1561                           window);
1562         g_object_unref (G_OBJECT (window->tree_model));
1563
1564         column = gtk_tree_view_column_new ();
1565
1566         cell = gtk_cell_renderer_pixbuf_new ();
1567         g_signal_connect (window->tree_view, "style-set", G_CALLBACK (tree_view_style_set_cb), cell);
1568         gtk_tree_view_column_pack_start (column, cell, FALSE);
1569         cell = gtk_cell_renderer_text_new ();
1570         gtk_tree_view_column_pack_start (column, cell, TRUE);
1571         gtk_tree_view_column_set_attributes (column, cell,
1572                                              "text", GCONF_TREE_MODEL_NAME_COLUMN,
1573                                              NULL);
1574         gtk_tree_view_append_column (GTK_TREE_VIEW (window->tree_view), column);
1575
1576         gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (window->sorted_tree_model), 0, GTK_SORT_ASCENDING);
1577         
1578         scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1579         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
1580                                              GTK_SHADOW_ETCHED_IN);
1581         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
1582                                         GTK_POLICY_AUTOMATIC,
1583                                         GTK_POLICY_AUTOMATIC);
1584         gtk_container_add (GTK_CONTAINER (scrolled_window), window->tree_view);
1585         gtk_paned_add1 (GTK_PANED (hpaned), scrolled_window);
1586
1587         /* Create list model and list view */
1588         window->list_model = gconf_list_model_new ();
1589         window->sorted_list_model = gtk_tree_model_sort_new_with_model (window->list_model);
1590         window->list_view = gtk_tree_view_new_with_model (window->sorted_list_model);
1591         g_object_unref (G_OBJECT (window->list_model));
1592         g_object_unref (G_OBJECT (window->sorted_list_model));
1593
1594         gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (window->sorted_list_model),
1595                                               GCONF_LIST_MODEL_KEY_NAME_COLUMN, GTK_SORT_ASCENDING);
1596
1597         g_signal_connect (window->list_view, "popup_menu",
1598                           G_CALLBACK (gconf_editor_window_list_view_popup_menu), window);
1599         g_signal_connect (window->list_view, "row_activated",
1600                           G_CALLBACK (gconf_editor_window_list_view_row_activated), window);
1601
1602         g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->list_view)), "changed",
1603                           G_CALLBACK (gconf_editor_window_update_list_selection), window);
1604         
1605         column = gtk_tree_view_column_new ();
1606         gtk_tree_view_column_set_reorderable (column, TRUE);
1607         gtk_tree_view_column_set_title (column, _("Name"));
1608
1609         cell = gtk_cell_renderer_pixbuf_new ();
1610         g_object_set (cell, "stock-size", GTK_ICON_SIZE_MENU, NULL);
1611         gtk_tree_view_column_pack_start (column, cell, FALSE);
1612         gtk_tree_view_column_set_attributes (column, cell,
1613                                              "icon-name", GCONF_LIST_MODEL_ICON_NAME_COLUMN,
1614                                              NULL);
1615
1616         gtk_tree_view_column_set_resizable (column, TRUE);
1617         cell = gtk_cell_renderer_text_new ();
1618         gtk_tree_view_column_pack_start (column, cell, TRUE);
1619         gtk_tree_view_column_set_attributes (column, cell,
1620                                              "text", GCONF_LIST_MODEL_KEY_NAME_COLUMN,
1621                                              NULL);
1622         gtk_tree_view_column_set_sort_column_id (column, GCONF_LIST_MODEL_KEY_NAME_COLUMN);
1623         gtk_tree_view_append_column (GTK_TREE_VIEW (window->list_view), column);
1624
1625         cell = gconf_cell_renderer_new ();
1626         g_signal_connect (cell, "changed",
1627                           G_CALLBACK (gconf_editor_gconf_value_changed), window);
1628         g_signal_connect (cell, "check_writable",
1629                           G_CALLBACK (gconf_editor_check_writable), window);
1630         
1631         window->value_column = column = gtk_tree_view_column_new_with_attributes (_("Value"),
1632                                                                                   cell,
1633                                                                                   "value", GCONF_LIST_MODEL_VALUE_COLUMN,
1634                                                                                   NULL);
1635         g_signal_connect (window->list_view, "button_press_event",
1636                           G_CALLBACK (list_view_button_press_event), window);
1637
1638         gtk_tree_view_column_set_reorderable (column, TRUE);
1639         gtk_tree_view_column_set_resizable (column, TRUE);
1640
1641         gtk_tree_view_append_column (GTK_TREE_VIEW (window->list_view), column);
1642
1643         scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1644         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
1645                                              GTK_SHADOW_ETCHED_IN);
1646         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
1647                                         GTK_POLICY_AUTOMATIC,
1648                                         GTK_POLICY_AUTOMATIC);
1649         gtk_container_add (GTK_CONTAINER (scrolled_window), window->list_view);
1650
1651         vpaned = gtk_vpaned_new ();
1652         gtk_paned_add2 (GTK_PANED (hpaned), vpaned);
1653
1654         gtk_paned_pack1 (GTK_PANED (vpaned), scrolled_window, TRUE, FALSE);
1655
1656         /* Create details area */
1657         label = gtk_label_new (NULL);
1658         markup = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("Key Documentation"));
1659         gtk_label_set_markup (GTK_LABEL (label), markup);
1660         g_free (markup);
1661
1662         details_frame = gtk_frame_new (NULL);
1663         gtk_frame_set_label_widget (GTK_FRAME (details_frame), label);
1664         gtk_frame_set_shadow_type (GTK_FRAME (details_frame), GTK_SHADOW_NONE);
1665         gtk_paned_pack2 (GTK_PANED (vpaned), details_frame, FALSE, FALSE);
1666
1667         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
1668         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 0, 24, 0);
1669         gtk_container_add (GTK_CONTAINER (details_frame), alignment);
1670
1671         table = gtk_table_new (6, 2, FALSE);
1672         gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1673         gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1674         
1675         gtk_container_add (GTK_CONTAINER (alignment), table);
1676
1677
1678         window->non_writable_label = gtk_hbox_new (FALSE, 6);
1679         gtk_table_attach (GTK_TABLE (table), window->non_writable_label,
1680                           0, 2, 0, 1,
1681                           GTK_FILL, 0, 0, 0);
1682
1683         image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON);
1684         gtk_widget_show (image);
1685         gtk_box_pack_start (GTK_BOX (window->non_writable_label), image, FALSE, FALSE, 0);
1686
1687         label = gtk_label_new (_("This key is not writable"));
1688         gtk_widget_show (label);
1689         gtk_box_pack_start (GTK_BOX (window->non_writable_label), label, FALSE, FALSE, 0);
1690         
1691
1692         window->no_schema_label = gtk_hbox_new (FALSE, 6);
1693         gtk_table_attach (GTK_TABLE (table), window->no_schema_label,
1694                           0, 2, 1, 2,
1695                           GTK_FILL, 0, 0, 0);
1696         image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON);
1697         gtk_widget_show (image);
1698         gtk_box_pack_start (GTK_BOX (window->no_schema_label), image, FALSE, FALSE, 0);
1699
1700         label = gtk_label_new (_("This key has no schema"));
1701         gtk_widget_show (label);
1702         gtk_box_pack_start (GTK_BOX (window->no_schema_label), label, FALSE, FALSE, 0);
1703
1704
1705         label = gtk_label_new (_("Key name:"));
1706         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1707         
1708         gtk_table_attach (GTK_TABLE (table), label,
1709                           0, 1, 2, 3,
1710                           GTK_FILL, 0, 0, 0);
1711         window->key_name_label = gtk_label_new (_("(None)"));
1712         gtk_label_set_selectable (GTK_LABEL (window->key_name_label), TRUE);
1713         gtk_misc_set_alignment (GTK_MISC (window->key_name_label), 0.0, 0.5);   
1714         gtk_table_attach (GTK_TABLE (table), window->key_name_label,
1715                           1, 2, 2, 3,
1716                           GTK_FILL, 0, 0, 0);
1717         
1718         label = gtk_label_new (_("Key owner:"));
1719         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);    
1720         gtk_table_attach (GTK_TABLE (table), label,
1721                           0, 1, 3, 4,
1722                           GTK_FILL, 0, 0, 0);
1723         window->owner_label= gtk_label_new (_("(None)"));
1724         gtk_label_set_selectable (GTK_LABEL (window->owner_label), TRUE);       
1725         gtk_misc_set_alignment (GTK_MISC (window->owner_label), 0.0, 0.5);              
1726         gtk_table_attach (GTK_TABLE (table), window->owner_label,
1727                           1, 2, 3, 4,
1728                           GTK_FILL, 0, 0, 0);
1729
1730         label = gtk_label_new (_("Short description:"));
1731         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);    
1732         gtk_table_attach (GTK_TABLE (table), label,
1733                           0, 1, 4, 5,
1734                           GTK_FILL, 0, 0, 0);
1735         window->short_desc_label= gtk_label_new (_("(None)"));
1736         gtk_label_set_line_wrap (GTK_LABEL (window->short_desc_label), TRUE);
1737         gtk_label_set_selectable (GTK_LABEL (window->short_desc_label), TRUE);  
1738         gtk_misc_set_alignment (GTK_MISC (window->short_desc_label), 0.0, 0.5);         
1739         gtk_table_attach (GTK_TABLE (table), window->short_desc_label,
1740                           1, 2, 4, 5,
1741                           GTK_FILL, 0, 0, 0);
1742
1743         label = gtk_label_new (_("Long description:"));
1744         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);    
1745         gtk_table_attach (GTK_TABLE (table), label,
1746                           0, 1, 5, 6,
1747                           GTK_FILL, GTK_FILL, 0, 0);
1748
1749         window->long_desc_buffer = gtk_text_buffer_new (NULL);
1750         gtk_text_buffer_set_text (window->long_desc_buffer, _("(None)"), -1);   
1751         text_view = gtk_text_view_new_with_buffer (window->long_desc_buffer);
1752         g_signal_connect (window, "style_set",
1753                           G_CALLBACK (gconf_editor_window_style_set),
1754                           text_view);
1755         gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), GTK_WRAP_WORD);
1756         gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE);
1757         scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1758         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
1759                                         GTK_POLICY_AUTOMATIC,
1760                                         GTK_POLICY_AUTOMATIC);
1761         gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
1762         
1763         gtk_table_attach (GTK_TABLE (table), scrolled_window, 
1764                           1, 2, 5, 6,
1765                           GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
1766
1767         gtk_widget_show_all (vbox);
1768         gtk_widget_hide (window->non_writable_label);
1769         gtk_widget_hide (window->no_schema_label);
1770         gtk_widget_hide (window->output_window);
1771         
1772         gtk_window_set_default_icon_name ("gconf-editor");
1773
1774         gconf_editor_window_setup_ui_prefs_handler (window);
1775 }
1776