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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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));
309 if (main_items[i] == A_PRINT) {
310 g_print("$$$ descr %s, trans %s\n",
311 toolbar_text[main_items[i]].descr,
312 gettext(toolbar_text[main_items[i]].descr));
316 else if (source == TOOLBAR_COMPOSE) {
317 gint comp_items[] = { A_SEND, A_SENDL, A_DRAFT,
318 A_INSERT, A_ATTACH, A_SIG,
319 A_EXTEDITOR, A_LINEWRAP_CURRENT,
320 A_LINEWRAP_ALL, A_ADDRBOOK,
326 for (i = 0; i < sizeof comp_items / sizeof comp_items[0]; i++)
327 items = g_list_append(items, gettext(toolbar_text[comp_items[i]].descr));
329 else if (source == TOOLBAR_MSGVIEW) {
330 gint msgv_items[] = { A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER,
331 A_REPLY_ALL, A_REPLY_ML, A_FORWARD,
332 A_TRASH, A_DELETE_REAL, A_GOTO_PREV, A_GOTO_NEXT,
333 A_ADDRBOOK, A_SYL_ACTIONS };
335 for (i = 0; i < sizeof msgv_items / sizeof msgv_items[0]; i++)
336 items = g_list_append(items, gettext(toolbar_text[msgv_items[i]].descr));
342 static void toolbar_parse_item(XMLFile *file, ToolbarType source)
346 ToolbarItem *item = NULL;
347 gboolean rewrite = FALSE;
349 attr = xml_get_current_tag_attr(file);
350 item = g_new0(ToolbarItem, 1);
352 name = ((XMLAttr *)attr->data)->name;
353 value = ((XMLAttr *)attr->data)->value;
355 if (g_utf8_collate(name, TOOLBAR_ICON_FILE) == 0)
356 item->file = g_strdup (value);
357 else if (g_utf8_collate(name, TOOLBAR_ICON_TEXT) == 0)
358 item->text = g_strdup (value);
359 else if (g_utf8_collate(name, TOOLBAR_ICON_ACTION) == 0)
360 item->index = toolbar_ret_val_from_text(value);
361 if (item->index == -1 && !strcmp(value, "A_DELETE")) {
363 item->index = A_TRASH;
365 item->file = g_strdup("trash_btn");
367 item->text = g_strdup(_("Trash"));
370 attr = g_list_next(attr);
372 if (item->index != -1) {
374 if (!toolbar_is_duplicate(item->index, source))
375 toolbar_config[source].item_list = g_slist_append(toolbar_config[source].item_list,
379 toolbar_save_config_file(source);
383 static void toolbar_set_default_main(void)
389 } default_toolbar[] = {
390 { A_RECEIVE_CUR, STOCK_PIXMAP_MAIL_RECEIVE, _("Get") },
391 { A_RECEIVE_ALL, STOCK_PIXMAP_MAIL_RECEIVE_ALL, _("Get All") },
392 { A_SEPARATOR, 0, ("") },
393 { A_SEND_QUEUED, STOCK_PIXMAP_MAIL_SEND_QUEUE, _("Send") },
394 { A_COMPOSE_EMAIL, STOCK_PIXMAP_MAIL_COMPOSE, _("Email") },
395 { A_SEPARATOR, 0, ("") },
396 { A_REPLY_MESSAGE, STOCK_PIXMAP_MAIL_REPLY, _("Reply") },
397 { A_REPLY_ALL, STOCK_PIXMAP_MAIL_REPLY_TO_ALL, _("All") },
398 { A_REPLY_SENDER, STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR, _("Sender") },
399 { A_FORWARD, STOCK_PIXMAP_MAIL_FORWARD, _("Forward") },
400 { A_SEPARATOR, 0, ("") },
401 { A_TRASH, STOCK_PIXMAP_TRASH, _("Trash") },
402 { A_EXECUTE, STOCK_PIXMAP_EXEC, _("Execute") },
403 { A_GOTO_PREV, STOCK_PIXMAP_UP_ARROW, _("Previous")},
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_SIG, STOCK_PIXMAP_MAIL_SIGN, _("Signature") },
448 { A_SEPARATOR, 0, ("") },
449 { A_EXTEDITOR, STOCK_PIXMAP_EDIT_EXTERN, _("Editor") },
450 { A_LINEWRAP_CURRENT, STOCK_PIXMAP_LINEWRAP_CURRENT, _("Wrap paragraph") },
451 { A_LINEWRAP_ALL, STOCK_PIXMAP_LINEWRAP_ALL, _("Wrap all") },
452 { A_SEPARATOR, 0, ("") },
453 { A_ADDRBOOK, STOCK_PIXMAP_ADDRESS_BOOK, _("Address") }
458 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
460 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
462 if (default_toolbar[i].action != A_SEPARATOR) {
464 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
466 toolbar_item->file = g_strdup(file);
467 toolbar_item->index = default_toolbar[i].action;
468 toolbar_item->text = g_strdup(default_toolbar[i].text);
471 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
472 toolbar_item->index = A_SEPARATOR;
475 if (toolbar_item->index != -1) {
476 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_COMPOSE))
477 toolbar_config[TOOLBAR_COMPOSE].item_list =
478 g_slist_append(toolbar_config[TOOLBAR_COMPOSE].item_list, toolbar_item);
483 static void toolbar_set_default_msgview(void)
489 } default_toolbar[] = {
490 { A_REPLY_MESSAGE, STOCK_PIXMAP_MAIL_REPLY, _("Reply") },
491 { A_REPLY_ALL, STOCK_PIXMAP_MAIL_REPLY_TO_ALL, _("All") },
492 { A_REPLY_SENDER, STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR, _("Sender") },
493 { A_FORWARD, STOCK_PIXMAP_MAIL_FORWARD, _("Forward") },
494 { A_SEPARATOR, 0, ("") },
495 { A_TRASH, STOCK_PIXMAP_TRASH, _("Trash") },
496 { A_GOTO_NEXT, STOCK_PIXMAP_DOWN_ARROW, _("Next") }
501 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
503 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
505 if (default_toolbar[i].action != A_SEPARATOR) {
507 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
509 toolbar_item->file = g_strdup(file);
510 toolbar_item->index = default_toolbar[i].action;
511 toolbar_item->text = g_strdup(default_toolbar[i].text);
514 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
515 toolbar_item->index = A_SEPARATOR;
518 if (toolbar_item->index != -1) {
519 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MSGVIEW))
520 toolbar_config[TOOLBAR_MSGVIEW].item_list =
521 g_slist_append(toolbar_config[TOOLBAR_MSGVIEW].item_list, toolbar_item);
526 void toolbar_set_default(ToolbarType source)
528 if (source == TOOLBAR_MAIN)
529 toolbar_set_default_main();
530 else if (source == TOOLBAR_COMPOSE)
531 toolbar_set_default_compose();
532 else if (source == TOOLBAR_MSGVIEW)
533 toolbar_set_default_msgview();
536 void toolbar_save_config_file(ToolbarType source)
541 gchar *fileSpec = NULL;
543 debug_print("save Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
545 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
546 pfile = prefs_write_open(fileSpec);
550 fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL);
552 fprintf(fp, "<%s>\n", TOOLBAR_TAG_INDEX);
554 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
555 ToolbarItem *toolbar_item = (ToolbarItem*) cur->data;
557 if (toolbar_item->index != A_SEPARATOR) {
558 fprintf(fp, "\t<%s %s=\"%s\" %s=\"",
560 TOOLBAR_ICON_FILE, toolbar_item->file,
562 xml_file_put_escape_str(fp, toolbar_item->text);
563 fprintf(fp, "\" %s=\"%s\"/>\n",
565 toolbar_ret_text_from_val(toolbar_item->index));
567 fprintf(fp, "\t<%s/>\n", TOOLBAR_TAG_SEPARATOR);
571 fprintf(fp, "</%s>\n", TOOLBAR_TAG_INDEX);
573 if (prefs_file_close (pfile) < 0 )
574 g_warning("failed to write toolbar configuration to file\n");
576 g_warning("failed to open toolbar configuration file for writing\n");
579 void toolbar_read_config_file(ToolbarType source)
581 XMLFile *file = NULL;
582 gchar *fileSpec = NULL;
587 debug_print("read Toolbar Configuration from %s\n", toolbar_config[source].conf_file);
589 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
590 file = xml_open_file(fileSpec);
593 toolbar_clear_list(source);
597 || (xml_get_dtd(file))
598 || (xml_parse_next_tag(file))
599 || (!xml_compare_tag(file, TOOLBAR_TAG_INDEX))) {
600 xml_close_file(file);
604 attr = xml_get_current_tag_attr(file);
611 if (xml_parse_next_tag(file))
614 /* Get next tag (icon, icon_text or icon_action) */
615 if (xml_compare_tag(file, TOOLBAR_TAG_ITEM)) {
616 toolbar_parse_item(file, source);
617 } else if (xml_compare_tag(file, TOOLBAR_TAG_SEPARATOR)) {
618 ToolbarItem *item = g_new0(ToolbarItem, 1);
620 item->file = g_strdup(toolbar_ret_descr_from_val(A_SEPARATOR));
621 item->index = A_SEPARATOR;
622 toolbar_config[source].item_list =
623 g_slist_append(toolbar_config[source].item_list, item);
627 xml_close_file(file);
630 if ((!file) || (g_slist_length(toolbar_config[source].item_list) == 0)) {
632 if (source == TOOLBAR_MAIN)
633 toolbar_set_default(TOOLBAR_MAIN);
634 else if (source == TOOLBAR_COMPOSE)
635 toolbar_set_default(TOOLBAR_COMPOSE);
636 else if (source == TOOLBAR_MSGVIEW)
637 toolbar_set_default(TOOLBAR_MSGVIEW);
639 g_warning("failed to write Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
643 toolbar_save_config_file(source);
648 * clears list of toolbar items read from configuration files
650 void toolbar_clear_list(ToolbarType source)
652 while (toolbar_config[source].item_list != NULL) {
653 ToolbarItem *item = (ToolbarItem*) toolbar_config[source].item_list->data;
655 toolbar_config[source].item_list =
656 g_slist_remove(toolbar_config[source].item_list, item);
664 g_slist_free(toolbar_config[source].item_list);
669 * return list of Toolbar items
671 GSList *toolbar_get_list(ToolbarType source)
675 if ((source == TOOLBAR_MAIN) || (source == TOOLBAR_COMPOSE) || (source == TOOLBAR_MSGVIEW))
676 list = toolbar_config[source].item_list;
681 void toolbar_set_list_item(ToolbarItem *t_item, ToolbarType source)
683 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
685 toolbar_item->file = g_strdup(t_item->file);
686 toolbar_item->text = g_strdup(t_item->text);
687 toolbar_item->index = t_item->index;
689 toolbar_config[source].item_list =
690 g_slist_append(toolbar_config[source].item_list,
694 void toolbar_action_execute(GtkWidget *widget,
700 gchar *action, *action_p;
701 gboolean found = FALSE;
704 for (cur = action_list; cur != NULL; cur = cur->next) {
705 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
707 if (widget == act->widget) {
709 for (lop = prefs_common.actions_list; lop != NULL; lop = lop->next) {
710 action = g_strdup((gchar*)lop->data);
712 action_p = strstr(action, ": ");
714 if (g_utf8_collate(act->name, action) == 0) {
728 actions_execute(data, i, widget, source);
730 g_warning ("Error: did not find Sylpheed Action to execute");
733 static void activate_compose_button (Toolbar *toolbar,
735 ComposeButtonType type)
737 if ((!toolbar->compose_mail_btn) || (!toolbar->compose_news_btn))
740 gtk_widget_hide(type == COMPOSEBUTTON_NEWS ? toolbar->compose_mail_btn
741 : toolbar->compose_news_btn);
742 gtk_widget_show(type == COMPOSEBUTTON_NEWS ? toolbar->compose_news_btn
743 : toolbar->compose_mail_btn);
744 toolbar->compose_btn_type = type;
747 void toolbar_set_compose_button(Toolbar *toolbar,
748 ComposeButtonType compose_btn_type)
750 if (toolbar->compose_btn_type != compose_btn_type)
751 activate_compose_button(toolbar,
752 prefs_common.toolbar_style,
756 void toolbar_toggle(guint action, gpointer data)
758 MainWindow *mainwin = (MainWindow*)data;
762 g_return_if_fail(mainwin != NULL);
764 toolbar_style(TOOLBAR_MAIN, action, mainwin);
766 list = compose_get_compose_list();
767 for (cur = list; cur != NULL; cur = cur->next) {
768 toolbar_style(TOOLBAR_COMPOSE, action, cur->data);
770 list = messageview_get_msgview_list();
771 for (cur = list; cur != NULL; cur = cur->next) {
772 toolbar_style(TOOLBAR_MSGVIEW, action, cur->data);
777 void toolbar_set_style(GtkWidget *toolbar_wid, GtkWidget *handlebox_wid, guint action)
779 switch ((ToolbarStyle)action) {
781 gtk_widget_hide(handlebox_wid);
784 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
788 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
792 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
799 prefs_common.toolbar_style = (ToolbarStyle)action;
800 gtk_widget_set_size_request(handlebox_wid, 1, -1);
802 if (prefs_common.toolbar_style != TOOLBAR_NONE) {
803 gtk_widget_show(handlebox_wid);
804 gtk_widget_queue_resize(handlebox_wid);
808 * Change the style of toolbar
810 static void toolbar_style(ToolbarType type, guint action, gpointer data)
812 GtkWidget *handlebox_wid;
813 GtkWidget *toolbar_wid;
814 MainWindow *mainwin = (MainWindow*)data;
815 Compose *compose = (Compose*)data;
816 MessageView *msgview = (MessageView*)data;
818 g_return_if_fail(data != NULL);
822 handlebox_wid = mainwin->handlebox;
823 toolbar_wid = mainwin->toolbar->toolbar;
825 case TOOLBAR_COMPOSE:
826 handlebox_wid = compose->handlebox;
827 toolbar_wid = compose->toolbar->toolbar;
829 case TOOLBAR_MSGVIEW:
830 handlebox_wid = msgview->handlebox;
831 toolbar_wid = msgview->toolbar->toolbar;
837 toolbar_set_style(toolbar_wid, handlebox_wid, action);
840 /* Toolbar handling */
841 static void toolbar_inc_cb(GtkWidget *widget,
844 ToolbarItem *toolbar_item = (ToolbarItem*)data;
847 g_return_if_fail(toolbar_item != NULL);
849 switch (toolbar_item->type) {
851 mainwin = (MainWindow*)toolbar_item->parent;
852 inc_mail_cb(mainwin, 0, NULL);
859 static void toolbar_inc_all_cb(GtkWidget *widget,
862 ToolbarItem *toolbar_item = (ToolbarItem*)data;
865 g_return_if_fail(toolbar_item != NULL);
867 switch (toolbar_item->type) {
869 mainwin = (MainWindow*)toolbar_item->parent;
870 inc_all_account_mail_cb(mainwin, 0, NULL);
877 static void toolbar_send_queued_cb(GtkWidget *widget,gpointer data)
879 ToolbarItem *toolbar_item = (ToolbarItem*)data;
882 g_return_if_fail(toolbar_item != NULL);
884 switch (toolbar_item->type) {
886 mainwin = (MainWindow*)toolbar_item->parent;
887 send_queue_cb(mainwin, 0, NULL);
894 static void toolbar_exec_cb(GtkWidget *widget,
897 MainWindow *mainwin = get_mainwin(data);
899 g_return_if_fail(mainwin != NULL);
900 summary_execute(mainwin->summaryview);
904 * Delete current/selected(s) message(s)
906 static void toolbar_trash_cb(GtkWidget *widget, gpointer data)
908 ToolbarItem *toolbar_item = (ToolbarItem*)data;
911 g_return_if_fail(toolbar_item != NULL);
912 g_return_if_fail(toolbar_item->parent);
914 switch (toolbar_item->type) {
915 case TOOLBAR_MSGVIEW:
916 messageview_delete((MessageView *)toolbar_item->parent);
919 mainwin = (MainWindow *)toolbar_item->parent;
920 summary_delete_trash(mainwin->summaryview);
923 debug_print("toolbar event not supported\n");
929 * Delete current/selected(s) message(s)
931 static void toolbar_delete_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(mainwin->summaryview);
948 debug_print("toolbar event not supported\n");
955 * Compose new message
957 static void toolbar_compose_cb(GtkWidget *widget, gpointer data)
959 ToolbarItem *toolbar_item = (ToolbarItem*)data;
961 MessageView *msgview;
963 g_return_if_fail(toolbar_item != NULL);
965 switch (toolbar_item->type) {
967 mainwin = (MainWindow*)toolbar_item->parent;
968 if (mainwin->toolbar->compose_btn_type == COMPOSEBUTTON_NEWS)
969 compose_news_cb(mainwin, 0, NULL);
971 compose_mail_cb(mainwin, 0, NULL);
973 case TOOLBAR_MSGVIEW:
974 msgview = (MessageView*)toolbar_item->parent;
975 compose_new_with_folderitem(NULL,
976 msgview->msginfo->folder);
979 debug_print("toolbar event not supported\n");
987 static void toolbar_reply_cb(GtkWidget *widget, gpointer data)
989 toolbar_reply(data, prefs_common.reply_with_quote ?
990 COMPOSE_REPLY_WITH_QUOTE : COMPOSE_REPLY_WITHOUT_QUOTE);
995 * Reply message to Sender and All recipients
997 static void toolbar_reply_to_all_cb(GtkWidget *widget, gpointer data)
1000 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_ALL_WITH_QUOTE
1001 : COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE);
1006 * Reply to Mailing List
1008 static void toolbar_reply_to_list_cb(GtkWidget *widget, gpointer data)
1011 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_LIST_WITH_QUOTE
1012 : COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE);
1017 * Reply to sender of message
1019 static void toolbar_reply_to_sender_cb(GtkWidget *widget, gpointer data)
1022 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_SENDER_WITH_QUOTE
1023 : COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE);
1029 static void toolbar_addrbook_cb(GtkWidget *widget, gpointer data)
1031 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1034 g_return_if_fail(toolbar_item != NULL);
1036 switch (toolbar_item->type) {
1038 case TOOLBAR_MSGVIEW:
1041 case TOOLBAR_COMPOSE:
1042 compose = (Compose *)toolbar_item->parent;
1047 addressbook_open(compose);
1052 * Forward current/selected(s) message(s)
1054 static void toolbar_forward_cb(GtkWidget *widget, gpointer data)
1056 toolbar_reply(data, COMPOSE_FORWARD);
1060 * Goto Prev Unread Message
1062 static void toolbar_prev_unread_cb(GtkWidget *widget, gpointer data)
1064 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1065 MainWindow *mainwin;
1066 MessageView *msgview;
1068 g_return_if_fail(toolbar_item != NULL);
1070 switch (toolbar_item->type) {
1072 mainwin = (MainWindow*)toolbar_item->parent;
1073 summary_select_prev_unread(mainwin->summaryview);
1076 case TOOLBAR_MSGVIEW:
1077 msgview = (MessageView*)toolbar_item->parent;
1078 summary_select_prev_unread(msgview->mainwin->summaryview);
1080 /* Now we need to update the messageview window */
1081 if (msgview->mainwin->summaryview->selected) {
1082 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1084 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1085 msgview->mainwin->summaryview->selected);
1087 messageview_show(msgview, msginfo,
1088 msgview->all_headers);
1090 gtk_widget_destroy(msgview->window);
1094 debug_print("toolbar event not supported\n");
1099 * Goto Next Unread Message
1101 static void toolbar_next_unread_cb(GtkWidget *widget, gpointer data)
1103 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1104 MainWindow *mainwin;
1105 MessageView *msgview;
1107 g_return_if_fail(toolbar_item != NULL);
1109 switch (toolbar_item->type) {
1111 mainwin = (MainWindow*)toolbar_item->parent;
1112 summary_select_next_unread(mainwin->summaryview);
1115 case TOOLBAR_MSGVIEW:
1116 msgview = (MessageView*)toolbar_item->parent;
1117 summary_select_next_unread(msgview->mainwin->summaryview);
1119 /* Now we need to update the messageview window */
1120 if (msgview->mainwin->summaryview->selected) {
1121 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1123 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1124 msgview->mainwin->summaryview->selected);
1126 messageview_show(msgview, msginfo,
1127 msgview->all_headers);
1129 gtk_widget_destroy(msgview->window);
1133 debug_print("toolbar event not supported\n");
1137 static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data)
1139 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1140 MainWindow *mainwin;
1142 g_return_if_fail(toolbar_item != NULL);
1144 switch (toolbar_item->type) {
1146 mainwin = (MainWindow *) toolbar_item->parent;
1147 summary_toggle_ignore_thread(mainwin->summaryview);
1149 case TOOLBAR_MSGVIEW:
1150 /* TODO: see toolbar_next_unread_cb() if you need
1151 * this in the message view */
1154 debug_print("toolbar event not supported\n");
1159 static void toolbar_print_cb(GtkWidget *widget, gpointer data)
1161 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1162 MainWindow *mainwin;
1164 g_return_if_fail(toolbar_item != NULL);
1166 switch (toolbar_item->type) {
1168 mainwin = (MainWindow *) toolbar_item->parent;
1169 summary_print(mainwin->summaryview);
1171 case TOOLBAR_MSGVIEW:
1172 /* TODO: see toolbar_next_unread_cb() if you need
1173 * this in the message view */
1176 debug_print("toolbar event not supported\n");
1181 static void toolbar_send_cb(GtkWidget *widget, gpointer data)
1183 compose_toolbar_cb(A_SEND, data);
1186 static void toolbar_send_later_cb(GtkWidget *widget, gpointer data)
1188 compose_toolbar_cb(A_SENDL, data);
1191 static void toolbar_draft_cb(GtkWidget *widget, gpointer data)
1193 compose_toolbar_cb(A_DRAFT, data);
1196 static void toolbar_insert_cb(GtkWidget *widget, gpointer data)
1198 compose_toolbar_cb(A_INSERT, data);
1201 static void toolbar_attach_cb(GtkWidget *widget, gpointer data)
1203 compose_toolbar_cb(A_ATTACH, data);
1206 static void toolbar_sig_cb(GtkWidget *widget, gpointer data)
1208 compose_toolbar_cb(A_SIG, data);
1211 static void toolbar_ext_editor_cb(GtkWidget *widget, gpointer data)
1213 compose_toolbar_cb(A_EXTEDITOR, data);
1216 static void toolbar_linewrap_current_cb(GtkWidget *widget, gpointer data)
1218 compose_toolbar_cb(A_LINEWRAP_CURRENT, data);
1221 static void toolbar_linewrap_all_cb(GtkWidget *widget, gpointer data)
1223 compose_toolbar_cb(A_LINEWRAP_ALL, data);
1227 static void toolbar_check_spelling_cb(GtkWidget *widget, gpointer data)
1229 compose_toolbar_cb(A_CHECK_SPELLING, data);
1233 * Execute actions from toolbar
1235 static void toolbar_actions_execute_cb(GtkWidget *widget, gpointer data)
1237 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1238 GSList *action_list;
1239 MainWindow *mainwin;
1241 MessageView *msgview;
1242 gpointer parent = toolbar_item->parent;
1244 g_return_if_fail(toolbar_item != NULL);
1246 switch (toolbar_item->type) {
1248 mainwin = (MainWindow*)parent;
1249 action_list = mainwin->toolbar->action_list;
1251 case TOOLBAR_COMPOSE:
1252 compose = (Compose*)parent;
1253 action_list = compose->toolbar->action_list;
1255 case TOOLBAR_MSGVIEW:
1256 msgview = (MessageView*)parent;
1257 action_list = msgview->toolbar->action_list;
1260 debug_print("toolbar event not supported\n");
1263 toolbar_action_execute(widget, action_list, parent, toolbar_item->type);
1266 static MainWindow *get_mainwin(gpointer data)
1268 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1269 MainWindow *mainwin = NULL;
1270 MessageView *msgview;
1272 g_return_val_if_fail(toolbar_item != NULL, NULL);
1274 switch(toolbar_item->type) {
1276 mainwin = (MainWindow*)toolbar_item->parent;
1278 case TOOLBAR_MSGVIEW:
1279 msgview = (MessageView*)toolbar_item->parent;
1280 mainwin = (MainWindow*)msgview->mainwin;
1289 static void toolbar_buttons_cb(GtkWidget *widget,
1296 void (*func)(GtkWidget *widget, gpointer data);
1298 { A_RECEIVE_ALL, toolbar_inc_all_cb },
1299 { A_RECEIVE_CUR, toolbar_inc_cb },
1300 { A_SEND_QUEUED, toolbar_send_queued_cb },
1301 { A_COMPOSE_EMAIL, toolbar_compose_cb },
1302 { A_COMPOSE_NEWS, toolbar_compose_cb },
1303 { A_REPLY_MESSAGE, toolbar_reply_cb },
1304 { A_REPLY_SENDER, toolbar_reply_to_sender_cb },
1305 { A_REPLY_ALL, toolbar_reply_to_all_cb },
1306 { A_REPLY_ML, toolbar_reply_to_list_cb },
1307 { A_FORWARD, toolbar_forward_cb },
1308 { A_TRASH, toolbar_trash_cb },
1309 { A_DELETE_REAL, toolbar_delete_cb },
1310 { A_EXECUTE, toolbar_exec_cb },
1311 { A_GOTO_PREV, toolbar_prev_unread_cb },
1312 { A_GOTO_NEXT, toolbar_next_unread_cb },
1313 { A_IGNORE_THREAD, toolbar_ignore_thread_cb },
1314 { A_PRINT, toolbar_print_cb },
1316 { A_SEND, toolbar_send_cb },
1317 { A_SENDL, toolbar_send_later_cb },
1318 { A_DRAFT, toolbar_draft_cb },
1319 { A_INSERT, toolbar_insert_cb },
1320 { A_ATTACH, toolbar_attach_cb },
1321 { A_SIG, toolbar_sig_cb },
1322 { A_EXTEDITOR, toolbar_ext_editor_cb },
1323 { A_LINEWRAP_CURRENT, toolbar_linewrap_current_cb },
1324 { A_LINEWRAP_ALL, toolbar_linewrap_all_cb },
1325 { A_ADDRBOOK, toolbar_addrbook_cb },
1327 { A_CHECK_SPELLING, toolbar_check_spelling_cb },
1329 { A_SYL_ACTIONS, toolbar_actions_execute_cb }
1332 num_items = sizeof(callbacks)/sizeof(callbacks[0]);
1334 for (i = 0; i < num_items; i++) {
1335 if (callbacks[i].index == item->index) {
1336 callbacks[i].func(widget, item);
1343 * Create a new toolbar with specified type
1344 * if a callback list is passed it will be used before the
1345 * common callback list
1347 Toolbar *toolbar_create(ToolbarType type,
1348 GtkWidget *container,
1351 ToolbarItem *toolbar_item;
1354 GtkWidget *icon_wid = NULL;
1355 GtkWidget *icon_news;
1357 GtkWidget *item_news;
1359 guint n_menu_entries;
1360 ComboButton *reply_combo;
1361 ComboButton *replyall_combo;
1362 ComboButton *replylist_combo;
1363 ComboButton *replysender_combo;
1364 ComboButton *fwd_combo;
1366 GtkTooltips *toolbar_tips;
1367 ToolbarSylpheedActions *action_item;
1369 GSList *toolbar_list;
1370 Toolbar *toolbar_data;
1373 toolbar_tips = gtk_tooltips_new();
1375 toolbar_read_config_file(type);
1376 toolbar_list = toolbar_get_list(type);
1378 toolbar_data = g_new0(Toolbar, 1);
1380 toolbar = gtk_toolbar_new();
1381 gtk_container_add(GTK_CONTAINER(container), toolbar);
1382 gtk_container_set_border_width(GTK_CONTAINER(container), 2);
1383 gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1384 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
1386 for (cur = toolbar_list; cur != NULL; cur = cur->next) {
1388 if (g_ascii_strcasecmp(((ToolbarItem*)cur->data)->file, TOOLBAR_TAG_SEPARATOR) == 0) {
1389 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
1393 toolbar_item = g_new0(ToolbarItem, 1);
1394 toolbar_item->index = ((ToolbarItem*)cur->data)->index;
1395 toolbar_item->file = g_strdup(((ToolbarItem*)cur->data)->file);
1396 toolbar_item->text = g_strdup(((ToolbarItem*)cur->data)->text);
1397 toolbar_item->parent = data;
1398 toolbar_item->type = type;
1400 /* collect toolbar items in list to keep track */
1401 toolbar_data->item_list =
1402 g_slist_append(toolbar_data->item_list,
1405 icon_wid = stock_pixmap_widget(container, stock_pixmap_get_icon(toolbar_item->file));
1406 item = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1410 icon_wid, G_CALLBACK(toolbar_buttons_cb),
1413 switch (toolbar_item->index) {
1416 toolbar_data->getall_btn = item;
1417 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1418 toolbar_data->getall_btn,
1419 _("Receive Mail on all Accounts"), NULL);
1422 toolbar_data->get_btn = item;
1423 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1424 toolbar_data->get_btn,
1425 _("Receive Mail on current Account"), NULL);
1428 toolbar_data->send_btn = item;
1429 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1430 toolbar_data->send_btn,
1431 _("Send Queued Messages"), NULL);
1433 case A_COMPOSE_EMAIL:
1434 icon_news = stock_pixmap_widget(container, STOCK_PIXMAP_NEWS_COMPOSE);
1435 item_news = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1439 icon_news, G_CALLBACK(toolbar_buttons_cb),
1441 toolbar_data->compose_mail_btn = item;
1442 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1443 toolbar_data->compose_mail_btn,
1444 _("Compose Email"), NULL);
1445 toolbar_data->compose_news_btn = item_news;
1446 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1447 toolbar_data->compose_news_btn,
1448 _("Compose News"), NULL);
1450 case A_REPLY_MESSAGE:
1451 toolbar_data->reply_btn = item;
1452 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1453 toolbar_data->reply_btn,
1454 _("Reply to Message"), NULL);
1455 n_menu_entries = sizeof(reply_entries) /
1456 sizeof(reply_entries[0]);
1457 reply_combo = gtkut_combo_button_create(toolbar_data->reply_btn,
1458 reply_entries, n_menu_entries,
1459 "<Reply>", (gpointer)toolbar_item);
1460 gtk_button_set_relief(GTK_BUTTON(reply_combo->arrow),
1462 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1463 GTK_WIDGET_PTR(reply_combo),
1464 _("Reply to Message"), "Reply");
1465 toolbar_data->reply_combo = reply_combo;
1467 case A_REPLY_SENDER:
1468 toolbar_data->replysender_btn = item;
1469 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1470 toolbar_data->replysender_btn,
1471 _("Reply to Sender"), NULL);
1472 n_menu_entries = sizeof(replysender_entries) /
1473 sizeof(replysender_entries[0]);
1474 replysender_combo = gtkut_combo_button_create(toolbar_data->replysender_btn,
1475 replysender_entries, n_menu_entries,
1476 "<ReplySender>", (gpointer)toolbar_item);
1477 gtk_button_set_relief(GTK_BUTTON(replysender_combo->arrow),
1479 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1480 GTK_WIDGET_PTR(replysender_combo),
1481 _("Reply to Sender"), "ReplySender");
1482 toolbar_data->replysender_combo = replysender_combo;
1485 toolbar_data->replyall_btn = item;
1486 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1487 toolbar_data->replyall_btn,
1488 _("Reply to All"), NULL);
1489 n_menu_entries = sizeof(replyall_entries) /
1490 sizeof(replyall_entries[0]);
1491 replyall_combo = gtkut_combo_button_create(toolbar_data->replyall_btn,
1492 replyall_entries, n_menu_entries,
1493 "<ReplyAll>", (gpointer)toolbar_item);
1494 gtk_button_set_relief(GTK_BUTTON(replyall_combo->arrow),
1496 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1497 GTK_WIDGET_PTR(replyall_combo),
1498 _("Reply to All"), "ReplyAll");
1499 toolbar_data->replyall_combo = replyall_combo;
1502 toolbar_data->replylist_btn = item;
1503 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1504 toolbar_data->replylist_btn,
1505 _("Reply to Mailing-list"), NULL);
1506 n_menu_entries = sizeof(replylist_entries) /
1507 sizeof(replylist_entries[0]);
1508 replylist_combo = gtkut_combo_button_create(toolbar_data->replylist_btn,
1509 replylist_entries, n_menu_entries,
1510 "<ReplyList>", (gpointer)toolbar_item);
1511 gtk_button_set_relief(GTK_BUTTON(replylist_combo->arrow),
1513 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1514 GTK_WIDGET_PTR(replylist_combo),
1515 _("Reply to Mailing-list"), "ReplyList");
1516 toolbar_data->replylist_combo = replylist_combo;
1519 toolbar_data->fwd_btn = item;
1520 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1521 toolbar_data->fwd_btn,
1522 _("Forward Message"), NULL);
1523 n_menu_entries = sizeof(forward_entries) /
1524 sizeof(forward_entries[0]);
1525 fwd_combo = gtkut_combo_button_create(toolbar_data->fwd_btn,
1526 forward_entries, n_menu_entries,
1527 "<Forward>", (gpointer)toolbar_item);
1528 gtk_button_set_relief(GTK_BUTTON(fwd_combo->arrow),
1530 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1531 GTK_WIDGET_PTR(fwd_combo),
1532 _("Forward Message"), "Fwd");
1533 toolbar_data->fwd_combo = fwd_combo;
1536 toolbar_data->trash_btn = item;
1537 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1538 toolbar_data->trash_btn,
1539 _("Trash Message"), NULL);
1542 toolbar_data->delete_btn = item;
1543 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1544 toolbar_data->delete_btn,
1545 _("Delete Message"), NULL);
1548 toolbar_data->exec_btn = item;
1549 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1550 toolbar_data->exec_btn,
1551 _("Execute"), NULL);
1554 toolbar_data->prev_btn = item;
1555 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1556 toolbar_data->prev_btn,
1557 _("Go to Previous Unread Message"),
1561 toolbar_data->next_btn = item;
1562 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1563 toolbar_data->next_btn,
1564 _("Go to Next Unread Message"),
1568 /* Compose Toolbar */
1570 toolbar_data->send_btn = item;
1571 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1572 toolbar_data->send_btn,
1573 _("Send Message"), NULL);
1576 toolbar_data->sendl_btn = item;
1577 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1578 toolbar_data->sendl_btn,
1579 _("Put into queue folder and send later"), NULL);
1582 toolbar_data->draft_btn = item;
1583 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1584 toolbar_data->draft_btn,
1585 _("Save to draft folder"), NULL);
1588 toolbar_data->insert_btn = item;
1589 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1590 toolbar_data->insert_btn,
1591 _("Insert file"), NULL);
1594 toolbar_data->attach_btn = item;
1595 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1596 toolbar_data->attach_btn,
1597 _("Attach file"), NULL);
1600 toolbar_data->sig_btn = item;
1601 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1602 toolbar_data->sig_btn,
1603 _("Insert signature"), NULL);
1606 toolbar_data->exteditor_btn = item;
1607 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1608 toolbar_data->exteditor_btn,
1609 _("Edit with external editor"), NULL);
1611 case A_LINEWRAP_CURRENT:
1612 toolbar_data->linewrap_current_btn = item;
1613 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1614 toolbar_data->linewrap_current_btn,
1615 _("Wrap long lines of current paragraph"), NULL);
1617 case A_LINEWRAP_ALL:
1618 toolbar_data->linewrap_all_btn = item;
1619 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1620 toolbar_data->linewrap_all_btn,
1621 _("Wrap all long lines"), NULL);
1624 toolbar_data->addrbook_btn = item;
1625 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1626 toolbar_data->addrbook_btn,
1627 _("Address book"), NULL);
1630 case A_CHECK_SPELLING:
1631 toolbar_data->spellcheck_btn = item;
1632 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1633 toolbar_data->spellcheck_btn,
1634 _("Check spelling"), NULL);
1639 action_item = g_new0(ToolbarSylpheedActions, 1);
1640 action_item->widget = item;
1641 action_item->name = g_strdup(toolbar_item->text);
1643 toolbar_data->action_list =
1644 g_slist_append(toolbar_data->action_list,
1647 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1649 action_item->name, NULL);
1651 gtk_widget_show(item);
1654 /* find and set the tool tip text */
1655 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1657 toolbar_ret_descr_from_val
1658 (toolbar_item->index),
1664 toolbar_data->toolbar = toolbar;
1665 if (type == TOOLBAR_MAIN)
1666 activate_compose_button(toolbar_data,
1667 prefs_common.toolbar_style,
1668 toolbar_data->compose_btn_type);
1670 gtk_widget_show_all(toolbar);
1672 return toolbar_data;
1676 * Free toolbar structures
1678 void toolbar_destroy(Toolbar * toolbar) {
1680 TOOLBAR_DESTROY_ITEMS(toolbar->item_list);
1681 TOOLBAR_DESTROY_ACTIONS(toolbar->action_list);
1684 void toolbar_update(ToolbarType type, gpointer data)
1686 Toolbar *toolbar_data;
1687 GtkWidget *handlebox;
1688 MainWindow *mainwin = (MainWindow*)data;
1689 Compose *compose = (Compose*)data;
1690 MessageView *msgview = (MessageView*)data;
1694 toolbar_data = mainwin->toolbar;
1695 handlebox = mainwin->handlebox;
1697 case TOOLBAR_COMPOSE:
1698 toolbar_data = compose->toolbar;
1699 handlebox = compose->handlebox;
1701 case TOOLBAR_MSGVIEW:
1702 toolbar_data = msgview->toolbar;
1703 handlebox = msgview->handlebox;
1709 gtk_container_remove(GTK_CONTAINER(handlebox),
1710 GTK_WIDGET(toolbar_data->toolbar));
1712 toolbar_init(toolbar_data);
1713 toolbar_data = toolbar_create(type, handlebox, data);
1716 mainwin->toolbar = toolbar_data;
1718 case TOOLBAR_COMPOSE:
1719 compose->toolbar = toolbar_data;
1721 case TOOLBAR_MSGVIEW:
1722 msgview->toolbar = toolbar_data;
1726 toolbar_style(type, prefs_common.toolbar_style, data);
1728 if (type == TOOLBAR_MAIN)
1729 toolbar_main_set_sensitive((MainWindow*)data);
1732 void toolbar_main_set_sensitive(gpointer data)
1734 SensitiveCond state;
1736 MainWindow *mainwin = (MainWindow*)data;
1737 Toolbar *toolbar = mainwin->toolbar;
1739 GSList *entry_list = NULL;
1741 typedef struct _Entry Entry;
1748 #define SET_WIDGET_COND(w, c) \
1750 Entry *e = g_new0(Entry, 1); \
1753 entry_list = g_slist_append(entry_list, e); \
1756 SET_WIDGET_COND(toolbar->get_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1757 SET_WIDGET_COND(toolbar->getall_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1758 SET_WIDGET_COND(toolbar->compose_news_btn, M_HAVE_ACCOUNT);
1759 SET_WIDGET_COND(toolbar->reply_btn,
1760 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1761 if (toolbar->reply_btn)
1762 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->reply_combo),
1763 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1764 SET_WIDGET_COND(toolbar->replyall_btn,
1765 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1766 if (toolbar->replyall_btn)
1767 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replyall_combo),
1768 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1769 SET_WIDGET_COND(toolbar->replylist_btn,
1770 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1771 if (toolbar->replylist_btn)
1772 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replylist_combo),
1773 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1774 SET_WIDGET_COND(toolbar->replysender_btn,
1775 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1776 if (toolbar->replysender_btn)
1777 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replysender_combo),
1778 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1779 SET_WIDGET_COND(toolbar->fwd_btn, M_HAVE_ACCOUNT|M_TARGET_EXIST);
1780 if (toolbar->fwd_btn)
1781 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->fwd_combo),
1782 M_HAVE_ACCOUNT|M_TARGET_EXIST);
1783 if (toolbar->fwd_combo) {
1784 GtkWidget *submenu = gtk_item_factory_get_widget(toolbar->fwd_combo->factory, "/Redirect");
1785 SET_WIDGET_COND(submenu, M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1788 if (prefs_common.next_unread_msg_dialog == NEXTUNREADMSGDIALOG_ASSUME_NO) {
1789 SET_WIDGET_COND(toolbar->next_btn, M_MSG_EXIST);
1791 SET_WIDGET_COND(toolbar->next_btn, 0);
1794 SET_WIDGET_COND(toolbar->trash_btn,
1795 M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED);
1796 SET_WIDGET_COND(toolbar->delete_btn,
1797 M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED);
1798 SET_WIDGET_COND(toolbar->exec_btn, M_DELAY_EXEC);
1800 for (cur = toolbar->action_list; cur != NULL; cur = cur->next) {
1801 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
1803 SET_WIDGET_COND(act->widget, M_TARGET_EXIST|M_UNLOCKED);
1806 #undef SET_WIDGET_COND
1808 state = main_window_get_current_state(mainwin);
1810 for (cur = entry_list; cur != NULL; cur = cur->next) {
1811 Entry *e = (Entry*) cur->data;
1813 if (e->widget != NULL) {
1814 sensitive = ((e->cond & state) == e->cond);
1815 gtk_widget_set_sensitive(e->widget, sensitive);
1819 while (entry_list != NULL) {
1820 Entry *e = (Entry*) entry_list->data;
1824 entry_list = g_slist_remove(entry_list, e);
1827 g_slist_free(entry_list);
1829 activate_compose_button(toolbar,
1830 prefs_common.toolbar_style,
1831 toolbar->compose_btn_type);
1834 void toolbar_comp_set_sensitive(gpointer data, gboolean sensitive)
1836 Compose *compose = (Compose*)data;
1837 GSList *items = compose->toolbar->action_list;
1839 if (compose->toolbar->send_btn)
1840 gtk_widget_set_sensitive(compose->toolbar->send_btn, sensitive);
1841 if (compose->toolbar->sendl_btn)
1842 gtk_widget_set_sensitive(compose->toolbar->sendl_btn, sensitive);
1843 if (compose->toolbar->draft_btn )
1844 gtk_widget_set_sensitive(compose->toolbar->draft_btn , sensitive);
1845 if (compose->toolbar->insert_btn )
1846 gtk_widget_set_sensitive(compose->toolbar->insert_btn , sensitive);
1847 if (compose->toolbar->attach_btn)
1848 gtk_widget_set_sensitive(compose->toolbar->attach_btn, sensitive);
1849 if (compose->toolbar->sig_btn)
1850 gtk_widget_set_sensitive(compose->toolbar->sig_btn, sensitive);
1851 if (compose->toolbar->exteditor_btn)
1852 gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, sensitive);
1853 if (compose->toolbar->linewrap_current_btn)
1854 gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, sensitive);
1855 if (compose->toolbar->linewrap_all_btn)
1856 gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, sensitive);
1857 if (compose->toolbar->addrbook_btn)
1858 gtk_widget_set_sensitive(compose->toolbar->addrbook_btn, sensitive);
1860 if (compose->toolbar->spellcheck_btn)
1861 gtk_widget_set_sensitive(compose->toolbar->spellcheck_btn, sensitive);
1863 for (; items != NULL; items = g_slist_next(items)) {
1864 ToolbarSylpheedActions *item = (ToolbarSylpheedActions *)items->data;
1865 gtk_widget_set_sensitive(item->widget, sensitive);
1870 * Initialize toolbar structure
1872 void toolbar_init(Toolbar * toolbar) {
1874 toolbar->toolbar = NULL;
1875 toolbar->get_btn = NULL;
1876 toolbar->getall_btn = NULL;
1877 toolbar->send_btn = NULL;
1878 toolbar->compose_mail_btn = NULL;
1879 toolbar->compose_news_btn = NULL;
1880 toolbar->reply_btn = NULL;
1881 toolbar->replysender_btn = NULL;
1882 toolbar->replyall_btn = NULL;
1883 toolbar->replylist_btn = NULL;
1884 toolbar->fwd_btn = NULL;
1885 toolbar->trash_btn = NULL;
1886 toolbar->delete_btn = NULL;
1887 toolbar->prev_btn = NULL;
1888 toolbar->next_btn = NULL;
1889 toolbar->exec_btn = NULL;
1891 /* compose buttons */
1892 toolbar->sendl_btn = NULL;
1893 toolbar->draft_btn = NULL;
1894 toolbar->insert_btn = NULL;
1895 toolbar->attach_btn = NULL;
1896 toolbar->sig_btn = NULL;
1897 toolbar->exteditor_btn = NULL;
1898 toolbar->linewrap_current_btn = NULL;
1899 toolbar->linewrap_all_btn = NULL;
1900 toolbar->addrbook_btn = NULL;
1902 toolbar->spellcheck_btn = NULL;
1905 toolbar_destroy(toolbar);
1910 static void toolbar_reply(gpointer data, guint action)
1912 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1913 MainWindow *mainwin;
1914 MessageView *msgview;
1915 GSList *msginfo_list = NULL;
1917 g_return_if_fail(toolbar_item != NULL);
1919 switch (toolbar_item->type) {
1921 mainwin = (MainWindow*)toolbar_item->parent;
1922 msginfo_list = summary_get_selection(mainwin->summaryview);
1923 msgview = (MessageView*)mainwin->messageview;
1925 case TOOLBAR_MSGVIEW:
1926 msgview = (MessageView*)toolbar_item->parent;
1927 g_return_if_fail(msgview != NULL);
1928 msginfo_list = g_slist_append(msginfo_list, msgview->msginfo);
1934 g_return_if_fail(msgview != NULL);
1935 g_return_if_fail(msginfo_list != NULL);
1936 compose_reply_from_messageview(msgview, msginfo_list, action);
1937 g_slist_free(msginfo_list);
1939 /* TODO: update reply state ion summaryview */
1943 /* exported functions */
1945 void inc_mail_cb(gpointer data, guint action, GtkWidget *widget)
1947 MainWindow *mainwin = (MainWindow*)data;
1949 inc_mail(mainwin, prefs_common.newmail_notify_manu);
1952 void inc_all_account_mail_cb(gpointer data, guint action, GtkWidget *widget)
1954 MainWindow *mainwin = (MainWindow*)data;
1956 inc_all_account_mail(mainwin, FALSE, prefs_common.newmail_notify_manu);
1959 void send_queue_cb(gpointer data, guint action, GtkWidget *widget)
1964 if (prefs_common.work_offline)
1965 if (alertpanel(_("Offline warning"),
1966 _("You're working offline. Override?"),
1967 GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT)
1970 /* ask for confirmation before sending queued messages only
1971 in online mode and if there is at least one message queued
1972 in any of the folder queue
1974 if (prefs_common.confirm_send_queued_messages) {
1976 /* check if there's a queued message */
1977 for (list = folder_get_list(); !found && list != NULL; list = list->next) {
1978 Folder *folder = list->data;
1980 found = !procmsg_queue_is_empty(folder->queue);
1982 /* if necessary, ask for confirmation before sending */
1983 if (found && !prefs_common.work_offline) {
1984 if (alertpanel(_("Send queued messages"),
1985 _("Send all queued messages?"),
1986 GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT)
1991 for (list = folder_get_list(); list != NULL; list = list->next) {
1992 Folder *folder = list->data;
1994 if (folder->queue) {
1995 if (procmsg_send_queue(folder->queue,
1996 prefs_common.savemsg) < 0)
1997 alertpanel_error(_("Some errors occurred while "
1998 "sending queued messages."));
1999 folder_item_scan(folder->queue);
2004 void compose_mail_cb(gpointer data, guint action, GtkWidget *widget)
2006 MainWindow *mainwin = (MainWindow*)data;
2007 PrefsAccount *ac = NULL;
2008 FolderItem *item = mainwin->summaryview->folder_item;
2013 ac = account_find_from_item(item);
2014 if (ac && ac->protocol != A_NNTP) {
2015 compose_new_with_folderitem(ac, item); /* CLAWS */
2021 * CLAWS - use current account
2023 if (cur_account && (cur_account->protocol != A_NNTP)) {
2024 compose_new_with_folderitem(cur_account, item);
2029 * CLAWS - just get the first one
2031 list = account_get_list();
2032 for (cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2033 ac = (PrefsAccount *) cur->data;
2034 if (ac->protocol != A_NNTP) {
2035 compose_new_with_folderitem(ac, item);
2041 void compose_news_cb(gpointer data, guint action, GtkWidget *widget)
2043 MainWindow *mainwin = (MainWindow*)data;
2044 PrefsAccount * ac = NULL;
2048 if (mainwin->summaryview->folder_item) {
2049 ac = mainwin->summaryview->folder_item->folder->account;
2050 if (ac && ac->protocol == A_NNTP) {
2052 mainwin->summaryview->folder_item->path,
2058 list = account_get_list();
2059 for(cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2060 ac = (PrefsAccount *) cur->data;
2061 if (ac->protocol == A_NNTP) {
2062 compose_new(ac, NULL, NULL);