in the UI replace 'POP3' with 'POP' and 'IMAP4' with 'IMAP'
[claws.git] / src / account.c
index 3706c03eb3f17e63d71d153aefb2fdfbd28af859..9c34f971cdb7aaec4cd59807bec978d5a4abade0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2009 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2015 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
@@ -19,6 +19,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
+#include "claws-features.h"
 #endif
 
 #include "defs.h"
@@ -51,6 +52,9 @@
 #include "remotefolder.h"
 #include "manual.h"
 #include "filtering.h"
+#include "prefs_actions.h"
+#include "hooks.h"
+#include "passwordstore.h"
 
 enum {
        ACCOUNT_IS_DEFAULT,
@@ -106,11 +110,9 @@ static gint account_delete_event   (GtkWidget      *widget,
                                         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);
@@ -209,7 +211,7 @@ void account_read_config_all(void)
        while (fgets(buf, sizeof(buf), fp) != NULL) {
                if (!strncmp(buf, "[Account: ", 10)) {
                        strretchomp(buf);
-                       memmove(buf, buf + 1, strlen(buf));
+                       memmove(buf, buf + 1, sizeof(buf) - 1);
                        buf[strlen(buf) - 1] = '\0';
                        debug_print("Found label: %s\n", buf);
                        ac_label_list = g_slist_append(ac_label_list,
@@ -282,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;
@@ -308,7 +310,7 @@ PrefsAccount *account_find_from_address(const gchar *address, gboolean newsgroup
        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;
@@ -338,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) {
@@ -372,6 +374,18 @@ GList *account_get_list(void)
        return account_list;
 }
 
+void account_edit_focus(void)
+{
+       if (edit_account.window == NULL) {
+               return;
+       }
+       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);
+}
+
 void account_edit_open(gpointer a, gpointer b)
 {
        inc_lock();
@@ -381,7 +395,7 @@ void account_edit_open(gpointer a, gpointer b)
        if (compose_get_compose_list()) {
                alertpanel_error(_("Some composing windows are open.\n"
                                   "Please close all the composing "
-                                  "windows before editing the accounts."));
+                                  "windows before editing accounts."));
                inc_unlock();
                return;
        }
@@ -393,11 +407,7 @@ void account_edit_open(gpointer a, gpointer b)
 
        account_list_view_set();
 
-       manage_window_set_transient(GTK_WINDOW(edit_account.window));
-       gtk_widget_grab_focus(edit_account.close_btn);
-       gtk_widget_show(edit_account.window);
-
-       manage_window_focus_in(edit_account.window, NULL, NULL);
+       account_edit_focus();
 }
 
 void account_add(void)
@@ -408,6 +418,8 @@ void account_add(void)
 
        if (!ac_prefs) return;
 
+       account_edit_focus();
+
        account_list = g_list_append(account_list, ac_prefs);
 
        if (ac_prefs->is_default)
@@ -442,10 +454,17 @@ void account_add(void)
 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);
+
+       if (compose_get_compose_list()) {
+               alertpanel_error(_("Some composing windows are open.\n"
+                                  "Please close all the composing "
+                                  "windows before editing accounts."));
+               return;
+       }
 
        prev_default = ac_prefs->is_default;
        Xstrdup_a(ac_name, ac_prefs->account_name ? ac_prefs->account_name : "",
@@ -453,14 +472,26 @@ void account_open(PrefsAccount *ac_prefs)
 
        prefs_account_open(ac_prefs, &account_dirty);
 
+       account_edit_focus();
+
        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) {
+                       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(old_prefix, new_prefix);
+                       prefs_filtering_rename_path(old_prefix, new_prefix);
+                       prefs_actions_rename_path(old_prefix, new_prefix);
+                       
+                       g_free(old_prefix);
+                       g_free(new_prefix);
                }
 
                account_write_config_all();
@@ -557,14 +588,12 @@ void account_rename_path(const gchar *old_id, const gchar *new_id)
        }
 }
 
-#undef CHECK_CHANGE_FOLDER
-
 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:
@@ -638,11 +667,10 @@ 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);
 
-       prefs_account_free(ac_prefs);
        account_list = g_list_remove(account_list, ac_prefs);
 
        if (cur_account == ac_prefs) cur_account = NULL;
@@ -662,7 +690,7 @@ void account_destroy(PrefsAccount *ac_prefs)
 static void account_size_allocate_cb(GtkWidget *widget,
                                         GtkAllocation *allocation)
 {
-       g_return_if_fail(allocation != NULL);
+       cm_return_if_fail(allocation != NULL);
 
        prefs_common.accountswin_width = allocation->width;
        prefs_common.accountswin_height = allocation->height;
@@ -698,15 +726,10 @@ static void account_edit_create(void)
        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);
 
@@ -831,9 +854,6 @@ static void account_edit_create(void)
        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)
@@ -853,7 +873,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);
@@ -938,6 +958,7 @@ static void account_clone(GtkWidget *widget, gpointer data)
 
        /* send */
        ACP_FASSIGN(gen_msgid);
+       ACP_FASSIGN(gen_xmailer);
        ACP_FASSIGN(add_customhdr);
        ACP_FASSIGN(use_smtp_auth);
        ACP_FASSIGN(smtp_auth_type);
@@ -1083,6 +1104,10 @@ static void account_delete(GtkWidget *widget, gpointer data)
                                GINT_TO_POINTER(ac_prefs->account_id));
        }
 
+       gchar *uid = g_strdup_printf("%d", ac_prefs->account_id);
+       passwd_store_delete_block(PWS_ACCOUNT, uid);
+       g_free(uid);
+
        debug_print("Removing filter rules relative to this account...\n");
        for(cur = filtering_rules ; cur != NULL ;) {
                FilteringProp * prop = (FilteringProp *) cur->data;
@@ -1215,7 +1240,7 @@ static void account_edit_close(GtkWidget *widget, gpointer data)
                account_flush_state();
 
        gtk_widget_hide(edit_account.window);
-
+       gtk_window_set_modal(GTK_WINDOW(edit_account.window), FALSE);
        inc_unlock();
 }
 
@@ -1225,15 +1250,14 @@ 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) 
@@ -1264,22 +1288,22 @@ static void account_list_view_add(PrefsAccount *ac_prefs)
 #ifdef USE_GNUTLS
        protocol = ac_prefs->protocol == A_POP3 ?
                  (ac_prefs->ssl_pop == SSL_TUNNEL ?
-                  "POP3 (SSL)" :
+                  "POP (SSL/TLS)" :
                   ac_prefs->ssl_pop == SSL_STARTTLS ?
-                  "POP3 (TLS)" : "POP3") :
+                  "POP (STARTTLS)" : "POP") :
                   ac_prefs->protocol == A_IMAP4 ?
                  (ac_prefs->ssl_imap == SSL_TUNNEL ?
-                  "IMAP4 (SSL)" :
+                  "IMAP (SSL/TLS)" :
                   ac_prefs->ssl_imap == SSL_STARTTLS ?
-                  "IMAP4 (TLS)" : "IMAP4") :
+                  "IMAP (STARTTLS)" : "IMAP") :
                   ac_prefs->protocol == A_NNTP ?
                  (ac_prefs->ssl_nntp == SSL_TUNNEL ?
-                  "NNTP (SSL)" : "NNTP") :
+                  "NNTP (SSL/TLS)" : "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" :
+       protocol = ac_prefs->protocol == A_POP3  ? "POP" :
+                  ac_prefs->protocol == A_IMAP4 ? "IMAP" :
                   ac_prefs->protocol == A_LOCAL ? "Local" :
                   ac_prefs->protocol == A_NNTP  ? "NNTP" :
                   ac_prefs->protocol == A_NONE ?  "SMTP" : "-";
@@ -1348,7 +1372,7 @@ static void account_list_set(void)
                GtkTreeIter iter;
 
                if (!gtk_tree_model_iter_nth_child(model, &iter, NULL, row)) {
-                       g_warning("%s(%d) - no iter found???\n", __FILE__, __LINE__);                                         
+                       g_warning("%s(%d) - no iter found???", __FILE__, __LINE__);
                        continue;
                }
        
@@ -1375,30 +1399,41 @@ PrefsAccount *account_get_reply_account(MsgInfo *msginfo, gboolean reply_autosel
        /* select the account set in folderitem's property (if enabled) */
        if (msginfo->folder->prefs && msginfo->folder->prefs->enable_default_account)
                account = account_find_from_id(msginfo->folder->prefs->default_account);
-       
+       else if (folder_has_parent_of_type(msginfo->folder, F_QUEUE) ||
+                folder_has_parent_of_type(msginfo->folder, F_OUTBOX) ||
+                folder_has_parent_of_type(msginfo->folder, F_DRAFT)) {
+                       gchar from[BUFFSIZE];
+                       if (!procheader_get_header_from_msginfo
+                               (msginfo, from, sizeof from, "From:")) {
+                               gchar *buf = from + strlen("From:");
+                               extract_address(buf);
+                               account = account_find_from_address(buf, FALSE);
+                       }
+       }
        /* select account by to: and cc: header if enabled */
        if (reply_autosel) {
                gchar * field = NULL;
                int fieldno = 0;
                for (field = msginfo->to; fieldno++ < 2; field = msginfo->cc) {
                        if (!account && field) {
-                               gchar *to = NULL;
-                               if (!strchr(field, ',')) {
-                                       Xstrdup_a(to, field, return NULL);
-                                       extract_address(to);
-                                       account = account_find_from_address(to, FALSE);
-                               } else {
-                                       gchar **split = g_strsplit(field, ",", -1);
-                                       int i = -1;
+                               gchar *f = g_strdup(field);
+                               if (f) {
+                                       gchar *cur = f;
+                                       gchar *next = NULL;
+                                       gchar *to = NULL;
                                        do {
-                                               i++;
-                                               if (!split[i])
-                                                       break;
-                                               Xstrdup_a(to, split[i], return NULL);
+                                               next = strchr_with_skip_quote(cur, '"', ',');
+                                               if (next)
+                                                       (*next) = 0;
+                                               Xstrdup_a(to, cur, return NULL);
                                                extract_address(to);
                                                account = account_find_from_address(to, FALSE);
+                                               if (next)
+                                                       cur = next + 1;
+                                               else
+                                                       break;
                                        } while (!account);
-                                       g_strfreev(split);
+                                       g_free(f);
                                }
                        }
                }
@@ -1517,7 +1552,6 @@ static void account_create_list_view_columns(GtkWidget *list_view)
 {
        GtkTreeViewColumn *column;
        GtkCellRenderer *renderer;
-       CLAWS_TIP_DECL();
 
        renderer = gtk_cell_renderer_toggle_new();
        g_object_set(renderer, 
@@ -1525,12 +1559,12 @@ static void account_create_list_view_columns(GtkWidget *list_view)
                     "activatable", TRUE,
                      NULL);
        column = gtk_tree_view_column_new_with_attributes
-               (Q_("Accounts List Get Column Name|G"), renderer,
+               (C_("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(column->button,
+       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),
@@ -1792,14 +1826,14 @@ gchar *account_get_signature_str(PrefsAccount *account)
        gchar *sig_str = NULL;
        gchar *utf8_sig_str = NULL;
 
-       g_return_val_if_fail(account != NULL, 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",
+                       g_warning("can't open signature file: '%s'",
                                  account->sig_path);
                        return NULL;
                }
@@ -1842,3 +1876,29 @@ PrefsAccount *account_get_cur_account (void)
 {
        return cur_account;
 }
+
+gboolean password_get(const gchar *user,
+                   const gchar *server,
+                   const gchar *protocol,
+                   guint16 port,
+                   gchar **password)
+{
+       PasswordRequest req;
+
+       /* all have to be set */
+       cm_return_val_if_fail(user != NULL, FALSE);
+       cm_return_val_if_fail(server != NULL, FALSE);
+       cm_return_val_if_fail(protocol != NULL, FALSE);
+       cm_return_val_if_fail(port != 0, FALSE);
+
+       req.user = user;
+       req.server = server;
+       req.protocol = protocol;
+       req.port = port;
+
+       if (hooks_invoke(PASSWORD_GET_HOOKLIST, &req)) {
+               *password = req.password;
+               return TRUE;
+       }
+       return FALSE;
+}