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