2011-11-21 [pawel] 3.7.10cvs97
[claws.git] / src / account.c
index 006da42dac323c1f0f4f71e62366f1269f72de44..474bea162c6a3641223a2385105d2ab79e41348e 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2011 Hiroyuki Yamamoto and the Claws Mail team
  *
  * 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
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -13,8 +13,8 @@
  * 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.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 
  */
 
 #ifdef HAVE_CONFIG_H
 #include "procheader.h"
 #include "customheader.h"
 #include "remotefolder.h"
+#include "manual.h"
+#include "filtering.h"
 
 enum {
-       ACCOUNT_IS_DEFAULT,             /* GDK_TYPE_PIXMAP! */
+       ACCOUNT_IS_DEFAULT,
        ACCOUNT_ENABLE_GET_ALL, 
        ACCOUNT_NAME,
        ACCOUNT_PROTOCOL,
@@ -72,11 +74,10 @@ typedef enum
 
 # define N_EDIT_ACCOUNT_COLS   5
 
-#define PREFSBUFSIZE           1024
-
 PrefsAccount *cur_account;
 
 static GList *account_list = NULL;
+static gboolean account_list_dirty = FALSE;
 
 static struct EditAccount {
        GtkWidget *window;
@@ -84,9 +85,10 @@ static struct EditAccount {
        GtkWidget *close_btn;
 } edit_account;
 
-static GdkPixbuf *mark_pixbuf;
-
 static void account_edit_create                (void);
+static void          account_destroy           (PrefsAccount   *ac_prefs);
+static void          account_set_as_default    (PrefsAccount   *ac_prefs);
+static void          account_set_menu          (void);
 
 static void account_edit_prefs         (GtkWidget *widget, gpointer data);
 static void account_delete             (GtkWidget *widget, gpointer data);
@@ -102,14 +104,22 @@ static void account_edit_close            (GtkWidget *widget, gpointer data);
 static gint account_delete_event       (GtkWidget      *widget,
                                         GdkEventAny    *event,
                                         gpointer        data);
+static void account_size_allocate_cb(GtkWidget *widget,
+                                        GtkAllocation *allocation);
+#ifndef MAEMO
 static gboolean account_key_pressed    (GtkWidget      *widget,
                                         GdkEventKey    *event,
                                         gpointer        data);
-
+#endif
+static gboolean account_search_func_cb (GtkTreeModel *model, gint column, 
+                                               const gchar *key, GtkTreeIter *iter, 
+                                               gpointer search_data);
 static void account_list_view_add      (PrefsAccount   *ac_prefs);
 static void account_list_view_set      (void);
 
 static void account_list_set           (void);
+static void account_rename_path_prefix (const gchar    *old_prefix,
+                                        const gchar    *new_prefix);
 
 typedef struct FindAccountInStore {
        gint             account_id;
@@ -128,13 +138,12 @@ static void account_list_view_insert_account_item (GtkListStore   *list_store,
                                                   PrefsAccount *account_data);
 
 static GtkWidget *account_list_view_create     (void);
-static void account_create_list_view_images    (GtkWidget *list_view);
 static void account_create_list_view_columns   (GtkWidget *list_view);
 
 static gint account_list_view_get_selected_account_id          (GtkWidget *list_view);
-GtkTreePath *account_list_view_get_selected_account_path       (GtkWidget *list_view);
-PrefsAccount *account_list_view_get_selected_account           (GtkWidget *list_view);
-gboolean account_list_view_select_account                      (GtkWidget *list_view, 
+static GtkTreePath *account_list_view_get_selected_account_path        (GtkWidget *list_view);
+static PrefsAccount *account_list_view_get_selected_account            (GtkWidget *list_view);
+static gboolean account_list_view_select_account                       (GtkWidget *list_view, 
                                                                 gint       account_id);
 
 static void account_list_view_set_default_by_id(GtkWidget *list_view,
@@ -173,6 +182,14 @@ static void account_row_changed_while_drag_drop    (GtkTreeModel *model,
                                                 gpointer      arg3,
                                                 GtkTreeView  *list_view);
 
+static void account_flush_state(void)
+{
+       account_set_menu();
+       main_window_reflect_prefs_all();
+
+       account_list_dirty = FALSE;
+}
+
 void account_read_config_all(void)
 {
        GSList *ac_label_list = NULL, *cur;
@@ -220,7 +237,7 @@ void account_read_config_all(void)
        }
 
        account_set_menu();
-       main_window_reflect_prefs_all();
+       main_window_reflect_prefs_all_now();
 
        while (ac_label_list) {
                g_free(ac_label_list->data);
@@ -267,8 +284,8 @@ PrefsAccount *account_find_from_smtp_server(const gchar *address,
        GList *cur;
        PrefsAccount *ac;
 
-       g_return_val_if_fail(address != NULL, NULL);
-       g_return_val_if_fail(smtp_server != NULL, NULL);
+       cm_return_val_if_fail(address != NULL, NULL);
+       cm_return_val_if_fail(smtp_server != NULL, NULL);
 
        for (cur = account_list; cur != NULL; cur = cur->next) {
                ac = (PrefsAccount *)cur->data;
@@ -284,20 +301,20 @@ PrefsAccount *account_find_from_smtp_server(const gchar *address,
  * account_find_from_address:
  * @address: Email address string.
  *
- * Find a mail (not news) account with the specified email address.
+ * Find a mail (not news if newsgroups_ok is FALSE) account with the specified email address.
  *
  * Return value: The found account, or NULL if not found.
  */
-PrefsAccount *account_find_from_address(const gchar *address)
+PrefsAccount *account_find_from_address(const gchar *address, gboolean newsgroups_ok)
 {
        GList *cur;
        PrefsAccount *ac;
 
-       g_return_val_if_fail(address != NULL, NULL);
+       cm_return_val_if_fail(address != NULL, NULL);
 
        for (cur = account_list; cur != NULL; cur = cur->next) {
                ac = (PrefsAccount *)cur->data;
-               if (ac->protocol != A_NNTP && ac->address &&
+               if ((ac->protocol != A_NNTP || newsgroups_ok) && ac->address &&
                    g_ascii_strcasecmp(address, ac->address) == 0)
                        return ac;
        }
@@ -323,7 +340,7 @@ PrefsAccount *account_find_from_item(FolderItem *item)
 {
        PrefsAccount *ac;
 
-       g_return_val_if_fail(item != NULL, NULL);
+       cm_return_val_if_fail(item != NULL, NULL);
 
        ac = item->account;
        if (!ac) {
@@ -342,18 +359,14 @@ PrefsAccount *account_find_from_item(FolderItem *item)
        return ac;
 }
 
-void account_set_menu(void)
+static void account_set_menu(void)
 {
        main_window_set_account_menu(account_list);
 }
 
-void account_foreach(AccountFunc func, gpointer user_data)
+void account_set_menu_only_toolbar(void)
 {
-       GList *cur;
-
-       for (cur = account_list; cur != NULL; cur = cur->next)
-               if (func((PrefsAccount *)cur->data, user_data) != 0)
-                       return;
+       main_window_set_account_menu_only_toolbar(account_list);
 }
 
 GList *account_get_list(void)
@@ -361,10 +374,12 @@ GList *account_get_list(void)
        return account_list;
 }
 
-void account_edit_open(void)
+void account_edit_open(gpointer a, gpointer b)
 {
        inc_lock();
 
+       account_list_dirty = FALSE;
+
        if (compose_get_compose_list()) {
                alertpanel_error(_("Some composing windows are open.\n"
                                   "Please close all the composing "
@@ -383,7 +398,7 @@ void account_edit_open(void)
        manage_window_set_transient(GTK_WINDOW(edit_account.window));
        gtk_widget_grab_focus(edit_account.close_btn);
        gtk_widget_show(edit_account.window);
-
+       gtk_window_set_modal(GTK_WINDOW(edit_account.window), TRUE);
        manage_window_focus_in(edit_account.window, NULL, NULL);
 }
 
@@ -391,7 +406,7 @@ void account_add(void)
 {
        PrefsAccount *ac_prefs;
 
-       ac_prefs = prefs_account_open(NULL);
+       ac_prefs = prefs_account_open(NULL, &account_list_dirty);
 
        if (!ac_prefs) return;
 
@@ -422,37 +437,50 @@ void account_add(void)
                if (ac_prefs->protocol == A_IMAP4)
                        folder->klass->create_tree(folder);
                folderview_set_all();
+               folder_write_list();
        }
 }
 
 void account_open(PrefsAccount *ac_prefs)
 {
        gboolean prev_default;
-       gchar *ac_name;
+       gchar *ac_name, *old_prefix, *new_prefix;
+       gboolean account_dirty = FALSE;
 
-       g_return_if_fail(ac_prefs != NULL);
+       cm_return_if_fail(ac_prefs != NULL);
 
        prev_default = ac_prefs->is_default;
        Xstrdup_a(ac_name, ac_prefs->account_name ? ac_prefs->account_name : "",
                  return);
 
-       prefs_account_open(ac_prefs);
+       prefs_account_open(ac_prefs, &account_dirty);
 
-       if (!prev_default && ac_prefs->is_default)
-               account_set_as_default(ac_prefs);
+       if (account_dirty) {
+               if (!prev_default && ac_prefs->is_default)
+                       account_set_as_default(ac_prefs);
 
-       if (ac_prefs->folder && strcmp2(ac_name, ac_prefs->account_name) != 0) {
-               folder_set_name(FOLDER(ac_prefs->folder),
-                               ac_prefs->account_name);
-               folderview_set_all();
-       }
+               if (ac_prefs->folder && strcmp2(ac_name, ac_prefs->account_name) != 0) {
+                       old_prefix = folder_get_identifier(FOLDER(ac_prefs->folder));
+                       folder_set_name(FOLDER(ac_prefs->folder),
+                                       ac_prefs->account_name);
+                       folderview_set_all();
+                       folder_prefs_save_config_recursive(FOLDER(ac_prefs->folder));
+                       new_prefix = folder_get_identifier(FOLDER(ac_prefs->folder));
+
+                       account_rename_path_prefix(old_prefix, new_prefix);
+                       prefs_filtering_rename_path_prefix(old_prefix, new_prefix);
+                       
+                       g_free(old_prefix);
+                       g_free(new_prefix);
+               }
 
-       account_write_config_all();
-       account_set_menu();
-       main_window_reflect_prefs_all();
+               account_write_config_all();
+
+               account_flush_state();
+       }
 }
 
-void account_set_as_default(PrefsAccount *ac_prefs)
+static void account_set_as_default(PrefsAccount *ac_prefs)
 {
        PrefsAccount *ap;
        GList *cur;
@@ -505,16 +533,75 @@ void account_set_missing_folder(void)
                        folder_add(folder);
                        if (ap->protocol == A_IMAP4)
                                folder->klass->create_tree(folder);
+                       folder_write_list();
+
                }
        }
 }
 
+#define CHECK_CHANGE_FOLDER(folder) {                                          \
+       if (folder && !strncmp(folder, old_id, strlen(old_id))) {               \
+               if (strlen(folder) == strlen(old_id)) {                         \
+                       g_free(folder);                                         \
+                       folder = g_strdup(new_id);                              \
+               } else if (strlen(folder) > strlen(old_id)                      \
+                 && folder[strlen(old_id)] == G_DIR_SEPARATOR) {               \
+                       gchar *new_path = g_strdup_printf("%s%s",               \
+                                       new_id, (folder + strlen(old_id)));     \
+                       g_free(folder);                                         \
+                       folder = new_path;                                      \
+               }                                                               \
+       }                                                                       \
+}
+
+void account_rename_path(const gchar *old_id, const gchar *new_id)
+{
+       GList *cur = account_list;
+       for (; cur != NULL; cur = g_list_next(cur)) {
+               PrefsAccount *ap = (PrefsAccount *)cur->data;
+               CHECK_CHANGE_FOLDER(ap->inbox);
+               CHECK_CHANGE_FOLDER(ap->local_inbox);
+               CHECK_CHANGE_FOLDER(ap->queue_folder);
+               CHECK_CHANGE_FOLDER(ap->sent_folder);
+               CHECK_CHANGE_FOLDER(ap->draft_folder);
+               CHECK_CHANGE_FOLDER(ap->trash_folder);
+       }
+}
+
+#undef CHECK_CHANGE_FOLDER
+
+#define CHANGE_FOLDER_PREFIX(folder) {                                         \
+       if (folder && g_str_has_prefix(folder, old_prefix)) {                   \
+               gchar *new_path = g_strconcat(new_prefix,                       \
+                                  (folder + strlen(old_prefix)), NULL);        \
+               g_free(folder);                                                 \
+               folder = new_path;                                              \
+       }                                                                       \
+}
+
+static void account_rename_path_prefix(const gchar *old_prefix,
+                               const gchar *new_prefix)
+{
+       GList *cur = account_list;
+       for (; cur != NULL; cur = g_list_next(cur)) {
+               PrefsAccount *ap = (PrefsAccount *)cur->data;
+               CHANGE_FOLDER_PREFIX(ap->inbox);
+               CHANGE_FOLDER_PREFIX(ap->local_inbox);
+               CHANGE_FOLDER_PREFIX(ap->queue_folder);
+               CHANGE_FOLDER_PREFIX(ap->sent_folder);
+               CHANGE_FOLDER_PREFIX(ap->draft_folder);
+               CHANGE_FOLDER_PREFIX(ap->trash_folder);
+       }
+}
+
+#undef CHANGE_FOLDER_PREFIX
+
 FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
                                       SpecialFolderItemType type)
 {
        FolderItem *item = NULL;
 
-       g_return_val_if_fail(ac_prefs != NULL, NULL);
+       cm_return_val_if_fail(ac_prefs != NULL, NULL);
 
        switch (type) {
        case F_INBOX:
@@ -531,6 +618,8 @@ FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
                if (!item) {
                        if (ac_prefs->folder)
                                item = FOLDER(ac_prefs->folder)->outbox;
+                       if (!item)
+                               item = folder_get_default_outbox_for_class(F_MH);
                        if (!item)
                                item = folder_get_default_outbox();
                }
@@ -543,6 +632,8 @@ FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
                if (!item) {
                        if (ac_prefs->folder)
                                item = FOLDER(ac_prefs->folder)->draft;
+                       if (!item)
+                               item = folder_get_default_draft_for_class(F_MH);
                        if (!item)
                                item = folder_get_default_draft();
                }
@@ -555,6 +646,8 @@ FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
                if (!item) {
                        if (ac_prefs->folder)
                                item = FOLDER(ac_prefs->folder)->queue;
+                       if (!item)
+                               item = folder_get_default_queue_for_class(F_MH);
                        if (!item)
                                item = folder_get_default_queue();
                }
@@ -567,6 +660,8 @@ FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
                if (!item) {
                        if (ac_prefs->folder)
                                item = FOLDER(ac_prefs->folder)->trash;
+                       if (!item)
+                               item = folder_get_default_trash_for_class(F_MH);
                        if (!item)
                                item = folder_get_default_trash();
                }
@@ -580,7 +675,7 @@ FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
 
 void account_destroy(PrefsAccount *ac_prefs)
 {
-       g_return_if_fail(ac_prefs != NULL);
+       cm_return_if_fail(ac_prefs != NULL);
 
        folder_unref_account_all(ac_prefs);
 
@@ -598,6 +693,17 @@ void account_destroy(PrefsAccount *ac_prefs)
        }
 }
 
+/*!
+ *\brief       Save Gtk object size to prefs dataset
+ */
+static void account_size_allocate_cb(GtkWidget *widget,
+                                        GtkAllocation *allocation)
+{
+       cm_return_if_fail(allocation != NULL);
+
+       prefs_common.accountswin_width = allocation->width;
+       prefs_common.accountswin_height = allocation->height;
+}
 
 static void account_edit_create(void)
 {
@@ -618,20 +724,25 @@ static void account_edit_create(void)
 
        GtkWidget *default_btn;
 
-       GtkWidget *hbbox;
+       GtkWidget *confirm_area;
+       GtkWidget *help_btn;
        GtkWidget *close_btn;
 
+       static GdkGeometry geometry;
+
        debug_print("Creating account edit window...\n");
 
-       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-       gtk_widget_set_size_request (window, 500, 350);
+       window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "account");
        gtk_container_set_border_width (GTK_CONTAINER (window), 8);
        gtk_window_set_title (GTK_WINDOW (window), _("Edit accounts"));
-       gtk_window_set_modal (GTK_WINDOW (window), TRUE);
        g_signal_connect (G_OBJECT (window), "delete_event",
                          G_CALLBACK (account_delete_event), NULL);
+#ifdef MAEMO
+       maemo_connect_key_press_to_mainwindow(GTK_WINDOW(window));
+#else
        g_signal_connect (G_OBJECT (window), "key_press_event",
                          G_CALLBACK (account_key_pressed), NULL);
+#endif                   
        MANAGE_WINDOW_SIGNALS_CONNECT (window);
        gtk_widget_realize(window);
 
@@ -644,11 +755,15 @@ static void account_edit_create(void)
        gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
 
        label = gtk_label_new
-               (_("New messages will be checked in this order. Check the boxes\n"
-                  "on the 'G' column to enable message retrieval by 'Get all'."));
+               (_("Using 'Get Mail' will retrieve messages from your Accounts "
+                  "in the order given, the checkbox indicates which accounts "
+                  "will be included. Bold text indicates the default account."));
        gtk_widget_show (label);
+       gtk_widget_set_size_request(GTK_WIDGET(label), 
+                                   prefs_common.accountswin_width-8, -1);
        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 4);
        gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+       gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 
        hbox = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (hbox);
@@ -676,11 +791,7 @@ static void account_edit_create(void)
        g_signal_connect (G_OBJECT(add_btn), "clicked",
                          G_CALLBACK (account_add), NULL);
 
-#if GTK_CHECK_VERSION(2, 6, 0)
        edit_btn = gtk_button_new_from_stock (GTK_STOCK_EDIT);
-#else
-       edit_btn = gtk_button_new_from_stock(GTK_STOCK_PROPERTIES);
-#endif
        gtk_widget_show (edit_btn);
        gtk_box_pack_start (GTK_BOX (vbox2), edit_btn, FALSE, FALSE, 4);
        g_signal_connect (G_OBJECT(edit_btn), "clicked",
@@ -714,37 +825,51 @@ static void account_edit_create(void)
        gtk_widget_show (hbox);
        gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
 
-       vbox2 = gtk_vbox_new(FALSE, 0);
-       gtk_widget_show (vbox2);
-       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
-
        default_btn = gtk_button_new_with_mnemonic
                (_(" _Set as default account "));
        gtk_widget_show (default_btn);
-       gtk_box_pack_start (GTK_BOX (vbox2), default_btn, TRUE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (hbox), default_btn, FALSE, FALSE, 0);
        g_signal_connect (G_OBJECT(default_btn), "clicked",
                          G_CALLBACK (account_set_default), NULL);
 
-       hbbox = gtk_hbutton_box_new();
-       gtk_button_box_set_layout(GTK_BUTTON_BOX(hbbox), GTK_BUTTONBOX_END);
-       gtk_box_set_spacing(GTK_BOX(hbbox), 5);
-
-       gtkut_stock_button_set_create(&hbbox, &close_btn, GTK_STOCK_CLOSE,
-                                     NULL, NULL, NULL, NULL);
-       gtk_widget_show(hbbox);
+       gtkut_stock_button_set_create_with_help(&confirm_area, &help_btn,
+                       &close_btn, GTK_STOCK_CLOSE,
+                       NULL, NULL, NULL, NULL);
+       gtk_widget_show(confirm_area);
 
-       gtk_box_pack_end (GTK_BOX (hbox), hbbox, FALSE, FALSE, 0);
+       gtk_box_pack_end (GTK_BOX (hbox), confirm_area, FALSE, FALSE, 0);
        gtk_widget_grab_default (close_btn);
 
        g_signal_connect (G_OBJECT (close_btn), "clicked",
                          G_CALLBACK (account_edit_close),
                          NULL);
+       g_signal_connect(G_OBJECT(help_btn), "clicked",
+                       G_CALLBACK(manual_open_with_anchor_cb),
+                       MANUAL_ANCHOR_ACCOUNTPREFS);
+
+
+       g_signal_connect(G_OBJECT(window), "size_allocate",
+                        G_CALLBACK(account_size_allocate_cb), NULL);
+
+       if (!geometry.min_height) {
+               geometry.min_width = 500;
+               geometry.min_height = 380;
+       }
 
-       account_create_list_view_images(list_view);
+       gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
+                                     GDK_HINT_MIN_SIZE);
+       gtk_widget_set_size_request(window, prefs_common.accountswin_width,
+                                   prefs_common.accountswin_height);
+#ifdef G_OS_WIN32
+       gtk_window_move(GTK_WINDOW(window), 48, 48);
+#endif
 
        edit_account.window    = window;
        edit_account.list_view = list_view;
        edit_account.close_btn = close_btn;
+#ifdef MAEMO
+       maemo_window_full_screen_if_needed(GTK_WINDOW(edit_account.window));
+#endif
 }
 
 static void account_edit_prefs(GtkWidget *widget, gpointer data)
@@ -764,7 +889,7 @@ static gboolean account_delete_references_func(GNode *node, gpointer data)
        FolderItem *item;
        gint account;
 
-       g_return_val_if_fail(node->data != NULL, FALSE);
+       cm_return_val_if_fail(node->data != NULL, FALSE);
 
        item = FOLDER_ITEM(node->data);
        account = GPOINTER_TO_INT(data);
@@ -799,6 +924,7 @@ static void account_clone(GtkWidget *widget, gpointer data)
                alertpanel_error(_("Accounts with remote folders cannot be copied."));
                return;
        }
+       account_list_dirty = TRUE;
        
        ac_clon = prefs_account_new();
        /* copy fields */
@@ -823,42 +949,38 @@ static void account_clone(GtkWidget *widget, gpointer data)
        ACP_FASSIGN(use_mail_command);
        ACP_FDUP(mail_command);
        
-#if USE_OPENSSL
        ACP_FASSIGN(ssl_pop);
        ACP_FASSIGN(ssl_imap);
        ACP_FASSIGN(ssl_nntp);
        ACP_FASSIGN(ssl_smtp);
        ACP_FASSIGN(use_nonblocking_ssl);
-#endif /* USE_OPENSSL */
        
-       ac_clon->tmp_pass = NULL;
-
        /* receive */
+       ACP_FASSIGN(use_apop_auth);
        ACP_FASSIGN(rmmail);
        ACP_FASSIGN(msg_leave_time);
-       ACP_FASSIGN(getall);
+       ACP_FASSIGN(msg_leave_hour);
        ACP_FASSIGN(recv_at_getall);
        ACP_FASSIGN(sd_rmmail_on_download);
-       ACP_FASSIGN(sd_filter_on_recv);
        ACP_FASSIGN(enable_size_limit);
        ACP_FASSIGN(size_limit);
        ACP_FASSIGN(filter_on_recv);
+       ACP_FASSIGN(filterhook_on_recv);
        ACP_FDUP(inbox);
+       ACP_FDUP(local_inbox);
        ACP_FASSIGN(max_articles);
 
        ACP_FASSIGN(imap_auth_type);
 
        /* send */
-       ACP_FASSIGN(add_date);
        ACP_FASSIGN(gen_msgid);
+       ACP_FASSIGN(gen_xmailer);
        ACP_FASSIGN(add_customhdr);
        ACP_FASSIGN(use_smtp_auth);
        ACP_FASSIGN(smtp_auth_type);
        ACP_FDUP(smtp_userid);
        ACP_FDUP(smtp_passwd);
 
-       ac_clon->tmp_smtp_pass = NULL;
-
        ACP_FASSIGN(pop_before_smtp);
        ACP_FASSIGN(pop_before_smtp_timeout);
        ACP_FASSIGN(last_pop_login_time);
@@ -889,10 +1011,28 @@ static void account_clone(GtkWidget *widget, gpointer data)
         ACP_FDUP(auto_bcc);
         ACP_FASSIGN(set_autoreplyto);
         ACP_FDUP(auto_replyto);
+       ACP_FASSIGN(enable_default_dictionary);
+       ACP_FDUP(default_dictionary);
+       ACP_FASSIGN(enable_default_alt_dictionary);
+       ACP_FDUP(default_alt_dictionary);
+       ACP_FASSIGN(compose_with_format);
+       ACP_FDUP(compose_subject_format);
+       ACP_FDUP(compose_body_format);
+       ACP_FASSIGN(reply_with_format);
+       ACP_FDUP(reply_quotemark);
+       ACP_FDUP(reply_body_format);
+       ACP_FASSIGN(forward_with_format);
+       ACP_FDUP(forward_quotemark);
+       ACP_FDUP(forward_body_format);
 
         /* privacy */
+       ACP_FDUP(default_privacy_system);
         ACP_FASSIGN(default_encrypt);
+       ACP_FASSIGN(default_encrypt_reply);
         ACP_FASSIGN(default_sign);
+       ACP_FASSIGN(default_sign_reply);
+       ACP_FASSIGN(save_encrypted_as_clear_text);
+       ACP_FASSIGN(encrypt_to_self);
        
         /* advanced */
         ACP_FASSIGN(set_smtpport);
@@ -908,13 +1048,19 @@ static void account_clone(GtkWidget *widget, gpointer data)
         ACP_FASSIGN(mark_crosspost_read);
         ACP_FASSIGN(crosspost_col);
 
+#ifndef G_OS_WIN32
         ACP_FASSIGN(set_tunnelcmd);
         ACP_FDUP(tunnelcmd);
+#endif
 
         ACP_FDUP(imap_dir);
+       ACP_FASSIGN(imap_subsonly);
+       ACP_FASSIGN(low_bandwidth);
 
         ACP_FASSIGN(set_sent_folder);
         ACP_FDUP(sent_folder);
+       ACP_FASSIGN(set_queue_folder);
+       ACP_FDUP(queue_folder);
         ACP_FASSIGN(set_draft_folder);
         ACP_FDUP(draft_folder);
         ACP_FASSIGN(set_trash_folder);
@@ -935,6 +1081,7 @@ static void account_delete(GtkWidget *widget, gpointer data)
        gchar buf[BUFFSIZE];
        GList *list;
        Folder *folder;
+       GSList *cur;
  
        ac_prefs = account_list_view_get_selected_account(edit_account.list_view);
        if (ac_prefs == NULL)
@@ -945,9 +1092,10 @@ static void account_delete(GtkWidget *widget, gpointer data)
                   ac_prefs->account_name ? ac_prefs->account_name :
                   _("(Untitled)"));
        if (alertpanel_full(_("Delete account"), buf,
-                           GTK_STOCK_YES, GTK_STOCK_NO, NULL, FALSE,
-                           NULL, ALERT_WARNING, G_ALERTALTERNATE) != G_ALERTDEFAULT)
+                           GTK_STOCK_CANCEL, GTK_STOCK_DELETE, NULL, FALSE,
+                           NULL, ALERT_WARNING, G_ALERTDEFAULT) != G_ALERTALTERNATE)
                return;
+       account_list_dirty = TRUE;
 
        if (ac_prefs->folder) {
                FolderItem *item;
@@ -971,6 +1119,23 @@ static void account_delete(GtkWidget *widget, gpointer data)
                                account_delete_references_func,
                                GINT_TO_POINTER(ac_prefs->account_id));
        }
+
+       debug_print("Removing filter rules relative to this account...\n");
+       for(cur = filtering_rules ; cur != NULL ;) {
+               FilteringProp * prop = (FilteringProp *) cur->data;
+
+               if (prop && (prop->account_id == ac_prefs->account_id)) {
+                       /* get next item before we kill the current one */
+                       cur = g_slist_next(cur);
+
+                       /* unallocate filteringprop and unchain it from the list */
+                       filteringprop_free(prop);
+                       filtering_rules = g_slist_remove(filtering_rules, prop);
+               } else {
+                       cur = g_slist_next(cur);
+               }
+       }
+       folder_write_list();
 }
 
 static void account_up(GtkWidget *widget, gpointer data)
@@ -984,6 +1149,7 @@ static void account_up(GtkWidget *widget, gpointer data)
        
        if (!sel) 
                return;
+       account_list_dirty = TRUE;
 
        up = gtk_tree_path_copy(sel);
        if (!up) {
@@ -1023,6 +1189,7 @@ static void account_down(GtkWidget *widget, gpointer data)
        
        if (!sel) 
                return;
+       account_list_dirty = TRUE;
 
        dn = gtk_tree_path_copy(sel);
        if (!dn) {
@@ -1067,8 +1234,7 @@ static void account_set_default(GtkWidget *widget, gpointer data)
        account_list_view_set();
        
        cur_account = ac_prefs;
-       account_set_menu();
-       main_window_reflect_prefs_all();
+       account_flush_state();
 }
 
 static void account_edit_close(GtkWidget *widget, gpointer data)
@@ -1082,11 +1248,11 @@ static void account_edit_close(GtkWidget *widget, gpointer data)
                cur_account = ac_prefs;
        }
 
-       account_set_menu();
-       main_window_reflect_prefs_all();
+       if (account_list_dirty)
+               account_flush_state();
 
        gtk_widget_hide(edit_account.window);
-
+       gtk_window_set_modal(GTK_WINDOW(edit_account.window), FALSE);
        inc_unlock();
 }
 
@@ -1096,15 +1262,33 @@ static gint account_delete_event(GtkWidget *widget, GdkEventAny *event,
        account_edit_close(NULL, NULL);
        return TRUE;
 }
-
+#ifndef MAEMO
 static gboolean account_key_pressed(GtkWidget *widget, GdkEventKey *event,
                                    gpointer data)
 {
-       if (event && event->keyval == GDK_Escape)
+       if (event && event->keyval == GDK_KEY_Escape)
                account_edit_close(NULL, NULL);
        return FALSE;
 }
+#endif
+
+static gboolean account_search_func_cb (GtkTreeModel *model, gint column, const gchar *key, 
+                                               GtkTreeIter *iter, gpointer search_data) 
+{
+       gboolean retval;
+       PrefsAccount *ac;
+
+       gtk_tree_model_get (model, iter, ACCOUNT_DATA, &ac, -1);
+
+       if (!ac->name || !key) return FALSE;
 
+       retval = (strncmp (key, ac->account_name, strlen(key)) != 0);
+
+       debug_print("selecting row\n");
+       account_list_view_select_account(edit_account.list_view, ac->account_id);
+
+       return retval;
+}
 static void account_list_view_add(PrefsAccount *ac_prefs)
 {
        GtkTreeView *list_view = GTK_TREE_VIEW(edit_account.list_view);
@@ -1114,7 +1298,7 @@ static void account_list_view_add(PrefsAccount *ac_prefs)
        gboolean getall;
 
        name = ac_prefs->account_name;
-#if USE_OPENSSL
+#ifdef USE_GNUTLS
        protocol = ac_prefs->protocol == A_POP3 ?
                  (ac_prefs->ssl_pop == SSL_TUNNEL ?
                   "POP3 (SSL)" :
@@ -1128,15 +1312,19 @@ static void account_list_view_add(PrefsAccount *ac_prefs)
                   ac_prefs->protocol == A_NNTP ?
                  (ac_prefs->ssl_nntp == SSL_TUNNEL ?
                   "NNTP (SSL)" : "NNTP") :
-                  "";
+                  ac_prefs->protocol == A_LOCAL ? "Local" :
+                  ac_prefs->protocol == A_NONE ?  "SMTP" : "-";
 #else
        protocol = ac_prefs->protocol == A_POP3  ? "POP3" :
                   ac_prefs->protocol == A_IMAP4 ? "IMAP4" :
                   ac_prefs->protocol == A_LOCAL ? "Local" :
-                  ac_prefs->protocol == A_NNTP  ? "NNTP" : "";
+                  ac_prefs->protocol == A_NNTP  ? "NNTP" :
+                  ac_prefs->protocol == A_NONE ?  "SMTP" : "-";
 #endif
-       server= ac_prefs->protocol == A_NNTP
-               ? ac_prefs->nntp_server : ac_prefs->recv_server;
+       server= ac_prefs->protocol == A_NNTP ? ac_prefs->nntp_server :
+                  ac_prefs->protocol == A_LOCAL ?  "-" :
+                  ac_prefs->protocol == A_NONE ? ac_prefs->smtp_server :
+                  ac_prefs->recv_server;
 
        has_getallbox = (ac_prefs->protocol == A_POP3  ||
                         ac_prefs->protocol == A_IMAP4 ||
@@ -1235,7 +1423,7 @@ PrefsAccount *account_get_reply_account(MsgInfo *msginfo, gboolean reply_autosel
                                if (!strchr(field, ',')) {
                                        Xstrdup_a(to, field, return NULL);
                                        extract_address(to);
-                                       account = account_find_from_address(to);
+                                       account = account_find_from_address(to, FALSE);
                                } else {
                                        gchar **split = g_strsplit(field, ",", -1);
                                        int i = -1;
@@ -1245,12 +1433,21 @@ PrefsAccount *account_get_reply_account(MsgInfo *msginfo, gboolean reply_autosel
                                                        break;
                                                Xstrdup_a(to, split[i], return NULL);
                                                extract_address(to);
-                                               account = account_find_from_address(to);
+                                               account = account_find_from_address(to, FALSE);
                                        } while (!account);
                                        g_strfreev(split);
                                }
                        }
                }
+               if (!account) {
+                       gchar deliveredto[BUFFSIZE];
+                       if (!procheader_get_header_from_msginfo
+                               (msginfo, deliveredto,sizeof deliveredto , "Delivered-To:")) { 
+                               gchar *buf = deliveredto + strlen("Delivered-To:");
+                               extract_address(buf);
+                               account = account_find_from_address(buf, FALSE);
+                       }
+               }
        }
 
        /* select the account for the whole folder (IMAP / NNTP) */
@@ -1272,7 +1469,7 @@ PrefsAccount *account_get_reply_account(MsgInfo *msginfo, gboolean reply_autosel
 static GtkListStore* account_create_data_store(void)
 {
        return gtk_list_store_new(N_ACCOUNT_COLUMNS,
-                                GDK_TYPE_PIXBUF,       /* ACCOUNT_IS_DEFAULT */
+                                G_TYPE_INT,            /* ACCOUNT_IS_DEFAULT */
                                 G_TYPE_BOOLEAN,        /* ACCOUNT_ENABLE_GET_ALL */
                                 G_TYPE_STRING,         /* ACCOUNT_NAME */
                                 G_TYPE_STRING,         /* ACCOUNT_PROTOCOL */
@@ -1299,7 +1496,7 @@ static void account_list_view_insert_account_item(GtkListStore *list_store,
        
        gtk_list_store_append(list_store, &iter);
        gtk_list_store_set(list_store, &iter, 
-                          ACCOUNT_IS_DEFAULT,     is_default ? mark_pixbuf : NULL,
+                          ACCOUNT_IS_DEFAULT,     is_default ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
                           ACCOUNT_ENABLE_GET_ALL, is_get_all,
                           ACCOUNT_NAME,           account_name,
                           ACCOUNT_PROTOCOL,       protocol,
@@ -1311,7 +1508,6 @@ static void account_list_view_insert_account_item(GtkListStore *list_store,
 /*!
  *\brief       Create and set up account list view, including tasks like
  *             creating the data store (\ref account_create_data_store()),
- *             creating images for the list view (\ref account_create_list_view_images()),
  *             and setting up the account list's individual columns (\ref 
  *             account_create_list_view_columns()).
  *
@@ -1325,8 +1521,10 @@ static GtkWidget *account_list_view_create(void)
 
        list_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)));
        g_object_unref(G_OBJECT(store));
-
-       gtk_tree_view_set_rules_hint(list_view, prefs_common.enable_rules_hint);
+#ifdef GENERIC_UMPC
+       g_object_set(list_view, "allow-checkbox-mode", FALSE, NULL);
+#endif
+       gtk_tree_view_set_rules_hint(list_view, prefs_common.use_stripes_everywhere);
        gtk_tree_view_set_reorderable(list_view, TRUE);
        
        selector = gtk_tree_view_get_selection(list_view);
@@ -1352,41 +1550,33 @@ static GtkWidget *account_list_view_create(void)
        return GTK_WIDGET(list_view);
 }
 
-static void account_create_list_view_images(GtkWidget *list_view)
-{
-       stock_pixbuf_gdk(list_view, STOCK_PIXMAP_MARK, &mark_pixbuf);
-}
-
 static void account_create_list_view_columns(GtkWidget *list_view)
 {
        GtkTreeViewColumn *column;
        GtkCellRenderer *renderer;
 
-       renderer = gtk_cell_renderer_pixbuf_new();
-       column = gtk_tree_view_column_new_with_attributes
-               ("D", renderer,
-                "pixbuf", ACCOUNT_IS_DEFAULT,
-                NULL);
-       gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);           
-
        renderer = gtk_cell_renderer_toggle_new();
        g_object_set(renderer, 
                     "radio", FALSE, 
                     "activatable", TRUE,
                      NULL);
        column = gtk_tree_view_column_new_with_attributes
-               ("G", renderer,
+               (Q_("Accounts List Get Column Name|G"), renderer,
                 "active", ACCOUNT_ENABLE_GET_ALL,
                 NULL);
        gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);          
+       gtk_tree_view_column_set_alignment (column, 0.5);
+       CLAWS_SET_TIP(gtk_tree_view_column_get_widget(column),
+                       _("'Get Mail' retrieves mail from the checked accounts"));
        g_signal_connect(G_OBJECT(renderer), "toggled",                      
                         G_CALLBACK(account_get_all_toggled),
                         list_view);
-       
+
        renderer = gtk_cell_renderer_text_new();
        column = gtk_tree_view_column_new_with_attributes
                (_("Name"), renderer,
                 "text", ACCOUNT_NAME,
+                "weight", ACCOUNT_IS_DEFAULT,
                 NULL);
        gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);          
        
@@ -1394,6 +1584,7 @@ static void account_create_list_view_columns(GtkWidget *list_view)
        column = gtk_tree_view_column_new_with_attributes
                (_("Protocol"), renderer,
                 "text", ACCOUNT_PROTOCOL,
+                "weight", ACCOUNT_IS_DEFAULT,
                 NULL);
        gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);           
        
@@ -1401,7 +1592,10 @@ static void account_create_list_view_columns(GtkWidget *list_view)
        column = gtk_tree_view_column_new_with_attributes
                (_("Server"), renderer,
                 "text", ACCOUNT_SERVER,
+                "weight", ACCOUNT_IS_DEFAULT,
                 NULL);
+       gtk_tree_view_set_search_column(GTK_TREE_VIEW(list_view), ACCOUNT_NAME);
+       gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(list_view), account_search_func_cb , NULL, NULL);
        gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);           
 }
 
@@ -1428,7 +1622,7 @@ static gint account_list_view_get_selected_account_id(GtkWidget *list_view)
 /*!
  *\brief       Get the tree path of the currently selected account
  */
-GtkTreePath *account_list_view_get_selected_account_path(GtkWidget *list_view)
+static GtkTreePath *account_list_view_get_selected_account_path(GtkWidget *list_view)
 {
        GtkTreeSelection *selector;
        GtkTreeModel *model;
@@ -1446,7 +1640,7 @@ GtkTreePath *account_list_view_get_selected_account_path(GtkWidget *list_view)
 /*!
  *\brief       Get the account data of the currently selected account
  */
-PrefsAccount *account_list_view_get_selected_account(GtkWidget *list_view)
+static PrefsAccount *account_list_view_get_selected_account(GtkWidget *list_view)
 {
        GtkTreeSelection *selector;
        GtkTreeModel *model;
@@ -1468,7 +1662,7 @@ PrefsAccount *account_list_view_get_selected_account(GtkWidget *list_view)
  *
  *\return      gboolean TRUE if found and selected, FALSE if not.
  */
-gboolean account_list_view_select_account(GtkWidget *list_view, gint account_id)
+static gboolean account_list_view_select_account(GtkWidget *list_view, gint account_id)
 {
        FindAccountInStore fis;
        GtkTreeModel *model;
@@ -1516,20 +1710,19 @@ static gboolean set_new_default_account(GtkTreeModel *model,
                                        gint         *account_id)
 {
        PrefsAccount *account = NULL;
-       GdkPixbuf *pixbuf;
+       PangoWeight weight;
        
        gtk_tree_model_get(model, iter, 
                           ACCOUNT_DATA, &account, 
                           -1);
 
        if (*account_id == account->account_id)
-               pixbuf = NULL;
+               weight = PANGO_WEIGHT_NORMAL;
        else
-               pixbuf = mark_pixbuf;
-       
+               weight = PANGO_WEIGHT_BOLD;
+
        gtk_list_store_set(GTK_LIST_STORE(model), iter, 
-                          ACCOUNT_IS_DEFAULT, pixbuf,
-                          -1);
+                          ACCOUNT_IS_DEFAULT, weight, -1);
 
        return FALSE;
 }
@@ -1628,3 +1821,60 @@ static void account_row_changed_while_drag_drop(GtkTreeModel *model,
 {      
        account_list_set();     
 }
+
+gchar *account_get_signature_str(PrefsAccount *account)
+{
+       gchar *sig_body = NULL;
+       gchar *sig_str = NULL;
+       gchar *utf8_sig_str = NULL;
+
+       cm_return_val_if_fail(account != NULL, NULL);
+
+       if (!account->sig_path)
+               return NULL;
+
+       if (account->sig_type == SIG_FILE) {
+               if (!is_file_or_fifo_exist(account->sig_path)) {
+                       g_warning("can't open signature file: %s\n",
+                                 account->sig_path);
+                       return NULL;
+               }
+       }
+
+       if (account->sig_type == SIG_COMMAND)
+               sig_body = get_command_output(account->sig_path);
+       else {
+               gchar *tmp;
+
+               tmp = file_read_to_str(account->sig_path);
+               if (!tmp)
+                       return NULL;
+               sig_body = normalize_newlines(tmp);
+               g_free(tmp);
+       }
+
+       if (account->sig_sep) {
+               sig_str = g_strconcat("\n", account->sig_sep, "\n", sig_body,
+                                     NULL);
+               g_free(sig_body);
+       } else
+               sig_str = g_strconcat("\n", sig_body, NULL);
+
+       if (sig_str) {
+               if (g_utf8_validate(sig_str, -1, NULL) == TRUE)
+                       utf8_sig_str = sig_str;
+               else {
+                       utf8_sig_str = conv_codeset_strdup
+                               (sig_str, conv_get_locale_charset_str_no_utf8(),
+                                CS_INTERNAL);
+                       g_free(sig_str);
+               }
+       }
+
+       return utf8_sig_str;
+}
+
+PrefsAccount *account_get_cur_account (void)
+{
+       return cur_account;
+}