2012-11-30 [wwp] 3.9.0cvs31
[claws.git] / src / toolbar.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2001-2012 Hiroyuki Yamamoto and the Claws Mail team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  * 
18  */
19
20 /*
21  * General functions for accessing address book files.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #include "claws-features.h"
27 #endif
28
29 #include "defs.h"
30
31 #include <glib.h>
32 #include <glib/gi18n.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <dirent.h>
36 #include <sys/stat.h>
37 #include <math.h>
38 #include <setjmp.h>
39
40 #include "main.h"
41 #include "mainwindow.h"
42 #include "summaryview.h"
43 #include "compose.h"
44 #include "utils.h"
45 #include "xml.h"
46 #include "mgutils.h"
47 #include "prefs_gtk.h"
48 #include "codeconv.h"
49 #include "stock_pixmap.h"
50 #include "manage_window.h"
51 #include "gtkutils.h"
52 #include "toolbar.h"
53 #include "menu.h"
54 #include "inc.h"
55 #include "action.h"
56 #include "prefs_actions.h"
57 #include "prefs_common.h"
58 #include "prefs_toolbar.h"
59 #include "alertpanel.h"
60 #include "imap.h"
61 #include "account.h"
62 #ifndef USE_NEW_ADDRBOOK
63         #include "addressbook.h"
64 #else
65         #include "addressbook-dbus.h"
66 #endif
67
68 /* elements */
69 #define TOOLBAR_TAG_INDEX        "toolbar"
70 #define TOOLBAR_TAG_ITEM         "item"
71 #define TOOLBAR_TAG_SEPARATOR    "separator"
72
73 #define TOOLBAR_ICON_FILE   "file"    
74 #define TOOLBAR_ICON_TEXT   "text"     
75 #define TOOLBAR_ICON_ACTION "action"    
76
77 static void toolbar_init(Toolbar * toolbar);
78 static gboolean      toolbar_is_duplicate               (gint           action,
79                                                  ToolbarType    source);
80 static void   toolbar_parse_item                (XMLFile        *file,
81                                                  ToolbarType    source);
82
83 static gint   toolbar_ret_val_from_text         (const gchar    *text);
84 static gchar *toolbar_ret_text_from_val         (gint           val);
85
86 static void   toolbar_set_default_main          (void);
87 static void   toolbar_set_default_compose       (void);
88 static void   toolbar_set_default_msgview       (void);
89
90 static void     toolbar_style                   (ToolbarType     type, 
91                                                  guint           action, 
92                                                  gpointer        data);
93
94 static MainWindow *get_mainwin                  (gpointer data);
95 static void activate_compose_button             (Toolbar        *toolbar,
96                                                  ToolbarStyle    style,
97                                                  ComposeButtonType type);
98
99 /* toolbar callbacks */
100 static void toolbar_reply                       (gpointer        data, 
101                                                  guint           action);
102 static void toolbar_learn                       (gpointer        data, 
103                                                  guint           action);
104 static void toolbar_delete_cb                   (GtkWidget      *widget,
105                                                  gpointer        data);
106 static void toolbar_trash_cb                    (GtkWidget      *widget,
107                                                  gpointer        data);
108
109 static void toolbar_compose_cb                  (GtkWidget      *widget,
110                                                  gpointer        data);
111
112 static void toolbar_learn_cb                    (GtkWidget      *widget,
113                                                  gpointer        data);
114
115 static void toolbar_reply_cb                    (GtkWidget      *widget,
116                                                  gpointer        data);
117
118 static void toolbar_reply_to_all_cb             (GtkWidget      *widget,
119                                                  gpointer        data);
120
121 static void toolbar_reply_to_list_cb            (GtkWidget      *widget,
122                                                  gpointer        data);
123
124 static void toolbar_reply_to_sender_cb          (GtkWidget      *widget,
125                                                  gpointer        data);
126
127 static void toolbar_forward_cb                  (GtkWidget      *widget,
128                                                  gpointer        data);
129
130 static void toolbar_prev_unread_cb              (GtkWidget      *widget,
131                                                  gpointer        data);
132 static void toolbar_next_unread_cb              (GtkWidget      *widget,
133                                                  gpointer        data);
134
135 static void toolbar_ignore_thread_cb            (GtkWidget      *widget,
136                                                  gpointer        data);
137
138 static void toolbar_watch_thread_cb             (GtkWidget      *widget,
139                                                  gpointer        data);
140
141 static void toolbar_print_cb                    (GtkWidget      *widget,
142                                                  gpointer        data);
143
144 static void toolbar_actions_execute_cb          (GtkWidget      *widget,
145                                                  gpointer        data);
146 static void toolbar_plugins_execute_cb      (GtkWidget      *widget,
147                              gpointer        data);
148
149
150 static void toolbar_send_cb                     (GtkWidget      *widget,
151                                                  gpointer        data);
152 static void toolbar_send_later_cb               (GtkWidget      *widget,
153                                                  gpointer        data);
154 static void toolbar_draft_cb                    (GtkWidget      *widget,
155                                                  gpointer        data);
156 static void toolbar_close_cb                    (GtkWidget      *widget,
157                                                  gpointer        data);
158 static void toolbar_preferences_cb              (GtkWidget      *widget,
159                                                  gpointer        data);
160 static void toolbar_open_mail_cb                (GtkWidget      *widget,
161                                                  gpointer        data);
162 static void toolbar_insert_cb                   (GtkWidget      *widget,
163                                                  gpointer        data);
164 static void toolbar_attach_cb                   (GtkWidget      *widget,
165                                                  gpointer        data);
166 static void toolbar_sig_cb                      (GtkWidget      *widget,
167                                                  gpointer        data);
168 static void toolbar_ext_editor_cb               (GtkWidget      *widget,
169                                                  gpointer        data);
170 static void toolbar_linewrap_current_cb         (GtkWidget      *widget,
171                                                  gpointer        data);
172 static void toolbar_linewrap_all_cb             (GtkWidget      *widget,
173                                                  gpointer        data);
174 static void toolbar_addrbook_cb                 (GtkWidget      *widget, 
175                                                  gpointer        data);
176 #ifdef USE_ENCHANT
177 static void toolbar_check_spelling_cb           (GtkWidget      *widget, 
178                                                  gpointer        data);
179 #endif
180 static void toolbar_cancel_inc_cb               (GtkWidget      *widget,
181                                                  gpointer        data);
182 static void toolbar_cancel_send_cb              (GtkWidget      *widget,
183                                                  gpointer        data);
184 static void toolbar_cancel_all_cb               (GtkWidget      *widget,
185                                                  gpointer        data);
186
187 struct {
188         gchar *index_str;
189         const gchar *descr;
190 } toolbar_text [] = {
191         { "A_RECEIVE_ALL",      N_("Receive Mail from all Accounts")       },
192         { "A_RECEIVE_CUR",      N_("Receive Mail from current Account")    },
193         { "A_SEND_QUEUED",      N_("Send Queued Messages")                 },
194         { "A_COMPOSE_EMAIL",    N_("Compose Email")                        },
195         { "A_COMPOSE_NEWS",     N_("Compose News")                         },
196         { "A_REPLY_MESSAGE",    N_("Reply to Message")                     },
197         { "A_REPLY_SENDER",     N_("Reply to Sender")                      },
198         { "A_REPLY_ALL",        N_("Reply to All")                         },
199         { "A_REPLY_ML",         N_("Reply to Mailing-list")                },
200         { "A_OPEN_MAIL",        N_("Open email")                           },
201         { "A_FORWARD",          N_("Forward Message")                      }, 
202         { "A_TRASH",            N_("Trash Message")                        },
203         { "A_DELETE_REAL",      N_("Delete Message")                       },
204         { "A_EXECUTE",          N_("Execute")                              },
205         { "A_GOTO_PREV",        N_("Go to Previous Unread Message")        },
206         { "A_GOTO_NEXT",        N_("Go to Next Unread Message")            },
207         { "A_IGNORE_THREAD",    N_("Ignore thread")                        },
208         { "A_WATCH_THREAD",     N_("Watch thread")                         },
209         { "A_PRINT",            N_("Print")                                },
210         { "A_LEARN_SPAM",       N_("Learn Spam or Ham")                    },
211         { "A_GO_FOLDERS",       N_("Open folder/Go to folder list")        },
212         { "A_PREFERENCES",      N_("Preferences")                          },
213
214         { "A_SEND",             N_("Send Message")                         },
215         { "A_SENDL",            N_("Put into queue folder and send later") },
216         { "A_DRAFT",            N_("Save to draft folder")                 },
217         { "A_INSERT",           N_("Insert file")                          },   
218         { "A_ATTACH",           N_("Attach file")                          },
219         { "A_SIG",              N_("Insert signature")                     },
220         { "A_EXTEDITOR",        N_("Edit with external editor")            },
221         { "A_LINEWRAP_CURRENT", N_("Wrap long lines of current paragraph") }, 
222         { "A_LINEWRAP_ALL",     N_("Wrap all long lines")                  }, 
223         { "A_ADDRBOOK",         N_("Address book")                         },
224 #ifdef USE_ENCHANT
225         { "A_CHECK_SPELLING",   N_("Check spelling")                       },
226 #endif
227         { "A_CLAWS_ACTIONS",    N_("Claws Mail Actions Feature")           }, 
228         { "A_CANCEL_INC",       N_("Cancel receiving")                     },
229         { "A_CANCEL_SEND",      N_("Cancel sending")                       },
230         { "A_CANCEL_ALL",       N_("Cancel receiving/sending")             },
231         { "A_CLOSE",            N_("Close window")                         },
232         { "A_SEPARATOR",        N_("Separator")                            },
233         { "A_CLAWS_PLUGINS",    N_("Claws Mail Plugins")                   },
234 };
235
236 /* struct holds configuration files and a list of
237  * currently active toolbar items 
238  * TOOLBAR_MAIN, TOOLBAR_COMPOSE and TOOLBAR_MSGVIEW
239  * give us an index
240  */
241 struct {
242         const gchar  *conf_file;
243         GSList       *item_list;
244 } toolbar_config[3] = {
245         { "toolbar_main.xml",    NULL},
246         { "toolbar_compose.xml", NULL}, 
247         { "toolbar_msgview.xml", NULL}
248 };
249
250 gint toolbar_ret_val_from_descr(const gchar *descr)
251 {
252         gint i;
253
254         for (i = 0; i < N_ACTION_VAL; i++) {
255                 if (g_utf8_collate(gettext(toolbar_text[i].descr), descr) == 0)
256                                 return i;
257         }
258         
259         return -1;
260 }
261
262 gchar *toolbar_ret_descr_from_val(gint val)
263 {
264         cm_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL);
265
266         return gettext(toolbar_text[val].descr);
267 }
268
269 static gint toolbar_ret_val_from_text(const gchar *text)
270 {
271         gint i;
272         
273         for (i = 0; i < N_ACTION_VAL; i++) {
274                 if (g_utf8_collate(toolbar_text[i].index_str, text) == 0)
275                                 return i;
276         }
277
278         return -1;
279 }
280
281 static gchar *toolbar_ret_text_from_val(gint val)
282 {
283         cm_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL);
284
285         return toolbar_text[val].index_str;
286 }
287
288 static gboolean toolbar_is_duplicate(gint action, ToolbarType source)
289 {
290         GSList *cur;
291
292         if ((action == A_SEPARATOR) || (action == A_CLAWS_ACTIONS) || (action == A_CLAWS_PLUGINS))
293                 return FALSE;
294
295         for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
296                 ToolbarItem *item = (ToolbarItem*) cur->data;
297                 
298                 if (item->index == action)
299                         return TRUE;
300         }
301         return FALSE;
302 }
303
304 /* depending on toolbar type this function 
305    returns a list of available toolbar events being 
306    displayed by prefs_toolbar
307 */
308 GList *toolbar_get_action_items(ToolbarType source)
309 {
310         GList *items = NULL;
311         gint i = 0;
312         
313         if (source == TOOLBAR_MAIN) {
314                 gint main_items[] = { A_RECEIVE_ALL,   A_RECEIVE_CUR,   A_SEND_QUEUED,
315                                         A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER, 
316                                         A_REPLY_ALL,     A_REPLY_ML,      A_OPEN_MAIL,     A_FORWARD, 
317                                         A_TRASH,         A_DELETE_REAL,   A_EXECUTE,       A_GOTO_PREV, 
318                                         A_GOTO_NEXT,     A_IGNORE_THREAD, A_WATCH_THREAD,  A_PRINT,
319                                         A_ADDRBOOK,      A_LEARN_SPAM,    A_GO_FOLDERS, 
320                                         A_CANCEL_INC,    A_CANCEL_SEND,   A_CANCEL_ALL,    A_PREFERENCES };
321
322                 for (i = 0; i < sizeof main_items / sizeof main_items[0]; i++)  {
323                         items = g_list_append(items, gettext(toolbar_text[main_items[i]].descr));
324                 }       
325         }
326         else if (source == TOOLBAR_COMPOSE) {
327                 gint comp_items[] =   { A_SEND,          A_SENDL,        A_DRAFT,
328                                         A_INSERT,        A_ATTACH,       A_SIG,
329                                         A_EXTEDITOR,     A_LINEWRAP_CURRENT,     
330                                         A_LINEWRAP_ALL,  A_ADDRBOOK,
331 #ifdef USE_ENCHANT
332                                         A_CHECK_SPELLING, 
333 #endif
334                                         A_CLOSE };      
335
336                 for (i = 0; i < sizeof comp_items / sizeof comp_items[0]; i++) 
337                         items = g_list_append(items, gettext(toolbar_text[comp_items[i]].descr));
338         }
339         else if (source == TOOLBAR_MSGVIEW) {
340                 gint msgv_items[] =   { A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER,
341                                         A_REPLY_ALL,     A_REPLY_ML,      A_FORWARD,
342                                         A_TRASH, A_DELETE_REAL,       A_GOTO_PREV,        A_GOTO_NEXT,
343                                         A_ADDRBOOK,      A_LEARN_SPAM, A_CLOSE };       
344
345                 for (i = 0; i < sizeof msgv_items / sizeof msgv_items[0]; i++) 
346                         items = g_list_append(items, gettext(toolbar_text[msgv_items[i]].descr));
347         }
348
349         return items;
350 }
351
352 static void toolbar_parse_item(XMLFile *file, ToolbarType source)
353 {
354         GList *attr;
355         gchar *name, *value;
356         ToolbarItem *item = NULL;
357         gboolean rewrite = FALSE;
358
359         attr = xml_get_current_tag_attr(file);
360         item = g_new0(ToolbarItem, 1);
361         while( attr ) {
362                 name = ((XMLAttr *)attr->data)->name;
363                 value = ((XMLAttr *)attr->data)->value;
364                 
365                 if (g_utf8_collate(name, TOOLBAR_ICON_FILE) == 0) 
366                         item->file = g_strdup (value);
367                 else if (g_utf8_collate(name, TOOLBAR_ICON_TEXT) == 0)
368                         item->text = g_strdup (*value ? gettext(value):"");
369                 else if (g_utf8_collate(name, TOOLBAR_ICON_ACTION) == 0)
370                         item->index = toolbar_ret_val_from_text(value);
371                 if (item->index == -1 && !strcmp(value, "A_DELETE")) {
372                         /* switch button */
373                         item->index = A_TRASH;
374                         g_free(item->file);
375                         item->file = g_strdup("trash_btn");
376                         g_free(item->text);
377                         item->text = g_strdup(C_("Toolbar", "Trash"));
378                         rewrite = TRUE;
379                 }
380                 if (item->index == -1 && !strcmp(value, "A_SYL_ACTIONS")) {
381                         /* switch button */
382                         item->index = A_CLAWS_ACTIONS;
383                         rewrite = TRUE;
384                 }
385                 attr = g_list_next(attr);
386         }
387         if (item->index != -1) {
388                 
389                 if (!toolbar_is_duplicate(item->index, source)) 
390                         toolbar_config[source].item_list = g_slist_append(toolbar_config[source].item_list,
391                                                                          item);
392         }
393         if (rewrite) {
394                 toolbar_save_config_file(source);
395         }
396 }
397
398 const gchar *toolbar_get_short_text(int action) {
399         switch(action) {
400         case A_GO_FOLDERS:      return _("Folders");
401         case A_OPEN_MAIL:       return _("Open");
402         case A_RECEIVE_ALL:     return _("Get Mail");
403         case A_RECEIVE_CUR:     return _("Get");
404         case A_SEND_QUEUED:     return _("Send");
405         case A_COMPOSE_EMAIL:   return C_("Toolbar", "Compose");
406         case A_COMPOSE_NEWS:    return C_("Toolbar", "Compose");
407         case A_REPLY_MESSAGE:   return _("Reply");
408         case A_REPLY_ALL:       return _("All");
409         case A_REPLY_SENDER:    return C_("Toolbar", "Sender");
410         case A_REPLY_ML:        return _("List");
411         case A_FORWARD:         return _("Forward");
412         case A_TRASH:           return C_("Toolbar", "Trash");
413         case A_DELETE_REAL:     return _("Delete");
414         case A_LEARN_SPAM:      return _("Spam");
415         case A_GOTO_PREV:       return _("Prev");
416         case A_GOTO_NEXT:       return _("Next");
417         case A_IGNORE_THREAD:   return _("Ignore thread");
418         case A_WATCH_THREAD:    return _("Watch thread");
419         case A_PRINT:           return _("Print");
420         case A_CLOSE:           return _("Close");
421         case A_PREFERENCES:     return _("Preferences");
422         case A_SEND:            return _("Send");
423         case A_SENDL:           return _("Send later");
424         case A_DRAFT:           return _("Draft");
425         case A_INSERT:          return _("Insert");
426         case A_ATTACH:          return _("Attach");
427         case A_SIG:             return _("Insert sig.");
428         case A_EXTEDITOR:       return _("Edit");
429         case A_LINEWRAP_CURRENT:return _("Wrap para.");
430         case A_LINEWRAP_ALL:    return _("Wrap all");
431         case A_ADDRBOOK:        return _("Address");
432         case A_CANCEL_INC:      return _("Stop");
433         case A_CANCEL_SEND:     return _("Stop");
434         case A_CANCEL_ALL:      return _("Stop all");
435         case A_EXECUTE:         return _("Execute");
436         #ifdef USE_ENCHANT
437         case A_CHECK_SPELLING:  return _("Check spelling");
438         #endif
439         default:                return "";
440         }
441 }
442
443 gint toolbar_get_icon(int action) {
444         switch(action) {
445         case A_GO_FOLDERS:      return STOCK_PIXMAP_GO_FOLDERS;
446         case A_OPEN_MAIL:       return STOCK_PIXMAP_OPEN_MAIL;
447         case A_RECEIVE_ALL:     return STOCK_PIXMAP_MAIL_RECEIVE_ALL;
448         case A_RECEIVE_CUR:     return STOCK_PIXMAP_MAIL_RECEIVE;
449         case A_SEND_QUEUED:     return STOCK_PIXMAP_MAIL_SEND_QUEUE;
450         case A_COMPOSE_EMAIL:   return STOCK_PIXMAP_MAIL_COMPOSE;
451         case A_COMPOSE_NEWS:    return STOCK_PIXMAP_NEWS_COMPOSE;
452         case A_REPLY_MESSAGE:   return STOCK_PIXMAP_MAIL_REPLY;
453         case A_REPLY_ALL:       return STOCK_PIXMAP_MAIL_REPLY_TO_ALL;
454         case A_REPLY_SENDER:    return STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR;
455         case A_REPLY_ML:        return STOCK_PIXMAP_MAIL_REPLY_TO_LIST;
456         case A_FORWARD:         return STOCK_PIXMAP_MAIL_FORWARD;
457         case A_TRASH:           return STOCK_PIXMAP_TRASH;
458         case A_DELETE_REAL:     return STOCK_PIXMAP_DELETE;
459         case A_LEARN_SPAM:      return STOCK_PIXMAP_SPAM_BTN;
460         case A_GOTO_PREV:       return STOCK_PIXMAP_UP_ARROW;
461         case A_GOTO_NEXT:       return STOCK_PIXMAP_DOWN_ARROW;
462         case A_IGNORE_THREAD:   return STOCK_PIXMAP_IGNORETHREAD;
463         case A_WATCH_THREAD:    return STOCK_PIXMAP_WATCHTHREAD;
464         case A_PRINT:           return STOCK_PIXMAP_PRINTER;
465         case A_CLOSE:           return STOCK_PIXMAP_CLOSE;
466         case A_PREFERENCES:     return STOCK_PIXMAP_PREFERENCES;
467         case A_SEND:            return STOCK_PIXMAP_MAIL_SEND;
468         case A_SENDL:           return STOCK_PIXMAP_MAIL_SEND_QUEUE;
469         case A_DRAFT:           return STOCK_PIXMAP_MAIL;
470         case A_INSERT:          return STOCK_PIXMAP_INSERT_FILE;
471         case A_ATTACH:          return STOCK_PIXMAP_MAIL_ATTACH;
472         case A_SIG:             return STOCK_PIXMAP_MAIL_SIGN;
473         case A_EXTEDITOR:       return STOCK_PIXMAP_EDIT_EXTERN;
474         case A_LINEWRAP_CURRENT:return STOCK_PIXMAP_LINEWRAP_CURRENT;
475         case A_LINEWRAP_ALL:    return STOCK_PIXMAP_LINEWRAP_ALL;
476         case A_ADDRBOOK:        return STOCK_PIXMAP_ADDRESS_BOOK;
477         case A_CANCEL_INC:      return STOCK_PIXMAP_CANCEL;
478         case A_CANCEL_SEND:     return STOCK_PIXMAP_CANCEL;
479         case A_CANCEL_ALL:      return STOCK_PIXMAP_CANCEL;
480         case A_EXECUTE:         return STOCK_PIXMAP_EXEC;
481         #ifdef USE_ENCHANT
482         case A_CHECK_SPELLING:  return STOCK_PIXMAP_CHECK_SPELLING;
483         #endif
484         default:                return -1;
485         }
486 }
487
488 static void toolbar_set_default_main(void) 
489 {
490         struct {
491                 gint action;
492         } default_toolbar[] = {
493 #ifdef GENERIC_UMPC
494                 { A_GO_FOLDERS},
495                 { A_OPEN_MAIL},         
496                 { A_SEPARATOR}, 
497 #endif
498                 { A_RECEIVE_ALL},
499                 { A_SEPARATOR}, 
500                 { A_SEND_QUEUED},
501                 { A_COMPOSE_EMAIL},
502                 { A_SEPARATOR},
503                 { A_REPLY_MESSAGE}, 
504 #ifndef GENERIC_UMPC
505                 { A_REPLY_ALL},
506                 { A_REPLY_SENDER},
507 #endif
508                 { A_FORWARD},
509                 { A_SEPARATOR},
510                 { A_TRASH},
511 #ifndef GENERIC_UMPC
512                 { A_LEARN_SPAM},
513 #endif
514                 { A_SEPARATOR},
515                 { A_GOTO_NEXT}
516         };
517         
518         gint i;
519         
520         for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
521                 
522                 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
523                 
524                 if (default_toolbar[i].action != A_SEPARATOR) {
525                         
526                         gchar *file = NULL;
527                         if (toolbar_get_icon(default_toolbar[i].action) > -1) {
528                                 file = stock_pixmap_get_name((StockPixmap)toolbar_get_icon(default_toolbar[i].action));
529                         }
530                         
531                         toolbar_item->file  = g_strdup(file);
532                         toolbar_item->index = default_toolbar[i].action;
533                         toolbar_item->text  = g_strdup(toolbar_get_short_text(default_toolbar[i].action));
534                 } else {
535
536                         toolbar_item->file  = g_strdup(TOOLBAR_TAG_SEPARATOR);
537                         toolbar_item->index = A_SEPARATOR;
538                 }
539                 
540                 if (toolbar_item->index != -1) {
541                         if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MAIN)) 
542                                 toolbar_config[TOOLBAR_MAIN].item_list = 
543                                         g_slist_append(toolbar_config[TOOLBAR_MAIN].item_list, toolbar_item);
544                 }       
545         }
546 }
547
548 static void toolbar_set_default_compose(void)
549 {
550         struct {
551                 gint action;
552         } default_toolbar[] = {
553 #ifdef GENERIC_UMPC
554                 { A_CLOSE},
555                 { A_SEPARATOR}, 
556 #endif
557                 { A_SEND},
558                 { A_SENDL},
559                 { A_DRAFT},
560                 { A_SEPARATOR}, 
561 #ifndef GENERIC_UMPC
562                 { A_INSERT},
563 #endif
564                 { A_ATTACH},
565                 { A_SEPARATOR},
566                 { A_ADDRBOOK}
567         };
568         
569         gint i;
570
571         for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
572                 
573                 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
574                 
575                 if (default_toolbar[i].action != A_SEPARATOR) {
576                         
577                         gchar *file = NULL;
578                         if (toolbar_get_icon(default_toolbar[i].action) > -1) {
579                                 file = stock_pixmap_get_name((StockPixmap)toolbar_get_icon(default_toolbar[i].action));
580                         }
581                         toolbar_item->file  = g_strdup(file);
582                         toolbar_item->index = default_toolbar[i].action;
583                         toolbar_item->text  = g_strdup(toolbar_get_short_text(default_toolbar[i].action));
584                 } else {
585
586                         toolbar_item->file  = g_strdup(TOOLBAR_TAG_SEPARATOR);
587                         toolbar_item->index = A_SEPARATOR;
588                 }
589                 
590                 if (toolbar_item->index != -1) {
591                         if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_COMPOSE)) 
592                                 toolbar_config[TOOLBAR_COMPOSE].item_list = 
593                                         g_slist_append(toolbar_config[TOOLBAR_COMPOSE].item_list, toolbar_item);
594                 }       
595         }
596 }
597
598 static void toolbar_set_default_msgview(void)
599 {
600         struct {
601                 gint action;
602         } default_toolbar[] = {
603 #ifdef GENERIC_UMPC
604                 { A_CLOSE},
605                 { A_SEPARATOR}, 
606 #endif
607                 { A_REPLY_MESSAGE}, 
608                 { A_REPLY_ALL},
609                 { A_REPLY_SENDER},
610                 { A_FORWARD},
611                 { A_SEPARATOR},
612                 { A_TRASH},
613 #ifndef GENERIC_UMPC
614                 { A_LEARN_SPAM},
615 #endif
616                 { A_GOTO_NEXT}
617         };
618         
619         gint i;
620
621         for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
622                 
623                 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
624                 
625                 if (default_toolbar[i].action != A_SEPARATOR) {
626                         gchar *file = NULL;
627                         if (toolbar_get_icon(default_toolbar[i].action) > -1) {
628                                 file = stock_pixmap_get_name((StockPixmap)toolbar_get_icon(default_toolbar[i].action));
629                         }
630                         
631                         toolbar_item->file  = g_strdup(file);
632                         toolbar_item->index = default_toolbar[i].action;
633                         toolbar_item->text  = g_strdup(toolbar_get_short_text(default_toolbar[i].action));
634                 } else {
635
636                         toolbar_item->file  = g_strdup(TOOLBAR_TAG_SEPARATOR);
637                         toolbar_item->index = A_SEPARATOR;
638                 }
639                 
640                 if (toolbar_item->index != -1) {
641                         if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MSGVIEW)) 
642                                 toolbar_config[TOOLBAR_MSGVIEW].item_list = 
643                                         g_slist_append(toolbar_config[TOOLBAR_MSGVIEW].item_list, toolbar_item);
644                 }       
645         }
646 }
647
648 void toolbar_set_default(ToolbarType source)
649 {
650         if (source == TOOLBAR_MAIN)
651                 toolbar_set_default_main();
652         else if  (source == TOOLBAR_COMPOSE)
653                 toolbar_set_default_compose();
654         else if  (source == TOOLBAR_MSGVIEW)
655                 toolbar_set_default_msgview();
656 }
657
658 void toolbar_save_config_file(ToolbarType source)
659 {
660         GSList *cur;
661         FILE *fp;
662         PrefFile *pfile;
663         gchar *fileSpec = NULL;
664
665         debug_print("save Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
666
667         fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
668         pfile = prefs_write_open(fileSpec);
669         if( pfile ) {
670                 fp = pfile->fp;
671                 if (fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL) < 0)
672                         goto fail;
673
674                 if (fprintf(fp, "<%s>\n", TOOLBAR_TAG_INDEX) < 0)
675                         goto fail;
676
677                 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
678                         ToolbarItem *toolbar_item = (ToolbarItem*) cur->data;
679                         
680                         if (toolbar_item->index != A_SEPARATOR) {
681                                 if (fprintf(fp, "\t<%s %s=\"%s\" %s=\"",
682                                         TOOLBAR_TAG_ITEM, 
683                                         TOOLBAR_ICON_FILE, toolbar_item->file,
684                                         TOOLBAR_ICON_TEXT) < 0)
685                                         goto fail;
686                                 if (xml_file_put_escape_str(fp, toolbar_item->text) < 0)
687                                         goto fail;
688                                 if (fprintf(fp, "\" %s=\"%s\"/>\n",
689                                         TOOLBAR_ICON_ACTION, 
690                                         toolbar_ret_text_from_val(toolbar_item->index)) < 0)
691                                         goto fail;
692                         } else {
693                                 if (fprintf(fp, "\t<%s/>\n", TOOLBAR_TAG_SEPARATOR) < 0)
694                                         goto fail;
695                         }
696                 }
697
698                 if (fprintf(fp, "</%s>\n", TOOLBAR_TAG_INDEX) < 0)
699                         goto fail;
700         
701                 g_free( fileSpec );
702                 if (prefs_file_close (pfile) < 0 ) 
703                         g_warning("failed to write toolbar configuration to file\n");
704                 return;
705                 
706 fail:
707                 FILE_OP_ERROR(fileSpec, "fprintf");
708                 g_free( fileSpec );
709                 prefs_file_close_revert (pfile);
710         } else
711                 g_warning("failed to open toolbar configuration file for writing\n");
712 }
713
714 void toolbar_read_config_file(ToolbarType source)
715 {
716         XMLFile *file   = NULL;
717         gchar *fileSpec = NULL;
718         jmp_buf    jumper;
719
720         debug_print("read Toolbar Configuration from %s\n", toolbar_config[source].conf_file);
721
722         fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
723         file = xml_open_file(fileSpec);
724         g_free(fileSpec);
725
726         toolbar_clear_list(source);
727
728         if (file) {
729                 if ((setjmp(jumper))
730                 || (xml_get_dtd(file))
731                 || (xml_parse_next_tag(file))
732                 || (!xml_compare_tag(file, TOOLBAR_TAG_INDEX))) {
733                         xml_close_file(file);
734                         return;
735                 }
736
737                 for (;;) {
738                         if (!file->level) 
739                                 break;
740                         /* Get item tag */
741                         if (xml_parse_next_tag(file)) 
742                                 longjmp(jumper, 1);
743
744                         /* Get next tag (icon, icon_text or icon_action) */
745                         if (xml_compare_tag(file, TOOLBAR_TAG_ITEM)) {
746                                 toolbar_parse_item(file, source);
747                         } else if (xml_compare_tag(file, TOOLBAR_TAG_SEPARATOR)) {
748                                 ToolbarItem *item = g_new0(ToolbarItem, 1);
749                         
750                                 item->file   = g_strdup(TOOLBAR_TAG_SEPARATOR);
751                                 item->index  = A_SEPARATOR;
752                                 toolbar_config[source].item_list = 
753                                         g_slist_append(toolbar_config[source].item_list, item);
754                         }
755
756                 }
757                 xml_close_file(file);
758         }
759
760         if ((!file) || (g_slist_length(toolbar_config[source].item_list) == 0)) {
761
762                 if (source == TOOLBAR_MAIN) 
763                         toolbar_set_default(TOOLBAR_MAIN);
764                 else if (source == TOOLBAR_COMPOSE) 
765                         toolbar_set_default(TOOLBAR_COMPOSE);
766                 else if (source == TOOLBAR_MSGVIEW) 
767                         toolbar_set_default(TOOLBAR_MSGVIEW);
768                 else {          
769                         g_warning("failed to write Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
770                         return;
771                 }
772
773                 toolbar_save_config_file(source);
774         }
775 }
776
777 /*
778  * clears list of toolbar items read from configuration files
779  */
780 void toolbar_clear_list(ToolbarType source)
781 {
782         while (toolbar_config[source].item_list != NULL) {
783                 ToolbarItem *item = (ToolbarItem*) toolbar_config[source].item_list->data;
784                 
785                 toolbar_config[source].item_list = 
786                         g_slist_remove(toolbar_config[source].item_list, item);
787
788                 g_free(item->file);
789                 g_free(item->text);
790                 g_free(item);   
791         }
792         g_slist_free(toolbar_config[source].item_list);
793 }
794
795
796 /* 
797  * return list of Toolbar items
798  */
799 GSList *toolbar_get_list(ToolbarType source)
800 {
801         GSList *list = NULL;
802
803         if ((source == TOOLBAR_MAIN) || (source == TOOLBAR_COMPOSE) || (source == TOOLBAR_MSGVIEW))
804                 list = toolbar_config[source].item_list;
805
806         return list;
807 }
808
809 void toolbar_set_list_item(ToolbarItem *t_item, ToolbarType source)
810 {
811         ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
812
813         toolbar_item->file  = g_strdup(t_item->file);
814         toolbar_item->text  = g_strdup(t_item->text);
815         toolbar_item->index = t_item->index;
816         
817         toolbar_config[source].item_list = 
818                 g_slist_append(toolbar_config[source].item_list,
819                                toolbar_item);
820 }
821
822 static void toolbar_action_execute(GtkWidget    *widget,
823                             GSList       *action_list, 
824                             gpointer     data,
825                             gint         source) 
826 {
827         GSList *cur;
828         gint i = 0;
829
830         for (cur = action_list; cur != NULL;  cur = cur->next) {
831                 ToolbarClawsActions *act = (ToolbarClawsActions*)cur->data;
832
833                 if (widget == act->widget) {
834                         i = prefs_actions_find_by_name(act->name);
835
836                         if (i != -1) 
837                                 break;
838                 }
839         }
840
841         if (i != -1) 
842                 actions_execute(data, i, widget, source);
843         else
844                 g_warning ("Error: did not find Claws Action to execute");
845 }
846
847 gboolean toolbar_check_action_btns(ToolbarType type)
848 {
849         GSList *temp, *curr, *list = toolbar_config[type].item_list;
850         gboolean modified = FALSE;
851         
852         curr = list;
853         while (curr != NULL) {
854                 ToolbarItem *toolbar_item = (ToolbarItem *) curr->data;
855                 temp = curr;
856                 curr = curr->next;
857                 
858                 if (toolbar_item->index != A_CLAWS_ACTIONS)
859                         continue;
860
861                 if (prefs_actions_find_by_name(toolbar_item->text) == -1) {
862                         list = g_slist_delete_link(list, temp);
863                         g_free(toolbar_item->file);
864                         g_free(toolbar_item->text);
865                         g_free(toolbar_item);
866                         modified = TRUE;
867                 }
868         }
869         
870         return modified;
871 }
872
873 #if !(GTK_CHECK_VERSION(2,12,0))
874 #define CLAWS_SET_TOOL_ITEM_TIP(widget,tip) { \
875         gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(widget), GTK_TOOLTIPS(toolbar_tips),    \
876                         tip, NULL);                                                             \
877 }
878 #else
879 #define CLAWS_SET_TOOL_ITEM_TIP(widget,tip) { \
880         gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), tip);                             \
881 }
882 #endif  
883
884 #if !(GTK_CHECK_VERSION(2,12,0))
885 #define CLAWS_SET_ARROW_TIP(widget,tip) { \
886         gtk_menu_tool_button_set_arrow_tooltip(GTK_MENU_TOOL_BUTTON(widget), GTK_TOOLTIPS(toolbar_tips),        \
887                         tip, NULL);                                                             \
888 }
889 #else
890 #define CLAWS_SET_ARROW_TIP(widget,tip) { \
891         gtk_menu_tool_button_set_arrow_tooltip_text(GTK_MENU_TOOL_BUTTON(widget), tip);                         \
892 }
893 #endif  
894
895 static void activate_compose_button (Toolbar           *toolbar,
896                                      ToolbarStyle      style,
897                                      ComposeButtonType type)
898 {
899 #if !(GTK_CHECK_VERSION(2,12,0))
900         GtkTooltips *toolbar_tips = toolbar->tooltips;
901 #endif
902         if ((!toolbar->compose_mail_btn))
903                 return;
904
905         if (type == COMPOSEBUTTON_NEWS) {
906                 gtk_tool_button_set_icon_widget(
907                         GTK_TOOL_BUTTON(toolbar->compose_mail_btn),
908                         toolbar->compose_news_icon);
909 #ifndef GENERIC_UMPC
910                 CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(toolbar->compose_mail_btn), _("Compose News message"));
911 #endif  
912                 gtk_widget_show(toolbar->compose_news_icon);
913         } else {
914                 gtk_tool_button_set_icon_widget(
915                         GTK_TOOL_BUTTON(toolbar->compose_mail_btn),
916                         toolbar->compose_mail_icon);
917 #ifndef GENERIC_UMPC
918                 CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(toolbar->compose_mail_btn), _("Compose Email"));
919 #endif  
920                 gtk_widget_show(toolbar->compose_mail_icon);
921         }
922         toolbar->compose_btn_type = type;
923 }
924
925 void toolbar_set_compose_button(Toolbar            *toolbar, 
926                                 ComposeButtonType  compose_btn_type)
927 {
928         if (toolbar->compose_btn_type != compose_btn_type)
929                 activate_compose_button(toolbar, 
930                                         prefs_common.toolbar_style,
931                                         compose_btn_type);
932 }
933
934 static void activate_learn_button (Toolbar           *toolbar,
935                                      ToolbarStyle      style,
936                                      LearnButtonType type)
937 {
938 #if !(GTK_CHECK_VERSION(2,12,0))
939         GtkTooltips *toolbar_tips = toolbar->tooltips;
940 #endif
941         if ((!toolbar->learn_spam_btn))
942                 return;
943
944         if (type == LEARN_SPAM) {
945                 gtk_tool_button_set_icon_widget(
946                         GTK_TOOL_BUTTON(toolbar->learn_spam_btn),
947                         toolbar->learn_spam_icon);
948                 gtk_tool_button_set_label(
949                         GTK_TOOL_BUTTON(toolbar->learn_spam_btn),
950                         _("Spam"));
951 #ifndef GENERIC_UMPC
952                 CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(toolbar->learn_spam_btn), _("Learn spam"));       
953 #endif
954                 gtk_widget_show(toolbar->learn_spam_icon);
955         } else {
956                 gtk_tool_button_set_icon_widget(
957                         GTK_TOOL_BUTTON(toolbar->learn_spam_btn),
958                         toolbar->learn_ham_icon);
959                 gtk_tool_button_set_label(
960                         GTK_TOOL_BUTTON(toolbar->learn_spam_btn),
961                         _("Ham"));
962 #ifndef GENERIC_UMPC
963                 CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(toolbar->learn_spam_btn), _("Learn ham"));
964 #endif  
965                 gtk_widget_show(toolbar->learn_ham_icon);
966         }
967         toolbar->learn_btn_type = type; 
968 }
969
970 void toolbar_set_learn_button(Toolbar            *toolbar, 
971                                 LearnButtonType  learn_btn_type)
972 {
973         if (toolbar->learn_btn_type != learn_btn_type)
974                 activate_learn_button(toolbar, 
975                                         prefs_common.toolbar_style,
976                                         learn_btn_type);
977 }
978
979 void toolbar_toggle(guint action, gpointer data)
980 {
981         MainWindow *mainwin = (MainWindow*)data;
982         GList *list;
983         GList *cur;
984
985         cm_return_if_fail(mainwin != NULL);
986
987         toolbar_style(TOOLBAR_MAIN, action, mainwin);
988
989         list = compose_get_compose_list();
990         for (cur = list; cur != NULL; cur = cur->next) {
991                 toolbar_style(TOOLBAR_COMPOSE, action, cur->data);
992         }
993         list = messageview_get_msgview_list();
994         for (cur = list; cur != NULL; cur = cur->next) {
995                 toolbar_style(TOOLBAR_MSGVIEW, action, cur->data);
996         }
997         
998 }
999
1000 void toolbar_set_style(GtkWidget *toolbar_wid, GtkWidget *handlebox_wid, guint action)
1001 {
1002         switch ((ToolbarStyle)action) {
1003         case TOOLBAR_NONE:
1004                 gtk_widget_hide(handlebox_wid);
1005                 break;
1006         case TOOLBAR_ICON:
1007                 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
1008                                       GTK_TOOLBAR_ICONS);
1009                 break;
1010         case TOOLBAR_TEXT:
1011                 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
1012                                       GTK_TOOLBAR_TEXT);
1013                 break;
1014         case TOOLBAR_BOTH:
1015                 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
1016                                       GTK_TOOLBAR_BOTH);
1017                 break;
1018         case TOOLBAR_BOTH_HORIZ:
1019                 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
1020                                       GTK_TOOLBAR_BOTH_HORIZ);
1021                 break;
1022         default:
1023                 return;
1024         }
1025
1026         prefs_common.toolbar_style = (ToolbarStyle)action;
1027         gtk_widget_set_size_request(handlebox_wid, 1, -1);
1028         
1029         if (prefs_common.toolbar_style != TOOLBAR_NONE) {
1030                 gtk_widget_show(handlebox_wid);
1031                 gtk_widget_queue_resize(handlebox_wid);
1032         }
1033 }
1034 /*
1035  * Change the style of toolbar
1036  */
1037 static void toolbar_style(ToolbarType type, guint action, gpointer data)
1038 {
1039         GtkWidget  *handlebox_wid;
1040         GtkWidget  *toolbar_wid;
1041         MainWindow *mainwin = (MainWindow*)data;
1042         Compose    *compose = (Compose*)data;
1043         MessageView *msgview = (MessageView*)data;
1044         
1045         cm_return_if_fail(data != NULL);
1046         
1047         switch (type) {
1048         case TOOLBAR_MAIN:
1049                 handlebox_wid = mainwin->handlebox;
1050                 toolbar_wid = mainwin->toolbar->toolbar;
1051                 break;
1052         case TOOLBAR_COMPOSE:
1053                 handlebox_wid = compose->handlebox;
1054                 toolbar_wid = compose->toolbar->toolbar;
1055                 break;
1056         case TOOLBAR_MSGVIEW: 
1057                 handlebox_wid = msgview->handlebox;
1058                 toolbar_wid = msgview->toolbar->toolbar;
1059                 break;
1060         default:
1061
1062                 return;
1063         }
1064         toolbar_set_style(toolbar_wid, handlebox_wid, action);
1065 }
1066
1067 /* Toolbar handling */
1068 static void toolbar_inc_cb(GtkWidget    *widget,
1069                            gpointer      data)
1070 {
1071         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1072         MainWindow *mainwin;
1073
1074         cm_return_if_fail(toolbar_item != NULL);
1075
1076         switch (toolbar_item->type) {
1077         case TOOLBAR_MAIN:
1078                 mainwin = (MainWindow*)toolbar_item->parent;    
1079                 inc_mail_cb(mainwin, 0, NULL);
1080                 break;
1081         default:
1082                 break;
1083         }
1084 }
1085
1086 static void toolbar_inc_all_cb(GtkWidget        *widget,
1087                                gpointer          data)
1088 {
1089         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1090         MainWindow *mainwin;
1091
1092         cm_return_if_fail(toolbar_item != NULL);
1093
1094         switch (toolbar_item->type) {
1095         case TOOLBAR_MAIN:
1096                 mainwin = (MainWindow*)toolbar_item->parent;
1097                 inc_all_account_mail_cb(mainwin, 0, NULL);
1098                 break;
1099         default:
1100                 break;
1101         }
1102 }
1103
1104 static void toolbar_send_queued_cb(GtkWidget *widget,gpointer data)
1105 {
1106         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1107         MainWindow *mainwin;
1108
1109         cm_return_if_fail(toolbar_item != NULL);
1110
1111         switch (toolbar_item->type) {
1112         case TOOLBAR_MAIN:
1113                 mainwin = (MainWindow*)toolbar_item->parent;
1114                 send_queue_cb(mainwin, 0, NULL);
1115                 break;
1116         default:
1117                 break;
1118         }
1119 }
1120
1121 static void toolbar_exec_cb(GtkWidget   *widget,
1122                             gpointer     data)
1123 {
1124         MainWindow *mainwin = get_mainwin(data);
1125
1126         cm_return_if_fail(mainwin != NULL);
1127         summary_execute(mainwin->summaryview);
1128 }
1129
1130 /*
1131  * Delete current/selected(s) message(s)
1132  */
1133 static void toolbar_trash_cb(GtkWidget *widget, gpointer data)
1134 {
1135         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1136         MainWindow *mainwin;
1137
1138         cm_return_if_fail(toolbar_item != NULL);
1139         cm_return_if_fail(toolbar_item->parent);
1140         
1141         switch (toolbar_item->type) {
1142         case TOOLBAR_MSGVIEW:
1143                 messageview_delete((MessageView *)toolbar_item->parent);
1144                 break;
1145         case TOOLBAR_MAIN:
1146                 mainwin = (MainWindow *)toolbar_item->parent;
1147                 summary_delete_trash(mainwin->summaryview);
1148                 break;
1149         default: 
1150                 debug_print("toolbar event not supported\n");
1151                 break;
1152         }
1153 }
1154
1155 /*
1156  * Delete current/selected(s) message(s)
1157  */
1158 static void toolbar_delete_cb(GtkWidget *widget, gpointer data)
1159 {
1160         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1161         MainWindow *mainwin;
1162
1163         cm_return_if_fail(toolbar_item != NULL);
1164         cm_return_if_fail(toolbar_item->parent);
1165         
1166         switch (toolbar_item->type) {
1167         case TOOLBAR_MSGVIEW:
1168                 messageview_delete((MessageView *)toolbar_item->parent);
1169                 break;
1170         case TOOLBAR_MAIN:
1171                 mainwin = (MainWindow *)toolbar_item->parent;
1172                 summary_delete(mainwin->summaryview);
1173                 break;
1174         default: 
1175                 debug_print("toolbar event not supported\n");
1176                 break;
1177         }
1178 }
1179
1180
1181 /*
1182  * Compose new message
1183  */
1184 static void toolbar_compose_cb(GtkWidget *widget, gpointer data)
1185 {
1186         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1187         MainWindow *mainwin;
1188         MessageView *msgview;
1189
1190         cm_return_if_fail(toolbar_item != NULL);
1191
1192         switch (toolbar_item->type) {
1193         case TOOLBAR_MAIN:
1194                 mainwin = (MainWindow*)toolbar_item->parent;
1195                 if (mainwin->toolbar->compose_btn_type == COMPOSEBUTTON_NEWS) 
1196                         compose_news_cb(mainwin, 0, NULL);
1197                 else
1198                         compose_mail_cb(mainwin, 0, NULL);
1199                 break;
1200         case TOOLBAR_MSGVIEW:
1201                 msgview = (MessageView*)toolbar_item->parent;
1202                 compose_new_with_folderitem(NULL, 
1203                                             msgview->msginfo->folder, NULL);
1204                 break;  
1205         default:
1206                 debug_print("toolbar event not supported\n");
1207         }
1208 }
1209
1210 static void toolbar_learn(gpointer data, guint as_spam)
1211 {
1212         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1213         MainWindow *mainwin;
1214         MessageView *msgview;
1215
1216         cm_return_if_fail(toolbar_item != NULL);
1217
1218         switch (toolbar_item->type) {
1219         case TOOLBAR_MAIN:
1220                 mainwin = (MainWindow*)toolbar_item->parent;
1221                 if (as_spam) 
1222                         mainwindow_learn(mainwin, TRUE);
1223                 else
1224                         mainwindow_learn(mainwin, FALSE);
1225                 break;
1226         case TOOLBAR_MSGVIEW:
1227                 msgview = (MessageView*)toolbar_item->parent;
1228                 if (as_spam) 
1229                         messageview_learn(msgview, TRUE);
1230                 else
1231                         messageview_learn(msgview, FALSE);
1232                 break;
1233         default:
1234                 debug_print("toolbar event not supported\n");
1235         }
1236 }
1237
1238 static void toolbar_learn_cb(GtkWidget *widget, gpointer data)
1239 {
1240         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1241         MainWindow *mainwin;
1242         MessageView *msgview;
1243
1244         cm_return_if_fail(toolbar_item != NULL);
1245
1246         switch (toolbar_item->type) {
1247         case TOOLBAR_MAIN:
1248                 mainwin = (MainWindow*)toolbar_item->parent;
1249                 if (mainwin->toolbar->learn_btn_type == LEARN_SPAM) 
1250                         mainwindow_learn(mainwin, TRUE);
1251                 else
1252                         mainwindow_learn(mainwin, FALSE);
1253                 break;
1254         case TOOLBAR_MSGVIEW:
1255                 msgview = (MessageView*)toolbar_item->parent;
1256                 if (msgview->toolbar->learn_btn_type == LEARN_SPAM) 
1257                         messageview_learn(msgview, TRUE);
1258                 else
1259                         messageview_learn(msgview, FALSE);
1260                 break;
1261         default:
1262                 debug_print("toolbar event not supported\n");
1263         }
1264 }
1265
1266
1267 /*
1268  * Reply Message
1269  */
1270 static void toolbar_reply_cb(GtkWidget *widget, gpointer data)
1271 {
1272         toolbar_reply(data, (prefs_common.reply_with_quote ? 
1273                       COMPOSE_REPLY_WITH_QUOTE : COMPOSE_REPLY_WITHOUT_QUOTE));
1274 }
1275
1276
1277 /*
1278  * Reply message to Sender and All recipients
1279  */
1280 static void toolbar_reply_to_all_cb(GtkWidget *widget, gpointer data)
1281 {
1282         toolbar_reply(data,
1283                       (prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_ALL_WITH_QUOTE 
1284                       : COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE));
1285 }
1286
1287
1288 /*
1289  * Reply to Mailing List
1290  */
1291 static void toolbar_reply_to_list_cb(GtkWidget *widget, gpointer data)
1292 {
1293         toolbar_reply(data, 
1294                       (prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_LIST_WITH_QUOTE 
1295                       : COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE));
1296 }
1297
1298
1299 /*
1300  * Reply to sender of message
1301  */ 
1302 static void toolbar_reply_to_sender_cb(GtkWidget *widget, gpointer data)
1303 {
1304         toolbar_reply(data, 
1305                       (prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_SENDER_WITH_QUOTE 
1306                       : COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE));
1307 }
1308
1309 /*
1310  * Open addressbook
1311  */ 
1312 static void toolbar_addrbook_cb(GtkWidget *widget, gpointer data)
1313 {
1314         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1315         Compose *compose;
1316
1317         cm_return_if_fail(toolbar_item != NULL);
1318
1319         switch (toolbar_item->type) {
1320         case TOOLBAR_MAIN:
1321         case TOOLBAR_MSGVIEW:
1322                 compose = NULL;
1323                 break;
1324         case TOOLBAR_COMPOSE:
1325                 compose = (Compose *)toolbar_item->parent;
1326                 break;
1327         default:
1328                 return;
1329         }
1330 #ifndef USE_NEW_ADDRBOOK
1331         addressbook_open(compose);
1332 #else
1333         GError* error = NULL;
1334         addressbook_connect_signals(compose);
1335         addressbook_dbus_open(TRUE, &error);
1336         if (error) {
1337                 g_warning("%s", error->message);
1338                 g_error_free(error);
1339         }
1340 #endif
1341 }
1342
1343
1344 /*
1345  * Forward current/selected(s) message(s)
1346  */
1347 static void toolbar_forward_cb(GtkWidget *widget, gpointer data)
1348 {
1349         toolbar_reply(data, (COMPOSE_FORWARD));
1350 }
1351
1352 /*
1353  * Goto Prev Unread Message
1354  */
1355 static void toolbar_prev_unread_cb(GtkWidget *widget, gpointer data)
1356 {
1357         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1358         MainWindow *mainwin;
1359         MessageView *msgview;
1360
1361         cm_return_if_fail(toolbar_item != NULL);
1362
1363         switch (toolbar_item->type) {
1364         case TOOLBAR_MAIN:
1365                 mainwin = (MainWindow*)toolbar_item->parent;
1366                 summary_select_prev_unread(mainwin->summaryview);
1367                 break;
1368                 
1369         case TOOLBAR_MSGVIEW:
1370                 msgview = (MessageView*)toolbar_item->parent;
1371                 msgview->updating = TRUE;
1372                 summary_select_prev_unread(msgview->mainwin->summaryview);
1373                 msgview->updating = FALSE;
1374
1375                 if (msgview->deferred_destroy) {
1376                         debug_print("messageview got away!\n");
1377                         messageview_destroy(msgview);
1378                         return;
1379                 }
1380                 
1381                 /* Now we need to update the messageview window */
1382                 if (msgview->mainwin->summaryview->selected) {
1383 #ifndef GENERIC_UMPC
1384                         MsgInfo * msginfo = summary_get_selected_msg(msgview->mainwin->summaryview);
1385                        
1386                         if (msginfo)
1387                                 messageview_show(msgview, msginfo, 
1388                                          msgview->all_headers);
1389 #endif
1390                 } else {
1391                         gtk_widget_destroy(msgview->window);
1392                 }
1393                 break;
1394         default:
1395                 debug_print("toolbar event not supported\n");
1396         }
1397 }
1398
1399 /*
1400  * Goto Next Unread Message
1401  */
1402 static void toolbar_next_unread_cb(GtkWidget *widget, gpointer data)
1403 {
1404         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1405         MainWindow *mainwin;
1406         MessageView *msgview;
1407
1408         cm_return_if_fail(toolbar_item != NULL);
1409
1410         switch (toolbar_item->type) {
1411         case TOOLBAR_MAIN:
1412                 mainwin = (MainWindow*)toolbar_item->parent;
1413                 summary_select_next_unread(mainwin->summaryview);
1414                 break;
1415                 
1416         case TOOLBAR_MSGVIEW:
1417                 msgview = (MessageView*)toolbar_item->parent;
1418                 msgview->updating = TRUE;
1419                 summary_select_next_unread(msgview->mainwin->summaryview);
1420                 msgview->updating = FALSE;
1421
1422                 if (msgview->deferred_destroy) {
1423                         debug_print("messageview got away!\n");
1424                         messageview_destroy(msgview);
1425                         return;
1426                 }
1427
1428                 /* Now we need to update the messageview window */
1429                 if (msgview->mainwin->summaryview->selected) {
1430 #ifndef GENERIC_UMPC
1431                         MsgInfo * msginfo = summary_get_selected_msg(msgview->mainwin->summaryview);
1432                         
1433                         if (msginfo)
1434                                 messageview_show(msgview, msginfo, 
1435                                          msgview->all_headers);
1436 #endif
1437                 } else {
1438                         gtk_widget_destroy(msgview->window);
1439                 }
1440                 break;
1441         default:
1442                 debug_print("toolbar event not supported\n");
1443         }
1444 }
1445
1446 static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data)
1447 {
1448         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1449         MainWindow *mainwin;
1450
1451         cm_return_if_fail(toolbar_item != NULL);
1452
1453         switch (toolbar_item->type) {
1454         case TOOLBAR_MAIN:
1455                 mainwin = (MainWindow *) toolbar_item->parent;
1456                 summary_toggle_ignore_thread(mainwin->summaryview);
1457                 break;
1458         case TOOLBAR_MSGVIEW:
1459                 /* TODO: see toolbar_next_unread_cb() if you need
1460                  * this in the message view */
1461                 break;
1462         default:
1463                 debug_print("toolbar event not supported\n");
1464                 break;
1465         }
1466 }
1467
1468 static void toolbar_watch_thread_cb(GtkWidget *widget, gpointer data)
1469 {
1470         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1471         MainWindow *mainwin;
1472
1473         cm_return_if_fail(toolbar_item != NULL);
1474
1475         switch (toolbar_item->type) {
1476         case TOOLBAR_MAIN:
1477                 mainwin = (MainWindow *) toolbar_item->parent;
1478                 summary_toggle_watch_thread(mainwin->summaryview);
1479                 break;
1480         case TOOLBAR_MSGVIEW:
1481                 /* TODO: see toolbar_next_unread_cb() if you need
1482                  * this in the message view */
1483                 break;
1484         default:
1485                 debug_print("toolbar event not supported\n");
1486                 break;
1487         }
1488 }
1489
1490 static void toolbar_cancel_inc_cb(GtkWidget *widget, gpointer data)
1491 {
1492         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1493
1494         cm_return_if_fail(toolbar_item != NULL);
1495         inc_cancel_all();
1496         imap_cancel_all();
1497 }
1498
1499 static void toolbar_cancel_send_cb(GtkWidget *widget, gpointer data)
1500 {
1501         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1502
1503         cm_return_if_fail(toolbar_item != NULL);
1504         send_cancel();
1505 }
1506
1507 static void toolbar_cancel_all_cb(GtkWidget *widget, gpointer data)
1508 {
1509         toolbar_cancel_inc_cb(widget, data);
1510         toolbar_cancel_send_cb(widget, data);
1511 }
1512
1513 static void toolbar_print_cb(GtkWidget *widget, gpointer data)
1514 {
1515         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1516         MainWindow *mainwin;
1517
1518         cm_return_if_fail(toolbar_item != NULL);
1519
1520         switch (toolbar_item->type) {
1521         case TOOLBAR_MAIN:
1522                 mainwin = (MainWindow *) toolbar_item->parent;
1523                 summary_print(mainwin->summaryview);
1524                 break;
1525         case TOOLBAR_MSGVIEW:
1526                 /* TODO: see toolbar_next_unread_cb() if you need
1527                  * this in the message view */
1528                 break;
1529         default:
1530                 debug_print("toolbar event not supported\n");
1531                 break;
1532         }
1533 }
1534
1535 static void toolbar_send_cb(GtkWidget *widget, gpointer data)
1536 {
1537         compose_toolbar_cb(A_SEND, data);
1538 }
1539
1540 static void toolbar_send_later_cb(GtkWidget *widget, gpointer data)
1541 {
1542         compose_toolbar_cb(A_SENDL, data);
1543 }
1544
1545 static void toolbar_draft_cb(GtkWidget *widget, gpointer data)
1546 {
1547         compose_toolbar_cb(A_DRAFT, data);
1548 }
1549
1550 static void toolbar_close_cb(GtkWidget *widget, gpointer data)
1551 {
1552         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1553         MainWindow *mainwin;
1554         MessageView *messageview;
1555         Compose *compose;
1556
1557         cm_return_if_fail(toolbar_item != NULL);
1558
1559         switch (toolbar_item->type) {
1560         case TOOLBAR_MAIN:
1561                 mainwin = (MainWindow *) toolbar_item->parent;
1562                 app_will_exit(NULL, mainwin);
1563                 break;
1564         case TOOLBAR_MSGVIEW:
1565                 messageview = (MessageView *)toolbar_item->parent;
1566                 messageview_destroy(messageview);
1567                 break;
1568         case TOOLBAR_COMPOSE:
1569                 compose = (Compose *)toolbar_item->parent;
1570                 compose_close_toolbar(compose);
1571                 break;
1572         }
1573 }
1574
1575 static void toolbar_preferences_cb(GtkWidget *widget, gpointer data)
1576 {
1577         prefs_gtk_open();
1578 }
1579
1580 static void toolbar_open_mail_cb(GtkWidget *widget, gpointer data)
1581 {
1582         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1583         MainWindow *mainwin;
1584
1585         cm_return_if_fail(toolbar_item != NULL);
1586
1587         switch (toolbar_item->type) {
1588         case TOOLBAR_MAIN:
1589                 mainwin = (MainWindow *) toolbar_item->parent;
1590                 summary_open_row(NULL, mainwin->summaryview);
1591                 break;
1592         case TOOLBAR_MSGVIEW:
1593                 debug_print("toolbar event not supported\n");
1594                 break;
1595         case TOOLBAR_COMPOSE:
1596                 debug_print("toolbar event not supported\n");
1597                 break;
1598         }
1599 }
1600
1601 static void toolbar_insert_cb(GtkWidget *widget, gpointer data)
1602 {
1603         compose_toolbar_cb(A_INSERT, data);
1604 }
1605
1606 static void toolbar_attach_cb(GtkWidget *widget, gpointer data)
1607 {
1608         compose_toolbar_cb(A_ATTACH, data);
1609 }
1610
1611 static void toolbar_sig_cb(GtkWidget *widget, gpointer data)
1612 {
1613         compose_toolbar_cb(A_SIG, data);
1614 }
1615
1616 static void toolbar_ext_editor_cb(GtkWidget *widget, gpointer data)
1617 {
1618         compose_toolbar_cb(A_EXTEDITOR, data);
1619 }
1620
1621 static void toolbar_linewrap_current_cb(GtkWidget *widget, gpointer data)
1622 {
1623         compose_toolbar_cb(A_LINEWRAP_CURRENT, data);
1624 }
1625
1626 static void toolbar_linewrap_all_cb(GtkWidget *widget, gpointer data)
1627 {
1628         compose_toolbar_cb(A_LINEWRAP_ALL, data);
1629 }
1630
1631 #ifdef USE_ENCHANT
1632 static void toolbar_check_spelling_cb(GtkWidget *widget, gpointer data)
1633 {
1634         compose_toolbar_cb(A_CHECK_SPELLING, data);
1635 }
1636 #endif
1637 /*
1638  * Execute actions from toolbar
1639  */
1640 static void toolbar_actions_execute_cb(GtkWidget *widget, gpointer data)
1641 {
1642         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1643         GSList *action_list;
1644         MainWindow *mainwin;
1645         Compose *compose;
1646         MessageView *msgview;
1647         gpointer parent = toolbar_item->parent;
1648
1649         cm_return_if_fail(toolbar_item != NULL);
1650
1651         switch (toolbar_item->type) {
1652         case TOOLBAR_MAIN:
1653                 mainwin = (MainWindow*)parent;
1654                 action_list = mainwin->toolbar->action_list;
1655                 break;
1656         case TOOLBAR_COMPOSE:
1657                 compose = (Compose*)parent;
1658                 action_list = compose->toolbar->action_list;
1659                 break;
1660         case TOOLBAR_MSGVIEW:
1661                 msgview = (MessageView*)parent;
1662                 action_list = msgview->toolbar->action_list;
1663                 break;
1664         default:
1665                 debug_print("toolbar event not supported\n");
1666                 return;
1667         }
1668         toolbar_action_execute(widget, action_list, parent, toolbar_item->type);        
1669 }
1670
1671 static void toolbar_plugins_execute_cb(GtkWidget *widget, gpointer data)
1672 {
1673         ToolbarItem *toolbar_item = data;
1674         prefs_toolbar_execute_plugin_item(toolbar_item->parent, toolbar_item->type, toolbar_item->text);
1675 }
1676
1677 static MainWindow *get_mainwin(gpointer data)
1678 {
1679         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1680         MainWindow *mainwin = NULL;
1681         MessageView *msgview;
1682
1683         cm_return_val_if_fail(toolbar_item != NULL, NULL);
1684
1685         switch(toolbar_item->type) {
1686         case TOOLBAR_MAIN:
1687                 mainwin = (MainWindow*)toolbar_item->parent;
1688                 break;
1689         case TOOLBAR_MSGVIEW:
1690                 msgview = (MessageView*)toolbar_item->parent;
1691                 mainwin = (MainWindow*)msgview->mainwin;
1692                 break;
1693         default:
1694                 break;
1695         }
1696
1697         return mainwin;
1698 }
1699
1700 static void toolbar_go_folders_cb(GtkWidget *widget, gpointer data)
1701 {
1702         ToolbarItem *toolbar_item = (ToolbarItem*)data;
1703         MainWindow *mainwin = NULL;
1704         switch(toolbar_item->type) {
1705         case TOOLBAR_MAIN:
1706                 mainwin = (MainWindow*)toolbar_item->parent;
1707                 break;
1708         default:
1709                 g_warning("wrong toolbar type\n");
1710                 return;
1711         }
1712
1713         if (!mainwin->in_folder) {
1714                 FolderItem *item = folderview_get_selected_item(mainwin->folderview);
1715                 if (item) {
1716                         folderview_select(mainwin->folderview, item);
1717                 }
1718         } else {
1719                 gtk_widget_grab_focus(mainwin->folderview->ctree);
1720                 mainwindow_exit_folder(mainwin);
1721         }
1722 }
1723
1724 static void toolbar_buttons_cb(GtkWidget   *widget, 
1725                                ToolbarItem *item)
1726 {
1727         gint num_items;
1728         gint i;
1729         struct {
1730                 gint   index;
1731                 void (*func)(GtkWidget *widget, gpointer data);
1732         } callbacks[] = {
1733                 { A_RECEIVE_ALL,        toolbar_inc_all_cb              },
1734                 { A_RECEIVE_CUR,        toolbar_inc_cb                  },
1735                 { A_SEND_QUEUED,        toolbar_send_queued_cb          },
1736                 { A_COMPOSE_EMAIL,      toolbar_compose_cb              },
1737                 { A_COMPOSE_NEWS,       toolbar_compose_cb              },
1738                 { A_REPLY_MESSAGE,      toolbar_reply_cb                },
1739                 { A_REPLY_SENDER,       toolbar_reply_to_sender_cb      },
1740                 { A_REPLY_ALL,          toolbar_reply_to_all_cb         },
1741                 { A_REPLY_ML,           toolbar_reply_to_list_cb        },
1742                 { A_FORWARD,            toolbar_forward_cb              },
1743                 { A_TRASH,              toolbar_trash_cb                },
1744                 { A_DELETE_REAL,        toolbar_delete_cb               },
1745                 { A_EXECUTE,            toolbar_exec_cb                 },
1746                 { A_GOTO_PREV,          toolbar_prev_unread_cb          },
1747                 { A_GOTO_NEXT,          toolbar_next_unread_cb          },
1748                 { A_IGNORE_THREAD,      toolbar_ignore_thread_cb        },
1749                 { A_WATCH_THREAD,       toolbar_watch_thread_cb         },
1750                 { A_PRINT,              toolbar_print_cb                },
1751                 { A_LEARN_SPAM,         toolbar_learn_cb                },
1752                 { A_GO_FOLDERS,         toolbar_go_folders_cb           },
1753
1754                 { A_SEND,               toolbar_send_cb                 },
1755                 { A_SENDL,              toolbar_send_later_cb           },
1756                 { A_DRAFT,              toolbar_draft_cb                },
1757                 { A_OPEN_MAIL,          toolbar_open_mail_cb            },
1758                 { A_CLOSE,              toolbar_close_cb                },
1759                 { A_PREFERENCES,        toolbar_preferences_cb          },
1760                 { A_INSERT,             toolbar_insert_cb               },
1761                 { A_ATTACH,             toolbar_attach_cb               },
1762                 { A_SIG,                toolbar_sig_cb                  },
1763                 { A_EXTEDITOR,          toolbar_ext_editor_cb           },
1764                 { A_LINEWRAP_CURRENT,   toolbar_linewrap_current_cb     },
1765                 { A_LINEWRAP_ALL,       toolbar_linewrap_all_cb         },
1766                 { A_ADDRBOOK,           toolbar_addrbook_cb             },
1767 #ifdef USE_ENCHANT
1768                 { A_CHECK_SPELLING,     toolbar_check_spelling_cb       },
1769 #endif
1770                 { A_CLAWS_ACTIONS,      toolbar_actions_execute_cb      },
1771                 { A_CANCEL_INC,         toolbar_cancel_inc_cb           },
1772                 { A_CANCEL_SEND,        toolbar_cancel_send_cb          },
1773                 { A_CANCEL_ALL,         toolbar_cancel_all_cb           },
1774                 { A_CLAWS_PLUGINS,  toolbar_plugins_execute_cb  },
1775         };
1776
1777         num_items = sizeof(callbacks)/sizeof(callbacks[0]);
1778
1779         for (i = 0; i < num_items; i++) {
1780                 if (callbacks[i].index == item->index) {
1781                         callbacks[i].func(widget, item);
1782                         return;
1783                 }
1784         }
1785 }
1786 #ifndef GENERIC_UMPC
1787 #define TOOLBAR_ITEM(item,icon,text,tooltip) {                                                          \
1788         item = GTK_WIDGET(gtk_tool_button_new(icon, text));                                             \
1789         gtkut_widget_set_can_focus(gtk_bin_get_child(GTK_BIN(item)), FALSE);                            \
1790         gtk_tool_item_set_homogeneous(GTK_TOOL_ITEM(item), FALSE);                                      \
1791         gtk_tool_item_set_is_important(GTK_TOOL_ITEM(item), TRUE);                                      \
1792         g_signal_connect (G_OBJECT(item), "clicked", G_CALLBACK(toolbar_buttons_cb), toolbar_item);     \
1793         gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), -1);                              \
1794         CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(item),                                                    \
1795                         tooltip);                                                                       \
1796 }
1797
1798 #define TOOLBAR_MENUITEM(item,icon,text,tooltip,menutip) {                                              \
1799         GtkWidget *child = NULL, *btn = NULL, *arr = NULL;                                              \
1800         GList *gchild = NULL;                                                                           \
1801         item = GTK_WIDGET(gtk_menu_tool_button_new(icon, text));                                        \
1802         gtk_tool_item_set_homogeneous(GTK_TOOL_ITEM(item), FALSE);                              \
1803         gtk_tool_item_set_is_important(GTK_TOOL_ITEM(item), TRUE);                                      \
1804         g_signal_connect (G_OBJECT(item), "clicked", G_CALLBACK(toolbar_buttons_cb), toolbar_item);     \
1805         gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), -1);                              \
1806         CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(item),                                                    \
1807                         tooltip);                                                                       \
1808         CLAWS_SET_ARROW_TIP(GTK_MENU_TOOL_BUTTON(item), menutip);                                       \
1809         child = gtk_bin_get_child(GTK_BIN(item));                                                       \
1810         gchild = gtk_container_get_children(                                                            \
1811                         GTK_CONTAINER(child));                                                          \
1812         btn = (GtkWidget *)gchild->data;                                                                \
1813         gtkut_widget_set_can_focus(btn, FALSE);                                                         \
1814         arr = (GtkWidget *)(gchild->next?gchild->next->data:NULL);                                      \
1815         gtkut_widget_set_can_focus(arr, FALSE);                                                         \
1816         g_list_free(gchild);                                                                            \
1817         gchild = gtk_container_get_children(GTK_CONTAINER(arr));                                        \
1818         gtk_widget_set_size_request(GTK_WIDGET(gchild->data), 9, -1);                                   \
1819         g_list_free(gchild);                                                                            \
1820 }
1821 #else
1822 #define TOOLBAR_ITEM(item,icon,text,tooltip) {                                                          \
1823         item = GTK_WIDGET(gtk_tool_button_new(icon, text));                                             \
1824         gtkut_widget_set_can_focus(gtk_bin_get_child(GTK_BIN(item)), FALSE);                            \
1825         gtk_tool_item_set_homogeneous(GTK_TOOL_ITEM(item), FALSE);                                      \
1826         gtk_tool_item_set_is_important(GTK_TOOL_ITEM(item), TRUE);                                      \
1827         g_signal_connect (G_OBJECT(item), "clicked", G_CALLBACK(toolbar_buttons_cb), toolbar_item);     \
1828         gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), -1);                              \
1829 }
1830
1831 #define TOOLBAR_MENUITEM(item,icon,text,tooltip,menutip) {                                              \
1832         GtkWidget *child = NULL, *btn = NULL, *arr = NULL;                                              \
1833         GList *gchild = NULL;                                                                           \
1834         item = GTK_WIDGET(gtk_menu_tool_button_new(icon, text));                                        \
1835         gtk_tool_item_set_homogeneous(GTK_TOOL_ITEM(item), FALSE);                              \
1836         gtk_tool_item_set_is_important(GTK_TOOL_ITEM(item), TRUE);                                      \
1837         g_signal_connect (G_OBJECT(item), "clicked", G_CALLBACK(toolbar_buttons_cb), toolbar_item);     \
1838         gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), -1);                              \
1839         child = gtk_bin_get_child(GTK_BIN(item));                                                       \
1840         gchild = gtk_container_get_children(                                                            \
1841                         GTK_CONTAINER(child));                                                          \
1842         btn = (GtkWidget *)gchild->data;                                                                \
1843         gtkut_widget_set_can_focus(btn, FALSE);                                                         \
1844         arr = (GtkWidget *)(gchild->next?gchild->next->data:NULL);                                      \
1845         gtkut_widget_set_can_focus(arr, FALSE);                                                         \
1846         g_list_free(gchild);                                                                            \
1847         gchild = gtk_container_get_children(GTK_CONTAINER(arr));                                        \
1848         gtk_widget_set_size_request(GTK_WIDGET(gchild->data), 9, -1);                                   \
1849         g_list_free(gchild);                                                                            \
1850 }
1851 #endif
1852
1853 #define ADD_MENU_ITEM(name,cb,data) {                                                   \
1854         item = gtk_menu_item_new_with_mnemonic(name);                                   \
1855         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);                              \
1856         g_signal_connect(G_OBJECT(item), "activate",                                    \
1857                          G_CALLBACK(cb),                                                \
1858                            toolbar_item);                                               \
1859         g_object_set_data(G_OBJECT(item), "int-value", GINT_TO_POINTER(data));          \
1860         gtk_widget_show(item);                                                          \
1861 }
1862
1863 static void toolbar_reply_menu_cb(GtkWidget *widget, gpointer data)
1864 {
1865         gpointer int_value = g_object_get_data(G_OBJECT(widget), "int-value");
1866         ToolbarItem *toolbar_item = (ToolbarItem *)data;
1867         
1868         toolbar_reply(toolbar_item, GPOINTER_TO_INT(int_value));
1869 }
1870
1871 static void toolbar_learn_menu_cb(GtkWidget *widget, gpointer data)
1872 {
1873         gpointer int_value = g_object_get_data(G_OBJECT(widget), "int-value");
1874         ToolbarItem *toolbar_item = (ToolbarItem *)data;
1875         
1876         toolbar_learn(toolbar_item, GPOINTER_TO_INT(int_value));
1877 }
1878
1879 /**
1880  * Create a new toolbar with specified type
1881  * if a callback list is passed it will be used before the 
1882  * common callback list
1883  **/
1884 Toolbar *toolbar_create(ToolbarType      type, 
1885                         GtkWidget       *container,
1886                         gpointer         data)
1887 {
1888         ToolbarItem *toolbar_item;
1889
1890         GtkWidget *toolbar;
1891         GtkWidget *icon_wid = NULL;
1892         GtkWidget *icon_news;
1893         GtkWidget *icon_ham;
1894         GtkWidget *item;
1895         ToolbarClawsActions *action_item;
1896         GSList *cur;
1897         GSList *toolbar_list;
1898         Toolbar *toolbar_data;
1899         GtkWidget *menu;
1900 #ifndef GENERIC_UMPC
1901 #if !(GTK_CHECK_VERSION(2,12,0))
1902         GtkTooltips *toolbar_tips = gtk_tooltips_new();
1903 #endif
1904 #endif  
1905         toolbar_read_config_file(type);
1906         toolbar_list = toolbar_get_list(type);
1907
1908         toolbar_data = g_new0(Toolbar, 1); 
1909
1910         toolbar = gtk_toolbar_new();
1911
1912 #if (GTK_CHECK_VERSION(2,16,0))
1913         gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL);
1914 #else
1915         gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1916 #endif
1917         gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
1918         gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolbar), TRUE);
1919         
1920         for (cur = toolbar_list; cur != NULL; cur = cur->next) {
1921
1922                 if (g_ascii_strcasecmp(((ToolbarItem*)cur->data)->file, TOOLBAR_TAG_SEPARATOR) == 0) {
1923                         gtk_toolbar_insert(GTK_TOOLBAR(toolbar), gtk_separator_tool_item_new(), -1);
1924                         continue;
1925                 }
1926                 
1927                 toolbar_item = g_new0(ToolbarItem, 1); 
1928                 toolbar_item->index = ((ToolbarItem*)cur->data)->index;
1929                 toolbar_item->file = g_strdup(((ToolbarItem*)cur->data)->file);
1930                 toolbar_item->text = g_strdup(((ToolbarItem*)cur->data)->text);
1931                 toolbar_item->parent = data;
1932                 toolbar_item->type = type;
1933
1934                 /* collect toolbar items in list to keep track */
1935                 toolbar_data->item_list = 
1936                         g_slist_append(toolbar_data->item_list, 
1937                                        toolbar_item);
1938                 icon_wid = stock_pixmap_widget(container, stock_pixmap_get_icon(toolbar_item->file));
1939                         
1940                 switch (toolbar_item->index) {
1941
1942                 case A_GO_FOLDERS:
1943                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Go to folder list"));
1944                         toolbar_data->folders_btn = item;
1945                         break;
1946                 case A_RECEIVE_ALL:
1947                         TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text,
1948                                 _("Receive Mail from all Accounts"),
1949                                 _("Receive Mail from selected Account"));
1950                         toolbar_data->getall_btn = item;
1951                         break;
1952                 case A_RECEIVE_CUR:
1953                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text, _("Receive Mail from current Account"));
1954                         toolbar_data->get_btn = item;
1955                         break;
1956                 case A_SEND_QUEUED:
1957                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Send Queued Messages"));
1958                         toolbar_data->send_btn = item; 
1959                         break;
1960                 case A_CLOSE:
1961                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Close window"));
1962                         toolbar_data->close_window_btn = item; 
1963                         break;
1964                 case A_PREFERENCES:
1965                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Open preferences"));
1966                         toolbar_data->preferences_btn = item; 
1967                         break;
1968                 case A_OPEN_MAIL:
1969                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Open email"));
1970                         toolbar_data->open_mail_btn = item; 
1971                         break;
1972                 case A_COMPOSE_EMAIL:
1973 #ifndef GENERIC_UMPC
1974                         TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text,
1975                                 _("Compose Email"),
1976                                 _("Compose with selected Account"));
1977                         toolbar_data->compose_mail_btn = item; 
1978                         toolbar_data->compose_mail_icon = icon_wid; 
1979                         g_object_ref(toolbar_data->compose_mail_icon);
1980
1981                         icon_news = stock_pixmap_widget(container, STOCK_PIXMAP_NEWS_COMPOSE);
1982                         toolbar_data->compose_news_icon = icon_news; 
1983                         g_object_ref(toolbar_data->compose_news_icon);
1984 #else
1985                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,
1986                                 _("Compose Email"));
1987                         toolbar_data->compose_mail_btn = item; 
1988                         toolbar_data->compose_mail_icon = icon_wid; 
1989
1990                         icon_news = stock_pixmap_widget(container, STOCK_PIXMAP_NEWS_COMPOSE);
1991                         toolbar_data->compose_news_icon = icon_news; 
1992 #endif
1993                         break;
1994                 case A_LEARN_SPAM:
1995                         TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text,
1996                                 _("Spam"),
1997                                 _("Learn as..."));
1998                         toolbar_data->learn_spam_btn = item; 
1999                         toolbar_data->learn_spam_icon = icon_wid; 
2000                         g_object_ref(toolbar_data->learn_spam_icon);
2001
2002                         icon_ham = stock_pixmap_widget(container, STOCK_PIXMAP_HAM_BTN);
2003                         toolbar_data->learn_ham_icon = icon_ham; 
2004                         g_object_ref(toolbar_data->learn_ham_icon);
2005
2006                         menu = gtk_menu_new();
2007                         ADD_MENU_ITEM(_("Learn as _Spam"), toolbar_learn_menu_cb, TRUE);
2008                         ADD_MENU_ITEM(_("Learn as _Ham"), toolbar_learn_menu_cb, FALSE);
2009                         gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->learn_spam_btn), menu);
2010                         break;
2011                 case A_REPLY_MESSAGE:
2012 #ifndef GENERIC_UMPC
2013                         TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text,
2014                                 _("Reply to Message"),
2015                                 _("Reply to Message options"));
2016                         toolbar_data->reply_btn = item;
2017
2018                         menu = gtk_menu_new();
2019                         ADD_MENU_ITEM(_("_Reply with quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_WITH_QUOTE);
2020                         ADD_MENU_ITEM(_("Reply without _quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_WITHOUT_QUOTE);
2021                         gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->reply_btn), menu);
2022 #else
2023                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,
2024                                 _("Reply to Message"));
2025                         toolbar_data->reply_btn = item;
2026 #endif
2027                         break;
2028                 case A_REPLY_SENDER:
2029 #ifndef GENERIC_UMPC
2030                         TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text,
2031                                 _("Reply to Sender"),
2032                                 _("Reply to Sender options"));
2033                         toolbar_data->replysender_btn = item;
2034
2035                         menu = gtk_menu_new();
2036                         ADD_MENU_ITEM(_("_Reply with quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_SENDER_WITH_QUOTE);
2037                         ADD_MENU_ITEM(_("Reply without _quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE);
2038                         gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->replysender_btn), menu);
2039 #else
2040                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,
2041                                 _("Reply to Sender"));
2042                         toolbar_data->replysender_btn = item;
2043 #endif
2044                         break;
2045                 case A_REPLY_ALL:
2046 #ifndef GENERIC_UMPC
2047                         TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text,
2048                                 _("Reply to All"),
2049                                 _("Reply to All options"));
2050                         toolbar_data->replyall_btn = item;
2051
2052                         menu = gtk_menu_new();
2053                         ADD_MENU_ITEM(_("_Reply with quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_ALL_WITH_QUOTE);
2054                         ADD_MENU_ITEM(_("Reply without _quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE);
2055                         gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->replyall_btn), menu);
2056 #else
2057                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,
2058                                 _("Reply to All"));
2059                         toolbar_data->replyall_btn = item;
2060 #endif
2061                         break;
2062                 case A_REPLY_ML:
2063 #ifndef GENERIC_UMPC
2064                         TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text,
2065                                 _("Reply to Mailing-list"),
2066                                 _("Reply to Mailing-list options"));
2067                         toolbar_data->replylist_btn = item;
2068
2069                         menu = gtk_menu_new();
2070                         ADD_MENU_ITEM(_("_Reply with quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_LIST_WITH_QUOTE);
2071                         ADD_MENU_ITEM(_("Reply without _quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE);
2072                         gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->replylist_btn), menu);
2073 #else
2074                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,
2075                                 _("Reply to Mailing-list"));
2076                         toolbar_data->replylist_btn = item;
2077 #endif
2078                         break;
2079                 case A_FORWARD:
2080 #ifndef GENERIC_UMPC
2081                         TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text,
2082                                 _("Forward Message"),
2083                                 _("Forward Message options"));
2084                         toolbar_data->fwd_btn = item;
2085
2086                         menu = gtk_menu_new();
2087                         ADD_MENU_ITEM(_("_Forward"), toolbar_reply_menu_cb, COMPOSE_FORWARD_INLINE);
2088                         ADD_MENU_ITEM(_("For_ward as attachment"), toolbar_reply_menu_cb, COMPOSE_FORWARD_AS_ATTACH);
2089                         ADD_MENU_ITEM(_("Redirec_t"), toolbar_reply_menu_cb, COMPOSE_REDIRECT);
2090                         gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->fwd_btn), menu);
2091 #else
2092                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,
2093                                 _("Forward Message"));
2094                         toolbar_data->fwd_btn = item;
2095 #endif
2096                         break;
2097                 case A_TRASH:
2098                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Trash Message"));
2099                         toolbar_data->trash_btn = item;
2100                         break;
2101                 case A_DELETE_REAL:
2102                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Delete Message"));
2103                         toolbar_data->delete_btn = item;
2104                         break;
2105                 case A_EXECUTE:
2106                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Execute"));
2107                         toolbar_data->exec_btn = item;
2108                         break;
2109                 case A_GOTO_PREV:
2110                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Go to Previous Unread Message"));
2111                         toolbar_data->prev_btn = item;
2112                         break;
2113                 case A_GOTO_NEXT:
2114                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Go to Next Unread Message"));
2115                         toolbar_data->next_btn = item;
2116                         break;
2117                 
2118                 /* Compose Toolbar */
2119                 case A_SEND:
2120                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Send Message"));
2121                         toolbar_data->send_btn = item;
2122                         break;
2123                 case A_SENDL:
2124                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Put into queue folder and send later"));
2125                         toolbar_data->sendl_btn = item;
2126                         break;
2127                 case A_DRAFT:
2128                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Save to draft folder"));
2129                         toolbar_data->draft_btn = item; 
2130                         break;
2131                 case A_INSERT:
2132                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Insert file"));
2133                         toolbar_data->insert_btn = item; 
2134                         break;
2135                 case A_ATTACH:
2136                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Attach file"));
2137                         toolbar_data->attach_btn = item;
2138                         break;
2139                 case A_SIG:
2140                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Insert signature"));
2141                         toolbar_data->sig_btn = item;
2142                         break;
2143                 case A_EXTEDITOR:
2144                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Edit with external editor"));
2145                         toolbar_data->exteditor_btn = item;
2146                         break;
2147                 case A_LINEWRAP_CURRENT:
2148                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Wrap long lines of current paragraph"));
2149                         toolbar_data->linewrap_current_btn = item;
2150                         break;
2151                 case A_LINEWRAP_ALL:
2152                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Wrap all long lines"));
2153                         toolbar_data->linewrap_all_btn = item;
2154                         break;
2155                 case A_ADDRBOOK:
2156                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Address book"));
2157                         toolbar_data->addrbook_btn = item;
2158                         break;
2159 #ifdef USE_ENCHANT
2160                 case A_CHECK_SPELLING:
2161                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Check spelling"));
2162                         toolbar_data->spellcheck_btn = item;
2163                         break;
2164 #endif
2165
2166                 case A_CLAWS_ACTIONS:
2167                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,toolbar_item->text);
2168                         action_item = g_new0(ToolbarClawsActions, 1);
2169                         action_item->widget = item;
2170                         action_item->name   = g_strdup(toolbar_item->text);
2171
2172                         toolbar_data->action_list = 
2173                                 g_slist_append(toolbar_data->action_list,
2174                                                action_item);
2175                         break;
2176                 case A_CANCEL_INC:
2177                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Cancel receiving"));
2178                         toolbar_data->cancel_inc_btn = item;
2179                         break;
2180                 case A_CANCEL_SEND:
2181                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Cancel sending"));
2182                         toolbar_data->cancel_send_btn = item;
2183                         break;
2184                 case A_CANCEL_ALL:
2185                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Cancel receiving/sending"));
2186                         toolbar_data->cancel_all_btn = item;
2187                         break;
2188                 case A_CLAWS_PLUGINS:
2189                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text, toolbar_item->text);
2190                         break;
2191                 default:
2192                         TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,
2193                                 toolbar_ret_descr_from_val(toolbar_item->index));
2194                         /* find and set the tool tip text */
2195                         break;
2196                 }
2197
2198         }
2199         toolbar_data->toolbar = toolbar;
2200 #ifndef GENERIC_UMPC
2201 #if !(GTK_CHECK_VERSION(2,12,0))
2202         toolbar_data->tooltips = toolbar_tips;
2203 #endif
2204 #endif
2205         gtk_widget_show_all(toolbar);
2206
2207         if (type == TOOLBAR_MAIN) {
2208 #ifdef GENERIC_UMPC
2209                 MainWindow *mainwin = mainwindow_get_mainwindow();
2210                 GtkWidget *progressbar = gtk_progress_bar_new();
2211                 item = GTK_WIDGET(gtk_tool_item_new());
2212                 gtk_container_add (GTK_CONTAINER (item), progressbar);
2213                 gtk_widget_show(item);
2214                 gtk_widget_set_size_request(progressbar, 84, -1);
2215                 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), -1);
2216                 mainwin->progressbar = progressbar;
2217 #endif
2218                 activate_compose_button(toolbar_data, 
2219                                         prefs_common.toolbar_style, 
2220                                         toolbar_data->compose_btn_type);
2221         }
2222         if (type != TOOLBAR_COMPOSE)
2223                 activate_learn_button(toolbar_data, prefs_common.toolbar_style,
2224                                 LEARN_SPAM);
2225         
2226 #ifndef MAEMO
2227         gtk_container_add(GTK_CONTAINER(container), toolbar);
2228         gtk_container_set_border_width(GTK_CONTAINER(container), 0);
2229 #else
2230         if ( GTK_IS_WINDOW(container) ) {
2231                 hildon_window_add_toolbar (HILDON_WINDOW(container), GTK_TOOLBAR(toolbar));
2232                 gtk_widget_show_all (container);
2233         } else {
2234                 gtk_container_add(GTK_CONTAINER(container), toolbar);
2235                 gtk_container_set_border_width(GTK_CONTAINER(container), 2);
2236         }
2237 #endif
2238         return toolbar_data; 
2239 }
2240
2241 /**
2242  * Free toolbar structures
2243  */ 
2244 void toolbar_destroy(Toolbar * toolbar) {
2245
2246         TOOLBAR_DESTROY_ITEMS(toolbar->item_list);      
2247         TOOLBAR_DESTROY_ACTIONS(toolbar->action_list);
2248 }
2249
2250 void toolbar_update(ToolbarType type, gpointer data)
2251 {
2252         Toolbar *toolbar_data;
2253         GtkWidget *handlebox;
2254         MainWindow *mainwin = (MainWindow*)data;
2255         Compose    *compose = (Compose*)data;
2256         MessageView *msgview = (MessageView*)data;
2257
2258 #ifndef GENERIC_UMPC
2259         switch(type) {
2260         case TOOLBAR_MAIN:
2261                 toolbar_data = mainwin->toolbar;
2262                 handlebox    = mainwin->handlebox;
2263                 break;
2264         case TOOLBAR_COMPOSE:
2265                 toolbar_data = compose->toolbar;
2266                 handlebox    = compose->handlebox;
2267                 break;
2268         case TOOLBAR_MSGVIEW:
2269                 toolbar_data = msgview->toolbar;
2270                 handlebox    = msgview->handlebox;
2271                 break;
2272         default:
2273                 return;
2274         }
2275
2276         gtk_container_remove(GTK_CONTAINER(handlebox), 
2277                              GTK_WIDGET(toolbar_data->toolbar));
2278
2279         toolbar_init(toolbar_data);
2280         toolbar_data = toolbar_create(type, handlebox, data);
2281 #else
2282         switch(type) {
2283         case TOOLBAR_MAIN:
2284                 toolbar_data = mainwin->toolbar;
2285                 handlebox    = mainwin->window;
2286                 break;
2287         case TOOLBAR_COMPOSE:
2288                 toolbar_data = compose->toolbar;
2289                 handlebox    = compose->window;
2290                 break;
2291         case TOOLBAR_MSGVIEW:
2292                 toolbar_data = msgview->toolbar;
2293                 handlebox    = msgview->window;
2294                 break;
2295         default:
2296                 return;
2297         }
2298 #ifdef MAEMO
2299         hildon_window_remove_toolbar(HILDON_WINDOW(handlebox), GTK_TOOLBAR(toolbar_data->toolbar));
2300 #endif
2301         toolbar_init(toolbar_data);
2302         toolbar_data = toolbar_create(type, handlebox, data);
2303 #endif
2304
2305         switch(type) {
2306         case TOOLBAR_MAIN:
2307                 mainwin->toolbar = toolbar_data;
2308                 break;
2309         case TOOLBAR_COMPOSE:
2310                 compose->toolbar = toolbar_data;
2311                 break;
2312         case TOOLBAR_MSGVIEW:
2313                 msgview->toolbar = toolbar_data;
2314                 break;
2315         }
2316
2317         toolbar_style(type, prefs_common.toolbar_style, data);
2318
2319         if (type == TOOLBAR_MAIN) {
2320                 toolbar_main_set_sensitive((MainWindow*)data);
2321                 account_set_menu_only_toolbar();
2322         }
2323 }
2324
2325 #if !GTK_CHECK_VERSION(2,14,0)
2326 /* Work around http://bugzilla.gnome.org/show_bug.cgi?id=56070 */
2327 #define GTK_BUTTON_SET_SENSITIVE(widget,sensitive) {            \
2328         gboolean in_btn1 = FALSE, in_btn2 = FALSE;              \
2329         if (GTK_IS_BUTTON(widget))                              \
2330                 in_btn1 = GTK_BUTTON(widget)->in_button;        \
2331         else if (GTK_IS_MENU_TOOL_BUTTON(widget)) {             \
2332                 GtkWidget *child = gtk_bin_get_child(           \
2333                         GTK_BIN(widget));                       \
2334                 GList *gchild = gtk_container_get_children(     \
2335                         GTK_CONTAINER(child));                  \
2336                 GtkWidget *btn = (GtkWidget *)gchild->data;     \
2337                 GtkWidget *arr = (GtkWidget *)                  \
2338                         (gchild->next?gchild->next->data:NULL); \
2339                 g_list_free(gchild);                            \
2340                 if (GTK_IS_BUTTON(btn))                         \
2341                         in_btn1 = GTK_BUTTON(btn)->in_button;   \
2342                 if (GTK_IS_BUTTON(arr))                         \
2343                         in_btn2 = GTK_BUTTON(arr)->in_button;   \
2344         }                                                       \
2345         else if (GTK_IS_TOOL_ITEM(widget)) {                    \
2346                 GtkWidget *child = gtk_bin_get_child(           \
2347                         GTK_BIN(widget));                       \
2348                 if (GTK_IS_BUTTON(child))                       \
2349                         in_btn1 = GTK_BUTTON(child)->in_button; \
2350         }                                                       \
2351         gtk_widget_set_sensitive(widget, sensitive);            \
2352         if (GTK_IS_BUTTON(widget))                              \
2353                 GTK_BUTTON(widget)->in_button = in_btn1;        \
2354         else if (GTK_IS_MENU_TOOL_BUTTON(widget)) {             \
2355                 GtkWidget *child = gtk_bin_get_child(           \
2356                         GTK_BIN(widget));                       \
2357                 GList *gchild = gtk_container_get_children(     \
2358                         GTK_CONTAINER(child));                  \
2359                 GtkWidget *btn = (GtkWidget *)gchild->data;     \
2360                 GtkWidget *arr = (GtkWidget *)                  \
2361                         (gchild->next?gchild->next->data:NULL); \
2362                 g_list_free(gchild);                            \
2363                 if (GTK_IS_BUTTON(btn))                         \
2364                         GTK_BUTTON(btn)->in_button = in_btn1;   \
2365                 if (GTK_IS_BUTTON(arr))                         \
2366                         GTK_BUTTON(arr)->in_button = in_btn2;   \
2367         }                                                       \
2368         else if (GTK_IS_TOOL_ITEM(widget)) {                    \
2369                 GtkWidget *child = gtk_bin_get_child(           \
2370                         GTK_BIN(widget));                       \
2371                 if (GTK_IS_BUTTON(child))                       \
2372                         GTK_BUTTON(child)->in_button = in_btn1; \
2373         }                                                       \
2374 }
2375 #else
2376 #define GTK_BUTTON_SET_SENSITIVE(widget,sensitive) {            \
2377         gtk_widget_set_sensitive(widget, sensitive);            \
2378 }
2379 #endif
2380
2381 void toolbar_main_set_sensitive(gpointer data)
2382 {
2383         SensitiveCond state;
2384         gboolean sensitive;
2385         MainWindow *mainwin = (MainWindow*)data;
2386         Toolbar *toolbar = mainwin->toolbar;
2387         GSList *cur;
2388         GSList *entry_list = NULL;
2389         
2390         typedef struct _Entry Entry;
2391         struct _Entry {
2392                 GtkWidget *widget;
2393                 SensitiveCondMask cond;
2394                 gboolean empty;
2395         };
2396
2397 #define SET_WIDGET_COND(w, ...)     \
2398 do { \
2399         Entry *e = g_new0(Entry, 1); \
2400         e->widget = w; \
2401         e->cond = main_window_get_mask(__VA_ARGS__, -1); \
2402         entry_list = g_slist_append(entry_list, e); \
2403 } while (0)
2404         
2405         /* match all bit flags */
2406
2407         if (toolbar->get_btn)
2408                 SET_WIDGET_COND(toolbar->get_btn, 
2409                         M_HAVE_ACCOUNT, M_UNLOCKED, M_HAVE_RETRIEVABLE_ACCOUNT);
2410
2411         if (toolbar->getall_btn) {
2412                 SET_WIDGET_COND(toolbar->getall_btn, 
2413                         M_HAVE_ACCOUNT, M_UNLOCKED, M_HAVE_ANY_RETRIEVABLE_ACCOUNT);
2414         }
2415         if (toolbar->send_btn) {
2416                 SET_WIDGET_COND(toolbar->send_btn,
2417                         M_HAVE_QUEUED_MAILS);
2418         }
2419         if (toolbar->compose_mail_btn) {
2420                 SET_WIDGET_COND(toolbar->compose_mail_btn, 
2421                         M_HAVE_ACCOUNT);
2422         }
2423         if (toolbar->close_window_btn) {
2424                 SET_WIDGET_COND(toolbar->close_window_btn, 
2425                         M_UNLOCKED);
2426         }
2427         if (toolbar->open_mail_btn) {
2428                 SET_WIDGET_COND(toolbar->open_mail_btn, 
2429                         M_TARGET_EXIST, M_SUMMARY_ISLIST);
2430         }
2431         if (toolbar->reply_btn) {
2432                 SET_WIDGET_COND(toolbar->reply_btn,
2433                         M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST);
2434         }
2435         if (toolbar->replyall_btn) {
2436                 SET_WIDGET_COND(toolbar->replyall_btn,
2437                         M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST);
2438         }
2439         if (toolbar->replylist_btn) {
2440                 SET_WIDGET_COND(toolbar->replylist_btn,
2441                         M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST);
2442         }
2443         if (toolbar->replysender_btn) {
2444                 SET_WIDGET_COND(toolbar->replysender_btn,
2445                         M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST);
2446         }
2447         if (toolbar->fwd_btn) {
2448                 SET_WIDGET_COND(toolbar->fwd_btn, 
2449                         M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST);
2450         }
2451
2452         if (prefs_common.next_unread_msg_dialog == NEXTUNREADMSGDIALOG_ASSUME_NO) {
2453                 SET_WIDGET_COND(toolbar->next_btn, M_MSG_EXIST, M_SUMMARY_ISLIST);
2454         } else {
2455                 SET_WIDGET_COND(toolbar->next_btn, 0);
2456         }
2457         
2458         if (toolbar->trash_btn)
2459                 SET_WIDGET_COND(toolbar->trash_btn,
2460                         M_TARGET_EXIST, M_ALLOW_DELETE, M_NOT_NEWS);
2461
2462         if (toolbar->delete_btn)
2463                 SET_WIDGET_COND(toolbar->delete_btn,
2464                         M_TARGET_EXIST, M_ALLOW_DELETE);
2465
2466         if (toolbar->exec_btn)
2467                 SET_WIDGET_COND(toolbar->exec_btn, 
2468                         M_DELAY_EXEC);
2469         
2470         if (toolbar->learn_spam_btn)
2471                 SET_WIDGET_COND(toolbar->learn_spam_btn, 
2472                         M_TARGET_EXIST, M_CAN_LEARN_SPAM, M_SUMMARY_ISLIST);
2473
2474         if (toolbar->cancel_inc_btn)
2475                 SET_WIDGET_COND(toolbar->cancel_inc_btn,
2476                                 M_INC_ACTIVE);
2477
2478         if (toolbar->cancel_send_btn)
2479                 SET_WIDGET_COND(toolbar->cancel_send_btn,
2480                                 M_SEND_ACTIVE);
2481
2482         for (cur = toolbar->action_list; cur != NULL;  cur = cur->next) {
2483                 ToolbarClawsActions *act = (ToolbarClawsActions*)cur->data;
2484                 
2485                 SET_WIDGET_COND(act->widget, M_TARGET_EXIST, M_UNLOCKED);
2486         }
2487
2488         state = main_window_get_current_state(mainwin);
2489
2490         for (cur = entry_list; cur != NULL; cur = cur->next) {
2491                 Entry *e = (Entry*) cur->data;
2492
2493                 if (e->widget != NULL) {
2494                         sensitive = ((e->cond & state) == e->cond);
2495                         GTK_BUTTON_SET_SENSITIVE(e->widget, sensitive); 
2496                 }
2497         }
2498         
2499         while (entry_list != NULL) {
2500                 Entry *e = (Entry*) entry_list->data;
2501
2502                 g_free(e);
2503                 entry_list = g_slist_remove(entry_list, e);
2504         }
2505
2506         /* match any bit flags */
2507
2508         if (toolbar->cancel_all_btn)
2509                 SET_WIDGET_COND(toolbar->cancel_all_btn,
2510                                 M_INC_ACTIVE, M_SEND_ACTIVE);
2511
2512         for (cur = entry_list; cur != NULL; cur = cur->next) {
2513                 Entry *e = (Entry*) cur->data;
2514
2515                 if (e->widget != NULL) {
2516                         sensitive = ((e->cond & state) != 0);
2517                         GTK_BUTTON_SET_SENSITIVE(e->widget, sensitive); 
2518                 }
2519         }
2520
2521         while (entry_list != NULL) {
2522                 Entry *e = (Entry*) entry_list->data;
2523
2524                 g_free(e);
2525                 entry_list = g_slist_remove(entry_list, e);
2526         }
2527
2528         g_slist_free(entry_list);
2529
2530         activate_compose_button(toolbar, 
2531                                 prefs_common.toolbar_style,
2532                                 toolbar->compose_btn_type);
2533         
2534 #undef SET_WIDGET_COND
2535 }
2536
2537 void toolbar_comp_set_sensitive(gpointer data, gboolean sensitive)
2538 {
2539         Compose *compose = (Compose*)data;
2540         GSList *items = compose->toolbar->action_list;
2541
2542         if (compose->toolbar->send_btn)
2543                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->send_btn, sensitive);
2544         if (compose->toolbar->sendl_btn)
2545                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->sendl_btn, sensitive);
2546         if (compose->toolbar->draft_btn )
2547                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->draft_btn , sensitive);
2548         if (compose->toolbar->insert_btn )
2549                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->insert_btn , sensitive);
2550         if (compose->toolbar->attach_btn)
2551                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->attach_btn, sensitive);
2552         if (compose->toolbar->sig_btn)
2553                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->sig_btn, sensitive);
2554         if (compose->toolbar->exteditor_btn)
2555                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->exteditor_btn, sensitive);
2556         if (compose->toolbar->linewrap_current_btn)
2557                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->linewrap_current_btn, sensitive);
2558         if (compose->toolbar->linewrap_all_btn)
2559                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->linewrap_all_btn, sensitive);
2560         if (compose->toolbar->addrbook_btn)
2561                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->addrbook_btn, sensitive);
2562 #ifdef USE_ENCHANT
2563         if (compose->toolbar->spellcheck_btn)
2564                 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->spellcheck_btn, sensitive);
2565 #endif
2566         for (; items != NULL; items = g_slist_next(items)) {
2567                 ToolbarClawsActions *item = (ToolbarClawsActions *)items->data;
2568                 GTK_BUTTON_SET_SENSITIVE(item->widget, sensitive);
2569         }
2570 }
2571
2572 /**
2573  * Initialize toolbar structure
2574  **/
2575 static void toolbar_init(Toolbar * toolbar)
2576 {
2577
2578         toolbar->toolbar           = NULL;
2579         toolbar->folders_btn       = NULL;
2580         toolbar->get_btn           = NULL;
2581         toolbar->getall_btn        = NULL;
2582         toolbar->send_btn          = NULL;
2583         toolbar->compose_mail_btn  = NULL;
2584         toolbar->compose_mail_icon = NULL;
2585         toolbar->compose_news_icon = NULL;
2586         toolbar->reply_btn         = NULL;
2587         toolbar->replysender_btn   = NULL;
2588         toolbar->replyall_btn      = NULL;
2589         toolbar->replylist_btn     = NULL;
2590         toolbar->fwd_btn           = NULL;
2591         toolbar->trash_btn         = NULL;
2592         toolbar->delete_btn        = NULL;
2593         toolbar->prev_btn          = NULL;
2594         toolbar->next_btn          = NULL;
2595         toolbar->exec_btn          = NULL;
2596         toolbar->separator         = NULL;
2597         toolbar->learn_spam_btn    = NULL;
2598         toolbar->learn_spam_icon   = NULL;
2599         toolbar->learn_ham_icon    = NULL;
2600         toolbar->cancel_inc_btn    = NULL;
2601         toolbar->cancel_send_btn   = NULL;
2602         toolbar->cancel_all_btn    = NULL;
2603
2604         /* compose buttons */ 
2605         toolbar->sendl_btn         = NULL;
2606         toolbar->draft_btn         = NULL;
2607         toolbar->insert_btn        = NULL;
2608         toolbar->attach_btn        = NULL;
2609         toolbar->sig_btn           = NULL; 
2610         toolbar->exteditor_btn     = NULL; 
2611         toolbar->linewrap_current_btn = NULL;   
2612         toolbar->linewrap_all_btn  = NULL;      
2613         toolbar->addrbook_btn      = NULL; 
2614
2615         toolbar->open_mail_btn     = NULL;
2616         toolbar->close_window_btn  = NULL;
2617         toolbar->preferences_btn   = NULL;
2618         toolbar->action_list       = NULL;
2619         toolbar->item_list         = NULL;
2620 #ifdef USE_ENCHANT
2621         toolbar->spellcheck_btn    = NULL;
2622 #endif
2623 #if !GTK_CHECK_VERSION(2,12,0)
2624         toolbar->tooltips          = NULL;
2625 #endif
2626
2627         toolbar_destroy(toolbar);
2628 }
2629
2630 /*
2631  */
2632 static void toolbar_reply(gpointer data, guint action)
2633 {
2634         ToolbarItem *toolbar_item = (ToolbarItem*)data;
2635         MainWindow *mainwin;
2636         MessageView *msgview;
2637         GSList *msginfo_list = NULL;
2638
2639         cm_return_if_fail(toolbar_item != NULL);
2640
2641         switch (toolbar_item->type) {
2642         case TOOLBAR_MAIN:
2643                 mainwin = (MainWindow*)toolbar_item->parent;
2644                 msginfo_list = summary_get_selection(mainwin->summaryview);
2645                 msgview = (MessageView*)mainwin->messageview;
2646                 break;
2647         case TOOLBAR_MSGVIEW:
2648                 msgview = (MessageView*)toolbar_item->parent;
2649                 cm_return_if_fail(msgview != NULL);     
2650                 msginfo_list = g_slist_append(msginfo_list, msgview->msginfo);
2651                 break;
2652         default:
2653                 return;
2654         }
2655
2656         cm_return_if_fail(msgview != NULL);
2657         cm_return_if_fail(msginfo_list != NULL);
2658         compose_reply_from_messageview(msgview, msginfo_list, action);
2659         g_slist_free(msginfo_list);
2660
2661         /* TODO: update reply state ion summaryview */
2662 }
2663
2664
2665 /* exported functions */
2666
2667 void inc_mail_cb(gpointer data, guint action, GtkWidget *widget)
2668 {
2669         MainWindow *mainwin = (MainWindow*)data;
2670
2671         inc_mail(mainwin, prefs_common.newmail_notify_manu);
2672 }
2673
2674 void inc_all_account_mail_cb(gpointer data, guint action, GtkWidget *widget)
2675 {
2676         MainWindow *mainwin = (MainWindow*)data;
2677
2678         inc_all_account_mail(mainwin, FALSE, prefs_common.newmail_notify_manu);
2679 }
2680
2681 void send_queue_cb(gpointer data, guint action, GtkWidget *widget)
2682 {
2683         GList *list;
2684         gboolean found;
2685         gboolean got_error = FALSE;
2686         gchar *errstr = NULL;
2687
2688         if (prefs_common.work_offline)
2689                 if (alertpanel(_("Offline warning"), 
2690                                _("You're working offline. Override?"),
2691                                GTK_STOCK_NO, GTK_STOCK_YES,
2692                                NULL) != G_ALERTALTERNATE)
2693                 return;
2694
2695         /* ask for confirmation before sending queued messages only
2696            in online mode and if there is at least one message queued
2697            in any of the folder queue
2698         */
2699         if (prefs_common.confirm_send_queued_messages) {
2700                 found = FALSE;
2701                 /* check if there's a queued message */
2702                 for (list = folder_get_list(); !found && list != NULL; list = list->next) {
2703                         Folder *folder = list->data;
2704
2705                         found = !procmsg_queue_is_empty(folder->queue);
2706                 }
2707                 /* if necessary, ask for confirmation before sending */
2708                 if (found && !prefs_common.work_offline) {
2709                         if (alertpanel(_("Send queued messages"), 
2710                                    _("Send all queued messages?"),
2711                                    GTK_STOCK_CANCEL, _("_Send"),
2712                                    NULL) != G_ALERTALTERNATE)
2713                                 return;
2714                 }
2715         }
2716
2717         for (list = folder_get_list(); list != NULL; list = list->next) {
2718                 Folder *folder = list->data;
2719
2720                 if (folder->queue) {
2721                         if (procmsg_send_queue(folder->queue, 
2722                                                prefs_common.savemsg,
2723                                                &errstr) < 0)
2724                                 got_error = TRUE;
2725                 }
2726         }
2727         if (got_error) {
2728                 if (!errstr)
2729                         alertpanel_error_log(_("Some errors occurred while "
2730                                            "sending queued messages."));
2731                 else {
2732                         alertpanel_error_log(_("Some errors occurred "
2733                                         "while sending queued messages:\n%s"), errstr);
2734                         g_free(errstr);
2735                 }
2736         }
2737 }
2738
2739 void compose_mail_cb(gpointer data, guint action, GtkWidget *widget)
2740 {
2741         MainWindow *mainwin = (MainWindow*)data;
2742         PrefsAccount *ac = NULL;
2743         FolderItem *item = mainwin->summaryview->folder_item;   
2744         GList * list;
2745         GList * cur;
2746         
2747         if (item) {
2748                 ac = account_find_from_item(item);
2749                 if (ac && ac->protocol != A_NNTP) {
2750                         compose_new_with_folderitem(ac, item, NULL);            /* CLAWS */
2751                         return;
2752                 }
2753         }
2754
2755         /*
2756          * CLAWS - use current account
2757          */
2758         if (cur_account && (cur_account->protocol != A_NNTP)) {
2759                 compose_new_with_folderitem(cur_account, item, NULL);
2760                 return;
2761         }
2762
2763         /*
2764          * CLAWS - just get the first one
2765          */
2766         list = account_get_list();
2767         for (cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2768                 ac = (PrefsAccount *) cur->data;
2769                 if (ac->protocol != A_NNTP) {
2770                         compose_new_with_folderitem(ac, item, NULL);
2771                         return;
2772                 }
2773         }
2774 }
2775
2776 void compose_news_cb(gpointer data, guint action, GtkWidget *widget)
2777 {
2778         MainWindow *mainwin = (MainWindow*)data;
2779         PrefsAccount * ac = NULL;
2780         GList * list;
2781         GList * cur;
2782
2783         if (mainwin->summaryview->folder_item) {
2784                 ac = mainwin->summaryview->folder_item->folder->account;
2785                 if (ac && ac->protocol == A_NNTP) {
2786                         compose_new_with_folderitem(ac,
2787                                     mainwin->summaryview->folder_item, NULL);
2788                         return;
2789                 }
2790         }
2791
2792         list = account_get_list();
2793         for(cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2794                 ac = (PrefsAccount *) cur->data;
2795                 if (ac->protocol == A_NNTP) {
2796                         compose_new_with_folderitem(ac,
2797                                     mainwin->summaryview->folder_item, NULL);
2798                         return;
2799                 }
2800         }
2801 }