New method for OAuth2 authentication and receiving of access token from David Fletche...
[claws.git] / src / prefs_toolbar.c
1 /*
2  * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3  * Copyright (C) 2002-2021 the Claws Mail team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 /*
20  * General functions for accessing address book files.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #  include "config.h"
25 #include "claws-features.h"
26 #endif
27
28 #include "defs.h"
29
30 #include <glib.h>
31 #include <glib/gi18n.h>
32 #include <gtk/gtk.h>
33 #include <gdk/gdkkeysyms.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36
37 #include "stock_pixmap.h"
38 #include "manage_window.h"
39 #include "combobox.h"
40 #include "gtkutils.h"
41 #include "mainwindow.h"
42 #include "alertpanel.h"
43 #include "prefs_common.h"
44 #include "prefs_actions.h"
45
46 #include "utils.h"
47
48 #include "toolbar.h"
49 #include "prefs_toolbar.h"
50 #include "prefswindow.h"
51 #include "prefs_gtk.h"
52 #include "plugin.h"
53 #include "messageview.h"
54
55 enum
56 {
57         SET_ICON          = 0,
58         SET_FILENAME      = 1,
59         SET_TEXT          = 2,
60         SET_EVENT         = 3,
61         SET_ICON_TEXT     = 4,          /*!< "icon" text (separator) */
62         SET_ICON_IS_TEXT  = 5,          /*!< icon is text representation */
63         N_SET_COLUMNS
64 };
65
66 enum
67 {
68         ITEM_FUNCTION     = 0,
69         ITEM_USER_ACTION  = 1,
70         ITEM_PLUGIN       = 2,
71         ITEM_SEPARATOR    = 3,
72 };
73
74 static const gint ToolbarIcons[] =
75 {
76         STOCK_PIXMAP_ADDRESS_BOOK,
77         STOCK_PIXMAP_ADDRESS_SEARCH,
78         STOCK_PIXMAP_BOOK,
79         STOCK_PIXMAP_CATEGORY,
80         STOCK_PIXMAP_CHECK_SPELLING,
81         STOCK_PIXMAP_CLOSE,
82         STOCK_PIXMAP_DOWN_ARROW,
83         STOCK_PIXMAP_UP_ARROW,
84         STOCK_PIXMAP_EDIT_EXTERN,
85         STOCK_PIXMAP_ERROR,
86         STOCK_PIXMAP_EXEC,
87         STOCK_PIXMAP_GROUP,
88         STOCK_PIXMAP_INSERT_FILE,
89         STOCK_PIXMAP_INTERFACE,
90         STOCK_PIXMAP_JPILOT,
91         STOCK_PIXMAP_LDAP,
92         STOCK_PIXMAP_LINEWRAP_CURRENT,
93         STOCK_PIXMAP_LINEWRAP_ALL,
94         STOCK_PIXMAP_MAIL_DRAFT,
95         STOCK_PIXMAP_MAIL_ATTACH,
96         STOCK_PIXMAP_MAIL_COMPOSE,
97         STOCK_PIXMAP_MAIL_FORWARD,
98         STOCK_PIXMAP_MAIL_RECEIVE,
99         STOCK_PIXMAP_MAIL_RECEIVE_ALL,
100         STOCK_PIXMAP_MAIL_REPLY,
101         STOCK_PIXMAP_MAIL_REPLY_TO_ALL,
102         STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR,
103         STOCK_PIXMAP_MAIL_REPLY_TO_LIST,
104         STOCK_PIXMAP_MAIL_SEND,
105         STOCK_PIXMAP_MAIL_SEND_QUEUE,
106         STOCK_PIXMAP_MAIL_SIGN,
107         STOCK_PIXMAP_OPEN_MAIL,
108         STOCK_PIXMAP_NEWS_COMPOSE,
109         STOCK_PIXMAP_PASTE,
110         STOCK_PIXMAP_PREFERENCES,
111         STOCK_PIXMAP_PROPERTIES,
112         STOCK_PIXMAP_VCARD,
113         STOCK_PIXMAP_ONLINE,
114         STOCK_PIXMAP_OFFLINE,
115         STOCK_PIXMAP_NOTICE_WARN,               /* small warning */
116         STOCK_PIXMAP_NOTICE_ERROR,              /* small error   */
117         STOCK_PIXMAP_NOTICE_NOTE,               /* small message */
118         STOCK_PIXMAP_GO_FOLDERS,
119         STOCK_PIXMAP_MIME_TEXT_PLAIN,
120         STOCK_PIXMAP_MIME_TEXT_HTML,
121         STOCK_PIXMAP_MIME_TEXT_PATCH,
122         STOCK_PIXMAP_MIME_APPLICATION,
123         STOCK_PIXMAP_MIME_IMAGE,
124         STOCK_PIXMAP_MIME_AUDIO,
125         STOCK_PIXMAP_MIME_TEXT_ENRICHED,
126         STOCK_PIXMAP_MIME_UNKNOWN,
127         STOCK_PIXMAP_MIME_PDF,
128         STOCK_PIXMAP_MIME_PS,
129         STOCK_PIXMAP_MIME_TEXT_CALENDAR,
130         STOCK_PIXMAP_MIME_PGP_SIG,
131         STOCK_PIXMAP_PRINTER_BTN,
132         STOCK_PIXMAP_PRIVACY_SIGNED,
133         STOCK_PIXMAP_PRIVACY_PASSED,
134         STOCK_PIXMAP_PRIVACY_FAILED,
135         STOCK_PIXMAP_PRIVACY_UNKNOWN,
136         STOCK_PIXMAP_PRIVACY_EXPIRED,
137         STOCK_PIXMAP_PRIVACY_WARN,
138         STOCK_PIXMAP_PRIVACY_EMBLEM_SIGNED,
139         STOCK_PIXMAP_PRIVACY_EMBLEM_PASSED,
140         STOCK_PIXMAP_PRIVACY_EMBLEM_FAILED,
141         STOCK_PIXMAP_PRIVACY_EMBLEM_WARN,
142         STOCK_PIXMAP_MIME_MESSAGE,
143         STOCK_PIXMAP_SPAM_BTN,
144         STOCK_PIXMAP_HAM_BTN,
145         STOCK_PIXMAP_TRASH,
146         STOCK_PIXMAP_DELETE,
147         STOCK_PIXMAP_DELETE_DUP,
148         STOCK_PIXMAP_CANCEL,
149         STOCK_PIXMAP_MARK_IGNORETHREAD,
150         STOCK_PIXMAP_MARK_WATCHTHREAD,
151         STOCK_PIXMAP_MARK_MARK,
152         STOCK_PIXMAP_MARK_UNMARK,
153         STOCK_PIXMAP_MARK_LOCKED,
154         STOCK_PIXMAP_MARK_UNLOCKED,
155         STOCK_PIXMAP_MARK_ALLREAD,
156         STOCK_PIXMAP_MARK_ALLUNREAD,
157         STOCK_PIXMAP_MARK_READ,
158         STOCK_PIXMAP_MARK_UNREAD,
159         STOCK_PIXMAP_DIR_OPEN,
160         STOCK_PIXMAP_EMPTY,              /* last entry */
161 };
162
163 typedef struct _ToolbarPage
164 {
165         PrefsPage  page;
166
167         GtkWidget *window;              /* do not modify */
168
169         ToolbarType source;
170         GList     *combo_action_list;   /* list of internal functions    */
171
172         GtkWidget *list_view_set;       /* toolbar items treeview        */
173         GtkWidget *item_text_entry;     /* item name                     */
174         GtkWidget *item_type_combo;     /* item type selection widget    */
175         GtkWidget *item_func_combo;     /* item internal function widget */
176         GtkWidget *item_action_combo;   /* item user action widget       */
177         GtkWidget *item_plugin_combo;   /* items registered by plugins */
178         GtkWidget *icon_button;         /* item icon chooser widget      */
179
180         GtkWidget *icon_chooser_win;
181         GtkWidget *icon_chooser_view;
182
183         gchar *item_icon_file;          /* item icon file                */
184
185 } ToolbarPage;
186
187 #define ERROR_MSG _("Selected Action already set.\nPlease choose another Action from List")
188 #define ERROR_MSG_NO_ICON _("Item has no icon defined.")
189 #define ERROR_MSG_NO_TEXT _("Item has no text defined.")
190
191 typedef struct _ToolbarPluginItem ToolbarPluginItem;
192 struct _ToolbarPluginItem {
193         gchar *plugin;
194         gchar *item_name;
195         ToolbarPluginCallback cb;
196         gpointer cb_data;
197 };
198
199 /* items registered by plugins */
200 static GHashTable *plugin_items_mainwin = NULL;
201 static GHashTable *plugin_items_compose = NULL;
202 static GHashTable *plugin_items_msgview = NULL;
203
204 static void prefs_toolbar_populate               (ToolbarPage *prefs_toolbar);
205
206 static void get_action_name                      (const gchar *entry,
207                                                   gchar **menu);
208
209 static gboolean is_duplicate                     (ToolbarPage *prefs_toolbar,
210                                                   gchar            *chosen_action);
211 static void prefs_toolbar_save                   (PrefsPage        *_page);
212
213 static void prefs_toolbar_register               (GtkButton        *button,
214                                                   ToolbarPage *prefs_toolbar);
215 static void prefs_toolbar_substitute             (GtkButton        *button,
216                                                   ToolbarPage *prefs_toolbar);
217 static void prefs_toolbar_delete                 (GtkButton        *button,
218                                                   ToolbarPage *prefs_toolbar);
219
220 static void prefs_toolbar_up                     (GtkButton        *button,
221                                                   ToolbarPage *prefs_toolbar);
222
223 static void prefs_toolbar_down                   (GtkButton        *button,
224                                                   ToolbarPage *prefs_toolbar);
225
226 static void action_selection_changed             (GtkComboBox *action_combo,
227                                                   ToolbarPage *prefs_toolbar);
228 static void plugin_selection_changed             (GtkComboBox *action_combo,
229                                                   ToolbarPage *prefs_toolbar);
230
231 static void func_selection_changed               (GtkComboBox *action_combo,
232                                                   ToolbarPage *prefs_toolbar);
233
234 static void prefs_toolbar_create                 (ToolbarPage *prefs_toolbar);
235
236 static GtkWidget *create_set_list_view           (ToolbarPage *prefs_toolbar);
237
238 static gboolean set_list_selected                (GtkTreeSelection *selector,
239                                                   GtkTreeModel *model,
240                                                   GtkTreePath *path,
241                                                   gboolean currently_selected,
242                                                   ToolbarPage *prefs_toolbar);
243
244 static void icon_chooser_create                  (GtkButton *button,
245                                                   ToolbarPage *prefs_toolbar);
246
247
248 static GHashTable** get_plugin_hash_from_toolbar_type(ToolbarType toolbar_type)
249 {
250         if (toolbar_type == TOOLBAR_MAIN)
251                 return &plugin_items_mainwin;
252         else if (toolbar_type == TOOLBAR_COMPOSE)
253                 return &plugin_items_compose;
254         else if (toolbar_type == TOOLBAR_MSGVIEW)
255                 return &plugin_items_msgview;
256         else
257                 return NULL;
258 }
259
260 static void prefs_toolbar_create_widget(PrefsPage *_page, GtkWindow *window, gpointer data)
261 {
262         ToolbarPage *prefs_toolbar = (ToolbarPage *) _page;
263
264         prefs_toolbar->window = GTK_WIDGET(window);
265
266         toolbar_read_config_file(prefs_toolbar->source);
267
268         prefs_toolbar_create(prefs_toolbar);
269         prefs_toolbar_populate(prefs_toolbar);
270 }
271
272 static void prefs_toolbar_save(PrefsPage *_page)
273 {
274         ToolbarPage *prefs_toolbar = (ToolbarPage *) _page;
275         GtkTreeView *list_view = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
276         GtkTreeModel *model = gtk_tree_view_get_model(list_view);
277         GtkTreeIter iter;
278
279         toolbar_clear_list(prefs_toolbar->source);
280
281         if (!gtk_tree_model_iter_n_children(model, NULL)
282         ||  !gtk_tree_model_get_iter_first(model, &iter))
283                 toolbar_set_default(prefs_toolbar->source);
284         else {
285                 do {
286                         ToolbarItem *item;
287                         gchar *fname, *text, *event;
288
289                         item = g_new0(ToolbarItem, 1);
290
291                         gtk_tree_model_get(model, &iter,
292                                            SET_FILENAME, &fname,
293                                            SET_TEXT, &text,
294                                            SET_EVENT, &event,
295                                            -1);
296
297                         /* XXX: remember that G_TYPE_STRING returned by model
298                          * is owned by caller of gtk_tree_model_get() */
299                         item->file  = fname;
300                         item->text  = text;
301                         item->index = toolbar_ret_val_from_descr(event);
302                         g_free(event);
303
304                         toolbar_set_list_item(item, prefs_toolbar->source);
305
306                         g_free(item->file);
307                         g_free(item->text);
308                         g_free(item);
309                 } while (gtk_tree_model_iter_next(model, &iter));
310         }
311
312         toolbar_save_config_file(prefs_toolbar->source);
313
314         if (prefs_toolbar->source == TOOLBAR_MAIN)
315                 toolbar_update(TOOLBAR_MAIN, mainwindow_get_mainwindow());
316         else if (prefs_toolbar->source == TOOLBAR_COMPOSE)
317                 compose_reflect_prefs_pixmap_theme();
318         else if (prefs_toolbar->source == TOOLBAR_MSGVIEW)
319                 messageview_reflect_prefs_pixmap_theme();
320 }
321
322 static void prefs_toolbar_destroy_widget(PrefsPage *_page)
323 {
324         ToolbarPage *prefs_toolbar = (ToolbarPage *) _page;
325
326         g_list_free(prefs_toolbar->combo_action_list);
327         prefs_toolbar->combo_action_list = NULL;
328 }
329
330 static void prefs_toolbar_set_displayed(ToolbarPage *prefs_toolbar)
331 {
332         GSList *cur;
333         GtkTreeView *list_view_set = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
334         GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model
335                                                 (list_view_set));
336         GSList *toolbar_list = toolbar_get_list(prefs_toolbar->source);
337         GtkTreeIter iter;
338
339         gtk_list_store_clear(store);
340
341         /* set currently active toolbar entries */
342         for (cur = toolbar_list; cur != NULL; cur = cur->next) {
343                 ToolbarItem *item = (ToolbarItem*) cur->data;
344
345                 gtk_list_store_append(store, &iter);
346
347                 if (item->index != A_SEPARATOR) {
348                         GdkPixbuf *pix;
349                         StockPixmap icon = stock_pixmap_get_icon(item->file);
350
351                         stock_pixbuf_gdk(icon, &pix);
352
353                         gtk_list_store_set(store, &iter,
354                                            SET_ICON, pix,
355                                            SET_FILENAME, item->file,
356                                            SET_TEXT, item->text,
357                                            SET_EVENT, toolbar_ret_descr_from_val(item->index),
358                                            SET_ICON_TEXT, NULL,
359                                            SET_ICON_IS_TEXT, FALSE,
360                                            -1);
361                 } else {
362                         gtk_list_store_set(store, &iter,
363                                            SET_ICON, NULL,
364                                            SET_FILENAME, toolbar_ret_descr_from_val(A_SEPARATOR),
365                                            SET_TEXT, (const gchar *) "",
366                                            SET_EVENT, toolbar_ret_descr_from_val(A_SEPARATOR),
367                                            SET_ICON_TEXT, (const gchar *) SEPARATOR_PIXMAP,
368                                            SET_ICON_IS_TEXT, TRUE,
369                                            -1);
370                 }
371         }
372
373         /* select first */
374         if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) {
375                 gtk_tree_selection_select_iter(gtk_tree_view_get_selection
376                                                         (list_view_set),
377                                                &iter);
378         }
379 }
380
381 static void add_item_to_plugin_combo(gpointer key, gpointer data, gpointer combo_box)
382 {
383         gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), (const gchar*)key);
384 }
385
386 static void prefs_toolbar_populate(ToolbarPage *prefs_toolbar)
387 {
388         GSList *cur;
389         gchar *act, *act_name;
390         GHashTable **hash;
391
392         prefs_toolbar->combo_action_list = toolbar_get_action_items(prefs_toolbar->source);
393         combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(prefs_toolbar->item_func_combo),
394                                      prefs_toolbar->combo_action_list);
395
396         /* get currently defined actions */
397         if (prefs_common.actions_list != NULL) {
398                 for (cur = prefs_common.actions_list; cur != NULL; cur = cur->next) {
399                         act = (gchar *)cur->data;
400                         get_action_name(act, &act_name);
401
402                         gtk_combo_box_text_append_text(
403                                 GTK_COMBO_BOX_TEXT(prefs_toolbar->item_action_combo),
404                                 act_name);
405
406                         g_free(act_name);
407                 }
408
409         } else
410                 combobox_set_sensitive(GTK_COMBO_BOX(prefs_toolbar->item_type_combo),
411                                         ITEM_USER_ACTION, FALSE);
412
413         /* items registered by plugins */
414         hash = get_plugin_hash_from_toolbar_type(prefs_toolbar->source);
415         if (hash && *hash)
416                 g_hash_table_foreach(*hash, add_item_to_plugin_combo,
417                                 prefs_toolbar->item_plugin_combo);
418         else
419                 combobox_set_sensitive(GTK_COMBO_BOX(prefs_toolbar->item_type_combo),
420                                         ITEM_PLUGIN, FALSE);
421
422         gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_func_combo), 0);
423         gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_action_combo), 0);
424         gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_plugin_combo), 0);
425
426         prefs_toolbar_set_displayed(prefs_toolbar);
427
428         toolbar_clear_list(prefs_toolbar->source);
429 }
430
431 static gboolean is_duplicate(ToolbarPage *prefs_toolbar, gchar *chosen_action)
432 {
433         GtkTreeView *list_view_set = GTK_TREE_VIEW
434                                         (prefs_toolbar->list_view_set);
435         GtkTreeModel *model_set = gtk_tree_view_get_model(list_view_set);
436         gchar *entry;
437         GtkTreeIter iter;
438         gboolean result;
439
440         cm_return_val_if_fail(chosen_action != NULL, TRUE);
441
442         if (!gtk_tree_model_iter_n_children(model_set, NULL))
443                 return FALSE;
444
445         if (!gtk_tree_model_get_iter_first(model_set, &iter))
446                 return FALSE;
447
448         result = FALSE;
449         do {
450                 gtk_tree_model_get(model_set, &iter,
451                                    SET_EVENT, &entry,
452                                    -1);
453                 if (g_utf8_collate(chosen_action, entry) == 0)
454                         result = TRUE;
455                 g_free(entry);
456         } while (!result && gtk_tree_model_iter_next(model_set, &iter));
457
458         return result;
459 }
460
461 static void prefs_toolbar_default(GtkButton *button, ToolbarPage *prefs_toolbar)
462 {
463         toolbar_clear_list(prefs_toolbar->source);
464         toolbar_set_default(prefs_toolbar->source);
465         prefs_toolbar_set_displayed(prefs_toolbar);
466 }
467
468 /*!
469  *\return       String that should be freed by caller.
470  */
471 static void get_action_name(const gchar *entry, gchar **menu)
472 {
473         gchar *act, *act_p;
474
475         *menu = NULL;
476
477         if (prefs_common.actions_list != NULL) {
478
479                 act = g_strdup(entry);
480                 act_p = strstr(act, ": ");
481                 if (act_p != NULL)
482                         act_p[0] = 0x00;
483                 /* freed by calling func */
484                 *menu = act;
485         }
486 }
487
488 static void prefs_toolbar_register(GtkButton *button, ToolbarPage *prefs_toolbar)
489 {
490         GtkTreeView *list_view_set   = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
491         gint item_type = gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo));
492         GtkListStore *store_set;
493         GtkTreeIter iter;
494
495         store_set = GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set));
496
497         /* SEPARATOR or other ? */
498         if (item_type == ITEM_SEPARATOR) {
499                 gtk_list_store_append(store_set, &iter);
500                 gtk_list_store_set(store_set, &iter,
501                                    SET_ICON, NULL,
502                                    SET_FILENAME, prefs_toolbar->item_icon_file,
503                                    SET_TEXT, NULL,
504                                    SET_EVENT, toolbar_ret_descr_from_val(A_SEPARATOR),
505                                    SET_ICON_TEXT, (const gchar *) SEPARATOR_PIXMAP,
506                                    SET_ICON_IS_TEXT, TRUE,
507                                    -1);
508         } else {
509                 GdkPixbuf *pixbuf;
510                 gchar *event, *text;
511
512                 if (prefs_toolbar->item_icon_file == NULL) {
513                         alertpanel_error(ERROR_MSG_NO_ICON);
514                         return;
515                 }
516                 stock_pixbuf_gdk(
517                                 stock_pixmap_get_icon(prefs_toolbar->item_icon_file),
518                                 &pixbuf);
519                 if(pixbuf == NULL) {
520                         alertpanel_error(ERROR_MSG_NO_ICON);
521                         return;
522                 }
523
524                 if (item_type == ITEM_FUNCTION) {
525                         event = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
526                                                 prefs_toolbar->item_func_combo));
527
528                         if (is_duplicate(prefs_toolbar, event)) {
529                                 alertpanel_error(ERROR_MSG);
530                                 g_free(event);
531                                 return;
532                         }
533                 } else if(item_type == ITEM_PLUGIN)
534                   event = toolbar_ret_descr_from_val(A_CLAWS_PLUGINS);
535                 else
536                         event = toolbar_ret_descr_from_val(A_CLAWS_ACTIONS);
537
538                 text = gtk_editable_get_chars(
539                         GTK_EDITABLE(prefs_toolbar->item_text_entry), 0 , -1);
540
541                 if (text != NULL) {
542                         gtk_list_store_append(store_set, &iter);
543                         gtk_list_store_set(store_set, &iter,
544                                            SET_ICON, pixbuf,
545                                            SET_FILENAME, prefs_toolbar->item_icon_file,
546                                            SET_TEXT, text,
547                                            SET_EVENT, event,
548                                            SET_ICON_TEXT, NULL,
549                                            SET_ICON_IS_TEXT, FALSE,
550                                            -1);
551                 } else {
552                         alertpanel_error(ERROR_MSG_NO_TEXT);
553                         return;
554                 }
555
556                 g_free(text);
557                 if((item_type != ITEM_USER_ACTION) && (item_type != ITEM_PLUGIN))
558                         g_free(event);
559         }
560
561         gtk_tree_selection_select_iter(gtk_tree_view_get_selection
562                                                 (list_view_set),
563                                        &iter);
564 }
565
566 static void prefs_toolbar_substitute(GtkButton *button, ToolbarPage *prefs_toolbar)
567 {
568         GtkTreeView *list_view_set   = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
569         GtkListStore *store_set   = GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set));
570         gint item_type = gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo));
571         GtkTreeSelection *sel_set;
572         GtkTreeIter iter_set;
573
574         if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set), NULL))
575                 return;
576
577         sel_set = gtk_tree_view_get_selection(list_view_set);
578         if (!gtk_tree_selection_get_selected(sel_set, NULL, &iter_set))
579                 return;
580
581         if (item_type == ITEM_SEPARATOR) {
582                 gtk_list_store_set(store_set, &iter_set,
583                                    SET_ICON, NULL,
584                                    SET_TEXT, NULL,
585                                    SET_EVENT, toolbar_ret_descr_from_val(A_SEPARATOR),
586                                    SET_FILENAME, prefs_toolbar->item_icon_file,
587                                    SET_ICON_TEXT, (const gchar *) SEPARATOR_PIXMAP,
588                                    SET_ICON_IS_TEXT, TRUE,
589                                    -1);
590         } else {
591                 GdkPixbuf *pixbuf;
592                 gchar *icon_event, *set_event, *text;
593
594                 if (prefs_toolbar->item_icon_file == NULL) {
595                         alertpanel_error(ERROR_MSG_NO_ICON);
596                         return;
597                 }
598                 stock_pixbuf_gdk(
599                                  stock_pixmap_get_icon(prefs_toolbar->item_icon_file),
600                                  &pixbuf);
601                 if(pixbuf == NULL) {
602                         alertpanel_error(ERROR_MSG_NO_ICON);
603                         return;
604                 }
605
606                 gtk_tree_model_get(GTK_TREE_MODEL(store_set), &iter_set,
607                                                   SET_EVENT, &set_event,
608                                                   -1);
609
610                 if (item_type == ITEM_FUNCTION) {
611                         icon_event = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
612                                                 prefs_toolbar->item_func_combo));
613
614                         if (is_duplicate(prefs_toolbar, icon_event)
615                         && g_utf8_collate(icon_event, set_event) != 0){
616                                 alertpanel_error(ERROR_MSG);
617                                 g_free(icon_event);
618                                 g_free(set_event);
619                                 return;
620                         }
621                 } else if(item_type == ITEM_PLUGIN)
622                         icon_event = toolbar_ret_descr_from_val(A_CLAWS_PLUGINS);
623                 else
624                         icon_event = toolbar_ret_descr_from_val(A_CLAWS_ACTIONS);
625
626                 text = gtk_editable_get_chars(
627                         GTK_EDITABLE(prefs_toolbar->item_text_entry), 0 , -1);
628
629                 /* change the row */
630                 if (text != NULL) {
631                         gtk_list_store_set(store_set, &iter_set,
632                                            SET_ICON, pixbuf,
633                                            SET_FILENAME, prefs_toolbar->item_icon_file,
634                                            SET_TEXT, text,
635                                            SET_EVENT, icon_event,
636                                            SET_ICON_TEXT, NULL,
637                                            SET_ICON_IS_TEXT, FALSE,
638                                            -1);
639                 } else
640                         alertpanel_error(ERROR_MSG_NO_TEXT);
641
642                 g_free(text);
643                 g_free(set_event);
644                 if((item_type != ITEM_USER_ACTION) && (item_type != ITEM_PLUGIN))
645                         g_free(icon_event);
646         }
647 }
648
649 static void prefs_toolbar_delete(GtkButton *button, ToolbarPage *prefs_toolbar)
650 {
651         GtkTreeView *list_view_set = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
652         GtkTreeModel *store_set = gtk_tree_view_get_model(list_view_set);
653         GtkTreeIter iter_set;
654         GtkTreePath *path;
655
656         if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set), NULL))
657                 return;
658
659         if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
660                                                         (list_view_set),
661                                              NULL,
662                                              &iter_set))
663                 return;
664
665         /* select prev list item, if deleted was first select next */
666         path = gtk_tree_model_get_path(store_set, &iter_set);
667         gtk_tree_path_prev(path);
668
669         gtk_list_store_remove(GTK_LIST_STORE(store_set), &iter_set);
670
671         gtk_tree_selection_select_path(
672                         gtk_tree_view_get_selection(list_view_set),
673                         path);
674
675         gtk_tree_path_free(path);
676 }
677
678 static void prefs_toolbar_up(GtkButton *button, ToolbarPage *prefs_toolbar)
679 {
680         GtkTreePath *prev, *sel;
681         GtkTreeIter isel;
682         GtkListStore *store = NULL;
683         GtkTreeModel *model = NULL;
684         GtkTreeIter iprev;
685
686         if (!gtk_tree_selection_get_selected
687                 (gtk_tree_view_get_selection
688                         (GTK_TREE_VIEW(prefs_toolbar->list_view_set)),
689                  &model,
690                  &isel))
691                 return;
692         store = (GtkListStore *)model;
693
694         sel = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &isel);
695         if (!sel)
696                 return;
697
698         /* no move if we're at row 0... */
699         prev = gtk_tree_path_copy(sel);
700         if (!gtk_tree_path_prev(prev)) {
701                 gtk_tree_path_free(prev);
702                 gtk_tree_path_free(sel);
703                 return;
704         }
705
706         gtk_tree_model_get_iter(GTK_TREE_MODEL(store),
707                                 &iprev, prev);
708         gtk_tree_path_free(sel);
709         gtk_tree_path_free(prev);
710
711         gtk_list_store_swap(store, &iprev, &isel);
712 }
713
714 static void prefs_toolbar_down(GtkButton *button, ToolbarPage *prefs_toolbar)
715 {
716         GtkListStore *store = NULL;
717         GtkTreeModel *model = NULL;
718         GtkTreeIter next, sel;
719
720         if (!gtk_tree_selection_get_selected
721                 (gtk_tree_view_get_selection
722                         (GTK_TREE_VIEW(prefs_toolbar->list_view_set)),
723                  &model,
724                  &sel))
725                 return;
726
727         store = (GtkListStore *)model;
728         next = sel;
729         if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &next))
730                 return;
731
732         gtk_list_store_swap(store, &next, &sel);
733 }
734
735 static void item_type_changed(GtkComboBox *item_type_combo,
736                                 ToolbarPage *prefs_toolbar)
737 {
738         gint active = gtk_combo_box_get_active(item_type_combo);
739
740         switch(active) {
741         case ITEM_FUNCTION:
742                 gtk_widget_show(prefs_toolbar->item_func_combo);
743                 gtk_widget_hide(prefs_toolbar->item_action_combo);
744                 gtk_widget_hide(prefs_toolbar->item_plugin_combo);
745                 gtk_combo_box_set_active(
746                         GTK_COMBO_BOX(prefs_toolbar->item_func_combo), 0);
747                 gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
748                 gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, TRUE);
749                 gtk_widget_set_sensitive(prefs_toolbar->item_func_combo, TRUE);
750                 gtk_widget_set_sensitive(prefs_toolbar->icon_button, TRUE);
751
752                 func_selection_changed(GTK_COMBO_BOX(prefs_toolbar->item_func_combo),
753                                         prefs_toolbar);
754                 break;
755         case ITEM_USER_ACTION:
756                 gtk_widget_show(prefs_toolbar->item_action_combo);
757                 gtk_widget_hide(prefs_toolbar->item_func_combo);
758                 gtk_widget_hide(prefs_toolbar->item_plugin_combo);
759                 gtk_combo_box_set_active(
760                         GTK_COMBO_BOX(prefs_toolbar->item_action_combo), 0);
761                 gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
762                 gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, FALSE);
763                 gtk_widget_set_sensitive(prefs_toolbar->item_action_combo, TRUE);
764                 gtk_widget_set_sensitive(prefs_toolbar->icon_button, TRUE);
765
766                 action_selection_changed(GTK_COMBO_BOX(prefs_toolbar->item_action_combo),
767                                         prefs_toolbar);
768                 break;
769         case ITEM_SEPARATOR:
770                 gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), _("None"));
771                 gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button), NULL);
772                 g_free(prefs_toolbar->item_icon_file);
773                 prefs_toolbar->item_icon_file = NULL;
774                 gtk_combo_box_set_active(
775                         GTK_COMBO_BOX(prefs_toolbar->item_func_combo), -1);
776                 gtk_combo_box_set_active(
777                         GTK_COMBO_BOX(prefs_toolbar->item_action_combo), -1);
778                 gtk_combo_box_set_active(
779                         GTK_COMBO_BOX(prefs_toolbar->item_plugin_combo), -1);
780                 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry), "");
781                 gtk_widget_set_sensitive(prefs_toolbar->item_action_combo, FALSE);
782                 gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, FALSE);
783                 gtk_widget_set_sensitive(prefs_toolbar->item_plugin_combo, FALSE);
784                 gtk_widget_set_sensitive(prefs_toolbar->item_func_combo, FALSE);
785                 gtk_widget_set_sensitive(prefs_toolbar->icon_button, FALSE);
786                 break;
787           case ITEM_PLUGIN:
788                 gtk_widget_show(prefs_toolbar->item_plugin_combo);
789                 gtk_widget_hide(prefs_toolbar->item_func_combo);
790                 gtk_widget_hide(prefs_toolbar->item_action_combo);
791                 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_plugin_combo), 0);
792                 gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
793                 gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, FALSE);
794                 gtk_widget_set_sensitive(prefs_toolbar->item_plugin_combo, TRUE);
795                 gtk_widget_set_sensitive(prefs_toolbar->icon_button, TRUE);
796                 plugin_selection_changed(GTK_COMBO_BOX(prefs_toolbar->item_plugin_combo), prefs_toolbar);
797                 break;
798         }
799
800 }
801
802 static void action_selection_changed(GtkComboBox *action_combo,
803                                 ToolbarPage *prefs_toolbar)
804 {
805         gchar *text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
806                            prefs_toolbar->item_action_combo));
807
808         if(text != NULL) { /* action */
809                 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry), text);
810                 g_free(text);
811         }
812 }
813
814 static void plugin_selection_changed(GtkComboBox *action_combo,
815                 ToolbarPage *prefs_toolbar)
816 {
817         gchar *text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(prefs_toolbar->item_plugin_combo));
818
819         if (text != NULL) { /* action */
820                 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry), text);
821                 g_free(text);
822         }
823 }
824
825 static void func_selection_changed(GtkComboBox *action_combo,
826                                 ToolbarPage *prefs_toolbar)
827 {
828         gchar *text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
829                            prefs_toolbar->item_func_combo));
830
831         if(text != NULL) { /* action */
832                 int action;
833
834                 action = toolbar_ret_val_from_descr(text);
835                 g_free(text);
836                 if (action > -1) {
837                         gint icon;
838
839                         gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry),
840                                         toolbar_get_short_text(action));
841                         icon = toolbar_get_icon(action);
842                         if (icon > -1)  {
843                                 StockPixmap stockp = (StockPixmap)icon;
844                                 g_free(prefs_toolbar->item_icon_file);
845                                 prefs_toolbar->item_icon_file = g_strdup(stock_pixmap_get_name(stockp));
846
847                                 gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button),
848                                      stock_pixmap_widget(stockp));
849                         }
850                 }
851         }
852 }
853
854 static void prefs_toolbar_create(ToolbarPage *prefs_toolbar)
855 {
856         GtkWidget *main_vbox;
857         GtkWidget *toolbar_item_hbox;
858         GtkWidget *icon_vbox;
859         GtkWidget *icon_label;
860         GtkWidget *icon_button;
861         GtkWidget *icon_hbox;
862         GtkWidget *item_type_combo;
863         GtkListStore *item_type_model;
864         GtkTreeIter iter;
865         GtkWidget *item_action_combo;
866         GtkWidget *item_plugin_combo;
867         GtkWidget *item_func_combo;
868         GtkWidget *reg_hbox;
869         GtkWidget *arrow;
870         GtkWidget *btn_hbox;
871 #ifdef GENERIC_UMPC
872         GtkWidget *hbox;
873 #endif
874         GtkWidget *reg_btn;
875         GtkWidget *subst_btn;
876         GtkWidget *del_btn;
877         GtkWidget *default_btn;
878         GtkWidget *vbox_frame;
879         GtkWidget *table;
880         GtkWidget *label_icon_text;
881         GtkWidget *item_text_entry;
882         GtkWidget *vbox_toolbar_items;
883         GtkWidget *hbox_bottom;
884         GtkWidget *scrolledwindow_list_view_set;
885         GtkWidget *list_view_set;
886         GtkWidget *label;
887
888         GtkWidget *btn_vbox;
889         GtkWidget *up_btn;
890         GtkWidget *down_btn;
891
892         debug_print("Creating custom toolbar window...\n");
893
894         main_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
895         gtk_widget_show(main_vbox);
896
897         PACK_FRAME (main_vbox, vbox_frame, _("Toolbar item"))
898         gtk_container_set_border_width(GTK_CONTAINER(vbox_frame), 8);
899         gtk_widget_show(vbox_frame);
900
901         toolbar_item_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
902         gtk_widget_show(toolbar_item_hbox);
903         gtk_container_add(GTK_CONTAINER (vbox_frame), toolbar_item_hbox);
904
905         table = gtk_grid_new();
906         gtk_container_set_border_width (GTK_CONTAINER (table), 8);
907         gtk_grid_set_row_spacing(GTK_GRID(table), 8);
908         gtk_grid_set_column_spacing(GTK_GRID(table), 8);
909
910         gtk_box_pack_start(GTK_BOX(toolbar_item_hbox), table,
911                            TRUE, TRUE, 0);
912
913         /* toolbar item type */
914         label = gtk_label_new(_("Item type"));
915         gtk_label_set_xalign(GTK_LABEL(label), 0.0);
916         gtk_widget_show(label);
917         gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
918
919         item_type_combo = gtkut_sc_combobox_create(NULL, TRUE);
920         item_type_model = GTK_LIST_STORE(gtk_combo_box_get_model(
921                                          GTK_COMBO_BOX(item_type_combo)));
922         COMBOBOX_ADD(item_type_model, _("Internal Function"), ITEM_FUNCTION);
923         COMBOBOX_ADD(item_type_model, _("User Action"), ITEM_USER_ACTION);
924         COMBOBOX_ADD(item_type_model, _("Plugins"), ITEM_PLUGIN);
925         COMBOBOX_ADD(item_type_model, _("Separator"), ITEM_SEPARATOR);
926         gtk_widget_set_size_request(item_type_combo, 200, -1);
927         gtk_grid_attach(GTK_GRID(table), item_type_combo, 1, 0, 1, 1);
928
929         /* available actions */
930         label = gtk_label_new(_("Event executed on click"));
931         gtk_label_set_xalign(GTK_LABEL(label), 0.0);
932         gtk_grid_attach(GTK_GRID(table), label, 0, 1, 1, 1);
933
934         item_action_combo = gtk_combo_box_text_new();
935         gtk_widget_set_size_request(item_action_combo, 200, -1);
936         gtk_grid_attach(GTK_GRID(table), item_action_combo, 1, 1, 1, 1);
937
938         /* available internal functions */
939         item_func_combo = gtk_combo_box_text_new();
940         gtk_widget_set_size_request(item_func_combo, 200, -1);
941         gtk_grid_attach(GTK_GRID(table), item_func_combo, 1, 1, 1, 1);
942
943         /* plugin-registered items */
944         item_plugin_combo = gtk_combo_box_text_new();
945         gtk_widget_set_size_request(item_plugin_combo, 200, -1);
946         gtk_grid_attach(GTK_GRID(table), item_plugin_combo, 1, 1, 1, 1);
947
948         /* toolbar item description */
949         label_icon_text = gtk_label_new(_("Toolbar text"));
950         gtk_label_set_xalign(GTK_LABEL(label_icon_text), 0.0);
951         gtk_widget_show (label_icon_text);
952         gtk_grid_attach(GTK_GRID(table), label_icon_text, 0, 2, 1, 1);
953
954         item_text_entry = gtk_entry_new();
955         gtk_grid_attach(GTK_GRID(table), item_text_entry, 1, 2, 1, 1);
956         gtk_widget_set_hexpand(item_text_entry, TRUE);
957         gtk_widget_set_halign(item_text_entry, GTK_ALIGN_FILL);
958
959         icon_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, VBOX_BORDER);
960         gtk_widget_show(icon_vbox);
961
962         icon_label = gtk_label_new(_("Icon"));
963         gtk_widget_set_size_request(icon_label, 100, -1);
964         gtk_box_pack_start(GTK_BOX(icon_vbox), icon_label, FALSE, FALSE, 0);
965
966         icon_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
967         gtk_widget_show(icon_hbox);
968
969         label = gtk_label_new("");
970         gtk_box_pack_start(GTK_BOX(icon_hbox), label, TRUE, TRUE, 0);
971
972         icon_button = gtk_button_new();
973         gtk_widget_show(icon_button);
974         gtk_widget_set_size_request(icon_button, 50, 50);
975         g_signal_connect(G_OBJECT(icon_button), "clicked",
976                          G_CALLBACK(icon_chooser_create), prefs_toolbar);
977         gtk_box_pack_start(GTK_BOX(icon_hbox), icon_button, FALSE, FALSE, 8);
978
979         label = gtk_label_new("");
980         gtk_box_pack_start(GTK_BOX(icon_hbox), label, TRUE, TRUE, 0);
981
982         gtk_box_pack_start(GTK_BOX(icon_vbox), icon_hbox, FALSE, FALSE, 0);
983
984         gtk_box_pack_start(GTK_BOX(toolbar_item_hbox), icon_vbox, FALSE, FALSE, 0);
985
986         /* register / substitute / delete */
987         reg_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
988         gtk_box_pack_start(GTK_BOX(main_vbox), reg_hbox, FALSE, FALSE, 0);
989         gtk_container_set_border_width(GTK_CONTAINER(reg_hbox), 10);
990
991         arrow = gtk_image_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_MENU);
992         gtk_box_pack_start(GTK_BOX(reg_hbox), arrow, FALSE, FALSE, 0);
993         gtk_widget_set_size_request(arrow, -1, 16);
994
995         btn_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
996         gtk_box_pack_start(GTK_BOX(reg_hbox), btn_hbox, FALSE, FALSE, 0);
997
998         reg_btn = gtkut_stock_button("list-add", _("_Add"));
999         gtk_box_pack_start(GTK_BOX(btn_hbox), reg_btn, FALSE, TRUE, 0);
1000         g_signal_connect(G_OBJECT(reg_btn), "clicked",
1001                          G_CALLBACK(prefs_toolbar_register),
1002                          prefs_toolbar);
1003
1004         subst_btn = gtkut_get_replace_btn(_("_Replace"));
1005         gtk_box_pack_start(GTK_BOX(btn_hbox), subst_btn, FALSE, TRUE, 0);
1006         g_signal_connect(G_OBJECT(subst_btn), "clicked",
1007                          G_CALLBACK(prefs_toolbar_substitute),
1008                          prefs_toolbar);
1009
1010         del_btn = gtkut_stock_button("edit-delete", _("D_elete"));
1011         gtk_box_pack_start(GTK_BOX(btn_hbox), del_btn, FALSE, TRUE, 0);
1012         g_signal_connect(G_OBJECT(del_btn), "clicked",
1013                          G_CALLBACK(prefs_toolbar_delete),
1014                           prefs_toolbar);
1015
1016         default_btn = gtk_button_new_with_label(_(" Use default "));
1017 #ifndef GENERIC_UMPC
1018         gtk_box_pack_end(GTK_BOX(reg_hbox), default_btn, FALSE, TRUE, 0);
1019 #else
1020         hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1021         gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);
1022         gtk_box_pack_start(GTK_BOX(hbox), default_btn, FALSE, FALSE, 0);
1023 #endif
1024         g_signal_connect(G_OBJECT(default_btn), "clicked",
1025                          G_CALLBACK(prefs_toolbar_default),
1026                          prefs_toolbar);
1027
1028         /* currently active toolbar items */
1029         vbox_toolbar_items = gtk_box_new(GTK_ORIENTATION_VERTICAL, VBOX_BORDER);
1030         gtk_box_pack_start(GTK_BOX(main_vbox), vbox_toolbar_items, TRUE, TRUE, 0);
1031
1032         hbox_bottom = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1033         gtk_container_add(GTK_CONTAINER(vbox_toolbar_items), hbox_bottom);
1034
1035         scrolledwindow_list_view_set = gtk_scrolled_window_new(NULL, NULL);
1036         gtk_box_pack_start(GTK_BOX(hbox_bottom), scrolledwindow_list_view_set, TRUE, TRUE, 0);
1037         gtk_container_set_border_width(GTK_CONTAINER(scrolledwindow_list_view_set), 8);
1038         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set),
1039                                         GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1040         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set),
1041                                             GTK_SHADOW_IN);
1042         gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set), TRUE);
1043
1044         list_view_set = create_set_list_view(prefs_toolbar);
1045         gtk_widget_show(list_view_set);
1046         gtk_container_add(GTK_CONTAINER(scrolledwindow_list_view_set), list_view_set);
1047         gtk_widget_set_vexpand(list_view_set, TRUE);
1048         gtk_widget_set_hexpand(list_view_set, TRUE);
1049
1050         btn_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1051         gtk_widget_show(btn_vbox);
1052         gtk_box_pack_start(GTK_BOX(hbox_bottom), btn_vbox, FALSE, FALSE, 0);
1053
1054         up_btn = gtkut_stock_button("go-up", _("_Up"));
1055         gtk_widget_show(up_btn);
1056         gtk_box_pack_start(GTK_BOX(btn_vbox), up_btn, FALSE, FALSE, 4);
1057
1058         down_btn = gtkut_stock_button("go-down", _("_Down"));
1059         gtk_widget_show(down_btn);
1060         gtk_box_pack_start(GTK_BOX(btn_vbox), down_btn, FALSE, FALSE, 0);
1061         gtk_container_set_border_width(GTK_CONTAINER(btn_vbox), 8);
1062
1063         g_signal_connect(G_OBJECT(item_type_combo), "changed",
1064                          G_CALLBACK(item_type_changed), prefs_toolbar);
1065         g_signal_connect(G_OBJECT(item_action_combo), "changed",
1066                          G_CALLBACK(action_selection_changed), prefs_toolbar);
1067         g_signal_connect(G_OBJECT(item_plugin_combo), "changed",
1068                          G_CALLBACK(plugin_selection_changed), prefs_toolbar);
1069         g_signal_connect(G_OBJECT(item_func_combo), "changed",
1070                          G_CALLBACK(func_selection_changed), prefs_toolbar);
1071         g_signal_connect(G_OBJECT(up_btn), "clicked",
1072                          G_CALLBACK(prefs_toolbar_up), prefs_toolbar);
1073         g_signal_connect(G_OBJECT(down_btn), "clicked",
1074                          G_CALLBACK(prefs_toolbar_down), prefs_toolbar);
1075
1076         gtk_widget_show_all(main_vbox);
1077
1078         prefs_toolbar->list_view_set    = list_view_set;
1079         prefs_toolbar->item_text_entry  = item_text_entry;
1080         prefs_toolbar->item_type_combo  = item_type_combo;
1081         prefs_toolbar->item_func_combo  = item_func_combo;
1082         prefs_toolbar->item_action_combo= item_action_combo;
1083         prefs_toolbar->item_plugin_combo= item_plugin_combo;
1084         prefs_toolbar->icon_button      = icon_button;
1085         prefs_toolbar->item_icon_file   = NULL;
1086
1087         prefs_toolbar->page.widget = main_vbox;
1088 }
1089
1090 ToolbarPage *prefs_toolbar_mainwindow;
1091 ToolbarPage *prefs_toolbar_composewindow;
1092 ToolbarPage *prefs_toolbar_messageview;
1093
1094 static void toolbar_unregister_plugin_item_real(GHashTable *hash,
1095                                         const gchar *plugin_name,
1096                                         const gchar *item_name)
1097 {
1098         gchar *key;
1099
1100         if (!hash)
1101                 return;
1102
1103         key = g_strdup_printf(plugin_name, "/", item_name, NULL);
1104         g_hash_table_remove(hash, key);
1105         g_free(key);
1106 }
1107
1108 void prefs_toolbar_unregister_plugin_item(ToolbarType toolbar_type,
1109                                         const gchar *plugin_name,
1110                                         const gchar *item_name)
1111 {
1112         GHashTable **hash;
1113         hash = get_plugin_hash_from_toolbar_type(toolbar_type);
1114         if (hash)
1115                 toolbar_unregister_plugin_item_real(*hash, plugin_name, item_name);
1116 }
1117
1118 static void prefs_toolbar_execute_plugin_item_real(gpointer parent,
1119                                 GHashTable *hash, const gchar *id)
1120 {
1121         ToolbarPluginItem *value;
1122         GSList *walk;
1123         gboolean found;
1124
1125         if (!hash) {
1126                 debug_print("No plugin registered toolbar items yet\n");
1127                 return;
1128         }
1129
1130         value = g_hash_table_lookup(hash, id);
1131         if (!value) {
1132                 debug_print("Could not find plugin toolbar item with id %s\n", id);
1133                 return;
1134         }
1135
1136         /* check if corresponding plugin is currently loaded */
1137         found = FALSE;
1138         for (walk = plugin_get_list(); walk; walk = walk->next) {
1139                 const gchar *plugin_name;
1140                 Plugin *plugin = walk->data;
1141                 plugin_name = plugin_get_name(plugin);
1142                 if (!strcmp(plugin_name, value->plugin)) {
1143                         found = TRUE;
1144                         break;
1145                 }
1146         }
1147         if (!found) {
1148                 debug_print("Plugin '%s' is currently not loaded, cannot execute toolbar action\n", value->plugin);
1149                 return;
1150         }
1151
1152         value->cb(parent, value->item_name, value->cb_data);
1153 }
1154
1155 void prefs_toolbar_execute_plugin_item(gpointer parent,
1156                         ToolbarType toolbar_type, const gchar *id)
1157 {
1158         GHashTable **hash;
1159         hash = get_plugin_hash_from_toolbar_type(toolbar_type);
1160         if (hash)
1161                 prefs_toolbar_execute_plugin_item_real(parent, *hash, id);
1162 }
1163
1164 static void destroy_plugin_item_hash_value(ToolbarPluginItem *item)
1165 {
1166         g_free(item->plugin);
1167         g_free(item->item_name);
1168         g_free(item);
1169 }
1170
1171 static void prefs_toolbar_register_plugin_item_real(GHashTable **hash,
1172                                         const gchar *plugin_name,
1173                                         const gchar *item_name,
1174                                         ToolbarPluginCallback cb,
1175                                         gpointer cb_data)
1176 {
1177         gchar *key;
1178         ToolbarPluginItem *value;
1179
1180         cm_return_if_fail(plugin_name && item_name);
1181
1182         if (!*hash) {
1183                 *hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1184                                 (GDestroyNotify) destroy_plugin_item_hash_value);
1185                 if (!*hash)
1186                         return;
1187         }
1188
1189         key = g_strconcat(plugin_name, "/", item_name, NULL);
1190         value = g_new0(ToolbarPluginItem, 1);
1191         value->plugin = g_strdup(plugin_name);
1192         value->item_name = g_strdup(item_name);
1193         value->cb = cb;
1194         value->cb_data = cb_data;
1195         g_hash_table_insert(*hash, key, value);
1196 }
1197
1198 void prefs_toolbar_register_plugin_item(ToolbarType toolbar_type,
1199                                         const gchar *plugin_name,
1200                                         const gchar *item_name,
1201                                         ToolbarPluginCallback cb,
1202                                         gpointer cb_data)
1203 {
1204         GHashTable **hash;
1205         hash = get_plugin_hash_from_toolbar_type(toolbar_type);
1206         if(hash)
1207                 prefs_toolbar_register_plugin_item_real(hash, plugin_name,
1208                                                 item_name, cb, cb_data);
1209 }
1210
1211 void prefs_toolbar_init(void)
1212 {
1213         ToolbarPage *page;
1214         static gchar *mainpath[3], *messagepath[3], *composepath[3];
1215
1216         mainpath[0] = _("Toolbars");
1217         mainpath[1] = _("Main Window");
1218         mainpath[2] = NULL;
1219
1220         page = g_new0(ToolbarPage, 1);
1221         page->page.path = mainpath;
1222         page->page.create_widget = prefs_toolbar_create_widget;
1223         page->page.destroy_widget = prefs_toolbar_destroy_widget;
1224         page->page.save_page = prefs_toolbar_save;
1225         page->source = TOOLBAR_MAIN;
1226         page->page.weight = 50.0;
1227         prefs_gtk_register_page((PrefsPage *) page);
1228         prefs_toolbar_mainwindow = page;
1229
1230         messagepath[0] = _("Toolbars");
1231         messagepath[1] = _("Message Window");
1232         messagepath[2] = NULL;
1233
1234         page = g_new0(ToolbarPage, 1);
1235         page->page.path = messagepath;
1236         page->page.create_widget = prefs_toolbar_create_widget;
1237         page->page.destroy_widget = prefs_toolbar_destroy_widget;
1238         page->page.save_page = prefs_toolbar_save;
1239         page->source = TOOLBAR_MSGVIEW;
1240         page->page.weight = 45.0;
1241         prefs_gtk_register_page((PrefsPage *) page);
1242         prefs_toolbar_messageview = page;
1243
1244         composepath[0] = _("Toolbars");
1245         composepath[1] = _("Compose Window");
1246         composepath[2] = NULL;
1247
1248         page = g_new0(ToolbarPage, 1);
1249         page->page.path = composepath;
1250         page->page.create_widget = prefs_toolbar_create_widget;
1251         page->page.destroy_widget = prefs_toolbar_destroy_widget;
1252         page->page.save_page = prefs_toolbar_save;
1253         page->source = TOOLBAR_COMPOSE;
1254         page->page.weight = 40.0;
1255         prefs_gtk_register_page((PrefsPage *) page);
1256         prefs_toolbar_composewindow = page;
1257 }
1258
1259 void prefs_toolbar_done(void)
1260 {
1261         prefs_gtk_unregister_page((PrefsPage *) prefs_toolbar_mainwindow);
1262         g_free(prefs_toolbar_mainwindow->item_icon_file);
1263         g_free(prefs_toolbar_mainwindow);
1264         prefs_gtk_unregister_page((PrefsPage *) prefs_toolbar_composewindow);
1265         g_free(prefs_toolbar_composewindow->item_icon_file);
1266         g_free(prefs_toolbar_composewindow);
1267         prefs_gtk_unregister_page((PrefsPage *) prefs_toolbar_messageview);
1268         g_free(prefs_toolbar_messageview->item_icon_file);
1269         g_free(prefs_toolbar_messageview);
1270 }
1271
1272 void prefs_toolbar_update_action_btns(void)
1273 {
1274         if (toolbar_check_action_btns(TOOLBAR_MAIN)) {
1275                 toolbar_save_config_file(TOOLBAR_MAIN);
1276                 toolbar_update(TOOLBAR_MAIN, mainwindow_get_mainwindow());
1277         }
1278
1279         if (toolbar_check_action_btns(TOOLBAR_COMPOSE)) {
1280                 toolbar_save_config_file(TOOLBAR_COMPOSE);
1281                 compose_reflect_prefs_pixmap_theme();
1282         }
1283
1284         if (toolbar_check_action_btns(TOOLBAR_MSGVIEW)) {
1285                 toolbar_save_config_file(TOOLBAR_MSGVIEW);
1286                 messageview_reflect_prefs_pixmap_theme();
1287         }
1288 }
1289
1290 static void set_visible_if_not_text(GtkTreeViewColumn *col,
1291                                     GtkCellRenderer   *renderer,
1292                                     GtkTreeModel      *model,
1293                                     GtkTreeIter       *iter,
1294                                     gpointer           user_data)
1295 {
1296         gboolean is_text;
1297         GdkPixbuf *pixbuf;
1298
1299         gtk_tree_model_get(model, iter, SET_ICON_IS_TEXT, &is_text, -1);
1300         if (is_text) {
1301                 g_object_set(renderer, "visible", FALSE, NULL);
1302         } else {
1303                 pixbuf = NULL;
1304                 gtk_tree_model_get(model, iter,
1305                                    SET_ICON, &pixbuf,
1306                                    -1);
1307                 /* note: getting a pixbuf from a tree model increases
1308                  * its refcount ... */
1309
1310                 g_object_set(renderer, "visible", TRUE, NULL);
1311                 g_object_set(renderer, "pixbuf",  pixbuf, NULL);
1312
1313                 if (pixbuf != NULL)
1314                         g_object_unref(pixbuf);
1315         }
1316 }
1317
1318 static GtkWidget *create_set_list_view(ToolbarPage *prefs_toolbar)
1319 {
1320         GtkTreeView *list_view;
1321         GtkListStore *store;
1322         GtkCellRenderer *renderer;
1323         GtkTreeViewColumn *column;
1324         GtkTreeSelection *selector;
1325
1326         store = gtk_list_store_new(N_SET_COLUMNS,
1327                                    GDK_TYPE_PIXBUF,
1328                                    G_TYPE_STRING,
1329                                    G_TYPE_STRING,
1330                                    G_TYPE_STRING,
1331                                    G_TYPE_STRING,
1332                                    G_TYPE_BOOLEAN,
1333                                    -1);
1334         list_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)));
1335         g_object_unref(G_OBJECT(store));
1336
1337         column = gtk_tree_view_column_new();
1338         gtk_tree_view_column_set_title(column, _("Icon"));
1339         renderer = gtk_cell_renderer_pixbuf_new();
1340         gtk_tree_view_column_pack_start(column, renderer, FALSE);
1341         gtk_tree_view_set_reorderable(list_view, TRUE);
1342         /* tell pixbuf renderer it is only visible if
1343          * the icon is not represented by text */
1344         gtk_tree_view_column_set_cell_data_func(column, renderer,
1345                                                 set_visible_if_not_text,
1346                                                 NULL, NULL);
1347
1348         renderer = gtk_cell_renderer_text_new();
1349         gtk_tree_view_column_pack_start(column, renderer, FALSE);
1350
1351         /* tell the text renderer it is only visible if the icon
1352          * is represented by an image */
1353         gtk_tree_view_column_set_attributes(column, renderer,
1354                                             "visible", SET_ICON_IS_TEXT,
1355                                             "text", SET_ICON_TEXT,
1356                                             NULL);
1357
1358         gtk_tree_view_append_column(list_view, column);
1359
1360         column = gtk_tree_view_column_new();
1361         gtk_tree_view_column_set_title(column, _("Icon text"));
1362         renderer = gtk_cell_renderer_text_new();
1363         gtk_tree_view_column_pack_start(column, renderer, FALSE);
1364         gtk_tree_view_column_set_attributes(column, renderer,
1365                                             "text", SET_TEXT,
1366                                             NULL);
1367         gtk_tree_view_append_column(list_view, column);
1368
1369         column = gtk_tree_view_column_new();
1370         gtk_tree_view_column_set_title(column, _("Mapped event"));
1371         renderer = gtk_cell_renderer_text_new();
1372         gtk_tree_view_column_pack_start(column, renderer, FALSE);
1373         gtk_tree_view_column_set_attributes(column, renderer,
1374                                             "text", SET_EVENT,
1375                                             NULL);
1376         gtk_tree_view_append_column(list_view, column);
1377
1378         /* various other tree view attributes */
1379         gtk_tree_view_set_rules_hint(list_view, prefs_common.use_stripes_everywhere);
1380
1381         selector = gtk_tree_view_get_selection(list_view);
1382         gtk_tree_selection_set_mode(selector, GTK_SELECTION_BROWSE);
1383         gtk_tree_selection_set_select_function
1384                 (selector, (GtkTreeSelectionFunc) set_list_selected,
1385                  prefs_toolbar, NULL);
1386
1387         return GTK_WIDGET(list_view);
1388
1389 }
1390
1391 static gboolean set_list_selected(GtkTreeSelection *selector,
1392                                   GtkTreeModel *model,
1393                                   GtkTreePath *path,
1394                                   gboolean currently_selected,
1395                                   ToolbarPage *prefs_toolbar)
1396 {
1397
1398         GtkTreeIter iter;
1399         gchar *icon_text, *icon_file, *descr;
1400         GList *cur;
1401         GSList *cur2;
1402         gint item_num;
1403         GdkPixbuf *pix;
1404
1405         if (currently_selected || !gtk_tree_model_get_iter(model, &iter, path))
1406                 return TRUE;
1407
1408         gtk_tree_model_get(model, &iter,
1409                            SET_ICON, &pix,
1410                            SET_TEXT, &icon_text,
1411                            SET_EVENT, &descr,
1412                            SET_FILENAME, &icon_file,
1413                            -1);
1414
1415         g_free(prefs_toolbar->item_icon_file);
1416         prefs_toolbar->item_icon_file = icon_file;
1417         gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button),
1418                              gtk_image_new_from_pixbuf(pix));
1419
1420         if (g_utf8_collate(toolbar_ret_descr_from_val(A_SEPARATOR), descr) == 0) {
1421                 gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button),
1422                                     _("None"));
1423                 g_free(prefs_toolbar->item_icon_file);
1424                 prefs_toolbar->item_icon_file = NULL;
1425                 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo),
1426                                         ITEM_SEPARATOR);
1427                 g_free(icon_text);
1428                 g_free(descr);
1429                 if (pix != NULL)
1430                         g_object_unref(pix);
1431
1432                 return TRUE;
1433         }
1434
1435         gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
1436         gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry),
1437                            icon_text);
1438
1439         if (g_utf8_collate(toolbar_ret_descr_from_val(A_CLAWS_ACTIONS), descr) == 0) {
1440                 gtk_combo_box_set_active(GTK_COMBO_BOX(
1441                         prefs_toolbar->item_type_combo), ITEM_USER_ACTION);
1442
1443                 for(cur2 = prefs_common.actions_list, item_num = 0; cur2 != NULL;
1444                     cur2 = cur2->next) {
1445                         gchar *item_string;
1446                         get_action_name((gchar *)cur2->data, &item_string);
1447
1448                         if(g_utf8_collate(item_string, icon_text) == 0) {
1449                                 gtk_combo_box_set_active(
1450                                         GTK_COMBO_BOX(prefs_toolbar->item_action_combo),
1451                                         item_num);
1452                                 g_free(item_string);
1453                                 break;
1454                         }
1455                         else {
1456                                 item_num++;
1457                                 g_free(item_string);
1458                         }
1459                 }
1460
1461                 gtk_widget_show(prefs_toolbar->item_action_combo);
1462                 gtk_widget_hide(prefs_toolbar->item_func_combo);
1463                 gtk_widget_hide(prefs_toolbar->item_plugin_combo);
1464
1465                 g_free(icon_text);
1466                 g_free(descr);
1467                 if (pix != NULL)
1468                         g_object_unref(pix);
1469
1470                 return TRUE;
1471         }
1472
1473         if (g_utf8_collate(toolbar_ret_descr_from_val(A_CLAWS_PLUGINS), descr) == 0) {
1474                 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo), ITEM_PLUGIN);
1475
1476                 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_plugin_combo), 0);
1477
1478                 gtk_widget_show(prefs_toolbar->item_plugin_combo);
1479                 gtk_widget_hide(prefs_toolbar->item_func_combo);
1480                 gtk_widget_hide(prefs_toolbar->item_action_combo);
1481
1482                 g_free(descr);
1483                 g_free(icon_text);
1484                 if (pix != NULL)
1485                         g_object_unref(pix);
1486                 return TRUE;
1487         }
1488
1489         /* scan combo list for selected description an set combo item accordingly */
1490         for (cur = prefs_toolbar->combo_action_list, item_num = 0; cur != NULL;
1491              cur = cur->next) {
1492                 gchar *item_str = (gchar*)cur->data;
1493                 if (g_utf8_collate(item_str, descr) == 0) {
1494                         gtk_combo_box_set_active(
1495                                 GTK_COMBO_BOX(prefs_toolbar->item_func_combo),
1496                                 item_num);
1497
1498                         break;
1499                 }
1500                 else
1501                         item_num++;
1502         }
1503
1504         gtk_combo_box_set_active(GTK_COMBO_BOX(
1505                         prefs_toolbar->item_type_combo),ITEM_FUNCTION);
1506         gtk_widget_hide(prefs_toolbar->item_action_combo);
1507         gtk_widget_show(prefs_toolbar->item_func_combo);
1508
1509         g_free(icon_text);
1510         g_free(descr);
1511         if (pix != NULL)
1512                 g_object_unref(pix);
1513
1514         return TRUE;
1515 }
1516
1517 static void icon_chooser_ok_clicked(GtkButton *button,
1518                                         ToolbarPage *prefs_toolbar)
1519 {
1520         GtkTreeModel *model;
1521         GtkTreeIter iter;
1522         GList *list;
1523         GdkPixbuf *pix;
1524         gchar *icon_file;
1525
1526         cm_return_if_fail(prefs_toolbar != NULL);
1527
1528         model = gtk_icon_view_get_model(GTK_ICON_VIEW(prefs_toolbar->icon_chooser_view));
1529         list = gtk_icon_view_get_selected_items(GTK_ICON_VIEW(prefs_toolbar->icon_chooser_view));
1530         if(list == NULL)
1531                 return;
1532
1533         if(!gtk_tree_model_get_iter(model, &iter, (GtkTreePath *)list->data)) {
1534                 gtk_tree_path_free(list->data);
1535                 g_list_free(list);
1536                 return;
1537         }
1538
1539         gtk_tree_model_get(model, &iter,
1540                            SET_ICON, &pix,
1541                            SET_FILENAME, &icon_file,
1542                            -1);
1543
1544         g_free(prefs_toolbar->item_icon_file);
1545         prefs_toolbar->item_icon_file = icon_file;
1546         gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button),
1547                              gtk_image_new_from_pixbuf(pix));
1548         if (pix != NULL)
1549                 g_object_unref(pix);
1550
1551         gtk_widget_destroy(prefs_toolbar->icon_chooser_win);
1552         prefs_toolbar->icon_chooser_win = NULL;
1553         prefs_toolbar->icon_chooser_view = NULL;
1554
1555         gtk_tree_path_free(list->data);
1556         g_list_free(list);
1557 }
1558
1559 static void icon_chooser_cancel_clicked(GtkButton *button,
1560                                         ToolbarPage *prefs_toolbar)
1561 {
1562         cm_return_if_fail(prefs_toolbar != NULL);
1563
1564         gtk_widget_destroy(prefs_toolbar->icon_chooser_win);
1565         prefs_toolbar->icon_chooser_win = NULL;
1566         prefs_toolbar->icon_chooser_view = NULL;
1567 }
1568
1569 static gboolean icon_chooser_key_pressed(GtkWidget *widget, GdkEventKey *event,
1570                         ToolbarPage *prefs_toolbar)
1571 {
1572         if (event && event->keyval == GDK_KEY_Escape) {
1573                 icon_chooser_cancel_clicked(NULL, prefs_toolbar);
1574                 return TRUE;
1575         }
1576
1577         return FALSE;
1578 }
1579
1580 static gboolean icon_list_key_pressed(GtkWidget *widget, GdkEventKey *event,
1581                         ToolbarPage *prefs_toolbar)
1582 {
1583         if (event) {
1584                 if (event->keyval == GDK_KEY_KP_Enter ||
1585                     event->keyval == GDK_KEY_Return ||
1586                     event->keyval == GDK_KEY_space) {
1587                         icon_chooser_ok_clicked(NULL, prefs_toolbar);
1588                         return TRUE;
1589                 }
1590         }
1591         return FALSE;
1592 }
1593
1594 static gboolean ok_cb(gpointer data)
1595 {
1596         ToolbarPage *prefs_toolbar = (ToolbarPage *)data;
1597         icon_chooser_ok_clicked(NULL, prefs_toolbar);
1598         return FALSE;
1599 }
1600
1601 static gboolean icon_list_button_release(GtkWidget *widget,
1602                                                GdkEventButton *event,
1603                                                ToolbarPage *prefs_toolbar )
1604 {
1605         static guint id = 0;
1606         if (id > 0) {
1607                 g_source_remove(id);
1608                 id = 0;
1609         }
1610         id = g_timeout_add(100, ok_cb, prefs_toolbar);
1611         return FALSE;
1612 }
1613
1614 static gboolean icon_window_button_press(GtkWidget *widget,
1615                                                GdkEventButton *event,
1616                                                ToolbarPage *prefs_toolbar )
1617 {
1618         GtkWidget *event_widget;
1619         gboolean restore = TRUE;
1620
1621         /* Test where mouse was clicked */
1622         event_widget = gtk_get_event_widget((GdkEvent *)event);
1623         if (event_widget != widget) {
1624                 while (event_widget) {
1625                         if (event_widget == widget)
1626                                 return FALSE;
1627                         else if (event_widget == prefs_toolbar->icon_chooser_win) {
1628                                 restore = FALSE;
1629                                 break;
1630                         }
1631                         event_widget = gtk_widget_get_parent(event_widget);
1632                 }
1633         }
1634
1635         if (restore) {
1636                 icon_chooser_cancel_clicked(NULL, prefs_toolbar);
1637                 return TRUE;
1638         }
1639         return FALSE;
1640 }
1641
1642 static void icon_chooser_activated(GtkTreeView *treeview, GtkTreePath *path,
1643                                 ToolbarPage *prefs_toolbar)
1644 {
1645         icon_chooser_ok_clicked(NULL, prefs_toolbar);
1646 }
1647
1648 static void icon_chooser_create(GtkButton *button, ToolbarPage *prefs_toolbar)
1649 {
1650         GtkAllocation allocation;
1651         GtkWidget *icon_chooser_win;
1652         GtkWidget *scrollwin;
1653         GtkWidget *icon_view;
1654         GtkListStore *store;
1655         GtkTreeIter iter;
1656         gint i, x, y;
1657
1658         store = gtk_list_store_new(2,
1659                                    GDK_TYPE_PIXBUF,
1660                                    G_TYPE_STRING,
1661                                    -1);
1662
1663         gtk_list_store_clear(store);
1664
1665         for (i = 0; ToolbarIcons[i] != STOCK_PIXMAP_EMPTY; i++) {
1666                 GdkPixbuf *pixbuf;
1667                 stock_pixbuf_gdk(ToolbarIcons[i], &pixbuf);
1668
1669                 gtk_list_store_append(store, &iter);
1670                 gtk_list_store_set(store, &iter,
1671                                    SET_ICON, pixbuf,
1672                                    SET_FILENAME, stock_pixmap_get_name((StockPixmap) ToolbarIcons[i]),
1673                                    -1);
1674         }
1675
1676         icon_chooser_win = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "prefs_toolbar");
1677         gtk_window_set_title(GTK_WINDOW(icon_chooser_win), _("Toolbar item icon"));
1678         gtk_window_set_decorated(GTK_WINDOW(icon_chooser_win), FALSE);
1679         gdk_window_get_origin(gtk_widget_get_window(
1680                         GTK_WIDGET(prefs_toolbar->icon_button)),
1681                         &x, &y);
1682         gtk_widget_get_allocation(GTK_WIDGET(prefs_toolbar->icon_button), &allocation);
1683         x += allocation.x;
1684         y += allocation.y;
1685         y += 50;
1686         x -= 300-50;
1687         gtk_window_move(GTK_WINDOW(icon_chooser_win), x, y);
1688         gtk_window_set_resizable(GTK_WINDOW(icon_chooser_win), FALSE);
1689         gtk_window_set_type_hint(GTK_WINDOW(icon_chooser_win), GDK_WINDOW_TYPE_HINT_DIALOG);
1690         gtk_widget_set_size_request(icon_chooser_win, 300, 320);
1691
1692         scrollwin = gtk_scrolled_window_new(NULL, NULL);
1693         gtk_container_add(GTK_CONTAINER(icon_chooser_win), scrollwin);
1694         gtk_widget_show(scrollwin);
1695         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
1696                                 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1697         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
1698                                 GTK_SHADOW_OUT);
1699         gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrollwin), TRUE);
1700
1701         icon_view = gtk_icon_view_new_with_model(GTK_TREE_MODEL(store));
1702         gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(icon_view), GTK_SELECTION_SINGLE);
1703         gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icon_view), SET_ICON);
1704         gtk_container_add(GTK_CONTAINER(scrollwin), GTK_WIDGET(icon_view));
1705
1706         g_signal_connect(G_OBJECT(icon_chooser_win), "key_press_event",
1707                          G_CALLBACK(icon_chooser_key_pressed), prefs_toolbar);
1708         g_signal_connect(G_OBJECT(icon_view), "item-activated",
1709                          G_CALLBACK(icon_chooser_activated), prefs_toolbar);
1710         g_signal_connect(G_OBJECT(icon_chooser_win),
1711                          "button-press-event",
1712                          G_CALLBACK(icon_window_button_press),
1713                          prefs_toolbar );
1714         g_signal_connect(G_OBJECT(icon_view),
1715                          "button-release-event",
1716                          G_CALLBACK(icon_list_button_release),
1717                          prefs_toolbar );
1718         g_signal_connect(G_OBJECT(icon_view), "key_press_event",
1719                          G_CALLBACK(icon_list_key_pressed), prefs_toolbar);
1720
1721         gtk_widget_show_all(icon_chooser_win);
1722         gtk_widget_grab_focus(GTK_WIDGET(icon_view));
1723         manage_window_set_transient(GTK_WINDOW(icon_chooser_win));
1724         gtk_window_set_modal(GTK_WINDOW(icon_chooser_win), TRUE);
1725
1726         prefs_toolbar->icon_chooser_win         = icon_chooser_win;
1727         prefs_toolbar->icon_chooser_view        = icon_view;
1728 }