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