2006-09-16 [paul] 2.4.0cvs190
[claws.git] / src / account.c
index ad40cc042a99692c195b50b094f69456c6f8bfdb..0c01275ee36903a639ae66774baf50d97597d9d3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2006 Hiroyuki Yamamoto and the Sylpheed-Claws 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
@@ -14,7 +14,7 @@
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -49,6 +49,8 @@
 #include "procheader.h"
 #include "customheader.h"
 #include "remotefolder.h"
+#include "manual.h"
+#include "filtering.h"
 
 enum {
        ACCOUNT_IS_DEFAULT,             /* GDK_TYPE_PIXMAP! */
@@ -102,6 +104,8 @@ 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);
 static gboolean account_key_pressed    (GtkWidget      *widget,
                                         GdkEventKey    *event,
                                         gpointer        data);
@@ -184,7 +188,7 @@ void account_read_config_all(void)
        debug_print("Reading all config for each account...\n");
 
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, ACCOUNT_RC, NULL);
-       if ((fp = fopen(rcpath, "rb")) == NULL) {
+       if ((fp = g_fopen(rcpath, "rb")) == NULL) {
                if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
                g_free(rcpath);
                return;
@@ -220,7 +224,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);
@@ -347,6 +351,11 @@ void account_set_menu(void)
        main_window_set_account_menu(account_list);
 }
 
+void account_set_menu_only_toolbar(void)
+{
+       main_window_set_account_menu_only_toolbar(account_list);
+}
+
 void account_foreach(AccountFunc func, gpointer user_data)
 {
        GList *cur;
@@ -509,6 +518,37 @@ void account_set_missing_folder(void)
        }
 }
 
+#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
+
 FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
                                       SpecialFolderItemType type)
 {
@@ -598,6 +638,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)
+{
+       g_return_if_fail(allocation != NULL);
+
+       prefs_common.accountswin_width = allocation->width;
+       prefs_common.accountswin_height = allocation->height;
+}
 
 static void account_edit_create(void)
 {
@@ -619,12 +670,14 @@ static void account_edit_create(void)
        GtkWidget *default_btn;
 
        GtkWidget *hbbox;
+       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);
        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);
@@ -644,11 +697,13 @@ 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 in the 'G' column indicates "
+                  "which accounts will be included."));
        gtk_widget_show (label);
        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);
@@ -670,17 +725,13 @@ static void account_edit_create(void)
        gtk_widget_show (vbox2);
        gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
 
-       add_btn = gtk_button_new_from_stock(GTK_STOCK_ADD);
+       add_btn = gtk_button_new_from_stock(GTK_STOCK_NEW);
        gtk_widget_show (add_btn);
        gtk_box_pack_start (GTK_BOX (vbox2), add_btn, FALSE, FALSE, 4);
        g_signal_connect (G_OBJECT(add_btn), "clicked",
                          G_CALLBACK (account_add), NULL);
 
-#ifdef GTK_STOCK_EDIT
        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",
@@ -718,7 +769,8 @@ static void account_edit_create(void)
        gtk_widget_show (vbox2);
        gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
 
-       default_btn = gtk_button_new_with_label (_(" Set as default account "));
+       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);
        g_signal_connect (G_OBJECT(default_btn), "clicked",
@@ -728,8 +780,9 @@ static void account_edit_create(void)
        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);
+       gtkut_stock_button_set_create_with_help(&hbbox, &help_btn,
+                       &close_btn, GTK_STOCK_CLOSE,
+                       NULL, NULL, NULL, NULL);
        gtk_widget_show(hbbox);
 
        gtk_box_pack_end (GTK_BOX (hbox), hbbox, FALSE, FALSE, 0);
@@ -738,9 +791,25 @@ static void account_edit_create(void)
        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);
 
        account_create_list_view_images(list_view);
 
+       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 = 350;
+       }
+
+       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);
+
        edit_account.window    = window;
        edit_account.list_view = list_view;
        edit_account.close_btn = close_btn;
@@ -795,13 +864,13 @@ static void account_clone(GtkWidget *widget, gpointer data)
                return;
 
        if (ac_prefs->protocol == A_IMAP4 || ac_prefs->protocol == A_NNTP) {
-               alertpanel_error(_("Accounts with remote folders cannot be cloned"));
+               alertpanel_error(_("Accounts with remote folders cannot be copied."));
                return;
        }
        
        ac_clon = prefs_account_new();
        /* copy fields */
-       ac_clon->account_name = g_strdup_printf(_("Cloned %s"), 
+       ac_clon->account_name = g_strdup_printf(_("Copy of %s"),
                                                ac_prefs->account_name);
        /* personal */
        ACP_FDUP(name);
@@ -848,7 +917,6 @@ static void account_clone(GtkWidget *widget, gpointer data)
        ACP_FASSIGN(imap_auth_type);
 
        /* send */
-       ACP_FASSIGN(add_date);
        ACP_FASSIGN(gen_msgid);
        ACP_FASSIGN(add_customhdr);
        ACP_FASSIGN(use_smtp_auth);
@@ -934,6 +1002,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)
@@ -943,8 +1012,9 @@ static void account_delete(GtkWidget *widget, gpointer data)
                   _("Do you really want to delete the account '%s'?"),
                   ac_prefs->account_name ? ac_prefs->account_name :
                   _("(Untitled)"));
-       if (alertpanel(_("Delete account"), buf,
-                      _("Yes"), _("+No"), NULL) != G_ALERTDEFAULT)
+       if (alertpanel_full(_("Delete account"), buf,
+                           GTK_STOCK_CANCEL, GTK_STOCK_DELETE, NULL, FALSE,
+                           NULL, ALERT_WARNING, G_ALERTDEFAULT) != G_ALERTALTERNATE)
                return;
 
        if (ac_prefs->folder) {
@@ -969,6 +1039,22 @@ 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);
+               }
+       }
 }
 
 static void account_up(GtkWidget *widget, gpointer data)
@@ -1324,7 +1410,8 @@ 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);
+       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);
        gtk_tree_selection_set_mode(selector, GTK_SELECTION_BROWSE);
@@ -1358,13 +1445,17 @@ static void account_create_list_view_columns(GtkWidget *list_view)
 {
        GtkTreeViewColumn *column;
        GtkCellRenderer *renderer;
+       GtkTooltips *tooltips = gtk_tooltips_new();
 
        renderer = gtk_cell_renderer_pixbuf_new();
        column = gtk_tree_view_column_new_with_attributes
-               ("D", renderer,
+               (Q_("Accounts List Default Column Name|D"), renderer,
                 "pixbuf", ACCOUNT_IS_DEFAULT,
                 NULL);
        gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);           
+       gtk_tree_view_column_set_alignment (column, 0.5);
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips), column->button,
+                       _("Default account"), NULL);
 
        renderer = gtk_cell_renderer_toggle_new();
        g_object_set(renderer, 
@@ -1372,14 +1463,17 @@ static void account_create_list_view_columns(GtkWidget *list_view)
                     "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);
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips), column->button,
+                       _("'Get Mail' retrieves mail from the checked accounts"), NULL);
        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,