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