toolbar.c (77460B)
1 /* 2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client 3 * Copyright (C) 2001-2025 the Claws Mail team and Hiroyuki Yamamoto 4 * 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 3 of the License, or 8 * (at your option) any later version. 9 * 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. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include "defs.h" 20 21 #include <glib.h> 22 #include <glib/gi18n.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <sys/stat.h> 26 #include <math.h> 27 #include <setjmp.h> 28 29 #include "main.h" 30 #include "mainwindow.h" 31 #include "summaryview.h" 32 #include "compose.h" 33 #include "utils.h" 34 #include "xml.h" 35 #include "mgutils.h" 36 #include "prefs_gtk.h" 37 #include "codeconv.h" 38 #include "stock_pixmap.h" 39 #include "manage_window.h" 40 #include "gtkutils.h" 41 #include "toolbar.h" 42 #include "menu.h" 43 #include "inc.h" 44 #include "action.h" 45 #include "prefs_actions.h" 46 #include "prefs_common.h" 47 #include "prefs_toolbar.h" 48 #include "alertpanel.h" 49 #include "imap.h" 50 #include "account.h" 51 #include "send_message.h" 52 #include "addressbook.h" 53 54 /* elements */ 55 #define TOOLBAR_TAG_INDEX "toolbar" 56 #define TOOLBAR_TAG_ITEM "item" 57 #define TOOLBAR_TAG_SEPARATOR "separator" 58 59 #define TOOLBAR_ICON_FILE "file" 60 #define TOOLBAR_ICON_TEXT "text" 61 #define TOOLBAR_ICON_ACTION "action" 62 63 static void toolbar_init(Toolbar * toolbar); 64 static gboolean toolbar_is_duplicate (gint action, 65 ToolbarType source); 66 static void toolbar_parse_item (XMLFile *file, 67 ToolbarType source, gboolean *rewrite); 68 69 static gint toolbar_ret_val_from_text (const gchar *text); 70 static gchar *toolbar_ret_text_from_val (gint val); 71 72 typedef struct _DefaultToolbar DefaultToolbar; 73 struct _DefaultToolbar { 74 gint action; 75 }; 76 static void toolbar_set_default_generic(ToolbarType toolbar_type, 77 DefaultToolbar *default_toolbar); 78 79 static void toolbar_style (ToolbarType type, 80 guint action, 81 gpointer data); 82 83 static MainWindow *get_mainwin (gpointer data); 84 static void activate_compose_button (Toolbar *toolbar, 85 ToolbarStyle style, 86 ComposeButtonType type); 87 88 /* toolbar callbacks */ 89 static void toolbar_reply (gpointer data, 90 guint action); 91 92 static void toolbar_delete_dup (gpointer data, 93 guint action); 94 95 static void toolbar_trash_cb (GtkWidget *widget, 96 gpointer data); 97 98 static void toolbar_delete_cb (GtkWidget *widget, 99 gpointer data); 100 101 static void toolbar_delete_dup_cb (GtkWidget *widget, 102 103 gpointer data); 104 105 static void toolbar_compose_cb (GtkWidget *widget, 106 gpointer data); 107 108 static void toolbar_reply_cb (GtkWidget *widget, 109 gpointer data); 110 111 static void toolbar_reply_to_all_cb (GtkWidget *widget, 112 gpointer data); 113 114 static void toolbar_reply_to_list_cb (GtkWidget *widget, 115 gpointer data); 116 117 static void toolbar_reply_to_sender_cb (GtkWidget *widget, 118 gpointer data); 119 120 static void toolbar_forward_cb (GtkWidget *widget, 121 gpointer data); 122 123 static void toolbar_prev_unread_cb (GtkWidget *widget, 124 gpointer data); 125 static void toolbar_next_unread_cb (GtkWidget *widget, 126 gpointer data); 127 128 static void toolbar_ignore_thread_cb (GtkWidget *widget, 129 gpointer data); 130 131 static void toolbar_watch_thread_cb (GtkWidget *widget, 132 gpointer data); 133 134 static void toolbar_mark_cb (GtkWidget *widget, 135 gpointer data); 136 137 static void toolbar_unmark_cb (GtkWidget *widget, 138 gpointer data); 139 140 static void toolbar_lock_cb (GtkWidget *widget, 141 gpointer data); 142 143 static void toolbar_unlock_cb (GtkWidget *widget, 144 gpointer data); 145 146 static void toolbar_all_read_cb (GtkWidget *widget, 147 gpointer data); 148 149 static void toolbar_all_unread_cb (GtkWidget *widget, 150 gpointer data); 151 152 static void toolbar_read_cb (GtkWidget *widget, 153 gpointer data); 154 155 static void toolbar_unread_cb (GtkWidget *widget, 156 gpointer data); 157 158 static void toolbar_run_processing_cb (GtkWidget *widget, 159 gpointer data); 160 161 static void toolbar_actions_execute_cb (GtkWidget *widget, 162 gpointer data); 163 164 static void toolbar_send_cb (GtkWidget *widget, 165 gpointer data); 166 static void toolbar_send_later_cb (GtkWidget *widget, 167 gpointer data); 168 static void toolbar_draft_cb (GtkWidget *widget, 169 gpointer data); 170 static void toolbar_close_cb (GtkWidget *widget, 171 gpointer data); 172 static void toolbar_preferences_cb (GtkWidget *widget, 173 gpointer data); 174 static void toolbar_open_mail_cb (GtkWidget *widget, 175 gpointer data); 176 static void toolbar_insert_cb (GtkWidget *widget, 177 gpointer data); 178 static void toolbar_attach_cb (GtkWidget *widget, 179 gpointer data); 180 static void toolbar_sig_cb (GtkWidget *widget, 181 gpointer data); 182 static void toolbar_ext_editor_cb (GtkWidget *widget, 183 gpointer data); 184 static void toolbar_linewrap_current_cb (GtkWidget *widget, 185 gpointer data); 186 static void toolbar_linewrap_all_cb (GtkWidget *widget, 187 gpointer data); 188 static void toolbar_addrbook_cb (GtkWidget *widget, 189 gpointer data); 190 static void toolbar_cancel_inc_cb (GtkWidget *widget, 191 gpointer data); 192 static void toolbar_cancel_send_cb (GtkWidget *widget, 193 gpointer data); 194 static void toolbar_cancel_all_cb (GtkWidget *widget, 195 gpointer data); 196 197 struct { 198 gchar *index_str; 199 const gchar *descr; 200 } toolbar_text [] = { 201 { "A_RECEIVE_ALL", N_("Receive Mail from all Accounts") }, 202 { "A_RECEIVE_CUR", N_("Receive Mail from current Account") }, 203 { "A_SEND_QUEUED", N_("Send Queued Messages") }, 204 { "A_COMPOSE_EMAIL", N_("Write Email") }, 205 { "A_REPLY_MESSAGE", N_("Reply to Message") }, 206 { "A_REPLY_SENDER", N_("Reply to Sender") }, 207 { "A_REPLY_ALL", N_("Reply to All") }, 208 { "A_REPLY_ML", N_("Reply to Mailing-list") }, 209 { "A_OPEN_MAIL", N_("Open email") }, 210 { "A_FORWARD", N_("Forward Message") }, 211 { "A_TRASH", N_("Trash Message") }, 212 { "A_DELETE_REAL", N_("Delete Message") }, 213 { "A_DELETE_DUP", N_("Delete duplicate messages") }, 214 { "A_EXECUTE", N_("Execute") }, 215 { "A_GOTO_PREV", N_("Go to Previous Unread Message") }, 216 { "A_GOTO_NEXT", N_("Go to Next Unread Message") }, 217 218 { "A_IGNORE_THREAD", N_("Ignore thread") }, 219 { "A_WATCH_THREAD", N_("Watch thread") }, 220 { "A_MARK", N_("Mark Message") }, 221 { "A_UNMARK", N_("Unmark Message") }, 222 { "A_LOCK", N_("Lock Message") }, 223 { "A_UNLOCK", N_("Unlock Message") }, 224 { "A_ALL_READ", N_("Mark all Messages as read") }, 225 { "A_ALL_UNREAD", N_("Mark all Messages as unread") }, 226 { "A_READ", N_("Mark Message as read") }, 227 { "A_UNREAD", N_("Mark Message as unread") }, 228 { "A_RUN_PROCESSING", N_("Run folder processing rules") }, 229 230 { "A_GO_FOLDERS", N_("Open folder/Go to folder list") }, 231 { "A_PREFERENCES", N_("Preferences") }, 232 233 { "A_SEND", N_("Send Message") }, 234 { "A_SEND_LATER", N_("Put into queue folder and send later") }, 235 { "A_DRAFT", N_("Save to draft folder") }, 236 { "A_INSERT", N_("Insert file") }, 237 { "A_ATTACH", N_("Attach file") }, 238 { "A_SIG", N_("Insert signature") }, 239 { "A_REP_SIG", N_("Replace signature") }, 240 { "A_EXTEDITOR", N_("Edit with external editor") }, 241 { "A_LINEWRAP_CURRENT", N_("Wrap long lines of current paragraph") }, 242 { "A_LINEWRAP_ALL", N_("Wrap all long lines") }, 243 { "A_ADDRBOOK", N_("Address book") }, 244 { "A_PRIVACY_SIGN", N_("Sign") }, 245 { "A_PRIVACY_ENCRYPT", N_("Encrypt") }, 246 { "A_CLAWS_ACTIONS", N_("Claws Mail Actions Feature") }, 247 { "A_CANCEL_INC", N_("Cancel receiving") }, 248 { "A_CANCEL_SEND", N_("Cancel sending") }, 249 { "A_CANCEL_ALL", N_("Cancel receiving/sending") }, 250 { "A_CLOSE", N_("Close window") }, 251 { "A_SEPARATOR", N_("Separator") }, 252 }; 253 254 /* migration table: support reading toolbar configuration files with 255 old action names and converting them to current action names, 256 see toolbar_parse_item(), which makes uses of this alias table. 257 */ 258 struct { 259 const gchar *old_name; 260 const gchar *current_name; 261 } toolbar_migration [] = { 262 { "A_SYL_ACTIONS", "A_CLAWS_ACTIONS" }, 263 { "A_SENDL", "A_SEND_LATER" }, 264 { NULL, NULL } 265 }; 266 267 /* struct holds configuration files and a list of 268 * currently active toolbar items 269 * TOOLBAR_MAIN, TOOLBAR_COMPOSE and TOOLBAR_MSGVIEW 270 * give us an index 271 */ 272 struct { 273 const gchar *conf_file; 274 GSList *item_list; 275 } toolbar_config[NUM_TOOLBARS] = { 276 { "toolbar_main.xml", NULL}, 277 { "toolbar_compose.xml", NULL}, 278 { "toolbar_msgview.xml", NULL} 279 }; 280 281 gint toolbar_ret_val_from_descr(const gchar *descr) 282 { 283 gint i; 284 285 for (i = 0; i < N_ACTION_VAL; i++) { 286 if (g_utf8_collate(toolbar_text[i].descr, descr) == 0) 287 return i; 288 } 289 290 return -1; 291 } 292 293 gchar *toolbar_ret_descr_from_val(gint val) 294 { 295 cm_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL); 296 297 return toolbar_text[val].descr; 298 } 299 300 static gint toolbar_ret_val_from_text(const gchar *text) 301 { 302 gint i; 303 304 for (i = 0; i < N_ACTION_VAL; i++) { 305 if (g_utf8_collate(toolbar_text[i].index_str, text) == 0) 306 return i; 307 } 308 309 return -1; 310 } 311 312 static gchar *toolbar_ret_text_from_val(gint val) 313 { 314 cm_return_val_if_fail(val >=0 && val < N_ACTION_VAL, NULL); 315 316 return toolbar_text[val].index_str; 317 } 318 319 static gboolean toolbar_is_duplicate(gint action, ToolbarType source) 320 { 321 GSList *cur; 322 323 if ((action == A_SEPARATOR) || (action == A_CLAWS_ACTIONS)) 324 return FALSE; 325 326 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) { 327 ToolbarItem *item = (ToolbarItem*) cur->data; 328 329 if (item->index == action) 330 return TRUE; 331 } 332 return FALSE; 333 } 334 335 /* depending on toolbar type this function 336 returns a list of available toolbar events being 337 displayed by prefs_toolbar 338 */ 339 GList *toolbar_get_action_items(ToolbarType source) 340 { 341 GList *items = NULL; 342 gint i = 0; 343 344 if (source == TOOLBAR_MAIN) { 345 gint main_items[] = { 346 A_RECEIVE_ALL, A_RECEIVE_CUR, A_SEND_QUEUED, 347 A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER, 348 A_REPLY_ALL, A_REPLY_ML, A_OPEN_MAIL, A_FORWARD, 349 A_TRASH, A_DELETE_REAL, A_DELETE_DUP, A_EXECUTE, 350 A_GOTO_PREV, A_GOTO_NEXT, A_IGNORE_THREAD, A_WATCH_THREAD, 351 A_MARK, A_UNMARK, A_LOCK, A_UNLOCK, 352 A_ALL_READ, A_ALL_UNREAD, A_READ, A_UNREAD, 353 A_RUN_PROCESSING, 354 A_ADDRBOOK, A_GO_FOLDERS, 355 A_CANCEL_INC, A_CANCEL_SEND, A_CANCEL_ALL, A_PREFERENCES }; 356 357 for (i = 0; i < sizeof main_items / sizeof main_items[0]; i++) { 358 items = g_list_append(items, toolbar_text[main_items[i]].descr); 359 } 360 } 361 else if (source == TOOLBAR_COMPOSE) { 362 gint comp_items[] = { 363 A_SEND, A_SEND_LATER, A_DRAFT, 364 A_INSERT, A_ATTACH, A_SIG, 365 A_REP_SIG, A_EXTEDITOR, A_LINEWRAP_CURRENT, 366 A_LINEWRAP_ALL, A_ADDRBOOK, 367 A_PRIVACY_SIGN, A_PRIVACY_ENCRYPT, 368 A_CLOSE }; 369 370 for (i = 0; i < sizeof comp_items / sizeof comp_items[0]; i++) 371 items = g_list_append(items, toolbar_text[comp_items[i]].descr); 372 } 373 else if (source == TOOLBAR_MSGVIEW) { 374 gint msgv_items[] = { 375 A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER, 376 A_REPLY_ALL, A_REPLY_ML, A_FORWARD, 377 A_TRASH, A_DELETE_REAL, A_GOTO_PREV, A_GOTO_NEXT, 378 A_ADDRBOOK, A_CLOSE }; 379 380 for (i = 0; i < sizeof msgv_items / sizeof msgv_items[0]; i++) 381 items = g_list_append(items, toolbar_text[msgv_items[i]].descr); 382 } 383 384 return items; 385 } 386 387 static void toolbar_parse_item(XMLFile *file, ToolbarType source, gboolean *rewrite) 388 { 389 GList *attr; 390 gchar *name, *value; 391 ToolbarItem *item = NULL; 392 393 g_return_if_fail(rewrite != NULL); 394 395 attr = xml_get_current_tag_attr(file); 396 item = g_new0(ToolbarItem, 1); 397 while( attr ) { 398 name = ((XMLAttr *)attr->data)->name; 399 value = ((XMLAttr *)attr->data)->value; 400 401 if (g_utf8_collate(name, TOOLBAR_ICON_FILE) == 0) 402 item->file = g_strdup (value); 403 else if (g_utf8_collate(name, TOOLBAR_ICON_TEXT) == 0) 404 item->text = g_strdup (*value ? value:""); 405 else if (g_utf8_collate(name, TOOLBAR_ICON_ACTION) == 0) 406 item->index = toolbar_ret_val_from_text(value); 407 408 if ((item->index == -1) && !strcmp(value, "A_DELETE")) { 409 /* switch button */ 410 item->index = A_TRASH; 411 g_free(item->file); 412 item->file = g_strdup("trash_btn"); 413 g_free(item->text); 414 item->text = g_strdup(C_("Toolbar", "Trash")); 415 *rewrite = TRUE; 416 } 417 if (!strcmp(item->file, "mail") && !strcmp(value, "A_DRAFT")) { 418 /* switch icon file */ 419 g_free(item->file); 420 item->file = g_strdup("mail_draft"); 421 *rewrite = TRUE; 422 } 423 if (item->index == -1) { 424 /* item not found in table: try migrating old action names to current ones */ 425 gint i; 426 427 /* replace action name */ 428 for (i = 0; toolbar_migration[i].old_name != NULL; i++) { 429 if (g_utf8_collate(value, toolbar_migration[i].old_name) == 0) { 430 item->index = toolbar_ret_val_from_text(toolbar_migration[i].current_name); 431 if (item->index != -1) { 432 *rewrite = TRUE; 433 debug_print("toolbar_parse_item: migrating action label from '%s' to '%s'\n", 434 value, toolbar_migration[i].current_name); 435 break; 436 } 437 } 438 } 439 } 440 if ((item->index == -1) && !rewrite) 441 g_warning("toolbar_parse_item: unrecognized action name '%s'", value); 442 443 attr = g_list_next(attr); 444 } 445 if (item->index != -1) { 446 if (!toolbar_is_duplicate(item->index, source)) { 447 toolbar_config[source].item_list = g_slist_append(toolbar_config[source].item_list, 448 item); 449 } else { 450 toolbar_item_destroy(item); 451 } 452 } else { 453 toolbar_item_destroy(item); 454 } 455 } 456 457 const gchar *toolbar_get_short_text(int action) { 458 switch(action) { 459 case A_RECEIVE_ALL: return _("Get Mail"); 460 case A_RECEIVE_CUR: return _("Get"); 461 case A_SEND_QUEUED: return _("Send"); 462 case A_COMPOSE_EMAIL: return C_("Toolbar", "Write"); 463 case A_REPLY_MESSAGE: return _("Reply"); 464 case A_REPLY_SENDER: return C_("Toolbar", "Sender"); 465 case A_REPLY_ALL: return _("All"); 466 case A_REPLY_ML: return _("List"); 467 case A_OPEN_MAIL: return _("Open"); 468 case A_FORWARD: return _("Forward"); 469 case A_TRASH: return C_("Toolbar", "Trash"); 470 case A_DELETE_REAL: return _("Delete"); 471 case A_DELETE_DUP: return _("Delete duplicates"); 472 case A_EXECUTE: return _("Execute"); 473 case A_GOTO_PREV: return _("Prev"); 474 case A_GOTO_NEXT: return _("Next"); 475 476 case A_IGNORE_THREAD: return _("Ignore thread"); 477 case A_WATCH_THREAD: return _("Watch thread"); 478 case A_MARK: return _("Mark"); 479 case A_UNMARK: return _("Unmark"); 480 case A_LOCK: return _("Lock"); 481 case A_UNLOCK: return _("Unlock"); 482 case A_ALL_READ: return _("All read"); 483 case A_ALL_UNREAD: return _("All unread"); 484 case A_READ: return _("Read"); 485 case A_UNREAD: return _("Unread"); 486 case A_RUN_PROCESSING: return _("Run proc. rules"); 487 488 case A_GO_FOLDERS: return _("Folders"); 489 case A_PREFERENCES: return _("Preferences"); 490 491 case A_SEND: return _("Send"); 492 case A_SEND_LATER: return _("Send later"); 493 case A_DRAFT: return _("Draft"); 494 case A_INSERT: return _("Insert"); 495 case A_ATTACH: return _("Attach"); 496 case A_SIG: return _("Insert sig."); 497 case A_REP_SIG: return _("Replace sig."); 498 case A_EXTEDITOR: return _("Edit"); 499 case A_LINEWRAP_CURRENT:return _("Wrap para."); 500 case A_LINEWRAP_ALL: return _("Wrap all"); 501 case A_ADDRBOOK: return _("Address"); 502 case A_PRIVACY_SIGN: return _("Sign"); 503 case A_PRIVACY_ENCRYPT: return _("Encrypt"); 504 505 case A_CANCEL_INC: return _("Stop"); 506 case A_CANCEL_SEND: return _("Stop"); 507 case A_CANCEL_ALL: return _("Stop all"); 508 case A_CLOSE: return _("Close"); 509 default: return ""; 510 } 511 } 512 513 gint toolbar_get_icon(int action) { 514 switch(action) { 515 case A_RECEIVE_ALL: return STOCK_PIXMAP_MAIL_RECEIVE_ALL; 516 case A_RECEIVE_CUR: return STOCK_PIXMAP_MAIL_RECEIVE; 517 case A_SEND_QUEUED: return STOCK_PIXMAP_MAIL_SEND_QUEUE; 518 case A_COMPOSE_EMAIL: return STOCK_PIXMAP_MAIL_COMPOSE; 519 case A_REPLY_MESSAGE: return STOCK_PIXMAP_MAIL_REPLY; 520 case A_REPLY_SENDER: return STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR; 521 case A_REPLY_ALL: return STOCK_PIXMAP_MAIL_REPLY_TO_ALL; 522 case A_REPLY_ML: return STOCK_PIXMAP_MAIL_REPLY_TO_LIST; 523 case A_OPEN_MAIL: return STOCK_PIXMAP_OPEN_MAIL; 524 case A_FORWARD: return STOCK_PIXMAP_MAIL_FORWARD; 525 case A_TRASH: return STOCK_PIXMAP_TRASH; 526 case A_DELETE_REAL: return STOCK_PIXMAP_DELETE; 527 case A_DELETE_DUP: return STOCK_PIXMAP_DELETE_DUP; 528 case A_EXECUTE: return STOCK_PIXMAP_EXEC; 529 case A_GOTO_PREV: return STOCK_PIXMAP_UP_ARROW; 530 case A_GOTO_NEXT: return STOCK_PIXMAP_DOWN_ARROW; 531 532 case A_IGNORE_THREAD: return STOCK_PIXMAP_MARK_IGNORETHREAD; 533 case A_WATCH_THREAD: return STOCK_PIXMAP_MARK_WATCHTHREAD; 534 case A_MARK: return STOCK_PIXMAP_MARK_MARK; 535 case A_UNMARK: return STOCK_PIXMAP_MARK_UNMARK; 536 case A_LOCK: return STOCK_PIXMAP_MARK_LOCKED; 537 case A_UNLOCK: return STOCK_PIXMAP_MARK_UNLOCKED; 538 case A_ALL_READ: return STOCK_PIXMAP_MARK_ALLREAD; 539 case A_ALL_UNREAD: return STOCK_PIXMAP_MARK_ALLUNREAD; 540 case A_READ: return STOCK_PIXMAP_MARK_READ; 541 case A_UNREAD: return STOCK_PIXMAP_MARK_UNREAD; 542 case A_RUN_PROCESSING: return STOCK_PIXMAP_DIR_OPEN; 543 544 case A_GO_FOLDERS: return STOCK_PIXMAP_GO_FOLDERS; 545 case A_PREFERENCES: return STOCK_PIXMAP_PREFERENCES; 546 547 case A_SEND: return STOCK_PIXMAP_MAIL_SEND; 548 case A_SEND_LATER: return STOCK_PIXMAP_MAIL_SEND_QUEUE; 549 case A_DRAFT: return STOCK_PIXMAP_MAIL_DRAFT; 550 case A_INSERT: return STOCK_PIXMAP_INSERT_FILE; 551 case A_ATTACH: return STOCK_PIXMAP_MAIL_ATTACH; 552 case A_SIG: return STOCK_PIXMAP_MAIL_SIGN; 553 case A_REP_SIG: return STOCK_PIXMAP_MAIL_SIGN; 554 case A_EXTEDITOR: return STOCK_PIXMAP_EDIT_EXTERN; 555 case A_LINEWRAP_CURRENT:return STOCK_PIXMAP_LINEWRAP_CURRENT; 556 case A_LINEWRAP_ALL: return STOCK_PIXMAP_LINEWRAP_ALL; 557 case A_ADDRBOOK: return STOCK_PIXMAP_ADDRESS_BOOK; 558 case A_PRIVACY_SIGN: return STOCK_PIXMAP_MAIL_PRIVACY_SIGNED; 559 case A_PRIVACY_ENCRYPT: return STOCK_PIXMAP_MAIL_PRIVACY_ENCRYPTED; 560 561 case A_CANCEL_INC: return STOCK_PIXMAP_CANCEL; 562 case A_CANCEL_SEND: return STOCK_PIXMAP_CANCEL; 563 case A_CANCEL_ALL: return STOCK_PIXMAP_CANCEL; 564 case A_CLOSE: return STOCK_PIXMAP_CLOSE; 565 default: return -1; 566 } 567 } 568 569 static void toolbar_set_default_generic(ToolbarType toolbar_type, DefaultToolbar *default_toolbar) 570 { 571 gint i; 572 573 g_return_if_fail(default_toolbar != NULL); 574 575 for (i = 0; default_toolbar[i].action != N_ACTION_VAL; i++) { 576 577 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1); 578 579 if (default_toolbar[i].action != A_SEPARATOR) { 580 gchar *file = NULL; 581 gint icon; 582 583 icon = toolbar_get_icon(default_toolbar[i].action); 584 if (icon > -1) { 585 file = stock_pixmap_get_name((StockPixmap)icon); 586 } 587 toolbar_item->file = g_strdup(file); 588 toolbar_item->index = default_toolbar[i].action; 589 toolbar_item->text = g_strdup(toolbar_get_short_text(default_toolbar[i].action)); 590 } else { 591 toolbar_item->file = g_strdup(TOOLBAR_TAG_SEPARATOR); 592 toolbar_item->index = A_SEPARATOR; 593 } 594 595 if (toolbar_item->index != -1) { 596 if (!toolbar_is_duplicate(toolbar_item->index, toolbar_type)) { 597 toolbar_config[toolbar_type].item_list = 598 g_slist_append(toolbar_config[toolbar_type].item_list, toolbar_item); 599 } else { 600 toolbar_item_destroy(toolbar_item); 601 } 602 } else { 603 toolbar_item_destroy(toolbar_item); 604 } 605 } 606 } 607 608 void toolbar_set_default(ToolbarType source) 609 { 610 DefaultToolbar default_toolbar_main[] = { 611 { A_RECEIVE_ALL}, 612 { A_SEPARATOR}, 613 { A_SEND_QUEUED}, 614 { A_COMPOSE_EMAIL}, 615 { A_SEPARATOR}, 616 { A_REPLY_MESSAGE}, 617 { A_REPLY_ALL}, 618 { A_REPLY_SENDER}, 619 { A_FORWARD}, 620 { A_SEPARATOR}, 621 { A_TRASH}, 622 { A_SEPARATOR}, 623 { A_GOTO_NEXT}, 624 { N_ACTION_VAL} 625 }; 626 DefaultToolbar default_toolbar_compose[] = { 627 { A_SEND}, 628 { A_SEND_LATER}, 629 { A_DRAFT}, 630 { A_SEPARATOR}, 631 { A_INSERT}, 632 { A_ATTACH}, 633 { A_SEPARATOR}, 634 { A_ADDRBOOK}, 635 { N_ACTION_VAL} 636 }; 637 638 DefaultToolbar default_toolbar_msgview[] = { 639 { A_REPLY_MESSAGE}, 640 { A_REPLY_ALL}, 641 { A_REPLY_SENDER}, 642 { A_FORWARD}, 643 { A_SEPARATOR}, 644 { A_TRASH}, 645 { A_GOTO_NEXT}, 646 { N_ACTION_VAL} 647 }; 648 649 if (source == TOOLBAR_MAIN) 650 toolbar_set_default_generic(TOOLBAR_MAIN, default_toolbar_main); 651 else if (source == TOOLBAR_COMPOSE) 652 toolbar_set_default_generic(TOOLBAR_COMPOSE, default_toolbar_compose); 653 else if (source == TOOLBAR_MSGVIEW) 654 toolbar_set_default_generic(TOOLBAR_MSGVIEW, default_toolbar_msgview); 655 } 656 657 void toolbar_save_config_file(ToolbarType source) 658 { 659 GSList *cur; 660 FILE *fp; 661 PrefFile *pfile; 662 gchar *fileSpec = NULL; 663 664 debug_print("save Toolbar Configuration to %s\n", toolbar_config[source].conf_file); 665 666 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL ); 667 pfile = prefs_write_open(fileSpec); 668 if( pfile ) { 669 fp = pfile->fp; 670 if (fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL) < 0) 671 goto fail; 672 673 if (fprintf(fp, "<%s>\n", TOOLBAR_TAG_INDEX) < 0) 674 goto fail; 675 676 for (cur = toolbar_config[source].item_list; cur != NULL; cur = cur->next) { 677 ToolbarItem *toolbar_item = (ToolbarItem*) cur->data; 678 679 if (toolbar_item->index != A_SEPARATOR) { 680 if (fprintf(fp, "\t<%s %s=\"%s\" %s=\"", 681 TOOLBAR_TAG_ITEM, 682 TOOLBAR_ICON_FILE, toolbar_item->file, 683 TOOLBAR_ICON_TEXT) < 0) 684 goto fail; 685 if (xml_file_put_escape_str(fp, toolbar_item->text) < 0) 686 goto fail; 687 if (fprintf(fp, "\" %s=\"%s\"/>\n", 688 TOOLBAR_ICON_ACTION, 689 toolbar_ret_text_from_val(toolbar_item->index)) < 0) 690 goto fail; 691 } else { 692 if (fprintf(fp, "\t<%s/>\n", TOOLBAR_TAG_SEPARATOR) < 0) 693 goto fail; 694 } 695 } 696 697 if (fprintf(fp, "</%s>\n", TOOLBAR_TAG_INDEX) < 0) 698 goto fail; 699 700 g_free( fileSpec ); 701 if (prefs_file_close (pfile) < 0 ) 702 g_warning("failed to write toolbar configuration to file"); 703 return; 704 705 fail: 706 FILE_OP_ERROR(fileSpec, "fprintf"); 707 g_free(fileSpec); 708 prefs_file_close_revert (pfile); 709 } else { 710 g_free(fileSpec); 711 g_warning("failed to open toolbar configuration file for writing"); 712 } 713 } 714 715 void toolbar_read_config_file(ToolbarType source) 716 { 717 XMLFile *file = NULL; 718 gchar *fileSpec = NULL; 719 jmp_buf jumper; 720 gboolean rewrite = FALSE; 721 722 debug_print("read Toolbar Configuration from %s\n", toolbar_config[source].conf_file); 723 724 fileSpec = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, toolbar_config[source].conf_file, NULL ); 725 file = xml_open_file(fileSpec); 726 g_free(fileSpec); 727 728 toolbar_clear_list(source); 729 730 if (file) { 731 if ((setjmp(jumper)) 732 || (xml_get_dtd(file)) 733 || (xml_parse_next_tag(file)) 734 || (!xml_compare_tag(file, TOOLBAR_TAG_INDEX))) { 735 xml_close_file(file); 736 return; 737 } 738 739 for (;;) { 740 if (!file->level) 741 break; 742 /* Get item tag */ 743 if (xml_parse_next_tag(file)) 744 longjmp(jumper, 1); 745 746 /* Get next tag (icon, icon_text or icon_action) */ 747 if (xml_compare_tag(file, TOOLBAR_TAG_ITEM)) { 748 toolbar_parse_item(file, source, &rewrite); 749 } else if (xml_compare_tag(file, TOOLBAR_TAG_SEPARATOR)) { 750 ToolbarItem *item = g_new0(ToolbarItem, 1); 751 752 item->file = g_strdup(TOOLBAR_TAG_SEPARATOR); 753 item->index = A_SEPARATOR; 754 toolbar_config[source].item_list = 755 g_slist_append(toolbar_config[source].item_list, item); 756 } 757 758 } 759 xml_close_file(file); 760 if (rewrite) { 761 debug_print("toolbar_read_config_file: rewriting toolbar\n"); 762 toolbar_save_config_file(source); 763 } 764 } 765 766 if ((!file) || (g_slist_length(toolbar_config[source].item_list) == 0)) { 767 768 if (source == TOOLBAR_MAIN) 769 toolbar_set_default(TOOLBAR_MAIN); 770 else if (source == TOOLBAR_COMPOSE) 771 toolbar_set_default(TOOLBAR_COMPOSE); 772 else if (source == TOOLBAR_MSGVIEW) 773 toolbar_set_default(TOOLBAR_MSGVIEW); 774 else { 775 g_warning("refusing to write unknown Toolbar Configuration number %d", source); 776 return; 777 } 778 779 toolbar_save_config_file(source); 780 } 781 } 782 783 /* 784 * clears list of toolbar items read from configuration files 785 */ 786 void toolbar_clear_list(ToolbarType source) 787 { 788 while (toolbar_config[source].item_list != NULL) { 789 ToolbarItem *item = (ToolbarItem*) toolbar_config[source].item_list->data; 790 791 toolbar_config[source].item_list = 792 g_slist_remove(toolbar_config[source].item_list, item); 793 794 toolbar_item_destroy(item); 795 } 796 g_slist_free(toolbar_config[source].item_list); 797 } 798 799 800 /* 801 * return list of Toolbar items 802 */ 803 GSList *toolbar_get_list(ToolbarType source) 804 { 805 GSList *list = NULL; 806 807 if ((source == TOOLBAR_MAIN) || (source == TOOLBAR_COMPOSE) || (source == TOOLBAR_MSGVIEW)) 808 list = toolbar_config[source].item_list; 809 810 return list; 811 } 812 813 void toolbar_set_list_item(ToolbarItem *t_item, ToolbarType source) 814 { 815 ToolbarItem *toolbar_item = g_new0(ToolbarItem, 1); 816 817 toolbar_item->file = g_strdup(t_item->file); 818 toolbar_item->text = g_strdup(t_item->text); 819 toolbar_item->index = t_item->index; 820 821 toolbar_config[source].item_list = 822 g_slist_append(toolbar_config[source].item_list, 823 toolbar_item); 824 } 825 826 static void toolbar_action_execute(GtkWidget *widget, 827 GSList *action_list, 828 gpointer data, 829 gint source) 830 { 831 GSList *cur; 832 gint i = 0; 833 834 for (cur = action_list; cur != NULL; cur = cur->next) { 835 ToolbarClawsActions *act = (ToolbarClawsActions*)cur->data; 836 837 if (widget == act->widget) { 838 i = prefs_actions_find_by_name(act->name); 839 840 if (i != -1) 841 break; 842 } 843 } 844 845 if (i != -1) 846 actions_execute(data, i, widget, source); 847 else 848 g_warning("error: did not find Action to execute"); 849 } 850 851 gboolean toolbar_check_action_btns(ToolbarType type) 852 { 853 GSList *temp, *curr, *list = toolbar_config[type].item_list; 854 gboolean modified = FALSE; 855 856 curr = list; 857 while (curr != NULL) { 858 ToolbarItem *toolbar_item = (ToolbarItem *) curr->data; 859 temp = curr; 860 curr = curr->next; 861 862 if (toolbar_item->index != A_CLAWS_ACTIONS) 863 continue; 864 865 if (prefs_actions_find_by_name(toolbar_item->text) == -1) { 866 list = g_slist_delete_link(list, temp); 867 g_free(toolbar_item->file); 868 g_free(toolbar_item->text); 869 g_free(toolbar_item); 870 modified = TRUE; 871 } 872 } 873 874 return modified; 875 } 876 877 #define CLAWS_SET_TOOL_ITEM_TIP(widget,tip) { \ 878 gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), tip); \ 879 } 880 881 #define CLAWS_SET_ARROW_TIP(widget,tip) { \ 882 gtk_menu_tool_button_set_arrow_tooltip_text(GTK_MENU_TOOL_BUTTON(widget), tip); \ 883 } 884 885 static void activate_compose_button (Toolbar *toolbar, 886 ToolbarStyle style, 887 ComposeButtonType type) 888 { 889 if ((!toolbar->compose_mail_btn)) 890 return; 891 892 gtk_tool_button_set_icon_widget( 893 GTK_TOOL_BUTTON(toolbar->compose_mail_btn), 894 toolbar->compose_mail_icon); 895 CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(toolbar->compose_mail_btn), _("Write Email")); 896 gtk_widget_show(toolbar->compose_mail_icon); 897 toolbar->compose_btn_type = type; 898 } 899 900 void toolbar_set_compose_button(Toolbar *toolbar, 901 ComposeButtonType compose_btn_type) 902 { 903 if (toolbar->compose_btn_type != compose_btn_type) 904 activate_compose_button(toolbar, 905 prefs_common.toolbar_style, 906 compose_btn_type); 907 } 908 909 void toolbar_toggle(guint action, gpointer data) 910 { 911 MainWindow *mainwin = (MainWindow*)data; 912 const GList *list; 913 const GList *cur; 914 915 cm_return_if_fail(mainwin != NULL); 916 917 toolbar_style(TOOLBAR_MAIN, action, mainwin); 918 919 list = compose_get_compose_list(); 920 for (cur = list; cur != NULL; cur = cur->next) { 921 toolbar_style(TOOLBAR_COMPOSE, action, cur->data); 922 } 923 list = messageview_get_msgview_list(); 924 for (cur = list; cur != NULL; cur = cur->next) { 925 toolbar_style(TOOLBAR_MSGVIEW, action, cur->data); 926 } 927 928 } 929 930 void toolbar_set_style(GtkWidget *toolbar_wid, GtkWidget *handlebox_wid, guint action) 931 { 932 switch ((ToolbarStyle)action) { 933 case TOOLBAR_NONE: 934 gtk_widget_hide(handlebox_wid); 935 break; 936 case TOOLBAR_ICON: 937 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid), 938 GTK_TOOLBAR_ICONS); 939 break; 940 case TOOLBAR_TEXT: 941 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid), 942 GTK_TOOLBAR_TEXT); 943 break; 944 case TOOLBAR_BOTH: 945 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid), 946 GTK_TOOLBAR_BOTH); 947 break; 948 case TOOLBAR_BOTH_HORIZ: 949 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar_wid), 950 GTK_TOOLBAR_BOTH_HORIZ); 951 break; 952 default: 953 return; 954 } 955 956 prefs_common.toolbar_style = (ToolbarStyle)action; 957 gtk_widget_set_size_request(handlebox_wid, 1, -1); 958 959 if (prefs_common.toolbar_style != TOOLBAR_NONE) { 960 gtk_widget_show(handlebox_wid); 961 gtk_widget_queue_resize(handlebox_wid); 962 } 963 } 964 /* 965 * Change the style of toolbar 966 */ 967 static void toolbar_style(ToolbarType type, guint action, gpointer data) 968 { 969 GtkWidget *handlebox_wid; 970 GtkWidget *toolbar_wid; 971 MainWindow *mainwin = (MainWindow*)data; 972 Compose *compose = (Compose*)data; 973 MessageView *msgview = (MessageView*)data; 974 975 cm_return_if_fail(data != NULL); 976 977 switch (type) { 978 case TOOLBAR_MAIN: 979 handlebox_wid = mainwin->handlebox; 980 toolbar_wid = mainwin->toolbar->toolbar; 981 break; 982 case TOOLBAR_COMPOSE: 983 handlebox_wid = compose->handlebox; 984 toolbar_wid = compose->toolbar->toolbar; 985 break; 986 case TOOLBAR_MSGVIEW: 987 handlebox_wid = msgview->handlebox; 988 toolbar_wid = msgview->toolbar->toolbar; 989 break; 990 default: 991 992 return; 993 } 994 toolbar_set_style(toolbar_wid, handlebox_wid, action); 995 } 996 997 /* Toolbar handling */ 998 static void toolbar_inc_cb(GtkWidget *widget, 999 gpointer data) 1000 { 1001 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1002 MainWindow *mainwin; 1003 1004 cm_return_if_fail(toolbar_item != NULL); 1005 1006 switch (toolbar_item->type) { 1007 case TOOLBAR_MAIN: 1008 mainwin = (MainWindow*)toolbar_item->parent; 1009 inc_mail_cb(mainwin, 0, NULL); 1010 break; 1011 default: 1012 break; 1013 } 1014 } 1015 1016 static void toolbar_inc_all_cb(GtkWidget *widget, 1017 gpointer data) 1018 { 1019 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1020 MainWindow *mainwin; 1021 1022 cm_return_if_fail(toolbar_item != NULL); 1023 1024 switch (toolbar_item->type) { 1025 case TOOLBAR_MAIN: 1026 mainwin = (MainWindow*)toolbar_item->parent; 1027 inc_all_account_mail_cb(mainwin, 0, NULL); 1028 break; 1029 default: 1030 break; 1031 } 1032 } 1033 1034 static void toolbar_send_queued_cb(GtkWidget *widget,gpointer data) 1035 { 1036 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1037 MainWindow *mainwin; 1038 1039 cm_return_if_fail(toolbar_item != NULL); 1040 1041 switch (toolbar_item->type) { 1042 case TOOLBAR_MAIN: 1043 mainwin = (MainWindow*)toolbar_item->parent; 1044 send_queue_cb(mainwin, 0, NULL); 1045 break; 1046 default: 1047 break; 1048 } 1049 } 1050 1051 static void toolbar_exec_cb(GtkWidget *widget, 1052 gpointer data) 1053 { 1054 MainWindow *mainwin = get_mainwin(data); 1055 1056 cm_return_if_fail(mainwin != NULL); 1057 summary_execute(mainwin->summaryview); 1058 } 1059 1060 /* 1061 * Delete current/selected(s) message(s) 1062 */ 1063 static void toolbar_trash_cb(GtkWidget *widget, gpointer data) 1064 { 1065 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1066 MainWindow *mainwin; 1067 1068 cm_return_if_fail(toolbar_item != NULL); 1069 cm_return_if_fail(toolbar_item->parent); 1070 1071 switch (toolbar_item->type) { 1072 case TOOLBAR_MSGVIEW: 1073 messageview_delete((MessageView *)toolbar_item->parent); 1074 break; 1075 case TOOLBAR_MAIN: 1076 mainwin = (MainWindow *)toolbar_item->parent; 1077 summary_delete_trash(mainwin->summaryview); 1078 break; 1079 default: 1080 debug_print("toolbar event not supported\n"); 1081 break; 1082 } 1083 } 1084 1085 /* 1086 * Delete current/selected(s) message(s) 1087 */ 1088 static void toolbar_delete_cb(GtkWidget *widget, gpointer data) 1089 { 1090 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1091 MainWindow *mainwin; 1092 1093 cm_return_if_fail(toolbar_item != NULL); 1094 cm_return_if_fail(toolbar_item->parent); 1095 1096 switch (toolbar_item->type) { 1097 case TOOLBAR_MSGVIEW: 1098 messageview_delete((MessageView *)toolbar_item->parent); 1099 break; 1100 case TOOLBAR_MAIN: 1101 mainwin = (MainWindow *)toolbar_item->parent; 1102 summary_delete(mainwin->summaryview); 1103 break; 1104 default: 1105 debug_print("toolbar event not supported\n"); 1106 break; 1107 } 1108 } 1109 1110 static void toolbar_delete_dup(gpointer data, guint all) 1111 { 1112 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1113 MainWindow *mainwin = NULL; 1114 1115 cm_return_if_fail(toolbar_item != NULL); 1116 1117 switch (toolbar_item->type) { 1118 case TOOLBAR_MAIN: 1119 mainwin = (MainWindow*)toolbar_item->parent; 1120 if (all) 1121 mainwindow_delete_duplicated_all(mainwin); 1122 else 1123 mainwindow_delete_duplicated(mainwin); 1124 break; 1125 case TOOLBAR_COMPOSE: 1126 case TOOLBAR_MSGVIEW: 1127 break; 1128 default: 1129 debug_print("toolbar event not supported\n"); 1130 return; 1131 } 1132 } 1133 1134 static void toolbar_delete_dup_cb(GtkWidget *widget, gpointer data) 1135 { 1136 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1137 MainWindow *mainwin = NULL; 1138 1139 cm_return_if_fail(toolbar_item != NULL); 1140 1141 switch (toolbar_item->type) { 1142 case TOOLBAR_MAIN: 1143 mainwin = (MainWindow*)toolbar_item->parent; 1144 mainwindow_delete_duplicated(mainwin); 1145 break; 1146 case TOOLBAR_COMPOSE: 1147 case TOOLBAR_MSGVIEW: 1148 break; 1149 default: 1150 return; 1151 } 1152 } 1153 1154 /* 1155 * Compose new message 1156 */ 1157 static void toolbar_compose_cb(GtkWidget *widget, gpointer data) 1158 { 1159 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1160 MainWindow *mainwin; 1161 MessageView *msgview; 1162 1163 cm_return_if_fail(toolbar_item != NULL); 1164 1165 switch (toolbar_item->type) { 1166 case TOOLBAR_MAIN: 1167 mainwin = (MainWindow*)toolbar_item->parent; 1168 compose_mail_cb(mainwin, 0, NULL); 1169 break; 1170 case TOOLBAR_MSGVIEW: 1171 msgview = (MessageView*)toolbar_item->parent; 1172 compose_new_with_folderitem(NULL, msgview->msginfo->folder, NULL); 1173 break; 1174 default: 1175 debug_print("toolbar event not supported\n"); 1176 } 1177 } 1178 1179 /* 1180 * Reply Message 1181 */ 1182 static void toolbar_reply_cb(GtkWidget *widget, gpointer data) 1183 { 1184 toolbar_reply(data, (prefs_common.reply_with_quote ? 1185 COMPOSE_REPLY_WITH_QUOTE : COMPOSE_REPLY_WITHOUT_QUOTE)); 1186 } 1187 1188 1189 /* 1190 * Reply message to Sender and All recipients 1191 */ 1192 static void toolbar_reply_to_all_cb(GtkWidget *widget, gpointer data) 1193 { 1194 toolbar_reply(data, 1195 (prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_ALL_WITH_QUOTE 1196 : COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE)); 1197 } 1198 1199 1200 /* 1201 * Reply to Mailing List 1202 */ 1203 static void toolbar_reply_to_list_cb(GtkWidget *widget, gpointer data) 1204 { 1205 toolbar_reply(data, 1206 (prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_LIST_WITH_QUOTE 1207 : COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE)); 1208 } 1209 1210 1211 /* 1212 * Reply to sender of message 1213 */ 1214 static void toolbar_reply_to_sender_cb(GtkWidget *widget, gpointer data) 1215 { 1216 toolbar_reply(data, 1217 (prefs_common.reply_with_quote ? COMPOSE_REPLY_TO_SENDER_WITH_QUOTE 1218 : COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE)); 1219 } 1220 1221 /* 1222 * Open addressbook 1223 */ 1224 static void toolbar_addrbook_cb(GtkWidget *widget, gpointer data) 1225 { 1226 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1227 Compose *compose; 1228 1229 cm_return_if_fail(toolbar_item != NULL); 1230 1231 switch (toolbar_item->type) { 1232 case TOOLBAR_MAIN: 1233 case TOOLBAR_MSGVIEW: 1234 compose = NULL; 1235 break; 1236 case TOOLBAR_COMPOSE: 1237 compose = (Compose *)toolbar_item->parent; 1238 break; 1239 default: 1240 return; 1241 } 1242 addressbook_open(compose); 1243 } 1244 1245 1246 /* 1247 * Forward current/selected(s) message(s) 1248 */ 1249 static void toolbar_forward_cb(GtkWidget *widget, gpointer data) 1250 { 1251 toolbar_reply(data, (COMPOSE_FORWARD)); 1252 } 1253 1254 /* 1255 * Goto Prev Unread Message 1256 */ 1257 static void toolbar_prev_unread_cb(GtkWidget *widget, gpointer data) 1258 { 1259 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1260 MainWindow *mainwin; 1261 MessageView *msgview; 1262 1263 cm_return_if_fail(toolbar_item != NULL); 1264 1265 switch (toolbar_item->type) { 1266 case TOOLBAR_MAIN: 1267 mainwin = (MainWindow*)toolbar_item->parent; 1268 summary_select_prev_unread(mainwin->summaryview); 1269 break; 1270 1271 case TOOLBAR_MSGVIEW: 1272 msgview = (MessageView*)toolbar_item->parent; 1273 msgview->updating = TRUE; 1274 summary_select_prev_unread(msgview->mainwin->summaryview); 1275 msgview->updating = FALSE; 1276 1277 if (msgview->deferred_destroy) { 1278 debug_print("messageview got away!\n"); 1279 messageview_destroy(msgview); 1280 return; 1281 } 1282 1283 /* Now we need to update the messageview window */ 1284 if (msgview->mainwin->summaryview->selected) { 1285 MsgInfo * msginfo = summary_get_selected_msg(msgview->mainwin->summaryview); 1286 1287 if (msginfo) 1288 messageview_show(msgview, msginfo, 1289 msgview->all_headers); 1290 } else { 1291 gtk_widget_destroy(msgview->window); 1292 } 1293 break; 1294 default: 1295 debug_print("toolbar event not supported\n"); 1296 } 1297 } 1298 1299 /* 1300 * Goto Next Unread Message 1301 */ 1302 static void toolbar_next_unread_cb(GtkWidget *widget, gpointer data) 1303 { 1304 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1305 MainWindow *mainwin; 1306 MessageView *msgview; 1307 1308 cm_return_if_fail(toolbar_item != NULL); 1309 1310 switch (toolbar_item->type) { 1311 case TOOLBAR_MAIN: 1312 mainwin = (MainWindow*)toolbar_item->parent; 1313 summary_select_next_unread(mainwin->summaryview); 1314 break; 1315 1316 case TOOLBAR_MSGVIEW: 1317 msgview = (MessageView*)toolbar_item->parent; 1318 msgview->updating = TRUE; 1319 summary_select_next_unread(msgview->mainwin->summaryview); 1320 msgview->updating = FALSE; 1321 1322 if (msgview->deferred_destroy) { 1323 debug_print("messageview got away!\n"); 1324 messageview_destroy(msgview); 1325 return; 1326 } 1327 1328 /* Now we need to update the messageview window */ 1329 if (msgview->mainwin->summaryview->selected) { 1330 MsgInfo * msginfo = summary_get_selected_msg(msgview->mainwin->summaryview); 1331 1332 if (msginfo) 1333 messageview_show(msgview, msginfo, 1334 msgview->all_headers); 1335 } else { 1336 gtk_widget_destroy(msgview->window); 1337 } 1338 break; 1339 default: 1340 debug_print("toolbar event not supported\n"); 1341 } 1342 } 1343 1344 static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data) 1345 { 1346 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1347 MainWindow *mainwin; 1348 1349 cm_return_if_fail(toolbar_item != NULL); 1350 1351 switch (toolbar_item->type) { 1352 case TOOLBAR_MAIN: 1353 mainwin = (MainWindow *) toolbar_item->parent; 1354 summary_toggle_ignore_thread(mainwin->summaryview); 1355 break; 1356 case TOOLBAR_MSGVIEW: 1357 /* TODO: see toolbar_next_unread_cb() if you need 1358 * this in the message view */ 1359 break; 1360 default: 1361 debug_print("toolbar event not supported\n"); 1362 break; 1363 } 1364 } 1365 1366 static void toolbar_watch_thread_cb(GtkWidget *widget, gpointer data) 1367 { 1368 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1369 MainWindow *mainwin; 1370 1371 cm_return_if_fail(toolbar_item != NULL); 1372 1373 switch (toolbar_item->type) { 1374 case TOOLBAR_MAIN: 1375 mainwin = (MainWindow *) toolbar_item->parent; 1376 summary_toggle_watch_thread(mainwin->summaryview); 1377 break; 1378 case TOOLBAR_MSGVIEW: 1379 /* TODO: see toolbar_next_unread_cb() if you need 1380 * this in the message view */ 1381 break; 1382 default: 1383 debug_print("toolbar event not supported\n"); 1384 break; 1385 } 1386 } 1387 1388 static void toolbar_mark_cb(GtkWidget *widget, gpointer data) 1389 { 1390 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1391 MainWindow *mainwin; 1392 1393 cm_return_if_fail(toolbar_item != NULL); 1394 1395 switch (toolbar_item->type) { 1396 case TOOLBAR_MAIN: 1397 mainwin = (MainWindow *) toolbar_item->parent; 1398 summary_mark(mainwin->summaryview); 1399 break; 1400 case TOOLBAR_MSGVIEW: 1401 /* TODO: see toolbar_next_unread_cb() if you need 1402 * this in the message view */ 1403 break; 1404 default: 1405 debug_print("toolbar event not supported\n"); 1406 break; 1407 } 1408 } 1409 1410 static void toolbar_unmark_cb(GtkWidget *widget, gpointer data) 1411 { 1412 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1413 MainWindow *mainwin; 1414 1415 cm_return_if_fail(toolbar_item != NULL); 1416 1417 switch (toolbar_item->type) { 1418 case TOOLBAR_MAIN: 1419 mainwin = (MainWindow *) toolbar_item->parent; 1420 summary_unmark(mainwin->summaryview); 1421 break; 1422 case TOOLBAR_MSGVIEW: 1423 /* TODO: see toolbar_next_unread_cb() if you need 1424 * this in the message view */ 1425 break; 1426 default: 1427 debug_print("toolbar event not supported\n"); 1428 break; 1429 } 1430 } 1431 1432 static void toolbar_lock_cb(GtkWidget *widget, gpointer data) 1433 { 1434 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1435 MainWindow *mainwin; 1436 1437 cm_return_if_fail(toolbar_item != NULL); 1438 1439 switch (toolbar_item->type) { 1440 case TOOLBAR_MAIN: 1441 mainwin = (MainWindow *) toolbar_item->parent; 1442 summary_msgs_lock(mainwin->summaryview); 1443 break; 1444 case TOOLBAR_MSGVIEW: 1445 /* TODO: see toolbar_next_unread_cb() if you need 1446 * this in the message view */ 1447 break; 1448 default: 1449 debug_print("toolbar event not supported\n"); 1450 break; 1451 } 1452 } 1453 1454 static void toolbar_unlock_cb(GtkWidget *widget, gpointer data) 1455 { 1456 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1457 MainWindow *mainwin; 1458 1459 cm_return_if_fail(toolbar_item != NULL); 1460 1461 switch (toolbar_item->type) { 1462 case TOOLBAR_MAIN: 1463 mainwin = (MainWindow *) toolbar_item->parent; 1464 summary_msgs_unlock(mainwin->summaryview); 1465 break; 1466 case TOOLBAR_MSGVIEW: 1467 /* TODO: see toolbar_next_unread_cb() if you need 1468 * this in the message view */ 1469 break; 1470 default: 1471 debug_print("toolbar event not supported\n"); 1472 break; 1473 } 1474 } 1475 1476 static void toolbar_all_read_cb(GtkWidget *widget, gpointer data) 1477 { 1478 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1479 MainWindow *mainwin; 1480 1481 cm_return_if_fail(toolbar_item != NULL); 1482 1483 switch (toolbar_item->type) { 1484 case TOOLBAR_MAIN: 1485 mainwin = (MainWindow *) toolbar_item->parent; 1486 summary_mark_all_read(mainwin->summaryview, TRUE); 1487 break; 1488 case TOOLBAR_MSGVIEW: 1489 /* TODO: see toolbar_next_unread_cb() if you need 1490 * this in the message view */ 1491 break; 1492 default: 1493 debug_print("toolbar event not supported\n"); 1494 break; 1495 } 1496 } 1497 1498 static void toolbar_all_unread_cb(GtkWidget *widget, gpointer data) 1499 { 1500 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1501 MainWindow *mainwin; 1502 1503 cm_return_if_fail(toolbar_item != NULL); 1504 1505 switch (toolbar_item->type) { 1506 case TOOLBAR_MAIN: 1507 mainwin = (MainWindow *) toolbar_item->parent; 1508 summary_mark_all_unread(mainwin->summaryview, TRUE); 1509 break; 1510 case TOOLBAR_MSGVIEW: 1511 /* TODO: see toolbar_next_unread_cb() if you need 1512 * this in the message view */ 1513 break; 1514 default: 1515 debug_print("toolbar event not supported\n"); 1516 break; 1517 } 1518 } 1519 1520 static void toolbar_read_cb(GtkWidget *widget, gpointer data) 1521 { 1522 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1523 MainWindow *mainwin; 1524 1525 cm_return_if_fail(toolbar_item != NULL); 1526 1527 switch (toolbar_item->type) { 1528 case TOOLBAR_MAIN: 1529 mainwin = (MainWindow *) toolbar_item->parent; 1530 summary_mark_as_read(mainwin->summaryview); 1531 break; 1532 case TOOLBAR_MSGVIEW: 1533 /* TODO: see toolbar_next_unread_cb() if you need 1534 * this in the message view */ 1535 break; 1536 default: 1537 debug_print("toolbar event not supported\n"); 1538 break; 1539 } 1540 } 1541 1542 static void toolbar_unread_cb(GtkWidget *widget, gpointer data) 1543 { 1544 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1545 MainWindow *mainwin; 1546 1547 cm_return_if_fail(toolbar_item != NULL); 1548 1549 switch (toolbar_item->type) { 1550 case TOOLBAR_MAIN: 1551 mainwin = (MainWindow *) toolbar_item->parent; 1552 summary_mark_as_unread(mainwin->summaryview); 1553 break; 1554 case TOOLBAR_MSGVIEW: 1555 /* TODO: see toolbar_next_unread_cb() if you need 1556 * this in the message view */ 1557 break; 1558 default: 1559 debug_print("toolbar event not supported\n"); 1560 break; 1561 } 1562 } 1563 1564 static void toolbar_run_processing_cb(GtkWidget *widget, gpointer data) 1565 { 1566 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1567 MainWindow *mainwin; 1568 FolderItem *item; 1569 1570 cm_return_if_fail(toolbar_item != NULL); 1571 1572 switch (toolbar_item->type) { 1573 case TOOLBAR_MAIN: 1574 mainwin = (MainWindow *) toolbar_item->parent; 1575 item = mainwin->summaryview->folder_item; 1576 cm_return_if_fail(item != NULL); 1577 item->processing_pending = FALSE; 1578 break; 1579 default: 1580 debug_print("toolbar event not supported\n"); 1581 break; 1582 } 1583 } 1584 1585 static void toolbar_cancel_inc_cb(GtkWidget *widget, gpointer data) 1586 { 1587 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1588 1589 cm_return_if_fail(toolbar_item != NULL); 1590 inc_cancel_all(); 1591 imap_cancel_all(); 1592 } 1593 1594 static void toolbar_cancel_send_cb(GtkWidget *widget, gpointer data) 1595 { 1596 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1597 1598 cm_return_if_fail(toolbar_item != NULL); 1599 send_cancel(); 1600 } 1601 1602 static void toolbar_cancel_all_cb(GtkWidget *widget, gpointer data) 1603 { 1604 toolbar_cancel_inc_cb(widget, data); 1605 toolbar_cancel_send_cb(widget, data); 1606 } 1607 1608 static void toolbar_send_cb(GtkWidget *widget, gpointer data) 1609 { 1610 compose_toolbar_cb(A_SEND, data); 1611 } 1612 1613 static void toolbar_send_later_cb(GtkWidget *widget, gpointer data) 1614 { 1615 compose_toolbar_cb(A_SEND_LATER, data); 1616 } 1617 1618 static void toolbar_draft_cb(GtkWidget *widget, gpointer data) 1619 { 1620 compose_toolbar_cb(A_DRAFT, data); 1621 } 1622 1623 static void toolbar_close_cb(GtkWidget *widget, gpointer data) 1624 { 1625 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1626 MainWindow *mainwin; 1627 MessageView *messageview; 1628 Compose *compose; 1629 1630 cm_return_if_fail(toolbar_item != NULL); 1631 1632 switch (toolbar_item->type) { 1633 case TOOLBAR_MAIN: 1634 mainwin = (MainWindow *) toolbar_item->parent; 1635 app_will_exit(NULL, mainwin); 1636 break; 1637 case TOOLBAR_MSGVIEW: 1638 messageview = (MessageView *)toolbar_item->parent; 1639 messageview_destroy(messageview); 1640 break; 1641 case TOOLBAR_COMPOSE: 1642 compose = (Compose *)toolbar_item->parent; 1643 compose_close_toolbar(compose); 1644 break; 1645 } 1646 } 1647 1648 static void toolbar_preferences_cb(GtkWidget *widget, gpointer data) 1649 { 1650 prefs_gtk_open(); 1651 } 1652 1653 static void toolbar_open_mail_cb(GtkWidget *widget, gpointer data) 1654 { 1655 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1656 MainWindow *mainwin; 1657 1658 cm_return_if_fail(toolbar_item != NULL); 1659 1660 switch (toolbar_item->type) { 1661 case TOOLBAR_MAIN: 1662 mainwin = (MainWindow *) toolbar_item->parent; 1663 summary_open_row(NULL, mainwin->summaryview); 1664 break; 1665 case TOOLBAR_MSGVIEW: 1666 debug_print("toolbar event not supported\n"); 1667 break; 1668 case TOOLBAR_COMPOSE: 1669 debug_print("toolbar event not supported\n"); 1670 break; 1671 } 1672 } 1673 1674 static void toolbar_insert_cb(GtkWidget *widget, gpointer data) 1675 { 1676 compose_toolbar_cb(A_INSERT, data); 1677 } 1678 1679 static void toolbar_attach_cb(GtkWidget *widget, gpointer data) 1680 { 1681 compose_toolbar_cb(A_ATTACH, data); 1682 } 1683 1684 static void toolbar_sig_cb(GtkWidget *widget, gpointer data) 1685 { 1686 compose_toolbar_cb(A_SIG, data); 1687 } 1688 1689 static void toolbar_replace_sig_cb(GtkWidget *widget, gpointer data) 1690 { 1691 compose_toolbar_cb(A_REP_SIG, data); 1692 } 1693 1694 static void toolbar_ext_editor_cb(GtkWidget *widget, gpointer data) 1695 { 1696 compose_toolbar_cb(A_EXTEDITOR, data); 1697 } 1698 1699 static void toolbar_linewrap_current_cb(GtkWidget *widget, gpointer data) 1700 { 1701 compose_toolbar_cb(A_LINEWRAP_CURRENT, data); 1702 } 1703 1704 static void toolbar_linewrap_all_cb(GtkWidget *widget, gpointer data) 1705 { 1706 compose_toolbar_cb(A_LINEWRAP_ALL, data); 1707 } 1708 1709 /* 1710 * Execute actions from toolbar 1711 */ 1712 static void toolbar_actions_execute_cb(GtkWidget *widget, gpointer data) 1713 { 1714 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1715 GSList *action_list; 1716 MainWindow *mainwin; 1717 Compose *compose; 1718 MessageView *msgview; 1719 gpointer parent = toolbar_item->parent; 1720 1721 cm_return_if_fail(toolbar_item != NULL); 1722 1723 switch (toolbar_item->type) { 1724 case TOOLBAR_MAIN: 1725 mainwin = (MainWindow*)parent; 1726 action_list = mainwin->toolbar->action_list; 1727 break; 1728 case TOOLBAR_COMPOSE: 1729 compose = (Compose*)parent; 1730 action_list = compose->toolbar->action_list; 1731 break; 1732 case TOOLBAR_MSGVIEW: 1733 msgview = (MessageView*)parent; 1734 action_list = msgview->toolbar->action_list; 1735 break; 1736 default: 1737 debug_print("toolbar event not supported\n"); 1738 return; 1739 } 1740 toolbar_action_execute(widget, action_list, parent, toolbar_item->type); 1741 } 1742 1743 static MainWindow *get_mainwin(gpointer data) 1744 { 1745 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1746 MainWindow *mainwin = NULL; 1747 MessageView *msgview; 1748 1749 cm_return_val_if_fail(toolbar_item != NULL, NULL); 1750 1751 switch(toolbar_item->type) { 1752 case TOOLBAR_MAIN: 1753 mainwin = (MainWindow*)toolbar_item->parent; 1754 break; 1755 case TOOLBAR_MSGVIEW: 1756 msgview = (MessageView*)toolbar_item->parent; 1757 mainwin = (MainWindow*)msgview->mainwin; 1758 break; 1759 default: 1760 break; 1761 } 1762 1763 return mainwin; 1764 } 1765 1766 static void toolbar_go_folders_cb(GtkWidget *widget, gpointer data) 1767 { 1768 ToolbarItem *toolbar_item = (ToolbarItem*)data; 1769 MainWindow *mainwin = NULL; 1770 switch(toolbar_item->type) { 1771 case TOOLBAR_MAIN: 1772 mainwin = (MainWindow*)toolbar_item->parent; 1773 break; 1774 default: 1775 g_warning("wrong toolbar type"); 1776 return; 1777 } 1778 1779 if (!mainwin->in_folder) { 1780 FolderItem *item = folderview_get_selected_item(mainwin->folderview); 1781 if (item) { 1782 folderview_select(mainwin->folderview, item); 1783 } 1784 } else { 1785 folderview_grab_focus(mainwin->folderview); 1786 mainwindow_exit_folder(mainwin); 1787 } 1788 } 1789 1790 static void toolbar_buttons_cb(GtkWidget *widget, 1791 ToolbarItem *item) 1792 { 1793 gint num_items; 1794 gint i; 1795 struct { 1796 gint index; 1797 void (*func)(GtkWidget *widget, gpointer data); 1798 } callbacks[] = { 1799 { A_RECEIVE_ALL, toolbar_inc_all_cb }, 1800 { A_RECEIVE_CUR, toolbar_inc_cb }, 1801 { A_SEND_QUEUED, toolbar_send_queued_cb }, 1802 { A_COMPOSE_EMAIL, toolbar_compose_cb }, 1803 { A_REPLY_MESSAGE, toolbar_reply_cb }, 1804 { A_REPLY_SENDER, toolbar_reply_to_sender_cb }, 1805 { A_REPLY_ALL, toolbar_reply_to_all_cb }, 1806 { A_REPLY_ML, toolbar_reply_to_list_cb }, 1807 { A_FORWARD, toolbar_forward_cb }, 1808 { A_TRASH, toolbar_trash_cb }, 1809 { A_DELETE_REAL, toolbar_delete_cb }, 1810 { A_EXECUTE, toolbar_exec_cb }, 1811 { A_GOTO_PREV, toolbar_prev_unread_cb }, 1812 { A_GOTO_NEXT, toolbar_next_unread_cb }, 1813 { A_IGNORE_THREAD, toolbar_ignore_thread_cb }, 1814 { A_WATCH_THREAD, toolbar_watch_thread_cb }, 1815 { A_MARK, toolbar_mark_cb }, 1816 { A_UNMARK, toolbar_unmark_cb }, 1817 { A_LOCK, toolbar_lock_cb }, 1818 { A_UNLOCK, toolbar_unlock_cb }, 1819 { A_ALL_READ, toolbar_all_read_cb }, 1820 { A_ALL_UNREAD, toolbar_all_unread_cb }, 1821 { A_READ, toolbar_read_cb }, 1822 { A_UNREAD, toolbar_unread_cb }, 1823 { A_RUN_PROCESSING, toolbar_run_processing_cb }, 1824 { A_DELETE_DUP, toolbar_delete_dup_cb }, 1825 { A_GO_FOLDERS, toolbar_go_folders_cb }, 1826 1827 { A_SEND, toolbar_send_cb }, 1828 { A_SEND_LATER, toolbar_send_later_cb }, 1829 { A_DRAFT, toolbar_draft_cb }, 1830 { A_OPEN_MAIL, toolbar_open_mail_cb }, 1831 { A_CLOSE, toolbar_close_cb }, 1832 { A_PREFERENCES, toolbar_preferences_cb }, 1833 { A_INSERT, toolbar_insert_cb }, 1834 { A_ATTACH, toolbar_attach_cb }, 1835 { A_SIG, toolbar_sig_cb }, 1836 { A_REP_SIG, toolbar_replace_sig_cb }, 1837 { A_EXTEDITOR, toolbar_ext_editor_cb }, 1838 { A_LINEWRAP_CURRENT, toolbar_linewrap_current_cb }, 1839 { A_LINEWRAP_ALL, toolbar_linewrap_all_cb }, 1840 { A_ADDRBOOK, toolbar_addrbook_cb }, 1841 { A_CLAWS_ACTIONS, toolbar_actions_execute_cb }, 1842 { A_CANCEL_INC, toolbar_cancel_inc_cb }, 1843 { A_CANCEL_SEND, toolbar_cancel_send_cb }, 1844 { A_CANCEL_ALL, toolbar_cancel_all_cb }, 1845 }; 1846 1847 num_items = sizeof(callbacks)/sizeof(callbacks[0]); 1848 1849 for (i = 0; i < num_items; i++) { 1850 if (callbacks[i].index == item->index) { 1851 callbacks[i].func(widget, item); 1852 return; 1853 } 1854 } 1855 } 1856 1857 #define TOOLBAR_ITEM(item,icon,text,tooltip) { \ 1858 item = GTK_WIDGET(gtk_tool_button_new(icon, text)); \ 1859 gtk_widget_set_can_focus(gtk_bin_get_child(GTK_BIN(item)), FALSE); \ 1860 gtk_tool_item_set_homogeneous(GTK_TOOL_ITEM(item), FALSE); \ 1861 gtk_tool_item_set_is_important(GTK_TOOL_ITEM(item), TRUE); \ 1862 g_signal_connect (G_OBJECT(item), "clicked", G_CALLBACK(toolbar_buttons_cb), toolbar_item); \ 1863 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), -1); \ 1864 CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(item), \ 1865 tooltip); \ 1866 } 1867 1868 #define TOOLBAR_TOGGLE_ITEM(item,icon,text,tooltip) { \ 1869 item = GTK_WIDGET(gtk_toggle_tool_button_new()); \ 1870 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(item), icon); \ 1871 gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), text); \ 1872 gtk_widget_set_can_focus(gtk_bin_get_child(GTK_BIN(item)), FALSE); \ 1873 gtk_tool_item_set_homogeneous(GTK_TOOL_ITEM(item), FALSE); \ 1874 gtk_tool_item_set_is_important(GTK_TOOL_ITEM(item), TRUE); \ 1875 g_signal_connect (G_OBJECT(item), "clicked", G_CALLBACK(toolbar_buttons_cb), toolbar_item); \ 1876 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), -1); \ 1877 CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(item), \ 1878 tooltip); \ 1879 } 1880 1881 #define TOOLBAR_MENUITEM(item,icon,text,tooltip,menutip) { \ 1882 GtkWidget *child = NULL, *btn = NULL, *arr = NULL; \ 1883 GList *gchild = NULL; \ 1884 item = GTK_WIDGET(gtk_menu_tool_button_new(icon, text)); \ 1885 gtk_tool_item_set_homogeneous(GTK_TOOL_ITEM(item), FALSE); \ 1886 gtk_tool_item_set_is_important(GTK_TOOL_ITEM(item), TRUE); \ 1887 g_signal_connect (G_OBJECT(item), "clicked", G_CALLBACK(toolbar_buttons_cb), toolbar_item); \ 1888 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), -1); \ 1889 CLAWS_SET_TOOL_ITEM_TIP(GTK_TOOL_ITEM(item), \ 1890 tooltip); \ 1891 CLAWS_SET_ARROW_TIP(GTK_MENU_TOOL_BUTTON(item), menutip); \ 1892 child = gtk_bin_get_child(GTK_BIN(item)); \ 1893 gchild = gtk_container_get_children( \ 1894 GTK_CONTAINER(child)); \ 1895 btn = (GtkWidget *)gchild->data; \ 1896 gtk_widget_set_can_focus(btn, FALSE); \ 1897 arr = (GtkWidget *)(gchild->next?gchild->next->data:NULL); \ 1898 gtk_widget_set_can_focus(arr, FALSE); \ 1899 g_list_free(gchild); \ 1900 gchild = gtk_container_get_children(GTK_CONTAINER(arr)); \ 1901 gtk_widget_set_size_request(GTK_WIDGET(gchild->data), 9, -1); \ 1902 g_list_free(gchild); \ 1903 } 1904 1905 #define ADD_MENU_ITEM(name,cb,data) { \ 1906 item = gtk_menu_item_new_with_mnemonic(name); \ 1907 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); \ 1908 g_signal_connect(G_OBJECT(item), "activate", \ 1909 G_CALLBACK(cb), \ 1910 toolbar_item); \ 1911 g_object_set_data(G_OBJECT(item), "int-value", GINT_TO_POINTER(data)); \ 1912 gtk_widget_show(item); \ 1913 } 1914 1915 static void toolbar_reply_menu_cb(GtkWidget *widget, gpointer data) 1916 { 1917 gpointer int_value = g_object_get_data(G_OBJECT(widget), "int-value"); 1918 ToolbarItem *toolbar_item = (ToolbarItem *)data; 1919 1920 toolbar_reply(toolbar_item, GPOINTER_TO_INT(int_value)); 1921 } 1922 1923 static void toolbar_delete_dup_menu_cb(GtkWidget *widget, gpointer data) 1924 { 1925 gpointer int_value = g_object_get_data(G_OBJECT(widget), "int-value"); 1926 ToolbarItem *toolbar_item = (ToolbarItem *)data; 1927 1928 toolbar_delete_dup(toolbar_item, GPOINTER_TO_INT(int_value)); 1929 } 1930 1931 /** 1932 * Create a new toolbar with specified type 1933 * if a callback list is passed it will be used before the 1934 * common callback list 1935 **/ 1936 Toolbar *toolbar_create(ToolbarType type, 1937 GtkWidget *container, 1938 gpointer data) 1939 { 1940 ToolbarItem *toolbar_item; 1941 1942 GtkWidget *toolbar; 1943 GtkWidget *icon_wid = NULL; 1944 GtkWidget *item; 1945 ToolbarClawsActions *action_item; 1946 GSList *cur; 1947 GSList *toolbar_list; 1948 Toolbar *toolbar_data; 1949 GtkWidget *menu; 1950 toolbar_read_config_file(type); 1951 toolbar_list = toolbar_get_list(type); 1952 1953 toolbar_data = g_new0(Toolbar, 1); 1954 1955 toolbar = gtk_toolbar_new(); 1956 1957 gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL); 1958 1959 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH); 1960 gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolbar), TRUE); 1961 gtk_widget_set_hexpand(toolbar, TRUE); 1962 1963 for (cur = toolbar_list; cur != NULL; cur = cur->next) { 1964 1965 if (g_ascii_strcasecmp(((ToolbarItem*)cur->data)->file, TOOLBAR_TAG_SEPARATOR) == 0) { 1966 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), gtk_separator_tool_item_new(), -1); 1967 continue; 1968 } 1969 1970 toolbar_item = g_new0(ToolbarItem, 1); 1971 toolbar_item->index = ((ToolbarItem*)cur->data)->index; 1972 toolbar_item->file = g_strdup(((ToolbarItem*)cur->data)->file); 1973 toolbar_item->text = g_strdup(((ToolbarItem*)cur->data)->text); 1974 toolbar_item->parent = data; 1975 toolbar_item->type = type; 1976 1977 /* collect toolbar items in list to keep track */ 1978 toolbar_data->item_list = 1979 g_slist_append(toolbar_data->item_list, 1980 toolbar_item); 1981 icon_wid = stock_pixmap_widget(stock_pixmap_get_icon(toolbar_item->file)); 1982 1983 switch (toolbar_item->index) { 1984 1985 case A_GO_FOLDERS: 1986 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Go to folder list")); 1987 toolbar_data->folders_btn = item; 1988 break; 1989 case A_RECEIVE_ALL: 1990 TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text, 1991 _("Receive Mail from all Accounts"), 1992 _("Receive Mail from selected Account")); 1993 toolbar_data->getall_btn = item; 1994 break; 1995 case A_RECEIVE_CUR: 1996 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Receive Mail from current Account")); 1997 toolbar_data->get_btn = item; 1998 break; 1999 case A_SEND_QUEUED: 2000 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Send Queued Messages")); 2001 toolbar_data->send_btn = item; 2002 break; 2003 case A_CLOSE: 2004 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Close window")); 2005 toolbar_data->close_window_btn = item; 2006 break; 2007 case A_PREFERENCES: 2008 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Open preferences")); 2009 toolbar_data->preferences_btn = item; 2010 break; 2011 case A_OPEN_MAIL: 2012 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Open email")); 2013 toolbar_data->open_mail_btn = item; 2014 break; 2015 case A_COMPOSE_EMAIL: 2016 TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text, 2017 _("Write Email"), 2018 _("Write with selected Account")); 2019 toolbar_data->compose_mail_btn = item; 2020 toolbar_data->compose_mail_icon = icon_wid; 2021 g_object_ref_sink(toolbar_data->compose_mail_icon); 2022 break; 2023 case A_DELETE_DUP: 2024 TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text, 2025 _("Delete duplicates"), 2026 _("Delete duplicates options")); 2027 toolbar_data->delete_dup_btn = item; 2028 2029 menu = gtk_menu_new(); 2030 ADD_MENU_ITEM(_("Delete duplicates in selected folder"), toolbar_delete_dup_menu_cb, FALSE); 2031 ADD_MENU_ITEM(_("Delete duplicates in all folders"), toolbar_delete_dup_menu_cb, TRUE); 2032 gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->delete_dup_btn), menu); 2033 break; 2034 case A_REPLY_MESSAGE: 2035 TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text, 2036 _("Reply to Message"), 2037 _("Reply to Message options")); 2038 toolbar_data->reply_btn = item; 2039 2040 menu = gtk_menu_new(); 2041 ADD_MENU_ITEM(_("_Reply with quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_WITH_QUOTE); 2042 ADD_MENU_ITEM(_("Reply without _quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_WITHOUT_QUOTE); 2043 gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->reply_btn), menu); 2044 break; 2045 case A_REPLY_SENDER: 2046 TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text, 2047 _("Reply to Sender"), 2048 _("Reply to Sender options")); 2049 toolbar_data->replysender_btn = item; 2050 2051 menu = gtk_menu_new(); 2052 ADD_MENU_ITEM(_("_Reply with quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_SENDER_WITH_QUOTE); 2053 ADD_MENU_ITEM(_("Reply without _quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE); 2054 gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->replysender_btn), menu); 2055 break; 2056 case A_REPLY_ALL: 2057 TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text, 2058 _("Reply to All"), 2059 _("Reply to All options")); 2060 toolbar_data->replyall_btn = item; 2061 2062 menu = gtk_menu_new(); 2063 ADD_MENU_ITEM(_("_Reply with quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_ALL_WITH_QUOTE); 2064 ADD_MENU_ITEM(_("Reply without _quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE); 2065 gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->replyall_btn), menu); 2066 break; 2067 case A_REPLY_ML: 2068 TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text, 2069 _("Reply to Mailing-list"), 2070 _("Reply to Mailing-list options")); 2071 toolbar_data->replylist_btn = item; 2072 2073 menu = gtk_menu_new(); 2074 ADD_MENU_ITEM(_("_Reply with quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_LIST_WITH_QUOTE); 2075 ADD_MENU_ITEM(_("Reply without _quote"), toolbar_reply_menu_cb, COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE); 2076 gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->replylist_btn), menu); 2077 break; 2078 case A_FORWARD: 2079 TOOLBAR_MENUITEM(item,icon_wid,toolbar_item->text, 2080 _("Forward Message"), 2081 _("Forward Message options")); 2082 toolbar_data->fwd_btn = item; 2083 2084 menu = gtk_menu_new(); 2085 ADD_MENU_ITEM(_("_Forward"), toolbar_reply_menu_cb, COMPOSE_FORWARD_INLINE); 2086 ADD_MENU_ITEM(_("For_ward as attachment"), toolbar_reply_menu_cb, COMPOSE_FORWARD_AS_ATTACH); 2087 ADD_MENU_ITEM(_("Redirec_t"), toolbar_reply_menu_cb, COMPOSE_REDIRECT); 2088 gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_data->fwd_btn), menu); 2089 break; 2090 case A_TRASH: 2091 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Trash Message")); 2092 toolbar_data->trash_btn = item; 2093 break; 2094 case A_DELETE_REAL: 2095 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Delete Message")); 2096 toolbar_data->delete_btn = item; 2097 break; 2098 case A_EXECUTE: 2099 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Execute")); 2100 toolbar_data->exec_btn = item; 2101 break; 2102 case A_GOTO_PREV: 2103 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Go to Previous Unread Message")); 2104 toolbar_data->prev_btn = item; 2105 break; 2106 case A_GOTO_NEXT: 2107 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Go to Next Unread Message")); 2108 toolbar_data->next_btn = item; 2109 break; 2110 2111 /* Compose Toolbar */ 2112 case A_SEND: 2113 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Send Message")); 2114 toolbar_data->send_btn = item; 2115 break; 2116 case A_SEND_LATER: 2117 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Put into queue folder and send later")); 2118 toolbar_data->sendl_btn = item; 2119 break; 2120 case A_DRAFT: 2121 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Save to draft folder")); 2122 toolbar_data->draft_btn = item; 2123 break; 2124 case A_INSERT: 2125 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Insert file")); 2126 toolbar_data->insert_btn = item; 2127 break; 2128 case A_ATTACH: 2129 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Attach file")); 2130 toolbar_data->attach_btn = item; 2131 break; 2132 case A_SIG: 2133 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Insert signature")); 2134 toolbar_data->sig_btn = item; 2135 break; 2136 case A_REP_SIG: 2137 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Replace signature")); 2138 toolbar_data->repsig_btn = item; 2139 break; 2140 case A_EXTEDITOR: 2141 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Edit with external editor")); 2142 toolbar_data->exteditor_btn = item; 2143 break; 2144 case A_LINEWRAP_CURRENT: 2145 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Wrap long lines of current paragraph")); 2146 toolbar_data->linewrap_current_btn = item; 2147 break; 2148 case A_LINEWRAP_ALL: 2149 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Wrap all long lines")); 2150 toolbar_data->linewrap_all_btn = item; 2151 break; 2152 case A_ADDRBOOK: 2153 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Address book")); 2154 toolbar_data->addrbook_btn = item; 2155 break; 2156 case A_CLAWS_ACTIONS: 2157 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,toolbar_item->text); 2158 action_item = g_new0(ToolbarClawsActions, 1); 2159 action_item->widget = item; 2160 action_item->name = g_strdup(toolbar_item->text); 2161 2162 toolbar_data->action_list = 2163 g_slist_append(toolbar_data->action_list, 2164 action_item); 2165 break; 2166 case A_CANCEL_INC: 2167 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Cancel receiving")); 2168 toolbar_data->cancel_inc_btn = item; 2169 break; 2170 case A_CANCEL_SEND: 2171 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Cancel sending")); 2172 toolbar_data->cancel_send_btn = item; 2173 break; 2174 case A_CANCEL_ALL: 2175 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text,_("Cancel receiving/sending")); 2176 toolbar_data->cancel_all_btn = item; 2177 break; 2178 default: 2179 TOOLBAR_ITEM(item,icon_wid,toolbar_item->text, 2180 toolbar_ret_descr_from_val(toolbar_item->index)); 2181 /* find and set the tool tip text */ 2182 break; 2183 } 2184 2185 } 2186 toolbar_data->toolbar = toolbar; 2187 2188 gtk_widget_show_all(toolbar); 2189 2190 if (type == TOOLBAR_MAIN) { 2191 activate_compose_button(toolbar_data, 2192 prefs_common.toolbar_style, 2193 toolbar_data->compose_btn_type); 2194 } 2195 2196 gtk_container_add(GTK_CONTAINER(container), toolbar); 2197 gtk_container_set_border_width(GTK_CONTAINER(container), 0); 2198 2199 return toolbar_data; 2200 } 2201 2202 /** 2203 * Free toolbar structures 2204 */ 2205 2206 #define UNREF_ICON(icon) if (toolbar->icon != NULL) \ 2207 g_object_unref(toolbar->icon) 2208 2209 void toolbar_destroy(Toolbar * toolbar) 2210 { 2211 UNREF_ICON(compose_mail_icon); 2212 TOOLBAR_DESTROY_ITEMS(toolbar->item_list); 2213 TOOLBAR_DESTROY_ACTIONS(toolbar->action_list); 2214 } 2215 2216 #undef UNREF_ICON 2217 2218 void toolbar_item_destroy(ToolbarItem *item) 2219 { 2220 cm_return_if_fail(item != NULL); 2221 2222 if (item->file) 2223 g_free(item->file); 2224 if (item->text) 2225 g_free(item->text); 2226 g_free(item); 2227 } 2228 2229 void toolbar_update(ToolbarType type, gpointer data) 2230 { 2231 Toolbar *toolbar_data; 2232 GtkWidget *handlebox; 2233 MainWindow *mainwin = (MainWindow*)data; 2234 Compose *compose = (Compose*)data; 2235 MessageView *msgview = (MessageView*)data; 2236 2237 switch(type) { 2238 case TOOLBAR_MAIN: 2239 toolbar_data = mainwin->toolbar; 2240 handlebox = mainwin->handlebox; 2241 break; 2242 case TOOLBAR_COMPOSE: 2243 toolbar_data = compose->toolbar; 2244 handlebox = compose->handlebox; 2245 break; 2246 case TOOLBAR_MSGVIEW: 2247 toolbar_data = msgview->toolbar; 2248 handlebox = msgview->handlebox; 2249 break; 2250 default: 2251 return; 2252 } 2253 2254 gtk_container_remove(GTK_CONTAINER(handlebox), 2255 GTK_WIDGET(toolbar_data->toolbar)); 2256 2257 toolbar_init(toolbar_data); 2258 toolbar_data = toolbar_create(type, handlebox, data); 2259 2260 switch(type) { 2261 case TOOLBAR_MAIN: 2262 mainwin->toolbar = toolbar_data; 2263 break; 2264 case TOOLBAR_COMPOSE: 2265 compose->toolbar = toolbar_data; 2266 break; 2267 case TOOLBAR_MSGVIEW: 2268 msgview->toolbar = toolbar_data; 2269 break; 2270 } 2271 2272 toolbar_style(type, prefs_common.toolbar_style, data); 2273 2274 if (type == TOOLBAR_MAIN) { 2275 toolbar_main_set_sensitive((MainWindow*)data); 2276 account_set_menu_only_toolbar(); 2277 } 2278 } 2279 2280 #define GTK_BUTTON_SET_SENSITIVE(widget,sensitive) { \ 2281 gtk_widget_set_sensitive(widget, sensitive); \ 2282 } 2283 2284 void toolbar_main_set_sensitive(gpointer data) 2285 { 2286 SensitiveCondMask state; 2287 gboolean sensitive; 2288 MainWindow *mainwin = (MainWindow*)data; 2289 Toolbar *toolbar = mainwin->toolbar; 2290 GSList *cur; 2291 GSList *entry_list = NULL; 2292 2293 typedef struct _Entry Entry; 2294 struct _Entry { 2295 GtkWidget *widget; 2296 SensitiveCondMask cond; 2297 gboolean empty; 2298 }; 2299 2300 #define SET_WIDGET_COND(w, ...) \ 2301 do { \ 2302 Entry *e = g_new0(Entry, 1); \ 2303 e->widget = w; \ 2304 e->cond = main_window_get_mask(__VA_ARGS__, -1); \ 2305 entry_list = g_slist_append(entry_list, e); \ 2306 } while (0) 2307 2308 /* match all bit flags */ 2309 2310 if (toolbar->get_btn) 2311 SET_WIDGET_COND(toolbar->get_btn, 2312 M_HAVE_ACCOUNT, M_UNLOCKED, M_HAVE_RETRIEVABLE_ACCOUNT); 2313 2314 if (toolbar->getall_btn) { 2315 SET_WIDGET_COND(toolbar->getall_btn, 2316 M_HAVE_ACCOUNT, M_UNLOCKED, M_HAVE_ANY_RETRIEVABLE_ACCOUNT); 2317 } 2318 if (toolbar->send_btn) { 2319 SET_WIDGET_COND(toolbar->send_btn, 2320 M_HAVE_QUEUED_MAILS); 2321 } 2322 if (toolbar->compose_mail_btn) { 2323 SET_WIDGET_COND(toolbar->compose_mail_btn, 2324 M_HAVE_ACCOUNT); 2325 } 2326 if (toolbar->close_window_btn) { 2327 SET_WIDGET_COND(toolbar->close_window_btn, 2328 M_UNLOCKED); 2329 } 2330 if (toolbar->open_mail_btn) { 2331 SET_WIDGET_COND(toolbar->open_mail_btn, 2332 M_TARGET_EXIST, M_SUMMARY_ISLIST); 2333 } 2334 if (toolbar->reply_btn) { 2335 SET_WIDGET_COND(toolbar->reply_btn, 2336 M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST); 2337 } 2338 if (toolbar->replyall_btn) { 2339 SET_WIDGET_COND(toolbar->replyall_btn, 2340 M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST); 2341 } 2342 if (toolbar->replylist_btn) { 2343 SET_WIDGET_COND(toolbar->replylist_btn, 2344 M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST); 2345 } 2346 if (toolbar->replysender_btn) { 2347 SET_WIDGET_COND(toolbar->replysender_btn, 2348 M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST); 2349 } 2350 if (toolbar->fwd_btn) { 2351 SET_WIDGET_COND(toolbar->fwd_btn, 2352 M_HAVE_ACCOUNT, M_TARGET_EXIST, M_SUMMARY_ISLIST); 2353 } 2354 2355 if (prefs_common.next_unread_msg_dialog == NEXTUNREADMSGDIALOG_ASSUME_NO) { 2356 SET_WIDGET_COND(toolbar->next_btn, M_MSG_EXIST, M_SUMMARY_ISLIST); 2357 } else { 2358 SET_WIDGET_COND(toolbar->next_btn, -1); 2359 } 2360 2361 if (toolbar->trash_btn) 2362 SET_WIDGET_COND(toolbar->trash_btn, 2363 M_TARGET_EXIST, M_ALLOW_DELETE, M_NOT_NEWS); 2364 2365 if (toolbar->delete_btn) 2366 SET_WIDGET_COND(toolbar->delete_btn, 2367 M_TARGET_EXIST, M_ALLOW_DELETE); 2368 2369 if (toolbar->delete_dup_btn) 2370 SET_WIDGET_COND(toolbar->delete_dup_btn, 2371 M_MSG_EXIST, M_ALLOW_DELETE, M_SUMMARY_ISLIST); 2372 2373 if (toolbar->exec_btn) 2374 SET_WIDGET_COND(toolbar->exec_btn, 2375 M_DELAY_EXEC); 2376 2377 if (toolbar->cancel_inc_btn) 2378 SET_WIDGET_COND(toolbar->cancel_inc_btn, 2379 M_INC_ACTIVE); 2380 2381 if (toolbar->cancel_send_btn) 2382 SET_WIDGET_COND(toolbar->cancel_send_btn, 2383 M_SEND_ACTIVE); 2384 2385 for (cur = toolbar->action_list; cur != NULL; cur = cur->next) { 2386 ToolbarClawsActions *act = (ToolbarClawsActions*)cur->data; 2387 2388 if (prefs_common.mainwin_toolbar_always_enable_actions) 2389 SET_WIDGET_COND(act->widget, M_UNLOCKED); 2390 else 2391 SET_WIDGET_COND(act->widget, M_TARGET_EXIST, M_UNLOCKED); 2392 } 2393 2394 state = main_window_get_current_state(mainwin); 2395 2396 for (cur = entry_list; cur != NULL; cur = cur->next) { 2397 Entry *e = (Entry*) cur->data; 2398 2399 if (e->widget != NULL) { 2400 sensitive = ((e->cond & state) == e->cond); 2401 GTK_BUTTON_SET_SENSITIVE(e->widget, sensitive); 2402 } 2403 } 2404 2405 while (entry_list != NULL) { 2406 Entry *e = (Entry*) entry_list->data; 2407 2408 entry_list = g_slist_remove(entry_list, e); 2409 g_free(e); 2410 } 2411 2412 /* match any bit flags */ 2413 2414 if (toolbar->cancel_all_btn) 2415 SET_WIDGET_COND(toolbar->cancel_all_btn, 2416 M_INC_ACTIVE, M_SEND_ACTIVE); 2417 2418 for (cur = entry_list; cur != NULL; cur = cur->next) { 2419 Entry *e = (Entry*) cur->data; 2420 2421 if (e->widget != NULL) { 2422 sensitive = ((e->cond & state) != 0); 2423 GTK_BUTTON_SET_SENSITIVE(e->widget, sensitive); 2424 } 2425 } 2426 2427 while (entry_list != NULL) { 2428 Entry *e = (Entry*) entry_list->data; 2429 2430 entry_list = g_slist_remove(entry_list, e); 2431 g_free(e); 2432 } 2433 2434 g_slist_free(entry_list); 2435 2436 activate_compose_button(toolbar, 2437 prefs_common.toolbar_style, 2438 toolbar->compose_btn_type); 2439 2440 #undef SET_WIDGET_COND 2441 } 2442 2443 void toolbar_comp_set_sensitive(gpointer data, gboolean sensitive) 2444 { 2445 Compose *compose = (Compose*)data; 2446 GSList *items = compose->toolbar->action_list; 2447 2448 if (compose->toolbar->send_btn) 2449 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->send_btn, sensitive); 2450 if (compose->toolbar->sendl_btn) 2451 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->sendl_btn, sensitive); 2452 if (compose->toolbar->draft_btn ) 2453 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->draft_btn , sensitive); 2454 if (compose->toolbar->insert_btn ) 2455 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->insert_btn , sensitive); 2456 if (compose->toolbar->attach_btn) 2457 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->attach_btn, sensitive); 2458 if (compose->toolbar->sig_btn) 2459 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->sig_btn, sensitive); 2460 if (compose->toolbar->repsig_btn) 2461 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->repsig_btn, sensitive); 2462 if (compose->toolbar->exteditor_btn) 2463 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->exteditor_btn, sensitive); 2464 if (compose->toolbar->linewrap_current_btn) 2465 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->linewrap_current_btn, sensitive); 2466 if (compose->toolbar->linewrap_all_btn) 2467 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->linewrap_all_btn, sensitive); 2468 if (compose->toolbar->addrbook_btn) 2469 GTK_BUTTON_SET_SENSITIVE(compose->toolbar->addrbook_btn, sensitive); 2470 for (; items != NULL; items = g_slist_next(items)) { 2471 ToolbarClawsActions *item = (ToolbarClawsActions *)items->data; 2472 GTK_BUTTON_SET_SENSITIVE(item->widget, sensitive); 2473 } 2474 } 2475 2476 /** 2477 * Initialize toolbar structure 2478 **/ 2479 static void toolbar_init(Toolbar * toolbar) 2480 { 2481 2482 toolbar->toolbar = NULL; 2483 toolbar->folders_btn = NULL; 2484 toolbar->get_btn = NULL; 2485 toolbar->getall_btn = NULL; 2486 toolbar->send_btn = NULL; 2487 toolbar->compose_mail_btn = NULL; 2488 toolbar->compose_mail_icon = NULL; 2489 toolbar->reply_btn = NULL; 2490 toolbar->replysender_btn = NULL; 2491 toolbar->replyall_btn = NULL; 2492 toolbar->replylist_btn = NULL; 2493 toolbar->fwd_btn = NULL; 2494 toolbar->trash_btn = NULL; 2495 toolbar->delete_btn = NULL; 2496 toolbar->delete_dup_btn = NULL; 2497 toolbar->prev_btn = NULL; 2498 toolbar->next_btn = NULL; 2499 toolbar->exec_btn = NULL; 2500 toolbar->separator = NULL; 2501 toolbar->cancel_inc_btn = NULL; 2502 toolbar->cancel_send_btn = NULL; 2503 toolbar->cancel_all_btn = NULL; 2504 2505 /* compose buttons */ 2506 toolbar->sendl_btn = NULL; 2507 toolbar->draft_btn = NULL; 2508 toolbar->insert_btn = NULL; 2509 toolbar->attach_btn = NULL; 2510 toolbar->sig_btn = NULL; 2511 toolbar->repsig_btn = NULL; 2512 toolbar->exteditor_btn = NULL; 2513 toolbar->linewrap_current_btn = NULL; 2514 toolbar->linewrap_all_btn = NULL; 2515 toolbar->addrbook_btn = NULL; 2516 2517 toolbar->open_mail_btn = NULL; 2518 toolbar->close_window_btn = NULL; 2519 toolbar->preferences_btn = NULL; 2520 toolbar->action_list = NULL; 2521 toolbar->item_list = NULL; 2522 2523 toolbar_destroy(toolbar); 2524 } 2525 2526 /* 2527 */ 2528 static void toolbar_reply(gpointer data, guint action) 2529 { 2530 ToolbarItem *toolbar_item = (ToolbarItem*)data; 2531 MainWindow *mainwin; 2532 MessageView *msgview; 2533 GSList *msginfo_list = NULL; 2534 gboolean msg_is_selected = FALSE; 2535 gboolean msg_is_opened = FALSE; 2536 2537 cm_return_if_fail(toolbar_item != NULL); 2538 2539 switch (toolbar_item->type) { 2540 case TOOLBAR_MAIN: 2541 mainwin = (MainWindow*)toolbar_item->parent; 2542 msginfo_list = summary_get_selection(mainwin->summaryview); 2543 msgview = (MessageView*)mainwin->messageview; 2544 msg_is_opened = summary_has_opened_message(mainwin->summaryview); 2545 msg_is_selected = summary_is_opened_message_selected(mainwin->summaryview); 2546 break; 2547 case TOOLBAR_MSGVIEW: 2548 msgview = (MessageView*)toolbar_item->parent; 2549 cm_return_if_fail(msgview != NULL); 2550 msginfo_list = g_slist_append(msginfo_list, msgview->msginfo); 2551 msg_is_opened = TRUE; 2552 msg_is_selected = TRUE; 2553 break; 2554 default: 2555 return; 2556 } 2557 2558 cm_return_if_fail(msgview != NULL); 2559 cm_return_if_fail(msginfo_list != NULL); 2560 if (!msg_is_opened) { 2561 compose_reply_from_messageview(NULL, msginfo_list, action); 2562 } else if (msg_is_selected) { 2563 compose_reply_from_messageview(msgview, msginfo_list, action); 2564 } else { 2565 compose_reply_from_messageview(msgview, NULL, action); 2566 } 2567 g_slist_free(msginfo_list); 2568 2569 /* TODO: update reply state ion summaryview */ 2570 } 2571 2572 2573 /* exported functions */ 2574 2575 void inc_mail_cb(gpointer data, guint action, GtkWidget *widget) 2576 { 2577 MainWindow *mainwin = (MainWindow*)data; 2578 2579 inc_mail(mainwin, prefs_common.newmail_notify_manu); 2580 } 2581 2582 void inc_all_account_mail_cb(gpointer data, guint action, GtkWidget *widget) 2583 { 2584 MainWindow *mainwin = (MainWindow*)data; 2585 inc_all_account_mail(mainwin, prefs_common.newmail_notify_manu); 2586 } 2587 2588 void send_queue_cb(gpointer data, guint action, GtkWidget *widget) 2589 { 2590 GList *list; 2591 gboolean found; 2592 gboolean got_error = FALSE; 2593 gchar *errstr = NULL; 2594 2595 if (prefs_common.work_offline) 2596 if (alertpanel(_("Offline warning"), 2597 _("You're working offline. Override?"), 2598 NULL, _("_No"), NULL, _("_Yes"), 2599 NULL, NULL, ALERTFOCUS_FIRST) != G_ALERTALTERNATE) 2600 return; 2601 2602 /* ask for confirmation before sending queued messages only 2603 in online mode and if there is at least one message queued 2604 in any of the folder queue 2605 */ 2606 if (prefs_common.confirm_send_queued_messages) { 2607 found = FALSE; 2608 /* check if there's a queued message */ 2609 for (list = folder_get_list(); !found && list != NULL; list = list->next) { 2610 Folder *folder = list->data; 2611 2612 found = !procmsg_queue_is_empty(folder->queue); 2613 } 2614 /* if necessary, ask for confirmation before sending */ 2615 if (found && !prefs_common.work_offline) { 2616 if (alertpanel(_("Send queued messages"), 2617 _("Send all queued messages?"), 2618 NULL, _("_Cancel"), NULL, _("_Send"), 2619 NULL, NULL, ALERTFOCUS_FIRST) != G_ALERTALTERNATE) 2620 return; 2621 } 2622 } 2623 2624 for (list = folder_get_list(); list != NULL; list = list->next) { 2625 Folder *folder = list->data; 2626 2627 if (folder->queue) { 2628 if (procmsg_send_queue(folder->queue, 2629 prefs_common.savemsg, 2630 &errstr) < 0) 2631 got_error = TRUE; 2632 } 2633 } 2634 if (got_error) { 2635 if (!errstr) 2636 alertpanel_error_log(_("Some errors occurred while " 2637 "sending queued messages.")); 2638 else { 2639 alertpanel_error_log(_("Some errors occurred " 2640 "while sending queued messages:\n%s"), errstr); 2641 g_free(errstr); 2642 } 2643 } 2644 } 2645 2646 void compose_mail_cb(gpointer data, guint action, GtkWidget *widget) 2647 { 2648 MainWindow *mainwin = (MainWindow*)data; 2649 PrefsAccount *ac = NULL; 2650 FolderItem *item = mainwin->summaryview->folder_item; 2651 GList * list; 2652 GList * cur; 2653 2654 if (item) { 2655 ac = account_find_from_item(item); 2656 if (ac && ac->protocol != A_IMAP4) { 2657 compose_new_with_folderitem(ac, item, NULL); /* CLAWS */ 2658 return; 2659 } 2660 } 2661 2662 if (cur_account) { 2663 compose_new_with_folderitem(cur_account, item, NULL); 2664 return; 2665 } 2666 2667 /* 2668 * CLAWS - just get the first one 2669 */ 2670 list = account_get_list(); 2671 for (cur = list ; cur != NULL ; cur = g_list_next(cur)) { 2672 ac = (PrefsAccount *) cur->data; 2673 compose_new_with_folderitem(ac, item, NULL); 2674 return; 2675 } 2676 }