2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2003 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_reply_cb (GtkWidget *widget,
103 static void toolbar_reply_to_all_cb (GtkWidget *widget,
106 static void toolbar_reply_to_list_cb (GtkWidget *widget,
109 static void toolbar_reply_to_sender_cb (GtkWidget *widget,
112 static void toolbar_forward_cb (GtkWidget *widget,
115 static void toolbar_prev_unread_cb (GtkWidget *widget,
117 static void toolbar_next_unread_cb (GtkWidget *widget,
120 static void toolbar_ignore_thread_cb (GtkWidget *widget,
123 static void toolbar_print_cb (GtkWidget *widget,
126 static void toolbar_actions_execute_cb (GtkWidget *widget,
130 static void toolbar_send_cb (GtkWidget *widget,
132 static void toolbar_send_later_cb (GtkWidget *widget,
134 static void toolbar_draft_cb (GtkWidget *widget,
136 static void toolbar_insert_cb (GtkWidget *widget,
138 static void toolbar_attach_cb (GtkWidget *widget,
140 static void toolbar_sig_cb (GtkWidget *widget,
142 static void toolbar_ext_editor_cb (GtkWidget *widget,
144 static void toolbar_linewrap_current_cb (GtkWidget *widget,
146 static void toolbar_linewrap_all_cb (GtkWidget *widget,
148 static void toolbar_addrbook_cb (GtkWidget *widget,
151 static void toolbar_check_spelling_cb (GtkWidget *widget,
158 } toolbar_text [] = {
159 { "A_RECEIVE_ALL", N_("Receive Mail on all Accounts") },
160 { "A_RECEIVE_CUR", N_("Receive Mail on current Account") },
161 { "A_SEND_QUEUED", N_("Send Queued Messages") },
162 { "A_COMPOSE_EMAIL", N_("Compose Email") },
163 { "A_COMPOSE_NEWS", N_("Compose News") },
164 { "A_REPLY_MESSAGE", N_("Reply to Message") },
165 { "A_REPLY_SENDER", N_("Reply to Sender") },
166 { "A_REPLY_ALL", N_("Reply to All") },
167 { "A_REPLY_ML", N_("Reply to Mailing-list") },
168 { "A_FORWARD", N_("Forward Message") },
169 { "A_TRASH", N_("Trash Message") },
170 { "A_DELETE_REAL", N_("Delete Message") },
171 { "A_EXECUTE", N_("Execute") },
172 { "A_GOTO_PREV", N_("Go to Previous Unread Message") },
173 { "A_GOTO_NEXT", N_("Go to Next Unread Message") },
174 { "A_IGNORE_THREAD", N_("Ignore thread") },
175 { "A_PRINT", N_("Print") },
177 { "A_SEND", N_("Send Message") },
178 { "A_SENDL", N_("Put into queue folder and send later") },
179 { "A_DRAFT", N_("Save to draft folder") },
180 { "A_INSERT", N_("Insert file") },
181 { "A_ATTACH", N_("Attach file") },
182 { "A_SIG", N_("Insert signature") },
183 { "A_EXTEDITOR", N_("Edit with external editor") },
184 { "A_LINEWRAP_CURRENT", N_("Wrap long lines of current paragraph") },
185 { "A_LINEWRAP_ALL", N_("Wrap all long lines") },
186 { "A_ADDRBOOK", N_("Address book") },
188 { "A_CHECK_SPELLING", N_("Check spelling") },
190 { "A_SYL_ACTIONS", N_("Sylpheed Actions Feature") },
191 { "A_SEPARATOR", "Separator" }
194 /* struct holds configuration files and a list of
195 * currently active toolbar items
196 * TOOLBAR_MAIN, TOOLBAR_COMPOSE and TOOLBAR_MSGVIEW
200 const gchar *conf_file;
202 } toolbar_config[3] = {
203 { "toolbar_main.xml", NULL},
204 { "toolbar_compose.xml", NULL},
205 { "toolbar_msgview.xml", NULL}
208 static GtkItemFactoryEntry reply_entries[] =
210 {N_("/Reply with _quote"), NULL, toolbar_reply, COMPOSE_REPLY_WITH_QUOTE, NULL},
211 {N_("/_Reply without quote"), NULL, toolbar_reply, COMPOSE_REPLY_WITHOUT_QUOTE, NULL}
213 static GtkItemFactoryEntry replyall_entries[] =
215 {N_("/Reply to all with _quote"), "<shift>A", toolbar_reply, COMPOSE_REPLY_TO_ALL_WITH_QUOTE, NULL},
216 {N_("/_Reply to all without quote"), "a", toolbar_reply, COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE, NULL}
218 static GtkItemFactoryEntry replylist_entries[] =
220 {N_("/Reply to list with _quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_LIST_WITH_QUOTE, NULL},
221 {N_("/_Reply to list without quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE, NULL}
223 static GtkItemFactoryEntry replysender_entries[] =
225 {N_("/Reply to sender with _quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_SENDER_WITH_QUOTE, NULL},
226 {N_("/_Reply to sender without quote"), NULL, toolbar_reply, COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE, NULL}
228 static GtkItemFactoryEntry forward_entries[] =
230 {N_("/_Forward"), "f", toolbar_reply, COMPOSE_FORWARD_INLINE, NULL},
231 {N_("/For_ward as attachment"), "<shift>F", toolbar_reply, COMPOSE_FORWARD_AS_ATTACH, NULL},
232 {N_("/Redirec_t"), NULL, toolbar_reply, COMPOSE_REDIRECT, NULL}
236 gint toolbar_ret_val_from_descr(const gchar *descr)
240 for (i = 0; i < N_ACTION_VAL; i++) {
241 if (g_utf8_collate(gettext(toolbar_text[i].descr), descr) == 0)
248 gchar *toolbar_ret_descr_from_val(gint val)
250 g_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL);
252 return gettext(toolbar_text[val].descr);
255 static gint toolbar_ret_val_from_text(const gchar *text)
259 for (i = 0; i < N_ACTION_VAL; i++) {
260 if (g_utf8_collate(toolbar_text[i].index_str, text) == 0)
267 static gchar *toolbar_ret_text_from_val(gint val)
269 g_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL);
271 return toolbar_text[val].index_str;
274 gboolean toolbar_is_duplicate(gint action, ToolbarType source)
278 if ((action == A_SEPARATOR) || (action == A_SYL_ACTIONS))
281 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
282 ToolbarItem *item = (ToolbarItem*) cur->data;
284 if (item->index == action)
290 /* depending on toolbar type this function
291 returns a list of available toolbar events being
292 displayed by prefs_toolbar
294 GList *toolbar_get_action_items(ToolbarType source)
299 if (source == TOOLBAR_MAIN) {
300 gint main_items[] = { A_RECEIVE_ALL, A_RECEIVE_CUR, A_SEND_QUEUED,
301 A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER,
302 A_REPLY_ALL, A_REPLY_ML, A_FORWARD,
303 A_TRASH , A_DELETE_REAL, A_EXECUTE, A_GOTO_PREV,
304 A_GOTO_NEXT, A_IGNORE_THREAD, A_PRINT,
305 A_ADDRBOOK, A_SYL_ACTIONS };
307 for (i = 0; i < sizeof main_items / sizeof main_items[0]; i++) {
308 items = g_list_append(items, gettext(toolbar_text[main_items[i]].descr));
311 else if (source == TOOLBAR_COMPOSE) {
312 gint comp_items[] = { A_SEND, A_SENDL, A_DRAFT,
313 A_INSERT, A_ATTACH, A_SIG,
314 A_EXTEDITOR, A_LINEWRAP_CURRENT,
315 A_LINEWRAP_ALL, A_ADDRBOOK,
321 for (i = 0; i < sizeof comp_items / sizeof comp_items[0]; i++)
322 items = g_list_append(items, gettext(toolbar_text[comp_items[i]].descr));
324 else if (source == TOOLBAR_MSGVIEW) {
325 gint msgv_items[] = { A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER,
326 A_REPLY_ALL, A_REPLY_ML, A_FORWARD,
327 A_TRASH, A_DELETE_REAL, A_GOTO_PREV, A_GOTO_NEXT,
328 A_ADDRBOOK, A_SYL_ACTIONS };
330 for (i = 0; i < sizeof msgv_items / sizeof msgv_items[0]; i++)
331 items = g_list_append(items, gettext(toolbar_text[msgv_items[i]].descr));
337 static void toolbar_parse_item(XMLFile *file, ToolbarType source)
341 ToolbarItem *item = NULL;
342 gboolean rewrite = FALSE;
344 attr = xml_get_current_tag_attr(file);
345 item = g_new0(ToolbarItem, 1);
347 name = ((XMLAttr *)attr->data)->name;
348 value = ((XMLAttr *)attr->data)->value;
350 if (g_utf8_collate(name, TOOLBAR_ICON_FILE) == 0)
351 item->file = g_strdup (value);
352 else if (g_utf8_collate(name, TOOLBAR_ICON_TEXT) == 0)
353 item->text = g_strdup (value);
354 else if (g_utf8_collate(name, TOOLBAR_ICON_ACTION) == 0)
355 item->index = toolbar_ret_val_from_text(value);
356 if (item->index == -1 && !strcmp(value, "A_DELETE")) {
358 item->index = A_TRASH;
360 item->file = g_strdup("trash_btn");
362 item->text = g_strdup(_("Trash"));
365 attr = g_list_next(attr);
367 if (item->index != -1) {
369 if (!toolbar_is_duplicate(item->index, source))
370 toolbar_config[source].item_list = g_slist_append(toolbar_config[source].item_list,
374 toolbar_save_config_file(source);
378 static void toolbar_set_default_main(void)
384 } default_toolbar[] = {
385 { A_RECEIVE_CUR, STOCK_PIXMAP_MAIL_RECEIVE, _("Get") },
386 { A_RECEIVE_ALL, STOCK_PIXMAP_MAIL_RECEIVE_ALL, _("Get All") },
387 { A_SEPARATOR, 0, ("") },
388 { A_SEND_QUEUED, STOCK_PIXMAP_MAIL_SEND_QUEUE, _("Send") },
389 { A_COMPOSE_EMAIL, STOCK_PIXMAP_MAIL_COMPOSE, _("Compose") },
390 { A_SEPARATOR, 0, ("") },
391 { A_REPLY_MESSAGE, STOCK_PIXMAP_MAIL_REPLY, _("Reply") },
392 { A_REPLY_ALL, STOCK_PIXMAP_MAIL_REPLY_TO_ALL, _("All") },
393 { A_REPLY_SENDER, STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR, _("Sender") },
394 { A_FORWARD, STOCK_PIXMAP_MAIL_FORWARD, _("Forward") },
395 { A_SEPARATOR, 0, ("") },
396 { A_TRASH, STOCK_PIXMAP_TRASH, _("Trash") },
397 { A_SEPARATOR, 0, ("") },
398 { A_GOTO_PREV, STOCK_PIXMAP_UP_ARROW, _("Previous")},
399 { A_GOTO_NEXT, STOCK_PIXMAP_DOWN_ARROW, _("Next") }
404 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
406 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
408 if (default_toolbar[i].action != A_SEPARATOR) {
410 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
412 toolbar_item->file = g_strdup(file);
413 toolbar_item->index = default_toolbar[i].action;
414 toolbar_item->text = g_strdup(default_toolbar[i].text);
417 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
418 toolbar_item->index = A_SEPARATOR;
421 if (toolbar_item->index != -1) {
422 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MAIN))
423 toolbar_config[TOOLBAR_MAIN].item_list =
424 g_slist_append(toolbar_config[TOOLBAR_MAIN].item_list, toolbar_item);
429 static void toolbar_set_default_compose(void)
435 } default_toolbar[] = {
436 { A_SEND, STOCK_PIXMAP_MAIL_SEND, _("Send") },
437 { A_SENDL, STOCK_PIXMAP_MAIL_SEND_QUEUE, _("Send later") },
438 { A_DRAFT, STOCK_PIXMAP_MAIL, _("Draft") },
439 { A_SEPARATOR, 0, ("") },
440 { A_INSERT, STOCK_PIXMAP_INSERT_FILE, _("Insert") },
441 { A_ATTACH, STOCK_PIXMAP_MAIL_ATTACH, _("Attach") },
442 { A_SEPARATOR, 0, ("") },
443 { A_ADDRBOOK, STOCK_PIXMAP_ADDRESS_BOOK, _("Address") }
448 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
450 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
452 if (default_toolbar[i].action != A_SEPARATOR) {
454 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
456 toolbar_item->file = g_strdup(file);
457 toolbar_item->index = default_toolbar[i].action;
458 toolbar_item->text = g_strdup(default_toolbar[i].text);
461 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
462 toolbar_item->index = A_SEPARATOR;
465 if (toolbar_item->index != -1) {
466 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_COMPOSE))
467 toolbar_config[TOOLBAR_COMPOSE].item_list =
468 g_slist_append(toolbar_config[TOOLBAR_COMPOSE].item_list, toolbar_item);
473 static void toolbar_set_default_msgview(void)
479 } default_toolbar[] = {
480 { A_REPLY_MESSAGE, STOCK_PIXMAP_MAIL_REPLY, _("Reply") },
481 { A_REPLY_ALL, STOCK_PIXMAP_MAIL_REPLY_TO_ALL, _("All") },
482 { A_REPLY_SENDER, STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR, _("Sender") },
483 { A_FORWARD, STOCK_PIXMAP_MAIL_FORWARD, _("Forward") },
484 { A_SEPARATOR, 0, ("") },
485 { A_TRASH, STOCK_PIXMAP_TRASH, _("Trash") },
486 { A_GOTO_NEXT, STOCK_PIXMAP_DOWN_ARROW, _("Next") }
491 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
493 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
495 if (default_toolbar[i].action != A_SEPARATOR) {
497 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
499 toolbar_item->file = g_strdup(file);
500 toolbar_item->index = default_toolbar[i].action;
501 toolbar_item->text = g_strdup(default_toolbar[i].text);
504 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
505 toolbar_item->index = A_SEPARATOR;
508 if (toolbar_item->index != -1) {
509 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MSGVIEW))
510 toolbar_config[TOOLBAR_MSGVIEW].item_list =
511 g_slist_append(toolbar_config[TOOLBAR_MSGVIEW].item_list, toolbar_item);
516 void toolbar_set_default(ToolbarType source)
518 if (source == TOOLBAR_MAIN)
519 toolbar_set_default_main();
520 else if (source == TOOLBAR_COMPOSE)
521 toolbar_set_default_compose();
522 else if (source == TOOLBAR_MSGVIEW)
523 toolbar_set_default_msgview();
526 void toolbar_save_config_file(ToolbarType source)
531 gchar *fileSpec = NULL;
533 debug_print("save Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
535 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
536 pfile = prefs_write_open(fileSpec);
540 fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL);
542 fprintf(fp, "<%s>\n", TOOLBAR_TAG_INDEX);
544 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
545 ToolbarItem *toolbar_item = (ToolbarItem*) cur->data;
547 if (toolbar_item->index != A_SEPARATOR) {
548 fprintf(fp, "\t<%s %s=\"%s\" %s=\"",
550 TOOLBAR_ICON_FILE, toolbar_item->file,
552 xml_file_put_escape_str(fp, toolbar_item->text);
553 fprintf(fp, "\" %s=\"%s\"/>\n",
555 toolbar_ret_text_from_val(toolbar_item->index));
557 fprintf(fp, "\t<%s/>\n", TOOLBAR_TAG_SEPARATOR);
561 fprintf(fp, "</%s>\n", TOOLBAR_TAG_INDEX);
563 if (prefs_file_close (pfile) < 0 )
564 g_warning("failed to write toolbar configuration to file\n");
566 g_warning("failed to open toolbar configuration file for writing\n");
569 void toolbar_read_config_file(ToolbarType source)
571 XMLFile *file = NULL;
572 gchar *fileSpec = NULL;
577 debug_print("read Toolbar Configuration from %s\n", toolbar_config[source].conf_file);
579 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
580 file = xml_open_file(fileSpec);
583 toolbar_clear_list(source);
587 || (xml_get_dtd(file))
588 || (xml_parse_next_tag(file))
589 || (!xml_compare_tag(file, TOOLBAR_TAG_INDEX))) {
590 xml_close_file(file);
594 attr = xml_get_current_tag_attr(file);
601 if (xml_parse_next_tag(file))
604 /* Get next tag (icon, icon_text or icon_action) */
605 if (xml_compare_tag(file, TOOLBAR_TAG_ITEM)) {
606 toolbar_parse_item(file, source);
607 } else if (xml_compare_tag(file, TOOLBAR_TAG_SEPARATOR)) {
608 ToolbarItem *item = g_new0(ToolbarItem, 1);
610 item->file = g_strdup(toolbar_ret_descr_from_val(A_SEPARATOR));
611 item->index = A_SEPARATOR;
612 toolbar_config[source].item_list =
613 g_slist_append(toolbar_config[source].item_list, item);
617 xml_close_file(file);
620 if ((!file) || (g_slist_length(toolbar_config[source].item_list) == 0)) {
622 if (source == TOOLBAR_MAIN)
623 toolbar_set_default(TOOLBAR_MAIN);
624 else if (source == TOOLBAR_COMPOSE)
625 toolbar_set_default(TOOLBAR_COMPOSE);
626 else if (source == TOOLBAR_MSGVIEW)
627 toolbar_set_default(TOOLBAR_MSGVIEW);
629 g_warning("failed to write Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
633 toolbar_save_config_file(source);
638 * clears list of toolbar items read from configuration files
640 void toolbar_clear_list(ToolbarType source)
642 while (toolbar_config[source].item_list != NULL) {
643 ToolbarItem *item = (ToolbarItem*) toolbar_config[source].item_list->data;
645 toolbar_config[source].item_list =
646 g_slist_remove(toolbar_config[source].item_list, item);
654 g_slist_free(toolbar_config[source].item_list);
659 * return list of Toolbar items
661 GSList *toolbar_get_list(ToolbarType source)
665 if ((source == TOOLBAR_MAIN) || (source == TOOLBAR_COMPOSE) || (source == TOOLBAR_MSGVIEW))
666 list = toolbar_config[source].item_list;
671 void toolbar_set_list_item(ToolbarItem *t_item, ToolbarType source)
673 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
675 toolbar_item->file = g_strdup(t_item->file);
676 toolbar_item->text = g_strdup(t_item->text);
677 toolbar_item->index = t_item->index;
679 toolbar_config[source].item_list =
680 g_slist_append(toolbar_config[source].item_list,
684 void toolbar_action_execute(GtkWidget *widget,
690 gchar *action, *action_p;
691 gboolean found = FALSE;
694 for (cur = action_list; cur != NULL; cur = cur->next) {
695 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
697 if (widget == act->widget) {
699 for (lop = prefs_common.actions_list; lop != NULL; lop = lop->next) {
700 action = g_strdup((gchar*)lop->data);
702 action_p = strstr(action, ": ");
704 if (g_utf8_collate(act->name, action) == 0) {
718 actions_execute(data, i, widget, source);
720 g_warning ("Error: did not find Sylpheed Action to execute");
723 static void activate_compose_button (Toolbar *toolbar,
725 ComposeButtonType type)
727 if ((!toolbar->compose_mail_btn) || (!toolbar->compose_news_btn))
730 gtk_widget_hide(type == COMPOSEBUTTON_NEWS ? toolbar->compose_mail_btn
731 : toolbar->compose_news_btn);
732 gtk_widget_show(type == COMPOSEBUTTON_NEWS ? toolbar->compose_news_btn
733 : toolbar->compose_mail_btn);
734 toolbar->compose_btn_type = type;
737 void toolbar_set_compose_button(Toolbar *toolbar,
738 ComposeButtonType compose_btn_type)
740 if (toolbar->compose_btn_type != compose_btn_type)
741 activate_compose_button(toolbar,
742 prefs_common.toolbar_style,
746 void toolbar_toggle(guint action, gpointer data)
748 MainWindow *mainwin = (MainWindow*)data;
752 g_return_if_fail(mainwin != NULL);
754 toolbar_style(TOOLBAR_MAIN, action, mainwin);
756 list = compose_get_compose_list();
757 for (cur = list; cur != NULL; cur = cur->next) {
758 toolbar_style(TOOLBAR_COMPOSE, action, cur->data);
760 list = messageview_get_msgview_list();
761 for (cur = list; cur != NULL; cur = cur->next) {
762 toolbar_style(TOOLBAR_MSGVIEW, action, cur->data);
767 void toolbar_set_style(GtkWidget *toolbar_wid, GtkWidget *handlebox_wid, guint action)
769 switch ((ToolbarStyle)action) {
771 gtk_widget_hide(handlebox_wid);
774 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
778 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
782 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
789 prefs_common.toolbar_style = (ToolbarStyle)action;
790 gtk_widget_set_size_request(handlebox_wid, 1, -1);
792 if (prefs_common.toolbar_style != TOOLBAR_NONE) {
793 gtk_widget_show(handlebox_wid);
794 gtk_widget_queue_resize(handlebox_wid);
798 * Change the style of toolbar
800 static void toolbar_style(ToolbarType type, guint action, gpointer data)
802 GtkWidget *handlebox_wid;
803 GtkWidget *toolbar_wid;
804 MainWindow *mainwin = (MainWindow*)data;
805 Compose *compose = (Compose*)data;
806 MessageView *msgview = (MessageView*)data;
808 g_return_if_fail(data != NULL);
812 handlebox_wid = mainwin->handlebox;
813 toolbar_wid = mainwin->toolbar->toolbar;
815 case TOOLBAR_COMPOSE:
816 handlebox_wid = compose->handlebox;
817 toolbar_wid = compose->toolbar->toolbar;
819 case TOOLBAR_MSGVIEW:
820 handlebox_wid = msgview->handlebox;
821 toolbar_wid = msgview->toolbar->toolbar;
827 toolbar_set_style(toolbar_wid, handlebox_wid, action);
830 /* Toolbar handling */
831 static void toolbar_inc_cb(GtkWidget *widget,
834 ToolbarItem *toolbar_item = (ToolbarItem*)data;
837 g_return_if_fail(toolbar_item != NULL);
839 switch (toolbar_item->type) {
841 mainwin = (MainWindow*)toolbar_item->parent;
842 inc_mail_cb(mainwin, 0, NULL);
849 static void toolbar_inc_all_cb(GtkWidget *widget,
852 ToolbarItem *toolbar_item = (ToolbarItem*)data;
855 g_return_if_fail(toolbar_item != NULL);
857 switch (toolbar_item->type) {
859 mainwin = (MainWindow*)toolbar_item->parent;
860 inc_all_account_mail_cb(mainwin, 0, NULL);
867 static void toolbar_send_queued_cb(GtkWidget *widget,gpointer data)
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 send_queue_cb(mainwin, 0, NULL);
884 static void toolbar_exec_cb(GtkWidget *widget,
887 MainWindow *mainwin = get_mainwin(data);
889 g_return_if_fail(mainwin != NULL);
890 summary_execute(mainwin->summaryview);
894 * Delete current/selected(s) message(s)
896 static void toolbar_trash_cb(GtkWidget *widget, gpointer data)
898 ToolbarItem *toolbar_item = (ToolbarItem*)data;
901 g_return_if_fail(toolbar_item != NULL);
902 g_return_if_fail(toolbar_item->parent);
904 switch (toolbar_item->type) {
905 case TOOLBAR_MSGVIEW:
906 messageview_delete((MessageView *)toolbar_item->parent);
909 mainwin = (MainWindow *)toolbar_item->parent;
910 summary_delete_trash(mainwin->summaryview);
913 debug_print("toolbar event not supported\n");
919 * Delete current/selected(s) message(s)
921 static void toolbar_delete_cb(GtkWidget *widget, gpointer data)
923 ToolbarItem *toolbar_item = (ToolbarItem*)data;
926 g_return_if_fail(toolbar_item != NULL);
927 g_return_if_fail(toolbar_item->parent);
929 switch (toolbar_item->type) {
930 case TOOLBAR_MSGVIEW:
931 messageview_delete((MessageView *)toolbar_item->parent);
934 mainwin = (MainWindow *)toolbar_item->parent;
935 summary_delete(mainwin->summaryview);
938 debug_print("toolbar event not supported\n");
945 * Compose new message
947 static void toolbar_compose_cb(GtkWidget *widget, gpointer data)
949 ToolbarItem *toolbar_item = (ToolbarItem*)data;
951 MessageView *msgview;
953 g_return_if_fail(toolbar_item != NULL);
955 switch (toolbar_item->type) {
957 mainwin = (MainWindow*)toolbar_item->parent;
958 if (mainwin->toolbar->compose_btn_type == COMPOSEBUTTON_NEWS)
959 compose_news_cb(mainwin, 0, NULL);
961 compose_mail_cb(mainwin, 0, NULL);
963 case TOOLBAR_MSGVIEW:
964 msgview = (MessageView*)toolbar_item->parent;
965 compose_new_with_folderitem(NULL,
966 msgview->msginfo->folder);
969 debug_print("toolbar event not supported\n");
977 static void toolbar_reply_cb(GtkWidget *widget, gpointer data)
979 toolbar_reply(data, prefs_common.reply_with_quote ?
980 COMPOSE_REPLY_WITH_QUOTE : COMPOSE_REPLY_WITHOUT_QUOTE);
985 * Reply message to Sender and All recipients
987 static void toolbar_reply_to_all_cb(GtkWidget *widget, gpointer data)
990 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_ALL_WITH_QUOTE
991 : COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE);
996 * Reply to Mailing List
998 static void toolbar_reply_to_list_cb(GtkWidget *widget, gpointer data)
1001 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_LIST_WITH_QUOTE
1002 : COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE);
1007 * Reply to sender of message
1009 static void toolbar_reply_to_sender_cb(GtkWidget *widget, gpointer data)
1012 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_SENDER_WITH_QUOTE
1013 : COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE);
1019 static void toolbar_addrbook_cb(GtkWidget *widget, gpointer data)
1021 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1024 g_return_if_fail(toolbar_item != NULL);
1026 switch (toolbar_item->type) {
1028 case TOOLBAR_MSGVIEW:
1031 case TOOLBAR_COMPOSE:
1032 compose = (Compose *)toolbar_item->parent;
1037 addressbook_open(compose);
1042 * Forward current/selected(s) message(s)
1044 static void toolbar_forward_cb(GtkWidget *widget, gpointer data)
1046 toolbar_reply(data, COMPOSE_FORWARD);
1050 * Goto Prev Unread Message
1052 static void toolbar_prev_unread_cb(GtkWidget *widget, gpointer data)
1054 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1055 MainWindow *mainwin;
1056 MessageView *msgview;
1058 g_return_if_fail(toolbar_item != NULL);
1060 switch (toolbar_item->type) {
1062 mainwin = (MainWindow*)toolbar_item->parent;
1063 summary_select_prev_unread(mainwin->summaryview);
1066 case TOOLBAR_MSGVIEW:
1067 msgview = (MessageView*)toolbar_item->parent;
1068 summary_select_prev_unread(msgview->mainwin->summaryview);
1070 /* Now we need to update the messageview window */
1071 if (msgview->mainwin->summaryview->selected) {
1072 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1074 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1075 msgview->mainwin->summaryview->selected);
1077 messageview_show(msgview, msginfo,
1078 msgview->all_headers);
1080 gtk_widget_destroy(msgview->window);
1084 debug_print("toolbar event not supported\n");
1089 * Goto Next Unread Message
1091 static void toolbar_next_unread_cb(GtkWidget *widget, gpointer data)
1093 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1094 MainWindow *mainwin;
1095 MessageView *msgview;
1097 g_return_if_fail(toolbar_item != NULL);
1099 switch (toolbar_item->type) {
1101 mainwin = (MainWindow*)toolbar_item->parent;
1102 summary_select_next_unread(mainwin->summaryview);
1105 case TOOLBAR_MSGVIEW:
1106 msgview = (MessageView*)toolbar_item->parent;
1107 summary_select_next_unread(msgview->mainwin->summaryview);
1109 /* Now we need to update the messageview window */
1110 if (msgview->mainwin->summaryview->selected) {
1111 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1113 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1114 msgview->mainwin->summaryview->selected);
1116 messageview_show(msgview, msginfo,
1117 msgview->all_headers);
1119 gtk_widget_destroy(msgview->window);
1123 debug_print("toolbar event not supported\n");
1127 static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data)
1129 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1130 MainWindow *mainwin;
1132 g_return_if_fail(toolbar_item != NULL);
1134 switch (toolbar_item->type) {
1136 mainwin = (MainWindow *) toolbar_item->parent;
1137 summary_toggle_ignore_thread(mainwin->summaryview);
1139 case TOOLBAR_MSGVIEW:
1140 /* TODO: see toolbar_next_unread_cb() if you need
1141 * this in the message view */
1144 debug_print("toolbar event not supported\n");
1149 static void toolbar_print_cb(GtkWidget *widget, gpointer data)
1151 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1152 MainWindow *mainwin;
1154 g_return_if_fail(toolbar_item != NULL);
1156 switch (toolbar_item->type) {
1158 mainwin = (MainWindow *) toolbar_item->parent;
1159 summary_print(mainwin->summaryview);
1161 case TOOLBAR_MSGVIEW:
1162 /* TODO: see toolbar_next_unread_cb() if you need
1163 * this in the message view */
1166 debug_print("toolbar event not supported\n");
1171 static void toolbar_send_cb(GtkWidget *widget, gpointer data)
1173 compose_toolbar_cb(A_SEND, data);
1176 static void toolbar_send_later_cb(GtkWidget *widget, gpointer data)
1178 compose_toolbar_cb(A_SENDL, data);
1181 static void toolbar_draft_cb(GtkWidget *widget, gpointer data)
1183 compose_toolbar_cb(A_DRAFT, data);
1186 static void toolbar_insert_cb(GtkWidget *widget, gpointer data)
1188 compose_toolbar_cb(A_INSERT, data);
1191 static void toolbar_attach_cb(GtkWidget *widget, gpointer data)
1193 compose_toolbar_cb(A_ATTACH, data);
1196 static void toolbar_sig_cb(GtkWidget *widget, gpointer data)
1198 compose_toolbar_cb(A_SIG, data);
1201 static void toolbar_ext_editor_cb(GtkWidget *widget, gpointer data)
1203 compose_toolbar_cb(A_EXTEDITOR, data);
1206 static void toolbar_linewrap_current_cb(GtkWidget *widget, gpointer data)
1208 compose_toolbar_cb(A_LINEWRAP_CURRENT, data);
1211 static void toolbar_linewrap_all_cb(GtkWidget *widget, gpointer data)
1213 compose_toolbar_cb(A_LINEWRAP_ALL, data);
1217 static void toolbar_check_spelling_cb(GtkWidget *widget, gpointer data)
1219 compose_toolbar_cb(A_CHECK_SPELLING, data);
1223 * Execute actions from toolbar
1225 static void toolbar_actions_execute_cb(GtkWidget *widget, gpointer data)
1227 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1228 GSList *action_list;
1229 MainWindow *mainwin;
1231 MessageView *msgview;
1232 gpointer parent = toolbar_item->parent;
1234 g_return_if_fail(toolbar_item != NULL);
1236 switch (toolbar_item->type) {
1238 mainwin = (MainWindow*)parent;
1239 action_list = mainwin->toolbar->action_list;
1241 case TOOLBAR_COMPOSE:
1242 compose = (Compose*)parent;
1243 action_list = compose->toolbar->action_list;
1245 case TOOLBAR_MSGVIEW:
1246 msgview = (MessageView*)parent;
1247 action_list = msgview->toolbar->action_list;
1250 debug_print("toolbar event not supported\n");
1253 toolbar_action_execute(widget, action_list, parent, toolbar_item->type);
1256 static MainWindow *get_mainwin(gpointer data)
1258 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1259 MainWindow *mainwin = NULL;
1260 MessageView *msgview;
1262 g_return_val_if_fail(toolbar_item != NULL, NULL);
1264 switch(toolbar_item->type) {
1266 mainwin = (MainWindow*)toolbar_item->parent;
1268 case TOOLBAR_MSGVIEW:
1269 msgview = (MessageView*)toolbar_item->parent;
1270 mainwin = (MainWindow*)msgview->mainwin;
1279 static void toolbar_buttons_cb(GtkWidget *widget,
1286 void (*func)(GtkWidget *widget, gpointer data);
1288 { A_RECEIVE_ALL, toolbar_inc_all_cb },
1289 { A_RECEIVE_CUR, toolbar_inc_cb },
1290 { A_SEND_QUEUED, toolbar_send_queued_cb },
1291 { A_COMPOSE_EMAIL, toolbar_compose_cb },
1292 { A_COMPOSE_NEWS, toolbar_compose_cb },
1293 { A_REPLY_MESSAGE, toolbar_reply_cb },
1294 { A_REPLY_SENDER, toolbar_reply_to_sender_cb },
1295 { A_REPLY_ALL, toolbar_reply_to_all_cb },
1296 { A_REPLY_ML, toolbar_reply_to_list_cb },
1297 { A_FORWARD, toolbar_forward_cb },
1298 { A_TRASH, toolbar_trash_cb },
1299 { A_DELETE_REAL, toolbar_delete_cb },
1300 { A_EXECUTE, toolbar_exec_cb },
1301 { A_GOTO_PREV, toolbar_prev_unread_cb },
1302 { A_GOTO_NEXT, toolbar_next_unread_cb },
1303 { A_IGNORE_THREAD, toolbar_ignore_thread_cb },
1304 { A_PRINT, toolbar_print_cb },
1306 { A_SEND, toolbar_send_cb },
1307 { A_SENDL, toolbar_send_later_cb },
1308 { A_DRAFT, toolbar_draft_cb },
1309 { A_INSERT, toolbar_insert_cb },
1310 { A_ATTACH, toolbar_attach_cb },
1311 { A_SIG, toolbar_sig_cb },
1312 { A_EXTEDITOR, toolbar_ext_editor_cb },
1313 { A_LINEWRAP_CURRENT, toolbar_linewrap_current_cb },
1314 { A_LINEWRAP_ALL, toolbar_linewrap_all_cb },
1315 { A_ADDRBOOK, toolbar_addrbook_cb },
1317 { A_CHECK_SPELLING, toolbar_check_spelling_cb },
1319 { A_SYL_ACTIONS, toolbar_actions_execute_cb }
1322 num_items = sizeof(callbacks)/sizeof(callbacks[0]);
1324 for (i = 0; i < num_items; i++) {
1325 if (callbacks[i].index == item->index) {
1326 callbacks[i].func(widget, item);
1333 * Create a new toolbar with specified type
1334 * if a callback list is passed it will be used before the
1335 * common callback list
1337 Toolbar *toolbar_create(ToolbarType type,
1338 GtkWidget *container,
1341 ToolbarItem *toolbar_item;
1344 GtkWidget *icon_wid = NULL;
1345 GtkWidget *icon_news;
1347 GtkWidget *item_news;
1349 guint n_menu_entries;
1350 ComboButton *reply_combo;
1351 ComboButton *replyall_combo;
1352 ComboButton *replylist_combo;
1353 ComboButton *replysender_combo;
1354 ComboButton *fwd_combo;
1356 GtkTooltips *toolbar_tips;
1357 ToolbarSylpheedActions *action_item;
1359 GSList *toolbar_list;
1360 Toolbar *toolbar_data;
1363 toolbar_tips = gtk_tooltips_new();
1365 toolbar_read_config_file(type);
1366 toolbar_list = toolbar_get_list(type);
1368 toolbar_data = g_new0(Toolbar, 1);
1370 toolbar = gtk_toolbar_new();
1371 gtk_container_add(GTK_CONTAINER(container), toolbar);
1372 gtk_container_set_border_width(GTK_CONTAINER(container), 2);
1373 gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1374 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
1376 for (cur = toolbar_list; cur != NULL; cur = cur->next) {
1378 if (g_ascii_strcasecmp(((ToolbarItem*)cur->data)->file, TOOLBAR_TAG_SEPARATOR) == 0) {
1379 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
1383 toolbar_item = g_new0(ToolbarItem, 1);
1384 toolbar_item->index = ((ToolbarItem*)cur->data)->index;
1385 toolbar_item->file = g_strdup(((ToolbarItem*)cur->data)->file);
1386 toolbar_item->text = g_strdup(((ToolbarItem*)cur->data)->text);
1387 toolbar_item->parent = data;
1388 toolbar_item->type = type;
1390 /* collect toolbar items in list to keep track */
1391 toolbar_data->item_list =
1392 g_slist_append(toolbar_data->item_list,
1395 icon_wid = stock_pixmap_widget(container, stock_pixmap_get_icon(toolbar_item->file));
1396 item = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1400 icon_wid, G_CALLBACK(toolbar_buttons_cb),
1403 switch (toolbar_item->index) {
1406 toolbar_data->getall_btn = item;
1407 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1408 toolbar_data->getall_btn,
1409 _("Receive Mail on all Accounts"), NULL);
1412 toolbar_data->get_btn = item;
1413 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1414 toolbar_data->get_btn,
1415 _("Receive Mail on current Account"), NULL);
1418 toolbar_data->send_btn = item;
1419 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1420 toolbar_data->send_btn,
1421 _("Send Queued Messages"), NULL);
1423 case A_COMPOSE_EMAIL:
1424 icon_news = stock_pixmap_widget(container, STOCK_PIXMAP_NEWS_COMPOSE);
1425 item_news = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1429 icon_news, G_CALLBACK(toolbar_buttons_cb),
1431 toolbar_data->compose_mail_btn = item;
1432 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1433 toolbar_data->compose_mail_btn,
1434 _("Compose Email"), NULL);
1435 toolbar_data->compose_news_btn = item_news;
1436 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1437 toolbar_data->compose_news_btn,
1438 _("Compose News"), NULL);
1440 case A_REPLY_MESSAGE:
1441 toolbar_data->reply_btn = item;
1442 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1443 toolbar_data->reply_btn,
1444 _("Reply to Message"), NULL);
1445 n_menu_entries = sizeof(reply_entries) /
1446 sizeof(reply_entries[0]);
1447 reply_combo = gtkut_combo_button_create(toolbar_data->reply_btn,
1448 reply_entries, n_menu_entries,
1449 "<Reply>", (gpointer)toolbar_item);
1450 gtk_button_set_relief(GTK_BUTTON(reply_combo->arrow),
1452 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1453 GTK_WIDGET_PTR(reply_combo),
1454 _("Reply to Message"), "Reply");
1455 toolbar_data->reply_combo = reply_combo;
1457 case A_REPLY_SENDER:
1458 toolbar_data->replysender_btn = item;
1459 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1460 toolbar_data->replysender_btn,
1461 _("Reply to Sender"), NULL);
1462 n_menu_entries = sizeof(replysender_entries) /
1463 sizeof(replysender_entries[0]);
1464 replysender_combo = gtkut_combo_button_create(toolbar_data->replysender_btn,
1465 replysender_entries, n_menu_entries,
1466 "<ReplySender>", (gpointer)toolbar_item);
1467 gtk_button_set_relief(GTK_BUTTON(replysender_combo->arrow),
1469 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1470 GTK_WIDGET_PTR(replysender_combo),
1471 _("Reply to Sender"), "ReplySender");
1472 toolbar_data->replysender_combo = replysender_combo;
1475 toolbar_data->replyall_btn = item;
1476 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1477 toolbar_data->replyall_btn,
1478 _("Reply to All"), NULL);
1479 n_menu_entries = sizeof(replyall_entries) /
1480 sizeof(replyall_entries[0]);
1481 replyall_combo = gtkut_combo_button_create(toolbar_data->replyall_btn,
1482 replyall_entries, n_menu_entries,
1483 "<ReplyAll>", (gpointer)toolbar_item);
1484 gtk_button_set_relief(GTK_BUTTON(replyall_combo->arrow),
1486 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1487 GTK_WIDGET_PTR(replyall_combo),
1488 _("Reply to All"), "ReplyAll");
1489 toolbar_data->replyall_combo = replyall_combo;
1492 toolbar_data->replylist_btn = item;
1493 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1494 toolbar_data->replylist_btn,
1495 _("Reply to Mailing-list"), NULL);
1496 n_menu_entries = sizeof(replylist_entries) /
1497 sizeof(replylist_entries[0]);
1498 replylist_combo = gtkut_combo_button_create(toolbar_data->replylist_btn,
1499 replylist_entries, n_menu_entries,
1500 "<ReplyList>", (gpointer)toolbar_item);
1501 gtk_button_set_relief(GTK_BUTTON(replylist_combo->arrow),
1503 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1504 GTK_WIDGET_PTR(replylist_combo),
1505 _("Reply to Mailing-list"), "ReplyList");
1506 toolbar_data->replylist_combo = replylist_combo;
1509 toolbar_data->fwd_btn = item;
1510 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1511 toolbar_data->fwd_btn,
1512 _("Forward Message"), NULL);
1513 n_menu_entries = sizeof(forward_entries) /
1514 sizeof(forward_entries[0]);
1515 fwd_combo = gtkut_combo_button_create(toolbar_data->fwd_btn,
1516 forward_entries, n_menu_entries,
1517 "<Forward>", (gpointer)toolbar_item);
1518 gtk_button_set_relief(GTK_BUTTON(fwd_combo->arrow),
1520 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1521 GTK_WIDGET_PTR(fwd_combo),
1522 _("Forward Message"), "Fwd");
1523 toolbar_data->fwd_combo = fwd_combo;
1526 toolbar_data->trash_btn = item;
1527 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1528 toolbar_data->trash_btn,
1529 _("Trash Message"), NULL);
1532 toolbar_data->delete_btn = item;
1533 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1534 toolbar_data->delete_btn,
1535 _("Delete Message"), NULL);
1538 toolbar_data->exec_btn = item;
1539 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1540 toolbar_data->exec_btn,
1541 _("Execute"), NULL);
1544 toolbar_data->prev_btn = item;
1545 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1546 toolbar_data->prev_btn,
1547 _("Go to Previous Unread Message"),
1551 toolbar_data->next_btn = item;
1552 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1553 toolbar_data->next_btn,
1554 _("Go to Next Unread Message"),
1558 /* Compose Toolbar */
1560 toolbar_data->send_btn = item;
1561 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1562 toolbar_data->send_btn,
1563 _("Send Message"), NULL);
1566 toolbar_data->sendl_btn = item;
1567 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1568 toolbar_data->sendl_btn,
1569 _("Put into queue folder and send later"), NULL);
1572 toolbar_data->draft_btn = item;
1573 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1574 toolbar_data->draft_btn,
1575 _("Save to draft folder"), NULL);
1578 toolbar_data->insert_btn = item;
1579 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1580 toolbar_data->insert_btn,
1581 _("Insert file"), NULL);
1584 toolbar_data->attach_btn = item;
1585 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1586 toolbar_data->attach_btn,
1587 _("Attach file"), NULL);
1590 toolbar_data->sig_btn = item;
1591 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1592 toolbar_data->sig_btn,
1593 _("Insert signature"), NULL);
1596 toolbar_data->exteditor_btn = item;
1597 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1598 toolbar_data->exteditor_btn,
1599 _("Edit with external editor"), NULL);
1601 case A_LINEWRAP_CURRENT:
1602 toolbar_data->linewrap_current_btn = item;
1603 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1604 toolbar_data->linewrap_current_btn,
1605 _("Wrap long lines of current paragraph"), NULL);
1607 case A_LINEWRAP_ALL:
1608 toolbar_data->linewrap_all_btn = item;
1609 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1610 toolbar_data->linewrap_all_btn,
1611 _("Wrap all long lines"), NULL);
1614 toolbar_data->addrbook_btn = item;
1615 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1616 toolbar_data->addrbook_btn,
1617 _("Address book"), NULL);
1620 case A_CHECK_SPELLING:
1621 toolbar_data->spellcheck_btn = item;
1622 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1623 toolbar_data->spellcheck_btn,
1624 _("Check spelling"), NULL);
1629 action_item = g_new0(ToolbarSylpheedActions, 1);
1630 action_item->widget = item;
1631 action_item->name = g_strdup(toolbar_item->text);
1633 toolbar_data->action_list =
1634 g_slist_append(toolbar_data->action_list,
1637 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1639 action_item->name, NULL);
1641 gtk_widget_show(item);
1644 /* find and set the tool tip text */
1645 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1647 toolbar_ret_descr_from_val
1648 (toolbar_item->index),
1654 toolbar_data->toolbar = toolbar;
1655 if (type == TOOLBAR_MAIN)
1656 activate_compose_button(toolbar_data,
1657 prefs_common.toolbar_style,
1658 toolbar_data->compose_btn_type);
1660 gtk_widget_show_all(toolbar);
1662 return toolbar_data;
1666 * Free toolbar structures
1668 void toolbar_destroy(Toolbar * toolbar) {
1670 TOOLBAR_DESTROY_ITEMS(toolbar->item_list);
1671 TOOLBAR_DESTROY_ACTIONS(toolbar->action_list);
1674 void toolbar_update(ToolbarType type, gpointer data)
1676 Toolbar *toolbar_data;
1677 GtkWidget *handlebox;
1678 MainWindow *mainwin = (MainWindow*)data;
1679 Compose *compose = (Compose*)data;
1680 MessageView *msgview = (MessageView*)data;
1684 toolbar_data = mainwin->toolbar;
1685 handlebox = mainwin->handlebox;
1687 case TOOLBAR_COMPOSE:
1688 toolbar_data = compose->toolbar;
1689 handlebox = compose->handlebox;
1691 case TOOLBAR_MSGVIEW:
1692 toolbar_data = msgview->toolbar;
1693 handlebox = msgview->handlebox;
1699 gtk_container_remove(GTK_CONTAINER(handlebox),
1700 GTK_WIDGET(toolbar_data->toolbar));
1702 toolbar_init(toolbar_data);
1703 toolbar_data = toolbar_create(type, handlebox, data);
1706 mainwin->toolbar = toolbar_data;
1708 case TOOLBAR_COMPOSE:
1709 compose->toolbar = toolbar_data;
1711 case TOOLBAR_MSGVIEW:
1712 msgview->toolbar = toolbar_data;
1716 toolbar_style(type, prefs_common.toolbar_style, data);
1718 if (type == TOOLBAR_MAIN)
1719 toolbar_main_set_sensitive((MainWindow*)data);
1722 void toolbar_main_set_sensitive(gpointer data)
1724 SensitiveCond state;
1726 MainWindow *mainwin = (MainWindow*)data;
1727 Toolbar *toolbar = mainwin->toolbar;
1729 GSList *entry_list = NULL;
1731 typedef struct _Entry Entry;
1738 #define SET_WIDGET_COND(w, c) \
1740 Entry *e = g_new0(Entry, 1); \
1743 entry_list = g_slist_append(entry_list, e); \
1746 SET_WIDGET_COND(toolbar->get_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1747 SET_WIDGET_COND(toolbar->getall_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1748 SET_WIDGET_COND(toolbar->compose_news_btn, M_HAVE_ACCOUNT);
1749 SET_WIDGET_COND(toolbar->reply_btn,
1750 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1751 if (toolbar->reply_btn)
1752 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->reply_combo),
1753 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1754 SET_WIDGET_COND(toolbar->replyall_btn,
1755 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1756 if (toolbar->replyall_btn)
1757 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replyall_combo),
1758 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1759 SET_WIDGET_COND(toolbar->replylist_btn,
1760 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1761 if (toolbar->replylist_btn)
1762 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replylist_combo),
1763 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1764 SET_WIDGET_COND(toolbar->replysender_btn,
1765 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1766 if (toolbar->replysender_btn)
1767 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replysender_combo),
1768 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1769 SET_WIDGET_COND(toolbar->fwd_btn, M_HAVE_ACCOUNT|M_TARGET_EXIST);
1770 if (toolbar->fwd_btn)
1771 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->fwd_combo),
1772 M_HAVE_ACCOUNT|M_TARGET_EXIST);
1773 if (toolbar->fwd_combo) {
1774 GtkWidget *submenu = gtk_item_factory_get_widget(toolbar->fwd_combo->factory, "/Redirect");
1775 SET_WIDGET_COND(submenu, M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1778 if (prefs_common.next_unread_msg_dialog == NEXTUNREADMSGDIALOG_ASSUME_NO) {
1779 SET_WIDGET_COND(toolbar->next_btn, M_MSG_EXIST);
1781 SET_WIDGET_COND(toolbar->next_btn, 0);
1784 SET_WIDGET_COND(toolbar->trash_btn,
1785 M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED);
1786 SET_WIDGET_COND(toolbar->delete_btn,
1787 M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED);
1788 SET_WIDGET_COND(toolbar->exec_btn, M_DELAY_EXEC);
1790 for (cur = toolbar->action_list; cur != NULL; cur = cur->next) {
1791 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
1793 SET_WIDGET_COND(act->widget, M_TARGET_EXIST|M_UNLOCKED);
1796 #undef SET_WIDGET_COND
1798 state = main_window_get_current_state(mainwin);
1800 for (cur = entry_list; cur != NULL; cur = cur->next) {
1801 Entry *e = (Entry*) cur->data;
1803 if (e->widget != NULL) {
1804 sensitive = ((e->cond & state) == e->cond);
1805 gtk_widget_set_sensitive(e->widget, sensitive);
1809 while (entry_list != NULL) {
1810 Entry *e = (Entry*) entry_list->data;
1814 entry_list = g_slist_remove(entry_list, e);
1817 g_slist_free(entry_list);
1819 activate_compose_button(toolbar,
1820 prefs_common.toolbar_style,
1821 toolbar->compose_btn_type);
1824 void toolbar_comp_set_sensitive(gpointer data, gboolean sensitive)
1826 Compose *compose = (Compose*)data;
1827 GSList *items = compose->toolbar->action_list;
1829 if (compose->toolbar->send_btn)
1830 gtk_widget_set_sensitive(compose->toolbar->send_btn, sensitive);
1831 if (compose->toolbar->sendl_btn)
1832 gtk_widget_set_sensitive(compose->toolbar->sendl_btn, sensitive);
1833 if (compose->toolbar->draft_btn )
1834 gtk_widget_set_sensitive(compose->toolbar->draft_btn , sensitive);
1835 if (compose->toolbar->insert_btn )
1836 gtk_widget_set_sensitive(compose->toolbar->insert_btn , sensitive);
1837 if (compose->toolbar->attach_btn)
1838 gtk_widget_set_sensitive(compose->toolbar->attach_btn, sensitive);
1839 if (compose->toolbar->sig_btn)
1840 gtk_widget_set_sensitive(compose->toolbar->sig_btn, sensitive);
1841 if (compose->toolbar->exteditor_btn)
1842 gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, sensitive);
1843 if (compose->toolbar->linewrap_current_btn)
1844 gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, sensitive);
1845 if (compose->toolbar->linewrap_all_btn)
1846 gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, sensitive);
1847 if (compose->toolbar->addrbook_btn)
1848 gtk_widget_set_sensitive(compose->toolbar->addrbook_btn, sensitive);
1850 if (compose->toolbar->spellcheck_btn)
1851 gtk_widget_set_sensitive(compose->toolbar->spellcheck_btn, sensitive);
1853 for (; items != NULL; items = g_slist_next(items)) {
1854 ToolbarSylpheedActions *item = (ToolbarSylpheedActions *)items->data;
1855 gtk_widget_set_sensitive(item->widget, sensitive);
1860 * Initialize toolbar structure
1862 void toolbar_init(Toolbar * toolbar) {
1864 toolbar->toolbar = NULL;
1865 toolbar->get_btn = NULL;
1866 toolbar->getall_btn = NULL;
1867 toolbar->send_btn = NULL;
1868 toolbar->compose_mail_btn = NULL;
1869 toolbar->compose_news_btn = NULL;
1870 toolbar->reply_btn = NULL;
1871 toolbar->replysender_btn = NULL;
1872 toolbar->replyall_btn = NULL;
1873 toolbar->replylist_btn = NULL;
1874 toolbar->fwd_btn = NULL;
1875 toolbar->trash_btn = NULL;
1876 toolbar->delete_btn = NULL;
1877 toolbar->prev_btn = NULL;
1878 toolbar->next_btn = NULL;
1879 toolbar->exec_btn = NULL;
1881 /* compose buttons */
1882 toolbar->sendl_btn = NULL;
1883 toolbar->draft_btn = NULL;
1884 toolbar->insert_btn = NULL;
1885 toolbar->attach_btn = NULL;
1886 toolbar->sig_btn = NULL;
1887 toolbar->exteditor_btn = NULL;
1888 toolbar->linewrap_current_btn = NULL;
1889 toolbar->linewrap_all_btn = NULL;
1890 toolbar->addrbook_btn = NULL;
1892 toolbar->spellcheck_btn = NULL;
1895 toolbar_destroy(toolbar);
1900 static void toolbar_reply(gpointer data, guint action)
1902 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1903 MainWindow *mainwin;
1904 MessageView *msgview;
1905 GSList *msginfo_list = NULL;
1907 g_return_if_fail(toolbar_item != NULL);
1909 switch (toolbar_item->type) {
1911 mainwin = (MainWindow*)toolbar_item->parent;
1912 msginfo_list = summary_get_selection(mainwin->summaryview);
1913 msgview = (MessageView*)mainwin->messageview;
1915 case TOOLBAR_MSGVIEW:
1916 msgview = (MessageView*)toolbar_item->parent;
1917 g_return_if_fail(msgview != NULL);
1918 msginfo_list = g_slist_append(msginfo_list, msgview->msginfo);
1924 g_return_if_fail(msgview != NULL);
1925 g_return_if_fail(msginfo_list != NULL);
1926 compose_reply_from_messageview(msgview, msginfo_list, action);
1927 g_slist_free(msginfo_list);
1929 /* TODO: update reply state ion summaryview */
1933 /* exported functions */
1935 void inc_mail_cb(gpointer data, guint action, GtkWidget *widget)
1937 MainWindow *mainwin = (MainWindow*)data;
1939 inc_mail(mainwin, prefs_common.newmail_notify_manu);
1942 void inc_all_account_mail_cb(gpointer data, guint action, GtkWidget *widget)
1944 MainWindow *mainwin = (MainWindow*)data;
1946 inc_all_account_mail(mainwin, FALSE, prefs_common.newmail_notify_manu);
1949 void send_queue_cb(gpointer data, guint action, GtkWidget *widget)
1954 if (prefs_common.work_offline)
1955 if (alertpanel(_("Offline warning"),
1956 _("You're working offline. Override?"),
1957 GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT)
1960 /* ask for confirmation before sending queued messages only
1961 in online mode and if there is at least one message queued
1962 in any of the folder queue
1964 if (prefs_common.confirm_send_queued_messages) {
1966 /* check if there's a queued message */
1967 for (list = folder_get_list(); !found && list != NULL; list = list->next) {
1968 Folder *folder = list->data;
1970 found = !procmsg_queue_is_empty(folder->queue);
1972 /* if necessary, ask for confirmation before sending */
1973 if (found && !prefs_common.work_offline) {
1974 if (alertpanel(_("Send queued messages"),
1975 _("Send all queued messages?"),
1976 GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT)
1981 for (list = folder_get_list(); list != NULL; list = list->next) {
1982 Folder *folder = list->data;
1984 if (folder->queue) {
1985 if (procmsg_send_queue(folder->queue,
1986 prefs_common.savemsg) < 0)
1987 alertpanel_error(_("Some errors occurred while "
1988 "sending queued messages."));
1993 void compose_mail_cb(gpointer data, guint action, GtkWidget *widget)
1995 MainWindow *mainwin = (MainWindow*)data;
1996 PrefsAccount *ac = NULL;
1997 FolderItem *item = mainwin->summaryview->folder_item;
2002 ac = account_find_from_item(item);
2003 if (ac && ac->protocol != A_NNTP) {
2004 compose_new_with_folderitem(ac, item); /* CLAWS */
2010 * CLAWS - use current account
2012 if (cur_account && (cur_account->protocol != A_NNTP)) {
2013 compose_new_with_folderitem(cur_account, item);
2018 * CLAWS - just get the first one
2020 list = account_get_list();
2021 for (cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2022 ac = (PrefsAccount *) cur->data;
2023 if (ac->protocol != A_NNTP) {
2024 compose_new_with_folderitem(ac, item);
2030 void compose_news_cb(gpointer data, guint action, GtkWidget *widget)
2032 MainWindow *mainwin = (MainWindow*)data;
2033 PrefsAccount * ac = NULL;
2037 if (mainwin->summaryview->folder_item) {
2038 ac = mainwin->summaryview->folder_item->folder->account;
2039 if (ac && ac->protocol == A_NNTP) {
2041 mainwin->summaryview->folder_item->path,
2047 list = account_get_list();
2048 for(cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2049 ac = (PrefsAccount *) cur->data;
2050 if (ac->protocol == A_NNTP) {
2051 compose_new(ac, NULL, NULL);