2007-03-05 [wwp] 2.8.0cvs19
authorTristan Chabredier <wwp@claws-mail.org>
Mon, 5 Mar 2007 10:37:37 +0000 (10:37 +0000)
committerTristan Chabredier <wwp@claws-mail.org>
Mon, 5 Mar 2007 10:37:37 +0000 (10:37 +0000)
* src/matcher_parser_parse.y
* src/prefs_filtering_action.c
* src/matcher.c
* src/matcher.h
* src/filtering.c
* src/filtering.h
Add new 'add_to_addressbook' filtering/processing action.

ChangeLog
PATCHSETS
configure.ac
src/filtering.c
src/filtering.h
src/matcher.c
src/matcher.h
src/matcher_parser_parse.y
src/prefs_filtering_action.c

index f4268ec..e20e052 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-03-05 [wwp]       2.8.0cvs19
+
+       * src/matcher_parser_parse.y
+       * src/prefs_filtering_action.c
+       * src/matcher.c
+       * src/matcher.h
+       * src/filtering.c
+       * src/filtering.h
+               Add new 'add_to_addressbook' filtering/processing action.
+
 2007-03-05 [wwp]       2.8.0cvs18
 
        * src/filtering.c
index ba6b6da..e179d29 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.179.2.157 -r 1.179.2.158 src/imap.c;  ) > 2.8.0cvs16.patchset
 ( cvs diff -u -r 1.60.2.25 -r 1.60.2.26 src/filtering.c;  cvs diff -u -r 1.75.2.36 -r 1.75.2.37 src/matcher.c;  cvs diff -u -r 1.39.2.10 -r 1.39.2.11 src/matcher.h;  cvs diff -u -r 1.25.2.25 -r 1.25.2.26 src/matcher_parser_parse.y;  cvs diff -u -r 1.1.4.34 -r 1.1.4.35 src/prefs_filtering_action.c;  ) > 2.8.0cvs17.patchset
 ( cvs diff -u -r 1.60.2.26 -r 1.60.2.27 src/filtering.c;  ) > 2.8.0cvs18.patchset
+( cvs diff -u -r 1.25.2.26 -r 1.25.2.27 src/matcher_parser_parse.y;  cvs diff -u -r 1.1.4.35 -r 1.1.4.36 src/prefs_filtering_action.c;  cvs diff -u -r 1.75.2.37 -r 1.75.2.38 src/matcher.c;  cvs diff -u -r 1.39.2.11 -r 1.39.2.12 src/matcher.h;  cvs diff -u -r 1.60.2.27 -r 1.60.2.28 src/filtering.c;  cvs diff -u -r 1.21.2.11 -r 1.21.2.12 src/filtering.h;  ) > 2.8.0cvs19.patchset
index 55a5e03..c8c6510 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=8
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=18
+EXTRA_VERSION=19
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index cc90b64..75c2584 100644 (file)
@@ -34,6 +34,8 @@
 #include "prefs_gtk.h"
 #include "compose.h"
 #include "prefs_common.h"
+#include "addrbook.h"
+#include "addr_compl.h"
 
 #define PREFSBUFSIZE           1024
 
@@ -58,7 +60,7 @@ static inline gint strlen_with_check(const gchar *expr, gint fline, const gchar
 
 FilteringAction * filteringaction_new(int type, int account_id,
                                      gchar * destination,
-                                     gint labelcolor, gint score)
+                                     gint labelcolor, gint score, gchar * header)
 {
        FilteringAction * action;
 
@@ -71,6 +73,11 @@ FilteringAction * filteringaction_new(int type, int account_id,
        } else {
                action->destination       = NULL;
        }
+       if (header) {
+               action->header    = g_strdup(header);
+       } else {
+               action->header       = NULL;
+       }
        action->labelcolor = labelcolor;        
         action->score = score;
        return action;
@@ -79,6 +86,7 @@ FilteringAction * filteringaction_new(int type, int account_id,
 void filteringaction_free(FilteringAction * action)
 {
        g_return_if_fail(action);
+       g_free(action->header);
        g_free(action->destination);
        g_free(action);
 }
@@ -402,6 +410,71 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                 procmsg_msginfo_set_flags(info, MSG_IGNORE_THREAD, 0);
                 return TRUE;
 
+       case MATCHACTION_ADD_TO_ADDRESSBOOK:
+               {
+                       AddressDataSource *book = NULL;
+                       AddressBookFile *abf = NULL;
+                       ItemFolder *folder = NULL;
+                       gchar buf[BUFFSIZE];
+                       Header *header;
+                       gint errors = 0;
+
+                       if (!addressbook_peek_folder_exists(action->destination, &book, &folder)) {
+                               g_warning("addressbook folder not found '%s'\n", action->destination);
+                               return FALSE;
+                       }
+                       if (!book) {
+                               g_warning("addressbook_peek_folder_exists returned NULL book\n");
+                               return FALSE;
+                       }
+
+                       abf = book->rawDataSource;
+
+                       /* get the header */
+                       procheader_get_header_from_msginfo(info, buf, sizeof(buf), action->header);
+                       header = procheader_parse_header(buf);
+
+                       /* add all addresses that are not already in */
+                       if (header && *header->body && (*header->body != '\0')) {
+                               GSList *address_list = NULL;
+                               GSList *walk = NULL;
+                               gchar *path = NULL;
+
+                               if (action->destination == NULL ||
+                                               strcasecmp(action->destination, _("Any")) == 0 ||
+                                               *(action->destination) == '\0')
+                                       path = NULL;
+                               else
+                                       path = action->destination;
+                               start_address_completion(path);
+
+                               address_list = address_list_append(address_list, header->body);
+                               for (walk = address_list; walk != NULL; walk = walk->next) {
+                                       gchar *stripped_addr = g_strdup(walk->data);
+                                       extract_address(stripped_addr);
+
+                                       if (complete_address(walk->data) <= 1) {
+                                               debug_print("adding address '%s' to addressbook '%s'\n",
+                                                               stripped_addr, action->destination);
+                                               if (!addrbook_add_contact(abf, folder, stripped_addr, stripped_addr, NULL)) {
+                                                       g_warning("contact could not been added\n");
+                                                       errors++;
+                                               }
+                                       } else {
+                                               debug_print("address '%s' already found in addressbook '%s', skipping\n",
+                                                               stripped_addr, action->destination);
+                                       }
+                                       g_free(stripped_addr);
+                               }
+
+                               g_slist_free(address_list);
+                               end_address_completion();
+                       } else {
+                               g_warning("header '%s' not set or empty\n", action->header);
+                       }
+                       return (errors == 0);
+               }
+
        default:
                break;
        }
@@ -560,6 +633,7 @@ gchar *filteringaction_to_string(gchar *dest, gint destlen, FilteringAction *act
 {
        const gchar *command_str;
        gchar * quoted_dest;
+       gchar * quoted_header;
        
        command_str = get_matchparser_tab_str(action->type);
 
@@ -607,6 +681,14 @@ gchar *filteringaction_to_string(gchar *dest, gint destlen, FilteringAction *act
                g_snprintf(dest, destlen, "%s %d", command_str, action->score);
                return dest;  
 
+       case MATCHACTION_ADD_TO_ADDRESSBOOK:
+               quoted_header = matcher_quote_str(action->header);
+               quoted_dest = matcher_quote_str(action->destination);
+               g_snprintf(dest, destlen, "%s \"%s\" \"%s\"", command_str, quoted_header, quoted_dest);
+               g_free(quoted_dest);
+               g_free(quoted_header);
+               return dest;
+
        default:
                return NULL;
        }
index 67909e2..c5b6538 100644 (file)
@@ -31,6 +31,7 @@ struct _FilteringAction {
        gchar  *destination;
        gint    labelcolor;
        gint    score;
+       gchar  *header;
 };
 
 typedef struct _FilteringAction FilteringAction;
@@ -56,7 +57,7 @@ enum {
 
 FilteringAction * filteringaction_new(int type, int account_id,
                                      gchar * destination,
-                                      gint labelcolor, gint score);
+                                      gint labelcolor, gint score, gchar *header);
 void filteringaction_free(FilteringAction *action);
 FilteringAction * filteringaction_parse(gchar **str);
 gboolean filteringaction_apply_action_list (GSList *action_list, MsgInfo *info);
index cf73a5b..18b32b9 100644 (file)
@@ -153,6 +153,7 @@ static const MatchParser matchparser_tab[] = {
        {MATCHACTION_STOP, "stop"},
        {MATCHACTION_HIDE, "hide"},
        {MATCHACTION_IGNORE, "ignore"},
+       {MATCHACTION_ADD_TO_ADDRESSBOOK, "add_to_addressbook"}
 };
 
 enum {
index 55998b3..0f22d84 100644 (file)
@@ -132,6 +132,7 @@ enum {
        MA_(STOP),
        MA_(HIDE),
        MA_(IGNORE),
+       MA_(ADD_TO_ADDRESSBOOK),
        /* boolean operations */
        MB_(OR),
        MB_(AND)
index 69184e9..0e1c04d 100644 (file)
@@ -333,6 +333,7 @@ int matcher_parserwrap(void)
 %token MATCHER_COLORLABEL MATCHER_NOT_COLORLABEL
 %token MATCHER_IGNORE_THREAD MATCHER_NOT_IGNORE_THREAD
 %token MATCHER_CHANGE_SCORE MATCHER_SET_SCORE
+%token MATCHER_ADD_TO_ADDRESSBOOK
 %token MATCHER_STOP MATCHER_HIDE MATCHER_IGNORE
 %token MATCHER_SPAM MATCHER_NOT_SPAM
 
@@ -1104,7 +1105,7 @@ MATCHER_EXECUTE MATCHER_STRING
 
        action_type = MATCHACTION_EXECUTE;
        cmd = $2;
-       action = filteringaction_new(action_type, 0, cmd, 0, 0);
+       action = filteringaction_new(action_type, 0, cmd, 0, 0, NULL);
 }
 | MATCHER_MOVE MATCHER_STRING
 {
@@ -1113,7 +1114,7 @@ MATCHER_EXECUTE MATCHER_STRING
 
        action_type = MATCHACTION_MOVE;
        destination = $2;
-       action = filteringaction_new(action_type, 0, destination, 0, 0);
+       action = filteringaction_new(action_type, 0, destination, 0, 0, NULL);
 }
 | MATCHER_COPY MATCHER_STRING
 {
@@ -1122,56 +1123,56 @@ MATCHER_EXECUTE MATCHER_STRING
 
        action_type = MATCHACTION_COPY;
        destination = $2;
-       action = filteringaction_new(action_type, 0, destination, 0, 0);
+       action = filteringaction_new(action_type, 0, destination, 0, 0, NULL);
 }
 | MATCHER_DELETE
 {
        gint action_type = 0;
 
        action_type = MATCHACTION_DELETE;
-       action = filteringaction_new(action_type, 0, NULL, 0, 0);
+       action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
 }
 | MATCHER_MARK
 {
        gint action_type = 0;
 
        action_type = MATCHACTION_MARK;
-       action = filteringaction_new(action_type, 0, NULL, 0, 0);
+       action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
 }
 | MATCHER_UNMARK
 {
        gint action_type = 0;
 
        action_type = MATCHACTION_UNMARK;
-       action = filteringaction_new(action_type, 0, NULL, 0, 0);
+       action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
 }
 | MATCHER_LOCK
 {
        gint action_type = 0;
 
        action_type = MATCHACTION_LOCK;
-       action = filteringaction_new(action_type, 0, NULL, 0, 0);
+       action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
 }
 | MATCHER_UNLOCK
 {
        gint action_type = 0;
 
        action_type = MATCHACTION_UNLOCK;
-       action = filteringaction_new(action_type, 0, NULL, 0, 0);
+       action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
 }
 | MATCHER_MARK_AS_READ
 {
        gint action_type = 0;
 
        action_type = MATCHACTION_MARK_AS_READ;
-       action = filteringaction_new(action_type, 0, NULL, 0, 0);
+       action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
 }
 | MATCHER_MARK_AS_UNREAD
 {
        gint action_type = 0;
 
        action_type = MATCHACTION_MARK_AS_UNREAD;
-       action = filteringaction_new(action_type, 0, NULL, 0, 0);
+       action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
 }
 | MATCHER_MARK_AS_SPAM
 {
@@ -1197,7 +1198,7 @@ MATCHER_EXECUTE MATCHER_STRING
        account_id = strtol($2, NULL, 10);
        destination = $3;
        action = filteringaction_new(action_type,
-            account_id, destination, 0, 0);
+            account_id, destination, 0, 0, NULL);
 }
 | MATCHER_FORWARD_AS_ATTACHMENT MATCHER_INTEGER MATCHER_STRING
 {
@@ -1209,7 +1210,7 @@ MATCHER_EXECUTE MATCHER_STRING
        account_id = strtol($2, NULL, 10);
        destination = $3;
        action = filteringaction_new(action_type,
-            account_id, destination, 0, 0);
+            account_id, destination, 0, 0, NULL);
 }
 | MATCHER_REDIRECT MATCHER_INTEGER MATCHER_STRING
 {
@@ -1221,7 +1222,7 @@ MATCHER_EXECUTE MATCHER_STRING
        account_id = strtol($2, NULL, 10);
        destination = $3;
        action = filteringaction_new(action_type,
-            account_id, destination, 0, 0);
+            account_id, destination, 0, 0, NULL);
 }
 | MATCHER_COLOR MATCHER_INTEGER
 {
@@ -1230,7 +1231,7 @@ MATCHER_EXECUTE MATCHER_STRING
 
        action_type = MATCHACTION_COLOR;
        color = strtol($2, NULL, 10);
-       action = filteringaction_new(action_type, 0, NULL, color, 0);
+       action = filteringaction_new(action_type, 0, NULL, color, 0, NULL);
 }
 | MATCHER_CHANGE_SCORE MATCHER_INTEGER
 {
@@ -1238,7 +1239,7 @@ MATCHER_EXECUTE MATCHER_STRING
         
         score = strtol($2, NULL, 10);
        action = filteringaction_new(MATCHACTION_CHANGE_SCORE, 0,
-                                    NULL, 0, score);
+                                    NULL, 0, score, NULL);
 }
 /* backward compatibility */
 | MATCHER_SCORE MATCHER_INTEGER
@@ -1247,7 +1248,7 @@ MATCHER_EXECUTE MATCHER_STRING
         
         score = strtol($2, NULL, 10);
        action = filteringaction_new(MATCHACTION_CHANGE_SCORE, 0,
-                                    NULL, 0, score);
+                                    NULL, 0, score, NULL);
 }
 | MATCHER_SET_SCORE MATCHER_INTEGER
 {
@@ -1255,18 +1256,31 @@ MATCHER_EXECUTE MATCHER_STRING
         
         score = strtol($2, NULL, 10);
        action = filteringaction_new(MATCHACTION_SET_SCORE, 0,
-                                    NULL, 0, score);
+                                    NULL, 0, score, NULL);
 }
 | MATCHER_HIDE
 {
-       action = filteringaction_new(MATCHACTION_HIDE, 0, NULL, 0, 0);
+       action = filteringaction_new(MATCHACTION_HIDE, 0, NULL, 0, 0, NULL);
 }
 | MATCHER_IGNORE
 {
-       action = filteringaction_new(MATCHACTION_IGNORE, 0, NULL, 0, 0);
+       action = filteringaction_new(MATCHACTION_IGNORE, 0, NULL, 0, 0, NULL);
+}
+| MATCHER_ADD_TO_ADDRESSBOOK MATCHER_STRING
+{
+       header = g_strdup($2);
+} MATCHER_STRING
+{
+       gchar *addressbook = NULL;
+       gint action_type = 0;
+
+       action_type = MATCHACTION_ADD_TO_ADDRESSBOOK;
+       addressbook = $2;
+       action = filteringaction_new(action_type, 0, addressbook, 0, 0, header);
+       g_free(header);
 }
 | MATCHER_STOP
 {
-       action = filteringaction_new(MATCHACTION_STOP, 0, NULL, 0, 0);
+       action = filteringaction_new(MATCHACTION_STOP, 0, NULL, 0, 0, NULL);
 }
 ;
index f627edc..45e765a 100644 (file)
@@ -74,6 +74,7 @@ static void prefs_filtering_action_type_selection_changed(GtkList *list,
 static void prefs_filtering_action_type_select(GtkList *list,
     GtkWidget *widget, gpointer user_data);
 static void prefs_filtering_action_select_dest(void);
+static void prefs_filtering_action_select_addressbook(void);
 static void prefs_filtering_action_up(void);
 static void prefs_filtering_action_down(void);
 static void prefs_filtering_action_set_dialog(GSList *action_list);
@@ -115,6 +116,11 @@ static struct FilteringAction_ {
        GtkWidget *color_label;
        GtkWidget *color_optmenu;
        GtkWidget *score_label;
+       GtkWidget *header_label;
+       GtkWidget *header_combo;
+       GtkWidget *header_entry;
+       GtkWidget *addressbook_label;
+       GtkWidget *addressbook_btn;
 
        gint current_action;
 } filtering_action;
@@ -141,6 +147,7 @@ typedef enum Action_ {
        ACTION_SET_SCORE,
        ACTION_HIDE,
        ACTION_IGNORE,
+       ACTION_ADD_TO_ADDRESSBOOK,
        ACTION_STOP,
        /* add other action constants */
 } Action;
@@ -169,6 +176,7 @@ static struct {
        { N_("Set score"),              ACTION_SET_SCORE},
        { N_("Hide"),                   ACTION_HIDE     },
        { N_("Ignore thread"),          ACTION_IGNORE   },
+       { N_("Add to address book"),    ACTION_ADD_TO_ADDRESSBOOK       },
        { N_("Stop filter"),            ACTION_STOP     },
 };
 
@@ -272,6 +280,11 @@ static void prefs_filtering_action_create(void)
        GtkWidget *color_label;
        GtkWidget *account_label;
        GtkWidget *account_combo;
+       GtkWidget *header_label;
+       GtkWidget *header_combo;
+       GtkWidget *header_entry;
+       GtkWidget *addressbook_label;
+       GtkWidget *addressbook_btn;
        GtkWidget *dest_entry;
        GtkWidget *dest_btn;
         GList * cur;
@@ -417,6 +430,24 @@ static void prefs_filtering_action_create(void)
        gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(account_combo)->entry),
                               FALSE);
 
+       /* header */
+
+       header_label = gtk_label_new(_("Header name"));
+       gtk_widget_show(header_label);
+       gtk_misc_set_alignment(GTK_MISC(header_label), 0, 0.5);
+       gtk_box_pack_start (GTK_BOX (hbox1), header_label, FALSE, FALSE, 0);
+
+       header_combo = gtk_combo_new();
+       gtk_widget_show(header_combo);
+       gtk_widget_set_size_request(header_combo, 120, -1);
+       gtkut_combo_set_items(GTK_COMBO (header_combo),
+                             "From", "To", "Cc", "Reply-To", "Sender",
+                             NULL);
+       gtk_box_pack_start (GTK_BOX (hbox1), header_combo,
+                           TRUE, TRUE, 0);
+       header_entry = GTK_COMBO(header_combo)->entry;
+       gtk_entry_set_editable(GTK_ENTRY(header_entry), TRUE);
+
        /* destination */
 
        hbox1 = gtk_hbox_new (FALSE, VSPACING);
@@ -449,6 +480,11 @@ static void prefs_filtering_action_create(void)
        gtk_misc_set_alignment (GTK_MISC (score_label), 0, 0.5);
        gtk_box_pack_start (GTK_BOX (hbox1), score_label, FALSE, FALSE, 0);
 
+       addressbook_label = gtk_label_new (_("Book/folder"));
+       gtk_widget_show(addressbook_label);
+       gtk_misc_set_alignment(GTK_MISC(addressbook_label), 0, 0.5);
+       gtk_box_pack_start(GTK_BOX(hbox1), addressbook_label, FALSE, FALSE, 0);
+
        dest_entry = gtk_entry_new ();
        gtk_widget_set_size_request (dest_entry, 150, -1);
        gtk_widget_show (dest_entry);
@@ -466,6 +502,13 @@ static void prefs_filtering_action_create(void)
                          G_CALLBACK(prefs_filtering_action_select_dest),
                          NULL);
 
+       addressbook_btn = gtk_button_new_with_label (_("Select ..."));
+       gtk_widget_show (addressbook_btn);
+       gtk_box_pack_start (GTK_BOX (hbox1), addressbook_btn, FALSE, FALSE, 0);
+       g_signal_connect (G_OBJECT (addressbook_btn), "clicked",
+                         G_CALLBACK(prefs_filtering_action_select_addressbook),
+                         NULL);
+
 #if GTK_CHECK_VERSION(2, 8, 0)
        exec_btn = gtk_button_new_from_stock(GTK_STOCK_INFO);
 #else
@@ -571,6 +614,11 @@ static void prefs_filtering_action_create(void)
        filtering_action.color_label   = color_label;
        filtering_action.color_optmenu = color_optmenu;
        filtering_action.score_label = score_label;
+       filtering_action.header_label = header_label;
+       filtering_action.header_combo = header_combo;
+       filtering_action.header_entry = header_entry;
+       filtering_action.addressbook_label = addressbook_label;
+       filtering_action.addressbook_btn = addressbook_btn;
        filtering_action.ok_btn = ok_btn;
        filtering_action.action_list_view = action_list_view;
 }
@@ -765,6 +813,8 @@ static gint prefs_filtering_action_get_matching_from_action(Action action_id)
                return MATCHACTION_CHANGE_SCORE;
        case ACTION_SET_SCORE:
                return MATCHACTION_SET_SCORE;
+       case ACTION_ADD_TO_ADDRESSBOOK:
+               return MATCHACTION_ADD_TO_ADDRESSBOOK;
        default:
                return -1;
        }
@@ -789,6 +839,7 @@ static FilteringAction * prefs_filtering_action_dialog_to_action(gboolean alert)
         FilteringAction * action;
         gchar * score_str = NULL;
         gint score;
+       gchar * header = NULL;
         
        action_id = get_sel_from_list(GTK_LIST(filtering_action.action_type_list));
        action_type = prefs_filtering_action_get_matching_from_action(action_id);
@@ -838,6 +889,22 @@ static FilteringAction * prefs_filtering_action_dialog_to_action(gboolean alert)
                }
                 score = strtol(score_str, NULL, 10);
                 break;
+       case ACTION_ADD_TO_ADDRESSBOOK:
+               header = gtk_editable_get_chars(GTK_EDITABLE(filtering_action.header_entry), 0, -1);
+               if (*header == '\0') {
+                       if (alert)
+                                alertpanel_error(_("Header is not set."));
+                       g_free(header);
+                       return NULL;
+               }
+               destination = gtk_editable_get_chars(GTK_EDITABLE(filtering_action.dest_entry), 0, -1);
+               if (*destination == '\0') {
+                       if (alert)
+                                alertpanel_error(_("Target addressbook/folder is not set."));
+                       g_free(destination);
+                       return NULL;
+               }
+               break;
        case ACTION_STOP:
        case ACTION_HIDE:
        case ACTION_IGNORE:
@@ -853,9 +920,8 @@ static FilteringAction * prefs_filtering_action_dialog_to_action(gboolean alert)
        default:
                break;
        }
-       
        action = filteringaction_new(action_type, account_id,
-            destination, labelcolor, score);
+            destination, labelcolor, score, header);
        
        g_free(destination);
        g_free(score_str);
@@ -1139,6 +1205,20 @@ static void prefs_filtering_action_select_dest(void)
        g_free(path);
 }
 
+static void prefs_filtering_action_select_addressbook(void)
+{
+       gchar *folderpath = NULL;
+       gchar *prev = NULL;
+       gboolean ret = FALSE;
+
+       prev = g_strdup(gtk_editable_get_chars(GTK_EDITABLE(filtering_action.dest_entry), 0, -1));
+       folderpath = prev;
+       ret = addressbook_folder_selection(&folderpath);
+       if ( ret != FALSE && folderpath != NULL)
+               gtk_entry_set_text(GTK_ENTRY(filtering_action.dest_entry), folderpath);
+       g_free(prev);
+}
+
 static void prefs_filtering_action_type_selection_changed(GtkList *list,
     gpointer user_data)
 {
@@ -1177,6 +1257,7 @@ static void prefs_filtering_action_type_select(GtkList *list,
        case ACTION_MOVE:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
                gtk_widget_show(filtering_action.dest_entry);
                gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
@@ -1190,10 +1271,18 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_hide(filtering_action.color_optmenu);
                gtk_widget_hide(filtering_action.color_label);
                gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
                break;
        case ACTION_COPY:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
                gtk_widget_show(filtering_action.dest_entry);
                gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
@@ -1207,10 +1296,18 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_hide(filtering_action.color_optmenu);
                gtk_widget_hide(filtering_action.color_label);
                gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
                break;
        case ACTION_DELETE:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
                gtk_widget_show(filtering_action.dest_entry);
                gtk_widget_set_sensitive(filtering_action.dest_entry, FALSE);
@@ -1224,6 +1321,13 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_hide(filtering_action.color_optmenu);
                gtk_widget_hide(filtering_action.color_label);
                gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
                break;
        case ACTION_MARK:
        case ACTION_UNMARK:
@@ -1238,6 +1342,7 @@ static void prefs_filtering_action_type_select(GtkList *list,
        case ACTION_IGNORE:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
                gtk_widget_show(filtering_action.dest_entry);
                gtk_widget_set_sensitive(filtering_action.dest_entry, FALSE);
@@ -1251,10 +1356,18 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_hide(filtering_action.color_optmenu);
                gtk_widget_hide(filtering_action.color_label);
                gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
                break;
        case ACTION_FORWARD:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, TRUE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, TRUE);
                gtk_widget_show(filtering_action.dest_entry);
                gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
@@ -1268,10 +1381,18 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_hide(filtering_action.color_optmenu);
                gtk_widget_hide(filtering_action.color_label);
                gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
                break;
        case ACTION_FORWARD_AS_ATTACHMENT:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, TRUE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, TRUE);
                gtk_widget_show(filtering_action.dest_entry);
                gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
@@ -1285,10 +1406,18 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_hide(filtering_action.color_optmenu);
                gtk_widget_hide(filtering_action.color_label);
                gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
                break;
        case ACTION_REDIRECT:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, TRUE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, TRUE);
                gtk_widget_show(filtering_action.dest_entry);
                gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
@@ -1302,10 +1431,18 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_hide(filtering_action.color_optmenu);
                gtk_widget_hide(filtering_action.color_label);
                gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
                break;
        case ACTION_EXECUTE:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
                gtk_widget_show(filtering_action.dest_entry);
                gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
@@ -1318,10 +1455,18 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_hide(filtering_action.color_optmenu);
                gtk_widget_hide(filtering_action.color_label);
                gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
                break;
        case ACTION_COLOR:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
                gtk_widget_hide(filtering_action.dest_entry);
                gtk_widget_hide(filtering_action.dest_btn);
@@ -1333,11 +1478,19 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_show(filtering_action.color_optmenu);
                gtk_widget_show(filtering_action.color_label);
                gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
                break;
        case ACTION_CHANGE_SCORE:
        case ACTION_SET_SCORE:
                gtk_widget_show(filtering_action.account_label);
                gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
+               gtk_widget_show(filtering_action.account_combo);
                gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
                gtk_widget_show(filtering_action.dest_entry);
                gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
@@ -1350,6 +1503,38 @@ static void prefs_filtering_action_type_select(GtkList *list,
                gtk_widget_hide(filtering_action.color_optmenu);
                gtk_widget_hide(filtering_action.color_label);
                gtk_widget_show(filtering_action.score_label);
+               gtk_widget_hide(filtering_action.header_label);
+               gtk_widget_hide(filtering_action.header_combo);
+               gtk_widget_hide(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, FALSE);
+               gtk_widget_hide(filtering_action.addressbook_label);
+               gtk_widget_hide(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, FALSE);
+               break;
+       case ACTION_ADD_TO_ADDRESSBOOK:
+               gtk_widget_hide(filtering_action.account_label);
+               gtk_widget_set_sensitive(filtering_action.account_label, FALSE);
+               gtk_widget_hide(filtering_action.account_combo);
+               gtk_widget_set_sensitive(filtering_action.account_combo, FALSE);
+               gtk_widget_show(filtering_action.dest_entry);
+               gtk_widget_set_sensitive(filtering_action.dest_entry, TRUE);
+               gtk_widget_hide(filtering_action.dest_btn);
+               gtk_widget_set_sensitive(filtering_action.dest_btn, FALSE);
+               gtk_widget_hide(filtering_action.dest_label);
+               gtk_widget_set_sensitive(filtering_action.dest_label, FALSE);
+               gtk_widget_hide(filtering_action.recip_label);
+               gtk_widget_hide(filtering_action.exec_label);
+               gtk_widget_hide(filtering_action.exec_btn);
+               gtk_widget_hide(filtering_action.color_optmenu);
+               gtk_widget_hide(filtering_action.color_label);
+               gtk_widget_hide(filtering_action.score_label);
+               gtk_widget_show(filtering_action.header_label);
+               gtk_widget_show(filtering_action.header_combo);
+               gtk_widget_show(filtering_action.header_entry);
+               gtk_widget_set_sensitive(filtering_action.header_entry, TRUE);
+               gtk_widget_show(filtering_action.addressbook_label);
+               gtk_widget_show(filtering_action.addressbook_btn);
+               gtk_widget_set_sensitive(filtering_action.addressbook_btn, TRUE);
                break;
        }
 }
@@ -1570,9 +1755,15 @@ static gboolean prefs_filtering_actions_selected
                gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
                                     ACTION_IGNORE);
                break;
+       case MATCHACTION_ADD_TO_ADDRESSBOOK:
+               if (action->header)
+                       gtk_entry_set_text(GTK_ENTRY(filtering_action.header_entry), action->header);
+               else
+                       gtk_entry_set_text(GTK_ENTRY(filtering_action.header_entry), "");
+               gtk_list_select_item(GTK_LIST(filtering_action.action_type_list),
+                                    ACTION_ADD_TO_ADDRESSBOOK);
        }
 
        filteringaction_free(action); /* XXX: memleak */
        return TRUE;
 }
-