From 0b3cbf57875fd692e4ba0b336fefa4bee1ed00dc Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Mon, 26 Feb 2018 11:23:00 +0100 Subject: Initial commit for sylpheed 3.7.0 --- src/prefs_filter.c | 875 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 875 insertions(+) create mode 100644 src/prefs_filter.c (limited to 'src/prefs_filter.c') diff --git a/src/prefs_filter.c b/src/prefs_filter.c new file mode 100644 index 0000000..671aab3 --- /dev/null +++ b/src/prefs_filter.c @@ -0,0 +1,875 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2014 Hiroyuki Yamamoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "defs.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" +#include "prefs.h" +#include "prefs_ui.h" +#include "prefs_filter.h" +#include "prefs_filter_edit.h" +#include "prefs_common.h" +#include "mainwindow.h" +#include "foldersel.h" +#include "manage_window.h" +#include "stock_pixmap.h" +#include "inc.h" +#include "procheader.h" +#include "menu.h" +#include "filter.h" +#include "utils.h" +#include "gtkutils.h" +#include "alertpanel.h" +#include "xml.h" +#include "plugin.h" + +static struct FilterRuleListWindow { + GtkWidget *window; + + GtkWidget *treeview; + GtkListStore *store; + GtkTreeSelection *selection; + + GtkWidget *add_btn; + GtkWidget *edit_btn; + GtkWidget *copy_btn; + GtkWidget *del_btn; + + GSList *default_hdr_list; + GSList *user_hdr_list; + GSList *msg_hdr_list; + + GHashTable *msg_hdr_table; + + GtkWidget *close_btn; + + gboolean on_init; + gboolean modified; +} rule_list_window; + +enum { + COL_ENABLED, + COL_NAME, + COL_FILTER_RULE, + N_COLS +}; + +static void prefs_filter_create (void); + +static void prefs_filter_set_dialog (void); +static void prefs_filter_set_list_row (GtkTreeIter *iter, + FilterRule *rule, + gboolean move_view); + +static void prefs_filter_set_list (void); + +/* callback functions */ +static void prefs_filter_add_cb (void); +static void prefs_filter_edit_cb (void); +static void prefs_filter_copy_cb (void); +static void prefs_filter_delete_cb (void); +static void prefs_filter_top (void); +static void prefs_filter_up (void); +static void prefs_filter_down (void); +static void prefs_filter_bottom (void); + +static gboolean prefs_filter_select (GtkTreeSelection *selection, + GtkTreeModel *model, + GtkTreePath *path, + gboolean cur_selected, + gpointer data); +static void prefs_filter_enable_toggled (GtkCellRenderer *cell, + gchar *path, + gpointer data); + +static void prefs_filter_row_activated (GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer data); +static void prefs_filter_row_reordered (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data, + gpointer user_data); +static void prefs_filter_row_inserted (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer user_data); + +static gint prefs_filter_deleted (GtkWidget *widget, + GdkEventAny *event, + gpointer data); +static gboolean prefs_filter_key_pressed(GtkWidget *widget, + GdkEventKey *event, + gpointer data); +static void prefs_filter_close (void); + + +void prefs_filter_open(MsgInfo *msginfo, const gchar *header, const gchar *key) +{ + inc_lock(); + + rule_list_window.on_init = TRUE; + + if (!rule_list_window.window) + prefs_filter_create(); + + prefs_filter_set_header_list(msginfo); + + manage_window_set_transient(GTK_WINDOW(rule_list_window.window)); + gtk_widget_grab_focus(rule_list_window.close_btn); + + prefs_filter_set_dialog(); + + gtk_widget_show(rule_list_window.window); + manage_window_focus_in(rule_list_window.window, NULL, NULL); + + rule_list_window.modified = FALSE; + + syl_plugin_signal_emit("prefs-filter-open", rule_list_window.window); + + if (msginfo) { + FilterRule *rule; + + rule = prefs_filter_edit_open(NULL, header, key); + gtk_window_present(GTK_WINDOW(rule_list_window.window)); + + if (rule) { + prefs_filter_set_list_row(NULL, rule, TRUE); + prefs_filter_set_list(); + } + } + + rule_list_window.on_init = FALSE; +} + +static void prefs_filter_create(void) +{ + GtkWidget *window; + GtkWidget *vbox; + GtkWidget *close_btn; + GtkWidget *confirm_area; + + GtkWidget *hbox; + GtkWidget *scrolledwin; + GtkWidget *treeview; + GtkListStore *store; + GtkTreeSelection *selection; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + GtkWidget *btn_vbox; + GtkWidget *spc_vbox; + GtkWidget *top_btn; + GtkWidget *up_btn; + GtkWidget *down_btn; + GtkWidget *bottom_btn; + + GtkWidget *btn_hbox; + GtkWidget *add_btn; + GtkWidget *edit_btn; + GtkWidget *copy_btn; + GtkWidget *del_btn; + GtkWidget *image; + + debug_print("Creating filter setting window...\n"); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_set_border_width(GTK_CONTAINER(window), 8); + gtk_widget_set_size_request(window, 540 * gtkut_get_dpi_multiplier(), 360 * gtkut_get_dpi_multiplier()); + gtk_window_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_window_set_modal(GTK_WINDOW(window), TRUE); + gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE); + + vbox = gtk_vbox_new(FALSE, 6); + gtk_widget_show(vbox); + gtk_container_add(GTK_CONTAINER(window), vbox); + + gtkut_stock_button_set_create(&confirm_area, + &close_btn, GTK_STOCK_CLOSE, + NULL, NULL, NULL, NULL); + gtk_widget_show(confirm_area); + gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0); + gtk_widget_grab_default(close_btn); + + gtk_window_set_title(GTK_WINDOW(window), + _("Filter settings")); + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(prefs_filter_deleted), NULL); + g_signal_connect(G_OBJECT(window), "key_press_event", + G_CALLBACK(prefs_filter_key_pressed), NULL); + MANAGE_WINDOW_SIGNALS_CONNECT (window); + g_signal_connect(G_OBJECT(close_btn), "clicked", + G_CALLBACK(prefs_filter_close), NULL); + + /* Rule list */ + + hbox = gtk_hbox_new(FALSE, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); + + scrolledwin = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolledwin); + gtk_widget_set_size_request(scrolledwin, -1, 150 * gtkut_get_dpi_multiplier()); + gtk_box_pack_start(GTK_BOX(hbox), scrolledwin, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin), + GTK_SHADOW_IN); + + store = gtk_list_store_new + (N_COLS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER); + + treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE); + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); + gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), COL_NAME); + gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview), TRUE); + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); + gtk_tree_selection_set_select_function(selection, prefs_filter_select, + NULL, NULL); + + renderer = gtk_cell_renderer_toggle_new(); + g_signal_connect(renderer, "toggled", + G_CALLBACK(prefs_filter_enable_toggled), NULL); + column = gtk_tree_view_column_new_with_attributes + (_("Enabled"), renderer, "active", COL_ENABLED, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes + (_("Name"), renderer, "text", COL_NAME, NULL); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + gtk_widget_show(treeview); + gtk_container_add(GTK_CONTAINER(scrolledwin), treeview); + + g_signal_connect(G_OBJECT(treeview), "row-activated", + G_CALLBACK(prefs_filter_row_activated), NULL); + g_signal_connect_after(G_OBJECT(store), "rows-reordered", + G_CALLBACK(prefs_filter_row_reordered), NULL); + g_signal_connect_after(G_OBJECT(store), "row-inserted", + G_CALLBACK(prefs_filter_row_inserted), NULL); + + /* Up / Down */ + + btn_vbox = gtk_vbox_new (FALSE, 8); + gtk_widget_show(btn_vbox); + gtk_box_pack_start(GTK_BOX(hbox), btn_vbox, FALSE, FALSE, 0); + + top_btn = gtk_button_new_from_stock(GTK_STOCK_GOTO_TOP); + gtk_widget_show(top_btn); + gtk_box_pack_start(GTK_BOX(btn_vbox), top_btn, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(top_btn), "clicked", + G_CALLBACK(prefs_filter_top), NULL); + + PACK_VSPACER(btn_vbox, spc_vbox, VSPACING_NARROW_2); + + up_btn = gtk_button_new(); + image = gtk_image_new_from_stock(GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON); + gtk_widget_show(image); + gtk_button_set_image(GTK_BUTTON(up_btn), image); + gtk_widget_show(up_btn); + gtk_box_pack_start(GTK_BOX(btn_vbox), up_btn, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(up_btn), "clicked", + G_CALLBACK(prefs_filter_up), NULL); + + down_btn = gtk_button_new(); + image = gtk_image_new_from_stock(GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_BUTTON); + gtk_widget_show(image); + gtk_button_set_image(GTK_BUTTON(down_btn), image); + gtk_widget_show(down_btn); + gtk_box_pack_start(GTK_BOX(btn_vbox), down_btn, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(down_btn), "clicked", + G_CALLBACK(prefs_filter_down), NULL); + + PACK_VSPACER(btn_vbox, spc_vbox, VSPACING_NARROW_2); + + bottom_btn = gtk_button_new_from_stock(GTK_STOCK_GOTO_BOTTOM); + gtk_widget_show(bottom_btn); + gtk_box_pack_start(GTK_BOX(btn_vbox), bottom_btn, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(bottom_btn), "clicked", + G_CALLBACK(prefs_filter_bottom), NULL); + + /* add / edit / copy / delete */ + + hbox = gtk_hbox_new(FALSE, 4); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + btn_hbox = gtk_hbox_new(TRUE, 4); + gtk_widget_show(btn_hbox); + gtk_box_pack_start(GTK_BOX(hbox), btn_hbox, FALSE, FALSE, 0); + + add_btn = gtk_button_new_from_stock(GTK_STOCK_ADD); + gtk_widget_show(add_btn); + gtk_box_pack_start(GTK_BOX(btn_hbox), add_btn, FALSE, TRUE, 0); + g_signal_connect(G_OBJECT(add_btn), "clicked", + G_CALLBACK(prefs_filter_add_cb), NULL); + +#ifdef GTK_STOCK_EDIT + edit_btn = gtk_button_new_from_stock(GTK_STOCK_EDIT); +#else + edit_btn = gtk_button_new_with_label(_("Edit")); +#endif + gtk_widget_show(edit_btn); + gtk_box_pack_start(GTK_BOX(btn_hbox), edit_btn, FALSE, TRUE, 0); + g_signal_connect(G_OBJECT(edit_btn), "clicked", + G_CALLBACK(prefs_filter_edit_cb), NULL); + + copy_btn = gtk_button_new_from_stock(GTK_STOCK_COPY); + gtk_widget_show(copy_btn); + gtk_box_pack_start(GTK_BOX(btn_hbox), copy_btn, FALSE, TRUE, 0); + g_signal_connect(G_OBJECT(copy_btn), "clicked", + G_CALLBACK(prefs_filter_copy_cb), NULL); + + del_btn = gtk_button_new_from_stock(GTK_STOCK_DELETE); + gtk_widget_show(del_btn); + gtk_box_pack_start(GTK_BOX(btn_hbox), del_btn, FALSE, TRUE, 0); + g_signal_connect(G_OBJECT(del_btn), "clicked", + G_CALLBACK(prefs_filter_delete_cb), NULL); + + gtk_widget_show_all(window); + + rule_list_window.window = window; + rule_list_window.close_btn = close_btn; + + rule_list_window.treeview = treeview; + rule_list_window.store = store; + rule_list_window.selection = selection; + + rule_list_window.add_btn = add_btn; + rule_list_window.edit_btn = edit_btn; + rule_list_window.copy_btn = copy_btn; + rule_list_window.del_btn = del_btn; + + rule_list_window.default_hdr_list = NULL; + rule_list_window.user_hdr_list = NULL; + rule_list_window.msg_hdr_list = NULL; + rule_list_window.msg_hdr_table = NULL; +} + +static void prefs_filter_set_dialog(void) +{ + GSList *cur; + + gtk_list_store_clear(rule_list_window.store); + + for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) { + FilterRule *rule = (FilterRule *)cur->data; + prefs_filter_set_list_row(NULL, rule, FALSE); + } +} + +static void prefs_filter_set_list_row(GtkTreeIter *iter, FilterRule *rule, + gboolean move_view) +{ + GtkListStore *store = rule_list_window.store; + gchar *rule_name; + GtkTreeIter iter_; + + g_return_if_fail(rule != NULL); + + if (rule->name && *rule->name) + rule_name = g_strdup(rule->name); + else + rule_name = filter_get_str(rule); + + if (!iter) { + gtk_list_store_append(store, &iter_); + gtk_list_store_set(store, &iter_, + COL_ENABLED, rule->enabled, + COL_NAME, rule_name, + COL_FILTER_RULE, rule, -1); + } else { + FilterRule *prev_rule = NULL; + + iter_ = *iter; + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter_, + COL_FILTER_RULE, &prev_rule, -1); + if (!prev_rule) { + g_warning("rule at the row not found\n"); + gtk_list_store_append(store, &iter_); + } + + gtk_list_store_set(store, &iter_, + COL_ENABLED, rule->enabled, + COL_NAME, rule_name, + COL_FILTER_RULE, rule, -1); + + if (prev_rule && prev_rule != rule) + filter_rule_free(prev_rule); + } + + g_free(rule_name); + + if (move_view) { + GtkTreePath *path; + + path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter_); + gtk_tree_view_scroll_to_cell + (GTK_TREE_VIEW(rule_list_window.treeview), + path, NULL, TRUE, 0.5, 0.0); + gtk_tree_path_free(path); + } + + rule_list_window.modified = TRUE; +} + +#define APPEND_HDR_LIST(hdr_list) \ + for (cur = hdr_list; cur != NULL; cur = cur->next) { \ + header = (Header *)cur->data; \ + \ + if (!g_hash_table_lookup(table, header->name)) { \ + g_hash_table_insert(table, header->name, header); \ + list = procheader_add_header_list \ + (list, header->name, header->body); \ + } \ + } + +GSList *prefs_filter_get_header_list(void) +{ + GSList *list = NULL; + GSList *cur; + GHashTable *table; + Header *header; + + table = g_hash_table_new(str_case_hash, str_case_equal); + + APPEND_HDR_LIST(rule_list_window.default_hdr_list) + APPEND_HDR_LIST(rule_list_window.user_hdr_list); + APPEND_HDR_LIST(rule_list_window.msg_hdr_list); + + g_hash_table_destroy(table); + + return list; +} + +#undef APPEND_HDR_LIST + +GSList *prefs_filter_get_user_header_list(void) +{ + return rule_list_window.user_hdr_list; +} + +gchar *prefs_filter_get_msg_header_field(const gchar *header_name) +{ + if (!rule_list_window.msg_hdr_table) + return NULL; + + return (gchar *)g_hash_table_lookup + (rule_list_window.msg_hdr_table, header_name); +} + +void prefs_filter_set_user_header_list(GSList *list) +{ + procheader_header_list_destroy(rule_list_window.user_hdr_list); + rule_list_window.user_hdr_list = list; +} + +void prefs_filter_set_msg_header_list(MsgInfo *msginfo) +{ + gchar *file; + GSList *cur; + GSList *next; + Header *header; + + if (rule_list_window.msg_hdr_table) { + g_hash_table_destroy(rule_list_window.msg_hdr_table); + rule_list_window.msg_hdr_table = NULL; + } + if (rule_list_window.msg_hdr_list) { + procheader_header_list_destroy(rule_list_window.msg_hdr_list); + rule_list_window.msg_hdr_list = NULL; + } + + if (!msginfo) + return; + + file = procmsg_get_message_file(msginfo); + g_return_if_fail(file != NULL); + + rule_list_window.msg_hdr_list = + procheader_get_header_list_from_file(file); + + g_free(file); + + rule_list_window.msg_hdr_table = + g_hash_table_new(str_case_hash, str_case_equal); + + for (cur = rule_list_window.msg_hdr_list; cur != NULL; + cur = next) { + next = cur->next; + header = (Header *)cur->data; + if (!g_ascii_strcasecmp(header->name, "Received") || + !g_ascii_strcasecmp(header->name, "Mime-Version") || + !g_ascii_strcasecmp(header->name, "X-UIDL")) { + procheader_header_free(header); + rule_list_window.msg_hdr_list = + g_slist_remove(rule_list_window.msg_hdr_list, + header); + continue; + } + if (!g_hash_table_lookup(rule_list_window.msg_hdr_table, + header->name)) { + g_hash_table_insert(rule_list_window.msg_hdr_table, + header->name, header->body); + } + } +} + +void prefs_filter_set_header_list(MsgInfo *msginfo) +{ + GSList *list = NULL; + gchar *path; + FILE *fp; + + list = procheader_add_header_list(list, "From", NULL); + list = procheader_add_header_list(list, "To", NULL); + list = procheader_add_header_list(list, "Cc", NULL); + list = procheader_add_header_list(list, "Subject", NULL); + list = procheader_add_header_list(list, "Reply-To", NULL); + list = procheader_add_header_list(list, "List-Id", NULL); + list = procheader_add_header_list(list, "X-ML-Name", NULL); + + procheader_header_list_destroy(rule_list_window.default_hdr_list); + rule_list_window.default_hdr_list = list; + + list = NULL; + path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_HEADER_RC, + NULL); + if ((fp = g_fopen(path, "rb")) != NULL) { + gchar buf[PREFSBUFSIZE]; + + while (fgets(buf, sizeof(buf), fp) != NULL) { + g_strstrip(buf); + if (buf[0] == '\0') continue; + list = procheader_add_header_list(list, buf, NULL); + } + + fclose(fp); + } else + if (ENOENT != errno) FILE_OP_ERROR(path, "fopen"); + g_free(path); + + prefs_filter_set_user_header_list(list); + prefs_filter_set_msg_header_list(msginfo); +} + +void prefs_filter_write_user_header_list(void) +{ + gchar *path; + PrefFile *pfile; + GSList *cur; + + path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_HEADER_RC, + NULL); + + if ((pfile = prefs_file_open(path)) == NULL) { + g_warning("failed to write filter user header list\n"); + g_free(path); + return; + } + g_free(path); + + for (cur = rule_list_window.user_hdr_list; cur != NULL; + cur = cur->next) { + Header *header = (Header *)cur->data; + fputs(header->name, pfile->fp); + fputc('\n', pfile->fp); + } + + if (prefs_file_close(pfile) < 0) + g_warning("failed to write filter user header list\n"); +} + +static void prefs_filter_set_list(void) +{ + FilterRule *rule; + GtkTreeIter iter; + GtkTreeModel *model = GTK_TREE_MODEL(rule_list_window.store); + + g_slist_free(prefs_common.fltlist); + prefs_common.fltlist = NULL; + + if (!gtk_tree_model_get_iter_first(model, &iter)) + return; + + do { + gtk_tree_model_get(model, &iter, COL_FILTER_RULE, &rule, -1); + if (rule) + prefs_common.fltlist = + g_slist_append(prefs_common.fltlist, rule); + } while (gtk_tree_model_iter_next(model, &iter)); +} + +static void prefs_filter_add_cb(void) +{ + FilterRule *rule; + + rule = prefs_filter_edit_open(NULL, NULL, NULL); + gtk_window_present(GTK_WINDOW(rule_list_window.window)); + + if (rule) { + prefs_filter_set_list_row(NULL, rule, TRUE); + prefs_filter_set_list(); + } +} + +static void prefs_filter_edit_cb(void) +{ + GtkTreeIter iter; + FilterRule *rule, *new_rule; + + if (!gtk_tree_selection_get_selected(rule_list_window.selection, + NULL, &iter)) + return; + + gtk_tree_model_get(GTK_TREE_MODEL(rule_list_window.store), &iter, + COL_FILTER_RULE, &rule, -1); + g_return_if_fail(rule != NULL); + + new_rule = prefs_filter_edit_open(rule, NULL, NULL); + gtk_window_present(GTK_WINDOW(rule_list_window.window)); + + if (new_rule) { + prefs_filter_set_list_row(&iter, new_rule, TRUE); + prefs_filter_set_list(); + } +} + +static void prefs_filter_copy_cb(void) +{ + GtkTreeIter iter; + FilterRule *rule, *new_rule; + + if (!gtk_tree_selection_get_selected(rule_list_window.selection, + NULL, &iter)) + return; + + gtk_tree_model_get(GTK_TREE_MODEL(rule_list_window.store), &iter, + COL_FILTER_RULE, &rule, -1); + g_return_if_fail(rule != NULL); + + new_rule = prefs_filter_edit_open(rule, NULL, NULL); + gtk_window_present(GTK_WINDOW(rule_list_window.window)); + + if (new_rule) { + prefs_filter_set_list_row(NULL, new_rule, TRUE); + prefs_filter_set_list(); + } +} + +static void prefs_filter_delete_cb(void) +{ + GtkTreeIter iter; + FilterRule *rule; + gchar buf[BUFFSIZE]; + gboolean valid; + + if (!gtk_tree_selection_get_selected(rule_list_window.selection, + NULL, &iter)) + return; + + gtk_tree_model_get(GTK_TREE_MODEL(rule_list_window.store), &iter, + COL_FILTER_RULE, &rule, -1); + g_return_if_fail(rule != NULL); + + g_snprintf(buf, sizeof(buf), + _("Do you really want to delete the rule '%s'?"), + rule->name ? rule->name : _("(Untitled)")); + if (alertpanel(_("Delete rule"), buf, + GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT) + return; + + valid = gtk_list_store_remove(rule_list_window.store, &iter); + if (valid) + gtk_tree_selection_select_iter(rule_list_window.selection, + &iter); + + prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, rule); + filter_rule_free(rule); + + rule_list_window.modified = TRUE; +} + +static void prefs_filter_top(void) +{ + GtkTreeIter iter; + + if (!gtk_tree_selection_get_selected(rule_list_window.selection, + NULL, &iter)) + return; + + gtk_list_store_move_after(rule_list_window.store, &iter, NULL); +} + +static void prefs_filter_up(void) +{ + GtkTreeModel *model = GTK_TREE_MODEL(rule_list_window.store); + GtkTreeIter iter, prev; + GtkTreePath *path; + + if (!gtk_tree_selection_get_selected(rule_list_window.selection, + NULL, &iter)) + return; + + path = gtk_tree_model_get_path(model, &iter); + if (gtk_tree_path_prev(path)) { + gtk_tree_model_get_iter(model, &prev, path); + gtk_list_store_swap(rule_list_window.store, &iter, &prev); + } + gtk_tree_path_free(path); +} + +static void prefs_filter_down(void) +{ + GtkTreeIter iter, next; + + if (!gtk_tree_selection_get_selected(rule_list_window.selection, + NULL, &iter)) + return; + + next = iter; + if (gtk_tree_model_iter_next(GTK_TREE_MODEL(rule_list_window.store), + &next)) + gtk_list_store_swap(rule_list_window.store, &iter, &next); +} + +static void prefs_filter_bottom(void) +{ + GtkTreeIter iter; + + if (!gtk_tree_selection_get_selected(rule_list_window.selection, + NULL, &iter)) + return; + + gtk_list_store_move_before(rule_list_window.store, &iter, NULL); +} + +static gboolean prefs_filter_select(GtkTreeSelection *selection, + GtkTreeModel *model, GtkTreePath *path, + gboolean cur_selected, gpointer data) +{ + return TRUE; +} + +static void prefs_filter_enable_toggled(GtkCellRenderer *cell, gchar *path_str, + gpointer data) +{ + FilterRule *rule; + GtkTreeIter iter; + GtkTreePath *path; + + path = gtk_tree_path_new_from_string(path_str); + gtk_tree_model_get_iter(GTK_TREE_MODEL(rule_list_window.store), + &iter, path); + gtk_tree_path_free(path); + gtk_tree_model_get(GTK_TREE_MODEL(rule_list_window.store), &iter, + COL_FILTER_RULE, &rule, -1); + + rule->enabled ^= TRUE; + + gtk_list_store_set(rule_list_window.store, &iter, + COL_ENABLED, rule->enabled, -1); + rule_list_window.modified = TRUE; +} + +static void prefs_filter_row_activated(GtkTreeView *treeview, GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer data) +{ + gtk_button_clicked(GTK_BUTTON(rule_list_window.edit_btn)); +} + +static void prefs_filter_row_reordered(GtkTreeModel *model, + GtkTreePath *path, GtkTreeIter *iter, + gpointer data, gpointer user_data) +{ + GtkTreeIter iter_; + GtkTreePath *path_; + + if (!gtk_tree_selection_get_selected(rule_list_window.selection, + NULL, &iter_)) + return; + path_ = gtk_tree_model_get_path + (GTK_TREE_MODEL(rule_list_window.store), &iter_); + gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(rule_list_window.treeview), + path_, NULL, FALSE, 0.0, 0.0); + gtk_tree_path_free(path_); + rule_list_window.modified = TRUE; +} + +static void prefs_filter_row_inserted(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer user_data) +{ + rule_list_window.modified = TRUE; +} + +static gint prefs_filter_deleted(GtkWidget *widget, GdkEventAny *event, + gpointer data) +{ + prefs_filter_close(); + return TRUE; +} + +static gboolean prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event, + gpointer data) +{ + if (rule_list_window.on_init) + return TRUE; + + if (event && event->keyval == GDK_Escape) + prefs_filter_close(); + return FALSE; +} + +static void prefs_filter_close(void) +{ + if (rule_list_window.on_init) + return; + + prefs_filter_set_msg_header_list(NULL); + if (rule_list_window.modified) { + prefs_filter_set_list(); + filter_write_config(); + } + gtk_widget_hide(rule_list_window.window); + gtk_list_store_clear(rule_list_window.store); + main_window_popup(main_window_get()); + inc_unlock(); +} -- cgit v1.3