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