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 or Ham") },
181 { "A_SEND", N_("Send Message") },
182 { "A_SENDL", N_("Put into queue folder and send later") },
183 { "A_DRAFT", N_("Save to draft folder") },
184 { "A_INSERT", N_("Insert file") },
185 { "A_ATTACH", N_("Attach file") },
186 { "A_SIG", N_("Insert signature") },
187 { "A_EXTEDITOR", N_("Edit with external editor") },
188 { "A_LINEWRAP_CURRENT", N_("Wrap long lines of current paragraph") },
189 { "A_LINEWRAP_ALL", N_("Wrap all long lines") },
190 { "A_ADDRBOOK", N_("Address book") },
192 { "A_CHECK_SPELLING", N_("Check spelling") },
194 { "A_SYL_ACTIONS", N_("Sylpheed-Claws Actions Feature") },
195 { "A_SEPARATOR", "Separator" }
198 /* struct holds configuration files and a list of
199 * currently active toolbar items
200 * TOOLBAR_MAIN, TOOLBAR_COMPOSE and TOOLBAR_MSGVIEW
204 const gchar *conf_file;
206 } toolbar_config[3] = {
207 { "toolbar_main.xml", NULL},
208 { "toolbar_compose.xml", NULL},
209 { "toolbar_msgview.xml", NULL}
212 static GtkItemFactoryEntry reply_entries[] =
214 {N_("/Reply with _quote"), NULL, toolbar_reply, COMPOSE_REPLY_WITH_QUOTE, NULL},
215 {N_("/_Reply without quote"), NULL, toolbar_reply, COMPOSE_REPLY_WITHOUT_QUOTE, NULL}
217 static GtkItemFactoryEntry replyall_entries[] =
219 {N_("/Reply to all with _quote"), "<shift>A", toolbar_reply, COMPOSE_REPLY_TO_ALL_WITH_QUOTE, NULL},
220 {N_("/_Reply to all without quote"), "a", toolbar_reply, COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE, NULL}
222 static GtkItemFactoryEntry replylist_entries[] =
224 {N_("/Reply to list with _quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_LIST_WITH_QUOTE, NULL},
225 {N_("/_Reply to list without quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE, NULL}
227 static GtkItemFactoryEntry replysender_entries[] =
229 {N_("/Reply to sender with _quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_SENDER_WITH_QUOTE, NULL},
230 {N_("/_Reply to sender without quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE, NULL}
232 static GtkItemFactoryEntry forward_entries[] =
234 {N_("/_Forward"), "f", toolbar_reply, COMPOSE_FORWARD_INLINE, NULL},
235 {N_("/For_ward as attachment"), "<shift>F", toolbar_reply, COMPOSE_FORWARD_AS_ATTACH, NULL},
236 {N_("/Redirec_t"), NULL, toolbar_reply, COMPOSE_REDIRECT, NULL}
240 gint toolbar_ret_val_from_descr(const gchar *descr)
244 for (i = 0; i < N_ACTION_VAL; i++) {
245 if (g_utf8_collate(gettext(toolbar_text[i].descr), descr) == 0)
252 gchar *toolbar_ret_descr_from_val(gint val)
254 g_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL);
256 return gettext(toolbar_text[val].descr);
259 static gint toolbar_ret_val_from_text(const gchar *text)
263 for (i = 0; i < N_ACTION_VAL; i++) {
264 if (g_utf8_collate(toolbar_text[i].index_str, text) == 0)
271 static gchar *toolbar_ret_text_from_val(gint val)
273 g_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL);
275 return toolbar_text[val].index_str;
278 gboolean toolbar_is_duplicate(gint action, ToolbarType source)
282 if ((action == A_SEPARATOR) || (action == A_SYL_ACTIONS))
285 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
286 ToolbarItem *item = (ToolbarItem*) cur->data;
288 if (item->index == action)
294 /* depending on toolbar type this function
295 returns a list of available toolbar events being
296 displayed by prefs_toolbar
298 GList *toolbar_get_action_items(ToolbarType source)
303 if (source == TOOLBAR_MAIN) {
304 gint main_items[] = { A_RECEIVE_ALL, A_RECEIVE_CUR, A_SEND_QUEUED,
305 A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER,
306 A_REPLY_ALL, A_REPLY_ML, A_FORWARD,
307 A_TRASH , A_DELETE_REAL, A_EXECUTE, A_GOTO_PREV,
308 A_GOTO_NEXT, A_IGNORE_THREAD, A_PRINT,
309 A_ADDRBOOK, A_LEARN_SPAM, A_SYL_ACTIONS };
311 for (i = 0; i < sizeof main_items / sizeof main_items[0]; i++) {
312 items = g_list_append(items, gettext(toolbar_text[main_items[i]].descr));
315 else if (source == TOOLBAR_COMPOSE) {
316 gint comp_items[] = { A_SEND, A_SENDL, A_DRAFT,
317 A_INSERT, A_ATTACH, A_SIG,
318 A_EXTEDITOR, A_LINEWRAP_CURRENT,
319 A_LINEWRAP_ALL, A_ADDRBOOK,
325 for (i = 0; i < sizeof comp_items / sizeof comp_items[0]; i++)
326 items = g_list_append(items, gettext(toolbar_text[comp_items[i]].descr));
328 else if (source == TOOLBAR_MSGVIEW) {
329 gint msgv_items[] = { A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER,
330 A_REPLY_ALL, A_REPLY_ML, A_FORWARD,
331 A_TRASH, A_DELETE_REAL, A_GOTO_PREV, A_GOTO_NEXT,
332 A_ADDRBOOK, A_LEARN_SPAM, A_SYL_ACTIONS };
334 for (i = 0; i < sizeof msgv_items / sizeof msgv_items[0]; i++)
335 items = g_list_append(items, gettext(toolbar_text[msgv_items[i]].descr));
341 static void toolbar_parse_item(XMLFile *file, ToolbarType source)
345 ToolbarItem *item = NULL;
346 gboolean rewrite = FALSE;
348 attr = xml_get_current_tag_attr(file);
349 item = g_new0(ToolbarItem, 1);
351 name = ((XMLAttr *)attr->data)->name;
352 value = ((XMLAttr *)attr->data)->value;
354 if (g_utf8_collate(name, TOOLBAR_ICON_FILE) == 0)
355 item->file = g_strdup (value);
356 else if (g_utf8_collate(name, TOOLBAR_ICON_TEXT) == 0)
357 item->text = g_strdup (value);
358 else if (g_utf8_collate(name, TOOLBAR_ICON_ACTION) == 0)
359 item->index = toolbar_ret_val_from_text(value);
360 if (item->index == -1 && !strcmp(value, "A_DELETE")) {
362 item->index = A_TRASH;
364 item->file = g_strdup("trash_btn");
366 item->text = g_strdup(_("Trash"));
369 attr = g_list_next(attr);
371 if (item->index != -1) {
373 if (!toolbar_is_duplicate(item->index, source))
374 toolbar_config[source].item_list = g_slist_append(toolbar_config[source].item_list,
378 toolbar_save_config_file(source);
382 static void toolbar_set_default_main(void)
388 } default_toolbar[] = {
389 { A_RECEIVE_ALL, STOCK_PIXMAP_MAIL_RECEIVE_ALL, _("Get Mail") },
390 { A_SEPARATOR, 0, ("") },
391 { A_SEND_QUEUED, STOCK_PIXMAP_MAIL_SEND_QUEUE, _("Send") },
392 { A_COMPOSE_EMAIL, STOCK_PIXMAP_MAIL_COMPOSE, _("Compose") },
393 { A_SEPARATOR, 0, ("") },
394 { A_REPLY_MESSAGE, STOCK_PIXMAP_MAIL_REPLY, _("Reply") },
395 { A_REPLY_ALL, STOCK_PIXMAP_MAIL_REPLY_TO_ALL, _("All") },
396 { A_REPLY_SENDER, STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR, _("Sender") },
397 { A_FORWARD, STOCK_PIXMAP_MAIL_FORWARD, _("Forward") },
398 { A_SEPARATOR, 0, ("") },
399 { A_TRASH, STOCK_PIXMAP_TRASH, _("Trash") },
400 #ifdef USE_SPAMASSASSIN_PLUGIN
401 { A_LEARN_SPAM, STOCK_PIXMAP_SPAM_BTN, _("Spam") },
403 { A_SEPARATOR, 0, ("") },
404 { A_GOTO_NEXT, STOCK_PIXMAP_DOWN_ARROW, _("Next") }
409 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
411 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
413 if (default_toolbar[i].action != A_SEPARATOR) {
415 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
417 toolbar_item->file = g_strdup(file);
418 toolbar_item->index = default_toolbar[i].action;
419 toolbar_item->text = g_strdup(default_toolbar[i].text);
422 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
423 toolbar_item->index = A_SEPARATOR;
426 if (toolbar_item->index != -1) {
427 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MAIN))
428 toolbar_config[TOOLBAR_MAIN].item_list =
429 g_slist_append(toolbar_config[TOOLBAR_MAIN].item_list, toolbar_item);
434 static void toolbar_set_default_compose(void)
440 } default_toolbar[] = {
441 { A_SEND, STOCK_PIXMAP_MAIL_SEND, _("Send") },
442 { A_SENDL, STOCK_PIXMAP_MAIL_SEND_QUEUE, _("Send later") },
443 { A_DRAFT, STOCK_PIXMAP_MAIL, _("Draft") },
444 { A_SEPARATOR, 0, ("") },
445 { A_INSERT, STOCK_PIXMAP_INSERT_FILE, _("Insert") },
446 { A_ATTACH, STOCK_PIXMAP_MAIL_ATTACH, _("Attach") },
447 { A_SEPARATOR, 0, ("") },
448 { A_ADDRBOOK, STOCK_PIXMAP_ADDRESS_BOOK, _("Address") }
453 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
455 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
457 if (default_toolbar[i].action != A_SEPARATOR) {
459 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
461 toolbar_item->file = g_strdup(file);
462 toolbar_item->index = default_toolbar[i].action;
463 toolbar_item->text = g_strdup(default_toolbar[i].text);
466 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
467 toolbar_item->index = A_SEPARATOR;
470 if (toolbar_item->index != -1) {
471 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_COMPOSE))
472 toolbar_config[TOOLBAR_COMPOSE].item_list =
473 g_slist_append(toolbar_config[TOOLBAR_COMPOSE].item_list, toolbar_item);
478 static void toolbar_set_default_msgview(void)
484 } default_toolbar[] = {
485 { A_REPLY_MESSAGE, STOCK_PIXMAP_MAIL_REPLY, _("Reply") },
486 { A_REPLY_ALL, STOCK_PIXMAP_MAIL_REPLY_TO_ALL, _("All") },
487 { A_REPLY_SENDER, STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR, _("Sender") },
488 { A_FORWARD, STOCK_PIXMAP_MAIL_FORWARD, _("Forward") },
489 { A_SEPARATOR, 0, ("") },
490 { A_TRASH, STOCK_PIXMAP_TRASH, _("Trash") },
491 #ifdef USE_SPAMASSASSIN_PLUGIN
492 { A_LEARN_SPAM, STOCK_PIXMAP_SPAM_BTN, _("Spam") },
494 { A_GOTO_NEXT, STOCK_PIXMAP_DOWN_ARROW, _("Next") }
499 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
501 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
503 if (default_toolbar[i].action != A_SEPARATOR) {
505 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
507 toolbar_item->file = g_strdup(file);
508 toolbar_item->index = default_toolbar[i].action;
509 toolbar_item->text = g_strdup(default_toolbar[i].text);
512 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
513 toolbar_item->index = A_SEPARATOR;
516 if (toolbar_item->index != -1) {
517 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MSGVIEW))
518 toolbar_config[TOOLBAR_MSGVIEW].item_list =
519 g_slist_append(toolbar_config[TOOLBAR_MSGVIEW].item_list, toolbar_item);
524 void toolbar_set_default(ToolbarType source)
526 if (source == TOOLBAR_MAIN)
527 toolbar_set_default_main();
528 else if (source == TOOLBAR_COMPOSE)
529 toolbar_set_default_compose();
530 else if (source == TOOLBAR_MSGVIEW)
531 toolbar_set_default_msgview();
534 void toolbar_save_config_file(ToolbarType source)
539 gchar *fileSpec = NULL;
541 debug_print("save Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
543 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
544 pfile = prefs_write_open(fileSpec);
548 fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL);
550 fprintf(fp, "<%s>\n", TOOLBAR_TAG_INDEX);
552 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
553 ToolbarItem *toolbar_item = (ToolbarItem*) cur->data;
555 if (toolbar_item->index != A_SEPARATOR) {
556 fprintf(fp, "\t<%s %s=\"%s\" %s=\"",
558 TOOLBAR_ICON_FILE, toolbar_item->file,
560 xml_file_put_escape_str(fp, toolbar_item->text);
561 fprintf(fp, "\" %s=\"%s\"/>\n",
563 toolbar_ret_text_from_val(toolbar_item->index));
565 fprintf(fp, "\t<%s/>\n", TOOLBAR_TAG_SEPARATOR);
569 fprintf(fp, "</%s>\n", TOOLBAR_TAG_INDEX);
571 if (prefs_file_close (pfile) < 0 )
572 g_warning("failed to write toolbar configuration to file\n");
574 g_warning("failed to open toolbar configuration file for writing\n");
577 void toolbar_read_config_file(ToolbarType source)
579 XMLFile *file = NULL;
580 gchar *fileSpec = NULL;
585 debug_print("read Toolbar Configuration from %s\n", toolbar_config[source].conf_file);
587 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
588 file = xml_open_file(fileSpec);
591 toolbar_clear_list(source);
595 || (xml_get_dtd(file))
596 || (xml_parse_next_tag(file))
597 || (!xml_compare_tag(file, TOOLBAR_TAG_INDEX))) {
598 xml_close_file(file);
602 attr = xml_get_current_tag_attr(file);
609 if (xml_parse_next_tag(file))
612 /* Get next tag (icon, icon_text or icon_action) */
613 if (xml_compare_tag(file, TOOLBAR_TAG_ITEM)) {
614 toolbar_parse_item(file, source);
615 } else if (xml_compare_tag(file, TOOLBAR_TAG_SEPARATOR)) {
616 ToolbarItem *item = g_new0(ToolbarItem, 1);
618 item->file = g_strdup(toolbar_ret_descr_from_val(A_SEPARATOR));
619 item->index = A_SEPARATOR;
620 toolbar_config[source].item_list =
621 g_slist_append(toolbar_config[source].item_list, item);
625 xml_close_file(file);
628 if ((!file) || (g_slist_length(toolbar_config[source].item_list) == 0)) {
630 if (source == TOOLBAR_MAIN)
631 toolbar_set_default(TOOLBAR_MAIN);
632 else if (source == TOOLBAR_COMPOSE)
633 toolbar_set_default(TOOLBAR_COMPOSE);
634 else if (source == TOOLBAR_MSGVIEW)
635 toolbar_set_default(TOOLBAR_MSGVIEW);
637 g_warning("failed to write Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
641 toolbar_save_config_file(source);
646 * clears list of toolbar items read from configuration files
648 void toolbar_clear_list(ToolbarType source)
650 while (toolbar_config[source].item_list != NULL) {
651 ToolbarItem *item = (ToolbarItem*) toolbar_config[source].item_list->data;
653 toolbar_config[source].item_list =
654 g_slist_remove(toolbar_config[source].item_list, item);
660 g_slist_free(toolbar_config[source].item_list);
665 * return list of Toolbar items
667 GSList *toolbar_get_list(ToolbarType source)
671 if ((source == TOOLBAR_MAIN) || (source == TOOLBAR_COMPOSE) || (source == TOOLBAR_MSGVIEW))
672 list = toolbar_config[source].item_list;
677 void toolbar_set_list_item(ToolbarItem *t_item, ToolbarType source)
679 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
681 toolbar_item->file = g_strdup(t_item->file);
682 toolbar_item->text = g_strdup(t_item->text);
683 toolbar_item->index = t_item->index;
685 toolbar_config[source].item_list =
686 g_slist_append(toolbar_config[source].item_list,
690 void toolbar_action_execute(GtkWidget *widget,
696 gchar *action, *action_p;
697 gboolean found = FALSE;
700 for (cur = action_list; cur != NULL; cur = cur->next) {
701 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
703 if (widget == act->widget) {
705 for (lop = prefs_common.actions_list; lop != NULL; lop = lop->next) {
706 action = g_strdup((gchar*)lop->data);
708 action_p = strstr(action, ": ");
710 if (g_utf8_collate(act->name, action) == 0) {
724 actions_execute(data, i, widget, source);
726 g_warning ("Error: did not find Sylpheed Action to execute");
729 static void activate_compose_button (Toolbar *toolbar,
731 ComposeButtonType type)
733 if ((!toolbar->compose_mail_btn) || (!toolbar->compose_news_btn))
736 gtk_widget_hide(type == COMPOSEBUTTON_NEWS ? toolbar->compose_mail_btn
737 : toolbar->compose_news_btn);
738 gtk_widget_show(type == COMPOSEBUTTON_NEWS ? toolbar->compose_news_btn
739 : toolbar->compose_mail_btn);
740 toolbar->compose_btn_type = type;
743 void toolbar_set_compose_button(Toolbar *toolbar,
744 ComposeButtonType compose_btn_type)
746 if (toolbar->compose_btn_type != compose_btn_type)
747 activate_compose_button(toolbar,
748 prefs_common.toolbar_style,
752 static void activate_learn_button (Toolbar *toolbar,
754 LearnButtonType type)
756 if ((!toolbar->learn_spam_btn) || (!toolbar->learn_ham_btn))
759 gtk_widget_hide(type == LEARN_SPAM ? toolbar->learn_ham_btn
760 : toolbar->learn_spam_btn);
761 gtk_widget_show(type == LEARN_SPAM ? toolbar->learn_spam_btn
762 : toolbar->learn_ham_btn);
763 toolbar->learn_btn_type = type;
766 void toolbar_set_learn_button(Toolbar *toolbar,
767 LearnButtonType learn_btn_type)
769 if (toolbar->learn_btn_type != learn_btn_type)
770 activate_learn_button(toolbar,
771 prefs_common.toolbar_style,
775 void toolbar_toggle(guint action, gpointer data)
777 MainWindow *mainwin = (MainWindow*)data;
781 g_return_if_fail(mainwin != NULL);
783 toolbar_style(TOOLBAR_MAIN, action, mainwin);
785 list = compose_get_compose_list();
786 for (cur = list; cur != NULL; cur = cur->next) {
787 toolbar_style(TOOLBAR_COMPOSE, action, cur->data);
789 list = messageview_get_msgview_list();
790 for (cur = list; cur != NULL; cur = cur->next) {
791 toolbar_style(TOOLBAR_MSGVIEW, action, cur->data);
796 void toolbar_set_style(GtkWidget *toolbar_wid, GtkWidget *handlebox_wid, guint action)
798 switch ((ToolbarStyle)action) {
800 gtk_widget_hide(handlebox_wid);
803 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
807 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
811 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
814 case TOOLBAR_BOTH_HORIZ:
815 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
816 GTK_TOOLBAR_BOTH_HORIZ);
822 prefs_common.toolbar_style = (ToolbarStyle)action;
823 gtk_widget_set_size_request(handlebox_wid, 1, -1);
825 if (prefs_common.toolbar_style != TOOLBAR_NONE) {
826 gtk_widget_show(handlebox_wid);
827 gtk_widget_queue_resize(handlebox_wid);
831 * Change the style of toolbar
833 static void toolbar_style(ToolbarType type, guint action, gpointer data)
835 GtkWidget *handlebox_wid;
836 GtkWidget *toolbar_wid;
837 MainWindow *mainwin = (MainWindow*)data;
838 Compose *compose = (Compose*)data;
839 MessageView *msgview = (MessageView*)data;
841 g_return_if_fail(data != NULL);
845 handlebox_wid = mainwin->handlebox;
846 toolbar_wid = mainwin->toolbar->toolbar;
848 case TOOLBAR_COMPOSE:
849 handlebox_wid = compose->handlebox;
850 toolbar_wid = compose->toolbar->toolbar;
852 case TOOLBAR_MSGVIEW:
853 handlebox_wid = msgview->handlebox;
854 toolbar_wid = msgview->toolbar->toolbar;
860 toolbar_set_style(toolbar_wid, handlebox_wid, action);
863 /* Toolbar handling */
864 static void toolbar_inc_cb(GtkWidget *widget,
867 ToolbarItem *toolbar_item = (ToolbarItem*)data;
870 g_return_if_fail(toolbar_item != NULL);
872 switch (toolbar_item->type) {
874 mainwin = (MainWindow*)toolbar_item->parent;
875 inc_mail_cb(mainwin, 0, NULL);
882 static void toolbar_inc_all_cb(GtkWidget *widget,
885 ToolbarItem *toolbar_item = (ToolbarItem*)data;
888 g_return_if_fail(toolbar_item != NULL);
890 switch (toolbar_item->type) {
892 mainwin = (MainWindow*)toolbar_item->parent;
893 inc_all_account_mail_cb(mainwin, 0, NULL);
900 static void toolbar_send_queued_cb(GtkWidget *widget,gpointer data)
902 ToolbarItem *toolbar_item = (ToolbarItem*)data;
905 g_return_if_fail(toolbar_item != NULL);
907 switch (toolbar_item->type) {
909 mainwin = (MainWindow*)toolbar_item->parent;
910 send_queue_cb(mainwin, 0, NULL);
917 static void toolbar_exec_cb(GtkWidget *widget,
920 MainWindow *mainwin = get_mainwin(data);
922 g_return_if_fail(mainwin != NULL);
923 summary_execute(mainwin->summaryview);
927 * Delete current/selected(s) message(s)
929 static void toolbar_trash_cb(GtkWidget *widget, gpointer data)
931 ToolbarItem *toolbar_item = (ToolbarItem*)data;
934 g_return_if_fail(toolbar_item != NULL);
935 g_return_if_fail(toolbar_item->parent);
937 switch (toolbar_item->type) {
938 case TOOLBAR_MSGVIEW:
939 messageview_delete((MessageView *)toolbar_item->parent);
942 mainwin = (MainWindow *)toolbar_item->parent;
943 summary_delete_trash(mainwin->summaryview);
946 debug_print("toolbar event not supported\n");
952 * Delete current/selected(s) message(s)
954 static void toolbar_delete_cb(GtkWidget *widget, gpointer data)
956 ToolbarItem *toolbar_item = (ToolbarItem*)data;
959 g_return_if_fail(toolbar_item != NULL);
960 g_return_if_fail(toolbar_item->parent);
962 switch (toolbar_item->type) {
963 case TOOLBAR_MSGVIEW:
964 messageview_delete((MessageView *)toolbar_item->parent);
967 mainwin = (MainWindow *)toolbar_item->parent;
968 summary_delete(mainwin->summaryview);
971 debug_print("toolbar event not supported\n");
978 * Compose new message
980 static void toolbar_compose_cb(GtkWidget *widget, gpointer data)
982 ToolbarItem *toolbar_item = (ToolbarItem*)data;
984 MessageView *msgview;
986 g_return_if_fail(toolbar_item != NULL);
988 switch (toolbar_item->type) {
990 mainwin = (MainWindow*)toolbar_item->parent;
991 if (mainwin->toolbar->compose_btn_type == COMPOSEBUTTON_NEWS)
992 compose_news_cb(mainwin, 0, NULL);
994 compose_mail_cb(mainwin, 0, NULL);
996 case TOOLBAR_MSGVIEW:
997 msgview = (MessageView*)toolbar_item->parent;
998 compose_new_with_folderitem(NULL,
999 msgview->msginfo->folder);
1002 debug_print("toolbar event not supported\n");
1006 static void toolbar_learn_cb(GtkWidget *widget, gpointer data)
1008 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1009 MainWindow *mainwin;
1010 MessageView *msgview;
1012 g_return_if_fail(toolbar_item != NULL);
1014 switch (toolbar_item->type) {
1016 mainwin = (MainWindow*)toolbar_item->parent;
1017 if (mainwin->toolbar->learn_btn_type == LEARN_SPAM)
1018 mainwindow_learn(mainwin, TRUE);
1020 mainwindow_learn(mainwin, FALSE);
1022 case TOOLBAR_MSGVIEW:
1023 msgview = (MessageView*)toolbar_item->parent;
1024 if (msgview->toolbar->learn_btn_type == LEARN_SPAM)
1025 messageview_learn(msgview, TRUE);
1027 messageview_learn(msgview, FALSE);
1030 debug_print("toolbar event not supported\n");
1038 static void toolbar_reply_cb(GtkWidget *widget, gpointer data)
1040 toolbar_reply(data, prefs_common.reply_with_quote ?
1041 COMPOSE_REPLY_WITH_QUOTE : COMPOSE_REPLY_WITHOUT_QUOTE);
1046 * Reply message to Sender and All recipients
1048 static void toolbar_reply_to_all_cb(GtkWidget *widget, gpointer data)
1051 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_ALL_WITH_QUOTE
1052 : COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE);
1057 * Reply to Mailing List
1059 static void toolbar_reply_to_list_cb(GtkWidget *widget, gpointer data)
1062 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_LIST_WITH_QUOTE
1063 : COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE);
1068 * Reply to sender of message
1070 static void toolbar_reply_to_sender_cb(GtkWidget *widget, gpointer data)
1073 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_SENDER_WITH_QUOTE
1074 : COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE);
1080 static void toolbar_addrbook_cb(GtkWidget *widget, gpointer data)
1082 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1085 g_return_if_fail(toolbar_item != NULL);
1087 switch (toolbar_item->type) {
1089 case TOOLBAR_MSGVIEW:
1092 case TOOLBAR_COMPOSE:
1093 compose = (Compose *)toolbar_item->parent;
1098 addressbook_open(compose);
1103 * Forward current/selected(s) message(s)
1105 static void toolbar_forward_cb(GtkWidget *widget, gpointer data)
1107 toolbar_reply(data, COMPOSE_FORWARD);
1111 * Goto Prev Unread Message
1113 static void toolbar_prev_unread_cb(GtkWidget *widget, gpointer data)
1115 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1116 MainWindow *mainwin;
1117 MessageView *msgview;
1119 g_return_if_fail(toolbar_item != NULL);
1121 switch (toolbar_item->type) {
1123 mainwin = (MainWindow*)toolbar_item->parent;
1124 summary_select_prev_unread(mainwin->summaryview);
1127 case TOOLBAR_MSGVIEW:
1128 msgview = (MessageView*)toolbar_item->parent;
1129 msgview->updating = TRUE;
1130 summary_select_prev_unread(msgview->mainwin->summaryview);
1131 msgview->updating = FALSE;
1133 if (msgview->deferred_destroy) {
1134 debug_print("messageview got away!\n");
1135 messageview_destroy(msgview);
1139 /* Now we need to update the messageview window */
1140 if (msgview->mainwin->summaryview->selected) {
1141 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1143 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1144 msgview->mainwin->summaryview->selected);
1146 messageview_show(msgview, msginfo,
1147 msgview->all_headers);
1149 gtk_widget_destroy(msgview->window);
1153 debug_print("toolbar event not supported\n");
1158 * Goto Next Unread Message
1160 static void toolbar_next_unread_cb(GtkWidget *widget, gpointer data)
1162 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1163 MainWindow *mainwin;
1164 MessageView *msgview;
1166 g_return_if_fail(toolbar_item != NULL);
1168 switch (toolbar_item->type) {
1170 mainwin = (MainWindow*)toolbar_item->parent;
1171 summary_select_next_unread(mainwin->summaryview);
1174 case TOOLBAR_MSGVIEW:
1175 msgview = (MessageView*)toolbar_item->parent;
1176 msgview->updating = TRUE;
1177 summary_select_next_unread(msgview->mainwin->summaryview);
1178 msgview->updating = FALSE;
1180 if (msgview->deferred_destroy) {
1181 debug_print("messageview got away!\n");
1182 messageview_destroy(msgview);
1186 /* Now we need to update the messageview window */
1187 if (msgview->mainwin->summaryview->selected) {
1188 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1190 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1191 msgview->mainwin->summaryview->selected);
1193 messageview_show(msgview, msginfo,
1194 msgview->all_headers);
1196 gtk_widget_destroy(msgview->window);
1200 debug_print("toolbar event not supported\n");
1204 static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data)
1206 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1207 MainWindow *mainwin;
1209 g_return_if_fail(toolbar_item != NULL);
1211 switch (toolbar_item->type) {
1213 mainwin = (MainWindow *) toolbar_item->parent;
1214 summary_toggle_ignore_thread(mainwin->summaryview);
1216 case TOOLBAR_MSGVIEW:
1217 /* TODO: see toolbar_next_unread_cb() if you need
1218 * this in the message view */
1221 debug_print("toolbar event not supported\n");
1226 static void toolbar_print_cb(GtkWidget *widget, gpointer data)
1228 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1229 MainWindow *mainwin;
1231 g_return_if_fail(toolbar_item != NULL);
1233 switch (toolbar_item->type) {
1235 mainwin = (MainWindow *) toolbar_item->parent;
1236 summary_print(mainwin->summaryview);
1238 case TOOLBAR_MSGVIEW:
1239 /* TODO: see toolbar_next_unread_cb() if you need
1240 * this in the message view */
1243 debug_print("toolbar event not supported\n");
1248 static void toolbar_send_cb(GtkWidget *widget, gpointer data)
1250 compose_toolbar_cb(A_SEND, data);
1253 static void toolbar_send_later_cb(GtkWidget *widget, gpointer data)
1255 compose_toolbar_cb(A_SENDL, data);
1258 static void toolbar_draft_cb(GtkWidget *widget, gpointer data)
1260 compose_toolbar_cb(A_DRAFT, data);
1263 static void toolbar_insert_cb(GtkWidget *widget, gpointer data)
1265 compose_toolbar_cb(A_INSERT, data);
1268 static void toolbar_attach_cb(GtkWidget *widget, gpointer data)
1270 compose_toolbar_cb(A_ATTACH, data);
1273 static void toolbar_sig_cb(GtkWidget *widget, gpointer data)
1275 compose_toolbar_cb(A_SIG, data);
1278 static void toolbar_ext_editor_cb(GtkWidget *widget, gpointer data)
1280 compose_toolbar_cb(A_EXTEDITOR, data);
1283 static void toolbar_linewrap_current_cb(GtkWidget *widget, gpointer data)
1285 compose_toolbar_cb(A_LINEWRAP_CURRENT, data);
1288 static void toolbar_linewrap_all_cb(GtkWidget *widget, gpointer data)
1290 compose_toolbar_cb(A_LINEWRAP_ALL, data);
1294 static void toolbar_check_spelling_cb(GtkWidget *widget, gpointer data)
1296 compose_toolbar_cb(A_CHECK_SPELLING, data);
1300 * Execute actions from toolbar
1302 static void toolbar_actions_execute_cb(GtkWidget *widget, gpointer data)
1304 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1305 GSList *action_list;
1306 MainWindow *mainwin;
1308 MessageView *msgview;
1309 gpointer parent = toolbar_item->parent;
1311 g_return_if_fail(toolbar_item != NULL);
1313 switch (toolbar_item->type) {
1315 mainwin = (MainWindow*)parent;
1316 action_list = mainwin->toolbar->action_list;
1318 case TOOLBAR_COMPOSE:
1319 compose = (Compose*)parent;
1320 action_list = compose->toolbar->action_list;
1322 case TOOLBAR_MSGVIEW:
1323 msgview = (MessageView*)parent;
1324 action_list = msgview->toolbar->action_list;
1327 debug_print("toolbar event not supported\n");
1330 toolbar_action_execute(widget, action_list, parent, toolbar_item->type);
1333 static MainWindow *get_mainwin(gpointer data)
1335 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1336 MainWindow *mainwin = NULL;
1337 MessageView *msgview;
1339 g_return_val_if_fail(toolbar_item != NULL, NULL);
1341 switch(toolbar_item->type) {
1343 mainwin = (MainWindow*)toolbar_item->parent;
1345 case TOOLBAR_MSGVIEW:
1346 msgview = (MessageView*)toolbar_item->parent;
1347 mainwin = (MainWindow*)msgview->mainwin;
1356 static void toolbar_buttons_cb(GtkWidget *widget,
1363 void (*func)(GtkWidget *widget, gpointer data);
1365 { A_RECEIVE_ALL, toolbar_inc_all_cb },
1366 { A_RECEIVE_CUR, toolbar_inc_cb },
1367 { A_SEND_QUEUED, toolbar_send_queued_cb },
1368 { A_COMPOSE_EMAIL, toolbar_compose_cb },
1369 { A_COMPOSE_NEWS, toolbar_compose_cb },
1370 { A_REPLY_MESSAGE, toolbar_reply_cb },
1371 { A_REPLY_SENDER, toolbar_reply_to_sender_cb },
1372 { A_REPLY_ALL, toolbar_reply_to_all_cb },
1373 { A_REPLY_ML, toolbar_reply_to_list_cb },
1374 { A_FORWARD, toolbar_forward_cb },
1375 { A_TRASH, toolbar_trash_cb },
1376 { A_DELETE_REAL, toolbar_delete_cb },
1377 { A_EXECUTE, toolbar_exec_cb },
1378 { A_GOTO_PREV, toolbar_prev_unread_cb },
1379 { A_GOTO_NEXT, toolbar_next_unread_cb },
1380 { A_IGNORE_THREAD, toolbar_ignore_thread_cb },
1381 { A_PRINT, toolbar_print_cb },
1382 { A_LEARN_SPAM, toolbar_learn_cb },
1384 { A_SEND, toolbar_send_cb },
1385 { A_SENDL, toolbar_send_later_cb },
1386 { A_DRAFT, toolbar_draft_cb },
1387 { A_INSERT, toolbar_insert_cb },
1388 { A_ATTACH, toolbar_attach_cb },
1389 { A_SIG, toolbar_sig_cb },
1390 { A_EXTEDITOR, toolbar_ext_editor_cb },
1391 { A_LINEWRAP_CURRENT, toolbar_linewrap_current_cb },
1392 { A_LINEWRAP_ALL, toolbar_linewrap_all_cb },
1393 { A_ADDRBOOK, toolbar_addrbook_cb },
1395 { A_CHECK_SPELLING, toolbar_check_spelling_cb },
1397 { A_SYL_ACTIONS, toolbar_actions_execute_cb }
1400 num_items = sizeof(callbacks)/sizeof(callbacks[0]);
1402 for (i = 0; i < num_items; i++) {
1403 if (callbacks[i].index == item->index) {
1404 callbacks[i].func(widget, item);
1411 * Create a new toolbar with specified type
1412 * if a callback list is passed it will be used before the
1413 * common callback list
1415 Toolbar *toolbar_create(ToolbarType type,
1416 GtkWidget *container,
1419 ToolbarItem *toolbar_item;
1422 GtkWidget *icon_wid = NULL;
1423 GtkWidget *icon_news;
1424 GtkWidget *icon_ham;
1426 GtkWidget *item_news;
1427 GtkWidget *item_ham;
1428 guint n_menu_entries;
1429 ComboButton *getall_combo;
1430 ComboButton *reply_combo;
1431 ComboButton *replyall_combo;
1432 ComboButton *replylist_combo;
1433 ComboButton *replysender_combo;
1434 ComboButton *fwd_combo;
1436 GtkTooltips *toolbar_tips;
1437 ToolbarSylpheedActions *action_item;
1439 GSList *toolbar_list;
1440 Toolbar *toolbar_data;
1443 toolbar_tips = gtk_tooltips_new();
1445 toolbar_read_config_file(type);
1446 toolbar_list = toolbar_get_list(type);
1448 toolbar_data = g_new0(Toolbar, 1);
1450 toolbar = gtk_toolbar_new();
1451 gtk_container_add(GTK_CONTAINER(container), toolbar);
1452 gtk_container_set_border_width(GTK_CONTAINER(container), 2);
1453 gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1454 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
1456 for (cur = toolbar_list; cur != NULL; cur = cur->next) {
1458 if (g_ascii_strcasecmp(((ToolbarItem*)cur->data)->file, TOOLBAR_TAG_SEPARATOR) == 0) {
1459 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
1463 toolbar_item = g_new0(ToolbarItem, 1);
1464 toolbar_item->index = ((ToolbarItem*)cur->data)->index;
1465 toolbar_item->file = g_strdup(((ToolbarItem*)cur->data)->file);
1466 toolbar_item->text = g_strdup(((ToolbarItem*)cur->data)->text);
1467 toolbar_item->parent = data;
1468 toolbar_item->type = type;
1470 /* collect toolbar items in list to keep track */
1471 toolbar_data->item_list =
1472 g_slist_append(toolbar_data->item_list,
1474 icon_wid = stock_pixmap_widget(container, stock_pixmap_get_icon(toolbar_item->file));
1475 item = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1479 icon_wid, G_CALLBACK(toolbar_buttons_cb),
1482 switch (toolbar_item->index) {
1485 toolbar_data->getall_btn = item;
1486 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1487 toolbar_data->getall_btn,
1488 _("Receive Mail on all Accounts"), NULL);
1489 getall_combo = gtkut_combo_button_create(toolbar_data->getall_btn, NULL, 0,
1490 "<GetAll>", (gpointer)toolbar_item);
1491 gtk_button_set_relief(GTK_BUTTON(getall_combo->arrow),
1493 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1494 GTK_WIDGET_PTR(getall_combo),
1495 _("Receive Mail on selected Account"), "Reply");
1496 toolbar_data->getall_combo = getall_combo;
1499 toolbar_data->get_btn = item;
1500 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1501 toolbar_data->get_btn,
1502 _("Receive Mail on current Account"), NULL);
1505 toolbar_data->send_btn = item;
1506 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1507 toolbar_data->send_btn,
1508 _("Send Queued Messages"), NULL);
1510 case A_COMPOSE_EMAIL:
1511 icon_news = stock_pixmap_widget(container, STOCK_PIXMAP_NEWS_COMPOSE);
1512 item_news = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1516 icon_news, G_CALLBACK(toolbar_buttons_cb),
1518 toolbar_data->compose_mail_btn = item;
1519 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1520 toolbar_data->compose_mail_btn,
1521 _("Compose Email"), NULL);
1522 toolbar_data->compose_news_btn = item_news;
1523 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1524 toolbar_data->compose_news_btn,
1525 _("Compose News"), NULL);
1528 icon_ham = stock_pixmap_widget(container, STOCK_PIXMAP_HAM_BTN);
1529 item_ham = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1533 icon_ham, G_CALLBACK(toolbar_buttons_cb),
1535 toolbar_data->learn_spam_btn = item;
1536 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1537 toolbar_data->learn_spam_btn,
1538 _("Learn Spam"), NULL);
1539 toolbar_data->learn_ham_btn = item_ham;
1540 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1541 toolbar_data->learn_ham_btn,
1542 _("Learn Ham"), NULL);
1544 case A_REPLY_MESSAGE:
1545 toolbar_data->reply_btn = item;
1546 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1547 toolbar_data->reply_btn,
1548 _("Reply to Message"), NULL);
1549 n_menu_entries = sizeof(reply_entries) /
1550 sizeof(reply_entries[0]);
1551 reply_combo = gtkut_combo_button_create(toolbar_data->reply_btn,
1552 reply_entries, n_menu_entries,
1553 "<Reply>", (gpointer)toolbar_item);
1554 gtk_button_set_relief(GTK_BUTTON(reply_combo->arrow),
1556 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1557 GTK_WIDGET_PTR(reply_combo),
1558 _("Reply to Message"), "Reply");
1559 toolbar_data->reply_combo = reply_combo;
1561 case A_REPLY_SENDER:
1562 toolbar_data->replysender_btn = item;
1563 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1564 toolbar_data->replysender_btn,
1565 _("Reply to Sender"), NULL);
1566 n_menu_entries = sizeof(replysender_entries) /
1567 sizeof(replysender_entries[0]);
1568 replysender_combo = gtkut_combo_button_create(toolbar_data->replysender_btn,
1569 replysender_entries, n_menu_entries,
1570 "<ReplySender>", (gpointer)toolbar_item);
1571 gtk_button_set_relief(GTK_BUTTON(replysender_combo->arrow),
1573 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1574 GTK_WIDGET_PTR(replysender_combo),
1575 _("Reply to Sender"), "ReplySender");
1576 toolbar_data->replysender_combo = replysender_combo;
1579 toolbar_data->replyall_btn = item;
1580 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1581 toolbar_data->replyall_btn,
1582 _("Reply to All"), NULL);
1583 n_menu_entries = sizeof(replyall_entries) /
1584 sizeof(replyall_entries[0]);
1585 replyall_combo = gtkut_combo_button_create(toolbar_data->replyall_btn,
1586 replyall_entries, n_menu_entries,
1587 "<ReplyAll>", (gpointer)toolbar_item);
1588 gtk_button_set_relief(GTK_BUTTON(replyall_combo->arrow),
1590 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1591 GTK_WIDGET_PTR(replyall_combo),
1592 _("Reply to All"), "ReplyAll");
1593 toolbar_data->replyall_combo = replyall_combo;
1596 toolbar_data->replylist_btn = item;
1597 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1598 toolbar_data->replylist_btn,
1599 _("Reply to Mailing-list"), NULL);
1600 n_menu_entries = sizeof(replylist_entries) /
1601 sizeof(replylist_entries[0]);
1602 replylist_combo = gtkut_combo_button_create(toolbar_data->replylist_btn,
1603 replylist_entries, n_menu_entries,
1604 "<ReplyList>", (gpointer)toolbar_item);
1605 gtk_button_set_relief(GTK_BUTTON(replylist_combo->arrow),
1607 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1608 GTK_WIDGET_PTR(replylist_combo),
1609 _("Reply to Mailing-list"), "ReplyList");
1610 toolbar_data->replylist_combo = replylist_combo;
1613 toolbar_data->fwd_btn = item;
1614 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1615 toolbar_data->fwd_btn,
1616 _("Forward Message"), NULL);
1617 n_menu_entries = sizeof(forward_entries) /
1618 sizeof(forward_entries[0]);
1619 fwd_combo = gtkut_combo_button_create(toolbar_data->fwd_btn,
1620 forward_entries, n_menu_entries,
1621 "<Forward>", (gpointer)toolbar_item);
1622 gtk_button_set_relief(GTK_BUTTON(fwd_combo->arrow),
1624 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1625 GTK_WIDGET_PTR(fwd_combo),
1626 _("Forward Message"), "Fwd");
1627 toolbar_data->fwd_combo = fwd_combo;
1630 toolbar_data->trash_btn = item;
1631 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1632 toolbar_data->trash_btn,
1633 _("Trash Message"), NULL);
1636 toolbar_data->delete_btn = item;
1637 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1638 toolbar_data->delete_btn,
1639 _("Delete Message"), NULL);
1642 toolbar_data->exec_btn = item;
1643 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1644 toolbar_data->exec_btn,
1645 _("Execute"), NULL);
1648 toolbar_data->prev_btn = item;
1649 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1650 toolbar_data->prev_btn,
1651 _("Go to Previous Unread Message"),
1655 toolbar_data->next_btn = item;
1656 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1657 toolbar_data->next_btn,
1658 _("Go to Next Unread Message"),
1662 /* Compose Toolbar */
1664 toolbar_data->send_btn = item;
1665 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1666 toolbar_data->send_btn,
1667 _("Send Message"), NULL);
1670 toolbar_data->sendl_btn = item;
1671 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1672 toolbar_data->sendl_btn,
1673 _("Put into queue folder and send later"), NULL);
1676 toolbar_data->draft_btn = item;
1677 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1678 toolbar_data->draft_btn,
1679 _("Save to draft folder"), NULL);
1682 toolbar_data->insert_btn = item;
1683 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1684 toolbar_data->insert_btn,
1685 _("Insert file"), NULL);
1688 toolbar_data->attach_btn = item;
1689 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1690 toolbar_data->attach_btn,
1691 _("Attach file"), NULL);
1694 toolbar_data->sig_btn = item;
1695 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1696 toolbar_data->sig_btn,
1697 _("Insert signature"), NULL);
1700 toolbar_data->exteditor_btn = item;
1701 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1702 toolbar_data->exteditor_btn,
1703 _("Edit with external editor"), NULL);
1705 case A_LINEWRAP_CURRENT:
1706 toolbar_data->linewrap_current_btn = item;
1707 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1708 toolbar_data->linewrap_current_btn,
1709 _("Wrap long lines of current paragraph"), NULL);
1711 case A_LINEWRAP_ALL:
1712 toolbar_data->linewrap_all_btn = item;
1713 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1714 toolbar_data->linewrap_all_btn,
1715 _("Wrap all long lines"), NULL);
1718 toolbar_data->addrbook_btn = item;
1719 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1720 toolbar_data->addrbook_btn,
1721 _("Address book"), NULL);
1724 case A_CHECK_SPELLING:
1725 toolbar_data->spellcheck_btn = item;
1726 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1727 toolbar_data->spellcheck_btn,
1728 _("Check spelling"), NULL);
1733 action_item = g_new0(ToolbarSylpheedActions, 1);
1734 action_item->widget = item;
1735 action_item->name = g_strdup(toolbar_item->text);
1737 toolbar_data->action_list =
1738 g_slist_append(toolbar_data->action_list,
1741 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1743 action_item->name, NULL);
1745 gtk_widget_show(item);
1748 /* find and set the tool tip text */
1749 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1751 toolbar_ret_descr_from_val
1752 (toolbar_item->index),
1758 toolbar_data->toolbar = toolbar;
1759 if (type == TOOLBAR_MAIN)
1760 activate_compose_button(toolbar_data,
1761 prefs_common.toolbar_style,
1762 toolbar_data->compose_btn_type);
1763 if (type != TOOLBAR_COMPOSE)
1764 activate_learn_button(toolbar_data, prefs_common.toolbar_style,
1767 gtk_widget_show_all(toolbar);
1769 return toolbar_data;
1773 * Free toolbar structures
1775 void toolbar_destroy(Toolbar * toolbar) {
1777 TOOLBAR_DESTROY_ITEMS(toolbar->item_list);
1778 TOOLBAR_DESTROY_ACTIONS(toolbar->action_list);
1781 void toolbar_update(ToolbarType type, gpointer data)
1783 Toolbar *toolbar_data;
1784 GtkWidget *handlebox;
1785 MainWindow *mainwin = (MainWindow*)data;
1786 Compose *compose = (Compose*)data;
1787 MessageView *msgview = (MessageView*)data;
1791 toolbar_data = mainwin->toolbar;
1792 handlebox = mainwin->handlebox;
1794 case TOOLBAR_COMPOSE:
1795 toolbar_data = compose->toolbar;
1796 handlebox = compose->handlebox;
1798 case TOOLBAR_MSGVIEW:
1799 toolbar_data = msgview->toolbar;
1800 handlebox = msgview->handlebox;
1806 gtk_container_remove(GTK_CONTAINER(handlebox),
1807 GTK_WIDGET(toolbar_data->toolbar));
1809 toolbar_init(toolbar_data);
1810 toolbar_data = toolbar_create(type, handlebox, data);
1813 mainwin->toolbar = toolbar_data;
1815 case TOOLBAR_COMPOSE:
1816 compose->toolbar = toolbar_data;
1818 case TOOLBAR_MSGVIEW:
1819 msgview->toolbar = toolbar_data;
1823 toolbar_style(type, prefs_common.toolbar_style, data);
1825 if (type == TOOLBAR_MAIN) {
1826 toolbar_main_set_sensitive((MainWindow*)data);
1827 account_set_menu_only_toolbar();
1831 void toolbar_main_set_sensitive(gpointer data)
1833 SensitiveCond state;
1835 MainWindow *mainwin = (MainWindow*)data;
1836 Toolbar *toolbar = mainwin->toolbar;
1838 GSList *entry_list = NULL;
1840 typedef struct _Entry Entry;
1847 #define SET_WIDGET_COND(w, c) \
1849 Entry *e = g_new0(Entry, 1); \
1852 entry_list = g_slist_append(entry_list, e); \
1855 SET_WIDGET_COND(toolbar->get_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1856 SET_WIDGET_COND(toolbar->getall_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1857 if (toolbar->getall_btn)
1858 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->getall_combo),
1859 M_HAVE_ACCOUNT|M_UNLOCKED);
1860 SET_WIDGET_COND(toolbar->compose_news_btn, M_HAVE_ACCOUNT);
1861 SET_WIDGET_COND(toolbar->reply_btn,
1862 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1863 if (toolbar->reply_btn)
1864 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->reply_combo),
1865 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1866 SET_WIDGET_COND(toolbar->replyall_btn,
1867 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1868 if (toolbar->replyall_btn)
1869 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replyall_combo),
1870 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1871 SET_WIDGET_COND(toolbar->replylist_btn,
1872 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1873 if (toolbar->replylist_btn)
1874 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replylist_combo),
1875 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1876 SET_WIDGET_COND(toolbar->replysender_btn,
1877 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1878 if (toolbar->replysender_btn)
1879 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replysender_combo),
1880 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1881 SET_WIDGET_COND(toolbar->fwd_btn, M_HAVE_ACCOUNT|M_TARGET_EXIST);
1882 if (toolbar->fwd_btn)
1883 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->fwd_combo),
1884 M_HAVE_ACCOUNT|M_TARGET_EXIST);
1885 if (toolbar->fwd_combo) {
1886 GtkWidget *submenu = gtk_item_factory_get_widget(toolbar->fwd_combo->factory, "/Redirect");
1887 SET_WIDGET_COND(submenu, M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1890 if (prefs_common.next_unread_msg_dialog == NEXTUNREADMSGDIALOG_ASSUME_NO) {
1891 SET_WIDGET_COND(toolbar->next_btn, M_MSG_EXIST);
1893 SET_WIDGET_COND(toolbar->next_btn, 0);
1896 if (toolbar->trash_btn)
1897 SET_WIDGET_COND(toolbar->trash_btn,
1898 M_TARGET_EXIST|M_ALLOW_DELETE);
1899 if (toolbar->delete_btn)
1900 SET_WIDGET_COND(toolbar->delete_btn,
1901 M_TARGET_EXIST|M_ALLOW_DELETE);
1902 if (toolbar->exec_btn)
1903 SET_WIDGET_COND(toolbar->exec_btn, M_DELAY_EXEC);
1905 if (toolbar->learn_ham_btn)
1906 SET_WIDGET_COND(toolbar->learn_ham_btn, M_TARGET_EXIST|M_CAN_LEARN_SPAM);
1907 if (toolbar->learn_spam_btn)
1908 SET_WIDGET_COND(toolbar->learn_spam_btn, M_TARGET_EXIST|M_CAN_LEARN_SPAM);
1910 for (cur = toolbar->action_list; cur != NULL; cur = cur->next) {
1911 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
1913 SET_WIDGET_COND(act->widget, M_TARGET_EXIST|M_UNLOCKED);
1916 #undef SET_WIDGET_COND
1918 state = main_window_get_current_state(mainwin);
1920 for (cur = entry_list; cur != NULL; cur = cur->next) {
1921 Entry *e = (Entry*) cur->data;
1923 if (e->widget != NULL) {
1924 sensitive = ((e->cond & state) == e->cond);
1925 gtk_widget_set_sensitive(e->widget, sensitive);
1929 while (entry_list != NULL) {
1930 Entry *e = (Entry*) entry_list->data;
1933 entry_list = g_slist_remove(entry_list, e);
1936 g_slist_free(entry_list);
1938 activate_compose_button(toolbar,
1939 prefs_common.toolbar_style,
1940 toolbar->compose_btn_type);
1943 void toolbar_comp_set_sensitive(gpointer data, gboolean sensitive)
1945 Compose *compose = (Compose*)data;
1946 GSList *items = compose->toolbar->action_list;
1948 if (compose->toolbar->send_btn)
1949 gtk_widget_set_sensitive(compose->toolbar->send_btn, sensitive);
1950 if (compose->toolbar->sendl_btn)
1951 gtk_widget_set_sensitive(compose->toolbar->sendl_btn, sensitive);
1952 if (compose->toolbar->draft_btn )
1953 gtk_widget_set_sensitive(compose->toolbar->draft_btn , sensitive);
1954 if (compose->toolbar->insert_btn )
1955 gtk_widget_set_sensitive(compose->toolbar->insert_btn , sensitive);
1956 if (compose->toolbar->attach_btn)
1957 gtk_widget_set_sensitive(compose->toolbar->attach_btn, sensitive);
1958 if (compose->toolbar->sig_btn)
1959 gtk_widget_set_sensitive(compose->toolbar->sig_btn, sensitive);
1960 if (compose->toolbar->exteditor_btn)
1961 gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, sensitive);
1962 if (compose->toolbar->linewrap_current_btn)
1963 gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, sensitive);
1964 if (compose->toolbar->linewrap_all_btn)
1965 gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, sensitive);
1966 if (compose->toolbar->addrbook_btn)
1967 gtk_widget_set_sensitive(compose->toolbar->addrbook_btn, sensitive);
1969 if (compose->toolbar->spellcheck_btn)
1970 gtk_widget_set_sensitive(compose->toolbar->spellcheck_btn, sensitive);
1972 for (; items != NULL; items = g_slist_next(items)) {
1973 ToolbarSylpheedActions *item = (ToolbarSylpheedActions *)items->data;
1974 gtk_widget_set_sensitive(item->widget, sensitive);
1979 * Initialize toolbar structure
1981 void toolbar_init(Toolbar * toolbar) {
1983 toolbar->toolbar = NULL;
1984 toolbar->get_btn = NULL;
1985 toolbar->getall_btn = NULL;
1986 toolbar->getall_combo = NULL;
1987 toolbar->send_btn = NULL;
1988 toolbar->compose_mail_btn = NULL;
1989 toolbar->compose_news_btn = NULL;
1990 toolbar->reply_btn = NULL;
1991 toolbar->replysender_btn = NULL;
1992 toolbar->replyall_btn = NULL;
1993 toolbar->replylist_btn = NULL;
1994 toolbar->fwd_btn = NULL;
1995 toolbar->trash_btn = NULL;
1996 toolbar->delete_btn = NULL;
1997 toolbar->prev_btn = NULL;
1998 toolbar->next_btn = NULL;
1999 toolbar->exec_btn = NULL;
2001 /* compose buttons */
2002 toolbar->sendl_btn = NULL;
2003 toolbar->draft_btn = NULL;
2004 toolbar->insert_btn = NULL;
2005 toolbar->attach_btn = NULL;
2006 toolbar->sig_btn = NULL;
2007 toolbar->exteditor_btn = NULL;
2008 toolbar->linewrap_current_btn = NULL;
2009 toolbar->linewrap_all_btn = NULL;
2010 toolbar->addrbook_btn = NULL;
2012 toolbar->spellcheck_btn = NULL;
2015 toolbar_destroy(toolbar);
2020 static void toolbar_reply(gpointer data, guint action)
2022 ToolbarItem *toolbar_item = (ToolbarItem*)data;
2023 MainWindow *mainwin;
2024 MessageView *msgview;
2025 GSList *msginfo_list = NULL;
2027 g_return_if_fail(toolbar_item != NULL);
2029 switch (toolbar_item->type) {
2031 mainwin = (MainWindow*)toolbar_item->parent;
2032 msginfo_list = summary_get_selection(mainwin->summaryview);
2033 msgview = (MessageView*)mainwin->messageview;
2035 case TOOLBAR_MSGVIEW:
2036 msgview = (MessageView*)toolbar_item->parent;
2037 g_return_if_fail(msgview != NULL);
2038 msginfo_list = g_slist_append(msginfo_list, msgview->msginfo);
2044 g_return_if_fail(msgview != NULL);
2045 g_return_if_fail(msginfo_list != NULL);
2046 compose_reply_from_messageview(msgview, msginfo_list, action);
2047 g_slist_free(msginfo_list);
2049 /* TODO: update reply state ion summaryview */
2053 /* exported functions */
2055 void inc_mail_cb(gpointer data, guint action, GtkWidget *widget)
2057 MainWindow *mainwin = (MainWindow*)data;
2059 inc_mail(mainwin, prefs_common.newmail_notify_manu);
2062 void inc_all_account_mail_cb(gpointer data, guint action, GtkWidget *widget)
2064 MainWindow *mainwin = (MainWindow*)data;
2066 inc_all_account_mail(mainwin, FALSE, prefs_common.newmail_notify_manu);
2069 void send_queue_cb(gpointer data, guint action, GtkWidget *widget)
2074 if (prefs_common.work_offline)
2075 if (alertpanel(_("Offline warning"),
2076 _("You're working offline. Override?"),
2077 GTK_STOCK_NO, GTK_STOCK_YES,
2078 NULL) != G_ALERTALTERNATE)
2081 /* ask for confirmation before sending queued messages only
2082 in online mode and if there is at least one message queued
2083 in any of the folder queue
2085 if (prefs_common.confirm_send_queued_messages) {
2087 /* check if there's a queued message */
2088 for (list = folder_get_list(); !found && list != NULL; list = list->next) {
2089 Folder *folder = list->data;
2091 found = !procmsg_queue_is_empty(folder->queue);
2093 /* if necessary, ask for confirmation before sending */
2094 if (found && !prefs_common.work_offline) {
2095 if (alertpanel(_("Send queued messages"),
2096 _("Send all queued messages?"),
2097 GTK_STOCK_CANCEL, _("_Send"),
2098 NULL) != G_ALERTALTERNATE)
2103 for (list = folder_get_list(); list != NULL; list = list->next) {
2104 Folder *folder = list->data;
2106 if (folder->queue) {
2107 if (procmsg_send_queue(folder->queue,
2108 prefs_common.savemsg) < 0)
2109 alertpanel_error(_("Some errors occurred while "
2110 "sending queued messages."));
2115 void compose_mail_cb(gpointer data, guint action, GtkWidget *widget)
2117 MainWindow *mainwin = (MainWindow*)data;
2118 PrefsAccount *ac = NULL;
2119 FolderItem *item = mainwin->summaryview->folder_item;
2124 ac = account_find_from_item(item);
2125 if (ac && ac->protocol != A_NNTP) {
2126 compose_new_with_folderitem(ac, item); /* CLAWS */
2132 * CLAWS - use current account
2134 if (cur_account && (cur_account->protocol != A_NNTP)) {
2135 compose_new_with_folderitem(cur_account, item);
2140 * CLAWS - just get the first one
2142 list = account_get_list();
2143 for (cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2144 ac = (PrefsAccount *) cur->data;
2145 if (ac->protocol != A_NNTP) {
2146 compose_new_with_folderitem(ac, item);
2152 void compose_news_cb(gpointer data, guint action, GtkWidget *widget)
2154 MainWindow *mainwin = (MainWindow*)data;
2155 PrefsAccount * ac = NULL;
2159 if (mainwin->summaryview->folder_item) {
2160 ac = mainwin->summaryview->folder_item->folder->account;
2161 if (ac && ac->protocol == A_NNTP) {
2162 compose_new_with_folderitem(ac,
2163 mainwin->summaryview->folder_item);
2168 list = account_get_list();
2169 for(cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2170 ac = (PrefsAccount *) cur->data;
2171 if (ac->protocol == A_NNTP) {
2172 compose_new_with_folderitem(ac,
2173 mainwin->summaryview->folder_item);