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, _("Email") },
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_EXECUTE, STOCK_PIXMAP_EXEC, _("Execute") },
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_SIG, STOCK_PIXMAP_MAIL_SIGN, _("Signature") },
443 { A_SEPARATOR, 0, ("") },
444 { A_EXTEDITOR, STOCK_PIXMAP_EDIT_EXTERN, _("Editor") },
445 { A_LINEWRAP_CURRENT, STOCK_PIXMAP_LINEWRAP_CURRENT, _("Wrap paragraph") },
446 { A_LINEWRAP_ALL, STOCK_PIXMAP_LINEWRAP_ALL, _("Wrap all") },
447 { A_SEPARATOR, 0, ("") },
448 { A_ADDRBOOK, STOCK_PIXMAP_ADDRESS_BOOK, _("Address") }
453 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
455 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
457 if (default_toolbar[i].action != A_SEPARATOR) {
459 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
461 toolbar_item->file = g_strdup(file);
462 toolbar_item->index = default_toolbar[i].action;
463 toolbar_item->text = g_strdup(default_toolbar[i].text);
466 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
467 toolbar_item->index = A_SEPARATOR;
470 if (toolbar_item->index != -1) {
471 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_COMPOSE))
472 toolbar_config[TOOLBAR_COMPOSE].item_list =
473 g_slist_append(toolbar_config[TOOLBAR_COMPOSE].item_list, toolbar_item);
478 static void toolbar_set_default_msgview(void)
484 } default_toolbar[] = {
485 { A_REPLY_MESSAGE, STOCK_PIXMAP_MAIL_REPLY, _("Reply") },
486 { A_REPLY_ALL, STOCK_PIXMAP_MAIL_REPLY_TO_ALL, _("All") },
487 { A_REPLY_SENDER, STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR, _("Sender") },
488 { A_FORWARD, STOCK_PIXMAP_MAIL_FORWARD, _("Forward") },
489 { A_SEPARATOR, 0, ("") },
490 { A_TRASH, STOCK_PIXMAP_TRASH, _("Trash") },
491 { A_GOTO_NEXT, STOCK_PIXMAP_DOWN_ARROW, _("Next") }
496 for (i = 0; i < sizeof(default_toolbar) / sizeof(default_toolbar[0]); i++) {
498 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
500 if (default_toolbar[i].action != A_SEPARATOR) {
502 gchar *file = stock_pixmap_get_name((StockPixmap)default_toolbar[i].icon);
504 toolbar_item->file = g_strdup(file);
505 toolbar_item->index = default_toolbar[i].action;
506 toolbar_item->text = g_strdup(default_toolbar[i].text);
509 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR);
510 toolbar_item->index = A_SEPARATOR;
513 if (toolbar_item->index != -1) {
514 if ( !toolbar_is_duplicate(toolbar_item->index, TOOLBAR_MSGVIEW))
515 toolbar_config[TOOLBAR_MSGVIEW].item_list =
516 g_slist_append(toolbar_config[TOOLBAR_MSGVIEW].item_list, toolbar_item);
521 void toolbar_set_default(ToolbarType source)
523 if (source == TOOLBAR_MAIN)
524 toolbar_set_default_main();
525 else if (source == TOOLBAR_COMPOSE)
526 toolbar_set_default_compose();
527 else if (source == TOOLBAR_MSGVIEW)
528 toolbar_set_default_msgview();
531 void toolbar_save_config_file(ToolbarType source)
536 gchar *fileSpec = NULL;
538 debug_print("save Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
540 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
541 pfile = prefs_write_open(fileSpec);
545 fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL);
547 fprintf(fp, "<%s>\n", TOOLBAR_TAG_INDEX);
549 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) {
550 ToolbarItem *toolbar_item = (ToolbarItem*) cur->data;
552 if (toolbar_item->index != A_SEPARATOR) {
553 fprintf(fp, "\t<%s %s=\"%s\" %s=\"",
555 TOOLBAR_ICON_FILE, toolbar_item->file,
557 xml_file_put_escape_str(fp, toolbar_item->text);
558 fprintf(fp, "\" %s=\"%s\"/>\n",
560 toolbar_ret_text_from_val(toolbar_item->index));
562 fprintf(fp, "\t<%s/>\n", TOOLBAR_TAG_SEPARATOR);
566 fprintf(fp, "</%s>\n", TOOLBAR_TAG_INDEX);
568 if (prefs_file_close (pfile) < 0 )
569 g_warning("failed to write toolbar configuration to file\n");
571 g_warning("failed to open toolbar configuration file for writing\n");
574 void toolbar_read_config_file(ToolbarType source)
576 XMLFile *file = NULL;
577 gchar *fileSpec = NULL;
582 debug_print("read Toolbar Configuration from %s\n", toolbar_config[source].conf_file);
584 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL );
585 file = xml_open_file(fileSpec);
588 toolbar_clear_list(source);
592 || (xml_get_dtd(file))
593 || (xml_parse_next_tag(file))
594 || (!xml_compare_tag(file, TOOLBAR_TAG_INDEX))) {
595 xml_close_file(file);
599 attr = xml_get_current_tag_attr(file);
606 if (xml_parse_next_tag(file))
609 /* Get next tag (icon, icon_text or icon_action) */
610 if (xml_compare_tag(file, TOOLBAR_TAG_ITEM)) {
611 toolbar_parse_item(file, source);
612 } else if (xml_compare_tag(file, TOOLBAR_TAG_SEPARATOR)) {
613 ToolbarItem *item = g_new0(ToolbarItem, 1);
615 item->file = g_strdup(toolbar_ret_descr_from_val(A_SEPARATOR));
616 item->index = A_SEPARATOR;
617 toolbar_config[source].item_list =
618 g_slist_append(toolbar_config[source].item_list, item);
622 xml_close_file(file);
625 if ((!file) || (g_slist_length(toolbar_config[source].item_list) == 0)) {
627 if (source == TOOLBAR_MAIN)
628 toolbar_set_default(TOOLBAR_MAIN);
629 else if (source == TOOLBAR_COMPOSE)
630 toolbar_set_default(TOOLBAR_COMPOSE);
631 else if (source == TOOLBAR_MSGVIEW)
632 toolbar_set_default(TOOLBAR_MSGVIEW);
634 g_warning("failed to write Toolbar Configuration to %s\n", toolbar_config[source].conf_file);
638 toolbar_save_config_file(source);
643 * clears list of toolbar items read from configuration files
645 void toolbar_clear_list(ToolbarType source)
647 while (toolbar_config[source].item_list != NULL) {
648 ToolbarItem *item = (ToolbarItem*) toolbar_config[source].item_list->data;
650 toolbar_config[source].item_list =
651 g_slist_remove(toolbar_config[source].item_list, item);
659 g_slist_free(toolbar_config[source].item_list);
664 * return list of Toolbar items
666 GSList *toolbar_get_list(ToolbarType source)
670 if ((source == TOOLBAR_MAIN) || (source == TOOLBAR_COMPOSE) || (source == TOOLBAR_MSGVIEW))
671 list = toolbar_config[source].item_list;
676 void toolbar_set_list_item(ToolbarItem *t_item, ToolbarType source)
678 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1);
680 toolbar_item->file = g_strdup(t_item->file);
681 toolbar_item->text = g_strdup(t_item->text);
682 toolbar_item->index = t_item->index;
684 toolbar_config[source].item_list =
685 g_slist_append(toolbar_config[source].item_list,
689 void toolbar_action_execute(GtkWidget *widget,
695 gchar *action, *action_p;
696 gboolean found = FALSE;
699 for (cur = action_list; cur != NULL; cur = cur->next) {
700 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
702 if (widget == act->widget) {
704 for (lop = prefs_common.actions_list; lop != NULL; lop = lop->next) {
705 action = g_strdup((gchar*)lop->data);
707 action_p = strstr(action, ": ");
709 if (g_utf8_collate(act->name, action) == 0) {
723 actions_execute(data, i, widget, source);
725 g_warning ("Error: did not find Sylpheed Action to execute");
728 static void activate_compose_button (Toolbar *toolbar,
730 ComposeButtonType type)
732 if ((!toolbar->compose_mail_btn) || (!toolbar->compose_news_btn))
735 gtk_widget_hide(type == COMPOSEBUTTON_NEWS ? toolbar->compose_mail_btn
736 : toolbar->compose_news_btn);
737 gtk_widget_show(type == COMPOSEBUTTON_NEWS ? toolbar->compose_news_btn
738 : toolbar->compose_mail_btn);
739 toolbar->compose_btn_type = type;
742 void toolbar_set_compose_button(Toolbar *toolbar,
743 ComposeButtonType compose_btn_type)
745 if (toolbar->compose_btn_type != compose_btn_type)
746 activate_compose_button(toolbar,
747 prefs_common.toolbar_style,
751 void toolbar_toggle(guint action, gpointer data)
753 MainWindow *mainwin = (MainWindow*)data;
757 g_return_if_fail(mainwin != NULL);
759 toolbar_style(TOOLBAR_MAIN, action, mainwin);
761 list = compose_get_compose_list();
762 for (cur = list; cur != NULL; cur = cur->next) {
763 toolbar_style(TOOLBAR_COMPOSE, action, cur->data);
765 list = messageview_get_msgview_list();
766 for (cur = list; cur != NULL; cur = cur->next) {
767 toolbar_style(TOOLBAR_MSGVIEW, action, cur->data);
772 void toolbar_set_style(GtkWidget *toolbar_wid, GtkWidget *handlebox_wid, guint action)
774 switch ((ToolbarStyle)action) {
776 gtk_widget_hide(handlebox_wid);
779 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
783 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
787 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid),
794 prefs_common.toolbar_style = (ToolbarStyle)action;
795 gtk_widget_set_size_request(handlebox_wid, 1, -1);
797 if (prefs_common.toolbar_style != TOOLBAR_NONE) {
798 gtk_widget_show(handlebox_wid);
799 gtk_widget_queue_resize(handlebox_wid);
803 * Change the style of toolbar
805 static void toolbar_style(ToolbarType type, guint action, gpointer data)
807 GtkWidget *handlebox_wid;
808 GtkWidget *toolbar_wid;
809 MainWindow *mainwin = (MainWindow*)data;
810 Compose *compose = (Compose*)data;
811 MessageView *msgview = (MessageView*)data;
813 g_return_if_fail(data != NULL);
817 handlebox_wid = mainwin->handlebox;
818 toolbar_wid = mainwin->toolbar->toolbar;
820 case TOOLBAR_COMPOSE:
821 handlebox_wid = compose->handlebox;
822 toolbar_wid = compose->toolbar->toolbar;
824 case TOOLBAR_MSGVIEW:
825 handlebox_wid = msgview->handlebox;
826 toolbar_wid = msgview->toolbar->toolbar;
832 toolbar_set_style(toolbar_wid, handlebox_wid, action);
835 /* Toolbar handling */
836 static void toolbar_inc_cb(GtkWidget *widget,
839 ToolbarItem *toolbar_item = (ToolbarItem*)data;
842 g_return_if_fail(toolbar_item != NULL);
844 switch (toolbar_item->type) {
846 mainwin = (MainWindow*)toolbar_item->parent;
847 inc_mail_cb(mainwin, 0, NULL);
854 static void toolbar_inc_all_cb(GtkWidget *widget,
857 ToolbarItem *toolbar_item = (ToolbarItem*)data;
860 g_return_if_fail(toolbar_item != NULL);
862 switch (toolbar_item->type) {
864 mainwin = (MainWindow*)toolbar_item->parent;
865 inc_all_account_mail_cb(mainwin, 0, NULL);
872 static void toolbar_send_queued_cb(GtkWidget *widget,gpointer data)
874 ToolbarItem *toolbar_item = (ToolbarItem*)data;
877 g_return_if_fail(toolbar_item != NULL);
879 switch (toolbar_item->type) {
881 mainwin = (MainWindow*)toolbar_item->parent;
882 send_queue_cb(mainwin, 0, NULL);
889 static void toolbar_exec_cb(GtkWidget *widget,
892 MainWindow *mainwin = get_mainwin(data);
894 g_return_if_fail(mainwin != NULL);
895 summary_execute(mainwin->summaryview);
899 * Delete current/selected(s) message(s)
901 static void toolbar_trash_cb(GtkWidget *widget, gpointer data)
903 ToolbarItem *toolbar_item = (ToolbarItem*)data;
906 g_return_if_fail(toolbar_item != NULL);
907 g_return_if_fail(toolbar_item->parent);
909 switch (toolbar_item->type) {
910 case TOOLBAR_MSGVIEW:
911 messageview_delete((MessageView *)toolbar_item->parent);
914 mainwin = (MainWindow *)toolbar_item->parent;
915 summary_delete_trash(mainwin->summaryview);
918 debug_print("toolbar event not supported\n");
924 * Delete current/selected(s) message(s)
926 static void toolbar_delete_cb(GtkWidget *widget, gpointer data)
928 ToolbarItem *toolbar_item = (ToolbarItem*)data;
931 g_return_if_fail(toolbar_item != NULL);
932 g_return_if_fail(toolbar_item->parent);
934 switch (toolbar_item->type) {
935 case TOOLBAR_MSGVIEW:
936 messageview_delete((MessageView *)toolbar_item->parent);
939 mainwin = (MainWindow *)toolbar_item->parent;
940 summary_delete(mainwin->summaryview);
943 debug_print("toolbar event not supported\n");
950 * Compose new message
952 static void toolbar_compose_cb(GtkWidget *widget, gpointer data)
954 ToolbarItem *toolbar_item = (ToolbarItem*)data;
956 MessageView *msgview;
958 g_return_if_fail(toolbar_item != NULL);
960 switch (toolbar_item->type) {
962 mainwin = (MainWindow*)toolbar_item->parent;
963 if (mainwin->toolbar->compose_btn_type == COMPOSEBUTTON_NEWS)
964 compose_news_cb(mainwin, 0, NULL);
966 compose_mail_cb(mainwin, 0, NULL);
968 case TOOLBAR_MSGVIEW:
969 msgview = (MessageView*)toolbar_item->parent;
970 compose_new_with_folderitem(NULL,
971 msgview->msginfo->folder);
974 debug_print("toolbar event not supported\n");
982 static void toolbar_reply_cb(GtkWidget *widget, gpointer data)
984 toolbar_reply(data, prefs_common.reply_with_quote ?
985 COMPOSE_REPLY_WITH_QUOTE : COMPOSE_REPLY_WITHOUT_QUOTE);
990 * Reply message to Sender and All recipients
992 static void toolbar_reply_to_all_cb(GtkWidget *widget, gpointer data)
995 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_ALL_WITH_QUOTE
996 : COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE);
1001 * Reply to Mailing List
1003 static void toolbar_reply_to_list_cb(GtkWidget *widget, gpointer data)
1006 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_LIST_WITH_QUOTE
1007 : COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE);
1012 * Reply to sender of message
1014 static void toolbar_reply_to_sender_cb(GtkWidget *widget, gpointer data)
1017 prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_SENDER_WITH_QUOTE
1018 : COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE);
1024 static void toolbar_addrbook_cb(GtkWidget *widget, gpointer data)
1026 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1029 g_return_if_fail(toolbar_item != NULL);
1031 switch (toolbar_item->type) {
1033 case TOOLBAR_MSGVIEW:
1036 case TOOLBAR_COMPOSE:
1037 compose = (Compose *)toolbar_item->parent;
1042 addressbook_open(compose);
1047 * Forward current/selected(s) message(s)
1049 static void toolbar_forward_cb(GtkWidget *widget, gpointer data)
1051 toolbar_reply(data, COMPOSE_FORWARD);
1055 * Goto Prev Unread Message
1057 static void toolbar_prev_unread_cb(GtkWidget *widget, gpointer data)
1059 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1060 MainWindow *mainwin;
1061 MessageView *msgview;
1063 g_return_if_fail(toolbar_item != NULL);
1065 switch (toolbar_item->type) {
1067 mainwin = (MainWindow*)toolbar_item->parent;
1068 summary_select_prev_unread(mainwin->summaryview);
1071 case TOOLBAR_MSGVIEW:
1072 msgview = (MessageView*)toolbar_item->parent;
1073 summary_select_prev_unread(msgview->mainwin->summaryview);
1075 /* Now we need to update the messageview window */
1076 if (msgview->mainwin->summaryview->selected) {
1077 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1079 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1080 msgview->mainwin->summaryview->selected);
1082 messageview_show(msgview, msginfo,
1083 msgview->all_headers);
1085 gtk_widget_destroy(msgview->window);
1089 debug_print("toolbar event not supported\n");
1094 * Goto Next Unread Message
1096 static void toolbar_next_unread_cb(GtkWidget *widget, gpointer data)
1098 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1099 MainWindow *mainwin;
1100 MessageView *msgview;
1102 g_return_if_fail(toolbar_item != NULL);
1104 switch (toolbar_item->type) {
1106 mainwin = (MainWindow*)toolbar_item->parent;
1107 summary_select_next_unread(mainwin->summaryview);
1110 case TOOLBAR_MSGVIEW:
1111 msgview = (MessageView*)toolbar_item->parent;
1112 summary_select_next_unread(msgview->mainwin->summaryview);
1114 /* Now we need to update the messageview window */
1115 if (msgview->mainwin->summaryview->selected) {
1116 GtkCTree *ctree = GTK_CTREE(msgview->mainwin->summaryview->ctree);
1118 MsgInfo * msginfo = gtk_ctree_node_get_row_data(ctree,
1119 msgview->mainwin->summaryview->selected);
1121 messageview_show(msgview, msginfo,
1122 msgview->all_headers);
1124 gtk_widget_destroy(msgview->window);
1128 debug_print("toolbar event not supported\n");
1132 static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data)
1134 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1135 MainWindow *mainwin;
1137 g_return_if_fail(toolbar_item != NULL);
1139 switch (toolbar_item->type) {
1141 mainwin = (MainWindow *) toolbar_item->parent;
1142 summary_toggle_ignore_thread(mainwin->summaryview);
1144 case TOOLBAR_MSGVIEW:
1145 /* TODO: see toolbar_next_unread_cb() if you need
1146 * this in the message view */
1149 debug_print("toolbar event not supported\n");
1154 static void toolbar_print_cb(GtkWidget *widget, gpointer data)
1156 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1157 MainWindow *mainwin;
1159 g_return_if_fail(toolbar_item != NULL);
1161 switch (toolbar_item->type) {
1163 mainwin = (MainWindow *) toolbar_item->parent;
1164 summary_print(mainwin->summaryview);
1166 case TOOLBAR_MSGVIEW:
1167 /* TODO: see toolbar_next_unread_cb() if you need
1168 * this in the message view */
1171 debug_print("toolbar event not supported\n");
1176 static void toolbar_send_cb(GtkWidget *widget, gpointer data)
1178 compose_toolbar_cb(A_SEND, data);
1181 static void toolbar_send_later_cb(GtkWidget *widget, gpointer data)
1183 compose_toolbar_cb(A_SENDL, data);
1186 static void toolbar_draft_cb(GtkWidget *widget, gpointer data)
1188 compose_toolbar_cb(A_DRAFT, data);
1191 static void toolbar_insert_cb(GtkWidget *widget, gpointer data)
1193 compose_toolbar_cb(A_INSERT, data);
1196 static void toolbar_attach_cb(GtkWidget *widget, gpointer data)
1198 compose_toolbar_cb(A_ATTACH, data);
1201 static void toolbar_sig_cb(GtkWidget *widget, gpointer data)
1203 compose_toolbar_cb(A_SIG, data);
1206 static void toolbar_ext_editor_cb(GtkWidget *widget, gpointer data)
1208 compose_toolbar_cb(A_EXTEDITOR, data);
1211 static void toolbar_linewrap_current_cb(GtkWidget *widget, gpointer data)
1213 compose_toolbar_cb(A_LINEWRAP_CURRENT, data);
1216 static void toolbar_linewrap_all_cb(GtkWidget *widget, gpointer data)
1218 compose_toolbar_cb(A_LINEWRAP_ALL, data);
1222 static void toolbar_check_spelling_cb(GtkWidget *widget, gpointer data)
1224 compose_toolbar_cb(A_CHECK_SPELLING, data);
1228 * Execute actions from toolbar
1230 static void toolbar_actions_execute_cb(GtkWidget *widget, gpointer data)
1232 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1233 GSList *action_list;
1234 MainWindow *mainwin;
1236 MessageView *msgview;
1237 gpointer parent = toolbar_item->parent;
1239 g_return_if_fail(toolbar_item != NULL);
1241 switch (toolbar_item->type) {
1243 mainwin = (MainWindow*)parent;
1244 action_list = mainwin->toolbar->action_list;
1246 case TOOLBAR_COMPOSE:
1247 compose = (Compose*)parent;
1248 action_list = compose->toolbar->action_list;
1250 case TOOLBAR_MSGVIEW:
1251 msgview = (MessageView*)parent;
1252 action_list = msgview->toolbar->action_list;
1255 debug_print("toolbar event not supported\n");
1258 toolbar_action_execute(widget, action_list, parent, toolbar_item->type);
1261 static MainWindow *get_mainwin(gpointer data)
1263 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1264 MainWindow *mainwin = NULL;
1265 MessageView *msgview;
1267 g_return_val_if_fail(toolbar_item != NULL, NULL);
1269 switch(toolbar_item->type) {
1271 mainwin = (MainWindow*)toolbar_item->parent;
1273 case TOOLBAR_MSGVIEW:
1274 msgview = (MessageView*)toolbar_item->parent;
1275 mainwin = (MainWindow*)msgview->mainwin;
1284 static void toolbar_buttons_cb(GtkWidget *widget,
1291 void (*func)(GtkWidget *widget, gpointer data);
1293 { A_RECEIVE_ALL, toolbar_inc_all_cb },
1294 { A_RECEIVE_CUR, toolbar_inc_cb },
1295 { A_SEND_QUEUED, toolbar_send_queued_cb },
1296 { A_COMPOSE_EMAIL, toolbar_compose_cb },
1297 { A_COMPOSE_NEWS, toolbar_compose_cb },
1298 { A_REPLY_MESSAGE, toolbar_reply_cb },
1299 { A_REPLY_SENDER, toolbar_reply_to_sender_cb },
1300 { A_REPLY_ALL, toolbar_reply_to_all_cb },
1301 { A_REPLY_ML, toolbar_reply_to_list_cb },
1302 { A_FORWARD, toolbar_forward_cb },
1303 { A_TRASH, toolbar_trash_cb },
1304 { A_DELETE_REAL, toolbar_delete_cb },
1305 { A_EXECUTE, toolbar_exec_cb },
1306 { A_GOTO_PREV, toolbar_prev_unread_cb },
1307 { A_GOTO_NEXT, toolbar_next_unread_cb },
1308 { A_IGNORE_THREAD, toolbar_ignore_thread_cb },
1309 { A_PRINT, toolbar_print_cb },
1311 { A_SEND, toolbar_send_cb },
1312 { A_SENDL, toolbar_send_later_cb },
1313 { A_DRAFT, toolbar_draft_cb },
1314 { A_INSERT, toolbar_insert_cb },
1315 { A_ATTACH, toolbar_attach_cb },
1316 { A_SIG, toolbar_sig_cb },
1317 { A_EXTEDITOR, toolbar_ext_editor_cb },
1318 { A_LINEWRAP_CURRENT, toolbar_linewrap_current_cb },
1319 { A_LINEWRAP_ALL, toolbar_linewrap_all_cb },
1320 { A_ADDRBOOK, toolbar_addrbook_cb },
1322 { A_CHECK_SPELLING, toolbar_check_spelling_cb },
1324 { A_SYL_ACTIONS, toolbar_actions_execute_cb }
1327 num_items = sizeof(callbacks)/sizeof(callbacks[0]);
1329 for (i = 0; i < num_items; i++) {
1330 if (callbacks[i].index == item->index) {
1331 callbacks[i].func(widget, item);
1338 * Create a new toolbar with specified type
1339 * if a callback list is passed it will be used before the
1340 * common callback list
1342 Toolbar *toolbar_create(ToolbarType type,
1343 GtkWidget *container,
1346 ToolbarItem *toolbar_item;
1349 GtkWidget *icon_wid = NULL;
1350 GtkWidget *icon_news;
1352 GtkWidget *item_news;
1354 guint n_menu_entries;
1355 ComboButton *reply_combo;
1356 ComboButton *replyall_combo;
1357 ComboButton *replylist_combo;
1358 ComboButton *replysender_combo;
1359 ComboButton *fwd_combo;
1361 GtkTooltips *toolbar_tips;
1362 ToolbarSylpheedActions *action_item;
1364 GSList *toolbar_list;
1365 Toolbar *toolbar_data;
1368 toolbar_tips = gtk_tooltips_new();
1370 toolbar_read_config_file(type);
1371 toolbar_list = toolbar_get_list(type);
1373 toolbar_data = g_new0(Toolbar, 1);
1375 toolbar = gtk_toolbar_new();
1376 gtk_container_add(GTK_CONTAINER(container), toolbar);
1377 gtk_container_set_border_width(GTK_CONTAINER(container), 2);
1378 gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1379 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
1381 for (cur = toolbar_list; cur != NULL; cur = cur->next) {
1383 if (g_ascii_strcasecmp(((ToolbarItem*)cur->data)->file, TOOLBAR_TAG_SEPARATOR) == 0) {
1384 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
1388 toolbar_item = g_new0(ToolbarItem, 1);
1389 toolbar_item->index = ((ToolbarItem*)cur->data)->index;
1390 toolbar_item->file = g_strdup(((ToolbarItem*)cur->data)->file);
1391 toolbar_item->text = g_strdup(((ToolbarItem*)cur->data)->text);
1392 toolbar_item->parent = data;
1393 toolbar_item->type = type;
1395 /* collect toolbar items in list to keep track */
1396 toolbar_data->item_list =
1397 g_slist_append(toolbar_data->item_list,
1400 icon_wid = stock_pixmap_widget(container, stock_pixmap_get_icon(toolbar_item->file));
1401 item = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1405 icon_wid, G_CALLBACK(toolbar_buttons_cb),
1408 switch (toolbar_item->index) {
1411 toolbar_data->getall_btn = item;
1412 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1413 toolbar_data->getall_btn,
1414 _("Receive Mail on all Accounts"), NULL);
1417 toolbar_data->get_btn = item;
1418 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1419 toolbar_data->get_btn,
1420 _("Receive Mail on current Account"), NULL);
1423 toolbar_data->send_btn = item;
1424 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1425 toolbar_data->send_btn,
1426 _("Send Queued Messages"), NULL);
1428 case A_COMPOSE_EMAIL:
1429 icon_news = stock_pixmap_widget(container, STOCK_PIXMAP_NEWS_COMPOSE);
1430 item_news = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
1434 icon_news, G_CALLBACK(toolbar_buttons_cb),
1436 toolbar_data->compose_mail_btn = item;
1437 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1438 toolbar_data->compose_mail_btn,
1439 _("Compose Email"), NULL);
1440 toolbar_data->compose_news_btn = item_news;
1441 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1442 toolbar_data->compose_news_btn,
1443 _("Compose News"), NULL);
1445 case A_REPLY_MESSAGE:
1446 toolbar_data->reply_btn = item;
1447 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1448 toolbar_data->reply_btn,
1449 _("Reply to Message"), NULL);
1450 n_menu_entries = sizeof(reply_entries) /
1451 sizeof(reply_entries[0]);
1452 reply_combo = gtkut_combo_button_create(toolbar_data->reply_btn,
1453 reply_entries, n_menu_entries,
1454 "<Reply>", (gpointer)toolbar_item);
1455 gtk_button_set_relief(GTK_BUTTON(reply_combo->arrow),
1457 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1458 GTK_WIDGET_PTR(reply_combo),
1459 _("Reply to Message"), "Reply");
1460 toolbar_data->reply_combo = reply_combo;
1462 case A_REPLY_SENDER:
1463 toolbar_data->replysender_btn = item;
1464 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1465 toolbar_data->replysender_btn,
1466 _("Reply to Sender"), NULL);
1467 n_menu_entries = sizeof(replysender_entries) /
1468 sizeof(replysender_entries[0]);
1469 replysender_combo = gtkut_combo_button_create(toolbar_data->replysender_btn,
1470 replysender_entries, n_menu_entries,
1471 "<ReplySender>", (gpointer)toolbar_item);
1472 gtk_button_set_relief(GTK_BUTTON(replysender_combo->arrow),
1474 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1475 GTK_WIDGET_PTR(replysender_combo),
1476 _("Reply to Sender"), "ReplySender");
1477 toolbar_data->replysender_combo = replysender_combo;
1480 toolbar_data->replyall_btn = item;
1481 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1482 toolbar_data->replyall_btn,
1483 _("Reply to All"), NULL);
1484 n_menu_entries = sizeof(replyall_entries) /
1485 sizeof(replyall_entries[0]);
1486 replyall_combo = gtkut_combo_button_create(toolbar_data->replyall_btn,
1487 replyall_entries, n_menu_entries,
1488 "<ReplyAll>", (gpointer)toolbar_item);
1489 gtk_button_set_relief(GTK_BUTTON(replyall_combo->arrow),
1491 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1492 GTK_WIDGET_PTR(replyall_combo),
1493 _("Reply to All"), "ReplyAll");
1494 toolbar_data->replyall_combo = replyall_combo;
1497 toolbar_data->replylist_btn = item;
1498 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1499 toolbar_data->replylist_btn,
1500 _("Reply to Mailing-list"), NULL);
1501 n_menu_entries = sizeof(replylist_entries) /
1502 sizeof(replylist_entries[0]);
1503 replylist_combo = gtkut_combo_button_create(toolbar_data->replylist_btn,
1504 replylist_entries, n_menu_entries,
1505 "<ReplyList>", (gpointer)toolbar_item);
1506 gtk_button_set_relief(GTK_BUTTON(replylist_combo->arrow),
1508 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1509 GTK_WIDGET_PTR(replylist_combo),
1510 _("Reply to Mailing-list"), "ReplyList");
1511 toolbar_data->replylist_combo = replylist_combo;
1514 toolbar_data->fwd_btn = item;
1515 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1516 toolbar_data->fwd_btn,
1517 _("Forward Message"), NULL);
1518 n_menu_entries = sizeof(forward_entries) /
1519 sizeof(forward_entries[0]);
1520 fwd_combo = gtkut_combo_button_create(toolbar_data->fwd_btn,
1521 forward_entries, n_menu_entries,
1522 "<Forward>", (gpointer)toolbar_item);
1523 gtk_button_set_relief(GTK_BUTTON(fwd_combo->arrow),
1525 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
1526 GTK_WIDGET_PTR(fwd_combo),
1527 _("Forward Message"), "Fwd");
1528 toolbar_data->fwd_combo = fwd_combo;
1531 toolbar_data->trash_btn = item;
1532 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1533 toolbar_data->trash_btn,
1534 _("Trash Message"), NULL);
1537 toolbar_data->delete_btn = item;
1538 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1539 toolbar_data->delete_btn,
1540 _("Delete Message"), NULL);
1543 toolbar_data->exec_btn = item;
1544 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1545 toolbar_data->exec_btn,
1546 _("Execute"), NULL);
1549 toolbar_data->prev_btn = item;
1550 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1551 toolbar_data->prev_btn,
1552 _("Go to Previous Unread Message"),
1556 toolbar_data->next_btn = item;
1557 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1558 toolbar_data->next_btn,
1559 _("Go to Next Unread Message"),
1563 /* Compose Toolbar */
1565 toolbar_data->send_btn = item;
1566 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1567 toolbar_data->send_btn,
1568 _("Send Message"), NULL);
1571 toolbar_data->sendl_btn = item;
1572 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1573 toolbar_data->sendl_btn,
1574 _("Put into queue folder and send later"), NULL);
1577 toolbar_data->draft_btn = item;
1578 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1579 toolbar_data->draft_btn,
1580 _("Save to draft folder"), NULL);
1583 toolbar_data->insert_btn = item;
1584 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1585 toolbar_data->insert_btn,
1586 _("Insert file"), NULL);
1589 toolbar_data->attach_btn = item;
1590 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1591 toolbar_data->attach_btn,
1592 _("Attach file"), NULL);
1595 toolbar_data->sig_btn = item;
1596 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1597 toolbar_data->sig_btn,
1598 _("Insert signature"), NULL);
1601 toolbar_data->exteditor_btn = item;
1602 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1603 toolbar_data->exteditor_btn,
1604 _("Edit with external editor"), NULL);
1606 case A_LINEWRAP_CURRENT:
1607 toolbar_data->linewrap_current_btn = item;
1608 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1609 toolbar_data->linewrap_current_btn,
1610 _("Wrap long lines of current paragraph"), NULL);
1612 case A_LINEWRAP_ALL:
1613 toolbar_data->linewrap_all_btn = item;
1614 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1615 toolbar_data->linewrap_all_btn,
1616 _("Wrap all long lines"), NULL);
1619 toolbar_data->addrbook_btn = item;
1620 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1621 toolbar_data->addrbook_btn,
1622 _("Address book"), NULL);
1625 case A_CHECK_SPELLING:
1626 toolbar_data->spellcheck_btn = item;
1627 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1628 toolbar_data->spellcheck_btn,
1629 _("Check spelling"), NULL);
1634 action_item = g_new0(ToolbarSylpheedActions, 1);
1635 action_item->widget = item;
1636 action_item->name = g_strdup(toolbar_item->text);
1638 toolbar_data->action_list =
1639 g_slist_append(toolbar_data->action_list,
1642 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1644 action_item->name, NULL);
1646 gtk_widget_show(item);
1649 /* find and set the tool tip text */
1650 gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips),
1652 toolbar_ret_descr_from_val
1653 (toolbar_item->index),
1659 toolbar_data->toolbar = toolbar;
1660 if (type == TOOLBAR_MAIN)
1661 activate_compose_button(toolbar_data,
1662 prefs_common.toolbar_style,
1663 toolbar_data->compose_btn_type);
1665 gtk_widget_show_all(toolbar);
1667 return toolbar_data;
1671 * Free toolbar structures
1673 void toolbar_destroy(Toolbar * toolbar) {
1675 TOOLBAR_DESTROY_ITEMS(toolbar->item_list);
1676 TOOLBAR_DESTROY_ACTIONS(toolbar->action_list);
1679 void toolbar_update(ToolbarType type, gpointer data)
1681 Toolbar *toolbar_data;
1682 GtkWidget *handlebox;
1683 MainWindow *mainwin = (MainWindow*)data;
1684 Compose *compose = (Compose*)data;
1685 MessageView *msgview = (MessageView*)data;
1689 toolbar_data = mainwin->toolbar;
1690 handlebox = mainwin->handlebox;
1692 case TOOLBAR_COMPOSE:
1693 toolbar_data = compose->toolbar;
1694 handlebox = compose->handlebox;
1696 case TOOLBAR_MSGVIEW:
1697 toolbar_data = msgview->toolbar;
1698 handlebox = msgview->handlebox;
1704 gtk_container_remove(GTK_CONTAINER(handlebox),
1705 GTK_WIDGET(toolbar_data->toolbar));
1707 toolbar_init(toolbar_data);
1708 toolbar_data = toolbar_create(type, handlebox, data);
1711 mainwin->toolbar = toolbar_data;
1713 case TOOLBAR_COMPOSE:
1714 compose->toolbar = toolbar_data;
1716 case TOOLBAR_MSGVIEW:
1717 msgview->toolbar = toolbar_data;
1721 toolbar_style(type, prefs_common.toolbar_style, data);
1723 if (type == TOOLBAR_MAIN)
1724 toolbar_main_set_sensitive((MainWindow*)data);
1727 void toolbar_main_set_sensitive(gpointer data)
1729 SensitiveCond state;
1731 MainWindow *mainwin = (MainWindow*)data;
1732 Toolbar *toolbar = mainwin->toolbar;
1734 GSList *entry_list = NULL;
1736 typedef struct _Entry Entry;
1743 #define SET_WIDGET_COND(w, c) \
1745 Entry *e = g_new0(Entry, 1); \
1748 entry_list = g_slist_append(entry_list, e); \
1751 SET_WIDGET_COND(toolbar->get_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1752 SET_WIDGET_COND(toolbar->getall_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
1753 SET_WIDGET_COND(toolbar->compose_news_btn, M_HAVE_ACCOUNT);
1754 SET_WIDGET_COND(toolbar->reply_btn,
1755 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1756 if (toolbar->reply_btn)
1757 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->reply_combo),
1758 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1759 SET_WIDGET_COND(toolbar->replyall_btn,
1760 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1761 if (toolbar->replyall_btn)
1762 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replyall_combo),
1763 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1764 SET_WIDGET_COND(toolbar->replylist_btn,
1765 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1766 if (toolbar->replylist_btn)
1767 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replylist_combo),
1768 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1769 SET_WIDGET_COND(toolbar->replysender_btn,
1770 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1771 if (toolbar->replysender_btn)
1772 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->replysender_combo),
1773 M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1774 SET_WIDGET_COND(toolbar->fwd_btn, M_HAVE_ACCOUNT|M_TARGET_EXIST);
1775 if (toolbar->fwd_btn)
1776 SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->fwd_combo),
1777 M_HAVE_ACCOUNT|M_TARGET_EXIST);
1778 if (toolbar->fwd_combo) {
1779 GtkWidget *submenu = gtk_item_factory_get_widget(toolbar->fwd_combo->factory, "/Redirect");
1780 SET_WIDGET_COND(submenu, M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
1783 if (prefs_common.next_unread_msg_dialog == NEXTUNREADMSGDIALOG_ASSUME_NO) {
1784 SET_WIDGET_COND(toolbar->next_btn, M_MSG_EXIST);
1786 SET_WIDGET_COND(toolbar->next_btn, 0);
1789 SET_WIDGET_COND(toolbar->trash_btn,
1790 M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED);
1791 SET_WIDGET_COND(toolbar->delete_btn,
1792 M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED);
1793 SET_WIDGET_COND(toolbar->exec_btn, M_DELAY_EXEC);
1795 for (cur = toolbar->action_list; cur != NULL; cur = cur->next) {
1796 ToolbarSylpheedActions *act = (ToolbarSylpheedActions*)cur->data;
1798 SET_WIDGET_COND(act->widget, M_TARGET_EXIST|M_UNLOCKED);
1801 #undef SET_WIDGET_COND
1803 state = main_window_get_current_state(mainwin);
1805 for (cur = entry_list; cur != NULL; cur = cur->next) {
1806 Entry *e = (Entry*) cur->data;
1808 if (e->widget != NULL) {
1809 sensitive = ((e->cond & state) == e->cond);
1810 gtk_widget_set_sensitive(e->widget, sensitive);
1814 while (entry_list != NULL) {
1815 Entry *e = (Entry*) entry_list->data;
1819 entry_list = g_slist_remove(entry_list, e);
1822 g_slist_free(entry_list);
1824 activate_compose_button(toolbar,
1825 prefs_common.toolbar_style,
1826 toolbar->compose_btn_type);
1829 void toolbar_comp_set_sensitive(gpointer data, gboolean sensitive)
1831 Compose *compose = (Compose*)data;
1832 GSList *items = compose->toolbar->action_list;
1834 if (compose->toolbar->send_btn)
1835 gtk_widget_set_sensitive(compose->toolbar->send_btn, sensitive);
1836 if (compose->toolbar->sendl_btn)
1837 gtk_widget_set_sensitive(compose->toolbar->sendl_btn, sensitive);
1838 if (compose->toolbar->draft_btn )
1839 gtk_widget_set_sensitive(compose->toolbar->draft_btn , sensitive);
1840 if (compose->toolbar->insert_btn )
1841 gtk_widget_set_sensitive(compose->toolbar->insert_btn , sensitive);
1842 if (compose->toolbar->attach_btn)
1843 gtk_widget_set_sensitive(compose->toolbar->attach_btn, sensitive);
1844 if (compose->toolbar->sig_btn)
1845 gtk_widget_set_sensitive(compose->toolbar->sig_btn, sensitive);
1846 if (compose->toolbar->exteditor_btn)
1847 gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, sensitive);
1848 if (compose->toolbar->linewrap_current_btn)
1849 gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, sensitive);
1850 if (compose->toolbar->linewrap_all_btn)
1851 gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, sensitive);
1852 if (compose->toolbar->addrbook_btn)
1853 gtk_widget_set_sensitive(compose->toolbar->addrbook_btn, sensitive);
1855 if (compose->toolbar->spellcheck_btn)
1856 gtk_widget_set_sensitive(compose->toolbar->spellcheck_btn, sensitive);
1858 for (; items != NULL; items = g_slist_next(items)) {
1859 ToolbarSylpheedActions *item = (ToolbarSylpheedActions *)items->data;
1860 gtk_widget_set_sensitive(item->widget, sensitive);
1865 * Initialize toolbar structure
1867 void toolbar_init(Toolbar * toolbar) {
1869 toolbar->toolbar = NULL;
1870 toolbar->get_btn = NULL;
1871 toolbar->getall_btn = NULL;
1872 toolbar->send_btn = NULL;
1873 toolbar->compose_mail_btn = NULL;
1874 toolbar->compose_news_btn = NULL;
1875 toolbar->reply_btn = NULL;
1876 toolbar->replysender_btn = NULL;
1877 toolbar->replyall_btn = NULL;
1878 toolbar->replylist_btn = NULL;
1879 toolbar->fwd_btn = NULL;
1880 toolbar->trash_btn = NULL;
1881 toolbar->delete_btn = NULL;
1882 toolbar->prev_btn = NULL;
1883 toolbar->next_btn = NULL;
1884 toolbar->exec_btn = NULL;
1886 /* compose buttons */
1887 toolbar->sendl_btn = NULL;
1888 toolbar->draft_btn = NULL;
1889 toolbar->insert_btn = NULL;
1890 toolbar->attach_btn = NULL;
1891 toolbar->sig_btn = NULL;
1892 toolbar->exteditor_btn = NULL;
1893 toolbar->linewrap_current_btn = NULL;
1894 toolbar->linewrap_all_btn = NULL;
1895 toolbar->addrbook_btn = NULL;
1897 toolbar->spellcheck_btn = NULL;
1900 toolbar_destroy(toolbar);
1905 static void toolbar_reply(gpointer data, guint action)
1907 ToolbarItem *toolbar_item = (ToolbarItem*)data;
1908 MainWindow *mainwin;
1909 MessageView *msgview;
1910 GSList *msginfo_list = NULL;
1912 g_return_if_fail(toolbar_item != NULL);
1914 switch (toolbar_item->type) {
1916 mainwin = (MainWindow*)toolbar_item->parent;
1917 msginfo_list = summary_get_selection(mainwin->summaryview);
1918 msgview = (MessageView*)mainwin->messageview;
1920 case TOOLBAR_MSGVIEW:
1921 msgview = (MessageView*)toolbar_item->parent;
1922 g_return_if_fail(msgview != NULL);
1923 msginfo_list = g_slist_append(msginfo_list, msgview->msginfo);
1929 g_return_if_fail(msgview != NULL);
1930 g_return_if_fail(msginfo_list != NULL);
1931 compose_reply_from_messageview(msgview, msginfo_list, action);
1932 g_slist_free(msginfo_list);
1934 /* TODO: update reply state ion summaryview */
1938 /* exported functions */
1940 void inc_mail_cb(gpointer data, guint action, GtkWidget *widget)
1942 MainWindow *mainwin = (MainWindow*)data;
1944 inc_mail(mainwin, prefs_common.newmail_notify_manu);
1947 void inc_all_account_mail_cb(gpointer data, guint action, GtkWidget *widget)
1949 MainWindow *mainwin = (MainWindow*)data;
1951 inc_all_account_mail(mainwin, FALSE, prefs_common.newmail_notify_manu);
1954 void send_queue_cb(gpointer data, guint action, GtkWidget *widget)
1959 if (prefs_common.work_offline)
1960 if (alertpanel(_("Offline warning"),
1961 _("You're working offline. Override?"),
1962 GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT)
1965 /* ask for confirmation before sending queued messages only
1966 in online mode and if there is at least one message queued
1967 in any of the folder queue
1969 if (prefs_common.confirm_send_queued_messages) {
1971 /* check if there's a queued message */
1972 for (list = folder_get_list(); !found && list != NULL; list = list->next) {
1973 Folder *folder = list->data;
1975 found = !procmsg_queue_is_empty(folder->queue);
1977 /* if necessary, ask for confirmation before sending */
1978 if (found && !prefs_common.work_offline) {
1979 if (alertpanel(_("Send queued messages"),
1980 _("Send all queued messages?"),
1981 GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT)
1986 for (list = folder_get_list(); list != NULL; list = list->next) {
1987 Folder *folder = list->data;
1989 if (folder->queue) {
1990 if (procmsg_send_queue(folder->queue,
1991 prefs_common.savemsg) < 0)
1992 alertpanel_error(_("Some errors occurred while "
1993 "sending queued messages."));
1998 void compose_mail_cb(gpointer data, guint action, GtkWidget *widget)
2000 MainWindow *mainwin = (MainWindow*)data;
2001 PrefsAccount *ac = NULL;
2002 FolderItem *item = mainwin->summaryview->folder_item;
2007 ac = account_find_from_item(item);
2008 if (ac && ac->protocol != A_NNTP) {
2009 compose_new_with_folderitem(ac, item); /* CLAWS */
2015 * CLAWS - use current account
2017 if (cur_account && (cur_account->protocol != A_NNTP)) {
2018 compose_new_with_folderitem(cur_account, item);
2023 * CLAWS - just get the first one
2025 list = account_get_list();
2026 for (cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2027 ac = (PrefsAccount *) cur->data;
2028 if (ac->protocol != A_NNTP) {
2029 compose_new_with_folderitem(ac, item);
2035 void compose_news_cb(gpointer data, guint action, GtkWidget *widget)
2037 MainWindow *mainwin = (MainWindow*)data;
2038 PrefsAccount * ac = NULL;
2042 if (mainwin->summaryview->folder_item) {
2043 ac = mainwin->summaryview->folder_item->folder->account;
2044 if (ac && ac->protocol == A_NNTP) {
2046 mainwin->summaryview->folder_item->path,
2052 list = account_get_list();
2053 for(cur = list ; cur != NULL ; cur = g_list_next(cur)) {
2054 ac = (PrefsAccount *) cur->data;
2055 if (ac->protocol == A_NNTP) {
2056 compose_new(ac, NULL, NULL);