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);
662 g_slist_free(toolbar_config[source].item_list);
667 * return list of Toolbar items
669 GSList *toolbar_get_list(ToolbarType source)
673 if ((source == TOOLBAR_MAIN) || (source == TOOLBAR_COMPOSE) || (source == TOOLBAR_MSGVIEW))
674 list = toolbar_config[source].item_list;
679 void toolbar_set_list_item(ToolbarItem *t_item, ToolbarType source)
681 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
683 toolbar_item->file = g_strdup(t_item->file);
684 toolbar_item->text = g_strdup(t_item->text);
685 toolbar_item->index = t_item->index;
687 toolbar_config[source].item_list =
688 g_slist_append(toolbar_config[source].item_list,
692 void toolbar_action_execute(GtkWidget *widget,
698 gchar *action, *action_p;
699 gboolean found = FALSE;
702 for (cur = action_list; cur != NULL; cur = cur->next) {
703 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
705 if (widget == act->widget) {
707 for (lop = prefs_common.actions_list; lop != NULL; lop = lop->next) {
708 action = g_strdup((gchar*)lop->data);
710 action_p = strstr(action, ": ");
712 if (g_utf8_collate(act->name, action) == 0) {
726 actions_execute(data, i, widget, source);
728 g_warning ("Error: did not find Sylpheed Action to execute");
731 static void activate_compose_button (Toolbar *toolbar,
733 ComposeButtonType type)
735 if ((!toolbar->compose_mail_btn) || (!toolbar->compose_news_btn))
738 gtk_widget_hide(type == COMPOSEBUTTON_NEWS ? toolbar->compose_mail_btn
739 : toolbar->compose_news_btn);
740 gtk_widget_show(type == COMPOSEBUTTON_NEWS ? toolbar->compose_news_btn
741 : toolbar->compose_mail_btn);
742 toolbar->compose_btn_type = type;
745 void toolbar_set_compose_button(Toolbar *toolbar,
746 ComposeButtonType compose_btn_type)
748 if (toolbar->compose_btn_type != compose_btn_type)
749 activate_compose_button(toolbar,
750 prefs_common.toolbar_style,
754 static void activate_learn_button (Toolbar *toolbar,
756 LearnButtonType type)
758 if ((!toolbar->learn_spam_btn) || (!toolbar->learn_ham_btn))
761 gtk_widget_hide(type == LEARN_SPAM ? toolbar->learn_ham_btn
762 : toolbar->learn_spam_btn);
763 gtk_widget_show(type == LEARN_SPAM ? toolbar->learn_spam_btn
764 : toolbar->learn_ham_btn);
765 toolbar->learn_btn_type = type;
768 void toolbar_set_learn_button(Toolbar *toolbar,
769 LearnButtonType learn_btn_type)
771 if (toolbar->learn_btn_type != learn_btn_type)
772 activate_learn_button(toolbar,
773 prefs_common.toolbar_style,
777 void toolbar_toggle(guint action, gpointer data)
779 MainWindow *mainwin = (MainWindow*)data;
783 g_return_if_fail(mainwin != NULL);
785 toolbar_style(TOOLBAR_MAIN, action, mainwin);
787 list = compose_get_compose_list();
788 for (cur = list; cur != NULL; cur = cur->next) {
789 toolbar_style(TOOLBAR_COMPOSE, action, cur->data);
791 list = messageview_get_msgview_list();
792 for (cur = list; cur != NULL; cur = cur->next) {
793 toolbar_style(TOOLBAR_MSGVIEW, action, cur->data);
798 void toolbar_set_style(GtkWidget *toolbar_wid, GtkWidget *handlebox_wid, guint action)
800 switch ((ToolbarStyle)action) {
802 gtk_widget_hide(handlebox_wid);
805 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
809 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
813 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
816 case TOOLBAR_BOTH_HORIZ:
817 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
818 GTK_TOOLBAR_BOTH_HORIZ);
824 prefs_common.toolbar_style = (ToolbarStyle)action;
825 gtk_widget_set_size_request(handlebox_wid, 1, -1);
827 if (prefs_common.toolbar_style != TOOLBAR_NONE) {
828 gtk_widget_show(handlebox_wid);
829 gtk_widget_queue_resize(handlebox_wid);
833 * Change the style of toolbar
835 static void toolbar_style(ToolbarType type, guint action, gpointer data)
837 GtkWidget *handlebox_wid;
838 GtkWidget *toolbar_wid;
839 MainWindow *mainwin = (MainWindow*)data;
840 Compose *compose = (Compose*)data;
841 MessageView *msgview = (MessageView*)data;
843 g_return_if_fail(data != NULL);
847 handlebox_wid = mainwin->handlebox;
848 toolbar_wid = mainwin->toolbar->toolbar;
850 case TOOLBAR_COMPOSE:
851 handlebox_wid = compose->handlebox;
852 toolbar_wid = compose->toolbar->toolbar;
854 case TOOLBAR_MSGVIEW:
855 handlebox_wid = msgview->handlebox;
856 toolbar_wid = msgview->toolbar->toolbar;
862 toolbar_set_style(toolbar_wid, handlebox_wid, action);
865 /* Toolbar handling */
866 static void toolbar_inc_cb(GtkWidget *widget,
869 ToolbarItem *toolbar_item = (ToolbarItem*)data;
872 g_return_if_fail(toolbar_item != NULL);
874 switch (toolbar_item->type) {
876 mainwin = (MainWindow*)toolbar_item->parent;
877 inc_mail_cb(mainwin, 0, NULL);
884 static void toolbar_inc_all_cb(GtkWidget *widget,
887 ToolbarItem *toolbar_item = (ToolbarItem*)data;
890 g_return_if_fail(toolbar_item != NULL);
892 switch (toolbar_item->type) {
894 mainwin = (MainWindow*)toolbar_item->parent;
895 inc_all_account_mail_cb(mainwin, 0, NULL);
902 static void toolbar_send_queued_cb(GtkWidget *widget,gpointer data)
904 ToolbarItem *toolbar_item = (ToolbarItem*)data;
907 g_return_if_fail(toolbar_item != NULL);
909 switch (toolbar_item->type) {
911 mainwin = (MainWindow*)toolbar_item->parent;
912 send_queue_cb(mainwin, 0, NULL);
919 static void toolbar_exec_cb(GtkWidget *widget,
922 MainWindow *mainwin = get_mainwin(data);
924 g_return_if_fail(mainwin != NULL);
925 summary_execute(mainwin->summaryview);
929 * Delete current/selected(s) message(s)
931 static void toolbar_trash_cb(GtkWidget *widget, gpointer data)
933 ToolbarItem *toolbar_item = (ToolbarItem*)data;
936 g_return_if_fail(toolbar_item != NULL);
937 g_return_if_fail(toolbar_item->parent);
939 switch (toolbar_item->type) {
940 case TOOLBAR_MSGVIEW:
941 messageview_delete((MessageView *)toolbar_item->parent);
944 mainwin = (MainWindow *)toolbar_item->parent;
945 summary_delete_trash(mainwin->summaryview);
948 debug_print("toolbar event not supported\n");
954 * Delete current/selected(s) message(s)
956 static void toolbar_delete_cb(GtkWidget *widget, gpointer data)
958 ToolbarItem *toolbar_item = (ToolbarItem*)data;
961 g_return_if_fail(toolbar_item != NULL);
962 g_return_if_fail(toolbar_item->parent);
964 switch (toolbar_item->type) {
965 case TOOLBAR_MSGVIEW:
966 messageview_delete((MessageView *)toolbar_item->parent);
969 mainwin = (MainWindow *)toolbar_item->parent;
970 summary_delete(mainwin->summaryview);
973 debug_print("toolbar event not supported\n");
980 * Compose new message
982 static void toolbar_compose_cb(GtkWidget *widget, gpointer data)
984 ToolbarItem *toolbar_item = (ToolbarItem*)data;
986 MessageView *msgview;
988 g_return_if_fail(toolbar_item != NULL);
990 switch (toolbar_item->type) {
992 mainwin = (MainWindow*)toolbar_item->parent;
993 if (mainwin->toolbar->compose_btn_type == COMPOSEBUTTON_NEWS)
994 compose_news_cb(mainwin, 0, NULL);
996 compose_mail_cb(mainwin, 0, NULL);
998 case TOOLBAR_MSGVIEW:
999 msgview = (MessageView*)toolbar_item->parent;
1000 compose_new_with_folderitem(NULL,
1001 msgview->msginfo->folder);
1004 debug_print("toolbar event not supported\n");
1008 static void toolbar_learn_cb(GtkWidget *widget, gpointer data)
1010 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1011 MainWindow *mainwin;
1012 MessageView *msgview;
1014 g_return_if_fail(toolbar_item != NULL);
1016 switch (toolbar_item->type) {
1018 mainwin = (MainWindow*)toolbar_item->parent;
1019 if (mainwin->toolbar->learn_btn_type == LEARN_SPAM)
1020 mainwindow_learn(mainwin, TRUE);
1022 mainwindow_learn(mainwin, FALSE);
1024 case TOOLBAR_MSGVIEW:
1025 msgview = (MessageView*)toolbar_item->parent;
1026 if (msgview->toolbar->learn_btn_type == LEARN_SPAM)
1027 messageview_learn(msgview, TRUE);
1029 messageview_learn(msgview, FALSE);
1032 debug_print("toolbar event not supported\n");
1040 static void toolbar_reply_cb(GtkWidget *widget, gpointer data)
1042 toolbar_reply(data, prefs_common.reply_with_quote ?
1043 COMPOSE_REPLY_WITH_QUOTE : COMPOSE_REPLY_WITHOUT_QUOTE);
1048 * Reply message to Sender and All recipients
1050 static void toolbar_reply_to_all_cb(GtkWidget *widget, gpointer data)
1053 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_ALL_WITH_QUOTE
1054 : COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE);
1059 * Reply to Mailing List
1061 static void toolbar_reply_to_list_cb(GtkWidget *widget, gpointer data)
1064 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_LIST_WITH_QUOTE
1065 : COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE);
1070 * Reply to sender of message
1072 static void toolbar_reply_to_sender_cb(GtkWidget *widget, gpointer data)
1075 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_SENDER_WITH_QUOTE
1076 : COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE);
1082 static void toolbar_addrbook_cb(GtkWidget *widget, gpointer data)
1084 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1087 g_return_if_fail(toolbar_item != NULL);
1089 switch (toolbar_item->type) {
1091 case TOOLBAR_MSGVIEW:
1094 case TOOLBAR_COMPOSE:
1095 compose = (Compose *)toolbar_item->parent;
1100 addressbook_open(compose);
1105 * Forward current/selected(s) message(s)
1107 static void toolbar_forward_cb(GtkWidget *widget, gpointer data)
1109 toolbar_reply(data, COMPOSE_FORWARD);
1113 * Goto Prev Unread Message
1115 static void toolbar_prev_unread_cb(GtkWidget *widget, gpointer data)
1117 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1118 MainWindow *mainwin;
1119 MessageView *msgview;
1121 g_return_if_fail(toolbar_item != NULL);
1123 switch (toolbar_item->type) {
1125 mainwin = (MainWindow*)toolbar_item->parent;
1126 summary_select_prev_unread(mainwin->summaryview);
1129 case TOOLBAR_MSGVIEW:
1130 msgview = (MessageView*)toolbar_item->parent;
1131 msgview->updating = TRUE;
1132 summary_select_prev_unread(msgview->mainwin->summaryview);
1133 msgview->updating = FALSE;
1135 if (msgview->deferred_destroy) {
1136 debug_print("messageview got away!\n");
1137 messageview_destroy(msgview);
1141 /* Now we need to update the messageview window */
1142 if (msgview->mainwin->summaryview->selected) {
1143 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1145 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1146 msgview->mainwin->summaryview->selected);
1148 messageview_show(msgview, msginfo,
1149 msgview->all_headers);
1151 gtk_widget_destroy(msgview->window);
1155 debug_print("toolbar event not supported\n");
1160 * Goto Next Unread Message
1162 static void toolbar_next_unread_cb(GtkWidget *widget, gpointer data)
1164 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1165 MainWindow *mainwin;
1166 MessageView *msgview;
1168 g_return_if_fail(toolbar_item != NULL);
1170 switch (toolbar_item->type) {
1172 mainwin = (MainWindow*)toolbar_item->parent;
1173 summary_select_next_unread(mainwin->summaryview);
1176 case TOOLBAR_MSGVIEW:
1177 msgview = (MessageView*)toolbar_item->parent;
1178 msgview->updating = TRUE;
1179 summary_select_next_unread(msgview->mainwin->summaryview);
1180 msgview->updating = FALSE;
1182 if (msgview->deferred_destroy) {
1183 debug_print("messageview got away!\n");
1184 messageview_destroy(msgview);
1188 /* Now we need to update the messageview window */
1189 if (msgview->mainwin->summaryview->selected) {
1190 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1192 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1193 msgview->mainwin->summaryview->selected);
1195 messageview_show(msgview, msginfo,
1196 msgview->all_headers);
1198 gtk_widget_destroy(msgview->window);
1202 debug_print("toolbar event not supported\n");
1206 static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data)
1208 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1209 MainWindow *mainwin;
1211 g_return_if_fail(toolbar_item != NULL);
1213 switch (toolbar_item->type) {
1215 mainwin = (MainWindow *) toolbar_item->parent;
1216 summary_toggle_ignore_thread(mainwin->summaryview);
1218 case TOOLBAR_MSGVIEW:
1219 /* TODO: see toolbar_next_unread_cb() if you need
1220 * this in the message view */
1223 debug_print("toolbar event not supported\n");
1228 static void toolbar_print_cb(GtkWidget *widget, gpointer data)
1230 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1231 MainWindow *mainwin;
1233 g_return_if_fail(toolbar_item != NULL);
1235 switch (toolbar_item->type) {
1237 mainwin = (MainWindow *) toolbar_item->parent;
1238 summary_print(mainwin->summaryview);
1240 case TOOLBAR_MSGVIEW:
1241 /* TODO: see toolbar_next_unread_cb() if you need
1242 * this in the message view */
1245 debug_print("toolbar event not supported\n");
1250 static void toolbar_send_cb(GtkWidget *widget, gpointer data)
1252 compose_toolbar_cb(A_SEND, data);
1255 static void toolbar_send_later_cb(GtkWidget *widget, gpointer data)
1257 compose_toolbar_cb(A_SENDL, data);
1260 static void toolbar_draft_cb(GtkWidget *widget, gpointer data)
1262 compose_toolbar_cb(A_DRAFT, data);
1265 static void toolbar_insert_cb(GtkWidget *widget, gpointer data)
1267 compose_toolbar_cb(A_INSERT, data);
1270 static void toolbar_attach_cb(GtkWidget *widget, gpointer data)
1272 compose_toolbar_cb(A_ATTACH, data);
1275 static void toolbar_sig_cb(GtkWidget *widget, gpointer data)
1277 compose_toolbar_cb(A_SIG, data);
1280 static void toolbar_ext_editor_cb(GtkWidget *widget, gpointer data)
1282 compose_toolbar_cb(A_EXTEDITOR, data);
1285 static void toolbar_linewrap_current_cb(GtkWidget *widget, gpointer data)
1287 compose_toolbar_cb(A_LINEWRAP_CURRENT, data);
1290 static void toolbar_linewrap_all_cb(GtkWidget *widget, gpointer data)
1292 compose_toolbar_cb(A_LINEWRAP_ALL, data);
1296 static void toolbar_check_spelling_cb(GtkWidget *widget, gpointer data)
1298 compose_toolbar_cb(A_CHECK_SPELLING, data);
1302 * Execute actions from toolbar
1304 static void toolbar_actions_execute_cb(GtkWidget *widget, gpointer data)
1306 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1307 GSList *action_list;
1308 MainWindow *mainwin;
1310 MessageView *msgview;
1311 gpointer parent = toolbar_item->parent;
1313 g_return_if_fail(toolbar_item != NULL);
1315 switch (toolbar_item->type) {
1317 mainwin = (MainWindow*)parent;
1318 action_list = mainwin->toolbar->action_list;
1320 case TOOLBAR_COMPOSE:
1321 compose = (Compose*)parent;
1322 action_list = compose->toolbar->action_list;
1324 case TOOLBAR_MSGVIEW:
1325 msgview = (MessageView*)parent;
1326 action_list = msgview->toolbar->action_list;
1329 debug_print("toolbar event not supported\n");
1332 toolbar_action_execute(widget, action_list, parent, toolbar_item->type);
1335 static MainWindow *get_mainwin(gpointer data)
1337 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1338 MainWindow *mainwin = NULL;
1339 MessageView *msgview;
1341 g_return_val_if_fail(toolbar_item != NULL, NULL);
1343 switch(toolbar_item->type) {
1345 mainwin = (MainWindow*)toolbar_item->parent;
1347 case TOOLBAR_MSGVIEW:
1348 msgview = (MessageView*)toolbar_item->parent;
1349 mainwin = (MainWindow*)msgview->mainwin;
1358 static void toolbar_buttons_cb(GtkWidget *widget,
1365 void (*func)(GtkWidget *widget, gpointer data);
1367 { A_RECEIVE_ALL, toolbar_inc_all_cb },
1368 { A_RECEIVE_CUR, toolbar_inc_cb },
1369 { A_SEND_QUEUED, toolbar_send_queued_cb },
1370 { A_COMPOSE_EMAIL, toolbar_compose_cb },
1371 { A_COMPOSE_NEWS, toolbar_compose_cb },
1372 { A_REPLY_MESSAGE, toolbar_reply_cb },
1373 { A_REPLY_SENDER, toolbar_reply_to_sender_cb },
1374 { A_REPLY_ALL, toolbar_reply_to_all_cb },
1375 { A_REPLY_ML, toolbar_reply_to_list_cb },
1376 { A_FORWARD, toolbar_forward_cb },
1377 { A_TRASH, toolbar_trash_cb },
1378 { A_DELETE_REAL, toolbar_delete_cb },
1379 { A_EXECUTE, toolbar_exec_cb },
1380 { A_GOTO_PREV, toolbar_prev_unread_cb },
1381 { A_GOTO_NEXT, toolbar_next_unread_cb },
1382 { A_IGNORE_THREAD, toolbar_ignore_thread_cb },
1383 { A_PRINT, toolbar_print_cb },
1384 { A_LEARN_SPAM, toolbar_learn_cb },
1386 { A_SEND, toolbar_send_cb },
1387 { A_SENDL, toolbar_send_later_cb },
1388 { A_DRAFT, toolbar_draft_cb },
1389 { A_INSERT, toolbar_insert_cb },
1390 { A_ATTACH, toolbar_attach_cb },
1391 { A_SIG, toolbar_sig_cb },
1392 { A_EXTEDITOR, toolbar_ext_editor_cb },
1393 { A_LINEWRAP_CURRENT, toolbar_linewrap_current_cb },
1394 { A_LINEWRAP_ALL, toolbar_linewrap_all_cb },
1395 { A_ADDRBOOK, toolbar_addrbook_cb },
1397 { A_CHECK_SPELLING, toolbar_check_spelling_cb },
1399 { A_SYL_ACTIONS, toolbar_actions_execute_cb }
1402 num_items = sizeof(callbacks)/sizeof(callbacks[0]);
1404 for (i = 0; i < num_items; i++) {
1405 if (callbacks[i].index == item->index) {
1406 callbacks[i].func(widget, item);
1413 * Create a new toolbar with specified type
1414 * if a callback list is passed it will be used before the
1415 * common callback list
1417 Toolbar *toolbar_create(ToolbarType type,
1418 GtkWidget *container,
1421 ToolbarItem *toolbar_item;
1424 GtkWidget *icon_wid = NULL;
1425 GtkWidget *icon_news;
1426 GtkWidget *icon_ham;
1428 GtkWidget *item_news;
1429 GtkWidget *item_ham;
1430 guint n_menu_entries;
1431 ComboButton *getall_combo;
1432 ComboButton *reply_combo;
1433 ComboButton *replyall_combo;
1434 ComboButton *replylist_combo;
1435 ComboButton *replysender_combo;
1436 ComboButton *fwd_combo;
1438 GtkTooltips *toolbar_tips;
1439 ToolbarSylpheedActions *action_item;
1441 GSList *toolbar_list;
1442 Toolbar *toolbar_data;
1445 toolbar_tips = gtk_tooltips_new();
1447 toolbar_read_config_file(type);
1448 toolbar_list = toolbar_get_list(type);
1450 toolbar_data = g_new0(Toolbar, 1);
1452 toolbar = gtk_toolbar_new();
1453 gtk_container_add(GTK_CONTAINER(container), toolbar);
1454 gtk_container_set_border_width(GTK_CONTAINER(container), 2);
1455 gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1456 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
1458 for (cur = toolbar_list; cur != NULL; cur = cur->next) {
1460 if (g_ascii_strcasecmp(((ToolbarItem*)cur->data)->file, TOOLBAR_TAG_SEPARATOR) == 0) {
1461 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
1465 toolbar_item = g_new0(ToolbarItem, 1);
1466 toolbar_item->index = ((ToolbarItem*)cur->data)->index;
1467 toolbar_item->file = g_strdup(((ToolbarItem*)cur->data)->file);
1468 toolbar_item->text = g_strdup(((ToolbarItem*)cur->data)->text);
1469 toolbar_item->parent = data;
1470 toolbar_item->type = type;
1472 /* collect toolbar items in list to keep track */
1473 toolbar_data->item_list =
1474 g_slist_append(toolbar_data->item_list,
1476 icon_wid = stock_pixmap_widget(container, stock_pixmap_get_icon(toolbar_item->file));
1477 item = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1481 icon_wid, G_CALLBACK(toolbar_buttons_cb),
1484 switch (toolbar_item->index) {
1487 toolbar_data->getall_btn = item;
1488 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1489 toolbar_data->getall_btn,
1490 _("Receive Mail on all Accounts"), NULL);
1491 getall_combo = gtkut_combo_button_create(toolbar_data->getall_btn, NULL, 0,
1492 "<GetAll>", (gpointer)toolbar_item);
1493 gtk_button_set_relief(GTK_BUTTON(getall_combo->arrow),
1495 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1496 GTK_WIDGET_PTR(getall_combo),
1497 _("Receive Mail on selected Account"), "Reply");
1498 toolbar_data->getall_combo = getall_combo;
1501 toolbar_data->get_btn = item;
1502 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1503 toolbar_data->get_btn,
1504 _("Receive Mail on current Account"), NULL);
1507 toolbar_data->send_btn = item;
1508 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1509 toolbar_data->send_btn,
1510 _("Send Queued Messages"), NULL);
1512 case A_COMPOSE_EMAIL:
1513 icon_news = stock_pixmap_widget(container, STOCK_PIXMAP_NEWS_COMPOSE);
1514 item_news = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1518 icon_news, G_CALLBACK(toolbar_buttons_cb),
1520 toolbar_data->compose_mail_btn = item;
1521 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1522 toolbar_data->compose_mail_btn,
1523 _("Compose Email"), NULL);
1524 toolbar_data->compose_news_btn = item_news;
1525 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1526 toolbar_data->compose_news_btn,
1527 _("Compose News"), NULL);
1530 icon_ham = stock_pixmap_widget(container, STOCK_PIXMAP_HAM_BTN);
1531 item_ham = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1535 icon_ham, G_CALLBACK(toolbar_buttons_cb),
1537 toolbar_data->learn_spam_btn = item;
1538 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1539 toolbar_data->learn_spam_btn,
1540 _("Learn Spam"), NULL);
1541 toolbar_data->learn_ham_btn = item_ham;
1542 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1543 toolbar_data->learn_ham_btn,
1544 _("Learn Ham"), NULL);
1546 case A_REPLY_MESSAGE:
1547 toolbar_data->reply_btn = item;
1548 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1549 toolbar_data->reply_btn,
1550 _("Reply to Message"), NULL);
1551 n_menu_entries = sizeof(reply_entries) /
1552 sizeof(reply_entries[0]);
1553 reply_combo = gtkut_combo_button_create(toolbar_data->reply_btn,
1554 reply_entries, n_menu_entries,
1555 "<Reply>", (gpointer)toolbar_item);
1556 gtk_button_set_relief(GTK_BUTTON(reply_combo->arrow),
1558 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1559 GTK_WIDGET_PTR(reply_combo),
1560 _("Reply to Message"), "Reply");
1561 toolbar_data->reply_combo = reply_combo;
1563 case A_REPLY_SENDER:
1564 toolbar_data->replysender_btn = item;
1565 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1566 toolbar_data->replysender_btn,
1567 _("Reply to Sender"), NULL);
1568 n_menu_entries = sizeof(replysender_entries) /
1569 sizeof(replysender_entries[0]);
1570 replysender_combo = gtkut_combo_button_create(toolbar_data->replysender_btn,
1571 replysender_entries, n_menu_entries,
1572 "<ReplySender>", (gpointer)toolbar_item);
1573 gtk_button_set_relief(GTK_BUTTON(replysender_combo->arrow),
1575 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1576 GTK_WIDGET_PTR(replysender_combo),
1577 _("Reply to Sender"), "ReplySender");
1578 toolbar_data->replysender_combo = replysender_combo;
1581 toolbar_data->replyall_btn = item;
1582 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1583 toolbar_data->replyall_btn,
1584 _("Reply to All"), NULL);
1585 n_menu_entries = sizeof(replyall_entries) /
1586 sizeof(replyall_entries[0]);
1587 replyall_combo = gtkut_combo_button_create(toolbar_data->replyall_btn,
1588 replyall_entries, n_menu_entries,
1589 "<ReplyAll>", (gpointer)toolbar_item);
1590 gtk_button_set_relief(GTK_BUTTON(replyall_combo->arrow),
1592 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1593 GTK_WIDGET_PTR(replyall_combo),
1594 _("Reply to All"), "ReplyAll");
1595 toolbar_data->replyall_combo = replyall_combo;
1598 toolbar_data->replylist_btn = item;
1599 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1600 toolbar_data->replylist_btn,
1601 _("Reply to Mailing-list"), NULL);
1602 n_menu_entries = sizeof(replylist_entries) /
1603 sizeof(replylist_entries[0]);
1604 replylist_combo = gtkut_combo_button_create(toolbar_data->replylist_btn,
1605 replylist_entries, n_menu_entries,
1606 "<ReplyList>", (gpointer)toolbar_item);
1607 gtk_button_set_relief(GTK_BUTTON(replylist_combo->arrow),
1609 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1610 GTK_WIDGET_PTR(replylist_combo),
1611 _("Reply to Mailing-list"), "ReplyList");
1612 toolbar_data->replylist_combo = replylist_combo;
1615 toolbar_data->fwd_btn = item;
1616 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1617 toolbar_data->fwd_btn,
1618 _("Forward Message"), NULL);
1619 n_menu_entries = sizeof(forward_entries) /
1620 sizeof(forward_entries[0]);
1621 fwd_combo = gtkut_combo_button_create(toolbar_data->fwd_btn,
1622 forward_entries, n_menu_entries,
1623 "<Forward>", (gpointer)toolbar_item);
1624 gtk_button_set_relief(GTK_BUTTON(fwd_combo->arrow),
1626 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1627 GTK_WIDGET_PTR(fwd_combo),
1628 _("Forward Message"), "Fwd");
1629 toolbar_data->fwd_combo = fwd_combo;
1632 toolbar_data->trash_btn = item;
1633 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1634 toolbar_data->trash_btn,
1635 _("Trash Message"), NULL);
1638 toolbar_data->delete_btn = item;
1639 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1640 toolbar_data->delete_btn,
1641 _("Delete Message"), NULL);
1644 toolbar_data->exec_btn = item;
1645 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1646 toolbar_data->exec_btn,
1647 _("Execute"), NULL);
1650 toolbar_data->prev_btn = item;
1651 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1652 toolbar_data->prev_btn,
1653 _("Go to Previous Unread Message"),
1657 toolbar_data->next_btn = item;
1658 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1659 toolbar_data->next_btn,
1660 _("Go to Next Unread Message"),
1664 /* Compose Toolbar */
1666 toolbar_data->send_btn = item;
1667 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1668 toolbar_data->send_btn,
1669 _("Send Message"), NULL);
1672 toolbar_data->sendl_btn = item;
1673 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1674 toolbar_data->sendl_btn,
1675 _("Put into queue folder and send later"), NULL);
1678 toolbar_data->draft_btn = item;
1679 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1680 toolbar_data->draft_btn,
1681 _("Save to draft folder"), NULL);
1684 toolbar_data->insert_btn = item;
1685 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1686 toolbar_data->insert_btn,
1687 _("Insert file"), NULL);
1690 toolbar_data->attach_btn = item;
1691 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1692 toolbar_data->attach_btn,
1693 _("Attach file"), NULL);
1696 toolbar_data->sig_btn = item;
1697 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1698 toolbar_data->sig_btn,
1699 _("Insert signature"), NULL);
1702 toolbar_data->exteditor_btn = item;
1703 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1704 toolbar_data->exteditor_btn,
1705 _("Edit with external editor"), NULL);
1707 case A_LINEWRAP_CURRENT:
1708 toolbar_data->linewrap_current_btn = item;
1709 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1710 toolbar_data->linewrap_current_btn,
1711 _("Wrap long lines of current paragraph"), NULL);
1713 case A_LINEWRAP_ALL:
1714 toolbar_data->linewrap_all_btn = item;
1715 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1716 toolbar_data->linewrap_all_btn,
1717 _("Wrap all long lines"), NULL);
1720 toolbar_data->addrbook_btn = item;
1721 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1722 toolbar_data->addrbook_btn,
1723 _("Address book"), NULL);
1726 case A_CHECK_SPELLING:
1727 toolbar_data->spellcheck_btn = item;
1728 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1729 toolbar_data->spellcheck_btn,
1730 _("Check spelling"), NULL);
1735 action_item = g_new0(ToolbarSylpheedActions, 1);
1736 action_item->widget = item;
1737 action_item->name = g_strdup(toolbar_item->text);
1739 toolbar_data->action_list =
1740 g_slist_append(toolbar_data->action_list,
1743 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1745 action_item->name, NULL);
1747 gtk_widget_show(item);
1750 /* find and set the tool tip text */
1751 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1753 toolbar_ret_descr_from_val
1754 (toolbar_item->index),
1760 toolbar_data->toolbar = toolbar;
1761 if (type == TOOLBAR_MAIN)
1762 activate_compose_button(toolbar_data,
1763 prefs_common.toolbar_style,
1764 toolbar_data->compose_btn_type);
1765 if (type != TOOLBAR_COMPOSE)
1766 activate_learn_button(toolbar_data, prefs_common.toolbar_style,
1769 gtk_widget_show_all(toolbar);
1771 return toolbar_data;
1775 * Free toolbar structures
1777 void toolbar_destroy(Toolbar * toolbar) {
1779 TOOLBAR_DESTROY_ITEMS(toolbar->item_list);
1780 TOOLBAR_DESTROY_ACTIONS(toolbar->action_list);
1783 void toolbar_update(ToolbarType type, gpointer data)
1785 Toolbar *toolbar_data;
1786 GtkWidget *handlebox;
1787 MainWindow *mainwin = (MainWindow*)data;
1788 Compose *compose = (Compose*)data;
1789 MessageView *msgview = (MessageView*)data;
1793 toolbar_data = mainwin->toolbar;
1794 handlebox = mainwin->handlebox;
1796 case TOOLBAR_COMPOSE:
1797 toolbar_data = compose->toolbar;
1798 handlebox = compose->handlebox;
1800 case TOOLBAR_MSGVIEW:
1801 toolbar_data = msgview->toolbar;
1802 handlebox = msgview->handlebox;
1808 gtk_container_remove(GTK_CONTAINER(handlebox),
1809 GTK_WIDGET(toolbar_data->toolbar));
1811 toolbar_init(toolbar_data);
1812 toolbar_data = toolbar_create(type, handlebox, data);
1815 mainwin->toolbar = toolbar_data;
1817 case TOOLBAR_COMPOSE:
1818 compose->toolbar = toolbar_data;
1820 case TOOLBAR_MSGVIEW:
1821 msgview->toolbar = toolbar_data;
1825 toolbar_style(type, prefs_common.toolbar_style, data);
1827 if (type == TOOLBAR_MAIN) {
1828 toolbar_main_set_sensitive((MainWindow*)data);
1829 account_set_menu_only_toolbar();
1833 void toolbar_main_set_sensitive(gpointer data)
1835 SensitiveCond state;
1837 MainWindow *mainwin = (MainWindow*)data;
1838 Toolbar *toolbar = mainwin->toolbar;
1840 GSList *entry_list = NULL;
1842 typedef struct _Entry Entry;
1849 #define SET_WIDGET_COND(w, c) \
1851 Entry *e = g_new0(Entry, 1); \
1854 entry_list = g_slist_append(entry_list, e); \
1857 SET_WIDGET_COND(toolbar->get_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1858 SET_WIDGET_COND(toolbar->getall_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1859 if (toolbar->getall_btn)
1860 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->getall_combo),
1861 M_HAVE_ACCOUNT|M_UNLOCKED);
1862 SET_WIDGET_COND(toolbar->compose_news_btn, M_HAVE_ACCOUNT);
1863 SET_WIDGET_COND(toolbar->reply_btn,
1864 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1865 if (toolbar->reply_btn)
1866 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->reply_combo),
1867 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1868 SET_WIDGET_COND(toolbar->replyall_btn,
1869 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1870 if (toolbar->replyall_btn)
1871 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replyall_combo),
1872 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1873 SET_WIDGET_COND(toolbar->replylist_btn,
1874 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1875 if (toolbar->replylist_btn)
1876 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replylist_combo),
1877 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1878 SET_WIDGET_COND(toolbar->replysender_btn,
1879 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1880 if (toolbar->replysender_btn)
1881 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replysender_combo),
1882 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1883 SET_WIDGET_COND(toolbar->fwd_btn, M_HAVE_ACCOUNT|M_TARGET_EXIST);
1884 if (toolbar->fwd_btn)
1885 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->fwd_combo),
1886 M_HAVE_ACCOUNT|M_TARGET_EXIST);
1887 if (toolbar->fwd_combo) {
1888 GtkWidget *submenu = gtk_item_factory_get_widget(toolbar->fwd_combo->factory, "/Redirect");
1889 SET_WIDGET_COND(submenu, M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1892 if (prefs_common.next_unread_msg_dialog == NEXTUNREADMSGDIALOG_ASSUME_NO) {
1893 SET_WIDGET_COND(toolbar->next_btn, M_MSG_EXIST);
1895 SET_WIDGET_COND(toolbar->next_btn, 0);
1898 if (toolbar->trash_btn)
1899 SET_WIDGET_COND(toolbar->trash_btn,
1900 M_TARGET_EXIST|M_ALLOW_DELETE);
1901 if (toolbar->delete_btn)
1902 SET_WIDGET_COND(toolbar->delete_btn,
1903 M_TARGET_EXIST|M_ALLOW_DELETE);
1904 if (toolbar->exec_btn)
1905 SET_WIDGET_COND(toolbar->exec_btn, M_DELAY_EXEC);
1907 if (toolbar->learn_ham_btn)
1908 SET_WIDGET_COND(toolbar->learn_ham_btn, M_TARGET_EXIST|M_CAN_LEARN_SPAM);
1909 if (toolbar->learn_spam_btn)
1910 SET_WIDGET_COND(toolbar->learn_spam_btn, M_TARGET_EXIST|M_CAN_LEARN_SPAM);
1912 for (cur = toolbar->action_list; cur != NULL; cur = cur->next) {
1913 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
1915 SET_WIDGET_COND(act->widget, M_TARGET_EXIST|M_UNLOCKED);
1918 #undef SET_WIDGET_COND
1920 state = main_window_get_current_state(mainwin);
1922 for (cur = entry_list; cur != NULL; cur = cur->next) {
1923 Entry *e = (Entry*) cur->data;
1925 if (e->widget != NULL) {
1926 sensitive = ((e->cond & state) == e->cond);
1927 gtk_widget_set_sensitive(e->widget, sensitive);
1931 while (entry_list != NULL) {
1932 Entry *e = (Entry*) entry_list->data;
1936 entry_list = g_slist_remove(entry_list, e);
1939 g_slist_free(entry_list);
1941 activate_compose_button(toolbar,
1942 prefs_common.toolbar_style,
1943 toolbar->compose_btn_type);
1946 void toolbar_comp_set_sensitive(gpointer data, gboolean sensitive)
1948 Compose *compose = (Compose*)data;
1949 GSList *items = compose->toolbar->action_list;
1951 if (compose->toolbar->send_btn)
1952 gtk_widget_set_sensitive(compose->toolbar->send_btn, sensitive);
1953 if (compose->toolbar->sendl_btn)
1954 gtk_widget_set_sensitive(compose->toolbar->sendl_btn, sensitive);
1955 if (compose->toolbar->draft_btn )
1956 gtk_widget_set_sensitive(compose->toolbar->draft_btn , sensitive);
1957 if (compose->toolbar->insert_btn )
1958 gtk_widget_set_sensitive(compose->toolbar->insert_btn , sensitive);
1959 if (compose->toolbar->attach_btn)
1960 gtk_widget_set_sensitive(compose->toolbar->attach_btn, sensitive);
1961 if (compose->toolbar->sig_btn)
1962 gtk_widget_set_sensitive(compose->toolbar->sig_btn, sensitive);
1963 if (compose->toolbar->exteditor_btn)
1964 gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, sensitive);
1965 if (compose->toolbar->linewrap_current_btn)
1966 gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, sensitive);
1967 if (compose->toolbar->linewrap_all_btn)
1968 gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, sensitive);
1969 if (compose->toolbar->addrbook_btn)
1970 gtk_widget_set_sensitive(compose->toolbar->addrbook_btn, sensitive);
1972 if (compose->toolbar->spellcheck_btn)
1973 gtk_widget_set_sensitive(compose->toolbar->spellcheck_btn, sensitive);
1975 for (; items != NULL; items = g_slist_next(items)) {
1976 ToolbarSylpheedActions *item = (ToolbarSylpheedActions *)items->data;
1977 gtk_widget_set_sensitive(item->widget, sensitive);
1982 * Initialize toolbar structure
1984 void toolbar_init(Toolbar * toolbar) {
1986 toolbar->toolbar = NULL;
1987 toolbar->get_btn = NULL;
1988 toolbar->getall_btn = NULL;
1989 toolbar->getall_combo = NULL;
1990 toolbar->send_btn = NULL;
1991 toolbar->compose_mail_btn = NULL;
1992 toolbar->compose_news_btn = NULL;
1993 toolbar->reply_btn = NULL;
1994 toolbar->replysender_btn = NULL;
1995 toolbar->replyall_btn = NULL;
1996 toolbar->replylist_btn = NULL;
1997 toolbar->fwd_btn = NULL;
1998 toolbar->trash_btn = NULL;
1999 toolbar->delete_btn = NULL;
2000 toolbar->prev_btn = NULL;
2001 toolbar->next_btn = NULL;
2002 toolbar->exec_btn = NULL;
2004 /* compose buttons */
2005 toolbar->sendl_btn = NULL;
2006 toolbar->draft_btn = NULL;
2007 toolbar->insert_btn = NULL;
2008 toolbar->attach_btn = NULL;
2009 toolbar->sig_btn = NULL;
2010 toolbar->exteditor_btn = NULL;
2011 toolbar->linewrap_current_btn = NULL;
2012 toolbar->linewrap_all_btn = NULL;
2013 toolbar->addrbook_btn = NULL;
2015 toolbar->spellcheck_btn = NULL;
2018 toolbar_destroy(toolbar);
2023 static void toolbar_reply(gpointer data, guint action)
2025 ToolbarItem *toolbar_item = (ToolbarItem*)data;
2026 MainWindow *mainwin;
2027 MessageView *msgview;
2028 GSList *msginfo_list = NULL;
2030 g_return_if_fail(toolbar_item != NULL);
2032 switch (toolbar_item->type) {
2034 mainwin = (MainWindow*)toolbar_item->parent;
2035 msginfo_list = summary_get_selection(mainwin->summaryview);
2036 msgview = (MessageView*)mainwin->messageview;
2038 case TOOLBAR_MSGVIEW:
2039 msgview = (MessageView*)toolbar_item->parent;
2040 g_return_if_fail(msgview != NULL);
2041 msginfo_list = g_slist_append(msginfo_list, msgview->msginfo);
2047 g_return_if_fail(msgview != NULL);
2048 g_return_if_fail(msginfo_list != NULL);
2049 compose_reply_from_messageview(msgview, msginfo_list, action);
2050 g_slist_free(msginfo_list);
2052 /* TODO: update reply state ion summaryview */
2056 /* exported functions */
2058 void inc_mail_cb(gpointer data, guint action, GtkWidget *widget)
2060 MainWindow *mainwin = (MainWindow*)data;
2062 inc_mail(mainwin, prefs_common.newmail_notify_manu);
2065 void inc_all_account_mail_cb(gpointer data, guint action, GtkWidget *widget)
2067 MainWindow *mainwin = (MainWindow*)data;
2069 inc_all_account_mail(mainwin, FALSE, prefs_common.newmail_notify_manu);
2072 void send_queue_cb(gpointer data, guint action, GtkWidget *widget)
2077 if (prefs_common.work_offline)
2078 if (alertpanel(_("Offline warning"),
2079 _("You're working offline. Override?"),
2080 GTK_STOCK_NO, GTK_STOCK_YES,
2081 NULL) != G_ALERTALTERNATE)
2084 /* ask for confirmation before sending queued messages only
2085 in online mode and if there is at least one message queued
2086 in any of the folder queue
2088 if (prefs_common.confirm_send_queued_messages) {
2090 /* check if there's a queued message */
2091 for (list = folder_get_list(); !found && list != NULL; list = list->next) {
2092 Folder *folder = list->data;
2094 found = !procmsg_queue_is_empty(folder->queue);
2096 /* if necessary, ask for confirmation before sending */
2097 if (found && !prefs_common.work_offline) {
2098 if (alertpanel(_("Send queued messages"),
2099 _("Send all queued messages?"),
2100 GTK_STOCK_CANCEL, _("_Send"),
2101 NULL) != G_ALERTALTERNATE)
2106 for (list = folder_get_list(); list != NULL; list = list->next) {
2107 Folder *folder = list->data;
2109 if (folder->queue) {
2110 if (procmsg_send_queue(folder->queue,
2111 prefs_common.savemsg) < 0)
2112 alertpanel_error(_("Some errors occurred while "
2113 "sending queued messages."));
2118 void compose_mail_cb(gpointer data, guint action, GtkWidget *widget)
2120 MainWindow *mainwin = (MainWindow*)data;
2121 PrefsAccount *ac = NULL;
2122 FolderItem *item = mainwin->summaryview->folder_item;
2127 ac = account_find_from_item(item);
2128 if (ac && ac->protocol != A_NNTP) {
2129 compose_new_with_folderitem(ac, item); /* CLAWS */
2135 * CLAWS - use current account
2137 if (cur_account && (cur_account->protocol != A_NNTP)) {
2138 compose_new_with_folderitem(cur_account, item);
2143 * CLAWS - just get the first one
2145 list = account_get_list();
2146 for (cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2147 ac = (PrefsAccount *) cur->data;
2148 if (ac->protocol != A_NNTP) {
2149 compose_new_with_folderitem(ac, item);
2155 void compose_news_cb(gpointer data, guint action, GtkWidget *widget)
2157 MainWindow *mainwin = (MainWindow*)data;
2158 PrefsAccount * ac = NULL;
2162 if (mainwin->summaryview->folder_item) {
2163 ac = mainwin->summaryview->folder_item->folder->account;
2164 if (ac && ac->protocol == A_NNTP) {
2165 compose_new_with_folderitem(ac,
2166 mainwin->summaryview->folder_item);
2171 list = account_get_list();
2172 for(cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2173 ac = (PrefsAccount *) cur->data;
2174 if (ac->protocol == A_NNTP) {
2175 compose_new_with_folderitem(ac,
2176 mainwin->summaryview->folder_item);