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