2007-10-07 [colin] 3.0.2cvs24
[claws.git] / src / prefs_toolbar.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2002-2007 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 #endif
27
28 #include "defs.h"
29
30 #include <glib.h>
31 #include <glib/gi18n.h>
32 #include <gtk/gtk.h>
33 #include <gtk/gtkoptionmenu.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 "gtkutils.h"
41 #include "mainwindow.h"
42 #include "alertpanel.h"
43 #include "prefs_common.h"
44
45 #include "utils.h"
46
47 #include "toolbar.h"
48 #include "prefs_toolbar.h"
49 #include "prefswindow.h"
50 #include "prefs_gtk.h"
51
52 enum
53 {
54         SET_ICON          = 0,
55         SET_FILENAME      = 1,
56         SET_TEXT          = 2,
57         SET_EVENT         = 3,
58         SET_ICON_TEXT     = 4,          /*!< "icon" text (separator) */ 
59         SET_ICON_IS_TEXT  = 5,          /*!< icon is text representation */
60         N_SET_COLUMNS
61 };
62
63 enum
64 {
65         ITEM_FUNCTION     = 0,
66         ITEM_USER_ACTION  = 1,
67         ITEM_SEPARATOR    = 2
68 };
69
70 typedef struct _ToolbarPage
71 {
72         PrefsPage  page;
73
74         GtkWidget *window;              /* do not modify */
75
76         ToolbarType source;
77         GList     *combo_action_list;   /* list of internal functions    */
78
79         GtkWidget *list_view_set;       /* toolbar items treeview        */
80         GtkWidget *item_text_entry;     /* item name                     */
81         GtkWidget *item_type_combo;     /* item type selection widget    */
82         GtkWidget *item_func_combo;     /* item internal function widget */
83         GtkWidget *item_action_combo;   /* item user action widget       */
84         GtkWidget *icon_button;         /* item icon chooser widget      */
85         
86         GtkWidget *icon_chooser_win;
87         GtkWidget *icon_chooser_list;
88         
89         gchar *item_icon_file;          /* item icon file                */
90
91 } ToolbarPage;
92
93 #define ERROR_MSG _("Selected Action already set.\nPlease choose another Action from List")
94 #define ERROR_MSG_NO_ICON _("Item has no icon defined.")
95 #define ERROR_MSG_NO_TEXT _("Item has no text defined.")
96
97 static void prefs_toolbar_populate               (ToolbarPage *prefs_toolbar);
98
99 static void get_action_name                      (const gchar *entry, 
100                                                   gchar **menu);
101                                                   
102 static gboolean is_duplicate                     (ToolbarPage *prefs_toolbar,
103                                                   gchar            *chosen_action);
104 static void prefs_toolbar_save                   (PrefsPage        *_page);
105
106 static void prefs_toolbar_register               (GtkButton        *button,
107                                                   ToolbarPage *prefs_toolbar);
108 static void prefs_toolbar_substitute             (GtkButton        *button,
109                                                   ToolbarPage *prefs_toolbar);
110 static void prefs_toolbar_delete                 (GtkButton        *button,
111                                                   ToolbarPage *prefs_toolbar);
112
113 static void prefs_toolbar_up                     (GtkButton        *button,
114                                                   ToolbarPage *prefs_toolbar);
115
116 static void prefs_toolbar_down                   (GtkButton        *button,
117                                                   ToolbarPage *prefs_toolbar);
118
119 static void action_selection_changed             (GtkComboBox *action_combo,
120                                                   ToolbarPage *prefs_toolbar);
121
122 static void func_selection_changed               (GtkComboBox *action_combo,
123                                                   ToolbarPage *prefs_toolbar);
124
125 static void prefs_toolbar_create                 (ToolbarPage *prefs_toolbar);
126
127 static GtkWidget *create_set_list_view           (ToolbarPage *prefs_toolbar);
128
129 static gboolean set_list_selected                (GtkTreeSelection *selector,
130                                                   GtkTreeModel *model, 
131                                                   GtkTreePath *path,
132                                                   gboolean currently_selected,
133                                                   ToolbarPage *prefs_toolbar);
134
135 static void icon_chooser_create                  (GtkButton *button,
136                                                   ToolbarPage *prefs_toolbar);
137
138 static void prefs_toolbar_create_widget(PrefsPage *_page, GtkWindow *window, gpointer data)
139 {
140         ToolbarPage *prefs_toolbar = (ToolbarPage *) _page;
141         gchar *win_titles[3];
142         win_titles[TOOLBAR_MAIN]    = _("Main toolbar configuration");
143         win_titles[TOOLBAR_COMPOSE] = _("Compose toolbar configuration");  
144         win_titles[TOOLBAR_MSGVIEW] = _("Message view toolbar configuration");  
145
146         prefs_toolbar->window = GTK_WIDGET(window);
147
148         toolbar_read_config_file(prefs_toolbar->source);
149
150         prefs_toolbar_create(prefs_toolbar);
151         prefs_toolbar_populate(prefs_toolbar);
152 }
153
154 static void prefs_toolbar_save(PrefsPage *_page)
155 {
156         ToolbarPage *prefs_toolbar = (ToolbarPage *) _page;
157         GtkTreeView *list_view = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
158         GtkTreeModel *model = gtk_tree_view_get_model(list_view);
159         GtkTreeIter iter;
160         
161         toolbar_clear_list(prefs_toolbar->source);
162
163         if (!gtk_tree_model_iter_n_children(model, NULL)
164         ||  !gtk_tree_model_get_iter_first(model, &iter))
165                 toolbar_set_default(prefs_toolbar->source);
166         else {
167                 do {
168                         ToolbarItem *item;
169                         gchar *fname, *text, *event; 
170                         
171                         item = g_new0(ToolbarItem, 1);
172
173                         gtk_tree_model_get(model, &iter,
174                                            SET_FILENAME, &fname,
175                                            SET_TEXT, &text,
176                                            SET_EVENT, &event,
177                                            -1);
178
179                         /* XXX: remember that G_TYPE_STRING returned by model
180                          * is owned by caller of gtk_tree_model_get() */
181                         item->file  = fname;
182                         item->text  = text;
183                         item->index = toolbar_ret_val_from_descr(event);
184                         g_free(event);
185
186                         /* TODO: save A_SYL_ACTIONS only if they are still active */
187                         toolbar_set_list_item(item, prefs_toolbar->source);
188
189                         g_free(item->file);
190                         g_free(item->text);
191                         g_free(item);
192                 } while (gtk_tree_model_iter_next(model, &iter));
193         }
194
195         toolbar_save_config_file(prefs_toolbar->source);
196
197         if (prefs_toolbar->source == TOOLBAR_MAIN) 
198                 main_window_reflect_prefs_all_real(TRUE);
199         else if (prefs_toolbar->source == TOOLBAR_COMPOSE)
200                 compose_reflect_prefs_pixmap_theme();
201         else if (prefs_toolbar->source == TOOLBAR_MSGVIEW)
202                 messageview_reflect_prefs_pixmap_theme();
203 }
204
205 static void prefs_toolbar_destroy_widget(PrefsPage *_page)
206 {
207         ToolbarPage *prefs_toolbar = (ToolbarPage *) _page;
208
209         g_list_free(prefs_toolbar->combo_action_list);
210         prefs_toolbar->combo_action_list = NULL;
211 }
212
213 static void prefs_toolbar_set_displayed(ToolbarPage *prefs_toolbar)
214 {
215         GSList *cur;
216         GtkTreeView *list_view_set = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
217         GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model
218                                                 (list_view_set));
219         GSList *toolbar_list = toolbar_get_list(prefs_toolbar->source);
220         GtkTreeIter iter;
221
222         gtk_list_store_clear(store);
223
224         /* set currently active toolbar entries */
225         for (cur = toolbar_list; cur != NULL; cur = cur->next) {
226                 ToolbarItem *item = (ToolbarItem*) cur->data;
227
228                 gtk_list_store_append(store, &iter);
229         
230                 if (item->index != A_SEPARATOR) {
231                         GdkPixbuf *pix;
232                         StockPixmap icon = stock_pixmap_get_icon(item->file);
233                         
234                         stock_pixbuf_gdk(prefs_toolbar->window, icon, &pix);
235
236                         gtk_list_store_set(store, &iter, 
237                                            SET_ICON, pix,
238                                            SET_FILENAME, item->file,
239                                            SET_TEXT, item->text,
240                                            SET_EVENT, toolbar_ret_descr_from_val(item->index),
241                                            SET_ICON_TEXT, NULL, 
242                                            SET_ICON_IS_TEXT, FALSE,
243                                            -1);
244                 } else {
245                         gtk_list_store_set(store, &iter,
246                                            SET_ICON, NULL,
247                                            SET_FILENAME, toolbar_ret_descr_from_val(A_SEPARATOR),
248                                            SET_TEXT, (const gchar *) "", 
249                                            SET_EVENT, toolbar_ret_descr_from_val(A_SEPARATOR),
250                                            SET_ICON_TEXT, (const gchar *) SEPARATOR_PIXMAP,
251                                            SET_ICON_IS_TEXT, TRUE,
252                                            -1);
253                 }
254         }
255
256         /* select first */
257         gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
258         gtk_tree_selection_select_iter(gtk_tree_view_get_selection
259                                                 (list_view_set),
260                                        &iter);  
261 }
262
263 static void prefs_toolbar_populate(ToolbarPage *prefs_toolbar)
264 {
265         GList *cur;
266         GSList *cur2;
267         gchar *act, *act_name;
268
269         gtk_combo_box_append_text(GTK_COMBO_BOX(prefs_toolbar->item_type_combo),
270                                   _("Internal Function"));      
271         gtk_combo_box_append_text(GTK_COMBO_BOX(prefs_toolbar->item_type_combo),
272                                   _("User Action"));
273         gtk_combo_box_append_text(GTK_COMBO_BOX(prefs_toolbar->item_type_combo),
274                                   _("Separator"));
275         
276         prefs_toolbar->combo_action_list = toolbar_get_action_items(prefs_toolbar->source);
277         for(cur = prefs_toolbar->combo_action_list; cur != NULL; cur = cur->next) {
278                 act = (gchar *)cur->data;
279                 gtk_combo_box_append_text(GTK_COMBO_BOX(prefs_toolbar->item_func_combo),
280                                           act);
281         }
282
283         /* get currently defined sylpheed actions */
284         if (prefs_common.actions_list != NULL) {
285                 for (cur2 = prefs_common.actions_list; cur2 != NULL; cur2 = cur2->next) {
286                         act = (gchar *)cur2->data;
287                         get_action_name(act, &act_name);
288                         
289                         gtk_combo_box_append_text(
290                                 GTK_COMBO_BOX(prefs_toolbar->item_action_combo),
291                                 act_name);
292
293                         g_free(act_name);
294                 } 
295
296         }
297         
298         gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo), 0);
299         gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_func_combo), 0);
300         gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_action_combo), 0);
301         
302         prefs_toolbar_set_displayed(prefs_toolbar);
303
304         toolbar_clear_list(prefs_toolbar->source);
305 }
306
307 static gboolean is_duplicate(ToolbarPage *prefs_toolbar, gchar *chosen_action)
308 {
309         GtkTreeView *list_view_set = GTK_TREE_VIEW
310                                         (prefs_toolbar->list_view_set);
311         GtkTreeModel *model_set = gtk_tree_view_get_model(list_view_set);                                       
312         gchar *entry;
313         GtkTreeIter iter;
314         gboolean result;
315
316         g_return_val_if_fail(chosen_action != NULL, TRUE);
317
318         if (!gtk_tree_model_iter_n_children(model_set, NULL))
319                 return FALSE;
320         
321         if (!gtk_tree_model_get_iter_first(model_set, &iter))
322                 return FALSE;
323
324         result = FALSE;
325         do {
326                 gtk_tree_model_get(model_set, &iter,
327                                    SET_EVENT, &entry, 
328                                    -1);
329                 if (g_utf8_collate(chosen_action, entry) == 0) 
330                         result = TRUE;
331                 g_free(entry);                  
332         } while (!result && gtk_tree_model_iter_next(model_set, &iter));
333
334         return result;
335 }
336
337 static void prefs_toolbar_default(GtkButton *button, ToolbarPage *prefs_toolbar)
338 {
339         toolbar_clear_list(prefs_toolbar->source);
340         toolbar_set_default(prefs_toolbar->source);
341         prefs_toolbar_set_displayed(prefs_toolbar);
342 }
343
344 /*!
345  *\return       String that should be freed by caller.
346  */
347 static void get_action_name(const gchar *entry, gchar **menu)
348 {
349         gchar *act, *act_p;
350         
351         *menu = NULL;
352
353         if (prefs_common.actions_list != NULL) {
354                 
355                 act = g_strdup(entry);
356                 act_p = strstr(act, ": ");
357                 if (act_p != NULL)
358                         act_p[0] = 0x00;
359                 /* freed by calling func */
360                 *menu = act;
361         }
362 }
363
364 static void prefs_toolbar_register(GtkButton *button, ToolbarPage *prefs_toolbar)
365 {
366         GtkTreeView *list_view_set   = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
367         gint item_type = gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo));
368         GtkListStore *store_set;
369         GtkTreeIter iter;
370
371         store_set = GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set));
372
373         /* SEPARATOR or other ? */
374         if (item_type == ITEM_SEPARATOR) {
375                 gtk_list_store_append(store_set, &iter);
376                 gtk_list_store_set(store_set, &iter,
377                                    SET_ICON, NULL,
378                                    SET_FILENAME, prefs_toolbar->item_icon_file,
379                                    SET_TEXT, NULL,
380                                    SET_EVENT, toolbar_ret_descr_from_val(A_SEPARATOR),
381                                    SET_ICON_TEXT, (const gchar *) SEPARATOR_PIXMAP,
382                                    SET_ICON_IS_TEXT, TRUE,
383                                    -1);
384         } else {
385                 GdkPixbuf *pixbuf;
386                 gchar *event, *text;
387
388                 stock_pixbuf_gdk(prefs_toolbar->window, 
389                                  stock_pixmap_get_icon(prefs_toolbar->item_icon_file),
390                                  &pixbuf);
391                 if(pixbuf == NULL) {
392                         alertpanel_error(ERROR_MSG_NO_ICON);
393                         return;
394                 }
395                                 
396                 if (item_type == ITEM_FUNCTION) {
397                         event = gtk_combo_box_get_active_text(GTK_COMBO_BOX(
398                                                 prefs_toolbar->item_func_combo));
399                                                 
400                         if (is_duplicate(prefs_toolbar, event)) {
401                                 alertpanel_error(ERROR_MSG);
402                                 g_free(event);
403                                 return;
404                         }
405                 } else
406                         event = toolbar_ret_descr_from_val(A_SYL_ACTIONS);
407                 
408                 text = gtk_editable_get_chars(
409                         GTK_EDITABLE(prefs_toolbar->item_text_entry), 0 , -1);
410
411                 if (text != NULL) {
412                         gtk_list_store_append(store_set, &iter);
413                         gtk_list_store_set(store_set, &iter,
414                                            SET_ICON, pixbuf,
415                                            SET_FILENAME, prefs_toolbar->item_icon_file,
416                                            SET_TEXT, text,
417                                            SET_EVENT, event,
418                                            SET_ICON_TEXT, NULL,
419                                            SET_ICON_IS_TEXT, FALSE,
420                                            -1);
421                 } else {
422                         alertpanel_error(ERROR_MSG_NO_TEXT);
423                         return;
424                 }
425                 
426                 g_free(text);
427                 if(item_type != ITEM_USER_ACTION)
428                         g_free(event);
429         }
430         
431         gtk_tree_selection_select_iter(gtk_tree_view_get_selection
432                                                 (list_view_set),
433                                        &iter);
434 }
435
436 static void prefs_toolbar_substitute(GtkButton *button, ToolbarPage *prefs_toolbar)
437 {
438         GtkTreeView *list_view_set   = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
439         GtkListStore *store_set   = GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set));
440         gint item_type = gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo));
441         GtkTreeSelection *sel_set;
442         GtkTreeIter iter_set;
443
444         if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set), NULL))
445                 return;
446                 
447         sel_set = gtk_tree_view_get_selection(list_view_set);           
448         if (!gtk_tree_selection_get_selected(sel_set, NULL, &iter_set))
449                 return;
450
451         if (item_type == ITEM_SEPARATOR) {
452                 gtk_list_store_set(store_set, &iter_set, 
453                                    SET_ICON, NULL,
454                                    SET_TEXT, NULL,
455                                    SET_EVENT, toolbar_ret_descr_from_val(A_SEPARATOR),
456                                    SET_FILENAME, prefs_toolbar->item_icon_file,
457                                    SET_ICON_TEXT, (const gchar *) SEPARATOR_PIXMAP,
458                                    SET_ICON_IS_TEXT, TRUE,
459                                    -1);
460         } else {
461                 GdkPixbuf *pixbuf;
462                 gchar *icon_event, *set_event, *text;
463
464                 stock_pixbuf_gdk(prefs_toolbar->window, 
465                                  stock_pixmap_get_icon(prefs_toolbar->item_icon_file),
466                                  &pixbuf);
467                 if(pixbuf == NULL) {
468                         alertpanel_error(ERROR_MSG_NO_ICON);
469                         return;
470                 }
471
472                 gtk_tree_model_get(GTK_TREE_MODEL(store_set), &iter_set, 
473                                                   SET_EVENT, &set_event,
474                                                   -1);
475                 
476                 if (item_type == ITEM_FUNCTION) {
477                         icon_event = gtk_combo_box_get_active_text(GTK_COMBO_BOX(
478                                                 prefs_toolbar->item_func_combo));
479                                                 
480                         if (is_duplicate(prefs_toolbar, icon_event)
481                         && g_utf8_collate(icon_event, set_event) != 0){
482                                 alertpanel_error(ERROR_MSG);
483                                 g_free(icon_event);
484                                 g_free(set_event);
485                                 return;
486                         }
487                 } else
488                         icon_event = toolbar_ret_descr_from_val(A_SYL_ACTIONS);
489                 
490                 text = gtk_editable_get_chars(
491                         GTK_EDITABLE(prefs_toolbar->item_text_entry), 0 , -1);
492
493                 /* change the row */
494                 if (text != NULL) {
495                         gtk_list_store_set(store_set, &iter_set,
496                                            SET_ICON, pixbuf,
497                                            SET_FILENAME, prefs_toolbar->item_icon_file,
498                                            SET_TEXT, text,
499                                            SET_EVENT, icon_event,
500                                            SET_ICON_TEXT, NULL,
501                                            SET_ICON_IS_TEXT, FALSE,
502                                            -1);
503                 } else 
504                         alertpanel_error(ERROR_MSG_NO_TEXT);
505                                 
506                 g_free(text);
507                 g_free(set_event);
508                 if(item_type != ITEM_USER_ACTION)
509                         g_free(icon_event);             
510         }
511 }
512
513 static void prefs_toolbar_delete(GtkButton *button, ToolbarPage *prefs_toolbar)
514 {
515         GtkTreeView *list_view_set = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
516         GtkTreeModel *store_set = gtk_tree_view_get_model(list_view_set);
517         GtkTreeIter iter_set;
518         GtkTreePath *path;                                                      
519
520         if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set), NULL))
521                 return;
522         
523         if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
524                                                         (list_view_set),
525                                              NULL,
526                                              &iter_set))
527                 return;                                      
528
529         /* select prev list item, if deleted was first select next */
530         path = gtk_tree_model_get_path(store_set, &iter_set);
531         gtk_tree_path_prev(path);
532         
533         gtk_list_store_remove(GTK_LIST_STORE(store_set), &iter_set);
534
535         gtk_tree_selection_select_path(
536                         gtk_tree_view_get_selection(list_view_set),
537                         path);
538
539         gtk_tree_path_free(path);
540 }
541
542 static void prefs_toolbar_up(GtkButton *button, ToolbarPage *prefs_toolbar)
543 {
544         GtkTreePath *prev, *sel;
545         GtkTreeIter isel;
546         GtkListStore *store = NULL;
547         GtkTreeModel *model = NULL;
548         GtkTreeIter iprev;
549         
550         if (!gtk_tree_selection_get_selected
551                 (gtk_tree_view_get_selection
552                         (GTK_TREE_VIEW(prefs_toolbar->list_view_set)),
553                  &model,        
554                  &isel))
555                 return;
556         store = (GtkListStore *)model;
557
558         sel = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &isel);
559         if (!sel)
560                 return;
561         
562         /* no move if we're at row 0... */
563         prev = gtk_tree_path_copy(sel);
564         if (!gtk_tree_path_prev(prev)) {
565                 gtk_tree_path_free(prev);
566                 gtk_tree_path_free(sel);
567                 return;
568         }
569
570         gtk_tree_model_get_iter(GTK_TREE_MODEL(store),
571                                 &iprev, prev);
572         gtk_tree_path_free(sel);
573         gtk_tree_path_free(prev);
574
575         gtk_list_store_swap(store, &iprev, &isel);
576 }
577
578 static void prefs_toolbar_down(GtkButton *button, ToolbarPage *prefs_toolbar)
579 {
580         GtkListStore *store = NULL;
581         GtkTreeModel *model = NULL;
582         GtkTreeIter next, sel;
583         
584         if (!gtk_tree_selection_get_selected
585                 (gtk_tree_view_get_selection
586                         (GTK_TREE_VIEW(prefs_toolbar->list_view_set)),
587                  &model,
588                  &sel))
589                 return;
590
591         store = (GtkListStore *)model;
592         next = sel;
593         if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &next)) 
594                 return;
595
596         gtk_list_store_swap(store, &next, &sel);
597 }
598
599 static void item_type_changed(GtkComboBox *item_type_combo,
600                                 ToolbarPage *prefs_toolbar)
601 {
602         gint active = gtk_combo_box_get_active(item_type_combo);
603
604         switch(active) {
605         case ITEM_FUNCTION:
606                 gtk_widget_show(prefs_toolbar->item_func_combo);
607                 gtk_widget_hide(prefs_toolbar->item_action_combo);
608                 gtk_combo_box_set_active(
609                         GTK_COMBO_BOX(prefs_toolbar->item_func_combo), 0);
610                 gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
611                 gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, TRUE);
612                 gtk_widget_set_sensitive(prefs_toolbar->item_func_combo, TRUE);
613                 gtk_widget_set_sensitive(prefs_toolbar->icon_button, TRUE);
614
615                 func_selection_changed(GTK_COMBO_BOX(prefs_toolbar->item_func_combo),
616                                         prefs_toolbar);
617                 break;
618         case ITEM_USER_ACTION:
619                 gtk_widget_show(prefs_toolbar->item_action_combo);
620                 gtk_widget_hide(prefs_toolbar->item_func_combo);
621                 gtk_combo_box_set_active(
622                         GTK_COMBO_BOX(prefs_toolbar->item_action_combo), 0);
623                 gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
624                 gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, FALSE);
625                 gtk_widget_set_sensitive(prefs_toolbar->item_action_combo, TRUE);
626                 gtk_widget_set_sensitive(prefs_toolbar->icon_button, TRUE);
627                 
628                 action_selection_changed(GTK_COMBO_BOX(prefs_toolbar->item_action_combo),
629                                         prefs_toolbar);         
630                 break;
631         case ITEM_SEPARATOR:
632                 gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), _("None"));
633                 gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button), NULL);
634                 gtk_combo_box_set_active(
635                         GTK_COMBO_BOX(prefs_toolbar->item_func_combo), -1);
636                 gtk_combo_box_set_active(
637                         GTK_COMBO_BOX(prefs_toolbar->item_action_combo), -1);
638                 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry), "");
639                 gtk_widget_set_sensitive(prefs_toolbar->item_action_combo, FALSE);
640                 gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, FALSE);
641                 gtk_widget_set_sensitive(prefs_toolbar->item_func_combo, FALSE);
642                 gtk_widget_set_sensitive(prefs_toolbar->icon_button, FALSE);
643                 break;
644         }
645
646 }
647
648 static void action_selection_changed(GtkComboBox *action_combo,
649                                 ToolbarPage *prefs_toolbar)
650 {
651         gchar *text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(
652                            prefs_toolbar->item_action_combo));
653
654         if(text != NULL) { /* action */
655                 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry), text);
656                 g_free(text);
657         } 
658 }
659
660 static void func_selection_changed(GtkComboBox *action_combo,
661                                 ToolbarPage *prefs_toolbar)
662 {
663         gchar *text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(
664                            prefs_toolbar->item_func_combo));
665
666         if(text != NULL) { /* action */
667                 int action = -1;
668                 action = toolbar_ret_val_from_descr(text);
669                 if (action >= 0)
670                         gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry), 
671                                         toolbar_get_short_text(action));
672                 g_free(text);
673                 if (action >= 0) {
674                         StockPixmap stockp = toolbar_get_icon(action);
675                         if (stockp >= 0)  {
676                                 g_free(prefs_toolbar->item_icon_file);
677                                 prefs_toolbar->item_icon_file = g_strdup(stock_pixmap_get_name(stockp));
678
679                                 gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button),
680                                      stock_pixmap_widget(prefs_toolbar->window, stockp));
681                         }
682                 }
683         } 
684 }
685
686 static void prefs_toolbar_create(ToolbarPage *prefs_toolbar)
687 {
688         GtkWidget *main_vbox;
689         GtkWidget *toolbar_item_hbox;
690         GtkWidget *icon_vbox;
691         GtkWidget *icon_label;
692         GtkWidget *icon_button;
693         GtkWidget *icon_hbox;
694         GtkWidget *item_type_combo;
695         GtkWidget *item_action_combo;
696         GtkWidget *item_func_combo;
697         GtkWidget *reg_hbox;
698         GtkWidget *arrow;
699         GtkWidget *btn_hbox;
700 #ifdef MAEMO
701         GtkWidget *hbox;
702 #endif
703         GtkWidget *reg_btn;
704         GtkWidget *subst_btn;
705         GtkWidget *del_btn;
706         GtkWidget *default_btn;
707         GtkWidget *vbox_frame;
708         GtkWidget *table;
709         GtkWidget *label_icon_text;
710         GtkWidget *item_text_entry;
711         GtkWidget *vbox_toolbar_items;
712         GtkWidget *hbox_bottom;
713         GtkWidget *scrolledwindow_list_view_set;
714         GtkWidget *list_view_set;
715         GtkWidget *label;
716
717         GtkWidget *btn_vbox;
718         GtkWidget *up_btn;
719         GtkWidget *down_btn;
720
721         debug_print("Creating custom toolbar window...\n");
722
723         main_vbox = gtk_vbox_new(FALSE, 0);
724         gtk_widget_show(main_vbox);
725
726         vbox_frame = gtk_frame_new(_("Toolbar item"));
727         gtk_widget_show(vbox_frame);
728         gtk_box_pack_start(GTK_BOX(main_vbox), vbox_frame, FALSE, TRUE, 0);
729
730         toolbar_item_hbox = gtk_hbox_new (FALSE, 4);
731         gtk_widget_show(toolbar_item_hbox);
732         gtk_container_add(GTK_CONTAINER (vbox_frame), toolbar_item_hbox);
733         
734         table = gtk_table_new (3, 3, FALSE);
735         gtk_box_pack_start(GTK_BOX(toolbar_item_hbox), table,
736                            TRUE, TRUE, 0);
737         gtk_container_set_border_width (GTK_CONTAINER (table), 8);
738         gtk_table_set_row_spacings (GTK_TABLE (table), 8);
739         gtk_table_set_col_spacings (GTK_TABLE (table), 8);
740
741         /* toolbar item type */
742         label = gtk_label_new(_("Item type"));
743         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
744         gtk_widget_show(label);
745         gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
746                          (GtkAttachOptions) (GTK_FILL),
747                          (GtkAttachOptions) (0), 0, 0); 
748         
749         item_type_combo = gtk_combo_box_new_text();
750         gtk_widget_set_size_request(item_type_combo, 200, -1);
751         gtk_table_attach(GTK_TABLE(table), item_type_combo, 1, 3, 0, 1,
752                          (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
753                          (GtkAttachOptions) (0), 0, 0);
754
755         /* available actions */
756         label = gtk_label_new(_("Event executed on click"));
757         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
758         gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
759                           (GtkAttachOptions) (GTK_FILL),
760                           (GtkAttachOptions) (0), 0, 0);
761
762         item_action_combo = gtk_combo_box_new_text();
763         gtk_widget_set_size_request(item_action_combo, 200, -1);
764         gtk_table_attach (GTK_TABLE (table), item_action_combo, 1, 3, 1, 2,
765                           (GtkAttachOptions) (GTK_FILL),
766                           (GtkAttachOptions) (0), 0, 0);
767                           
768         /* available internal functions */
769         item_func_combo = gtk_combo_box_new_text();
770         gtk_widget_set_size_request(item_func_combo, 200, -1);
771         gtk_table_attach (GTK_TABLE (table), item_func_combo, 1, 3, 1, 2,
772                           (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
773                           (GtkAttachOptions) (0), 0, 0);
774         
775         /* toolbar item description */
776         label_icon_text = gtk_label_new(_("Toolbar text"));
777         gtk_misc_set_alignment(GTK_MISC(label_icon_text), 0, 0.5);
778         gtk_widget_show (label_icon_text);
779         gtk_table_attach (GTK_TABLE (table), label_icon_text, 0, 1, 2, 3,
780                           (GtkAttachOptions) (GTK_FILL),
781                           (GtkAttachOptions) (0), 0, 0);
782
783         item_text_entry = gtk_entry_new();
784         gtk_table_attach (GTK_TABLE (table), item_text_entry, 1, 3, 2, 3,
785                           (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
786                           (GtkAttachOptions) (0), 0, 0);
787
788         icon_vbox = gtk_vbox_new(FALSE, VBOX_BORDER);
789         gtk_widget_show(icon_vbox);
790         
791         icon_label = gtk_label_new(_("Icon"));
792         gtk_widget_set_size_request(icon_label, 100, -1);
793         gtk_box_pack_start(GTK_BOX(icon_vbox), icon_label, FALSE, FALSE, 0);
794         
795         icon_hbox = gtk_hbox_new(FALSE, 0);
796         gtk_widget_show(icon_hbox);
797         
798         label = gtk_label_new("");
799         gtk_box_pack_start(GTK_BOX(icon_hbox), label, TRUE, TRUE, 0);
800         
801         icon_button = gtk_button_new();
802         gtk_widget_show(icon_button);
803         gtk_widget_set_size_request(icon_button, 50, 50);
804         g_signal_connect(G_OBJECT(icon_button), "clicked",
805                          G_CALLBACK(icon_chooser_create), prefs_toolbar);
806         gtk_box_pack_start(GTK_BOX(icon_hbox), icon_button, FALSE, FALSE, 8);
807
808         label = gtk_label_new("");
809         gtk_box_pack_start(GTK_BOX(icon_hbox), label, TRUE, TRUE, 0);   
810         
811         gtk_box_pack_start(GTK_BOX(icon_vbox), icon_hbox, FALSE, FALSE, 0);
812         
813         gtk_box_pack_start(GTK_BOX(toolbar_item_hbox), icon_vbox, FALSE, FALSE, 0);
814                 
815         /* register / substitute / delete */
816         reg_hbox = gtk_hbox_new(FALSE, 4);
817         gtk_box_pack_start(GTK_BOX(main_vbox), reg_hbox, FALSE, FALSE, 0);
818         gtk_container_set_border_width(GTK_CONTAINER(reg_hbox), 10);
819
820         arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
821         gtk_box_pack_start(GTK_BOX(reg_hbox), arrow, FALSE, FALSE, 0);
822         gtk_widget_set_size_request(arrow, -1, 16);
823
824         btn_hbox = gtk_hbox_new(TRUE, 4);
825         gtk_box_pack_start(GTK_BOX(reg_hbox), btn_hbox, FALSE, FALSE, 0);
826
827         reg_btn = gtk_button_new_from_stock(GTK_STOCK_ADD);
828         gtk_box_pack_start(GTK_BOX(btn_hbox), reg_btn, FALSE, TRUE, 0);
829         g_signal_connect(G_OBJECT(reg_btn), "clicked",
830                          G_CALLBACK(prefs_toolbar_register), 
831                          prefs_toolbar);
832
833         subst_btn = gtkut_get_replace_btn(_("Replace"));
834         gtk_box_pack_start(GTK_BOX(btn_hbox), subst_btn, FALSE, TRUE, 0);
835         g_signal_connect(G_OBJECT(subst_btn), "clicked",
836                          G_CALLBACK(prefs_toolbar_substitute),
837                          prefs_toolbar);
838
839         del_btn = gtk_button_new_from_stock(GTK_STOCK_DELETE);
840         gtk_box_pack_start(GTK_BOX(btn_hbox), del_btn, FALSE, TRUE, 0);
841         g_signal_connect(G_OBJECT(del_btn), "clicked",
842                          G_CALLBACK(prefs_toolbar_delete), 
843                           prefs_toolbar);
844
845         default_btn = gtk_button_new_with_label(_(" Use default "));
846 #ifndef MAEMO
847         gtk_box_pack_end(GTK_BOX(reg_hbox), default_btn, FALSE, TRUE, 0);
848 #else
849         hbox = gtk_hbox_new(FALSE, 0);
850         gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);
851         gtk_box_pack_start(GTK_BOX(hbox), default_btn, FALSE, FALSE, 0);
852 #endif
853         g_signal_connect(G_OBJECT(default_btn), "clicked",
854                          G_CALLBACK(prefs_toolbar_default), 
855                          prefs_toolbar);
856
857         /* currently active toolbar items */
858         vbox_toolbar_items = gtk_vbox_new(FALSE, VBOX_BORDER);
859         gtk_box_pack_start(GTK_BOX(main_vbox), vbox_toolbar_items, TRUE, TRUE, 0);
860         
861         hbox_bottom = gtk_hbox_new(FALSE, 0);
862         gtk_container_add(GTK_CONTAINER(vbox_toolbar_items), hbox_bottom);
863         
864         scrolledwindow_list_view_set = gtk_scrolled_window_new(NULL, NULL);
865         gtk_box_pack_start(GTK_BOX(hbox_bottom), scrolledwindow_list_view_set, TRUE, TRUE, 0);
866         gtk_container_set_border_width(GTK_CONTAINER(scrolledwindow_list_view_set), 1);
867         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set), 
868                                         GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
869         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set),
870                                             GTK_SHADOW_IN);
871
872         list_view_set = create_set_list_view(prefs_toolbar); 
873         gtk_widget_show(list_view_set);
874         gtk_container_add(GTK_CONTAINER(scrolledwindow_list_view_set), list_view_set);
875         gtk_widget_set_size_request(list_view_set, 225, 120);
876
877         btn_vbox = gtk_vbox_new(FALSE, 8);
878         gtk_widget_show(btn_vbox);
879         gtk_box_pack_start(GTK_BOX(hbox_bottom), btn_vbox, FALSE, FALSE, 5);
880
881         up_btn = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
882         gtk_widget_show(up_btn);
883         gtk_box_pack_start(GTK_BOX(btn_vbox), up_btn, FALSE, FALSE, 2);
884
885         down_btn = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
886         gtk_widget_show(down_btn);
887         gtk_box_pack_start(GTK_BOX(btn_vbox), down_btn, FALSE, FALSE, 0);
888
889         g_signal_connect(G_OBJECT(item_type_combo), "changed",
890                          G_CALLBACK(item_type_changed), prefs_toolbar);
891         g_signal_connect(G_OBJECT(item_action_combo), "changed",
892                          G_CALLBACK(action_selection_changed), prefs_toolbar);
893         g_signal_connect(G_OBJECT(item_func_combo), "changed",
894                          G_CALLBACK(func_selection_changed), prefs_toolbar);
895         g_signal_connect(G_OBJECT(up_btn), "clicked",
896                          G_CALLBACK(prefs_toolbar_up), prefs_toolbar);
897         g_signal_connect(G_OBJECT(down_btn), "clicked",
898                          G_CALLBACK(prefs_toolbar_down), prefs_toolbar);
899         
900         gtk_widget_show_all(main_vbox);
901
902         prefs_toolbar->list_view_set    = list_view_set;
903         prefs_toolbar->item_text_entry  = item_text_entry;
904         prefs_toolbar->item_type_combo  = item_type_combo;
905         prefs_toolbar->item_func_combo  = item_func_combo;
906         prefs_toolbar->item_action_combo= item_action_combo;
907         prefs_toolbar->icon_button      = icon_button;
908         prefs_toolbar->item_icon_file   = NULL;
909         
910         prefs_toolbar->page.widget = main_vbox;
911 }
912
913 ToolbarPage *prefs_toolbar_mainwindow;
914 ToolbarPage *prefs_toolbar_composewindow;
915 ToolbarPage *prefs_toolbar_messageview;
916
917 void prefs_toolbar_init(void)
918 {
919         ToolbarPage *page;
920         static gchar *mainpath[3], *messagepath[3], *composepath[3];
921
922         mainpath[0] = _("Customize Toolbars");
923         mainpath[1] = _("Main Window");
924         mainpath[2] = NULL;
925
926         page = g_new0(ToolbarPage, 1);
927         page->page.path = mainpath;
928         page->page.create_widget = prefs_toolbar_create_widget;
929         page->page.destroy_widget = prefs_toolbar_destroy_widget;
930         page->page.save_page = prefs_toolbar_save;
931         page->source = TOOLBAR_MAIN;
932         page->page.weight = 50.0;
933         prefs_gtk_register_page((PrefsPage *) page);
934         prefs_toolbar_mainwindow = page;
935
936         messagepath[0] = _("Customize Toolbars");
937         messagepath[1] = _("Message Window");
938         messagepath[2] = NULL;
939
940         page = g_new0(ToolbarPage, 1);
941         page->page.path = messagepath;
942         page->page.create_widget = prefs_toolbar_create_widget;
943         page->page.destroy_widget = prefs_toolbar_destroy_widget;
944         page->page.save_page = prefs_toolbar_save;
945         page->source = TOOLBAR_MSGVIEW;
946         page->page.weight = 45.0;
947         prefs_gtk_register_page((PrefsPage *) page);
948         prefs_toolbar_messageview = page;
949
950         composepath[0] = _("Customize Toolbars");
951         composepath[1] = _("Compose Window");
952         composepath[2] = NULL;
953
954         page = g_new0(ToolbarPage, 1);
955         page->page.path = composepath;
956         page->page.create_widget = prefs_toolbar_create_widget;
957         page->page.destroy_widget = prefs_toolbar_destroy_widget;
958         page->page.save_page = prefs_toolbar_save;
959         page->source = TOOLBAR_COMPOSE;
960         page->page.weight = 40.0;
961         prefs_gtk_register_page((PrefsPage *) page);
962         prefs_toolbar_composewindow = page;
963 }
964
965 void prefs_toolbar_done(void)
966 {
967         prefs_gtk_unregister_page((PrefsPage *) prefs_toolbar_mainwindow);
968         g_free(prefs_toolbar_mainwindow->item_icon_file);
969         g_free(prefs_toolbar_mainwindow);
970         prefs_gtk_unregister_page((PrefsPage *) prefs_toolbar_composewindow);
971         g_free(prefs_toolbar_composewindow->item_icon_file);
972         g_free(prefs_toolbar_composewindow);
973         prefs_gtk_unregister_page((PrefsPage *) prefs_toolbar_messageview);
974         g_free(prefs_toolbar_messageview->item_icon_file);
975         g_free(prefs_toolbar_messageview);
976 }
977
978 static void set_visible_if_not_text(GtkTreeViewColumn *col,
979                                     GtkCellRenderer   *renderer,
980                                     GtkTreeModel      *model,
981                                     GtkTreeIter       *iter,
982                                     gpointer           user_data)
983 {
984         gboolean is_text;
985         GdkPixbuf *pixbuf;
986
987         gtk_tree_model_get(model, iter, SET_ICON_IS_TEXT, &is_text, -1);
988         if (is_text) {
989                 g_object_set(renderer, "visible", FALSE, NULL); 
990         } else {
991                 pixbuf = NULL;
992                 gtk_tree_model_get(model, iter, 
993                                    SET_ICON, &pixbuf,
994                                    -1);
995                 /* note getting a pixbuf from a tree model increases
996                  * its refcount ... */
997                 g_object_unref(pixbuf);
998                 
999                 g_object_set(renderer, "visible", TRUE, NULL);
1000                 g_object_set(renderer, "pixbuf",  pixbuf, NULL);
1001         }
1002 }
1003
1004 static GtkWidget *create_set_list_view(ToolbarPage *prefs_toolbar)
1005 {
1006         GtkTreeView *list_view;
1007         GtkListStore *store;
1008         GtkCellRenderer *renderer;
1009         GtkTreeViewColumn *column;
1010         GtkTreeSelection *selector;
1011
1012         store = gtk_list_store_new(N_SET_COLUMNS, 
1013                                    GDK_TYPE_PIXBUF,
1014                                    G_TYPE_STRING,
1015                                    G_TYPE_STRING,
1016                                    G_TYPE_STRING,
1017                                    G_TYPE_STRING,
1018                                    G_TYPE_BOOLEAN,
1019                                    -1);
1020         list_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)));
1021         g_object_unref(G_OBJECT(store));
1022
1023         column = gtk_tree_view_column_new();
1024         gtk_tree_view_column_set_title(column, _("Icon"));
1025         renderer = gtk_cell_renderer_pixbuf_new();
1026         gtk_tree_view_column_pack_start(column, renderer, FALSE);
1027         
1028         /* tell pixbuf renderer it is only visible if 
1029          * the icon is not represented by text */
1030         gtk_tree_view_column_set_cell_data_func(column, renderer,
1031                                                 set_visible_if_not_text,
1032                                                 NULL, NULL);
1033         
1034         renderer = gtk_cell_renderer_text_new();
1035         gtk_tree_view_column_pack_start(column, renderer, FALSE);
1036         
1037         /* tell the text renderer it is only visible if the icon
1038          * is represented by an image */
1039         gtk_tree_view_column_set_attributes(column, renderer,
1040                                             "visible", SET_ICON_IS_TEXT,
1041                                             "text", SET_ICON_TEXT,
1042                                             NULL);
1043
1044         gtk_tree_view_append_column(list_view, column);
1045
1046         column = gtk_tree_view_column_new();
1047         gtk_tree_view_column_set_title(column, _("Icon text"));
1048         renderer = gtk_cell_renderer_text_new();
1049         gtk_tree_view_column_pack_start(column, renderer, FALSE);
1050         gtk_tree_view_column_set_attributes(column, renderer,
1051                                             "text", SET_TEXT,
1052                                             NULL);
1053         gtk_tree_view_append_column(list_view, column);
1054
1055         column = gtk_tree_view_column_new();
1056         gtk_tree_view_column_set_title(column, _("Mapped event"));
1057         renderer = gtk_cell_renderer_text_new();
1058         gtk_tree_view_column_pack_start(column, renderer, FALSE);
1059         gtk_tree_view_column_set_attributes(column, renderer,
1060                                             "text", SET_EVENT,
1061                                             NULL);
1062         gtk_tree_view_append_column(list_view, column);
1063
1064         /* various other tree view attributes */
1065         gtk_tree_view_set_rules_hint(list_view, prefs_common.use_stripes_everywhere);
1066         
1067         selector = gtk_tree_view_get_selection(list_view);
1068         gtk_tree_selection_set_mode(selector, GTK_SELECTION_BROWSE);
1069         gtk_tree_selection_set_select_function
1070                 (selector, (GtkTreeSelectionFunc) set_list_selected,
1071                  prefs_toolbar, NULL);
1072
1073         return GTK_WIDGET(list_view);   
1074
1075 }
1076
1077 static gboolean set_list_selected(GtkTreeSelection *selector,
1078                                   GtkTreeModel *model, 
1079                                   GtkTreePath *path,
1080                                   gboolean currently_selected,
1081                                   ToolbarPage *prefs_toolbar)
1082 {
1083
1084         GtkTreeIter iter;
1085         gchar *icon_text, *icon_file, *descr;
1086         GList *cur;
1087         GSList *cur2;
1088         gint item_num;
1089         GdkPixbuf *pix;
1090         
1091         if (currently_selected || !gtk_tree_model_get_iter(model, &iter, path))
1092                 return TRUE;
1093         
1094         gtk_tree_model_get(model, &iter,
1095                            SET_ICON, &pix,
1096                            SET_TEXT, &icon_text,
1097                            SET_EVENT, &descr,
1098                            SET_FILENAME, &icon_file,
1099                            -1);
1100         
1101         g_free(prefs_toolbar->item_icon_file);
1102         prefs_toolbar->item_icon_file = icon_file;
1103         gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button),
1104                              gtk_image_new_from_pixbuf(pix));
1105         
1106         if (g_utf8_collate(toolbar_ret_descr_from_val(A_SEPARATOR), descr) == 0) {
1107                 gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button),
1108                                     _("None"));
1109                 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo),
1110                                         ITEM_SEPARATOR);
1111                 g_free(icon_text);
1112                 g_free(descr);
1113
1114                 return TRUE;
1115         }
1116         
1117         gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
1118         gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry), 
1119                            icon_text);
1120
1121         if (g_utf8_collate(toolbar_ret_descr_from_val(A_SYL_ACTIONS), descr) == 0) {
1122                 gtk_combo_box_set_active(GTK_COMBO_BOX(
1123                         prefs_toolbar->item_type_combo), ITEM_USER_ACTION);
1124
1125                 for(cur2 = prefs_common.actions_list, item_num = 0; cur2 != NULL;
1126                     cur2 = cur2->next) {
1127                         gchar *item_string;
1128                         get_action_name((gchar *)cur2->data, &item_string);
1129                         
1130                         if(g_utf8_collate(item_string, icon_text) == 0) {
1131                                 gtk_combo_box_set_active(
1132                                         GTK_COMBO_BOX(prefs_toolbar->item_action_combo),
1133                                         item_num);
1134                                 g_free(item_string);
1135                                 break;
1136                         }
1137                         else {
1138                                 item_num++;
1139                                 g_free(item_string);
1140                         }
1141                 }
1142                 
1143                 g_free(icon_text);
1144                 g_free(descr);
1145
1146                 return TRUE;
1147         }
1148         
1149         /* scan combo list for selected description an set combo item accordingly */
1150         for (cur = prefs_toolbar->combo_action_list, item_num = 0; cur != NULL; 
1151              cur = cur->next) {
1152                 gchar *item_str = (gchar*)cur->data;
1153                 if (g_utf8_collate(item_str, descr) == 0) {
1154                         gtk_combo_box_set_active(
1155                                 GTK_COMBO_BOX(prefs_toolbar->item_func_combo),
1156                                 item_num);
1157                         
1158                         break;
1159                 }
1160                 else
1161                         item_num++;
1162         }
1163
1164         gtk_combo_box_set_active(GTK_COMBO_BOX(
1165                         prefs_toolbar->item_type_combo),ITEM_FUNCTION);
1166
1167         g_free(icon_text);
1168         g_free(descr);
1169
1170         return TRUE;
1171 }
1172
1173 static void icon_chooser_ok_clicked(GtkButton *button,
1174                                         ToolbarPage *prefs_toolbar)
1175 {
1176         GtkTreeModel *model;
1177         GtkTreeIter iter;
1178         GdkPixbuf *pix;
1179         gchar *icon_file;
1180         
1181         g_return_if_fail(prefs_toolbar != NULL);
1182         
1183         if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
1184                         (GTK_TREE_VIEW(prefs_toolbar->icon_chooser_list)),
1185                         &model, &iter))
1186                 return;
1187         
1188         gtk_tree_model_get(model, &iter,
1189                            SET_ICON, &pix,
1190                            SET_FILENAME, &icon_file,
1191                            -1);
1192
1193         g_free(prefs_toolbar->item_icon_file);
1194         prefs_toolbar->item_icon_file = icon_file;
1195
1196         gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button),
1197                              gtk_image_new_from_pixbuf(pix));
1198         
1199         gtk_widget_destroy(prefs_toolbar->icon_chooser_win);
1200         prefs_toolbar->icon_chooser_win = NULL;
1201         prefs_toolbar->icon_chooser_list = NULL;
1202 }
1203
1204 static void icon_chooser_cancel_clicked(GtkButton *button,
1205                                         ToolbarPage *prefs_toolbar)
1206 {
1207         g_return_if_fail(prefs_toolbar != NULL);
1208
1209         gtk_widget_destroy(prefs_toolbar->icon_chooser_win);
1210         prefs_toolbar->icon_chooser_win = NULL;
1211         prefs_toolbar->icon_chooser_list = NULL;
1212 }
1213
1214 static gboolean icon_chooser_key_pressed(GtkWidget *widget, GdkEventKey *event,
1215                         ToolbarPage *prefs_toolbar)
1216 {
1217         if (event && event->keyval == GDK_Escape) {
1218                 icon_chooser_cancel_clicked(NULL, prefs_toolbar);
1219                 return TRUE;
1220         }
1221
1222         return FALSE;
1223 }
1224
1225 static void icon_chooser_tree_activated(GtkTreeView *treeview, GtkTreePath *path,
1226                                      GtkTreeViewColumn *column, ToolbarPage *prefs_toolbar)
1227 {
1228         icon_chooser_ok_clicked(NULL, prefs_toolbar);
1229 }
1230
1231 static void icon_chooser_create(GtkButton *button, ToolbarPage *prefs_toolbar)
1232 {
1233         static GtkWidget *icon_chooser_win;
1234         GtkWidget *label;
1235         GtkWidget *scrollwin;
1236         GtkWidget *vbox;
1237         GtkWidget *confirm_area;
1238         GtkWidget *ok_btn;
1239         GtkWidget *cancel_btn;
1240         GtkTreeView *list_view;
1241         GtkListStore *store;
1242         GtkTreeSelection *selector;
1243         GtkTreeViewColumn *column;
1244         GtkCellRenderer *renderer;
1245         GtkTreeIter iter;
1246         gint i;
1247         
1248         store = gtk_list_store_new(2, 
1249                                    GDK_TYPE_PIXBUF,
1250                                    G_TYPE_STRING,
1251                                    -1);
1252                                    
1253         gtk_list_store_clear(store);
1254
1255         for (i = 0; i < STOCK_PIXMAP_EMPTY; i++) {
1256                 GdkPixbuf *pixbuf;
1257                 if (i == STOCK_PIXMAP_CLAWS_MAIL_LOGO) /* that's too big */
1258                         continue;
1259
1260                 stock_pixbuf_gdk(prefs_toolbar->window, i, &pixbuf);
1261                 
1262                 gtk_list_store_append(store, &iter);
1263                 gtk_list_store_set(store, &iter,
1264                                    SET_ICON, pixbuf,
1265                                    SET_FILENAME, stock_pixmap_get_name((StockPixmap) i),
1266                                    -1);
1267         }
1268         
1269         icon_chooser_win = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "prefs_toolbar");
1270         gtk_window_set_title(GTK_WINDOW(icon_chooser_win), _("Toolbar item icon"));
1271         gtk_window_set_position(GTK_WINDOW(icon_chooser_win), GTK_WIN_POS_CENTER);
1272         gtk_window_set_resizable(GTK_WINDOW(icon_chooser_win), FALSE);
1273         gtk_widget_set_size_request(icon_chooser_win, 300, 250);
1274         
1275         vbox = gtk_vbox_new(FALSE, 5);
1276         gtk_widget_show(vbox);
1277         gtk_container_set_border_width(GTK_CONTAINER(vbox), VBOX_BORDER);
1278         gtk_container_add(GTK_CONTAINER(icon_chooser_win), vbox);
1279         
1280         label = gtk_label_new(_("Choose icon:"));
1281         gtk_widget_show(label);
1282         gtk_misc_set_alignment(GTK_MISC(label), 0, -1);
1283         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
1284         
1285         scrollwin = gtk_scrolled_window_new(NULL, NULL);
1286         gtk_widget_show(scrollwin);
1287         gtk_box_pack_start(GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0);
1288         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
1289                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1290         
1291         list_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)));
1292         gtk_widget_show(GTK_WIDGET(list_view));
1293         
1294         column = gtk_tree_view_column_new();
1295
1296         renderer = gtk_cell_renderer_pixbuf_new();
1297         gtk_tree_view_column_pack_start(column, renderer, FALSE);
1298         gtk_tree_view_column_set_attributes(column, renderer,
1299                                             "pixbuf", SET_ICON, 
1300                                             NULL);
1301
1302         gtk_tree_view_append_column(list_view, column);
1303
1304         column = gtk_tree_view_column_new();
1305         renderer = gtk_cell_renderer_text_new();
1306         gtk_tree_view_column_pack_start(column, renderer, TRUE);
1307         gtk_tree_view_column_set_attributes(column, renderer,
1308                                             "text", SET_FILENAME,
1309                                             NULL);
1310         
1311         gtk_tree_view_append_column(list_view, column);
1312
1313         gtk_tree_view_set_rules_hint(list_view, prefs_common.use_stripes_everywhere);
1314         gtk_tree_view_set_headers_visible(list_view, FALSE);
1315         
1316         selector = gtk_tree_view_get_selection(list_view);
1317         gtk_tree_selection_set_mode(selector, GTK_SELECTION_SINGLE);
1318
1319         gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
1320         gtk_tree_selection_select_iter(gtk_tree_view_get_selection
1321                                                 (list_view), &iter);
1322         gtk_container_add(GTK_CONTAINER(scrollwin), GTK_WIDGET(list_view));
1323
1324         gtkut_stock_button_set_create(&confirm_area, &cancel_btn, GTK_STOCK_CANCEL,
1325                                       &ok_btn, GTK_STOCK_OK, NULL, NULL);
1326
1327         gtk_box_pack_start(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
1328         gtk_widget_show(confirm_area);
1329         gtk_widget_grab_default(ok_btn);
1330
1331         g_signal_connect(G_OBJECT(ok_btn), "clicked",
1332                          G_CALLBACK(icon_chooser_ok_clicked), prefs_toolbar);
1333         g_signal_connect(G_OBJECT(cancel_btn), "clicked",
1334                          G_CALLBACK(icon_chooser_cancel_clicked), prefs_toolbar);
1335         g_signal_connect(G_OBJECT(icon_chooser_win), "key_press_event",
1336                          G_CALLBACK(icon_chooser_key_pressed), prefs_toolbar);
1337         g_signal_connect(G_OBJECT(list_view), "row-activated",
1338                          G_CALLBACK(icon_chooser_tree_activated), prefs_toolbar);
1339
1340         gtk_widget_show_all(icon_chooser_win);
1341         gtk_window_set_modal(GTK_WINDOW(icon_chooser_win), TRUE);
1342         
1343         prefs_toolbar->icon_chooser_win         = icon_chooser_win;
1344         prefs_toolbar->icon_chooser_list        = GTK_WIDGET(list_view);
1345 }