2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2001 Hiroyuki Yamamoto
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include <gdk/gdkkeysyms.h>
36 #include "prefs_gtk.h"
37 #include "prefs_filtering_action.h"
38 #include "prefs_common.h"
39 #include "mainwindow.h"
40 #include "foldersel.h"
41 #include "manage_window.h"
46 #include "alertpanel.h"
48 #include "description_window.h"
50 #include "matcher_parser.h"
51 #include "colorlabel.h"
54 static void prefs_filtering_action_create(void);
55 static void prefs_filtering_action_delete_cb(void);
56 static void prefs_filtering_action_substitute_cb(void);
57 static void prefs_filtering_action_register_cb(void);
58 static void prefs_filtering_action_reset_dialog(void);
59 static gboolean prefs_filtering_action_key_pressed(GtkWidget *widget,
60 GdkEventKey *event, gpointer data);
61 static void prefs_filtering_action_cancel(void);
62 static void prefs_filtering_action_ok(void);
63 static gint prefs_filtering_action_deleted(GtkWidget *widget,
64 GdkEventAny *event, gpointer data);
65 static void prefs_filtering_action_type_selection_changed(GtkList *list,
67 static void prefs_filtering_action_type_select(GtkList *list,
68 GtkWidget *widget, gpointer user_data);
69 static void prefs_filtering_action_select_dest(void);
70 static void prefs_filtering_action_select(GtkCList *clist,
71 gint row, gint column, GdkEvent *event);
72 static void prefs_filtering_action_up(void);
73 static void prefs_filtering_action_down(void);
74 static void prefs_filtering_action_set_dialog(GSList *action_list);
75 static GSList *prefs_filtering_action_get_list(void);
79 *\brief UI data for matcher dialog
81 static struct FilteringAction {
86 GtkWidget *action_clist;
87 GtkWidget *action_type_list;
88 GtkWidget *action_combo;
89 GtkWidget *account_label;
90 GtkWidget *account_list;
91 GtkWidget *account_combo;
92 GtkWidget *dest_entry;
94 GtkWidget *dest_label;
95 GtkWidget *recip_label;
96 GtkWidget *exec_label;
98 GtkWidget *color_label;
99 GtkWidget *color_optmenu;
105 typedef enum Action_ {
114 ACTION_MARK_AS_UNREAD,
116 ACTION_FORWARD_AS_ATTACHMENT,
120 /* add other action constants */
127 { N_("Move"), ACTION_MOVE },
128 { N_("Copy"), ACTION_COPY },
129 { N_("Delete"), ACTION_DELETE },
130 { N_("Mark"), ACTION_MARK },
131 { N_("Unmark"), ACTION_UNMARK },
132 { N_("Lock"), ACTION_LOCK },
133 { N_("Unlock"), ACTION_UNLOCK },
134 { N_("Mark as read"), ACTION_MARK_AS_READ },
135 { N_("Mark as unread"), ACTION_MARK_AS_UNREAD },
136 { N_("Forward"), ACTION_FORWARD },
137 { N_("Forward as attachment"), ACTION_FORWARD_AS_ATTACHMENT },
138 { N_("Redirect"), ACTION_REDIRECT },
139 { N_("Execute"), ACTION_EXECUTE },
140 { N_("Color"), ACTION_COLOR }
147 static PrefsFilteringActionSignal *filtering_action_callback;
150 *\brief Find index of list selection
152 *\param list GTK list widget
154 *\return gint Selection index
156 static gint get_sel_from_list(GtkList *list)
162 if (list->selection == NULL)
165 sel = list->selection->data;
166 for (child = list->children; child != NULL; child = g_list_next(child)) {
167 if (child->data == sel)
176 *\brief Opens the filtering action dialog with a list of actions
178 *\param matchers List of conditions
182 void prefs_filtering_action_open(GSList *action_list,
183 PrefsFilteringActionSignal *cb)
187 if (!filtering_action.window) {
188 prefs_filtering_action_create();
191 manage_window_set_transient(GTK_WINDOW(filtering_action.window));
192 gtk_widget_grab_focus(filtering_action.ok_btn);
194 filtering_action_callback = cb;
196 prefs_filtering_action_set_dialog(action_list);
198 gtk_widget_show(filtering_action.window);
202 *\brief Create the matcher dialog
204 static void prefs_filtering_action_create(void)
209 GtkWidget *cancel_btn;
210 GtkWidget *confirm_area;
216 GtkWidget *action_label;
217 GtkWidget *recip_label;
218 GtkWidget *action_combo;
219 GtkWidget *action_type_list;
220 GtkWidget *account_list;
221 GtkWidget *dest_label;
222 GtkWidget *exec_label;
223 GtkWidget *color_label;
224 GtkWidget *account_label;
225 GtkWidget *account_combo;
226 GtkWidget *dest_entry;
234 GtkWidget *subst_btn;
237 GtkWidget *action_hbox;
238 GtkWidget *action_scrolledwin;
239 GtkWidget *action_clist;
247 GtkWidget *color_optmenu;
255 debug_print("Creating matcher configuration window...\n");
257 window = gtk_window_new(GTK_WINDOW_DIALOG);
258 gtk_container_set_border_width(GTK_CONTAINER(window), 8);
259 gtk_window_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
260 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
261 gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
263 vbox = gtk_vbox_new(FALSE, 6);
264 gtk_widget_show(vbox);
265 gtk_container_add(GTK_CONTAINER(window), vbox);
267 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
268 &cancel_btn, _("Cancel"), NULL, NULL);
269 gtk_widget_show(confirm_area);
270 gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
271 gtk_widget_grab_default(ok_btn);
273 gtk_window_set_title(GTK_WINDOW(window),
274 _("Filtering action configuration"));
275 gtk_signal_connect(GTK_OBJECT(window), "delete_event",
276 GTK_SIGNAL_FUNC(prefs_filtering_action_deleted), NULL);
277 gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
278 GTK_SIGNAL_FUNC(prefs_filtering_action_key_pressed), NULL);
279 MANAGE_WINDOW_SIGNALS_CONNECT(window);
280 gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
281 GTK_SIGNAL_FUNC(prefs_filtering_action_ok), NULL);
282 gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked",
283 GTK_SIGNAL_FUNC(prefs_filtering_action_cancel), NULL);
285 vbox1 = gtk_vbox_new(FALSE, VSPACING);
286 gtk_widget_show(vbox1);
287 gtk_box_pack_start(GTK_BOX(vbox), vbox1, TRUE, TRUE, 0);
288 gtk_container_set_border_width(GTK_CONTAINER (vbox1), 2);
290 /* action to be defined */
292 hbox1 = gtk_hbox_new (FALSE, VSPACING);
293 gtk_widget_show (hbox1);
294 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 0);
295 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
297 action_label = gtk_label_new (_("Action"));
298 gtk_widget_show (action_label);
299 gtk_misc_set_alignment (GTK_MISC (action_label), 0, 0.5);
300 gtk_box_pack_start (GTK_BOX (hbox1), action_label, FALSE, FALSE, 0);
302 action_combo = gtk_combo_new ();
303 gtk_widget_show (action_combo);
304 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(action_combo)->entry),
308 for (i = 0; i < sizeof action_text / sizeof action_text[0]; i++)
309 combo_items = g_list_append
310 (combo_items, (gpointer) _(action_text[i].text));
311 gtk_combo_set_popdown_strings(GTK_COMBO(action_combo), combo_items);
313 g_list_free(combo_items);
315 gtk_box_pack_start (GTK_BOX (hbox1), action_combo,
317 action_type_list = GTK_COMBO(action_combo)->list;
318 gtk_signal_connect (GTK_OBJECT (action_type_list), "select-child",
319 GTK_SIGNAL_FUNC (prefs_filtering_action_type_select),
322 gtk_signal_connect(GTK_OBJECT(action_type_list), "selection-changed",
323 GTK_SIGNAL_FUNC(prefs_filtering_action_type_selection_changed),
328 hbox1 = gtk_hbox_new (FALSE, VSPACING);
329 gtk_widget_show (vbox1);
330 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 0);
331 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
333 account_label = gtk_label_new (_("Account"));
334 gtk_widget_show (account_label);
335 gtk_misc_set_alignment (GTK_MISC (account_label), 0, 0.5);
336 gtk_box_pack_start (GTK_BOX (hbox1), account_label, FALSE, FALSE, 0);
338 account_combo = gtk_combo_new ();
339 gtk_widget_set_usize (account_combo, 150, -1);
340 gtk_widget_show (account_combo);
343 for (accounts = account_get_list() ; accounts != NULL;
344 accounts = accounts->next) {
345 PrefsAccount *ac = (PrefsAccount *)accounts->data;
348 name = g_strdup_printf("%s <%s> (%s)",
349 ac->name, ac->address,
351 combo_items = g_list_append(combo_items, (gpointer) name);
354 gtk_combo_set_popdown_strings(GTK_COMBO(account_combo), combo_items);
356 for(cur = g_list_first(combo_items) ; cur != NULL ;
357 cur = g_list_next(cur))
359 g_list_free(combo_items);
361 gtk_box_pack_start (GTK_BOX (hbox1), account_combo,
363 account_list = GTK_COMBO(account_combo)->list;
364 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(account_combo)->entry),
369 hbox1 = gtk_hbox_new (FALSE, VSPACING);
370 gtk_widget_show (vbox1);
371 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 0);
372 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
374 dest_label = gtk_label_new (_("Destination"));
375 gtk_widget_show (dest_label);
376 gtk_misc_set_alignment (GTK_MISC (dest_label), 0, 0.5);
377 gtk_box_pack_start (GTK_BOX (hbox1), dest_label, FALSE, FALSE, 0);
379 recip_label = gtk_label_new (_("Recipient"));
380 gtk_widget_show (recip_label);
381 gtk_misc_set_alignment (GTK_MISC (recip_label), 0, 0.5);
382 gtk_box_pack_start (GTK_BOX (hbox1), recip_label, FALSE, FALSE, 0);
384 exec_label = gtk_label_new (_("Execute"));
385 gtk_widget_show (exec_label);
386 gtk_misc_set_alignment (GTK_MISC (exec_label), 0, 0.5);
387 gtk_box_pack_start (GTK_BOX (hbox1), exec_label, FALSE, FALSE, 0);
389 color_label = gtk_label_new (_("Color"));
390 gtk_widget_show(color_label);
391 gtk_misc_set_alignment(GTK_MISC(color_label), 0, 0.5);
392 gtk_box_pack_start(GTK_BOX(hbox1), color_label, FALSE, FALSE, 0);
394 dest_entry = gtk_entry_new ();
395 gtk_widget_set_usize (dest_entry, 150, -1);
396 gtk_widget_show (dest_entry);
397 gtk_box_pack_start (GTK_BOX (hbox1), dest_entry, TRUE, TRUE, 0);
399 color_optmenu = gtk_option_menu_new();
400 gtk_option_menu_set_menu(GTK_OPTION_MENU(color_optmenu),
401 colorlabel_create_color_menu());
402 gtk_box_pack_start(GTK_BOX(hbox1), color_optmenu, TRUE, TRUE, 0);
404 dest_btn = gtk_button_new_with_label (_("Select ..."));
405 gtk_widget_show (dest_btn);
406 gtk_box_pack_start (GTK_BOX (hbox1), dest_btn, FALSE, FALSE, 0);
407 gtk_signal_connect (GTK_OBJECT (dest_btn), "clicked",
408 GTK_SIGNAL_FUNC (prefs_filtering_action_select_dest),
411 exec_btn = gtk_button_new_with_label (_("Info ..."));
412 gtk_widget_show (exec_btn);
413 gtk_box_pack_start (GTK_BOX (hbox1), exec_btn, FALSE, FALSE, 0);
414 gtk_signal_connect (GTK_OBJECT (exec_btn), "clicked",
415 GTK_SIGNAL_FUNC (prefs_filtering_action_exec_info),
418 /* register / substitute / delete */
420 reg_hbox = gtk_hbox_new(FALSE, 4);
421 gtk_widget_show(reg_hbox);
422 gtk_box_pack_start(GTK_BOX(vbox1), reg_hbox, FALSE, FALSE, 0);
424 arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
425 gtk_widget_show(arrow);
426 gtk_box_pack_start(GTK_BOX(reg_hbox), arrow, FALSE, FALSE, 0);
427 gtk_widget_set_usize(arrow, -1, 16);
429 btn_hbox = gtk_hbox_new(TRUE, 4);
430 gtk_widget_show(btn_hbox);
431 gtk_box_pack_start(GTK_BOX(reg_hbox), btn_hbox, FALSE, FALSE, 0);
433 reg_btn = gtk_button_new_with_label(_("Add"));
434 gtk_widget_show(reg_btn);
435 gtk_box_pack_start(GTK_BOX(btn_hbox), reg_btn, FALSE, TRUE, 0);
436 gtk_signal_connect(GTK_OBJECT(reg_btn), "clicked",
437 GTK_SIGNAL_FUNC(prefs_filtering_action_register_cb), NULL);
439 subst_btn = gtk_button_new_with_label(_(" Replace "));
440 gtk_widget_show(subst_btn);
441 gtk_box_pack_start(GTK_BOX(btn_hbox), subst_btn, FALSE, TRUE, 0);
442 gtk_signal_connect(GTK_OBJECT(subst_btn), "clicked",
443 GTK_SIGNAL_FUNC(prefs_filtering_action_substitute_cb),
446 del_btn = gtk_button_new_with_label(_("Delete"));
447 gtk_widget_show(del_btn);
448 gtk_box_pack_start(GTK_BOX(btn_hbox), del_btn, FALSE, TRUE, 0);
449 gtk_signal_connect(GTK_OBJECT(del_btn), "clicked",
450 GTK_SIGNAL_FUNC(prefs_filtering_action_delete_cb), NULL);
452 action_hbox = gtk_hbox_new(FALSE, 8);
453 gtk_widget_show(action_hbox);
454 gtk_box_pack_start(GTK_BOX(vbox1), action_hbox, TRUE, TRUE, 0);
456 action_scrolledwin = gtk_scrolled_window_new(NULL, NULL);
457 gtk_widget_show(action_scrolledwin);
458 gtk_widget_set_usize(action_scrolledwin, -1, 150);
459 gtk_box_pack_start(GTK_BOX(action_hbox), action_scrolledwin,
461 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(action_scrolledwin),
462 GTK_POLICY_AUTOMATIC,
463 GTK_POLICY_AUTOMATIC);
465 title[0] = _("Current action list");
466 action_clist = gtk_clist_new_with_titles(1, title);
467 gtk_widget_show(action_clist);
468 gtk_container_add(GTK_CONTAINER(action_scrolledwin), action_clist);
469 gtk_clist_set_column_width(GTK_CLIST(action_clist), 0, 80);
470 gtk_clist_set_selection_mode(GTK_CLIST(action_clist),
471 GTK_SELECTION_BROWSE);
472 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(action_clist)->column[0].button,
474 gtk_signal_connect(GTK_OBJECT(action_clist), "select_row",
475 GTK_SIGNAL_FUNC(prefs_filtering_action_select), NULL);
477 btn_vbox = gtk_vbox_new(FALSE, 8);
478 gtk_widget_show(btn_vbox);
479 gtk_box_pack_start(GTK_BOX(action_hbox), btn_vbox, FALSE, FALSE, 0);
481 up_btn = gtk_button_new_with_label(_("Up"));
482 gtk_widget_show(up_btn);
483 gtk_box_pack_start(GTK_BOX(btn_vbox), up_btn, FALSE, FALSE, 0);
484 gtk_signal_connect(GTK_OBJECT(up_btn), "clicked",
485 GTK_SIGNAL_FUNC(prefs_filtering_action_up), NULL);
487 down_btn = gtk_button_new_with_label(_("Down"));
488 gtk_widget_show(down_btn);
489 gtk_box_pack_start(GTK_BOX(btn_vbox), down_btn, FALSE, FALSE, 0);
490 gtk_signal_connect(GTK_OBJECT(down_btn), "clicked",
491 GTK_SIGNAL_FUNC(prefs_filtering_action_down), NULL);
493 gtk_widget_show_all(window);
495 filtering_action.window = window;
496 filtering_action.action_type_list = action_type_list;
497 filtering_action.action_combo = action_combo;
498 filtering_action.account_label = account_label;
499 filtering_action.account_list = account_list;
500 filtering_action.account_combo = account_combo;
501 filtering_action.dest_entry = dest_entry;
502 filtering_action.dest_btn = dest_btn;
503 filtering_action.dest_label = dest_label;
504 filtering_action.recip_label = recip_label;
505 filtering_action.exec_label = exec_label;
506 filtering_action.exec_btn = exec_btn;
507 filtering_action.color_label = color_label;
508 filtering_action.color_optmenu = color_optmenu;
509 filtering_action.ok_btn = ok_btn;
510 filtering_action.action_clist = action_clist;
514 *\brief Set the contents of a row
516 *\param row Index of row to set
517 *\param prop Condition to set
519 *\return gint Row index \a prop has been added
521 static gint prefs_filtering_action_clist_set_row(gint row, FilteringAction *action)
523 GtkCList *clist = GTK_CLIST(filtering_action.action_clist);
524 gchar *action_tab_str[1];
528 if (action == NULL) {
529 action_tab_str[0] = _("(New)");
530 return gtk_clist_append(clist, action_tab_str);
533 filteringaction_to_string(buf, sizeof buf, action);
534 action_str = g_strdup(buf);
536 action_tab_str[0] = action_str;
538 row = gtk_clist_append(clist, action_tab_str);
540 gtk_clist_set_text(clist, row, 0, action_tab_str[0]);
547 *\brief Update scrollbar
549 static void prefs_filtering_action_update_hscrollbar(void)
551 gint optwidth = gtk_clist_optimal_column_width(GTK_CLIST(filtering_action.action_clist), 0);
552 gtk_clist_set_column_width(GTK_CLIST(filtering_action.action_clist), 0, optwidth);
556 *\brief Initializes dialog with a set of conditions
558 *\param matchers List of conditions
560 static void prefs_filtering_action_set_dialog(GSList *action_list)
562 GtkCList *clist = GTK_CLIST(filtering_action.action_clist);
565 gtk_clist_freeze(clist);
566 gtk_clist_clear(clist);
568 prefs_filtering_action_clist_set_row(-1, NULL);
569 if (action_list != NULL) {
570 for (cur = action_list; cur != NULL;
571 cur = g_slist_next(cur)) {
572 FilteringAction *action;
573 action = (FilteringAction *) cur->data;
574 prefs_filtering_action_clist_set_row(-1, action);
578 prefs_filtering_action_update_hscrollbar();
580 gtk_clist_thaw(clist);
582 prefs_filtering_action_reset_dialog();
586 *\brief Converts current actions in list box in
587 * an action list used by the filtering system.
589 *\return GSList * List of actions.
591 static GSList *prefs_filtering_action_get_list(void)
594 FilteringAction *action;
600 while (gtk_clist_get_text(GTK_CLIST(filtering_action.action_clist),
601 row, 0, &action_str)) {
603 if (strcmp(action_str, _("(New)")) != 0) {
604 GSList * tmp_action_list;
605 tmp_action_list = matcher_parser_get_action_list(action_str);
607 if (tmp_action_list == NULL)
610 action_list = g_slist_concat(action_list,
620 *\brief Returns account ID from the given list index
622 *\return gint account ID
624 static gint get_account_id_from_list_id(gint list_id)
628 for (accounts = account_get_list() ; accounts != NULL;
629 accounts = accounts->next) {
630 PrefsAccount *ac = (PrefsAccount *)accounts->data;
633 return ac->account_id;
640 *\brief Returns list index from the given account ID
642 *\return gint list index
644 static gint get_list_id_from_account_id(gint account_id)
649 for (accounts = account_get_list() ; accounts != NULL;
650 accounts = accounts->next) {
651 PrefsAccount *ac = (PrefsAccount *)accounts->data;
653 if (account_id == ac->account_id)
662 *\brief Returns parser action ID from internal action ID
664 *\return gint parser action ID
666 static gint prefs_filtering_action_get_matching_from_action(Action action_id)
670 return MATCHACTION_MOVE;
672 return MATCHACTION_COPY;
674 return MATCHACTION_DELETE;
676 return MATCHACTION_MARK;
678 return MATCHACTION_UNMARK;
680 return MATCHACTION_LOCK;
682 return MATCHACTION_UNLOCK;
683 case ACTION_MARK_AS_READ:
684 return MATCHACTION_MARK_AS_READ;
685 case ACTION_MARK_AS_UNREAD:
686 return MATCHACTION_MARK_AS_UNREAD;
688 return MATCHACTION_FORWARD;
689 case ACTION_FORWARD_AS_ATTACHMENT:
690 return MATCHACTION_FORWARD_AS_ATTACHMENT;
691 case ACTION_REDIRECT:
692 return MATCHACTION_REDIRECT;
694 return MATCHACTION_EXECUTE;
696 return MATCHACTION_COLOR;
703 *\brief Returns action from the content of the dialog
705 *\param alert specifies whether alert dialog boxes should be shown
708 *\return FilteringAction * action entered in the dialog box.
710 static FilteringAction * prefs_filtering_action_dialog_to_action(gboolean alert)
718 FilteringAction * action;
720 action_id = get_sel_from_list(GTK_LIST(filtering_action.action_type_list));
721 action_type = prefs_filtering_action_get_matching_from_action(action_id);
722 list_id = get_sel_from_list(GTK_LIST(filtering_action.account_list));
723 account_id = get_account_id_from_list_id(list_id);
729 destination = gtk_entry_get_text(GTK_ENTRY(filtering_action.dest_entry));
730 if (*destination == '\0') {
732 alertpanel_error(_("Destination is not set."));
737 case ACTION_FORWARD_AS_ATTACHMENT:
738 case ACTION_REDIRECT:
739 destination = gtk_entry_get_text(GTK_ENTRY(filtering_action.dest_entry));
740 if (*destination == '\0') {
742 alertpanel_error(_("Recipient is not set."));
747 labelcolor = colorlabel_get_color_menu_active_item(
748 gtk_option_menu_get_menu(GTK_OPTION_MENU(filtering_action.color_optmenu)));
756 action = filteringaction_new(action_type, account_id, destination, labelcolor);
762 *\brief Signal handler for register button
764 static void prefs_filtering_action_register_cb(void)
766 FilteringAction *action;
768 action = prefs_filtering_action_dialog_to_action(TRUE);
772 prefs_filtering_action_clist_set_row(-1, action);
774 filteringaction_free(action);
776 prefs_filtering_action_reset_dialog();
777 prefs_filtering_action_update_hscrollbar();
781 *\brief Signal handler for substitute button
783 static void prefs_filtering_action_substitute_cb(void)
785 GtkCList *clist = GTK_CLIST(filtering_action.action_clist);
787 FilteringAction *action;
789 if (!clist->selection) return;
790 row = GPOINTER_TO_INT(clist->selection->data);
794 action = prefs_filtering_action_dialog_to_action(TRUE);
798 prefs_filtering_action_clist_set_row(row, action);
800 filteringaction_free(action);
802 prefs_filtering_action_reset_dialog();
804 prefs_filtering_action_update_hscrollbar();
808 *\brief Signal handler for delete button
810 static void prefs_filtering_action_delete_cb(void)
812 GtkCList *clist = GTK_CLIST(filtering_action.action_clist);
815 if (!clist->selection) return;
816 row = GPOINTER_TO_INT(clist->selection->data);
820 gtk_clist_remove(clist, row);
822 prefs_filtering_action_reset_dialog();
824 prefs_filtering_action_update_hscrollbar();
828 *\brief Signal handler for 'move up' button
830 static void prefs_filtering_action_up(void)
832 GtkCList *clist = GTK_CLIST(filtering_action.action_clist);
835 if (!clist->selection) return;
837 row = GPOINTER_TO_INT(clist->selection->data);
839 gtk_clist_row_move(clist, row, row - 1);
840 if (gtk_clist_row_is_visible(clist, row - 1) != GTK_VISIBILITY_FULL)
841 gtk_clist_moveto(clist, row - 1, 0, 0, 0);
846 *\brief Signal handler for 'move down' button
848 static void prefs_filtering_action_down(void)
850 GtkCList *clist = GTK_CLIST(filtering_action.action_clist);
853 if (!clist->selection) return;
855 row = GPOINTER_TO_INT(clist->selection->data);
856 if (row >= 1 && row < clist->rows - 1) {
857 gtk_clist_row_move(clist, row, row + 1);
858 if (gtk_clist_row_is_visible(clist, row + 1) != GTK_VISIBILITY_FULL)
859 gtk_clist_moveto(clist, row + 1, 0, 1, 0);
864 *\brief Signal handler for select row.
866 *\param clist List widget
867 *\param row Selected row
868 *\param column Selected column
869 *\param event Event information
871 static void prefs_filtering_action_select(GtkCList *clist,
872 gint row, gint column, GdkEvent *event)
875 FilteringAction *action;
876 GSList * action_list;
879 if (!gtk_clist_get_text(GTK_CLIST(filtering_action.action_clist),
880 row, 0, &action_str))
884 prefs_filtering_action_reset_dialog();
888 action_list = matcher_parser_get_action_list(action_str);
889 if (action_list == NULL)
892 action = action_list->data;
893 g_slist_free(action_list);
895 if (action->destination)
896 gtk_entry_set_text(GTK_ENTRY(filtering_action.dest_entry), action->destination);
898 gtk_entry_set_text(GTK_ENTRY(filtering_action.dest_entry), "");
900 switch(action->type) {
901 case MATCHACTION_MOVE:
902 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
905 case MATCHACTION_COPY:
906 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
909 case MATCHACTION_DELETE:
910 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
913 case MATCHACTION_MARK:
914 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
917 case MATCHACTION_UNMARK:
918 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
921 case MATCHACTION_LOCK:
922 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
925 case MATCHACTION_UNLOCK:
926 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
929 case MATCHACTION_MARK_AS_READ:
930 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
931 ACTION_MARK_AS_READ);
933 case MATCHACTION_MARK_AS_UNREAD:
934 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
935 ACTION_MARK_AS_UNREAD);
937 case MATCHACTION_FORWARD:
938 list_id = get_list_id_from_account_id(action->account_id);
939 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
941 gtk_list_select_item(GTK_LIST(filtering_action.account_list),
944 case MATCHACTION_FORWARD_AS_ATTACHMENT:
945 list_id = get_list_id_from_account_id(action->account_id);
946 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
947 ACTION_FORWARD_AS_ATTACHMENT);
948 gtk_list_select_item(GTK_LIST(filtering_action.account_list),
951 case MATCHACTION_REDIRECT:
952 list_id = get_list_id_from_account_id(action->account_id);
953 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
955 gtk_list_select_item(GTK_LIST(filtering_action.account_list),
958 case MATCHACTION_EXECUTE:
959 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
962 case MATCHACTION_COLOR:
963 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
965 gtk_option_menu_set_history(GTK_OPTION_MENU(filtering_action.color_optmenu), action->labelcolor);
971 *\brief Handle key press
973 *\param widget Widget receiving key press
974 *\param event Key event
975 *\param data User data
977 static gboolean prefs_filtering_action_key_pressed(GtkWidget *widget,
978 GdkEventKey *event, gpointer data)
980 if (event && event->keyval == GDK_Escape)
981 prefs_filtering_action_cancel();
986 *\brief Cancel matcher dialog
988 static void prefs_filtering_action_cancel(void)
990 gtk_widget_hide(filtering_action.window);
995 *\brief Accept current matchers
997 static void prefs_filtering_action_ok(void)
999 GSList * action_list;
1002 action_list = prefs_filtering_action_get_list();
1004 if (action_list == NULL) {
1005 alertpanel_error(_("No action was defined."));
1009 if (filtering_action_callback != NULL)
1010 filtering_action_callback(action_list);
1011 for(cur = action_list ; cur != NULL ; cur = cur->next) {
1012 filteringaction_free(cur->data);
1014 g_slist_free(action_list);
1016 gtk_widget_hide(filtering_action.window);
1021 *\brief Called when closing dialog box
1023 *\param widget Dialog widget
1024 *\param event Event info
1025 *\param data User data
1029 static gint prefs_filtering_action_deleted(GtkWidget *widget,
1030 GdkEventAny *event, gpointer data)
1032 prefs_filtering_action_cancel();
1037 * Strings describing exec format strings
1039 * When adding new lines, remember to put 2 strings for each line
1041 static gchar *exec_desc_strings[] = {
1043 "%s", N_("Subject"),
1048 "%i", N_("Message-ID"),
1049 "%n", N_("Newsgroups"),
1050 "%r", N_("References"),
1051 "%F", N_("Filename - should not be modified"),
1052 "\\n", N_("new line"),
1053 "\\", N_("escape character for quotes"),
1054 "\\\"",N_("quote character"),
1058 static DescriptionWindow exec_desc_win = {
1061 N_("Description of symbols"),
1068 *\brief Show Execute action's info
1070 void prefs_filtering_action_exec_info(void)
1072 description_window_create(&exec_desc_win);
1075 static void prefs_filtering_action_select_dest(void)
1080 dest = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL);
1083 path = folder_item_get_identifier(dest);
1085 gtk_entry_set_text(GTK_ENTRY(filtering_action.dest_entry), path);
1089 static void prefs_filtering_action_type_selection_changed(GtkList *list,
1094 value = get_sel_from_list(GTK_LIST(filtering_action.action_type_list));
1096 if (filtering_action.current_action != value) {
1097 if (filtering_action.current_action == ACTION_FORWARD
1098 || filtering_action.current_action == ACTION_FORWARD_AS_ATTACHMENT
1099 || filtering_action.current_action == ACTION_REDIRECT) {
1100 debug_print("unregistering address completion entry\n");
1101 address_completion_unregister_entry(GTK_ENTRY(filtering_action.dest_entry));
1103 if (value == ACTION_FORWARD || value == ACTION_FORWARD_AS_ATTACHMENT
1104 || value == ACTION_REDIRECT) {
1105 debug_print("registering address completion entry\n");
1106 address_completion_register_entry(GTK_ENTRY(filtering_action.dest_entry));
1108 filtering_action.current_action = value;
1112 static void prefs_filtering_action_type_select(GtkList *list,
1113 GtkWidget *widget, gpointer user_data)
1117 value = (Action) get_sel_from_list(GTK_LIST(filtering_action.action_type_list));
1121 gtk_widget_show(filtering_action.account_label);
1122 gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
1123 gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
1124 gtk_widget_show(filtering_action.dest_entry);
1125 gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
1126 gtk_widget_show(filtering_action.dest_btn);
1127 gtk_widget_set_sensitive(filtering_action.dest_btn, TRUE);
1128 gtk_widget_show(filtering_action.dest_label);
1129 gtk_widget_set_sensitive(filtering_action.dest_label, TRUE);
1130 gtk_widget_hide(filtering_action.recip_label);
1131 gtk_widget_hide(filtering_action.exec_label);
1132 gtk_widget_hide(filtering_action.exec_btn);
1133 gtk_widget_hide(filtering_action.color_optmenu);
1134 gtk_widget_hide(filtering_action.color_label);
1137 gtk_widget_show(filtering_action.account_label);
1138 gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
1139 gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
1140 gtk_widget_show(filtering_action.dest_entry);
1141 gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
1142 gtk_widget_show(filtering_action.dest_btn);
1143 gtk_widget_set_sensitive(filtering_action.dest_btn, TRUE);
1144 gtk_widget_show(filtering_action.dest_label);
1145 gtk_widget_set_sensitive(filtering_action.dest_label, TRUE);
1146 gtk_widget_hide(filtering_action.recip_label);
1147 gtk_widget_hide(filtering_action.exec_label);
1148 gtk_widget_hide(filtering_action.exec_btn);
1149 gtk_widget_hide(filtering_action.color_optmenu);
1150 gtk_widget_hide(filtering_action.color_label);
1153 gtk_widget_show(filtering_action.account_label);
1154 gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
1155 gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
1156 gtk_widget_show(filtering_action.dest_entry);
1157 gtk_widget_set_sensitive(filtering_action.dest_entry, FALSE);
1158 gtk_widget_show(filtering_action.dest_btn);
1159 gtk_widget_set_sensitive(filtering_action.dest_btn, FALSE);
1160 gtk_widget_show(filtering_action.dest_label);
1161 gtk_widget_set_sensitive(filtering_action.dest_label, FALSE);
1162 gtk_widget_hide(filtering_action.recip_label);
1163 gtk_widget_hide(filtering_action.exec_label);
1164 gtk_widget_hide(filtering_action.exec_btn);
1165 gtk_widget_hide(filtering_action.color_optmenu);
1166 gtk_widget_hide(filtering_action.color_label);
1172 case ACTION_MARK_AS_READ:
1173 case ACTION_MARK_AS_UNREAD:
1174 gtk_widget_show(filtering_action.account_label);
1175 gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
1176 gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
1177 gtk_widget_show(filtering_action.dest_entry);
1178 gtk_widget_set_sensitive(filtering_action.dest_entry, FALSE);
1179 gtk_widget_show(filtering_action.dest_btn);
1180 gtk_widget_set_sensitive(filtering_action.dest_btn, FALSE);
1181 gtk_widget_show(filtering_action.dest_label);
1182 gtk_widget_set_sensitive(filtering_action.dest_label, FALSE);
1183 gtk_widget_hide(filtering_action.recip_label);
1184 gtk_widget_hide(filtering_action.exec_label);
1185 gtk_widget_hide(filtering_action.exec_btn);
1186 gtk_widget_hide(filtering_action.color_optmenu);
1187 gtk_widget_hide(filtering_action.color_label);
1189 case ACTION_FORWARD:
1190 gtk_widget_show(filtering_action.account_label);
1191 gtk_widget_set_sensitive(filtering_action.account_label, TRUE);
1192 gtk_widget_set_sensitive(filtering_action.account_combo, TRUE);
1193 gtk_widget_show(filtering_action.dest_entry);
1194 gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
1195 gtk_widget_show(filtering_action.dest_btn);
1196 gtk_widget_set_sensitive(filtering_action.dest_btn, FALSE);
1197 gtk_widget_hide(filtering_action.dest_label);
1198 gtk_widget_show(filtering_action.recip_label);
1199 gtk_widget_set_sensitive(filtering_action.recip_label, TRUE);
1200 gtk_widget_hide(filtering_action.exec_label);
1201 gtk_widget_hide(filtering_action.exec_btn);
1202 gtk_widget_hide(filtering_action.color_optmenu);
1203 gtk_widget_hide(filtering_action.color_label);
1205 case ACTION_FORWARD_AS_ATTACHMENT:
1206 gtk_widget_show(filtering_action.account_label);
1207 gtk_widget_set_sensitive(filtering_action.account_label, TRUE);
1208 gtk_widget_set_sensitive(filtering_action.account_combo, TRUE);
1209 gtk_widget_show(filtering_action.dest_entry);
1210 gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
1211 gtk_widget_show(filtering_action.dest_btn);
1212 gtk_widget_set_sensitive(filtering_action.dest_btn, FALSE);
1213 gtk_widget_hide(filtering_action.dest_label);
1214 gtk_widget_show(filtering_action.recip_label);
1215 gtk_widget_set_sensitive(filtering_action.recip_label, TRUE);
1216 gtk_widget_hide(filtering_action.exec_label);
1217 gtk_widget_hide(filtering_action.exec_btn);
1218 gtk_widget_hide(filtering_action.color_optmenu);
1219 gtk_widget_hide(filtering_action.color_label);
1221 case ACTION_REDIRECT:
1222 gtk_widget_show(filtering_action.account_label);
1223 gtk_widget_set_sensitive(filtering_action.account_label, TRUE);
1224 gtk_widget_set_sensitive(filtering_action.account_combo, TRUE);
1225 gtk_widget_show(filtering_action.dest_entry);
1226 gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
1227 gtk_widget_show(filtering_action.dest_btn);
1228 gtk_widget_set_sensitive(filtering_action.dest_btn, FALSE);
1229 gtk_widget_hide(filtering_action.dest_label);
1230 gtk_widget_show(filtering_action.recip_label);
1231 gtk_widget_set_sensitive(filtering_action.recip_label, TRUE);
1232 gtk_widget_hide(filtering_action.exec_label);
1233 gtk_widget_hide(filtering_action.exec_btn);
1234 gtk_widget_hide(filtering_action.color_optmenu);
1235 gtk_widget_hide(filtering_action.color_label);
1237 case ACTION_EXECUTE:
1238 gtk_widget_show(filtering_action.account_label);
1239 gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
1240 gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
1241 gtk_widget_show(filtering_action.dest_entry);
1242 gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
1243 gtk_widget_hide(filtering_action.dest_btn);
1244 gtk_widget_hide(filtering_action.dest_label);
1245 gtk_widget_hide(filtering_action.recip_label);
1246 gtk_widget_show(filtering_action.exec_label);
1247 gtk_widget_set_sensitive(filtering_action.exec_btn, TRUE);
1248 gtk_widget_show(filtering_action.exec_btn);
1249 gtk_widget_hide(filtering_action.color_optmenu);
1250 gtk_widget_hide(filtering_action.color_label);
1253 gtk_widget_show(filtering_action.account_label);
1254 gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
1255 gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
1256 gtk_widget_hide(filtering_action.dest_entry);
1257 gtk_widget_hide(filtering_action.dest_btn);
1258 gtk_widget_hide(filtering_action.dest_label);
1259 gtk_widget_hide(filtering_action.recip_label);
1260 gtk_widget_hide(filtering_action.exec_label);
1261 gtk_widget_show(filtering_action.exec_btn);
1262 gtk_widget_set_sensitive(filtering_action.exec_btn, FALSE);
1263 gtk_widget_show(filtering_action.color_optmenu);
1264 gtk_widget_show(filtering_action.color_label);
1269 static void prefs_filtering_action_reset_dialog(void)
1271 gtk_list_select_item(GTK_LIST(filtering_action.action_type_list), 0);
1272 gtk_list_select_item(GTK_LIST(filtering_action.account_list), 0);
1273 gtk_entry_set_text(GTK_ENTRY(filtering_action.dest_entry), "");