Fix wrong time unit shown in offline-override dialog (IMAP), and
[claws.git] / src / inc.c
index 5761f7750739d58feb0d6fb7fcc005be097e335a..ed681fb3ab85c6200ca00dd611dfc4e518393447 100644 (file)
--- a/src/inc.c
+++ b/src/inc.c
@@ -39,6 +39,7 @@
 #include "prefs_account.h"
 #include "account.h"
 #include "procmsg.h"
+#include "proxy.h"
 #include "socket.h"
 #include "ssl.h"
 #include "pop.h"
@@ -64,6 +65,9 @@ extern SessionStats session_stats;
 
 static GList *inc_dialog_list = NULL;
 
+static time_t inc_offline_overridden_yes = 0;
+static time_t inc_offline_overridden_no  = 0;
+
 guint inc_lock_count = 0;
 
 static GdkPixbuf *currentpix;
@@ -132,7 +136,6 @@ static gint get_spool                       (FolderItem     *dest,
                                         PrefsAccount   *account);
 
 static gint inc_spool_account(PrefsAccount *account);
-static gint inc_all_spool(void);
 static void inc_autocheck_timer_set_interval   (guint           interval);
 static gint inc_autocheck_func                 (gpointer        data);
 
@@ -172,6 +175,7 @@ static void inc_finished(MainWindow *mainwin, gboolean new_messages, gboolean au
                folderview_unselect(mainwin->folderview);
                folderview_select(mainwin->folderview, item);
        }
+       statusbar_progress_all(0,0,0);
 }
 
 void inc_mail(MainWindow *mainwin, gboolean notify)
@@ -308,14 +312,13 @@ gint inc_account_mail(MainWindow *mainwin, PrefsAccount *account)
        return new_msgs;
 }
 
-void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
+void inc_account_list_mail(MainWindow *mainwin, GList *account_list, gboolean autocheck,
                          gboolean notify)
 {
        GList *list, *queue_list = NULL;
        IncProgressDialog *inc_dialog;
-       gint new_msgs = 0;
-       gint account_new_msgs = 0;
-       
+       gint new_msgs = 0, num;
+
        if (prefs_common.work_offline && 
            !inc_offline_should_override( (autocheck == FALSE),
                _("Claws Mail needs network access in order "
@@ -324,16 +327,13 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
 
        if (inc_lock_count) return;
 
-       inc_autocheck_timer_remove();
        main_window_lock(mainwin);
 
-       list = account_get_list();
-       if (!list) {
+       if (!account_list) {
                inc_update_stats(new_msgs);
                inc_finished(mainwin, new_msgs > 0, autocheck);
                main_window_unlock(mainwin);
                inc_notify_cmd(new_msgs, notify);
-               inc_autocheck_timer_set();
                return;
        }
 
@@ -343,39 +343,57 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
                        log_error(LOG_PROTOCOL, _("%s failed\n"), prefs_common.extinc_cmd);
                        
                        main_window_unlock(mainwin);
-                       inc_autocheck_timer_set();
                        return;
                }
        }
-       
-       /* check local folders */
-       account_new_msgs = inc_all_spool();
-       if (account_new_msgs > 0)
-               new_msgs += account_new_msgs;
 
-       /* check IMAP4 / News folders */
-       for (list = account_get_list(); list != NULL; list = list->next) {
+       /* Check all accounts in the list, one by one. */
+       for (list = account_list; list != NULL; list = list->next) {
                PrefsAccount *account = list->data;
-               if ((account->protocol == A_IMAP4 ||
-                    account->protocol == A_NNTP) && account->recv_at_getall) {
-                       new_msgs += folderview_check_new(FOLDER(account->folder));
+
+               if (account == NULL) {
+                       debug_print("INC: Huh? inc_account_list_mail() got a NULL account, this should not happen!\n");
+                       continue;
                }
-       }
 
-       /* check POP3 accounts */
-       for (list = account_get_list(); list != NULL; list = list->next) {
-               IncSession *session;
-               PrefsAccount *account = list->data;
+               debug_print("INC: checking account %d\n", account->account_id);
+               switch (account->protocol) {
+                       case A_POP3:
+                               if (!(account->receive_in_progress)) {
+                                       IncSession *session = inc_session_new(account);
+
+                                       if (session != NULL) {
+                                               debug_print("INC: adding POP3 account %d to inc queue\n",
+                                                               account->account_id);
+                                               queue_list = g_list_append(queue_list, session);
+                                       }
+                               }
+                               break;
 
-               if (account->recv_at_getall) {
-                       if (!(account->receive_in_progress)) {
-                               session = inc_session_new(account);
-                               if (session)
-                                       queue_list = g_list_append(queue_list, session);
-                       }
+                       case A_IMAP4:
+                       case A_NNTP:
+                               new_msgs += folderview_check_new(FOLDER(account->folder));
+                               break;
+
+                       case A_LOCAL:
+                               num = inc_spool_account(account);
+                               if (num > 0)
+                                       new_msgs += num;
+                               break;
+
+                       case A_NONE:
+                               /* Nothing to do here, it's a SMTP-only account. */
+                               break;
+
+                       default:
+                               debug_print("INC: encountered account %d with unknown protocol %d, ignoring\n",
+                                               account->account_id, account->protocol);
+                               break;
                }
        }
 
+
+
        if (queue_list) {
                inc_dialog = inc_progress_dialog_create(autocheck);
                inc_dialog->queue_list = queue_list;
@@ -391,7 +409,45 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
        inc_finished(mainwin, new_msgs > 0, autocheck);
        main_window_unlock(mainwin);
        inc_notify_cmd(new_msgs, notify);
-       inc_autocheck_timer_set();
+}
+
+void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
+                         gboolean notify)
+{
+       GList *list, *list2 = NULL;
+       gboolean condition;
+
+       debug_print("INC: inc_all_account_mail(), autocheck: %s\n",
+                       autocheck ? "YES" : "NO");
+
+       /* Collect list of accounts which use the global autocheck interval. */
+       for (list = account_get_list(); list != NULL; list = list->next) {
+               PrefsAccount *account = list->data;
+
+               /* Nothing to do for SMTP-only accounts. */
+               if (account->protocol == A_NONE)
+                       continue;
+
+               /* Set up condition which decides whether or not to check
+                * this account, based on whether we're doing global autocheck
+                * or a manual 'Get all' check. */
+               if (autocheck)
+                       condition = prefs_common_get_prefs()->autochk_newmail
+                               && account->autochk_use_default;
+               else
+                       condition = account->recv_at_getall;
+
+               if (condition) {
+                       debug_print("INC: will check account %d\n", account->account_id);
+                       list2 = g_list_append(list2, account);
+               }
+       }
+
+       /* Do the check on the collected accounts. */
+       if (list2 != NULL) {
+               inc_account_list_mail(mainwin, list2, autocheck, notify);
+               g_list_free(list2);
+       }
 }
 
 static void inc_progress_dialog_size_allocate_cb(GtkWidget *widget,
@@ -782,32 +838,34 @@ static IncState inc_pop3_session_do(IncSession *session)
 {
        Pop3Session *pop3_session = POP3_SESSION(session->session);
        IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data;
+       PrefsAccount *ac = pop3_session->ac_prefs;
        gchar *server;
        gchar *account_name;
        gushort port;
        gchar *buf;
+       ProxyInfo *proxy_info = NULL;
 
        debug_print("getting new messages of account %s...\n",
-                   pop3_session->ac_prefs->account_name);
+                   ac->account_name);
                    
-       pop3_session->ac_prefs->last_pop_login_time = time(NULL);
+       ac->last_pop_login_time = time(NULL);
 
        buf = g_strdup_printf(_("%s: Retrieving new messages"),
-                             pop3_session->ac_prefs->recv_server);
+                             ac->recv_server);
        gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), buf);
        g_free(buf);
 
-       server = pop3_session->ac_prefs->recv_server;
-       account_name = pop3_session->ac_prefs->account_name;
+       server = ac->recv_server;
+       account_name = ac->account_name;
        port = pop3_get_port(pop3_session);
 
 #ifdef USE_GNUTLS
-       SESSION(pop3_session)->ssl_type = pop3_session->ac_prefs->ssl_pop;
-       if (pop3_session->ac_prefs->ssl_pop != SSL_NONE)
+       SESSION(pop3_session)->ssl_type = ac->ssl_pop;
+       if (ac->ssl_pop != SSL_NONE)
                SESSION(pop3_session)->nonblocking =
-                       pop3_session->ac_prefs->use_nonblocking_ssl;
+                       ac->use_nonblocking_ssl;
 #else
-       if (pop3_session->ac_prefs->ssl_pop != SSL_NONE) {
+       if (ac->ssl_pop != SSL_NONE) {
                if (alertpanel_full(_("Insecure connection"),
                        _("This connection is configured to be secured "
                          "using SSL/TLS, but SSL/TLS is not available "
@@ -828,6 +886,22 @@ static IncState inc_pop3_session_do(IncSession *session)
        log_message(LOG_PROTOCOL, "%s\n", buf);
 
        progress_dialog_set_label(inc_dialog->dialog, buf);
+
+       if (ac->use_proxy) {
+               if (ac->use_default_proxy) {
+                       proxy_info = (ProxyInfo *)&(prefs_common.proxy_info);
+                       if (proxy_info->use_proxy_auth)
+                               proxy_info->proxy_pass = passwd_store_get(PWS_CORE, PWS_CORE_PROXY,
+                                       PWS_CORE_PROXY_PASS);
+               } else {
+                       proxy_info = (ProxyInfo *)&(ac->proxy_info);
+                       if (proxy_info->use_proxy_auth)
+                               proxy_info->proxy_pass = passwd_store_get_account(ac->account_id,
+                                       PWS_ACCOUNT_PROXY_PASS);
+               }
+       }
+       SESSION(pop3_session)->proxy_info = proxy_info;
+
        GTK_EVENTS_FLUSH();
        g_free(buf);
 
@@ -1331,29 +1405,6 @@ static gint inc_spool_account(PrefsAccount *account)
        return result;
 }
 
-static gint inc_all_spool(void)
-{
-       GList *list = NULL;
-       gint new_msgs = 0;
-       gint account_new_msgs = 0;
-
-       list = account_get_list();
-       if (!list) return 0;
-
-       for (; list != NULL; list = list->next) {
-               PrefsAccount *account = list->data;
-
-               if ((account->protocol == A_LOCAL) &&
-                   (account->recv_at_getall)) {
-                       account_new_msgs = inc_spool_account(account);
-                       if (account_new_msgs > 0)
-                               new_msgs += account_new_msgs;
-               }
-       }
-
-       return new_msgs;
-}
-
 static gint get_spool(FolderItem *dest, const gchar *mbox, PrefsAccount *account)
 {
        gint msgs, size;
@@ -1444,20 +1495,23 @@ void inc_autocheck_timer_init(MainWindow *mainwin)
        inc_autocheck_timer_set();
 }
 
-static void inc_autocheck_timer_set_interval(guint interval)
+static void inc_autocheck_timer_set_interval(guint _interval)
 {
+       guint interval = _interval;
+
+       /* Convert the interval to seconds if needed. */
+       if (_interval % 1000 == 0)
+               interval /= 1000;
+
        inc_autocheck_timer_remove();
        /* last test is to avoid re-enabling auto_check after modifying 
           the common preferences */
        if (prefs_common.autochk_newmail && autocheck_data
            && prefs_common.work_offline == FALSE) {
-               if (interval % 1000 == 0)
                        autocheck_timer =
-                               g_timeout_add_seconds(interval/1000, inc_autocheck_func, autocheck_data);
-               else
-                       autocheck_timer = g_timeout_add
-                               (interval, inc_autocheck_func, autocheck_data);
-               debug_print("added timer = %d\n", autocheck_timer);
+                               g_timeout_add_seconds(interval, inc_autocheck_func, autocheck_data);
+               debug_print("added global inc timer %d at %u seconds\n",
+                               autocheck_timer, interval);
        }
 }
 
@@ -1469,7 +1523,7 @@ void inc_autocheck_timer_set(void)
 void inc_autocheck_timer_remove(void)
 {
        if (autocheck_timer) {
-               debug_print("removed timer = %d\n", autocheck_timer);
+               debug_print("removed global inc timer %d\n", autocheck_timer);
                g_source_remove(autocheck_timer);
                autocheck_timer = 0;
        }
@@ -1480,21 +1534,69 @@ static gint inc_autocheck_func(gpointer data)
        MainWindow *mainwin = (MainWindow *)data;
 
        if (inc_lock_count) {
-               debug_print("autocheck is locked.\n");
+               debug_print("global inc: autocheck is locked.\n");
                inc_autocheck_timer_set_interval(1000);
                return FALSE;
        }
 
        inc_all_account_mail(mainwin, TRUE, prefs_common.newmail_notify_auto);
+       inc_autocheck_timer_set();
+
+       return FALSE;
+}
+
+static gboolean inc_account_autocheck_func(gpointer data)
+{
+       PrefsAccount *account = (PrefsAccount *)data;
+       GList *list = NULL;
+
+       cm_return_val_if_fail(account != NULL, FALSE);
+
+       debug_print("account %d: inc_account_autocheck_func\n",
+                       account->account_id);
+
+       list = g_list_append(list, account);
+       inc_account_list_mail(mainwindow_get_mainwindow(),
+                       list, TRUE, prefs_common.newmail_notify_auto);
+       g_list_free(list);
+
+       inc_account_autocheck_timer_set_interval(account);
 
        return FALSE;
 }
 
+void inc_account_autocheck_timer_remove(PrefsAccount *account)
+{
+       cm_return_if_fail(account != NULL);
+
+       if (account->autocheck_timer != 0) {
+               g_source_remove(account->autocheck_timer);
+               debug_print("INC: account %d: removed inc timer %d\n", account->account_id,
+                               account->autocheck_timer);
+               account->autocheck_timer = 0;
+       }
+}
+
+void inc_account_autocheck_timer_set_interval(PrefsAccount *account)
+{
+       cm_return_if_fail(account != NULL);
+
+       inc_account_autocheck_timer_remove(account);
+
+       if (account->autochk_use_default
+                       || !account->autochk_use_custom
+                       || account->autochk_itv == 0)
+               return;
+
+       account->autocheck_timer = g_timeout_add_seconds(
+                       account->autochk_itv, inc_account_autocheck_func, account);
+       debug_print("INC: account %d: added inc timer %d at %u seconds\n",
+                       account->account_id, account->autocheck_timer, account->autochk_itv);
+}
+
 gboolean inc_offline_should_override(gboolean force_ask, const gchar *msg)
 {
-       static time_t overridden_yes = 0;
-       static time_t overridden_no  = 0;
-       int length = 10; /* minutes */
+       gint length = 10; /* seconds */
        gint answer = G_ALERTDEFAULT;
 
 #ifdef HAVE_NETWORKMANAGER_SUPPORT
@@ -1504,27 +1606,51 @@ gboolean inc_offline_should_override(gboolean force_ask, const gchar *msg)
 #endif
 
        if (prefs_common.autochk_newmail)
-               length = prefs_common.autochk_itv; /* minutes */
+               length = prefs_common.autochk_itv; /* seconds */
 
        if (force_ask) {
-               overridden_no = (time_t)0;
+               inc_offline_overridden_no = (time_t)0;
        }
 
        if (prefs_common.work_offline) {
                gchar *tmp = NULL;
                
-               if (time(NULL) - overridden_yes < length * 60) /* seconds */
+               if (time(NULL) - inc_offline_overridden_yes < length * 60) /* seconds */
                         return TRUE;
-               else if (time(NULL) - overridden_no < length * 60) /* seconds */
+               else if (time(NULL) - inc_offline_overridden_no < length * 60) /* seconds */
                         return FALSE;
 
-               if (!force_ask)
+               if (!force_ask) {
+                       gchar *unit = _("seconds");
+
+                       /* show the offline override time (length) using the must appropriate unit:
+                          the biggest unit possible (hours, minutes, seconds), provided that there
+                          is not inferior unit involved: 1 hour, 150 minutes, 25 minutes, 90 minutes,
+                          30 seconds, 90 seconds. */
+                       if ((length / 3600) > 0) { /* hours? */
+                               if (((length % 3600) % 60) == 0) { /* no seconds left? */
+                                       if ((length % 3600) > 0) { /* minutes left? */
+                                               length = length / 60;
+                                               unit = ngettext("minute", "minutes", length);
+                                       } else {
+                                               length = length / 3600;
+                                               unit = ngettext("hour", "hours", length);
+                                       }
+                               } /* else: seconds */
+                       } else {
+                               if ((length / 60) > 0) { /* minutes left? */
+                                       if ((length % 60) == 0) {
+                                               length = length / 60;
+                                               unit = ngettext("minute", "minutes", length);
+                                       }
+                               } /* else: seconds */
+                       }
                        tmp = g_strdup_printf(
-                               _("%s%sYou're working offline. Override for %d minutes?"),
+                               _("%s%sYou're working offline. Override for %d %s?"),
                                msg?msg:"", 
                                msg?"\n\n":"",
-                               length);
-               else
+                               length, unit);
+               else
                        tmp = g_strdup_printf(
                                _("%s%sYou're working offline. Override?"),
                                msg?msg:"", 
@@ -1532,21 +1658,27 @@ gboolean inc_offline_should_override(gboolean force_ask, const gchar *msg)
 
                answer = alertpanel(_("Offline warning"), 
                               tmp,
-                              GTK_STOCK_NO, "+" GTK_STOCK_YES, 
-                               !force_ask? _("On_ly once"):NULL);
+                              GTK_STOCK_NO, GTK_STOCK_YES,
+                               !force_ask? _("On_ly once"):NULL, ALERTFOCUS_SECOND);
                g_free(tmp);
                if (answer == G_ALERTALTERNATE) {
-                       overridden_yes = time(NULL);
+                       inc_offline_overridden_yes = time(NULL);
                        return TRUE;
                } else if (answer == G_ALERTDEFAULT) {
                        if (!force_ask)
-                               overridden_no  = time(NULL);
+                               inc_offline_overridden_no  = time(NULL);
                        return FALSE;
                } else {
-                       overridden_yes = (time_t)0;
-                       overridden_no  = (time_t)0;
+                       inc_reset_offline_override_timers();
                        return TRUE;
                }
        }
        return TRUE;
 }
+
+void inc_reset_offline_override_timers()
+{
+       debug_print("resetting offline override timers\n");
+       inc_offline_overridden_yes = (time_t)0;
+       inc_offline_overridden_no  = (time_t)0;
+}