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 summary_select_prev_unread(msgview->mainwin->summaryview);
1133 /* Now we need to update the messageview window */
1134 if (msgview->mainwin->summaryview->selected) {
1135 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1137 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1138 msgview->mainwin->summaryview->selected);
1140 messageview_show(msgview, msginfo,
1141 msgview->all_headers);
1143 gtk_widget_destroy(msgview->window);
1147 debug_print("toolbar event not supported\n");
1152 * Goto Next Unread Message
1154 static void toolbar_next_unread_cb(GtkWidget *widget, gpointer data)
1156 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1157 MainWindow *mainwin;
1158 MessageView *msgview;
1160 g_return_if_fail(toolbar_item != NULL);
1162 switch (toolbar_item->type) {
1164 mainwin = (MainWindow*)toolbar_item->parent;
1165 summary_select_next_unread(mainwin->summaryview);
1168 case TOOLBAR_MSGVIEW:
1169 msgview = (MessageView*)toolbar_item->parent;
1170 summary_select_next_unread(msgview->mainwin->summaryview);
1172 /* Now we need to update the messageview window */
1173 if (msgview->mainwin->summaryview->selected) {
1174 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1176 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1177 msgview->mainwin->summaryview->selected);
1179 messageview_show(msgview, msginfo,
1180 msgview->all_headers);
1182 gtk_widget_destroy(msgview->window);
1186 debug_print("toolbar event not supported\n");
1190 static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data)
1192 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1193 MainWindow *mainwin;
1195 g_return_if_fail(toolbar_item != NULL);
1197 switch (toolbar_item->type) {
1199 mainwin = (MainWindow *) toolbar_item->parent;
1200 summary_toggle_ignore_thread(mainwin->summaryview);
1202 case TOOLBAR_MSGVIEW:
1203 /* TODO: see toolbar_next_unread_cb() if you need
1204 * this in the message view */
1207 debug_print("toolbar event not supported\n");
1212 static void toolbar_print_cb(GtkWidget *widget, gpointer data)
1214 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1215 MainWindow *mainwin;
1217 g_return_if_fail(toolbar_item != NULL);
1219 switch (toolbar_item->type) {
1221 mainwin = (MainWindow *) toolbar_item->parent;
1222 summary_print(mainwin->summaryview);
1224 case TOOLBAR_MSGVIEW:
1225 /* TODO: see toolbar_next_unread_cb() if you need
1226 * this in the message view */
1229 debug_print("toolbar event not supported\n");
1234 static void toolbar_send_cb(GtkWidget *widget, gpointer data)
1236 compose_toolbar_cb(A_SEND, data);
1239 static void toolbar_send_later_cb(GtkWidget *widget, gpointer data)
1241 compose_toolbar_cb(A_SENDL, data);
1244 static void toolbar_draft_cb(GtkWidget *widget, gpointer data)
1246 compose_toolbar_cb(A_DRAFT, data);
1249 static void toolbar_insert_cb(GtkWidget *widget, gpointer data)
1251 compose_toolbar_cb(A_INSERT, data);
1254 static void toolbar_attach_cb(GtkWidget *widget, gpointer data)
1256 compose_toolbar_cb(A_ATTACH, data);
1259 static void toolbar_sig_cb(GtkWidget *widget, gpointer data)
1261 compose_toolbar_cb(A_SIG, data);
1264 static void toolbar_ext_editor_cb(GtkWidget *widget, gpointer data)
1266 compose_toolbar_cb(A_EXTEDITOR, data);
1269 static void toolbar_linewrap_current_cb(GtkWidget *widget, gpointer data)
1271 compose_toolbar_cb(A_LINEWRAP_CURRENT, data);
1274 static void toolbar_linewrap_all_cb(GtkWidget *widget, gpointer data)
1276 compose_toolbar_cb(A_LINEWRAP_ALL, data);
1280 static void toolbar_check_spelling_cb(GtkWidget *widget, gpointer data)
1282 compose_toolbar_cb(A_CHECK_SPELLING, data);
1286 * Execute actions from toolbar
1288 static void toolbar_actions_execute_cb(GtkWidget *widget, gpointer data)
1290 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1291 GSList *action_list;
1292 MainWindow *mainwin;
1294 MessageView *msgview;
1295 gpointer parent = toolbar_item->parent;
1297 g_return_if_fail(toolbar_item != NULL);
1299 switch (toolbar_item->type) {
1301 mainwin = (MainWindow*)parent;
1302 action_list = mainwin->toolbar->action_list;
1304 case TOOLBAR_COMPOSE:
1305 compose = (Compose*)parent;
1306 action_list = compose->toolbar->action_list;
1308 case TOOLBAR_MSGVIEW:
1309 msgview = (MessageView*)parent;
1310 action_list = msgview->toolbar->action_list;
1313 debug_print("toolbar event not supported\n");
1316 toolbar_action_execute(widget, action_list, parent, toolbar_item->type);
1319 static MainWindow *get_mainwin(gpointer data)
1321 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1322 MainWindow *mainwin = NULL;
1323 MessageView *msgview;
1325 g_return_val_if_fail(toolbar_item != NULL, NULL);
1327 switch(toolbar_item->type) {
1329 mainwin = (MainWindow*)toolbar_item->parent;
1331 case TOOLBAR_MSGVIEW:
1332 msgview = (MessageView*)toolbar_item->parent;
1333 mainwin = (MainWindow*)msgview->mainwin;
1342 static void toolbar_buttons_cb(GtkWidget *widget,
1349 void (*func)(GtkWidget *widget, gpointer data);
1351 { A_RECEIVE_ALL, toolbar_inc_all_cb },
1352 { A_RECEIVE_CUR, toolbar_inc_cb },
1353 { A_SEND_QUEUED, toolbar_send_queued_cb },
1354 { A_COMPOSE_EMAIL, toolbar_compose_cb },
1355 { A_COMPOSE_NEWS, toolbar_compose_cb },
1356 { A_REPLY_MESSAGE, toolbar_reply_cb },
1357 { A_REPLY_SENDER, toolbar_reply_to_sender_cb },
1358 { A_REPLY_ALL, toolbar_reply_to_all_cb },
1359 { A_REPLY_ML, toolbar_reply_to_list_cb },
1360 { A_FORWARD, toolbar_forward_cb },
1361 { A_TRASH, toolbar_trash_cb },
1362 { A_DELETE_REAL, toolbar_delete_cb },
1363 { A_EXECUTE, toolbar_exec_cb },
1364 { A_GOTO_PREV, toolbar_prev_unread_cb },
1365 { A_GOTO_NEXT, toolbar_next_unread_cb },
1366 { A_IGNORE_THREAD, toolbar_ignore_thread_cb },
1367 { A_PRINT, toolbar_print_cb },
1368 { A_LEARN_SPAM, toolbar_learn_cb },
1370 { A_SEND, toolbar_send_cb },
1371 { A_SENDL, toolbar_send_later_cb },
1372 { A_DRAFT, toolbar_draft_cb },
1373 { A_INSERT, toolbar_insert_cb },
1374 { A_ATTACH, toolbar_attach_cb },
1375 { A_SIG, toolbar_sig_cb },
1376 { A_EXTEDITOR, toolbar_ext_editor_cb },
1377 { A_LINEWRAP_CURRENT, toolbar_linewrap_current_cb },
1378 { A_LINEWRAP_ALL, toolbar_linewrap_all_cb },
1379 { A_ADDRBOOK, toolbar_addrbook_cb },
1381 { A_CHECK_SPELLING, toolbar_check_spelling_cb },
1383 { A_SYL_ACTIONS, toolbar_actions_execute_cb }
1386 num_items = sizeof(callbacks)/sizeof(callbacks[0]);
1388 for (i = 0; i < num_items; i++) {
1389 if (callbacks[i].index == item->index) {
1390 callbacks[i].func(widget, item);
1397 * Create a new toolbar with specified type
1398 * if a callback list is passed it will be used before the
1399 * common callback list
1401 Toolbar *toolbar_create(ToolbarType type,
1402 GtkWidget *container,
1405 ToolbarItem *toolbar_item;
1408 GtkWidget *icon_wid = NULL;
1409 GtkWidget *icon_news;
1410 GtkWidget *icon_ham;
1412 GtkWidget *item_news;
1413 GtkWidget *item_ham;
1414 guint n_menu_entries;
1415 ComboButton *getall_combo;
1416 ComboButton *reply_combo;
1417 ComboButton *replyall_combo;
1418 ComboButton *replylist_combo;
1419 ComboButton *replysender_combo;
1420 ComboButton *fwd_combo;
1422 GtkTooltips *toolbar_tips;
1423 ToolbarSylpheedActions *action_item;
1425 GSList *toolbar_list;
1426 Toolbar *toolbar_data;
1429 toolbar_tips = gtk_tooltips_new();
1431 toolbar_read_config_file(type);
1432 toolbar_list = toolbar_get_list(type);
1434 toolbar_data = g_new0(Toolbar, 1);
1436 toolbar = gtk_toolbar_new();
1437 gtk_container_add(GTK_CONTAINER(container), toolbar);
1438 gtk_container_set_border_width(GTK_CONTAINER(container), 2);
1439 gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1440 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
1442 for (cur = toolbar_list; cur != NULL; cur = cur->next) {
1444 if (g_ascii_strcasecmp(((ToolbarItem*)cur->data)->file, TOOLBAR_TAG_SEPARATOR) == 0) {
1445 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
1449 toolbar_item = g_new0(ToolbarItem, 1);
1450 toolbar_item->index = ((ToolbarItem*)cur->data)->index;
1451 toolbar_item->file = g_strdup(((ToolbarItem*)cur->data)->file);
1452 toolbar_item->text = g_strdup(((ToolbarItem*)cur->data)->text);
1453 toolbar_item->parent = data;
1454 toolbar_item->type = type;
1456 /* collect toolbar items in list to keep track */
1457 toolbar_data->item_list =
1458 g_slist_append(toolbar_data->item_list,
1460 icon_wid = stock_pixmap_widget(container, stock_pixmap_get_icon(toolbar_item->file));
1461 item = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1465 icon_wid, G_CALLBACK(toolbar_buttons_cb),
1468 switch (toolbar_item->index) {
1471 toolbar_data->getall_btn = item;
1472 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1473 toolbar_data->getall_btn,
1474 _("Receive Mail on all Accounts"), NULL);
1475 getall_combo = gtkut_combo_button_create(toolbar_data->getall_btn, NULL, 0,
1476 "<GetAll>", (gpointer)toolbar_item);
1477 gtk_button_set_relief(GTK_BUTTON(getall_combo->arrow),
1479 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1480 GTK_WIDGET_PTR(getall_combo),
1481 _("Receive Mail on selected Account"), "Reply");
1482 toolbar_data->getall_combo = getall_combo;
1485 toolbar_data->get_btn = item;
1486 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1487 toolbar_data->get_btn,
1488 _("Receive Mail on current Account"), NULL);
1491 toolbar_data->send_btn = item;
1492 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1493 toolbar_data->send_btn,
1494 _("Send Queued Messages"), NULL);
1496 case A_COMPOSE_EMAIL:
1497 icon_news = stock_pixmap_widget(container, STOCK_PIXMAP_NEWS_COMPOSE);
1498 item_news = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1502 icon_news, G_CALLBACK(toolbar_buttons_cb),
1504 toolbar_data->compose_mail_btn = item;
1505 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1506 toolbar_data->compose_mail_btn,
1507 _("Compose Email"), NULL);
1508 toolbar_data->compose_news_btn = item_news;
1509 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1510 toolbar_data->compose_news_btn,
1511 _("Compose News"), NULL);
1514 icon_ham = stock_pixmap_widget(container, STOCK_PIXMAP_HAM_BTN);
1515 item_ham = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1519 icon_ham, G_CALLBACK(toolbar_buttons_cb),
1521 toolbar_data->learn_spam_btn = item;
1522 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1523 toolbar_data->learn_spam_btn,
1524 _("Learn Spam"), NULL);
1525 toolbar_data->learn_ham_btn = item_ham;
1526 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1527 toolbar_data->learn_ham_btn,
1528 _("Learn Ham"), NULL);
1530 case A_REPLY_MESSAGE:
1531 toolbar_data->reply_btn = item;
1532 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1533 toolbar_data->reply_btn,
1534 _("Reply to Message"), NULL);
1535 n_menu_entries = sizeof(reply_entries) /
1536 sizeof(reply_entries[0]);
1537 reply_combo = gtkut_combo_button_create(toolbar_data->reply_btn,
1538 reply_entries, n_menu_entries,
1539 "<Reply>", (gpointer)toolbar_item);
1540 gtk_button_set_relief(GTK_BUTTON(reply_combo->arrow),
1542 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1543 GTK_WIDGET_PTR(reply_combo),
1544 _("Reply to Message"), "Reply");
1545 toolbar_data->reply_combo = reply_combo;
1547 case A_REPLY_SENDER:
1548 toolbar_data->replysender_btn = item;
1549 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1550 toolbar_data->replysender_btn,
1551 _("Reply to Sender"), NULL);
1552 n_menu_entries = sizeof(replysender_entries) /
1553 sizeof(replysender_entries[0]);
1554 replysender_combo = gtkut_combo_button_create(toolbar_data->replysender_btn,
1555 replysender_entries, n_menu_entries,
1556 "<ReplySender>", (gpointer)toolbar_item);
1557 gtk_button_set_relief(GTK_BUTTON(replysender_combo->arrow),
1559 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1560 GTK_WIDGET_PTR(replysender_combo),
1561 _("Reply to Sender"), "ReplySender");
1562 toolbar_data->replysender_combo = replysender_combo;
1565 toolbar_data->replyall_btn = item;
1566 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1567 toolbar_data->replyall_btn,
1568 _("Reply to All"), NULL);
1569 n_menu_entries = sizeof(replyall_entries) /
1570 sizeof(replyall_entries[0]);
1571 replyall_combo = gtkut_combo_button_create(toolbar_data->replyall_btn,
1572 replyall_entries, n_menu_entries,
1573 "<ReplyAll>", (gpointer)toolbar_item);
1574 gtk_button_set_relief(GTK_BUTTON(replyall_combo->arrow),
1576 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1577 GTK_WIDGET_PTR(replyall_combo),
1578 _("Reply to All"), "ReplyAll");
1579 toolbar_data->replyall_combo = replyall_combo;
1582 toolbar_data->replylist_btn = item;
1583 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1584 toolbar_data->replylist_btn,
1585 _("Reply to Mailing-list"), NULL);
1586 n_menu_entries = sizeof(replylist_entries) /
1587 sizeof(replylist_entries[0]);
1588 replylist_combo = gtkut_combo_button_create(toolbar_data->replylist_btn,
1589 replylist_entries, n_menu_entries,
1590 "<ReplyList>", (gpointer)toolbar_item);
1591 gtk_button_set_relief(GTK_BUTTON(replylist_combo->arrow),
1593 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1594 GTK_WIDGET_PTR(replylist_combo),
1595 _("Reply to Mailing-list"), "ReplyList");
1596 toolbar_data->replylist_combo = replylist_combo;
1599 toolbar_data->fwd_btn = item;
1600 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1601 toolbar_data->fwd_btn,
1602 _("Forward Message"), NULL);
1603 n_menu_entries = sizeof(forward_entries) /
1604 sizeof(forward_entries[0]);
1605 fwd_combo = gtkut_combo_button_create(toolbar_data->fwd_btn,
1606 forward_entries, n_menu_entries,
1607 "<Forward>", (gpointer)toolbar_item);
1608 gtk_button_set_relief(GTK_BUTTON(fwd_combo->arrow),
1610 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1611 GTK_WIDGET_PTR(fwd_combo),
1612 _("Forward Message"), "Fwd");
1613 toolbar_data->fwd_combo = fwd_combo;
1616 toolbar_data->trash_btn = item;
1617 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1618 toolbar_data->trash_btn,
1619 _("Trash Message"), NULL);
1622 toolbar_data->delete_btn = item;
1623 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1624 toolbar_data->delete_btn,
1625 _("Delete Message"), NULL);
1628 toolbar_data->exec_btn = item;
1629 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1630 toolbar_data->exec_btn,
1631 _("Execute"), NULL);
1634 toolbar_data->prev_btn = item;
1635 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1636 toolbar_data->prev_btn,
1637 _("Go to Previous Unread Message"),
1641 toolbar_data->next_btn = item;
1642 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1643 toolbar_data->next_btn,
1644 _("Go to Next Unread Message"),
1648 /* Compose Toolbar */
1650 toolbar_data->send_btn = item;
1651 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1652 toolbar_data->send_btn,
1653 _("Send Message"), NULL);
1656 toolbar_data->sendl_btn = item;
1657 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1658 toolbar_data->sendl_btn,
1659 _("Put into queue folder and send later"), NULL);
1662 toolbar_data->draft_btn = item;
1663 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1664 toolbar_data->draft_btn,
1665 _("Save to draft folder"), NULL);
1668 toolbar_data->insert_btn = item;
1669 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1670 toolbar_data->insert_btn,
1671 _("Insert file"), NULL);
1674 toolbar_data->attach_btn = item;
1675 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1676 toolbar_data->attach_btn,
1677 _("Attach file"), NULL);
1680 toolbar_data->sig_btn = item;
1681 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1682 toolbar_data->sig_btn,
1683 _("Insert signature"), NULL);
1686 toolbar_data->exteditor_btn = item;
1687 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1688 toolbar_data->exteditor_btn,
1689 _("Edit with external editor"), NULL);
1691 case A_LINEWRAP_CURRENT:
1692 toolbar_data->linewrap_current_btn = item;
1693 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1694 toolbar_data->linewrap_current_btn,
1695 _("Wrap long lines of current paragraph"), NULL);
1697 case A_LINEWRAP_ALL:
1698 toolbar_data->linewrap_all_btn = item;
1699 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1700 toolbar_data->linewrap_all_btn,
1701 _("Wrap all long lines"), NULL);
1704 toolbar_data->addrbook_btn = item;
1705 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1706 toolbar_data->addrbook_btn,
1707 _("Address book"), NULL);
1710 case A_CHECK_SPELLING:
1711 toolbar_data->spellcheck_btn = item;
1712 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1713 toolbar_data->spellcheck_btn,
1714 _("Check spelling"), NULL);
1719 action_item = g_new0(ToolbarSylpheedActions, 1);
1720 action_item->widget = item;
1721 action_item->name = g_strdup(toolbar_item->text);
1723 toolbar_data->action_list =
1724 g_slist_append(toolbar_data->action_list,
1727 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1729 action_item->name, NULL);
1731 gtk_widget_show(item);
1734 /* find and set the tool tip text */
1735 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1737 toolbar_ret_descr_from_val
1738 (toolbar_item->index),
1744 toolbar_data->toolbar = toolbar;
1745 if (type == TOOLBAR_MAIN)
1746 activate_compose_button(toolbar_data,
1747 prefs_common.toolbar_style,
1748 toolbar_data->compose_btn_type);
1749 if (type != TOOLBAR_COMPOSE)
1750 activate_learn_button(toolbar_data, prefs_common.toolbar_style,
1753 gtk_widget_show_all(toolbar);
1755 return toolbar_data;
1759 * Free toolbar structures
1761 void toolbar_destroy(Toolbar * toolbar) {
1763 TOOLBAR_DESTROY_ITEMS(toolbar->item_list);
1764 TOOLBAR_DESTROY_ACTIONS(toolbar->action_list);
1767 void toolbar_update(ToolbarType type, gpointer data)
1769 Toolbar *toolbar_data;
1770 GtkWidget *handlebox;
1771 MainWindow *mainwin = (MainWindow*)data;
1772 Compose *compose = (Compose*)data;
1773 MessageView *msgview = (MessageView*)data;
1777 toolbar_data = mainwin->toolbar;
1778 handlebox = mainwin->handlebox;
1780 case TOOLBAR_COMPOSE:
1781 toolbar_data = compose->toolbar;
1782 handlebox = compose->handlebox;
1784 case TOOLBAR_MSGVIEW:
1785 toolbar_data = msgview->toolbar;
1786 handlebox = msgview->handlebox;
1792 gtk_container_remove(GTK_CONTAINER(handlebox),
1793 GTK_WIDGET(toolbar_data->toolbar));
1795 toolbar_init(toolbar_data);
1796 toolbar_data = toolbar_create(type, handlebox, data);
1799 mainwin->toolbar = toolbar_data;
1801 case TOOLBAR_COMPOSE:
1802 compose->toolbar = toolbar_data;
1804 case TOOLBAR_MSGVIEW:
1805 msgview->toolbar = toolbar_data;
1809 toolbar_style(type, prefs_common.toolbar_style, data);
1811 if (type == TOOLBAR_MAIN) {
1812 toolbar_main_set_sensitive((MainWindow*)data);
1813 account_set_menu_only_toolbar();
1817 void toolbar_main_set_sensitive(gpointer data)
1819 SensitiveCond state;
1821 MainWindow *mainwin = (MainWindow*)data;
1822 Toolbar *toolbar = mainwin->toolbar;
1824 GSList *entry_list = NULL;
1826 typedef struct _Entry Entry;
1833 #define SET_WIDGET_COND(w, c) \
1835 Entry *e = g_new0(Entry, 1); \
1838 entry_list = g_slist_append(entry_list, e); \
1841 SET_WIDGET_COND(toolbar->get_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1842 SET_WIDGET_COND(toolbar->getall_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1843 if (toolbar->getall_btn)
1844 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->getall_combo),
1845 M_HAVE_ACCOUNT|M_UNLOCKED);
1846 SET_WIDGET_COND(toolbar->compose_news_btn, M_HAVE_ACCOUNT);
1847 SET_WIDGET_COND(toolbar->reply_btn,
1848 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1849 if (toolbar->reply_btn)
1850 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->reply_combo),
1851 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1852 SET_WIDGET_COND(toolbar->replyall_btn,
1853 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1854 if (toolbar->replyall_btn)
1855 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replyall_combo),
1856 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1857 SET_WIDGET_COND(toolbar->replylist_btn,
1858 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1859 if (toolbar->replylist_btn)
1860 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replylist_combo),
1861 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1862 SET_WIDGET_COND(toolbar->replysender_btn,
1863 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1864 if (toolbar->replysender_btn)
1865 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replysender_combo),
1866 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1867 SET_WIDGET_COND(toolbar->fwd_btn, M_HAVE_ACCOUNT|M_TARGET_EXIST);
1868 if (toolbar->fwd_btn)
1869 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->fwd_combo),
1870 M_HAVE_ACCOUNT|M_TARGET_EXIST);
1871 if (toolbar->fwd_combo) {
1872 GtkWidget *submenu = gtk_item_factory_get_widget(toolbar->fwd_combo->factory, "/Redirect");
1873 SET_WIDGET_COND(submenu, M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1876 if (prefs_common.next_unread_msg_dialog == NEXTUNREADMSGDIALOG_ASSUME_NO) {
1877 SET_WIDGET_COND(toolbar->next_btn, M_MSG_EXIST);
1879 SET_WIDGET_COND(toolbar->next_btn, 0);
1882 if (toolbar->trash_btn)
1883 SET_WIDGET_COND(toolbar->trash_btn,
1884 M_TARGET_EXIST|M_ALLOW_DELETE);
1885 if (toolbar->delete_btn)
1886 SET_WIDGET_COND(toolbar->delete_btn,
1887 M_TARGET_EXIST|M_ALLOW_DELETE);
1888 if (toolbar->exec_btn)
1889 SET_WIDGET_COND(toolbar->exec_btn, M_DELAY_EXEC);
1891 if (toolbar->learn_ham_btn)
1892 SET_WIDGET_COND(toolbar->learn_ham_btn, M_TARGET_EXIST|M_CAN_LEARN_SPAM);
1893 if (toolbar->learn_spam_btn)
1894 SET_WIDGET_COND(toolbar->learn_spam_btn, M_TARGET_EXIST|M_CAN_LEARN_SPAM);
1896 for (cur = toolbar->action_list; cur != NULL; cur = cur->next) {
1897 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
1899 SET_WIDGET_COND(act->widget, M_TARGET_EXIST|M_UNLOCKED);
1902 #undef SET_WIDGET_COND
1904 state = main_window_get_current_state(mainwin);
1906 for (cur = entry_list; cur != NULL; cur = cur->next) {
1907 Entry *e = (Entry*) cur->data;
1909 if (e->widget != NULL) {
1910 sensitive = ((e->cond & state) == e->cond);
1911 gtk_widget_set_sensitive(e->widget, sensitive);
1915 while (entry_list != NULL) {
1916 Entry *e = (Entry*) entry_list->data;
1920 entry_list = g_slist_remove(entry_list, e);
1923 g_slist_free(entry_list);
1925 activate_compose_button(toolbar,
1926 prefs_common.toolbar_style,
1927 toolbar->compose_btn_type);
1930 void toolbar_comp_set_sensitive(gpointer data, gboolean sensitive)
1932 Compose *compose = (Compose*)data;
1933 GSList *items = compose->toolbar->action_list;
1935 if (compose->toolbar->send_btn)
1936 gtk_widget_set_sensitive(compose->toolbar->send_btn, sensitive);
1937 if (compose->toolbar->sendl_btn)
1938 gtk_widget_set_sensitive(compose->toolbar->sendl_btn, sensitive);
1939 if (compose->toolbar->draft_btn )
1940 gtk_widget_set_sensitive(compose->toolbar->draft_btn , sensitive);
1941 if (compose->toolbar->insert_btn )
1942 gtk_widget_set_sensitive(compose->toolbar->insert_btn , sensitive);
1943 if (compose->toolbar->attach_btn)
1944 gtk_widget_set_sensitive(compose->toolbar->attach_btn, sensitive);
1945 if (compose->toolbar->sig_btn)
1946 gtk_widget_set_sensitive(compose->toolbar->sig_btn, sensitive);
1947 if (compose->toolbar->exteditor_btn)
1948 gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, sensitive);
1949 if (compose->toolbar->linewrap_current_btn)
1950 gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, sensitive);
1951 if (compose->toolbar->linewrap_all_btn)
1952 gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, sensitive);
1953 if (compose->toolbar->addrbook_btn)
1954 gtk_widget_set_sensitive(compose->toolbar->addrbook_btn, sensitive);
1956 if (compose->toolbar->spellcheck_btn)
1957 gtk_widget_set_sensitive(compose->toolbar->spellcheck_btn, sensitive);
1959 for (; items != NULL; items = g_slist_next(items)) {
1960 ToolbarSylpheedActions *item = (ToolbarSylpheedActions *)items->data;
1961 gtk_widget_set_sensitive(item->widget, sensitive);
1966 * Initialize toolbar structure
1968 void toolbar_init(Toolbar * toolbar) {
1970 toolbar->toolbar = NULL;
1971 toolbar->get_btn = NULL;
1972 toolbar->getall_btn = NULL;
1973 toolbar->getall_combo = NULL;
1974 toolbar->send_btn = NULL;
1975 toolbar->compose_mail_btn = NULL;
1976 toolbar->compose_news_btn = NULL;
1977 toolbar->reply_btn = NULL;
1978 toolbar->replysender_btn = NULL;
1979 toolbar->replyall_btn = NULL;
1980 toolbar->replylist_btn = NULL;
1981 toolbar->fwd_btn = NULL;
1982 toolbar->trash_btn = NULL;
1983 toolbar->delete_btn = NULL;
1984 toolbar->prev_btn = NULL;
1985 toolbar->next_btn = NULL;
1986 toolbar->exec_btn = NULL;
1988 /* compose buttons */
1989 toolbar->sendl_btn = NULL;
1990 toolbar->draft_btn = NULL;
1991 toolbar->insert_btn = NULL;
1992 toolbar->attach_btn = NULL;
1993 toolbar->sig_btn = NULL;
1994 toolbar->exteditor_btn = NULL;
1995 toolbar->linewrap_current_btn = NULL;
1996 toolbar->linewrap_all_btn = NULL;
1997 toolbar->addrbook_btn = NULL;
1999 toolbar->spellcheck_btn = NULL;
2002 toolbar_destroy(toolbar);
2007 static void toolbar_reply(gpointer data, guint action)
2009 ToolbarItem *toolbar_item = (ToolbarItem*)data;
2010 MainWindow *mainwin;
2011 MessageView *msgview;
2012 GSList *msginfo_list = NULL;
2014 g_return_if_fail(toolbar_item != NULL);
2016 switch (toolbar_item->type) {
2018 mainwin = (MainWindow*)toolbar_item->parent;
2019 msginfo_list = summary_get_selection(mainwin->summaryview);
2020 msgview = (MessageView*)mainwin->messageview;
2022 case TOOLBAR_MSGVIEW:
2023 msgview = (MessageView*)toolbar_item->parent;
2024 g_return_if_fail(msgview != NULL);
2025 msginfo_list = g_slist_append(msginfo_list, msgview->msginfo);
2031 g_return_if_fail(msgview != NULL);
2032 g_return_if_fail(msginfo_list != NULL);
2033 compose_reply_from_messageview(msgview, msginfo_list, action);
2034 g_slist_free(msginfo_list);
2036 /* TODO: update reply state ion summaryview */
2040 /* exported functions */
2042 void inc_mail_cb(gpointer data, guint action, GtkWidget *widget)
2044 MainWindow *mainwin = (MainWindow*)data;
2046 inc_mail(mainwin, prefs_common.newmail_notify_manu);
2049 void inc_all_account_mail_cb(gpointer data, guint action, GtkWidget *widget)
2051 MainWindow *mainwin = (MainWindow*)data;
2053 inc_all_account_mail(mainwin, FALSE, prefs_common.newmail_notify_manu);
2056 void send_queue_cb(gpointer data, guint action, GtkWidget *widget)
2061 if (prefs_common.work_offline)
2062 if (alertpanel(_("Offline warning"),
2063 _("You're working offline. Override?"),
2064 GTK_STOCK_NO, GTK_STOCK_YES,
2065 NULL) != G_ALERTALTERNATE)
2068 /* ask for confirmation before sending queued messages only
2069 in online mode and if there is at least one message queued
2070 in any of the folder queue
2072 if (prefs_common.confirm_send_queued_messages) {
2074 /* check if there's a queued message */
2075 for (list = folder_get_list(); !found && list != NULL; list = list->next) {
2076 Folder *folder = list->data;
2078 found = !procmsg_queue_is_empty(folder->queue);
2080 /* if necessary, ask for confirmation before sending */
2081 if (found && !prefs_common.work_offline) {
2082 if (alertpanel(_("Send queued messages"),
2083 _("Send all queued messages?"),
2084 GTK_STOCK_CANCEL, _("_Send"),
2085 NULL) != G_ALERTALTERNATE)
2090 for (list = folder_get_list(); list != NULL; list = list->next) {
2091 Folder *folder = list->data;
2093 if (folder->queue) {
2094 if (procmsg_send_queue(folder->queue,
2095 prefs_common.savemsg) < 0)
2096 alertpanel_error(_("Some errors occurred while "
2097 "sending queued messages."));
2102 void compose_mail_cb(gpointer data, guint action, GtkWidget *widget)
2104 MainWindow *mainwin = (MainWindow*)data;
2105 PrefsAccount *ac = NULL;
2106 FolderItem *item = mainwin->summaryview->folder_item;
2111 ac = account_find_from_item(item);
2112 if (ac && ac->protocol != A_NNTP) {
2113 compose_new_with_folderitem(ac, item); /* CLAWS */
2119 * CLAWS - use current account
2121 if (cur_account && (cur_account->protocol != A_NNTP)) {
2122 compose_new_with_folderitem(cur_account, item);
2127 * CLAWS - just get the first one
2129 list = account_get_list();
2130 for (cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2131 ac = (PrefsAccount *) cur->data;
2132 if (ac->protocol != A_NNTP) {
2133 compose_new_with_folderitem(ac, item);
2139 void compose_news_cb(gpointer data, guint action, GtkWidget *widget)
2141 MainWindow *mainwin = (MainWindow*)data;
2142 PrefsAccount * ac = NULL;
2146 if (mainwin->summaryview->folder_item) {
2147 ac = mainwin->summaryview->folder_item->folder->account;
2148 if (ac && ac->protocol == A_NNTP) {
2149 compose_new_with_folderitem(ac,
2150 mainwin->summaryview->folder_item);
2155 list = account_get_list();
2156 for(cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2157 ac = (PrefsAccount *) cur->data;
2158 if (ac->protocol == A_NNTP) {
2159 compose_new_with_folderitem(ac,
2160 mainwin->summaryview->folder_item);