Eliminate FIXME: enable or disable individual plugins from configure
[geeqie.git] / src / desktop_file.c
1 /*
2  * Copyright (C) 2004 John Ellis
3  * Copyright (C) 2008 - 2016 The Geeqie Team
4  *
5  * Author: Vladimir Nadvornik
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include "main.h"
23 #include "desktop_file.h"
24
25 #include "editors.h"
26 #include "filedata.h"
27 #include "misc.h"
28 #include "ui_misc.h"
29 #include "ui_fileops.h"
30 #include "ui_utildlg.h"
31 #include "pixbuf_util.h"
32 #include "window.h"
33 #include "utilops.h"
34 #include "layout_util.h"
35
36 #define CONFIG_WINDOW_DEF_WIDTH         700
37 #define CONFIG_WINDOW_DEF_HEIGHT        400
38
39
40
41 typedef struct _EditorWindow EditorWindow;
42 struct _EditorWindow
43 {
44         GtkWidget *window;
45         GtkWidget *entry;
46         GtkWidget *save_button;
47         GtkTextBuffer *buffer;
48         gchar *desktop_name;
49         gboolean modified;
50 };
51
52 typedef struct _EditorListWindow EditorListWindow;
53 struct _EditorListWindow
54 {
55         GtkWidget *window;
56         GtkWidget *view;
57         GenericDialog *gd;      /* any open confirm dialogs ? */
58         GtkWidget *delete_button;
59         GtkWidget *edit_button;
60 };
61
62 typedef struct _EditorWindowDel_Data EditorWindowDel_Data;
63 struct _EditorWindowDel_Data
64 {
65         EditorListWindow *ewl;
66         gchar *path;
67 };
68
69 static EditorListWindow *editor_list_window = NULL;
70
71 static gboolean editor_window_save(EditorWindow *ew)
72 {
73         gchar *dir;
74         gchar *path;
75         gchar *text;
76         GtkTextIter start, end;
77         GError *error = NULL;
78         gboolean ret = TRUE;
79         const gchar *name = gtk_entry_get_text(GTK_ENTRY(ew->entry));
80
81         if (!name || !name[0])
82                 {
83                 file_util_warning_dialog(_("Can't save"), _("Please specify file name."), GTK_STOCK_DIALOG_ERROR, NULL);
84                 return FALSE;
85                 }
86
87         gtk_text_buffer_get_bounds(ew->buffer, &start, &end);
88         text = gtk_text_buffer_get_text(ew->buffer, &start, &end, FALSE);
89
90         dir = g_build_filename(get_rc_dir(), "applications", NULL);
91         path = g_build_filename(dir, name, NULL);
92
93         if (!recursive_mkdir_if_not_exists(dir, 0755))
94                 {
95                 file_util_warning_dialog(_("Can't save"), _("Could not create directory"), GTK_STOCK_DIALOG_ERROR, NULL);
96                 ret = FALSE;
97                 }
98
99         if (ret && !g_file_set_contents(path, text, -1, &error))
100                 {
101                 file_util_warning_dialog(_("Can't save"), error->message, GTK_STOCK_DIALOG_ERROR, NULL);
102                 g_error_free(error);
103                 ret = FALSE;
104                 }
105
106         g_free(path);
107         g_free(dir);
108         g_free(text);
109         layout_editors_reload_start();
110         /* idle function is not needed, everything should be cached */
111         layout_editors_reload_finish();
112         return ret;
113 }
114
115 static void editor_window_close_cb(GtkWidget *widget, gpointer data)
116 {
117         EditorWindow *ew = data;
118
119         g_free(ew->desktop_name);
120         gtk_widget_destroy(ew->window);
121         g_free(ew);
122 }
123
124 static gint editor_window_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data)
125 {
126         editor_window_close_cb(w, data);
127         return TRUE;
128 }
129
130 static void editor_window_save_cb(GtkWidget *widget, gpointer data)
131 {
132         EditorWindow *ew = data;
133
134         if (ew->modified)
135                 {
136                 editor_window_save(ew);
137                 }
138
139         gtk_widget_set_sensitive(ew->save_button, FALSE);
140         gtk_text_buffer_set_modified(ew->buffer, FALSE);
141         ew->modified = FALSE;
142 }
143
144 static void editor_window_text_modified_cb(GtkWidget *widget, gpointer data)
145 {
146         EditorWindow *ew = data;
147
148         if (gtk_text_buffer_get_modified(ew->buffer))
149                 {
150                 gtk_widget_set_sensitive(ew->save_button, TRUE);
151                 ew->modified = TRUE;
152                 }
153 }
154
155 static void editor_window_entry_changed_cb(GtkWidget *widget, gpointer data)
156 {
157         EditorWindow *ew = data;
158         const gchar *content = gtk_entry_get_text(GTK_ENTRY(ew->entry));
159         gboolean modified = ew->modified;
160
161         if (!modified)
162                 {
163                 modified = (!ew->desktop_name && *content);
164                 }
165
166         if (!modified)
167                 {
168                 modified = strcmp(ew->desktop_name, content);
169                 }
170
171         gtk_widget_set_sensitive(ew->save_button, modified);
172         ew->modified = modified;
173 }
174
175 static void editor_window_new(const gchar *src_path, const gchar *desktop_name)
176 {
177         EditorWindow *ew;
178         GtkWidget *win_vbox;
179         GtkWidget *hbox;
180         GtkWidget *button;
181         GtkWidget *ct_button;
182         GtkWidget *button_hbox;
183         GtkWidget *scrolled;
184         GtkWidget *text_view;
185         gchar *text;
186         gsize size;
187
188         ew = g_new0(EditorWindow, 1);
189
190
191         ew->window = window_new(GTK_WINDOW_TOPLEVEL, "Desktop", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Desktop file"));
192         gtk_window_set_type_hint(GTK_WINDOW(ew->window), GDK_WINDOW_TYPE_HINT_DIALOG);
193
194         g_signal_connect(G_OBJECT(ew->window), "delete_event",
195                          G_CALLBACK(editor_window_delete_cb), ew);
196
197         gtk_window_set_default_size(GTK_WINDOW(ew->window), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
198         gtk_window_set_resizable(GTK_WINDOW(ew->window), TRUE);
199         gtk_container_set_border_width(GTK_CONTAINER(ew->window), PREF_PAD_BORDER);
200
201         win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
202         gtk_container_add(GTK_CONTAINER(ew->window), win_vbox);
203         gtk_widget_show(win_vbox);
204
205         hbox = gtk_hbox_new(FALSE, PREF_PAD_SPACE);
206         gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
207         gtk_widget_show(hbox);
208
209         ew->entry = gtk_entry_new();
210         gtk_box_pack_start(GTK_BOX(hbox), ew->entry, TRUE, TRUE, 0);
211         ew->desktop_name = NULL;
212         if (desktop_name)
213                 {
214                 gtk_entry_set_text(GTK_ENTRY(ew->entry), desktop_name);
215                 ew->desktop_name = g_strdup(desktop_name);
216                 }
217         gtk_widget_show(ew->entry);
218         g_signal_connect(G_OBJECT(ew->entry), "changed", G_CALLBACK(editor_window_entry_changed_cb), ew);
219
220         button_hbox = gtk_hbutton_box_new();
221         gtk_button_box_set_layout(GTK_BUTTON_BOX(button_hbox), GTK_BUTTONBOX_END);
222         gtk_box_set_spacing(GTK_BOX(button_hbox), PREF_PAD_BUTTON_GAP);
223         gtk_box_pack_end(GTK_BOX(hbox), button_hbox, FALSE, FALSE, 0);
224         gtk_widget_show(button_hbox);
225
226         ew->save_button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
227                                  G_CALLBACK(editor_window_save_cb), ew);
228         gtk_container_add(GTK_CONTAINER(button_hbox), ew->save_button);
229         gtk_widget_set_can_default(ew->save_button, TRUE);
230         gtk_widget_set_sensitive(ew->save_button, FALSE);
231         gtk_widget_show(ew->save_button);
232         ct_button = ew->save_button;
233
234         button = pref_button_new(NULL, GTK_STOCK_CLOSE, NULL, FALSE,
235                                  G_CALLBACK(editor_window_close_cb), ew);
236         gtk_container_add(GTK_CONTAINER(button_hbox), button);
237         gtk_widget_set_can_default(button, TRUE);
238         gtk_widget_show(button);
239
240         if (!generic_dialog_get_alternative_button_order(ew->window))
241                 {
242                 gtk_box_reorder_child(GTK_BOX(button_hbox), ct_button, -1);
243                 }
244
245
246         scrolled = gtk_scrolled_window_new(NULL, NULL);
247         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
248         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
249                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
250         gtk_box_pack_start(GTK_BOX(win_vbox), scrolled, TRUE, TRUE, 5);
251         gtk_widget_show(scrolled);
252
253         text_view = gtk_text_view_new();
254         gtk_container_add(GTK_CONTAINER(scrolled), text_view);
255         gtk_widget_show(text_view);
256
257         ew->buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
258         if (g_file_get_contents(src_path, &text, &size, NULL))
259                 {
260                 gtk_text_buffer_set_text(ew->buffer, text, size);
261                 }
262         gtk_text_buffer_set_modified(ew->buffer, FALSE);
263         g_signal_connect(G_OBJECT(ew->buffer), "modified-changed",
264                          G_CALLBACK(editor_window_text_modified_cb), ew);
265
266         gtk_widget_show(ew->window);
267 }
268
269
270 static void editor_list_window_close_cb(GtkWidget *widget, gpointer data)
271 {
272         gtk_widget_destroy(editor_list_window->window);
273         g_free(editor_list_window);
274         editor_list_window = NULL;
275 }
276
277 static gboolean editor_list_window_delete(GtkWidget *widget, GdkEventAny *event, gpointer data)
278 {
279         editor_list_window_close_cb(NULL, NULL);
280         return TRUE;
281 }
282
283 static void editor_list_window_delete_dlg_cancel(GenericDialog *gd, gpointer data);
284
285 static void editor_list_window_delete_dlg_cancel(GenericDialog *gd, gpointer data)
286 {
287         EditorWindowDel_Data *ewdl = data;
288
289         ewdl->ewl->gd = NULL;
290         g_free(ewdl->path);
291         g_free(ewdl);
292 }
293
294 static void editor_list_window_delete_dlg_ok_cb(GenericDialog *gd, gpointer data)
295 {
296         EditorWindowDel_Data *ewdl = data;
297
298         if (!unlink_file(ewdl->path))
299                 {
300                 gchar *text = g_strdup_printf(_("Unable to delete file:\n%s"), ewdl->path);
301                 warning_dialog(_("File deletion failed"), text, GTK_STOCK_DIALOG_WARNING, NULL);
302                 g_free(text);
303                 }
304         else
305                 {
306                 /* refresh list */
307                 layout_editors_reload_start();
308                 /* idle function is not needed, everything should be cached */
309                 layout_editors_reload_finish();
310                 }
311
312         editor_list_window_delete_dlg_cancel(gd, data);
313 }
314
315 static void editor_list_window_delete_cb(GtkWidget *widget, gpointer data)
316 {
317         EditorListWindow *ewl = data;
318         GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(ewl->view));
319         GtkTreeIter iter;
320
321         if (gtk_tree_selection_get_selected(sel, NULL, &iter))
322                 {
323                 GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(ewl->view));
324                 gchar *path;
325                 gchar *key;
326                 gchar *text;
327                 EditorWindowDel_Data *ewdl;
328
329                 gtk_tree_model_get(store, &iter,
330                                    DESKTOP_FILE_COLUMN_PATH, &path,
331                                    DESKTOP_FILE_COLUMN_KEY, &key, -1);
332
333
334                 ewdl = g_new(EditorWindowDel_Data, 1);
335                 ewdl->ewl = ewl;
336                 ewdl->path = path;
337
338                 if (ewl->gd)
339                         {
340                         GenericDialog *gd = ewl->gd;
341                         editor_list_window_delete_dlg_cancel(ewl->gd, ewl->gd->data);
342                         generic_dialog_close(gd);
343                         }
344
345                 ewl->gd = generic_dialog_new(_("Delete file"), "dlg_confirm",
346                                             NULL, TRUE,
347                                             editor_list_window_delete_dlg_cancel, ewdl);
348
349                 generic_dialog_add_button(ewl->gd, GTK_STOCK_DELETE, NULL, editor_list_window_delete_dlg_ok_cb, TRUE);
350
351                 text = g_strdup_printf(_("About to delete the file:\n %s"), path);
352                 generic_dialog_add_message(ewl->gd, GTK_STOCK_DIALOG_QUESTION,
353                                            _("Delete file"), text, TRUE);
354                 g_free(text);
355
356                 gtk_widget_show(ewl->gd->dialog);
357                 }
358 }
359
360 static void editor_list_window_edit_cb(GtkWidget *widget, gpointer data)
361 {
362         EditorListWindow *ewl = data;
363         GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(ewl->view));
364         GtkTreeIter iter;
365
366         if (gtk_tree_selection_get_selected(sel, NULL, &iter))
367                 {
368                 GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(ewl->view));
369                 gchar *path;
370                 gchar *key;
371
372                 gtk_tree_model_get(store, &iter,
373                                    DESKTOP_FILE_COLUMN_PATH, &path,
374                                    DESKTOP_FILE_COLUMN_KEY, &key, -1);
375                 editor_window_new(path, key);
376                 g_free(key);
377                 g_free(path);
378                 }
379 }
380
381 static void editor_list_window_new_cb(GtkWidget *widget, gpointer data)
382 {
383         editor_window_new(DESKTOP_FILE_TEMPLATE, _("new.desktop"));
384 }
385
386 static void editor_list_window_help_cb(GtkWidget *widget, gpointer data)
387 {
388         help_window_show("GuidePluginsConfig.html");
389 }
390
391 static void editor_list_window_selection_changed_cb(GtkWidget *widget, gpointer data)
392 {
393         EditorListWindow *ewl = data;
394         GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(ewl->view));
395         GtkTreeIter iter;
396
397         if (gtk_tree_selection_get_selected(sel, NULL, &iter))
398                 {
399                 GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(ewl->view));
400                 gchar *path;
401
402                 gtk_tree_model_get(store, &iter,
403                                                    DESKTOP_FILE_COLUMN_PATH, &path,
404                                                    -1);
405
406                 gtk_widget_set_sensitive(ewl->delete_button, access_file(path, W_OK));
407                 gtk_widget_set_sensitive(ewl->edit_button, TRUE);
408                 g_free(path);
409                 }
410
411 }
412
413 static gint editor_list_window_sort_cb(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data)
414 {
415         gint n = GPOINTER_TO_INT(data);
416         gint ret = 0;
417         gboolean bool1, bool2;
418
419         switch (n)
420                 {
421                 case DESKTOP_FILE_COLUMN_KEY:
422                 case DESKTOP_FILE_COLUMN_NAME:
423                 case DESKTOP_FILE_COLUMN_PATH:
424                 case DESKTOP_FILE_COLUMN_HIDDEN:
425                         {
426                         gchar *s1, *s2;
427
428                         gtk_tree_model_get(model, a, n, &s1, -1);
429                         gtk_tree_model_get(model, b, n, &s2, -1);
430
431                         if (!s1 || !s2)
432                                 {
433                                 if (!s1 && !s2) break;
434                                 ret = s1 ? 1 : -1;
435                                 }
436                         else
437                                 {
438                                 ret = g_utf8_collate(s1, s2);
439                                 }
440
441                         g_free(s1);
442                         g_free(s2);
443                         }
444                         break;
445                 case DESKTOP_FILE_COLUMN_DISABLED:
446                         {
447                         gtk_tree_model_get(model, a, n, &bool1, -1);
448                         gtk_tree_model_get(model, b, n, &bool2, -1);
449
450                         if (bool1 == bool2)
451                                 {
452                                 ret = 0;
453                                 }
454                         else if (bool1 > bool2)
455                                 {
456                                 ret = -1;
457                                 }
458                         else
459                                 {
460                                 ret = 1;
461                                 }
462                         break;
463                         }
464
465                 default:
466                         g_return_val_if_reached(0);
467                 }
468
469         return ret;
470 }
471
472 static void plugin_disable_cb(GtkCellRendererToggle *renderer, gchar *path_str, gpointer data)
473 {
474         EditorListWindow *ewl = data;
475         GtkTreePath *tpath;
476         GtkTreeIter iter;
477         GtkTreeModel *model;
478         gboolean disabled;
479         gchar *path;
480         GList *list;
481         gchar *haystack;
482
483         tpath = gtk_tree_path_new_from_string(path_str);
484         model = gtk_tree_view_get_model(GTK_TREE_VIEW(ewl->view));
485         gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
486         gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, DESKTOP_FILE_COLUMN_DISABLED, &disabled, -1);
487         gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, DESKTOP_FILE_COLUMN_PATH, &path, -1);
488
489         gtk_list_store_set(GTK_LIST_STORE(desktop_file_list), &iter, DESKTOP_FILE_COLUMN_DISABLED, !disabled, -1);
490
491         if (!disabled)
492                 {
493                 options->disabled_plugins = g_list_append((options->disabled_plugins), g_strdup(path));
494                 }
495         else
496                 {
497                 list = options->disabled_plugins;
498                 while (list)
499                         {
500                         haystack = list->data;
501
502                         if (haystack && strcmp(haystack, path) == 0)
503                                 {
504                                 g_free(haystack);
505                                 options->disabled_plugins = g_list_remove(options->disabled_plugins, haystack);
506                                 }
507
508                         list = list->next;
509                         }
510                 }
511
512         layout_editors_reload_start();
513         layout_editors_reload_finish();
514 }
515
516 static void plugin_disable_set_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
517                                                         GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
518 {
519         gboolean disabled;
520
521         gtk_tree_model_get(tree_model, iter, DESKTOP_FILE_COLUMN_DISABLED, &disabled, -1);
522
523         if (disabled)
524                 {
525                 g_object_set(GTK_CELL_RENDERER(cell), "active", TRUE, NULL);
526                 }
527         else
528                 {
529                 g_object_set(GTK_CELL_RENDERER(cell), "active", FALSE, NULL);
530                 }
531 }
532
533 static void editor_list_window_create(void)
534 {
535         GtkWidget *win_vbox;
536         GtkWidget *hbox;
537         GtkWidget *button;
538         GtkWidget *scrolled;
539         GtkCellRenderer *renderer;
540         GtkTreeSelection *selection;
541         GtkTreeViewColumn *column;
542         GtkTreeModel *store;
543         GtkTreeSortable *sortable;
544         EditorListWindow *ewl;
545
546         editor_list_window = ewl = g_new0(EditorListWindow, 1);
547
548         ewl->window = window_new(GTK_WINDOW_TOPLEVEL, "editors", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Plugins"));
549         gtk_window_set_type_hint(GTK_WINDOW(ewl->window), GDK_WINDOW_TYPE_HINT_DIALOG);
550         g_signal_connect(G_OBJECT(ewl->window), "delete_event",
551                          G_CALLBACK(editor_list_window_delete), NULL);
552         gtk_window_set_default_size(GTK_WINDOW(ewl->window), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
553         gtk_window_set_resizable(GTK_WINDOW(ewl->window), TRUE);
554         gtk_container_set_border_width(GTK_CONTAINER(ewl->window), PREF_PAD_BORDER);
555
556         win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
557         gtk_container_add(GTK_CONTAINER(ewl->window), win_vbox);
558         gtk_widget_show(win_vbox);
559
560         hbox = gtk_hbutton_box_new();
561         gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
562         gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
563         gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
564         gtk_widget_show(hbox);
565
566
567         button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
568                                  G_CALLBACK(editor_list_window_help_cb), ewl);
569         gtk_container_add(GTK_CONTAINER(hbox), button);
570         gtk_widget_set_can_default(button, TRUE);
571         gtk_widget_show(button);
572
573         button = pref_button_new(NULL, GTK_STOCK_NEW, NULL, FALSE,
574                                  G_CALLBACK(editor_list_window_new_cb), ewl);
575         gtk_container_add(GTK_CONTAINER(hbox), button);
576         gtk_widget_set_can_default(button, TRUE);
577         gtk_widget_show(button);
578
579         button = pref_button_new(NULL, GTK_STOCK_EDIT, NULL, FALSE,
580                                  G_CALLBACK(editor_list_window_edit_cb), ewl);
581         gtk_container_add(GTK_CONTAINER(hbox), button);
582         gtk_widget_set_can_default(button, TRUE);
583         gtk_widget_set_sensitive(button, FALSE);
584         gtk_widget_show(button);
585         ewl->edit_button = button;
586
587         button = pref_button_new(NULL, GTK_STOCK_DELETE, NULL, FALSE,
588                                  G_CALLBACK(editor_list_window_delete_cb), ewl);
589         gtk_container_add(GTK_CONTAINER(hbox), button);
590         gtk_widget_set_can_default(button, TRUE);
591         gtk_widget_set_sensitive(button, FALSE);
592         gtk_widget_show(button);
593         ewl->delete_button = button;
594
595         button = pref_button_new(NULL, GTK_STOCK_CLOSE, NULL, FALSE,
596                                  G_CALLBACK(editor_list_window_close_cb), ewl);
597         gtk_container_add(GTK_CONTAINER(hbox), button);
598         gtk_widget_set_can_default(button, TRUE);
599         gtk_widget_show(button);
600
601         scrolled = gtk_scrolled_window_new(NULL, NULL);
602         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
603         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
604                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
605         gtk_box_pack_start(GTK_BOX(win_vbox), scrolled, TRUE, TRUE, 5);
606         gtk_widget_show(scrolled);
607
608         ewl->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(desktop_file_list));
609         selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ewl->view));
610         gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
611         g_signal_connect(selection, "changed", G_CALLBACK(editor_list_window_selection_changed_cb), ewl);
612
613         gtk_tree_view_set_enable_search(GTK_TREE_VIEW(ewl->view), FALSE);
614
615         column = gtk_tree_view_column_new();
616         gtk_tree_view_column_set_title(column, _("Disabled"));
617         gtk_tree_view_column_set_resizable(column, TRUE);
618
619         renderer = gtk_cell_renderer_toggle_new();
620         g_signal_connect(G_OBJECT(renderer), "toggled",
621                          G_CALLBACK(plugin_disable_cb), ewl);
622         gtk_tree_view_column_pack_start(column, renderer, FALSE);
623         gtk_tree_view_column_set_cell_data_func(column, renderer, plugin_disable_set_func,
624                                                 NULL, NULL);
625         gtk_tree_view_append_column(GTK_TREE_VIEW(ewl->view), column);
626         gtk_tree_view_column_set_sort_column_id(column, DESKTOP_FILE_COLUMN_DISABLED);
627
628         column = gtk_tree_view_column_new();
629         gtk_tree_view_column_set_title(column, _("Name"));
630         gtk_tree_view_column_set_resizable(column, TRUE);
631         renderer = gtk_cell_renderer_text_new();
632         gtk_tree_view_column_pack_start(column, renderer, FALSE);
633         gtk_tree_view_column_add_attribute(column, renderer, "text", DESKTOP_FILE_COLUMN_NAME);
634         gtk_tree_view_append_column(GTK_TREE_VIEW(ewl->view), column);
635         gtk_tree_view_column_set_sort_column_id(column, DESKTOP_FILE_COLUMN_NAME);
636
637         column = gtk_tree_view_column_new();
638         gtk_tree_view_column_set_title(column, _("Hidden"));
639         gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
640         renderer = gtk_cell_renderer_text_new();
641         gtk_tree_view_column_pack_start(column, renderer, FALSE);
642         gtk_tree_view_column_add_attribute(column, renderer, "text", DESKTOP_FILE_COLUMN_HIDDEN);
643         gtk_tree_view_append_column(GTK_TREE_VIEW(ewl->view), column);
644         gtk_tree_view_column_set_sort_column_id(column, DESKTOP_FILE_COLUMN_HIDDEN);
645         gtk_tree_view_column_set_alignment(column, 0.5);
646
647         column = gtk_tree_view_column_new();
648         gtk_tree_view_column_set_title(column, _("Desktop file"));
649         gtk_tree_view_column_set_resizable(column, TRUE);
650         renderer = gtk_cell_renderer_text_new();
651         gtk_tree_view_column_pack_start(column, renderer, FALSE);
652         gtk_tree_view_column_add_attribute(column, renderer, "text", DESKTOP_FILE_COLUMN_KEY);
653         gtk_tree_view_append_column(GTK_TREE_VIEW(ewl->view), column);
654         gtk_tree_view_column_set_sort_column_id(column, DESKTOP_FILE_COLUMN_KEY);
655
656         column = gtk_tree_view_column_new();
657         gtk_tree_view_column_set_title(column, _("Path"));
658         gtk_tree_view_column_set_resizable(column, TRUE);
659         renderer = gtk_cell_renderer_text_new();
660         gtk_tree_view_column_pack_start(column, renderer, FALSE);
661         gtk_tree_view_column_add_attribute(column, renderer, "text", DESKTOP_FILE_COLUMN_PATH);
662         gtk_tree_view_append_column(GTK_TREE_VIEW(ewl->view), column);
663         gtk_tree_view_column_set_sort_column_id(column, DESKTOP_FILE_COLUMN_PATH);
664
665         /* set up sorting */
666         store = gtk_tree_view_get_model(GTK_TREE_VIEW(ewl->view));
667         sortable = GTK_TREE_SORTABLE(store);
668         gtk_tree_sortable_set_sort_func(sortable, DESKTOP_FILE_COLUMN_KEY, editor_list_window_sort_cb,
669                                         GINT_TO_POINTER(DESKTOP_FILE_COLUMN_KEY), NULL);
670         gtk_tree_sortable_set_sort_func(sortable, DESKTOP_FILE_COLUMN_HIDDEN, editor_list_window_sort_cb,
671                                         GINT_TO_POINTER(DESKTOP_FILE_COLUMN_HIDDEN), NULL);
672         gtk_tree_sortable_set_sort_func(sortable, DESKTOP_FILE_COLUMN_NAME, editor_list_window_sort_cb,
673                                         GINT_TO_POINTER(DESKTOP_FILE_COLUMN_NAME), NULL);
674         gtk_tree_sortable_set_sort_func(sortable, DESKTOP_FILE_COLUMN_PATH, editor_list_window_sort_cb,
675                                         GINT_TO_POINTER(DESKTOP_FILE_COLUMN_PATH), NULL);
676         gtk_tree_sortable_set_sort_func(sortable, DESKTOP_FILE_COLUMN_DISABLED, editor_list_window_sort_cb,
677                                         GINT_TO_POINTER(DESKTOP_FILE_COLUMN_DISABLED), NULL);
678
679         /* set initial sort order */
680     gtk_tree_sortable_set_sort_column_id(sortable, DESKTOP_FILE_COLUMN_NAME, GTK_SORT_ASCENDING);
681
682         gtk_container_add(GTK_CONTAINER(scrolled), ewl->view);
683         gtk_widget_show(ewl->view);
684
685         gtk_widget_show(ewl->window);
686 }
687
688 /*
689  *-----------------------------------------------------------------------------
690  * config window show (public)
691  *-----------------------------------------------------------------------------
692  */
693
694 void show_editor_list_window(void)
695 {
696         if (editor_list_window)
697                 {
698                 gtk_window_present(GTK_WINDOW(editor_list_window));
699                 return;
700                 }
701
702         editor_list_window_create();
703 }
704 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */