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