2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2006 Hiroyuki Yamamoto and the Sylpheed-Claws team
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.
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.
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.
21 * General functions for accessing address book files.
31 #include <glib/gi18n.h>
39 #include "mainwindow.h"
40 #include "summaryview.h"
45 #include "prefs_gtk.h"
47 #include "stock_pixmap.h"
48 #include "manage_window.h"
54 #include "prefs_actions.h"
55 #include "prefs_common.h"
56 #include "prefs_toolbar.h"
57 #include "alertpanel.h"
60 #define TOOLBAR_TAG_INDEX "toolbar"
61 #define TOOLBAR_TAG_ITEM "item"
62 #define TOOLBAR_TAG_SEPARATOR "separator"
64 #define TOOLBAR_ICON_FILE "file"
65 #define TOOLBAR_ICON_TEXT "text"
66 #define TOOLBAR_ICON_ACTION "action"
68 gboolean toolbar_is_duplicate (gint action,
70 static void toolbar_parse_item (XMLFile *file,
73 static gint toolbar_ret_val_from_text (const gchar *text);
74 static gchar *toolbar_ret_text_from_val (gint val);
76 static void toolbar_set_default_main (void);
77 static void toolbar_set_default_compose (void);
78 static void toolbar_set_default_msgview (void);
80 static void toolbar_style (ToolbarType type,
84 static MainWindow *get_mainwin (gpointer data);
85 static void activate_compose_button (Toolbar *toolbar,
87 ComposeButtonType type);
89 /* toolbar callbacks */
90 static void toolbar_reply (gpointer data,
92 static void toolbar_delete_cb (GtkWidget *widget,
94 static void toolbar_trash_cb (GtkWidget *widget,
97 static void toolbar_compose_cb (GtkWidget *widget,
100 static void toolbar_learn_cb (GtkWidget *widget,
103 static void toolbar_reply_cb (GtkWidget *widget,
106 static void toolbar_reply_to_all_cb (GtkWidget *widget,
109 static void toolbar_reply_to_list_cb (GtkWidget *widget,
112 static void toolbar_reply_to_sender_cb (GtkWidget *widget,
115 static void toolbar_forward_cb (GtkWidget *widget,
118 static void toolbar_prev_unread_cb (GtkWidget *widget,
120 static void toolbar_next_unread_cb (GtkWidget *widget,
123 static void toolbar_ignore_thread_cb (GtkWidget *widget,
126 static void toolbar_print_cb (GtkWidget *widget,
129 static void toolbar_actions_execute_cb (GtkWidget *widget,
133 static void toolbar_send_cb (GtkWidget *widget,
135 static void toolbar_send_later_cb (GtkWidget *widget,
137 static void toolbar_draft_cb (GtkWidget *widget,
139 static void toolbar_insert_cb (GtkWidget *widget,
141 static void toolbar_attach_cb (GtkWidget *widget,
143 static void toolbar_sig_cb (GtkWidget *widget,
145 static void toolbar_ext_editor_cb (GtkWidget *widget,
147 static void toolbar_linewrap_current_cb (GtkWidget *widget,
149 static void toolbar_linewrap_all_cb (GtkWidget *widget,
151 static void toolbar_addrbook_cb (GtkWidget *widget,
154 static void toolbar_check_spelling_cb (GtkWidget *widget,
161 } toolbar_text [] = {
162 { "A_RECEIVE_ALL", N_("Receive Mail on all Accounts") },
163 { "A_RECEIVE_CUR", N_("Receive Mail on current Account") },
164 { "A_SEND_QUEUED", N_("Send Queued Messages") },
165 { "A_COMPOSE_EMAIL", N_("Compose Email") },
166 { "A_COMPOSE_NEWS", N_("Compose News") },
167 { "A_REPLY_MESSAGE", N_("Reply to Message") },
168 { "A_REPLY_SENDER", N_("Reply to Sender") },
169 { "A_REPLY_ALL", N_("Reply to All") },
170 { "A_REPLY_ML", N_("Reply to Mailing-list") },
171 { "A_FORWARD", N_("Forward Message") },
172 { "A_TRASH", N_("Trash Message") },
173 { "A_DELETE_REAL", N_("Delete Message") },
174 { "A_EXECUTE", N_("Execute") },
175 { "A_GOTO_PREV", N_("Go to Previous Unread Message") },
176 { "A_GOTO_NEXT", N_("Go to Next Unread Message") },
177 { "A_IGNORE_THREAD", N_("Ignore thread") },
178 { "A_PRINT", N_("Print") },
179 { "A_LEARN_SPAM", N_("Learn Spam") },
180 { "A_LEARN_HAM", N_("Learn Ham") },
182 { "A_SEND", N_("Send Message") },
183 { "A_SENDL", N_("Put into queue folder and send later") },
184 { "A_DRAFT", N_("Save to draft folder") },
185 { "A_INSERT", N_("Insert file") },
186 { "A_ATTACH", N_("Attach file") },
187 { "A_SIG", N_("Insert signature") },
188 { "A_EXTEDITOR", N_("Edit with external editor") },
189 { "A_LINEWRAP_CURRENT", N_("Wrap long lines of current paragraph") },
190 { "A_LINEWRAP_ALL", N_("Wrap all long lines") },
191 { "A_ADDRBOOK", N_("Address book") },
193 { "A_CHECK_SPELLING", N_("Check spelling") },
195 { "A_SYL_ACTIONS", N_("Sylpheed-Claws Actions Feature") },
196 { "A_SEPARATOR", "Separator" }
199 /* struct holds configuration files and a list of
200 * currently active toolbar items
201 * TOOLBAR_MAIN, TOOLBAR_COMPOSE and TOOLBAR_MSGVIEW
205 const gchar *conf_file;
207 } toolbar_config[3] = {
208 { "toolbar_main.xml", NULL},
209 { "toolbar_compose.xml", NULL},
210 { "toolbar_msgview.xml", NULL}
213 static GtkItemFactoryEntry reply_entries[] =
215 {N_("/Reply with _quote"), NULL, toolbar_reply, COMPOSE_REPLY_WITH_QUOTE, NULL},
216 {N_("/_Reply without quote"), NULL, toolbar_reply, COMPOSE_REPLY_WITHOUT_QUOTE, NULL}
218 static GtkItemFactoryEntry replyall_entries[] =
220 {N_("/Reply to all with _quote"), "<shift>A", toolbar_reply, COMPOSE_REPLY_TO_ALL_WITH_QUOTE, NULL},
221 {N_("/_Reply to all without quote"), "a", toolbar_reply, COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE, NULL}
223 static GtkItemFactoryEntry replylist_entries[] =
225 {N_("/Reply to list with _quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_LIST_WITH_QUOTE, NULL},
226 {N_("/_Reply to list without quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE, NULL}
228 static GtkItemFactoryEntry replysender_entries[] =
230 {N_("/Reply to sender with _quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_SENDER_WITH_QUOTE, NULL},
231 {N_("/_Reply to sender without quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE, NULL}
233 static GtkItemFactoryEntry forward_entries[] =
235 {N_("/_Forward"), "f", toolbar_reply, COMPOSE_FORWARD_INLINE, NULL},
236 {N_("/For_ward as attachment"), "<shift>F", toolbar_reply, COMPOSE_FORWARD_AS_ATTACH, NULL},
237 {N_("/Redirec_t"), NULL, toolbar_reply, COMPOSE_REDIRECT, NULL}
241 gint toolbar_ret_val_from_descr(const gchar *descr)
245 for (i = 0; i < N_ACTION_VAL; i++) {
246 if (g_utf8_collate(gettext(toolbar_text[i].descr), descr) == 0)
253 gchar *toolbar_ret_descr_from_val(gint val)
255 g_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL);
257 return gettext(toolbar_text[val].descr);
260 static gint toolbar_ret_val_from_text(const gchar *text)
264 for (i = 0; i < N_ACTION_VAL; i++) {
265 if (g_utf8_collate(toolbar_text[i].index_str, text) == 0)
272 static gchar *toolbar_ret_text_from_val(gint val)
274 g_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL);
276 return toolbar_text[val].index_str;
279 gboolean toolbar_is_duplicate(gint action, ToolbarType source)
283 if ((action == A_SEPARATOR) || (action == A_SYL_ACTIONS))
286 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
287 ToolbarItem *item = (ToolbarItem*) cur->data;
289 if (item->index == action)
295 /* depending on toolbar type this function
296 returns a list of available toolbar events being
297 displayed by prefs_toolbar
299 GList *toolbar_get_action_items(ToolbarType source)
304 if (source == TOOLBAR_MAIN) {
305 gint main_items[] = { A_RECEIVE_ALL, A_RECEIVE_CUR, A_SEND_QUEUED,
306 A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER,
307 A_REPLY_ALL, A_REPLY_ML, A_FORWARD,
308 A_TRASH , A_DELETE_REAL, A_EXECUTE, A_GOTO_PREV,
309 A_GOTO_NEXT, A_IGNORE_THREAD, A_PRINT,
310 A_ADDRBOOK, A_LEARN_SPAM, A_SYL_ACTIONS };
312 for (i = 0; i < sizeof main_items / sizeof main_items[0]; i++) {
313 items = g_list_append(items, gettext(toolbar_text[main_items[i]].descr));
316 else if (source == TOOLBAR_COMPOSE) {
317 gint comp_items[] = { A_SEND, A_SENDL, A_DRAFT,
318 A_INSERT, A_ATTACH, A_SIG,
319 A_EXTEDITOR, A_LINEWRAP_CURRENT,
320 A_LINEWRAP_ALL, A_ADDRBOOK,
326 for (i = 0; i < sizeof comp_items / sizeof comp_items[0]; i++)
327 items = g_list_append(items, gettext(toolbar_text[comp_items[i]].descr));
329 else if (source == TOOLBAR_MSGVIEW) {
330 gint msgv_items[] = { A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER,
331 A_REPLY_ALL, A_REPLY_ML, A_FORWARD,
332 A_TRASH, A_DELETE_REAL, A_GOTO_PREV, A_GOTO_NEXT,
333 A_ADDRBOOK, A_LEARN_SPAM, A_SYL_ACTIONS };
335 for (i = 0; i < sizeof msgv_items / sizeof msgv_items[0]; i++)
336 items = g_list_append(items, gettext(toolbar_text[msgv_items[i]].descr));
342 static void toolbar_parse_item(XMLFile *file, ToolbarType source)
346 ToolbarItem *item = NULL;
347 gboolean rewrite = FALSE;
349 attr = xml_get_current_tag_attr(file);
350 item = g_new0(ToolbarItem, 1);
352 name = ((XMLAttr *)attr->data)->name;
353 value = ((XMLAttr *)attr->data)->value;
355 if (g_utf8_collate(name, TOOLBAR_ICON_FILE) == 0)
356 item->file = g_strdup (value);
357 else if (g_utf8_collate(name, TOOLBAR_ICON_TEXT) == 0)
358 item->text = g_strdup (value);
359 else if (g_utf8_collate(name, TOOLBAR_ICON_ACTION) == 0)
360 item->index = toolbar_ret_val_from_text(value);
361 if (item->index == -1 && !strcmp(value, "A_DELETE")) {
363 item->index = A_TRASH;
365 item->file = g_strdup("trash_btn");
367 item->text = g_strdup(_("Trash"));
370 attr = g_list_next(attr);
372 if (item->index != -1) {
374 if (!toolbar_is_duplicate(item->index, source))
375 toolbar_config[source].item_list = g_slist_append(toolbar_config[source].item_list,
379 toolbar_save_config_file(source);
383 static void toolbar_set_default_main(void)
389 } default_toolbar[] = {
390 { A_RECEIVE_ALL, STOCK_PIXMAP_MAIL_RECEIVE_ALL, _("Get Mail") },
391 { A_SEPARATOR, 0, ("") },
392 { A_SEND_QUEUED, STOCK_PIXMAP_MAIL_SEND_QUEUE, _("Send") },
393 { A_COMPOSE_EMAIL, STOCK_PIXMAP_MAIL_COMPOSE, _("Compose") },
394 { A_SEPARATOR, 0, ("") },
395 { A_REPLY_MESSAGE, STOCK_PIXMAP_MAIL_REPLY, _("Reply") },
396 { A_REPLY_ALL, STOCK_PIXMAP_MAIL_REPLY_TO_ALL, _("All") },
397 { A_REPLY_SENDER, STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR, _("Sender") },
398 { A_FORWARD, STOCK_PIXMAP_MAIL_FORWARD, _("Forward") },
399 { A_SEPARATOR, 0, ("") },
400 { A_TRASH, STOCK_PIXMAP_TRASH, _("Trash") },
401 #ifdef USE_SPAMASSASSIN_PLUGIN
402 { A_LEARN_SPAM, STOCK_PIXMAP_SPAM_BTN, _("Spam") },
404 { A_SEPARATOR, 0, ("") },
405 { A_GOTO_NEXT, STOCK_PIXMAP_DOWN_ARROW, _("Next") }
410 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
412 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
414 if (default_toolbar[i].action != A_SEPARATOR) {
416 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
418 toolbar_item->file = g_strdup(file);
419 toolbar_item->index = default_toolbar[i].action;
420 toolbar_item->text = g_strdup(default_toolbar[i].text);
423 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
424 toolbar_item->index = A_SEPARATOR;
427 if (toolbar_item->index != -1) {
428 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MAIN))
429 toolbar_config[TOOLBAR_MAIN].item_list =
430 g_slist_append(toolbar_config[TOOLBAR_MAIN].item_list, toolbar_item);
435 static void toolbar_set_default_compose(void)
441 } default_toolbar[] = {
442 { A_SEND, STOCK_PIXMAP_MAIL_SEND, _("Send") },
443 { A_SENDL, STOCK_PIXMAP_MAIL_SEND_QUEUE, _("Send later") },
444 { A_DRAFT, STOCK_PIXMAP_MAIL, _("Draft") },
445 { A_SEPARATOR, 0, ("") },
446 { A_INSERT, STOCK_PIXMAP_INSERT_FILE, _("Insert") },
447 { A_ATTACH, STOCK_PIXMAP_MAIL_ATTACH, _("Attach") },
448 { A_SEPARATOR, 0, ("") },
449 { A_ADDRBOOK, STOCK_PIXMAP_ADDRESS_BOOK, _("Address") }
454 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
456 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
458 if (default_toolbar[i].action != A_SEPARATOR) {
460 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
462 toolbar_item->file = g_strdup(file);
463 toolbar_item->index = default_toolbar[i].action;
464 toolbar_item->text = g_strdup(default_toolbar[i].text);
467 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
468 toolbar_item->index = A_SEPARATOR;
471 if (toolbar_item->index != -1) {
472 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_COMPOSE))
473 toolbar_config[TOOLBAR_COMPOSE].item_list =
474 g_slist_append(toolbar_config[TOOLBAR_COMPOSE].item_list, toolbar_item);
479 static void toolbar_set_default_msgview(void)
485 } default_toolbar[] = {
486 { A_REPLY_MESSAGE, STOCK_PIXMAP_MAIL_REPLY, _("Reply") },
487 { A_REPLY_ALL, STOCK_PIXMAP_MAIL_REPLY_TO_ALL, _("All") },
488 { A_REPLY_SENDER, STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR, _("Sender") },
489 { A_FORWARD, STOCK_PIXMAP_MAIL_FORWARD, _("Forward") },
490 { A_SEPARATOR, 0, ("") },
491 { A_TRASH, STOCK_PIXMAP_TRASH, _("Trash") },
492 #ifdef USE_SPAMASSASSIN_PLUGIN
493 { A_LEARN_SPAM, STOCK_PIXMAP_SPAM_BTN, _("Spam") },
495 { A_GOTO_NEXT, STOCK_PIXMAP_DOWN_ARROW, _("Next") }
500 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
502 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
504 if (default_toolbar[i].action != A_SEPARATOR) {
506 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
508 toolbar_item->file = g_strdup(file);
509 toolbar_item->index = default_toolbar[i].action;
510 toolbar_item->text = g_strdup(default_toolbar[i].text);
513 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
514 toolbar_item->index = A_SEPARATOR;
517 if (toolbar_item->index != -1) {
518 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MSGVIEW))
519 toolbar_config[TOOLBAR_MSGVIEW].item_list =
520 g_slist_append(toolbar_config[TOOLBAR_MSGVIEW].item_list, toolbar_item);
525 void toolbar_set_default(ToolbarType source)
527 if (source == TOOLBAR_MAIN)
528 toolbar_set_default_main();
529 else if (source == TOOLBAR_COMPOSE)
530 toolbar_set_default_compose();
531 else if (source == TOOLBAR_MSGVIEW)
532 toolbar_set_default_msgview();
535 void toolbar_save_config_file(ToolbarType source)
540 gchar *fileSpec = NULL;
542 debug_print("save Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
544 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
545 pfile = prefs_write_open(fileSpec);
549 fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL);
551 fprintf(fp, "<%s>\n", TOOLBAR_TAG_INDEX);
553 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
554 ToolbarItem *toolbar_item = (ToolbarItem*) cur->data;
556 if (toolbar_item->index != A_SEPARATOR) {
557 fprintf(fp, "\t<%s %s=\"%s\" %s=\"",
559 TOOLBAR_ICON_FILE, toolbar_item->file,
561 xml_file_put_escape_str(fp, toolbar_item->text);
562 fprintf(fp, "\" %s=\"%s\"/>\n",
564 toolbar_ret_text_from_val(toolbar_item->index));
566 fprintf(fp, "\t<%s/>\n", TOOLBAR_TAG_SEPARATOR);
570 fprintf(fp, "</%s>\n", TOOLBAR_TAG_INDEX);
572 if (prefs_file_close (pfile) < 0 )
573 g_warning("failed to write toolbar configuration to file\n");
575 g_warning("failed to open toolbar configuration file for writing\n");
578 void toolbar_read_config_file(ToolbarType source)
580 XMLFile *file = NULL;
581 gchar *fileSpec = NULL;
586 debug_print("read Toolbar Configuration from %s\n", toolbar_config[source].conf_file);
588 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
589 file = xml_open_file(fileSpec);
592 toolbar_clear_list(source);
596 || (xml_get_dtd(file))
597 || (xml_parse_next_tag(file))
598 || (!xml_compare_tag(file, TOOLBAR_TAG_INDEX))) {
599 xml_close_file(file);
603 attr = xml_get_current_tag_attr(file);
610 if (xml_parse_next_tag(file))
613 /* Get next tag (icon, icon_text or icon_action) */
614 if (xml_compare_tag(file, TOOLBAR_TAG_ITEM)) {
615 toolbar_parse_item(file, source);
616 } else if (xml_compare_tag(file, TOOLBAR_TAG_SEPARATOR)) {
617 ToolbarItem *item = g_new0(ToolbarItem, 1);
619 item->file = g_strdup(toolbar_ret_descr_from_val(A_SEPARATOR));
620 item->index = A_SEPARATOR;
621 toolbar_config[source].item_list =
622 g_slist_append(toolbar_config[source].item_list, item);
626 xml_close_file(file);
629 if ((!file) || (g_slist_length(toolbar_config[source].item_list) == 0)) {
631 if (source == TOOLBAR_MAIN)
632 toolbar_set_default(TOOLBAR_MAIN);
633 else if (source == TOOLBAR_COMPOSE)
634 toolbar_set_default(TOOLBAR_COMPOSE);
635 else if (source == TOOLBAR_MSGVIEW)
636 toolbar_set_default(TOOLBAR_MSGVIEW);
638 g_warning("failed to write Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
642 toolbar_save_config_file(source);
647 * clears list of toolbar items read from configuration files
649 void toolbar_clear_list(ToolbarType source)
651 while (toolbar_config[source].item_list != NULL) {
652 ToolbarItem *item = (ToolbarItem*) toolbar_config[source].item_list->data;
654 toolbar_config[source].item_list =
655 g_slist_remove(toolbar_config[source].item_list, item);
663 g_slist_free(toolbar_config[source].item_list);
668 * return list of Toolbar items
670 GSList *toolbar_get_list(ToolbarType source)
674 if ((source == TOOLBAR_MAIN) || (source == TOOLBAR_COMPOSE) || (source == TOOLBAR_MSGVIEW))
675 list = toolbar_config[source].item_list;
680 void toolbar_set_list_item(ToolbarItem *t_item, ToolbarType source)
682 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
684 toolbar_item->file = g_strdup(t_item->file);
685 toolbar_item->text = g_strdup(t_item->text);
686 toolbar_item->index = t_item->index;
688 toolbar_config[source].item_list =
689 g_slist_append(toolbar_config[source].item_list,
693 void toolbar_action_execute(GtkWidget *widget,
699 gchar *action, *action_p;
700 gboolean found = FALSE;
703 for (cur = action_list; cur != NULL; cur = cur->next) {
704 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
706 if (widget == act->widget) {
708 for (lop = prefs_common.actions_list; lop != NULL; lop = lop->next) {
709 action = g_strdup((gchar*)lop->data);
711 action_p = strstr(action, ": ");
713 if (g_utf8_collate(act->name, action) == 0) {
727 actions_execute(data, i, widget, source);
729 g_warning ("Error: did not find Sylpheed Action to execute");
732 static void activate_compose_button (Toolbar *toolbar,
734 ComposeButtonType type)
736 if ((!toolbar->compose_mail_btn) || (!toolbar->compose_news_btn))
739 gtk_widget_hide(type == COMPOSEBUTTON_NEWS ? toolbar->compose_mail_btn
740 : toolbar->compose_news_btn);
741 gtk_widget_show(type == COMPOSEBUTTON_NEWS ? toolbar->compose_news_btn
742 : toolbar->compose_mail_btn);
743 toolbar->compose_btn_type = type;
746 void toolbar_set_compose_button(Toolbar *toolbar,
747 ComposeButtonType compose_btn_type)
749 if (toolbar->compose_btn_type != compose_btn_type)
750 activate_compose_button(toolbar,
751 prefs_common.toolbar_style,
755 static void activate_learn_button (Toolbar *toolbar,
757 LearnButtonType type)
759 if ((!toolbar->learn_spam_btn) || (!toolbar->learn_ham_btn))
762 gtk_widget_hide(type == LEARN_SPAM ? toolbar->learn_ham_btn
763 : toolbar->learn_spam_btn);
764 gtk_widget_show(type == LEARN_SPAM ? toolbar->learn_spam_btn
765 : toolbar->learn_ham_btn);
766 toolbar->learn_btn_type = type;
769 void toolbar_set_learn_button(Toolbar *toolbar,
770 LearnButtonType learn_btn_type)
772 if (toolbar->learn_btn_type != learn_btn_type)
773 activate_learn_button(toolbar,
774 prefs_common.toolbar_style,
778 void toolbar_toggle(guint action, gpointer data)
780 MainWindow *mainwin = (MainWindow*)data;
784 g_return_if_fail(mainwin != NULL);
786 toolbar_style(TOOLBAR_MAIN, action, mainwin);
788 list = compose_get_compose_list();
789 for (cur = list; cur != NULL; cur = cur->next) {
790 toolbar_style(TOOLBAR_COMPOSE, action, cur->data);
792 list = messageview_get_msgview_list();
793 for (cur = list; cur != NULL; cur = cur->next) {
794 toolbar_style(TOOLBAR_MSGVIEW, action, cur->data);
799 void toolbar_set_style(GtkWidget *toolbar_wid, GtkWidget *handlebox_wid, guint action)
801 switch ((ToolbarStyle)action) {
803 gtk_widget_hide(handlebox_wid);
806 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
810 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
814 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
817 case TOOLBAR_BOTH_HORIZ:
818 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
819 GTK_TOOLBAR_BOTH_HORIZ);
825 prefs_common.toolbar_style = (ToolbarStyle)action;
826 gtk_widget_set_size_request(handlebox_wid, 1, -1);
828 if (prefs_common.toolbar_style != TOOLBAR_NONE) {
829 gtk_widget_show(handlebox_wid);
830 gtk_widget_queue_resize(handlebox_wid);
834 * Change the style of toolbar
836 static void toolbar_style(ToolbarType type, guint action, gpointer data)
838 GtkWidget *handlebox_wid;
839 GtkWidget *toolbar_wid;
840 MainWindow *mainwin = (MainWindow*)data;
841 Compose *compose = (Compose*)data;
842 MessageView *msgview = (MessageView*)data;
844 g_return_if_fail(data != NULL);
848 handlebox_wid = mainwin->handlebox;
849 toolbar_wid = mainwin->toolbar->toolbar;
851 case TOOLBAR_COMPOSE:
852 handlebox_wid = compose->handlebox;
853 toolbar_wid = compose->toolbar->toolbar;
855 case TOOLBAR_MSGVIEW:
856 handlebox_wid = msgview->handlebox;
857 toolbar_wid = msgview->toolbar->toolbar;
863 toolbar_set_style(toolbar_wid, handlebox_wid, action);
866 /* Toolbar handling */
867 static void toolbar_inc_cb(GtkWidget *widget,
870 ToolbarItem *toolbar_item = (ToolbarItem*)data;
873 g_return_if_fail(toolbar_item != NULL);
875 switch (toolbar_item->type) {
877 mainwin = (MainWindow*)toolbar_item->parent;
878 inc_mail_cb(mainwin, 0, NULL);
885 static void toolbar_inc_all_cb(GtkWidget *widget,
888 ToolbarItem *toolbar_item = (ToolbarItem*)data;
891 g_return_if_fail(toolbar_item != NULL);
893 switch (toolbar_item->type) {
895 mainwin = (MainWindow*)toolbar_item->parent;
896 inc_all_account_mail_cb(mainwin, 0, NULL);
903 static void toolbar_send_queued_cb(GtkWidget *widget,gpointer data)
905 ToolbarItem *toolbar_item = (ToolbarItem*)data;
908 g_return_if_fail(toolbar_item != NULL);
910 switch (toolbar_item->type) {
912 mainwin = (MainWindow*)toolbar_item->parent;
913 send_queue_cb(mainwin, 0, NULL);
920 static void toolbar_exec_cb(GtkWidget *widget,
923 MainWindow *mainwin = get_mainwin(data);
925 g_return_if_fail(mainwin != NULL);
926 summary_execute(mainwin->summaryview);
930 * Delete current/selected(s) message(s)
932 static void toolbar_trash_cb(GtkWidget *widget, gpointer data)
934 ToolbarItem *toolbar_item = (ToolbarItem*)data;
937 g_return_if_fail(toolbar_item != NULL);
938 g_return_if_fail(toolbar_item->parent);
940 switch (toolbar_item->type) {
941 case TOOLBAR_MSGVIEW:
942 messageview_delete((MessageView *)toolbar_item->parent);
945 mainwin = (MainWindow *)toolbar_item->parent;
946 summary_delete_trash(mainwin->summaryview);
949 debug_print("toolbar event not supported\n");
955 * Delete current/selected(s) message(s)
957 static void toolbar_delete_cb(GtkWidget *widget, gpointer data)
959 ToolbarItem *toolbar_item = (ToolbarItem*)data;
962 g_return_if_fail(toolbar_item != NULL);
963 g_return_if_fail(toolbar_item->parent);
965 switch (toolbar_item->type) {
966 case TOOLBAR_MSGVIEW:
967 messageview_delete((MessageView *)toolbar_item->parent);
970 mainwin = (MainWindow *)toolbar_item->parent;
971 summary_delete(mainwin->summaryview);
974 debug_print("toolbar event not supported\n");
981 * Compose new message
983 static void toolbar_compose_cb(GtkWidget *widget, gpointer data)
985 ToolbarItem *toolbar_item = (ToolbarItem*)data;
987 MessageView *msgview;
989 g_return_if_fail(toolbar_item != NULL);
991 switch (toolbar_item->type) {
993 mainwin = (MainWindow*)toolbar_item->parent;
994 if (mainwin->toolbar->compose_btn_type == COMPOSEBUTTON_NEWS)
995 compose_news_cb(mainwin, 0, NULL);
997 compose_mail_cb(mainwin, 0, NULL);
999 case TOOLBAR_MSGVIEW:
1000 msgview = (MessageView*)toolbar_item->parent;
1001 compose_new_with_folderitem(NULL,
1002 msgview->msginfo->folder);
1005 debug_print("toolbar event not supported\n");
1009 static void toolbar_learn_cb(GtkWidget *widget, gpointer data)
1011 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1012 MainWindow *mainwin;
1013 MessageView *msgview;
1015 g_return_if_fail(toolbar_item != NULL);
1017 switch (toolbar_item->type) {
1019 mainwin = (MainWindow*)toolbar_item->parent;
1020 if (mainwin->toolbar->learn_btn_type == LEARN_SPAM)
1021 mainwindow_learn(mainwin, TRUE);
1023 mainwindow_learn(mainwin, FALSE);
1025 case TOOLBAR_MSGVIEW:
1026 msgview = (MessageView*)toolbar_item->parent;
1027 if (msgview->toolbar->learn_btn_type == LEARN_SPAM)
1028 messageview_learn(msgview, TRUE);
1030 messageview_learn(msgview, FALSE);
1033 debug_print("toolbar event not supported\n");
1041 static void toolbar_reply_cb(GtkWidget *widget, gpointer data)
1043 toolbar_reply(data, prefs_common.reply_with_quote ?
1044 COMPOSE_REPLY_WITH_QUOTE : COMPOSE_REPLY_WITHOUT_QUOTE);
1049 * Reply message to Sender and All recipients
1051 static void toolbar_reply_to_all_cb(GtkWidget *widget, gpointer data)
1054 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_ALL_WITH_QUOTE
1055 : COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE);
1060 * Reply to Mailing List
1062 static void toolbar_reply_to_list_cb(GtkWidget *widget, gpointer data)
1065 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_LIST_WITH_QUOTE
1066 : COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE);
1071 * Reply to sender of message
1073 static void toolbar_reply_to_sender_cb(GtkWidget *widget, gpointer data)
1076 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_SENDER_WITH_QUOTE
1077 : COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE);
1083 static void toolbar_addrbook_cb(GtkWidget *widget, gpointer data)
1085 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1088 g_return_if_fail(toolbar_item != NULL);
1090 switch (toolbar_item->type) {
1092 case TOOLBAR_MSGVIEW:
1095 case TOOLBAR_COMPOSE:
1096 compose = (Compose *)toolbar_item->parent;
1101 addressbook_open(compose);
1106 * Forward current/selected(s) message(s)
1108 static void toolbar_forward_cb(GtkWidget *widget, gpointer data)
1110 toolbar_reply(data, COMPOSE_FORWARD);
1114 * Goto Prev Unread Message
1116 static void toolbar_prev_unread_cb(GtkWidget *widget, gpointer data)
1118 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1119 MainWindow *mainwin;
1120 MessageView *msgview;
1122 g_return_if_fail(toolbar_item != NULL);
1124 switch (toolbar_item->type) {
1126 mainwin = (MainWindow*)toolbar_item->parent;
1127 summary_select_prev_unread(mainwin->summaryview);
1130 case TOOLBAR_MSGVIEW:
1131 msgview = (MessageView*)toolbar_item->parent;
1132 summary_select_prev_unread(msgview->mainwin->summaryview);
1134 /* Now we need to update the messageview window */
1135 if (msgview->mainwin->summaryview->selected) {
1136 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1138 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1139 msgview->mainwin->summaryview->selected);
1141 messageview_show(msgview, msginfo,
1142 msgview->all_headers);
1144 gtk_widget_destroy(msgview->window);
1148 debug_print("toolbar event not supported\n");
1153 * Goto Next Unread Message
1155 static void toolbar_next_unread_cb(GtkWidget *widget, gpointer data)
1157 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1158 MainWindow *mainwin;
1159 MessageView *msgview;
1161 g_return_if_fail(toolbar_item != NULL);
1163 switch (toolbar_item->type) {
1165 mainwin = (MainWindow*)toolbar_item->parent;
1166 summary_select_next_unread(mainwin->summaryview);
1169 case TOOLBAR_MSGVIEW:
1170 msgview = (MessageView*)toolbar_item->parent;
1171 summary_select_next_unread(msgview->mainwin->summaryview);
1173 /* Now we need to update the messageview window */
1174 if (msgview->mainwin->summaryview->selected) {
1175 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1177 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1178 msgview->mainwin->summaryview->selected);
1180 messageview_show(msgview, msginfo,
1181 msgview->all_headers);
1183 gtk_widget_destroy(msgview->window);
1187 debug_print("toolbar event not supported\n");
1191 static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data)
1193 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1194 MainWindow *mainwin;
1196 g_return_if_fail(toolbar_item != NULL);
1198 switch (toolbar_item->type) {
1200 mainwin = (MainWindow *) toolbar_item->parent;
1201 summary_toggle_ignore_thread(mainwin->summaryview);
1203 case TOOLBAR_MSGVIEW:
1204 /* TODO: see toolbar_next_unread_cb() if you need
1205 * this in the message view */
1208 debug_print("toolbar event not supported\n");
1213 static void toolbar_print_cb(GtkWidget *widget, gpointer data)
1215 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1216 MainWindow *mainwin;
1218 g_return_if_fail(toolbar_item != NULL);
1220 switch (toolbar_item->type) {
1222 mainwin = (MainWindow *) toolbar_item->parent;
1223 summary_print(mainwin->summaryview);
1225 case TOOLBAR_MSGVIEW:
1226 /* TODO: see toolbar_next_unread_cb() if you need
1227 * this in the message view */
1230 debug_print("toolbar event not supported\n");
1235 static void toolbar_send_cb(GtkWidget *widget, gpointer data)
1237 compose_toolbar_cb(A_SEND, data);
1240 static void toolbar_send_later_cb(GtkWidget *widget, gpointer data)
1242 compose_toolbar_cb(A_SENDL, data);
1245 static void toolbar_draft_cb(GtkWidget *widget, gpointer data)
1247 compose_toolbar_cb(A_DRAFT, data);
1250 static void toolbar_insert_cb(GtkWidget *widget, gpointer data)
1252 compose_toolbar_cb(A_INSERT, data);
1255 static void toolbar_attach_cb(GtkWidget *widget, gpointer data)
1257 compose_toolbar_cb(A_ATTACH, data);
1260 static void toolbar_sig_cb(GtkWidget *widget, gpointer data)
1262 compose_toolbar_cb(A_SIG, data);
1265 static void toolbar_ext_editor_cb(GtkWidget *widget, gpointer data)
1267 compose_toolbar_cb(A_EXTEDITOR, data);
1270 static void toolbar_linewrap_current_cb(GtkWidget *widget, gpointer data)
1272 compose_toolbar_cb(A_LINEWRAP_CURRENT, data);
1275 static void toolbar_linewrap_all_cb(GtkWidget *widget, gpointer data)
1277 compose_toolbar_cb(A_LINEWRAP_ALL, data);
1281 static void toolbar_check_spelling_cb(GtkWidget *widget, gpointer data)
1283 compose_toolbar_cb(A_CHECK_SPELLING, data);
1287 * Execute actions from toolbar
1289 static void toolbar_actions_execute_cb(GtkWidget *widget, gpointer data)
1291 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1292 GSList *action_list;
1293 MainWindow *mainwin;
1295 MessageView *msgview;
1296 gpointer parent = toolbar_item->parent;
1298 g_return_if_fail(toolbar_item != NULL);
1300 switch (toolbar_item->type) {
1302 mainwin = (MainWindow*)parent;
1303 action_list = mainwin->toolbar->action_list;
1305 case TOOLBAR_COMPOSE:
1306 compose = (Compose*)parent;
1307 action_list = compose->toolbar->action_list;
1309 case TOOLBAR_MSGVIEW:
1310 msgview = (MessageView*)parent;
1311 action_list = msgview->toolbar->action_list;
1314 debug_print("toolbar event not supported\n");
1317 toolbar_action_execute(widget, action_list, parent, toolbar_item->type);
1320 static MainWindow *get_mainwin(gpointer data)
1322 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1323 MainWindow *mainwin = NULL;
1324 MessageView *msgview;
1326 g_return_val_if_fail(toolbar_item != NULL, NULL);
1328 switch(toolbar_item->type) {
1330 mainwin = (MainWindow*)toolbar_item->parent;
1332 case TOOLBAR_MSGVIEW:
1333 msgview = (MessageView*)toolbar_item->parent;
1334 mainwin = (MainWindow*)msgview->mainwin;
1343 static void toolbar_buttons_cb(GtkWidget *widget,
1350 void (*func)(GtkWidget *widget, gpointer data);
1352 { A_RECEIVE_ALL, toolbar_inc_all_cb },
1353 { A_RECEIVE_CUR, toolbar_inc_cb },
1354 { A_SEND_QUEUED, toolbar_send_queued_cb },
1355 { A_COMPOSE_EMAIL, toolbar_compose_cb },
1356 { A_COMPOSE_NEWS, toolbar_compose_cb },
1357 { A_REPLY_MESSAGE, toolbar_reply_cb },
1358 { A_REPLY_SENDER, toolbar_reply_to_sender_cb },
1359 { A_REPLY_ALL, toolbar_reply_to_all_cb },
1360 { A_REPLY_ML, toolbar_reply_to_list_cb },
1361 { A_FORWARD, toolbar_forward_cb },
1362 { A_TRASH, toolbar_trash_cb },
1363 { A_DELETE_REAL, toolbar_delete_cb },
1364 { A_EXECUTE, toolbar_exec_cb },
1365 { A_GOTO_PREV, toolbar_prev_unread_cb },
1366 { A_GOTO_NEXT, toolbar_next_unread_cb },
1367 { A_IGNORE_THREAD, toolbar_ignore_thread_cb },
1368 { A_PRINT, toolbar_print_cb },
1369 { A_LEARN_SPAM, toolbar_learn_cb },
1370 { A_LEARN_HAM, toolbar_learn_cb },
1372 { A_SEND, toolbar_send_cb },
1373 { A_SENDL, toolbar_send_later_cb },
1374 { A_DRAFT, toolbar_draft_cb },
1375 { A_INSERT, toolbar_insert_cb },
1376 { A_ATTACH, toolbar_attach_cb },
1377 { A_SIG, toolbar_sig_cb },
1378 { A_EXTEDITOR, toolbar_ext_editor_cb },
1379 { A_LINEWRAP_CURRENT, toolbar_linewrap_current_cb },
1380 { A_LINEWRAP_ALL, toolbar_linewrap_all_cb },
1381 { A_ADDRBOOK, toolbar_addrbook_cb },
1383 { A_CHECK_SPELLING, toolbar_check_spelling_cb },
1385 { A_SYL_ACTIONS, toolbar_actions_execute_cb }
1388 num_items = sizeof(callbacks)/sizeof(callbacks[0]);
1390 for (i = 0; i < num_items; i++) {
1391 if (callbacks[i].index == item->index) {
1392 callbacks[i].func(widget, item);
1399 * Create a new toolbar with specified type
1400 * if a callback list is passed it will be used before the
1401 * common callback list
1403 Toolbar *toolbar_create(ToolbarType type,
1404 GtkWidget *container,
1407 ToolbarItem *toolbar_item;
1410 GtkWidget *icon_wid = NULL;
1411 GtkWidget *icon_news;
1412 GtkWidget *icon_ham;
1414 GtkWidget *item_news;
1415 GtkWidget *item_ham;
1416 guint n_menu_entries;
1417 ComboButton *getall_combo;
1418 ComboButton *reply_combo;
1419 ComboButton *replyall_combo;
1420 ComboButton *replylist_combo;
1421 ComboButton *replysender_combo;
1422 ComboButton *fwd_combo;
1424 GtkTooltips *toolbar_tips;
1425 ToolbarSylpheedActions *action_item;
1427 GSList *toolbar_list;
1428 Toolbar *toolbar_data;
1431 toolbar_tips = gtk_tooltips_new();
1433 toolbar_read_config_file(type);
1434 toolbar_list = toolbar_get_list(type);
1436 toolbar_data = g_new0(Toolbar, 1);
1438 toolbar = gtk_toolbar_new();
1439 gtk_container_add(GTK_CONTAINER(container), toolbar);
1440 gtk_container_set_border_width(GTK_CONTAINER(container), 2);
1441 gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1442 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
1444 for (cur = toolbar_list; cur != NULL; cur = cur->next) {
1446 if (g_ascii_strcasecmp(((ToolbarItem*)cur->data)->file, TOOLBAR_TAG_SEPARATOR) == 0) {
1447 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
1451 toolbar_item = g_new0(ToolbarItem, 1);
1452 toolbar_item->index = ((ToolbarItem*)cur->data)->index;
1453 toolbar_item->file = g_strdup(((ToolbarItem*)cur->data)->file);
1454 toolbar_item->text = g_strdup(((ToolbarItem*)cur->data)->text);
1455 toolbar_item->parent = data;
1456 toolbar_item->type = type;
1458 /* collect toolbar items in list to keep track */
1459 toolbar_data->item_list =
1460 g_slist_append(toolbar_data->item_list,
1462 icon_wid = stock_pixmap_widget(container, stock_pixmap_get_icon(toolbar_item->file));
1463 item = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1467 icon_wid, G_CALLBACK(toolbar_buttons_cb),
1470 switch (toolbar_item->index) {
1473 toolbar_data->getall_btn = item;
1474 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1475 toolbar_data->getall_btn,
1476 _("Receive Mail on all Accounts"), NULL);
1477 getall_combo = gtkut_combo_button_create(toolbar_data->getall_btn, NULL, 0,
1478 "<GetAll>", (gpointer)toolbar_item);
1479 gtk_button_set_relief(GTK_BUTTON(getall_combo->arrow),
1481 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1482 GTK_WIDGET_PTR(getall_combo),
1483 _("Receive Mail on selected Account"), "Reply");
1484 toolbar_data->getall_combo = getall_combo;
1487 toolbar_data->get_btn = item;
1488 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1489 toolbar_data->get_btn,
1490 _("Receive Mail on current Account"), NULL);
1493 toolbar_data->send_btn = item;
1494 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1495 toolbar_data->send_btn,
1496 _("Send Queued Messages"), NULL);
1498 case A_COMPOSE_EMAIL:
1499 icon_news = stock_pixmap_widget(container, STOCK_PIXMAP_NEWS_COMPOSE);
1500 item_news = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1504 icon_news, G_CALLBACK(toolbar_buttons_cb),
1506 toolbar_data->compose_mail_btn = item;
1507 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1508 toolbar_data->compose_mail_btn,
1509 _("Compose Email"), NULL);
1510 toolbar_data->compose_news_btn = item_news;
1511 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1512 toolbar_data->compose_news_btn,
1513 _("Compose News"), NULL);
1516 icon_ham = stock_pixmap_widget(container, STOCK_PIXMAP_HAM_BTN);
1517 item_ham = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1521 icon_ham, G_CALLBACK(toolbar_buttons_cb),
1523 toolbar_data->learn_spam_btn = item;
1524 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1525 toolbar_data->learn_spam_btn,
1526 _("Learn Spam"), NULL);
1527 toolbar_data->learn_ham_btn = item_ham;
1528 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1529 toolbar_data->learn_ham_btn,
1530 _("Learn Ham"), NULL);
1532 case A_REPLY_MESSAGE:
1533 toolbar_data->reply_btn = item;
1534 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1535 toolbar_data->reply_btn,
1536 _("Reply to Message"), NULL);
1537 n_menu_entries = sizeof(reply_entries) /
1538 sizeof(reply_entries[0]);
1539 reply_combo = gtkut_combo_button_create(toolbar_data->reply_btn,
1540 reply_entries, n_menu_entries,
1541 "<Reply>", (gpointer)toolbar_item);
1542 gtk_button_set_relief(GTK_BUTTON(reply_combo->arrow),
1544 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1545 GTK_WIDGET_PTR(reply_combo),
1546 _("Reply to Message"), "Reply");
1547 toolbar_data->reply_combo = reply_combo;
1549 case A_REPLY_SENDER:
1550 toolbar_data->replysender_btn = item;
1551 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1552 toolbar_data->replysender_btn,
1553 _("Reply to Sender"), NULL);
1554 n_menu_entries = sizeof(replysender_entries) /
1555 sizeof(replysender_entries[0]);
1556 replysender_combo = gtkut_combo_button_create(toolbar_data->replysender_btn,
1557 replysender_entries, n_menu_entries,
1558 "<ReplySender>", (gpointer)toolbar_item);
1559 gtk_button_set_relief(GTK_BUTTON(replysender_combo->arrow),
1561 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1562 GTK_WIDGET_PTR(replysender_combo),
1563 _("Reply to Sender"), "ReplySender");
1564 toolbar_data->replysender_combo = replysender_combo;
1567 toolbar_data->replyall_btn = item;
1568 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1569 toolbar_data->replyall_btn,
1570 _("Reply to All"), NULL);
1571 n_menu_entries = sizeof(replyall_entries) /
1572 sizeof(replyall_entries[0]);
1573 replyall_combo = gtkut_combo_button_create(toolbar_data->replyall_btn,
1574 replyall_entries, n_menu_entries,
1575 "<ReplyAll>", (gpointer)toolbar_item);
1576 gtk_button_set_relief(GTK_BUTTON(replyall_combo->arrow),
1578 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1579 GTK_WIDGET_PTR(replyall_combo),
1580 _("Reply to All"), "ReplyAll");
1581 toolbar_data->replyall_combo = replyall_combo;
1584 toolbar_data->replylist_btn = item;
1585 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1586 toolbar_data->replylist_btn,
1587 _("Reply to Mailing-list"), NULL);
1588 n_menu_entries = sizeof(replylist_entries) /
1589 sizeof(replylist_entries[0]);
1590 replylist_combo = gtkut_combo_button_create(toolbar_data->replylist_btn,
1591 replylist_entries, n_menu_entries,
1592 "<ReplyList>", (gpointer)toolbar_item);
1593 gtk_button_set_relief(GTK_BUTTON(replylist_combo->arrow),
1595 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1596 GTK_WIDGET_PTR(replylist_combo),
1597 _("Reply to Mailing-list"), "ReplyList");
1598 toolbar_data->replylist_combo = replylist_combo;
1601 toolbar_data->fwd_btn = item;
1602 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1603 toolbar_data->fwd_btn,
1604 _("Forward Message"), NULL);
1605 n_menu_entries = sizeof(forward_entries) /
1606 sizeof(forward_entries[0]);
1607 fwd_combo = gtkut_combo_button_create(toolbar_data->fwd_btn,
1608 forward_entries, n_menu_entries,
1609 "<Forward>", (gpointer)toolbar_item);
1610 gtk_button_set_relief(GTK_BUTTON(fwd_combo->arrow),
1612 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1613 GTK_WIDGET_PTR(fwd_combo),
1614 _("Forward Message"), "Fwd");
1615 toolbar_data->fwd_combo = fwd_combo;
1618 toolbar_data->trash_btn = item;
1619 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1620 toolbar_data->trash_btn,
1621 _("Trash Message"), NULL);
1624 toolbar_data->delete_btn = item;
1625 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1626 toolbar_data->delete_btn,
1627 _("Delete Message"), NULL);
1630 toolbar_data->exec_btn = item;
1631 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1632 toolbar_data->exec_btn,
1633 _("Execute"), NULL);
1636 toolbar_data->prev_btn = item;
1637 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1638 toolbar_data->prev_btn,
1639 _("Go to Previous Unread Message"),
1643 toolbar_data->next_btn = item;
1644 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1645 toolbar_data->next_btn,
1646 _("Go to Next Unread Message"),
1650 /* Compose Toolbar */
1652 toolbar_data->send_btn = item;
1653 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1654 toolbar_data->send_btn,
1655 _("Send Message"), NULL);
1658 toolbar_data->sendl_btn = item;
1659 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1660 toolbar_data->sendl_btn,
1661 _("Put into queue folder and send later"), NULL);
1664 toolbar_data->draft_btn = item;
1665 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1666 toolbar_data->draft_btn,
1667 _("Save to draft folder"), NULL);
1670 toolbar_data->insert_btn = item;
1671 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1672 toolbar_data->insert_btn,
1673 _("Insert file"), NULL);
1676 toolbar_data->attach_btn = item;
1677 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1678 toolbar_data->attach_btn,
1679 _("Attach file"), NULL);
1682 toolbar_data->sig_btn = item;
1683 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1684 toolbar_data->sig_btn,
1685 _("Insert signature"), NULL);
1688 toolbar_data->exteditor_btn = item;
1689 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1690 toolbar_data->exteditor_btn,
1691 _("Edit with external editor"), NULL);
1693 case A_LINEWRAP_CURRENT:
1694 toolbar_data->linewrap_current_btn = item;
1695 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1696 toolbar_data->linewrap_current_btn,
1697 _("Wrap long lines of current paragraph"), NULL);
1699 case A_LINEWRAP_ALL:
1700 toolbar_data->linewrap_all_btn = item;
1701 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1702 toolbar_data->linewrap_all_btn,
1703 _("Wrap all long lines"), NULL);
1706 toolbar_data->addrbook_btn = item;
1707 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1708 toolbar_data->addrbook_btn,
1709 _("Address book"), NULL);
1712 case A_CHECK_SPELLING:
1713 toolbar_data->spellcheck_btn = item;
1714 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1715 toolbar_data->spellcheck_btn,
1716 _("Check spelling"), NULL);
1721 action_item = g_new0(ToolbarSylpheedActions, 1);
1722 action_item->widget = item;
1723 action_item->name = g_strdup(toolbar_item->text);
1725 toolbar_data->action_list =
1726 g_slist_append(toolbar_data->action_list,
1729 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1731 action_item->name, NULL);
1733 gtk_widget_show(item);
1736 /* find and set the tool tip text */
1737 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1739 toolbar_ret_descr_from_val
1740 (toolbar_item->index),
1746 toolbar_data->toolbar = toolbar;
1747 if (type == TOOLBAR_MAIN)
1748 activate_compose_button(toolbar_data,
1749 prefs_common.toolbar_style,
1750 toolbar_data->compose_btn_type);
1751 if (type != TOOLBAR_COMPOSE)
1752 activate_learn_button(toolbar_data, prefs_common.toolbar_style,
1755 gtk_widget_show_all(toolbar);
1757 return toolbar_data;
1761 * Free toolbar structures
1763 void toolbar_destroy(Toolbar * toolbar) {
1765 TOOLBAR_DESTROY_ITEMS(toolbar->item_list);
1766 TOOLBAR_DESTROY_ACTIONS(toolbar->action_list);
1769 void toolbar_update(ToolbarType type, gpointer data)
1771 Toolbar *toolbar_data;
1772 GtkWidget *handlebox;
1773 MainWindow *mainwin = (MainWindow*)data;
1774 Compose *compose = (Compose*)data;
1775 MessageView *msgview = (MessageView*)data;
1779 toolbar_data = mainwin->toolbar;
1780 handlebox = mainwin->handlebox;
1782 case TOOLBAR_COMPOSE:
1783 toolbar_data = compose->toolbar;
1784 handlebox = compose->handlebox;
1786 case TOOLBAR_MSGVIEW:
1787 toolbar_data = msgview->toolbar;
1788 handlebox = msgview->handlebox;
1794 gtk_container_remove(GTK_CONTAINER(handlebox),
1795 GTK_WIDGET(toolbar_data->toolbar));
1797 toolbar_init(toolbar_data);
1798 toolbar_data = toolbar_create(type, handlebox, data);
1801 mainwin->toolbar = toolbar_data;
1803 case TOOLBAR_COMPOSE:
1804 compose->toolbar = toolbar_data;
1806 case TOOLBAR_MSGVIEW:
1807 msgview->toolbar = toolbar_data;
1811 toolbar_style(type, prefs_common.toolbar_style, data);
1813 if (type == TOOLBAR_MAIN) {
1814 toolbar_main_set_sensitive((MainWindow*)data);
1815 account_set_menu_only_toolbar();
1819 void toolbar_main_set_sensitive(gpointer data)
1821 SensitiveCond state;
1823 MainWindow *mainwin = (MainWindow*)data;
1824 Toolbar *toolbar = mainwin->toolbar;
1826 GSList *entry_list = NULL;
1828 typedef struct _Entry Entry;
1835 #define SET_WIDGET_COND(w, c) \
1837 Entry *e = g_new0(Entry, 1); \
1840 entry_list = g_slist_append(entry_list, e); \
1843 SET_WIDGET_COND(toolbar->get_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1844 SET_WIDGET_COND(toolbar->getall_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1845 if (toolbar->getall_btn)
1846 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->getall_combo),
1847 M_HAVE_ACCOUNT|M_UNLOCKED);
1848 SET_WIDGET_COND(toolbar->compose_news_btn, M_HAVE_ACCOUNT);
1849 SET_WIDGET_COND(toolbar->reply_btn,
1850 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1851 if (toolbar->reply_btn)
1852 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->reply_combo),
1853 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1854 SET_WIDGET_COND(toolbar->replyall_btn,
1855 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1856 if (toolbar->replyall_btn)
1857 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replyall_combo),
1858 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1859 SET_WIDGET_COND(toolbar->replylist_btn,
1860 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1861 if (toolbar->replylist_btn)
1862 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replylist_combo),
1863 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1864 SET_WIDGET_COND(toolbar->replysender_btn,
1865 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1866 if (toolbar->replysender_btn)
1867 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replysender_combo),
1868 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1869 SET_WIDGET_COND(toolbar->fwd_btn, M_HAVE_ACCOUNT|M_TARGET_EXIST);
1870 if (toolbar->fwd_btn)
1871 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->fwd_combo),
1872 M_HAVE_ACCOUNT|M_TARGET_EXIST);
1873 if (toolbar->fwd_combo) {
1874 GtkWidget *submenu = gtk_item_factory_get_widget(toolbar->fwd_combo->factory, "/Redirect");
1875 SET_WIDGET_COND(submenu, M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1878 if (prefs_common.next_unread_msg_dialog == NEXTUNREADMSGDIALOG_ASSUME_NO) {
1879 SET_WIDGET_COND(toolbar->next_btn, M_MSG_EXIST);
1881 SET_WIDGET_COND(toolbar->next_btn, 0);
1884 if (toolbar->trash_btn)
1885 SET_WIDGET_COND(toolbar->trash_btn,
1886 M_TARGET_EXIST|M_ALLOW_DELETE);
1887 if (toolbar->delete_btn)
1888 SET_WIDGET_COND(toolbar->delete_btn,
1889 M_TARGET_EXIST|M_ALLOW_DELETE);
1890 if (toolbar->exec_btn)
1891 SET_WIDGET_COND(toolbar->exec_btn, M_DELAY_EXEC);
1893 if (toolbar->learn_ham_btn)
1894 SET_WIDGET_COND(toolbar->learn_ham_btn, M_TARGET_EXIST|M_CAN_LEARN_SPAM);
1895 if (toolbar->learn_spam_btn)
1896 SET_WIDGET_COND(toolbar->learn_spam_btn, M_TARGET_EXIST|M_CAN_LEARN_SPAM);
1898 for (cur = toolbar->action_list; cur != NULL; cur = cur->next) {
1899 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
1901 SET_WIDGET_COND(act->widget, M_TARGET_EXIST|M_UNLOCKED);
1904 #undef SET_WIDGET_COND
1906 state = main_window_get_current_state(mainwin);
1908 for (cur = entry_list; cur != NULL; cur = cur->next) {
1909 Entry *e = (Entry*) cur->data;
1911 if (e->widget != NULL) {
1912 sensitive = ((e->cond & state) == e->cond);
1913 gtk_widget_set_sensitive(e->widget, sensitive);
1917 while (entry_list != NULL) {
1918 Entry *e = (Entry*) entry_list->data;
1922 entry_list = g_slist_remove(entry_list, e);
1925 g_slist_free(entry_list);
1927 activate_compose_button(toolbar,
1928 prefs_common.toolbar_style,
1929 toolbar->compose_btn_type);
1932 void toolbar_comp_set_sensitive(gpointer data, gboolean sensitive)
1934 Compose *compose = (Compose*)data;
1935 GSList *items = compose->toolbar->action_list;
1937 if (compose->toolbar->send_btn)
1938 gtk_widget_set_sensitive(compose->toolbar->send_btn, sensitive);
1939 if (compose->toolbar->sendl_btn)
1940 gtk_widget_set_sensitive(compose->toolbar->sendl_btn, sensitive);
1941 if (compose->toolbar->draft_btn )
1942 gtk_widget_set_sensitive(compose->toolbar->draft_btn , sensitive);
1943 if (compose->toolbar->insert_btn )
1944 gtk_widget_set_sensitive(compose->toolbar->insert_btn , sensitive);
1945 if (compose->toolbar->attach_btn)
1946 gtk_widget_set_sensitive(compose->toolbar->attach_btn, sensitive);
1947 if (compose->toolbar->sig_btn)
1948 gtk_widget_set_sensitive(compose->toolbar->sig_btn, sensitive);
1949 if (compose->toolbar->exteditor_btn)
1950 gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, sensitive);
1951 if (compose->toolbar->linewrap_current_btn)
1952 gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, sensitive);
1953 if (compose->toolbar->linewrap_all_btn)
1954 gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, sensitive);
1955 if (compose->toolbar->addrbook_btn)
1956 gtk_widget_set_sensitive(compose->toolbar->addrbook_btn, sensitive);
1958 if (compose->toolbar->spellcheck_btn)
1959 gtk_widget_set_sensitive(compose->toolbar->spellcheck_btn, sensitive);
1961 for (; items != NULL; items = g_slist_next(items)) {
1962 ToolbarSylpheedActions *item = (ToolbarSylpheedActions *)items->data;
1963 gtk_widget_set_sensitive(item->widget, sensitive);
1968 * Initialize toolbar structure
1970 void toolbar_init(Toolbar * toolbar) {
1972 toolbar->toolbar = NULL;
1973 toolbar->get_btn = NULL;
1974 toolbar->getall_btn = NULL;
1975 toolbar->getall_combo = NULL;
1976 toolbar->send_btn = NULL;
1977 toolbar->compose_mail_btn = NULL;
1978 toolbar->compose_news_btn = NULL;
1979 toolbar->reply_btn = NULL;
1980 toolbar->replysender_btn = NULL;
1981 toolbar->replyall_btn = NULL;
1982 toolbar->replylist_btn = NULL;
1983 toolbar->fwd_btn = NULL;
1984 toolbar->trash_btn = NULL;
1985 toolbar->delete_btn = NULL;
1986 toolbar->prev_btn = NULL;
1987 toolbar->next_btn = NULL;
1988 toolbar->exec_btn = NULL;
1990 /* compose buttons */
1991 toolbar->sendl_btn = NULL;
1992 toolbar->draft_btn = NULL;
1993 toolbar->insert_btn = NULL;
1994 toolbar->attach_btn = NULL;
1995 toolbar->sig_btn = NULL;
1996 toolbar->exteditor_btn = NULL;
1997 toolbar->linewrap_current_btn = NULL;
1998 toolbar->linewrap_all_btn = NULL;
1999 toolbar->addrbook_btn = NULL;
2001 toolbar->spellcheck_btn = NULL;
2004 toolbar_destroy(toolbar);
2009 static void toolbar_reply(gpointer data, guint action)
2011 ToolbarItem *toolbar_item = (ToolbarItem*)data;
2012 MainWindow *mainwin;
2013 MessageView *msgview;
2014 GSList *msginfo_list = NULL;
2016 g_return_if_fail(toolbar_item != NULL);
2018 switch (toolbar_item->type) {
2020 mainwin = (MainWindow*)toolbar_item->parent;
2021 msginfo_list = summary_get_selection(mainwin->summaryview);
2022 msgview = (MessageView*)mainwin->messageview;
2024 case TOOLBAR_MSGVIEW:
2025 msgview = (MessageView*)toolbar_item->parent;
2026 g_return_if_fail(msgview != NULL);
2027 msginfo_list = g_slist_append(msginfo_list, msgview->msginfo);
2033 g_return_if_fail(msgview != NULL);
2034 g_return_if_fail(msginfo_list != NULL);
2035 compose_reply_from_messageview(msgview, msginfo_list, action);
2036 g_slist_free(msginfo_list);
2038 /* TODO: update reply state ion summaryview */
2042 /* exported functions */
2044 void inc_mail_cb(gpointer data, guint action, GtkWidget *widget)
2046 MainWindow *mainwin = (MainWindow*)data;
2048 inc_mail(mainwin, prefs_common.newmail_notify_manu);
2051 void inc_all_account_mail_cb(gpointer data, guint action, GtkWidget *widget)
2053 MainWindow *mainwin = (MainWindow*)data;
2055 inc_all_account_mail(mainwin, FALSE, prefs_common.newmail_notify_manu);
2058 void send_queue_cb(gpointer data, guint action, GtkWidget *widget)
2063 if (prefs_common.work_offline)
2064 if (alertpanel(_("Offline warning"),
2065 _("You're working offline. Override?"),
2066 GTK_STOCK_NO, GTK_STOCK_YES,
2067 NULL) != G_ALERTALTERNATE)
2070 /* ask for confirmation before sending queued messages only
2071 in online mode and if there is at least one message queued
2072 in any of the folder queue
2074 if (prefs_common.confirm_send_queued_messages) {
2076 /* check if there's a queued message */
2077 for (list = folder_get_list(); !found && list != NULL; list = list->next) {
2078 Folder *folder = list->data;
2080 found = !procmsg_queue_is_empty(folder->queue);
2082 /* if necessary, ask for confirmation before sending */
2083 if (found && !prefs_common.work_offline) {
2084 if (alertpanel(_("Send queued messages"),
2085 _("Send all queued messages?"),
2086 GTK_STOCK_CANCEL, _("_Send"),
2087 NULL) != G_ALERTALTERNATE)
2092 for (list = folder_get_list(); list != NULL; list = list->next) {
2093 Folder *folder = list->data;
2095 if (folder->queue) {
2096 if (procmsg_send_queue(folder->queue,
2097 prefs_common.savemsg) < 0)
2098 alertpanel_error(_("Some errors occurred while "
2099 "sending queued messages."));
2104 void compose_mail_cb(gpointer data, guint action, GtkWidget *widget)
2106 MainWindow *mainwin = (MainWindow*)data;
2107 PrefsAccount *ac = NULL;
2108 FolderItem *item = mainwin->summaryview->folder_item;
2113 ac = account_find_from_item(item);
2114 if (ac && ac->protocol != A_NNTP) {
2115 compose_new_with_folderitem(ac, item); /* CLAWS */
2121 * CLAWS - use current account
2123 if (cur_account && (cur_account->protocol != A_NNTP)) {
2124 compose_new_with_folderitem(cur_account, item);
2129 * CLAWS - just get the first one
2131 list = account_get_list();
2132 for (cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2133 ac = (PrefsAccount *) cur->data;
2134 if (ac->protocol != A_NNTP) {
2135 compose_new_with_folderitem(ac, item);
2141 void compose_news_cb(gpointer data, guint action, GtkWidget *widget)
2143 MainWindow *mainwin = (MainWindow*)data;
2144 PrefsAccount * ac = NULL;
2148 if (mainwin->summaryview->folder_item) {
2149 ac = mainwin->summaryview->folder_item->folder->account;
2150 if (ac && ac->protocol == A_NNTP) {
2151 compose_new_with_folderitem(ac,
2152 mainwin->summaryview->folder_item);
2157 list = account_get_list();
2158 for(cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2159 ac = (PrefsAccount *) cur->data;
2160 if (ac->protocol == A_NNTP) {
2161 compose_new_with_folderitem(ac,
2162 mainwin->summaryview->folder_item);