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