From b9ca7b1ef5cd1f96ae6e28ae78d12c1e3258c23f Mon Sep 17 00:00:00 2001 From: hiro Date: Wed, 12 Jan 2005 11:22:08 +0000 Subject: Initial import of Sylpheed (GTK2 version). git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@1 ee746299-78ed-0310-b773-934348b2243d --- src/prefs_filter.c | 841 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 841 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 00000000..041aa4bf --- /dev/null +++ b/src/prefs_filter.c @@ -0,0 +1,841 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2004 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 "intl.h" +#include "main.h" +#include "prefs.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" + +static struct FilterRuleListWindow { + GtkWidget *window; + + GtkWidget *clist; + + 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; +} rule_list_window; + +static GdkPixmap *markxpm; +static GdkBitmap *markxpmmask; + +static void prefs_filter_create (void); + +//static void prefs_filter_read_old_config (void); + +static void prefs_filter_set_dialog (void); +static void prefs_filter_set_list_row (gint row, + FilterRule *rule, + gboolean move_view); + +static void prefs_filter_set_header_list (MsgInfo *msginfo); + +static void prefs_filter_write_user_header_list (void); + +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 void prefs_filter_select (GtkCList *clist, + gint row, + gint column, + GdkEvent *event); +static void prefs_filter_row_move (GtkCList *clist, + gint source_row, + gint dest_row); + +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) +{ + inc_lock(); + + 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); + + if (msginfo) { + FilterRule *rule; + + rule = prefs_filter_edit_open(NULL, header); + + if (rule) { + prefs_filter_set_list_row(-1, rule, TRUE); + prefs_filter_set_list(); + } + } +} + +static void prefs_filter_create(void) +{ + GtkWidget *window; + GtkWidget *vbox; + GtkWidget *close_btn; + GtkWidget *confirm_area; + + GtkWidget *hbox; + GtkWidget *scrolledwin; + GtkWidget *clist; + + 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; + + gchar *title[2]; + + 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_usize(window, 540, 360); + 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_button_set_create(&confirm_area, &close_btn, _("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 setting")); + 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_usize(scrolledwin, -1, 150); + 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); + + title[0] = _("Enabled"); + title[1] = _("Name"); + clist = gtk_clist_new_with_titles(2, title); + gtk_widget_show(clist); + gtk_container_add (GTK_CONTAINER(scrolledwin), clist); + gtk_clist_set_column_width(GTK_CLIST(clist), 0, 64); + gtk_clist_set_column_justification(GTK_CLIST(clist), 0, + GTK_JUSTIFY_CENTER); + gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_BROWSE); + GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[0].button, + GTK_CAN_FOCUS); + GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[1].button, + GTK_CAN_FOCUS); + g_signal_connect(G_OBJECT(clist), "select_row", + G_CALLBACK(prefs_filter_select), NULL); + g_signal_connect_after(G_OBJECT(clist), "row_move", + G_CALLBACK(prefs_filter_row_move), 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_with_label(_("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_with_label(_("Up")); + 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_with_label(_("Down")); + 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_with_label(_("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_with_label(_("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); + + edit_btn = gtk_button_new_with_label(_("Edit")); + 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_with_label(_("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_with_label(_(" 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); + + stock_pixmap_gdk(clist, STOCK_PIXMAP_MARK, &markxpm, &markxpmmask); + + rule_list_window.window = window; + rule_list_window.close_btn = close_btn; + + rule_list_window.clist = clist; + + 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; +} + +void prefs_filter_read_config(void) +{ + gchar *rcpath; + GNode *node; + FilterRule *rule; + + debug_print("Reading filter configuration...\n"); + + /* remove all previous filter list */ + while (prefs_common.fltlist != NULL) { + rule = (FilterRule *)prefs_common.fltlist->data; + filter_rule_free(rule); + prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, + rule); + } + +#warning FIXME_GTK2 + rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_LIST, + NULL); + if (!is_file_exist(rcpath)) { + //prefs_filter_read_old_config(); + g_free(rcpath); + return; + } + + node = xml_parse_file(rcpath); + if (!node) { + g_warning("Can't parse %s\n", rcpath); + g_free(rcpath); + return; + } + g_free(rcpath); + + prefs_common.fltlist = filter_xml_node_to_filter_list(node); + + xml_free_tree(node); +} + +#if 0 +static void prefs_filter_read_old_config(void) +{ + gchar *rcpath; + FILE *fp; + gchar buf[PREFSBUFSIZE]; + FilterRule *rule; + + debug_print("Reading old filter configuration...\n"); + + rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL); + if ((fp = fopen(rcpath, "rb")) == NULL) { + if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen"); + g_free(rcpath); + return; + } + g_free(rcpath); + + while (fgets(buf, sizeof(buf), fp) != NULL) { + g_strchomp(buf); + rule = filter_read_str(buf); + if (rule) { + prefs_common.fltlist = + g_slist_append(prefs_common.fltlist, rule); + } + } + + fclose(fp); +} +#endif + +void prefs_filter_write_config(void) +{ + filter_write_config(prefs_common.fltlist); +} + +void prefs_filter_rename_path(const gchar *old_path, const gchar *new_path) +{ + GSList *cur; + + g_return_if_fail(old_path != NULL); + g_return_if_fail(new_path != NULL); + + for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) { + FilterRule *rule = (FilterRule *)cur->data; + filter_rule_rename_dest_path(rule, old_path, new_path); + } + + filter_write_config(prefs_common.fltlist); +} + +void prefs_filter_delete_path(const gchar *path) +{ + GSList *cur; + GSList *next; + + g_return_if_fail(path != NULL); + + for (cur = prefs_common.fltlist; cur != NULL; cur = next) { + FilterRule *rule = (FilterRule *)cur->data; + next = cur->next; + + filter_rule_delete_action_by_dest_path(rule, path); + if (!rule->action_list) { + prefs_common.fltlist = + g_slist_remove(prefs_common.fltlist, rule); + filter_rule_free(rule); + } + } + + filter_write_config(prefs_common.fltlist); +} + +static void prefs_filter_set_dialog(void) +{ + GtkCList *clist = GTK_CLIST(rule_list_window.clist); + GSList *cur; + + gtk_clist_freeze(clist); + gtk_clist_clear(clist); + + for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) { + FilterRule *rule = (FilterRule *)cur->data; + prefs_filter_set_list_row(-1, rule, FALSE); + } + + gtk_clist_thaw(clist); +} + +static void prefs_filter_set_list_row(gint row, FilterRule *rule, + gboolean move_view) +{ + GtkCList *clist = GTK_CLIST(rule_list_window.clist); + gchar *cond_str[2] = {"", NULL}; + + if (!rule) + rule = gtk_clist_get_row_data(clist, row); + + g_return_if_fail(rule != NULL); + + if (rule->name && *rule->name) + cond_str[1] = g_strdup(rule->name); + else { + cond_str[1] = filter_get_str(rule); + } + + if (row < 0) + row = gtk_clist_append(clist, cond_str); + else { + FilterRule *prev_rule; + + prev_rule = gtk_clist_get_row_data(clist, row); + if (rule == prev_rule) + gtk_clist_set_text(clist, row, 1, cond_str[1]); + else if (prev_rule) { + gtk_clist_set_text(clist, row, 1, cond_str[1]); + filter_rule_free(prev_rule); + } else + row = gtk_clist_append(clist, cond_str); + } + + if (rule->enabled) + gtk_clist_set_pixmap(clist, row, 0, markxpm, markxpmmask); + else + gtk_clist_set_text(clist, row, 0, ""); + + gtk_clist_set_row_data(clist, row, rule); + g_free(cond_str[1]); + + if (move_view && + gtk_clist_row_is_visible(clist, row) != GTK_VISIBILITY_FULL) + gtk_clist_moveto(clist, row, -1, 0.5, 0.0); +} + +#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 = g_slist_append(list, header); \ + } \ + } + +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_strcasecmp(header->name, "Received") || + !g_strcasecmp(header->name, "Mime-Version") || + !g_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); + } + } +} + +static 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 = 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); +} + +static 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) +{ + gint row = 0; + FilterRule *rule; + + g_slist_free(prefs_common.fltlist); + prefs_common.fltlist = NULL; + + while ((rule = gtk_clist_get_row_data + (GTK_CLIST(rule_list_window.clist), row)) != NULL) { + prefs_common.fltlist = g_slist_append(prefs_common.fltlist, + rule); + row++; + } +} + +static void prefs_filter_add_cb(void) +{ + FilterRule *rule; + + rule = prefs_filter_edit_open(NULL, NULL); + + if (rule) { + prefs_filter_set_list_row(-1, rule, TRUE); + prefs_filter_set_list(); + } +} + +static void prefs_filter_edit_cb(void) +{ + GtkCList *clist = GTK_CLIST(rule_list_window.clist); + FilterRule *rule, *new_rule; + gint row; + + if (!clist->selection) return; + + row = GPOINTER_TO_INT(clist->selection->data); + + rule = gtk_clist_get_row_data(clist, row); + g_return_if_fail(rule != NULL); + + new_rule = prefs_filter_edit_open(rule, NULL); + + if (new_rule) { + prefs_filter_set_list_row(row, new_rule, TRUE); + prefs_filter_set_list(); + } +} + +static void prefs_filter_copy_cb(void) +{ + GtkCList *clist = GTK_CLIST(rule_list_window.clist); + FilterRule *rule, *new_rule; + gint row; + + if (!clist->selection) return; + + row = GPOINTER_TO_INT(clist->selection->data); + + rule = gtk_clist_get_row_data(clist, row); + g_return_if_fail(rule != NULL); + + new_rule = prefs_filter_edit_open(rule, NULL); + + if (new_rule) { + prefs_filter_set_list_row(-1, new_rule, TRUE); + prefs_filter_set_list(); + } +} + +static void prefs_filter_delete_cb(void) +{ + GtkCList *clist = GTK_CLIST(rule_list_window.clist); + FilterRule *rule; + gint row; + + if (!clist->selection) return; + row = GPOINTER_TO_INT(clist->selection->data); + + if (alertpanel(_("Delete rule"), + _("Do you really want to delete this rule?"), + _("Yes"), _("No"), NULL) != G_ALERTDEFAULT) + return; + + rule = gtk_clist_get_row_data(clist, row); + filter_rule_free(rule); + gtk_clist_remove(clist, row); + prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, rule); + if (!clist->selection) + gtk_clist_select_row(clist, row - 1, -1); +} + +static void prefs_filter_top(void) +{ + GtkCList *clist = GTK_CLIST(rule_list_window.clist); + gint row; + + if (!clist->selection) return; + + row = GPOINTER_TO_INT(clist->selection->data); + if (row > 0) + gtk_clist_row_move(clist, row, 0); +} + +static void prefs_filter_up(void) +{ + GtkCList *clist = GTK_CLIST(rule_list_window.clist); + gint row; + + if (!clist->selection) return; + + row = GPOINTER_TO_INT(clist->selection->data); + if (row > 0) + gtk_clist_row_move(clist, row, row - 1); +} + +static void prefs_filter_down(void) +{ + GtkCList *clist = GTK_CLIST(rule_list_window.clist); + gint row; + + if (!clist->selection) return; + + row = GPOINTER_TO_INT(clist->selection->data); + if (row < clist->rows - 1) + gtk_clist_row_move(clist, row, row + 1); +} + +static void prefs_filter_bottom(void) +{ + GtkCList *clist = GTK_CLIST(rule_list_window.clist); + gint row; + + if (!clist->selection) return; + + row = GPOINTER_TO_INT(clist->selection->data); + if (row < clist->rows - 1) + gtk_clist_row_move(clist, row, clist->rows - 1); +} + +static void prefs_filter_select(GtkCList *clist, gint row, gint column, + GdkEvent *event) +{ + if (event && event->type == GDK_2BUTTON_PRESS) { + prefs_filter_edit_cb(); + return; + } + + if (column == 0) { + FilterRule *rule; + rule = gtk_clist_get_row_data(clist, row); + rule->enabled ^= TRUE; + prefs_filter_set_list_row(row, rule, FALSE); + } +} + +static void prefs_filter_row_move(GtkCList *clist, gint source_row, + gint dest_row) +{ + prefs_filter_set_list(); + if (gtk_clist_row_is_visible(clist, dest_row) != GTK_VISIBILITY_FULL) + gtk_clist_moveto(clist, dest_row, -1, 0.5, 0.0); +} + +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 (event && event->keyval == GDK_Escape) + prefs_filter_close(); + return FALSE; +} + +static void prefs_filter_close(void) +{ + prefs_filter_set_msg_header_list(NULL); + prefs_filter_write_user_header_list(); + filter_write_config(prefs_common.fltlist); + gtk_widget_hide(rule_list_window.window); + gtk_clist_clear(GTK_CLIST(rule_list_window.clist)); + inc_unlock(); +} -- cgit v1.2.3