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