prefs_folder_item.c (52305B)
1 /* 2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client 3 * Copyright (C) 1999-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 /* alfons - all folder item specific settings should migrate into 20 * folderlist.xml!!! the old folderitemrc file will only serve for a few 21 * versions (for compatibility) */ 22 23 #include "defs.h" 24 25 #include <glib.h> 26 #include <glib/gi18n.h> 27 #include "folder.h" 28 #include "alertpanel.h" 29 #include "prefs_folder_item.h" 30 #include "folderview.h" 31 #include "summaryview.h" 32 #include "menu.h" 33 #include "account.h" 34 #include "prefs_gtk.h" 35 #include "manage_window.h" 36 #include "utils.h" 37 #include "addr_compl.h" 38 #include "prefs_common.h" 39 #include "gtkutils.h" 40 #include "folder_item_prefs.h" 41 #include "string_match.h" 42 #include "combobox.h" 43 #include "stock_pixmap.h" 44 #include "file-utils.h" 45 46 #define ASSIGN_STRING(string, value) \ 47 { \ 48 g_free(string); \ 49 string = (value); \ 50 } 51 52 typedef struct _FolderItemGeneralPage FolderItemGeneralPage; 53 typedef struct _FolderItemComposePage FolderItemComposePage; 54 static gboolean can_save = TRUE; 55 56 struct _FolderItemGeneralPage 57 { 58 PrefsPage page; 59 60 FolderItem *item; 61 62 GtkWidget *table; 63 GtkWidget *no_save_warning; 64 GtkWidget *folder_type; 65 GtkWidget *checkbtn_simplify_subject; 66 GtkWidget *entry_simplify_subject; 67 GtkWidget *entry_regexp_test_string; 68 GtkWidget *entry_regexp_test_result; 69 GtkWidget *checkbtn_folder_chmod; 70 GtkWidget *entry_folder_chmod; 71 GtkWidget *checkbtn_enable_processing; 72 GtkWidget *checkbtn_enable_processing_when_opening; 73 GtkWidget *checkbtn_newmailcheck; 74 GtkWidget *checkbtn_skip_on_goto_unread_or_new; 75 GtkWidget *checkbtn_offlinesync; 76 GtkWidget *label_offlinesync; 77 GtkWidget *entry_offlinesync; 78 GtkWidget *label_end_offlinesync; 79 GtkWidget *checkbtn_remove_old_offlinesync; 80 GtkWidget *render_html; 81 82 /* apply to sub folders */ 83 GtkWidget *simplify_subject_rec_checkbtn; 84 GtkWidget *folder_chmod_rec_checkbtn; 85 GtkWidget *enable_processing_rec_checkbtn; 86 GtkWidget *enable_processing_when_opening_rec_checkbtn; 87 GtkWidget *newmailcheck_rec_checkbtn; 88 GtkWidget *skip_on_goto_unread_or_new_rec_checkbtn; 89 GtkWidget *offlinesync_rec_checkbtn; 90 GtkWidget *render_html_rec_checkbtn; 91 }; 92 93 struct _FolderItemComposePage 94 { 95 PrefsPage page; 96 97 FolderItem *item; 98 99 GtkWidget *window; 100 GtkWidget *table; 101 GtkWidget *no_save_warning; 102 GtkWidget *checkbtn_save_copy_to_folder; 103 GtkWidget *checkbtn_default_from; 104 GtkWidget *entry_default_from; 105 GtkWidget *checkbtn_default_to; 106 GtkWidget *entry_default_to; 107 GtkWidget *checkbtn_default_reply_to; 108 GtkWidget *entry_default_reply_to; 109 GtkWidget *checkbtn_default_cc; 110 GtkWidget *entry_default_cc; 111 GtkWidget *checkbtn_default_bcc; 112 GtkWidget *entry_default_bcc; 113 GtkWidget *checkbtn_default_replyto; 114 GtkWidget *entry_default_replyto; 115 GtkWidget *checkbtn_enable_default_account; 116 GtkWidget *optmenu_default_account; 117 118 /* apply to sub folders */ 119 GtkWidget *save_copy_to_folder_rec_checkbtn; 120 GtkWidget *default_from_rec_checkbtn; 121 GtkWidget *default_to_rec_checkbtn; 122 GtkWidget *default_reply_to_rec_checkbtn; 123 GtkWidget *default_cc_rec_checkbtn; 124 GtkWidget *default_bcc_rec_checkbtn; 125 GtkWidget *default_replyto_rec_checkbtn; 126 GtkWidget *default_account_rec_checkbtn; 127 }; 128 129 static void general_save_folder_prefs(FolderItem *folder, FolderItemGeneralPage *page); 130 static void compose_save_folder_prefs(FolderItem *folder, FolderItemComposePage *page); 131 132 static gboolean general_save_recurse_func(GNode *node, gpointer data); 133 static gboolean compose_save_recurse_func(GNode *node, gpointer data); 134 135 static void clean_cache_cb(GtkWidget *widget, gpointer data); 136 static void folder_regexp_test_cb(GtkWidget *widget, gpointer data); 137 static void folder_regexp_set_subject_example_cb(GtkWidget *widget, gpointer data); 138 139 #define SAFE_STRING(str) \ 140 (str) ? (str) : "" 141 142 static GtkWidget *prefs_folder_no_save_warning_create_widget() { 143 GtkWidget *hbox; 144 GtkWidget *icon; 145 GtkWidget *label; 146 147 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); 148 149 icon = stock_pixmap_widget(STOCK_PIXMAP_NOTICE_WARN); 150 gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 8); 151 152 label = gtk_label_new(g_strconcat("<i>", 153 _("These preferences will not be saved as this folder " 154 "is a top-level folder.\nHowever, you can set them for the " 155 "whole mailbox tree by using \"Apply to subfolders\"."), 156 "</i>", NULL)); 157 gtk_label_set_use_markup(GTK_LABEL(label), TRUE); 158 gtk_label_set_xalign(GTK_LABEL(label), 0.0); 159 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); 160 161 return hbox; 162 } 163 164 static void prefs_folder_item_general_create_widget_func(PrefsPage * page_, 165 GtkWindow * window, 166 gpointer data) 167 { 168 FolderItemGeneralPage *page = (FolderItemGeneralPage *) page_; 169 FolderItem *item = (FolderItem *) data; 170 guint rowcount; 171 172 GtkWidget *table; 173 GtkWidget *hbox, *hbox2, *hbox_spc; 174 GtkWidget *box1, *box2; 175 GtkWidget *label; 176 177 GtkListStore *folder_type_menu; 178 GtkWidget *folder_type; 179 GtkTreeIter iter; 180 GtkWidget *dummy_checkbtn, *clean_cache_btn; 181 SpecialFolderItemType type; 182 GtkWidget *no_save_warning = NULL; 183 184 GtkWidget *checkbtn_simplify_subject; 185 GtkWidget *entry_simplify_subject; 186 GtkWidget *label_regexp_test; 187 GtkWidget *entry_regexp_test_string; 188 GtkWidget *label_regexp_result; 189 GtkWidget *entry_regexp_test_result; 190 191 GtkWidget *checkbtn_folder_chmod; 192 GtkWidget *entry_folder_chmod; 193 GtkWidget *checkbtn_enable_processing; 194 GtkWidget *checkbtn_enable_processing_when_opening; 195 GtkWidget *checkbtn_newmailcheck; 196 GtkWidget *checkbtn_skip_on_goto_unread_or_new; 197 GtkWidget *checkbtn_offlinesync; 198 GtkWidget *label_offlinesync; 199 GtkWidget *entry_offlinesync; 200 GtkWidget *label_end_offlinesync; 201 GtkWidget *checkbtn_remove_old_offlinesync; 202 GtkWidget *render_html; 203 GtkListStore *render_html_menu; 204 205 GtkWidget *simplify_subject_rec_checkbtn; 206 207 GtkWidget *folder_chmod_rec_checkbtn; 208 GtkWidget *enable_processing_rec_checkbtn; 209 GtkWidget *enable_processing_when_opening_rec_checkbtn; 210 GtkWidget *newmailcheck_rec_checkbtn; 211 GtkWidget *skip_on_goto_unread_or_new_rec_checkbtn; 212 GtkWidget *offlinesync_rec_checkbtn; 213 GtkWidget *render_html_rec_checkbtn; 214 215 gint wreq1, wreq2; 216 217 page->item = item; 218 219 /* Table */ 220 table = gtk_grid_new(); 221 gtk_container_set_border_width (GTK_CONTAINER (table), VBOX_BORDER); 222 gtk_grid_set_row_spacing(GTK_GRID(table), 4); 223 gtk_grid_set_column_spacing(GTK_GRID(table), 4); 224 225 rowcount = 0; 226 227 if (!can_save) { 228 no_save_warning = prefs_folder_no_save_warning_create_widget(); 229 gtk_grid_attach(GTK_GRID(table), no_save_warning, 0, rowcount, 1, 1); 230 rowcount++; 231 } 232 233 /* Apply to subfolders */ 234 label = gtk_label_new(_("Apply to\nsubfolders")); 235 gtk_grid_attach(GTK_GRID(table), label, 2, rowcount, 1, 1); 236 rowcount++; 237 238 /* folder_type */ 239 folder_type = gtkut_sc_combobox_create(NULL, FALSE); 240 gtk_widget_show (folder_type); 241 242 type = F_NORMAL; 243 if (item->stype == F_INBOX) 244 type = F_INBOX; 245 else if (folder_has_parent_of_type(item, F_OUTBOX)) 246 type = F_OUTBOX; 247 else if (folder_has_parent_of_type(item, F_DRAFT)) 248 type = F_DRAFT; 249 else if (folder_has_parent_of_type(item, F_QUEUE)) 250 type = F_QUEUE; 251 else if (folder_has_parent_of_type(item, F_TRASH)) 252 type = F_TRASH; 253 254 folder_type_menu = GTK_LIST_STORE(gtk_combo_box_get_model( 255 GTK_COMBO_BOX(folder_type))); 256 257 COMBOBOX_ADD (folder_type_menu, _("Normal"), F_NORMAL); 258 COMBOBOX_ADD (folder_type_menu, _("Inbox"), F_INBOX); 259 COMBOBOX_ADD (folder_type_menu, _("Sent"), F_OUTBOX); 260 COMBOBOX_ADD (folder_type_menu, _("Drafts"), F_DRAFT); 261 COMBOBOX_ADD (folder_type_menu, _("Queue"), F_QUEUE); 262 COMBOBOX_ADD (folder_type_menu, _("Trash"), F_TRASH); 263 264 combobox_select_by_data(GTK_COMBO_BOX(folder_type), type); 265 266 box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING); 267 box2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); 268 gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0); 269 270 label = gtk_label_new(_("Folder type")); 271 gtk_label_set_xalign(GTK_LABEL(label), 0.0); 272 gtk_box_pack_start(GTK_BOX(box2), label, FALSE, FALSE, 0); 273 gtk_box_pack_start(GTK_BOX(box2), folder_type, FALSE, FALSE, 0); 274 gtk_grid_attach(GTK_GRID(table), box1, 0, rowcount, 1, 1); 275 276 dummy_checkbtn = gtk_check_button_new(); 277 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dummy_checkbtn), type != F_INBOX); 278 gtk_widget_set_sensitive(dummy_checkbtn, FALSE); 279 280 if (type == item->stype && type == F_NORMAL) 281 gtk_widget_set_sensitive(folder_type, TRUE); 282 else 283 gtk_widget_set_sensitive(folder_type, FALSE); 284 285 gtk_grid_attach(GTK_GRID(table), dummy_checkbtn, 2, rowcount, 1, 1); 286 287 rowcount++; 288 289 /* Simplify Subject */ 290 box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING); 291 box2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); 292 gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0); 293 294 checkbtn_simplify_subject = gtk_check_button_new_with_label(_("Simplify Subject RegExp")); 295 gtk_box_pack_start(GTK_BOX(box2), checkbtn_simplify_subject, FALSE, FALSE, 0); 296 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_simplify_subject), 297 item->prefs->enable_simplify_subject); 298 g_signal_connect(G_OBJECT(checkbtn_simplify_subject), "toggled", 299 G_CALLBACK(folder_regexp_set_subject_example_cb), page); 300 301 entry_simplify_subject = gtk_entry_new(); 302 gtk_box_pack_start(GTK_BOX(box2), entry_simplify_subject, TRUE, TRUE, 0); 303 SET_TOGGLE_SENSITIVITY(checkbtn_simplify_subject, entry_simplify_subject); 304 gtk_entry_set_text(GTK_ENTRY(entry_simplify_subject), 305 SAFE_STRING(item->prefs->simplify_subject_regexp)); 306 307 g_signal_connect(G_OBJECT(entry_simplify_subject), "changed", 308 G_CALLBACK(folder_regexp_test_cb), page); 309 310 simplify_subject_rec_checkbtn = gtk_check_button_new(); 311 gtk_grid_attach(GTK_GRID(table), simplify_subject_rec_checkbtn, 2, rowcount, 1, 1); 312 gtk_grid_attach(GTK_GRID(table), box1, 0, rowcount, 1, 1); 313 314 rowcount++; 315 316 /* Test string */ 317 box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING); 318 box2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); 319 gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0); 320 321 label_regexp_test = gtk_label_new(_("Test string")); 322 gtk_box_pack_start(GTK_BOX(box2), label_regexp_test, FALSE, FALSE, 0); 323 gtk_label_set_xalign(GTK_LABEL(label_regexp_test), 1); 324 SET_TOGGLE_SENSITIVITY(checkbtn_simplify_subject, label_regexp_test); 325 326 entry_regexp_test_string = gtk_entry_new(); 327 gtk_box_pack_start(GTK_BOX(box2), entry_regexp_test_string, TRUE, TRUE, 0); 328 gtk_grid_attach(GTK_GRID(table), box1, 0, rowcount, 1, 1); 329 330 SET_TOGGLE_SENSITIVITY(checkbtn_simplify_subject, entry_regexp_test_string); 331 332 g_signal_connect(G_OBJECT(entry_regexp_test_string), "changed", 333 G_CALLBACK(folder_regexp_test_cb), page); 334 335 rowcount++; 336 337 /* Test result */ 338 box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING); 339 box2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); 340 gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0); 341 342 label_regexp_result = gtk_label_new(_("Result")); 343 gtk_box_pack_start(GTK_BOX(box2), label_regexp_result, FALSE, FALSE, 0); 344 gtk_label_set_xalign(GTK_LABEL(label_regexp_result), 1); 345 SET_TOGGLE_SENSITIVITY(checkbtn_simplify_subject, label_regexp_result); 346 347 entry_regexp_test_result = gtk_entry_new(); 348 gtk_box_pack_start(GTK_BOX(box2), entry_regexp_test_result, TRUE, TRUE, 0); 349 SET_TOGGLE_SENSITIVITY(checkbtn_simplify_subject, entry_regexp_test_result); 350 gtk_editable_set_editable(GTK_EDITABLE(entry_regexp_test_result), FALSE); 351 gtk_grid_attach(GTK_GRID(table), box1, 0, rowcount, 1, 1); 352 353 rowcount++; 354 355 /* Folder chmod */ 356 box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING); 357 box2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); 358 gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0); 359 360 checkbtn_folder_chmod = gtk_check_button_new_with_label(_("Folder chmod")); 361 gtk_box_pack_start(GTK_BOX(box2), checkbtn_folder_chmod, FALSE, FALSE, 0); 362 363 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_folder_chmod), 364 item->prefs->enable_folder_chmod); 365 366 entry_folder_chmod = gtk_entry_new(); 367 gtk_box_pack_start(GTK_BOX(box2), entry_folder_chmod, FALSE, FALSE, 0); 368 SET_TOGGLE_SENSITIVITY(checkbtn_folder_chmod, entry_folder_chmod); 369 if (item->prefs->folder_chmod) { 370 gchar *buf; 371 372 buf = g_strdup_printf("%o", item->prefs->folder_chmod); 373 gtk_entry_set_text(GTK_ENTRY(entry_folder_chmod), buf); 374 g_free(buf); 375 } 376 377 gtk_grid_attach(GTK_GRID(table), box1, 0, rowcount, 1, 1); 378 folder_chmod_rec_checkbtn = gtk_check_button_new(); 379 gtk_grid_attach(GTK_GRID(table), folder_chmod_rec_checkbtn, 2, rowcount, 1, 1); 380 rowcount++; 381 382 /* Enable processing at startup */ 383 checkbtn_enable_processing = 384 gtk_check_button_new_with_label(_("Run Processing rules at start-up")); 385 gtk_grid_attach(GTK_GRID(table), checkbtn_enable_processing, 0, rowcount, 1, 1); 386 387 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_enable_processing), 388 item->prefs->enable_processing); 389 390 enable_processing_rec_checkbtn = gtk_check_button_new(); 391 gtk_grid_attach(GTK_GRID(table), enable_processing_rec_checkbtn, 2, rowcount, 1, 1); 392 393 rowcount++; 394 395 /* Enable processing rules when opening folder */ 396 checkbtn_enable_processing_when_opening = 397 gtk_check_button_new_with_label(_("Run Processing rules when opening")); 398 gtk_grid_attach(GTK_GRID(table), checkbtn_enable_processing_when_opening, 0, rowcount, 1, 1); 399 400 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_enable_processing_when_opening), 401 item->prefs->enable_processing_when_opening); 402 403 enable_processing_when_opening_rec_checkbtn = gtk_check_button_new(); 404 gtk_grid_attach(GTK_GRID(table), enable_processing_when_opening_rec_checkbtn, 2, rowcount, 1, 1); 405 406 rowcount++; 407 408 /* Check folder for new mail */ 409 checkbtn_newmailcheck = gtk_check_button_new_with_label(_("Scan for new mail")); 410 CLAWS_SET_TIP(checkbtn_newmailcheck, 411 _("Turn this option on if mail is delivered directly " 412 "to this folder by server side filtering on IMAP or " 413 "by an external application")); 414 gtk_grid_attach(GTK_GRID(table), checkbtn_newmailcheck, 0, rowcount, 1, 1); 415 416 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_newmailcheck), 417 item->prefs->newmailcheck); 418 newmailcheck_rec_checkbtn = gtk_check_button_new(); 419 gtk_grid_attach(GTK_GRID(table), newmailcheck_rec_checkbtn, 2, rowcount, 1, 1); 420 421 rowcount++; 422 423 /* Render HTML messages as text? */ 424 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, VSPACING_NARROW_2); 425 gtk_box_set_spacing(GTK_BOX(hbox), 8); 426 gtk_grid_attach(GTK_GRID(table), hbox, 0, rowcount, 1, 1); 427 428 label = gtk_label_new(_("Render HTML messages as text")); 429 gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0); 430 431 render_html = gtkut_sc_combobox_create (NULL, FALSE); 432 gtk_box_pack_start (GTK_BOX(hbox), render_html, FALSE, FALSE, 0); 433 434 render_html_menu = GTK_LIST_STORE(gtk_combo_box_get_model( 435 GTK_COMBO_BOX(render_html))); 436 COMBOBOX_ADD (render_html_menu, _("Default"), HTML_RENDER_DEFAULT); 437 COMBOBOX_ADD (render_html_menu, _("No"), HTML_RENDER_NEVER); 438 COMBOBOX_ADD (render_html_menu, _("Yes"), HTML_RENDER_ALWAYS); 439 440 combobox_select_by_data(GTK_COMBO_BOX(render_html), 441 item->prefs->render_html); 442 443 CLAWS_SET_TIP(hbox, 444 _("\"Default\" will follow global preference (found in '/Configuration/Preferences/Message View/Text Options')")); 445 446 render_html_rec_checkbtn = gtk_check_button_new(); 447 gtk_grid_attach(GTK_GRID(table), render_html_rec_checkbtn, 2, rowcount, 1, 1); 448 449 rowcount++; 450 451 /* Skip folder on 'goto unread (or new) message' */ 452 checkbtn_skip_on_goto_unread_or_new = gtk_check_button_new_with_label( 453 _("Skip folder when searching for unread or new messages")); 454 CLAWS_SET_TIP(checkbtn_skip_on_goto_unread_or_new, 455 _("Turn this option on if you want this folder to be ignored " 456 "when searching for unread or new messages")); 457 gtk_grid_attach(GTK_GRID(table), checkbtn_skip_on_goto_unread_or_new, 0, rowcount, 1, 1); 458 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_skip_on_goto_unread_or_new), 459 item->prefs->skip_on_goto_unread_or_new); 460 461 skip_on_goto_unread_or_new_rec_checkbtn = gtk_check_button_new(); 462 gtk_grid_attach(GTK_GRID(table), skip_on_goto_unread_or_new_rec_checkbtn, 2, rowcount, 1, 1); 463 464 rowcount++; 465 466 /* Synchronise folder for offline use */ 467 checkbtn_offlinesync = gtk_check_button_new_with_label(_("Synchronise for offline use")); 468 gtk_grid_attach(GTK_GRID(table), checkbtn_offlinesync, 0, rowcount, 1, 1); 469 470 offlinesync_rec_checkbtn = gtk_check_button_new(); 471 gtk_grid_attach(GTK_GRID(table), offlinesync_rec_checkbtn, 2, rowcount, 1, 1); 472 473 rowcount++; 474 475 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); 476 gtk_grid_attach(GTK_GRID(table), hbox, 0, rowcount, 1, 1); 477 gtk_widget_set_hexpand(hbox, TRUE); 478 gtk_widget_set_halign(hbox, GTK_ALIGN_FILL); 479 480 rowcount++; 481 482 hbox_spc = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); 483 gtk_box_pack_start (GTK_BOX (hbox), hbox_spc, FALSE, FALSE, 0); 484 gtk_widget_set_size_request (hbox_spc, 12, -1); 485 486 label_offlinesync = gtk_label_new(_("Fetch message bodies from the last")); 487 gtk_box_pack_start (GTK_BOX (hbox), label_offlinesync, FALSE, FALSE, 0); 488 489 entry_offlinesync = gtk_entry_new(); 490 gtk_widget_set_size_request (entry_offlinesync, 64, -1); 491 CLAWS_SET_TIP(entry_offlinesync, _("0: all bodies")); 492 gtk_box_pack_start (GTK_BOX (hbox), entry_offlinesync, FALSE, FALSE, 0); 493 494 label_end_offlinesync = gtk_label_new(_("days")); 495 gtk_box_pack_start (GTK_BOX (hbox), label_end_offlinesync, FALSE, FALSE, 0); 496 497 checkbtn_remove_old_offlinesync = gtk_check_button_new_with_label( 498 _("Remove older messages bodies")); 499 500 hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); 501 gtk_grid_attach(GTK_GRID(table), hbox2, 0, rowcount, 1, 1); 502 gtk_widget_set_hexpand(hbox2, TRUE); 503 gtk_widget_set_halign(hbox2, GTK_ALIGN_FILL); 504 505 rowcount++; 506 507 hbox_spc = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); 508 gtk_box_pack_start (GTK_BOX (hbox2), hbox_spc, FALSE, FALSE, 0); 509 gtk_widget_set_size_request (hbox_spc, 12, -1); 510 gtk_box_pack_start (GTK_BOX (hbox2), checkbtn_remove_old_offlinesync, FALSE, FALSE, 0); 511 512 SET_TOGGLE_SENSITIVITY (checkbtn_offlinesync, hbox); 513 SET_TOGGLE_SENSITIVITY (checkbtn_offlinesync, hbox2); 514 515 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); 516 clean_cache_btn = gtk_button_new_with_label(_("Discard folder cache")); 517 gtk_box_pack_start (GTK_BOX (hbox), clean_cache_btn, FALSE, FALSE, 0); 518 gtk_widget_set_hexpand(hbox, FALSE); 519 gtk_widget_set_halign(hbox, GTK_ALIGN_FILL); 520 gtk_grid_attach(GTK_GRID(table), hbox, 0, rowcount, 1, 1); 521 g_signal_connect(G_OBJECT(clean_cache_btn), "clicked", 522 G_CALLBACK(clean_cache_cb), 523 page); 524 525 gtk_widget_show_all(table); 526 527 /* line few widgets up now that we know their display size */ 528 gtk_widget_get_preferred_width(label_regexp_test, &wreq1, NULL); 529 gtk_widget_get_preferred_width(label_regexp_result, &wreq2, NULL); 530 gtk_widget_set_size_request(label_regexp_test, MAX(100, MAX(wreq1, wreq2)), -1); 531 gtk_widget_set_size_request(label_regexp_result, MAX(100, MAX(wreq1, wreq2)), -1); 532 533 if (item->folder && (item->folder->klass->type != F_IMAP && 534 item->folder->klass->type != F_NEWS)) { 535 item->prefs->offlinesync = TRUE; 536 item->prefs->offlinesync_days = 0; 537 item->prefs->remove_old_bodies = FALSE; 538 539 gtk_widget_set_sensitive(GTK_WIDGET(checkbtn_offlinesync), 540 FALSE); 541 gtk_widget_set_sensitive(GTK_WIDGET(offlinesync_rec_checkbtn), 542 FALSE); 543 gtk_widget_hide(GTK_WIDGET(checkbtn_offlinesync)); 544 gtk_widget_hide(GTK_WIDGET(hbox)); 545 gtk_widget_hide(GTK_WIDGET(hbox2)); 546 gtk_widget_hide(GTK_WIDGET(offlinesync_rec_checkbtn)); 547 gtk_widget_hide(GTK_WIDGET(label_offlinesync)); 548 gtk_widget_hide(GTK_WIDGET(entry_offlinesync)); 549 gtk_widget_hide(GTK_WIDGET(label_end_offlinesync)); 550 gtk_widget_hide(GTK_WIDGET(checkbtn_remove_old_offlinesync)); 551 gtk_widget_hide(GTK_WIDGET(clean_cache_btn)); 552 553 } 554 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_offlinesync), 555 item->prefs->offlinesync); 556 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_remove_old_offlinesync), 557 item->prefs->remove_old_bodies); 558 gtk_entry_set_text(GTK_ENTRY(entry_offlinesync), itos(item->prefs->offlinesync_days)); 559 560 page->table = table; 561 page->folder_type = folder_type; 562 page->no_save_warning = no_save_warning; 563 564 page->checkbtn_simplify_subject = checkbtn_simplify_subject; 565 page->entry_simplify_subject = entry_simplify_subject; 566 page->entry_regexp_test_string = entry_regexp_test_string; 567 page->entry_regexp_test_result = entry_regexp_test_result; 568 569 page->checkbtn_folder_chmod = checkbtn_folder_chmod; 570 page->entry_folder_chmod = entry_folder_chmod; 571 page->checkbtn_enable_processing = checkbtn_enable_processing; 572 page->checkbtn_enable_processing_when_opening = checkbtn_enable_processing_when_opening; 573 page->checkbtn_newmailcheck = checkbtn_newmailcheck; 574 page->checkbtn_skip_on_goto_unread_or_new = checkbtn_skip_on_goto_unread_or_new; 575 page->checkbtn_offlinesync = checkbtn_offlinesync; 576 page->label_offlinesync = label_offlinesync; 577 page->entry_offlinesync = entry_offlinesync; 578 page->label_end_offlinesync = label_end_offlinesync; 579 page->checkbtn_remove_old_offlinesync = checkbtn_remove_old_offlinesync; 580 page->render_html = render_html; 581 582 page->simplify_subject_rec_checkbtn = simplify_subject_rec_checkbtn; 583 584 page->folder_chmod_rec_checkbtn = folder_chmod_rec_checkbtn; 585 page->enable_processing_rec_checkbtn = enable_processing_rec_checkbtn; 586 page->enable_processing_when_opening_rec_checkbtn = enable_processing_when_opening_rec_checkbtn; 587 page->newmailcheck_rec_checkbtn = newmailcheck_rec_checkbtn; 588 page->skip_on_goto_unread_or_new_rec_checkbtn = skip_on_goto_unread_or_new_rec_checkbtn; 589 page->offlinesync_rec_checkbtn = offlinesync_rec_checkbtn; 590 page->render_html_rec_checkbtn = render_html_rec_checkbtn; 591 592 page->page.widget = table; 593 594 folder_regexp_set_subject_example_cb(NULL, page); 595 } 596 597 static void prefs_folder_item_general_destroy_widget_func(PrefsPage *page_) 598 { 599 /* FolderItemGeneralPage *page = (FolderItemGeneralPage *) page_; */ 600 } 601 602 /** \brief Save the prefs in page to folder. 603 * 604 * If the folder is not the one specified in page->item, then only those properties 605 * that have the relevant 'apply to sub folders' button checked are saved 606 */ 607 static void general_save_folder_prefs(FolderItem *folder, FolderItemGeneralPage *page) 608 { 609 FolderItemPrefs *prefs = folder->prefs; 610 gchar *buf; 611 gboolean all = FALSE, summary_update_needed = FALSE; 612 SpecialFolderItemType type = F_NORMAL; 613 FolderView *folderview = mainwindow_get_mainwindow()->folderview; 614 HTMLRenderType render_html = HTML_RENDER_DEFAULT; 615 616 if (folder->path == NULL) 617 return; 618 619 cm_return_if_fail(prefs != NULL); 620 621 if (page->item == folder) 622 all = TRUE; 623 624 type = combobox_get_active_data(GTK_COMBO_BOX(page->folder_type)); 625 if (all && folder->stype != type && page->item->parent_stype == F_NORMAL) { 626 folder_item_change_type(folder, type); 627 summary_update_needed = TRUE; 628 } 629 630 render_html = 631 combobox_get_active_data(GTK_COMBO_BOX(page->render_html)); 632 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->render_html_rec_checkbtn))) 633 prefs->render_html = render_html; 634 635 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->simplify_subject_rec_checkbtn))) { 636 gboolean old_simplify_subject = prefs->enable_simplify_subject; 637 int regexp_diffs = g_strcmp0(prefs->simplify_subject_regexp, gtk_editable_get_chars( 638 GTK_EDITABLE(page->entry_simplify_subject), 0, -1)); 639 prefs->enable_simplify_subject = 640 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_simplify_subject)); 641 ASSIGN_STRING(prefs->simplify_subject_regexp, 642 gtk_editable_get_chars(GTK_EDITABLE(page->entry_simplify_subject), 0, -1)); 643 if (old_simplify_subject != prefs->enable_simplify_subject || regexp_diffs != 0) 644 summary_update_needed = TRUE; 645 } 646 647 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->folder_chmod_rec_checkbtn))) { 648 prefs->enable_folder_chmod = 649 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_folder_chmod)); 650 buf = gtk_editable_get_chars(GTK_EDITABLE(page->entry_folder_chmod), 0, -1); 651 prefs->folder_chmod = prefs_chmod_mode(buf); 652 g_free(buf); 653 } 654 655 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->enable_processing_rec_checkbtn))) { 656 prefs->enable_processing = 657 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_enable_processing)); 658 } 659 660 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->enable_processing_when_opening_rec_checkbtn))) { 661 prefs->enable_processing_when_opening = 662 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_enable_processing_when_opening)); 663 } 664 665 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->newmailcheck_rec_checkbtn))) { 666 prefs->newmailcheck = 667 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_newmailcheck)); 668 } 669 670 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->skip_on_goto_unread_or_new_rec_checkbtn))) { 671 prefs->skip_on_goto_unread_or_new = 672 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_skip_on_goto_unread_or_new)); 673 } 674 675 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->offlinesync_rec_checkbtn))) { 676 prefs->offlinesync = 677 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_offlinesync)); 678 prefs->offlinesync_days = 679 atoi(gtk_entry_get_text(GTK_ENTRY(page->entry_offlinesync))); 680 prefs->remove_old_bodies = 681 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_remove_old_offlinesync)); 682 } 683 684 folder_item_prefs_save_config(folder); 685 686 if (folder->opened && summary_update_needed) { 687 summary_set_prefs_from_folderitem(folderview->summaryview, folder); 688 summary_show(folderview->summaryview, folder, FALSE); 689 } 690 } 691 692 static gboolean general_save_recurse_func(GNode *node, gpointer data) 693 { 694 FolderItem *item = (FolderItem *) node->data; 695 FolderItemGeneralPage *page = (FolderItemGeneralPage *) data; 696 697 cm_return_val_if_fail(item != NULL, TRUE); 698 cm_return_val_if_fail(page != NULL, TRUE); 699 700 general_save_folder_prefs(item, page); 701 702 /* optimise by not continuing if none of the 'apply to sub folders' 703 check boxes are selected - and optimise the checking by only doing 704 it once */ 705 if ((node == page->item->node) && 706 !( 707 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->simplify_subject_rec_checkbtn)) || 708 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->folder_chmod_rec_checkbtn)) || 709 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->enable_processing_rec_checkbtn)) || 710 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->enable_processing_when_opening_rec_checkbtn)) || 711 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->newmailcheck_rec_checkbtn)) || 712 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->offlinesync_rec_checkbtn)) || 713 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->skip_on_goto_unread_or_new_rec_checkbtn)) || 714 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->render_html_rec_checkbtn)) 715 )) 716 return TRUE; 717 else 718 return FALSE; 719 } 720 721 static void prefs_folder_item_general_save_func(PrefsPage *page_) 722 { 723 FolderItemGeneralPage *page = (FolderItemGeneralPage *) page_; 724 725 g_node_traverse(page->item->node, G_PRE_ORDER, G_TRAVERSE_ALL, 726 -1, general_save_recurse_func, page); 727 728 main_window_set_menu_sensitive(mainwindow_get_mainwindow()); 729 730 } 731 732 static RecvProtocol item_protocol(FolderItem *item) 733 { 734 if (!item) 735 return A_NONE; 736 if (!item->folder) 737 return A_NONE; 738 if (!item->folder->account) 739 return A_NONE; 740 return item->folder->account->protocol; 741 } 742 743 static void prefs_folder_item_compose_create_widget_func(PrefsPage * page_, 744 GtkWindow * window, 745 gpointer data) 746 { 747 FolderItemComposePage *page = (FolderItemComposePage *) page_; 748 FolderItem *item = (FolderItem *) data; 749 guint rowcount; 750 gchar *text = NULL; 751 gchar *tr = NULL; 752 753 GtkWidget *table; 754 GtkWidget *hbox; 755 GtkWidget *label; 756 757 GtkWidget *no_save_warning = NULL; 758 GtkWidget *checkbtn_save_copy_to_folder = NULL; 759 GtkWidget *checkbtn_default_from = NULL; 760 GtkWidget *entry_default_from = NULL; 761 GtkWidget *checkbtn_default_to = NULL; 762 GtkWidget *entry_default_to = NULL; 763 GtkWidget *checkbtn_default_reply_to = NULL; 764 GtkWidget *entry_default_reply_to = NULL; 765 GtkWidget *checkbtn_default_cc = NULL; 766 GtkWidget *entry_default_cc = NULL; 767 GtkWidget *checkbtn_default_bcc = NULL; 768 GtkWidget *entry_default_bcc = NULL; 769 GtkWidget *checkbtn_default_replyto = NULL; 770 GtkWidget *entry_default_replyto = NULL; 771 GtkWidget *checkbtn_enable_default_account = NULL; 772 GtkWidget *optmenu_default_account = NULL; 773 GtkListStore *optmenu_default_account_menu = NULL; 774 GtkTreeIter iter; 775 GtkWidget *save_copy_to_folder_rec_checkbtn = NULL; 776 GtkWidget *default_from_rec_checkbtn = NULL; 777 GtkWidget *default_to_rec_checkbtn = NULL; 778 GtkWidget *default_reply_to_rec_checkbtn = NULL; 779 GtkWidget *default_cc_rec_checkbtn = NULL; 780 GtkWidget *default_bcc_rec_checkbtn = NULL; 781 GtkWidget *default_replyto_rec_checkbtn = NULL; 782 GtkWidget *default_account_rec_checkbtn = NULL; 783 784 GList *cur_ac; 785 GList *account_list; 786 PrefsAccount *ac_prefs; 787 gboolean default_account_set = FALSE; 788 789 page->item = item; 790 791 /* Table */ 792 #define TABLEHEIGHT 6 793 table = gtk_grid_new(); 794 gtk_container_set_border_width (GTK_CONTAINER (table), VBOX_BORDER); 795 gtk_grid_set_row_spacing(GTK_GRID(table), 4); 796 gtk_grid_set_column_spacing(GTK_GRID(table), 4); 797 rowcount = 0; 798 799 if (!can_save) { 800 no_save_warning = prefs_folder_no_save_warning_create_widget(); 801 gtk_grid_attach(GTK_GRID(table), no_save_warning, 0, rowcount, 1, 1); 802 rowcount++; 803 } 804 805 /* Apply to subfolders */ 806 label = gtk_label_new(_("Apply to\nsubfolders")); 807 gtk_grid_attach(GTK_GRID(table), label, 2, rowcount, 1, 1); 808 rowcount++; 809 810 if (item_protocol(item)) { 811 /* Save Copy to Folder */ 812 checkbtn_save_copy_to_folder = gtk_check_button_new_with_label 813 (_("Save copy of outgoing messages to this folder instead of Sent")); 814 gtk_grid_attach(GTK_GRID(table), checkbtn_save_copy_to_folder, 0, rowcount, 2, 1); 815 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_save_copy_to_folder), 816 item->prefs->save_copy_to_folder ? TRUE : FALSE); 817 818 save_copy_to_folder_rec_checkbtn = gtk_check_button_new(); 819 gtk_grid_attach(GTK_GRID(table), save_copy_to_folder_rec_checkbtn, 2, rowcount, 1, 1); 820 rowcount++; 821 822 /* Default From */ 823 tr = g_strdup(C_("folder properties: %s stands for a header name", 824 "Default %s")); 825 text = g_strdup_printf(tr, "From:"); 826 checkbtn_default_from = gtk_check_button_new_with_label(text); 827 gtk_grid_attach(GTK_GRID(table), checkbtn_default_from, 0, rowcount, 1, 1); 828 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_default_from), 829 item->prefs->enable_default_from); 830 g_free(text); 831 g_free(tr); 832 833 entry_default_from = gtk_entry_new(); 834 gtk_grid_attach(GTK_GRID(table), entry_default_from, 1, rowcount, 1, 1); 835 gtk_widget_set_hexpand(entry_default_from, TRUE); 836 gtk_widget_set_halign(entry_default_from, GTK_ALIGN_FILL); 837 SET_TOGGLE_SENSITIVITY(checkbtn_default_from, entry_default_from); 838 gtk_entry_set_text(GTK_ENTRY(entry_default_from), SAFE_STRING(item->prefs->default_from)); 839 address_completion_register_entry(GTK_ENTRY(entry_default_from), 840 TRUE); 841 842 default_from_rec_checkbtn = gtk_check_button_new(); 843 gtk_grid_attach(GTK_GRID(table), default_from_rec_checkbtn, 2, rowcount, 1, 1); 844 845 rowcount++; 846 847 /* Default To */ 848 tr = g_strdup(C_("folder properties: %s stands for a header name", 849 "Default %s")); 850 text = g_strdup_printf(tr, "To:"); 851 checkbtn_default_to = gtk_check_button_new_with_label(text); 852 gtk_grid_attach(GTK_GRID(table), checkbtn_default_to, 0, rowcount, 1, 1); 853 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_default_to), 854 item->prefs->enable_default_to); 855 g_free(text); 856 g_free(tr); 857 858 entry_default_to = gtk_entry_new(); 859 gtk_grid_attach(GTK_GRID(table), entry_default_to, 1, rowcount, 1, 1); 860 gtk_widget_set_hexpand(entry_default_to, TRUE); 861 gtk_widget_set_halign(entry_default_to, GTK_ALIGN_FILL); 862 SET_TOGGLE_SENSITIVITY(checkbtn_default_to, entry_default_to); 863 gtk_entry_set_text(GTK_ENTRY(entry_default_to), SAFE_STRING(item->prefs->default_to)); 864 address_completion_register_entry(GTK_ENTRY(entry_default_to), 865 TRUE); 866 867 default_to_rec_checkbtn = gtk_check_button_new(); 868 gtk_grid_attach(GTK_GRID(table), default_to_rec_checkbtn, 2, rowcount, 1, 1); 869 870 rowcount++; 871 872 /* Default address to reply to */ 873 tr = g_strdup(C_("folder properties: %s stands for a header name", 874 "Default %s for replies")); 875 text = g_strdup_printf(tr, "To:"); 876 checkbtn_default_reply_to = gtk_check_button_new_with_label(text); 877 gtk_grid_attach(GTK_GRID(table), checkbtn_default_reply_to, 0, rowcount, 1, 1); 878 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_default_reply_to), 879 item->prefs->enable_default_reply_to); 880 g_free(text); 881 g_free(tr); 882 883 entry_default_reply_to = gtk_entry_new(); 884 gtk_grid_attach(GTK_GRID(table), entry_default_reply_to, 1, rowcount, 1, 1); 885 gtk_widget_set_hexpand(entry_default_reply_to, TRUE); 886 gtk_widget_set_halign(entry_default_reply_to, GTK_ALIGN_FILL); 887 SET_TOGGLE_SENSITIVITY(checkbtn_default_reply_to, entry_default_reply_to); 888 gtk_entry_set_text(GTK_ENTRY(entry_default_reply_to), SAFE_STRING(item->prefs->default_reply_to)); 889 address_completion_register_entry( 890 GTK_ENTRY(entry_default_reply_to), TRUE); 891 892 default_reply_to_rec_checkbtn = gtk_check_button_new(); 893 gtk_grid_attach(GTK_GRID(table), default_reply_to_rec_checkbtn, 2, rowcount, 1, 1); 894 895 rowcount++; 896 897 /* Default Cc */ 898 tr = g_strdup(C_("folder properties: %s stands for a header name", 899 "Default %s")); 900 text = g_strdup_printf(tr, "Cc:"); 901 checkbtn_default_cc = gtk_check_button_new_with_label(text); 902 gtk_grid_attach(GTK_GRID(table), checkbtn_default_cc, 0, rowcount, 1, 1); 903 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_default_cc), 904 item->prefs->enable_default_cc); 905 g_free(text); 906 g_free(tr); 907 908 entry_default_cc = gtk_entry_new(); 909 gtk_grid_attach(GTK_GRID(table), entry_default_cc, 1, rowcount, 1, 1); 910 gtk_widget_set_hexpand(entry_default_cc, TRUE); 911 gtk_widget_set_halign(entry_default_cc, GTK_ALIGN_FILL); 912 SET_TOGGLE_SENSITIVITY(checkbtn_default_cc, entry_default_cc); 913 gtk_entry_set_text(GTK_ENTRY(entry_default_cc), SAFE_STRING(item->prefs->default_cc)); 914 address_completion_register_entry(GTK_ENTRY(entry_default_cc), 915 TRUE); 916 917 default_cc_rec_checkbtn = gtk_check_button_new(); 918 gtk_grid_attach(GTK_GRID(table), default_cc_rec_checkbtn, 2, rowcount, 1, 1); 919 920 rowcount++; 921 922 /* Default Bcc */ 923 tr = g_strdup(C_("folder properties: %s stands for a header name", 924 "Default %s")); 925 text = g_strdup_printf(tr, "Bcc:"); 926 checkbtn_default_bcc = gtk_check_button_new_with_label(text); 927 gtk_grid_attach(GTK_GRID(table), checkbtn_default_bcc, 0, rowcount, 1, 1); 928 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_default_bcc), 929 item->prefs->enable_default_bcc); 930 g_free(text); 931 g_free(tr); 932 933 entry_default_bcc = gtk_entry_new(); 934 gtk_grid_attach(GTK_GRID(table), entry_default_bcc, 1, rowcount, 1, 1); 935 gtk_widget_set_hexpand(entry_default_bcc, TRUE); 936 gtk_widget_set_halign(entry_default_bcc, GTK_ALIGN_FILL); 937 SET_TOGGLE_SENSITIVITY(checkbtn_default_bcc, entry_default_bcc); 938 gtk_entry_set_text(GTK_ENTRY(entry_default_bcc), SAFE_STRING(item->prefs->default_bcc)); 939 address_completion_register_entry(GTK_ENTRY(entry_default_bcc), 940 TRUE); 941 942 default_bcc_rec_checkbtn = gtk_check_button_new(); 943 gtk_grid_attach(GTK_GRID(table), default_bcc_rec_checkbtn, 2, rowcount, 1, 1); 944 945 rowcount++; 946 947 /* Default Reply-to */ 948 tr = g_strdup(C_("folder properties: %s stands for a header name", 949 "Default %s")); 950 text = g_strdup_printf(tr, "Reply-To:"); 951 checkbtn_default_replyto = gtk_check_button_new_with_label(text); 952 gtk_grid_attach(GTK_GRID(table), checkbtn_default_replyto, 0, rowcount, 1, 1); 953 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_default_replyto), 954 item->prefs->enable_default_replyto); 955 g_free(text); 956 g_free(tr); 957 958 entry_default_replyto = gtk_entry_new(); 959 gtk_grid_attach(GTK_GRID(table), entry_default_replyto, 1, rowcount, 1, 1); 960 gtk_widget_set_hexpand(entry_default_replyto, TRUE); 961 gtk_widget_set_halign(entry_default_replyto, GTK_ALIGN_FILL); 962 SET_TOGGLE_SENSITIVITY(checkbtn_default_replyto, entry_default_replyto); 963 gtk_entry_set_text(GTK_ENTRY(entry_default_replyto), SAFE_STRING(item->prefs->default_replyto)); 964 address_completion_register_entry(GTK_ENTRY(entry_default_replyto), 965 TRUE); 966 967 default_replyto_rec_checkbtn = gtk_check_button_new(); 968 gtk_grid_attach(GTK_GRID(table), default_replyto_rec_checkbtn, 2, rowcount, 1, 1); 969 970 rowcount++; 971 } 972 /* Default account */ 973 checkbtn_enable_default_account = gtk_check_button_new_with_label(_("Default account")); 974 gtk_grid_attach(GTK_GRID(table), checkbtn_enable_default_account, 0, rowcount, 1, 1); 975 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_enable_default_account), 976 item->prefs->enable_default_account); 977 978 optmenu_default_account = gtkut_sc_combobox_create(NULL, FALSE); 979 gtk_grid_attach(GTK_GRID(table), optmenu_default_account, 1, rowcount, 1, 1); 980 optmenu_default_account_menu = GTK_LIST_STORE( 981 gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu_default_account))); 982 983 account_list = account_get_list(); 984 for (cur_ac = account_list; cur_ac != NULL; cur_ac = cur_ac->next) { 985 ac_prefs = (PrefsAccount *)cur_ac->data; 986 COMBOBOX_ADD_ESCAPED (optmenu_default_account_menu, 987 ac_prefs->account_name?ac_prefs->account_name : _("Untitled"), 988 ac_prefs->account_id); 989 990 /* Set combobox to current default account id */ 991 if (ac_prefs->account_id == item->prefs->default_account) { 992 combobox_select_by_data(GTK_COMBO_BOX(optmenu_default_account), 993 ac_prefs->account_id); 994 default_account_set = TRUE; 995 } 996 } 997 998 /* If nothing has been set (folder doesn't have a default account set), 999 * pre-select global default account, since that's what actually used 1000 * anyway. We don't want nothing selected in combobox. */ 1001 if( !default_account_set ) 1002 combobox_select_by_data(GTK_COMBO_BOX(optmenu_default_account), 1003 account_get_default()->account_id); 1004 1005 SET_TOGGLE_SENSITIVITY(checkbtn_enable_default_account, optmenu_default_account); 1006 1007 default_account_rec_checkbtn = gtk_check_button_new(); 1008 gtk_grid_attach(GTK_GRID(table), default_account_rec_checkbtn, 2, rowcount, 1, 1); 1009 rowcount++; 1010 1011 gtk_widget_show_all(table); 1012 1013 page->window = GTK_WIDGET(window); 1014 page->table = table; 1015 page->no_save_warning = no_save_warning; 1016 page->checkbtn_save_copy_to_folder = checkbtn_save_copy_to_folder; 1017 page->checkbtn_default_from = checkbtn_default_from; 1018 page->entry_default_from = entry_default_from; 1019 page->checkbtn_default_to = checkbtn_default_to; 1020 page->entry_default_to = entry_default_to; 1021 page->checkbtn_default_reply_to = checkbtn_default_reply_to; 1022 page->entry_default_reply_to = entry_default_reply_to; 1023 page->checkbtn_default_cc = checkbtn_default_cc; 1024 page->entry_default_cc = entry_default_cc; 1025 page->checkbtn_default_bcc = checkbtn_default_bcc; 1026 page->entry_default_bcc = entry_default_bcc; 1027 page->checkbtn_default_replyto = checkbtn_default_replyto; 1028 page->entry_default_replyto = entry_default_replyto; 1029 page->checkbtn_enable_default_account = checkbtn_enable_default_account; 1030 page->optmenu_default_account = optmenu_default_account; 1031 1032 page->save_copy_to_folder_rec_checkbtn = save_copy_to_folder_rec_checkbtn; 1033 page->default_from_rec_checkbtn = default_from_rec_checkbtn; 1034 page->default_to_rec_checkbtn = default_to_rec_checkbtn; 1035 page->default_reply_to_rec_checkbtn = default_reply_to_rec_checkbtn; 1036 page->default_cc_rec_checkbtn = default_cc_rec_checkbtn; 1037 page->default_bcc_rec_checkbtn = default_bcc_rec_checkbtn; 1038 page->default_replyto_rec_checkbtn = default_replyto_rec_checkbtn; 1039 page->default_account_rec_checkbtn = default_account_rec_checkbtn; 1040 1041 page->page.widget = table; 1042 } 1043 1044 static void prefs_folder_item_compose_destroy_widget_func(PrefsPage *page_) 1045 { 1046 FolderItemComposePage *page = (FolderItemComposePage *) page_; 1047 1048 if (page->entry_default_from) 1049 address_completion_unregister_entry(GTK_ENTRY(page->entry_default_from)); 1050 if (page->entry_default_to) 1051 address_completion_unregister_entry(GTK_ENTRY(page->entry_default_to)); 1052 if (page->entry_default_reply_to) 1053 address_completion_unregister_entry(GTK_ENTRY(page->entry_default_reply_to)); 1054 if (page->entry_default_cc) 1055 address_completion_unregister_entry(GTK_ENTRY(page->entry_default_cc)); 1056 if (page->entry_default_bcc) 1057 address_completion_unregister_entry(GTK_ENTRY(page->entry_default_bcc)); 1058 if (page->entry_default_replyto) 1059 address_completion_unregister_entry(GTK_ENTRY(page->entry_default_replyto)); 1060 } 1061 1062 /** \brief Save the prefs in page to folder. 1063 * 1064 * If the folder is not the one specified in page->item, then only those properties 1065 * that have the relevant 'apply to sub folders' button checked are saved 1066 */ 1067 static void compose_save_folder_prefs(FolderItem *folder, FolderItemComposePage *page) 1068 { 1069 FolderItemPrefs *prefs = folder->prefs; 1070 1071 gboolean all = FALSE; 1072 1073 if (folder->path == NULL) 1074 return; 1075 1076 if (page->item == folder) 1077 all = TRUE; 1078 1079 cm_return_if_fail(prefs != NULL); 1080 1081 if (item_protocol(folder)) { 1082 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->save_copy_to_folder_rec_checkbtn))) { 1083 prefs->save_copy_to_folder = 1084 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_save_copy_to_folder)); 1085 } 1086 1087 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_from_rec_checkbtn))) { 1088 prefs->enable_default_from = 1089 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_default_from)); 1090 ASSIGN_STRING(prefs->default_from, 1091 gtk_editable_get_chars(GTK_EDITABLE(page->entry_default_from), 0, -1)); 1092 } 1093 1094 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_to_rec_checkbtn))) { 1095 prefs->enable_default_to = 1096 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_default_to)); 1097 ASSIGN_STRING(prefs->default_to, 1098 gtk_editable_get_chars(GTK_EDITABLE(page->entry_default_to), 0, -1)); 1099 } 1100 1101 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_reply_to_rec_checkbtn))) { 1102 prefs->enable_default_reply_to = 1103 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_default_reply_to)); 1104 ASSIGN_STRING(prefs->default_reply_to, 1105 gtk_editable_get_chars(GTK_EDITABLE(page->entry_default_reply_to), 0, -1)); 1106 } 1107 1108 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_cc_rec_checkbtn))) { 1109 1110 prefs->enable_default_cc = 1111 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_default_cc)); 1112 ASSIGN_STRING(prefs->default_cc, 1113 gtk_editable_get_chars(GTK_EDITABLE(page->entry_default_cc), 0, -1)); 1114 } 1115 1116 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_bcc_rec_checkbtn))) { 1117 1118 prefs->enable_default_bcc = 1119 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_default_bcc)); 1120 ASSIGN_STRING(prefs->default_bcc, 1121 gtk_editable_get_chars(GTK_EDITABLE(page->entry_default_bcc), 0, -1)); 1122 } 1123 1124 if (all || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_replyto_rec_checkbtn))) { 1125 1126 prefs->enable_default_replyto = 1127 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_default_replyto)); 1128 ASSIGN_STRING(prefs->default_replyto, 1129 gtk_editable_get_chars(GTK_EDITABLE(page->entry_default_replyto), 0, -1)); 1130 } 1131 1132 } else { 1133 prefs->save_copy_to_folder = FALSE; 1134 prefs->enable_default_from = FALSE; 1135 prefs->enable_default_to = FALSE; 1136 prefs->enable_default_reply_to = FALSE; 1137 prefs->enable_default_cc = FALSE; 1138 prefs->enable_default_bcc = FALSE; 1139 prefs->enable_default_replyto = FALSE; 1140 } 1141 1142 if (all || gtk_toggle_button_get_active( 1143 GTK_TOGGLE_BUTTON(page->default_account_rec_checkbtn))) { 1144 prefs->enable_default_account = 1145 gtk_toggle_button_get_active( 1146 GTK_TOGGLE_BUTTON(page->checkbtn_enable_default_account)); 1147 prefs->default_account = combobox_get_active_data( 1148 GTK_COMBO_BOX(page->optmenu_default_account)); 1149 } 1150 1151 folder_item_prefs_save_config(folder); 1152 } 1153 1154 static gboolean compose_save_recurse_func(GNode *node, gpointer data) 1155 { 1156 FolderItem *item = (FolderItem *) node->data; 1157 FolderItemComposePage *page = (FolderItemComposePage *) data; 1158 1159 cm_return_val_if_fail(item != NULL, TRUE); 1160 cm_return_val_if_fail(page != NULL, TRUE); 1161 1162 compose_save_folder_prefs(item, page); 1163 1164 /* optimise by not continuing if none of the 'apply to sub folders' 1165 check boxes are selected - and optimise the checking by only doing 1166 it once */ 1167 if ((node == page->item->node) && 1168 !(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->save_copy_to_folder_rec_checkbtn)) || 1169 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_from_rec_checkbtn)) || 1170 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_to_rec_checkbtn)) || 1171 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_account_rec_checkbtn)) || 1172 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_cc_rec_checkbtn)) || 1173 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_bcc_rec_checkbtn)) || 1174 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_replyto_rec_checkbtn)) || 1175 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_reply_to_rec_checkbtn)) 1176 )) 1177 return TRUE; 1178 else if ((node == page->item->node) && 1179 !(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->default_account_rec_checkbtn)) 1180 )) 1181 return TRUE; 1182 else 1183 return FALSE; 1184 } 1185 1186 static void prefs_folder_item_compose_save_func(PrefsPage *page_) 1187 { 1188 FolderItemComposePage *page = (FolderItemComposePage *) page_; 1189 1190 g_node_traverse(page->item->node, G_PRE_ORDER, G_TRAVERSE_ALL, 1191 -1, compose_save_recurse_func, page); 1192 1193 } 1194 1195 static void clean_cache_cb(GtkWidget *widget, gpointer data) 1196 { 1197 FolderItemGeneralPage *page = (FolderItemGeneralPage *) data; 1198 FolderItem *item = page->item; 1199 gboolean was_open = FALSE; 1200 FolderView *folderview = NULL; 1201 1202 if (alertpanel_full(_("Discard cache"), 1203 _("Do you really want to discard the local cached " 1204 "data for this folder?"), 1205 NULL, _("_Cancel"), NULL, _("Discard"), NULL, NULL, 1206 ALERTFOCUS_SECOND, FALSE, NULL, ALERT_WARNING) 1207 != G_ALERTALTERNATE) 1208 return; 1209 1210 if (mainwindow_get_mainwindow()) 1211 folderview = mainwindow_get_mainwindow()->folderview; 1212 1213 if (folderview && item->opened) { 1214 folderview_close_opened(folderview, FALSE); 1215 was_open = TRUE; 1216 } 1217 folder_item_discard_cache(item); 1218 if (was_open) 1219 folderview_select(folderview,item); 1220 } 1221 1222 static regex_t *summary_compile_simplify_regexp(gchar *simplify_subject_regexp) 1223 { 1224 int err; 1225 gchar buf[BUFFSIZE]; 1226 regex_t *preg = NULL; 1227 1228 preg = g_new0(regex_t, 1); 1229 1230 err = regcomp(preg, simplify_subject_regexp, REG_EXTENDED); 1231 if (err) { 1232 regerror(err, preg, buf, BUFFSIZE); 1233 regfree(preg); 1234 g_free(preg); 1235 preg = NULL; 1236 } 1237 1238 return preg; 1239 } 1240 1241 static void folder_regexp_test_cb(GtkWidget *widget, gpointer data) 1242 { 1243 GdkColor red = { (guint32)0, (guint16)0xff, (guint16)0x70, (guint16)0x70 }; 1244 static gchar buf[BUFFSIZE]; 1245 FolderItemGeneralPage *page = (FolderItemGeneralPage *)data; 1246 gchar *test_string, *regexp; 1247 regex_t *preg; 1248 1249 regexp = g_strdup(gtk_entry_get_text(GTK_ENTRY(page->entry_simplify_subject))); 1250 test_string = g_strdup(gtk_entry_get_text(GTK_ENTRY(page->entry_regexp_test_string))); 1251 1252 if (!regexp || !regexp[0]) { 1253 gtk_widget_modify_base(page->entry_simplify_subject, 1254 GTK_STATE_NORMAL, NULL); 1255 if (test_string) 1256 gtk_entry_set_text(GTK_ENTRY(page->entry_regexp_test_result), test_string); 1257 1258 g_free(test_string); 1259 g_free(regexp); 1260 return; 1261 } 1262 1263 if (!test_string || !test_string[0]) { 1264 g_free(test_string); 1265 g_free(regexp); 1266 return; 1267 } 1268 1269 preg = summary_compile_simplify_regexp(regexp); 1270 1271 gtk_widget_modify_base(page->entry_simplify_subject, 1272 GTK_STATE_NORMAL, preg ? NULL : &red); 1273 1274 if (preg != NULL) { 1275 string_remove_match(buf, BUFFSIZE, test_string, preg); 1276 1277 gtk_entry_set_text(GTK_ENTRY(page->entry_regexp_test_result), buf); 1278 1279 regfree(preg); 1280 g_free(preg); 1281 } 1282 1283 g_free(test_string); 1284 g_free(regexp); 1285 } 1286 1287 static gchar *folder_regexp_get_subject_example(void) 1288 { 1289 MsgInfo *msginfo_selected; 1290 SummaryView *summaryview = NULL; 1291 1292 if (!mainwindow_get_mainwindow()) 1293 return NULL; 1294 summaryview = mainwindow_get_mainwindow()->summaryview; 1295 1296 msginfo_selected = summary_get_selected_msg(summaryview); 1297 return msginfo_selected ? g_strdup(msginfo_selected->subject) : NULL; 1298 } 1299 1300 static void folder_regexp_set_subject_example_cb(GtkWidget *widget, gpointer data) 1301 { 1302 FolderItemGeneralPage *page = (FolderItemGeneralPage *)data; 1303 1304 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_simplify_subject))) { 1305 gchar *subject = folder_regexp_get_subject_example(); 1306 if (subject) { 1307 gtk_entry_set_text(GTK_ENTRY(page->entry_regexp_test_string), subject); 1308 g_free(subject); 1309 } 1310 } 1311 } 1312 1313 static void register_general_page() 1314 { 1315 static gchar *pfi_general_path[2]; 1316 static FolderItemGeneralPage folder_item_general_page; 1317 1318 pfi_general_path[0] = _("General"); 1319 pfi_general_path[1] = NULL; 1320 1321 folder_item_general_page.page.path = pfi_general_path; 1322 folder_item_general_page.page.create_widget = prefs_folder_item_general_create_widget_func; 1323 folder_item_general_page.page.destroy_widget = prefs_folder_item_general_destroy_widget_func; 1324 folder_item_general_page.page.save_page = prefs_folder_item_general_save_func; 1325 1326 prefs_folder_item_register_page((PrefsPage *) &folder_item_general_page, NULL); 1327 } 1328 1329 1330 static void register_compose_page(void) 1331 { 1332 static gchar *pfi_compose_path[2]; 1333 static FolderItemComposePage folder_item_compose_page; 1334 1335 pfi_compose_path[0] = _("Write"); 1336 pfi_compose_path[1] = NULL; 1337 1338 folder_item_compose_page.page.path = pfi_compose_path; 1339 folder_item_compose_page.page.create_widget = prefs_folder_item_compose_create_widget_func; 1340 folder_item_compose_page.page.destroy_widget = prefs_folder_item_compose_destroy_widget_func; 1341 folder_item_compose_page.page.save_page = prefs_folder_item_compose_save_func; 1342 1343 prefs_folder_item_register_page((PrefsPage *) &folder_item_compose_page, NULL); 1344 } 1345 1346 static GSList *prefs_pages = NULL; 1347 1348 static void prefs_folder_item_address_completion_start(PrefsWindow *window) 1349 { 1350 address_completion_start(window->window); 1351 } 1352 1353 static void prefs_folder_item_address_completion_end(PrefsWindow *window) 1354 { 1355 address_completion_end(window->window); 1356 } 1357 1358 void prefs_folder_item_open(FolderItem *item) 1359 { 1360 gchar *id, *title; 1361 GSList *pages; 1362 1363 if (prefs_pages == NULL) { 1364 register_general_page(); 1365 register_compose_page(); 1366 } 1367 1368 if (item->path) { 1369 id = folder_item_get_identifier (item); 1370 can_save = TRUE; 1371 } else { 1372 id = g_strdup(item->name); 1373 can_save = FALSE; 1374 } 1375 1376 pages = g_slist_concat( 1377 g_slist_copy(prefs_pages), 1378 g_slist_copy(item->folder->klass->prefs_pages)); 1379 1380 title = g_strdup_printf (_("Properties for folder %s"), id); 1381 g_free (id); 1382 prefswindow_open(title, pages, item, 1383 &prefs_common.folderitemwin_width, &prefs_common.folderitemwin_height, 1384 prefs_folder_item_address_completion_start, 1385 NULL, 1386 prefs_folder_item_address_completion_end); 1387 1388 g_slist_free(pages); 1389 g_free (title); 1390 } 1391 1392 void prefs_folder_item_register_page(PrefsPage *page, FolderClass *klass) 1393 { 1394 if (klass != NULL) 1395 klass->prefs_pages = g_slist_append(klass->prefs_pages, page); 1396 else 1397 prefs_pages = g_slist_append(prefs_pages, page); 1398 } 1399 1400 void prefs_folder_item_unregister_page(PrefsPage *page, FolderClass *klass) 1401 { 1402 if (klass != NULL) 1403 klass->prefs_pages = g_slist_remove(klass->prefs_pages, page); 1404 else 1405 prefs_pages = g_slist_remove(prefs_pages, page); 1406 }