Fix incorporation dialog focus with master passphrase dialog.
[claws.git] / src / inc.c
index d4b80694f00989a67bd3220ad80814421bb483af..6344d22bbf71992eda57d7b0c6040c7b806def9a 100644 (file)
--- a/src/inc.c
+++ b/src/inc.c
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2013 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"
 #include "filtering.h"
 #include "log.h"
 #include "hooks.h"
+#include "logwindow.h"
+#include "passwordstore.h"
 
-#ifdef MAEMO
-#ifdef CHINOOK
-#include <hildon/hildon-banner.h>
-#include <hildon/hildon-sound.h>
-#else
-#include <hildon-widgets/hildon-banner.h>
-#include <hildon-widgets/hildon-system-sound.h>
-#endif
-#include <libosso.h>
-
-#ifdef CONIC
-#include <conicconnection.h>
-#include <conicconnectionevent.h>
-
-static ConIcConnection *maemo_connection = NULL;
-static gboolean maemo_warned_offline = FALSE;
-#endif
-#endif
+extern SessionStats session_stats;
 
 static GList *inc_dialog_list = NULL;
 
@@ -85,8 +71,9 @@ static GdkPixbuf *currentpix;
 static GdkPixbuf *errorpix;
 static GdkPixbuf *okpix;
 
-#define MSGBUFSIZE     8192
+#define MESSAGEBUFSIZE 8192
 
+static void inc_update_stats(gint new_msgs);
 static void inc_finished               (MainWindow             *mainwin,
                                         gboolean                new_messages,
                                         gboolean                autocheck);
@@ -133,6 +120,8 @@ static gint inc_drop_message                (Pop3Session    *session,
 static void inc_put_error              (IncState        istate,
                                         Pop3Session    *session);
 
+static void inc_showlog_cb             (GtkWidget      *widget,
+                                        gpointer        data);
 static void inc_cancel_cb              (GtkWidget      *widget,
                                         gpointer        data);
 static gint inc_dialog_delete_cb       (GtkWidget      *widget,
@@ -150,7 +139,13 @@ static gint inc_autocheck_func                     (gpointer        data);
 
 static void inc_notify_cmd             (gint new_msgs, 
                                         gboolean notify);
-       
+
+static void inc_update_stats(gint new_msgs)
+{
+       /* update session statistics */
+       session_stats.received += new_msgs;
+}
+
 /**
  * inc_finished:
  * @mainwin: Main window.
@@ -170,7 +165,7 @@ static void inc_finished(MainWindow *mainwin, gboolean new_messages, gboolean au
 
                if (cur_account && cur_account->inbox)
                        item = folder_find_item_from_identifier(cur_account->inbox);
-               if (item == NULL && cur_account->folder)
+               if (item == NULL && cur_account && cur_account->folder)
                        item = cur_account->folder->inbox;
                if (item == NULL)
                        item = folder_get_default_inbox();
@@ -211,6 +206,7 @@ void inc_mail(MainWindow *mainwin, gboolean notify)
                        new_msgs += account_new_msgs;
        }
 
+       inc_update_stats(new_msgs);
        inc_finished(mainwin, new_msgs > 0, FALSE);
        main_window_unlock(mainwin);
        inc_notify_cmd(new_msgs, notify);
@@ -293,6 +289,8 @@ gint inc_account_mail(MainWindow *mainwin, PrefsAccount *account)
 
        if (inc_lock_count) return 0;
 
+       if (account->receive_in_progress) return 0;
+
        if (prefs_common.work_offline && 
            !inc_offline_should_override(TRUE,
                _("Claws Mail needs network access in order "
@@ -304,6 +302,7 @@ gint inc_account_mail(MainWindow *mainwin, PrefsAccount *account)
 
        new_msgs = inc_account_mail_real(mainwin, account);
 
+       inc_update_stats(new_msgs);
        inc_finished(mainwin, new_msgs > 0, FALSE);
        main_window_unlock(mainwin);
        inc_autocheck_timer_set();
@@ -332,6 +331,7 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
 
        list = account_get_list();
        if (!list) {
+               inc_update_stats(new_msgs);
                inc_finished(mainwin, new_msgs > 0, autocheck);
                main_window_unlock(mainwin);
                inc_notify_cmd(new_msgs, notify);
@@ -370,9 +370,11 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
                PrefsAccount *account = list->data;
 
                if (account->recv_at_getall) {
-                       session = inc_session_new(account);
-                       if (session)
-                               queue_list = g_list_append(queue_list, session);
+                       if (!(account->receive_in_progress)) {
+                               session = inc_session_new(account);
+                               if (session)
+                                       queue_list = g_list_append(queue_list, session);
+                       }
                }
        }
 
@@ -387,6 +389,7 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
                new_msgs += inc_start(inc_dialog);
        }
 
+       inc_update_stats(new_msgs);
        inc_finished(mainwin, new_msgs > 0, autocheck);
        main_window_unlock(mainwin);
        inc_notify_cmd(new_msgs, notify);
@@ -396,7 +399,7 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
 static void inc_progress_dialog_size_allocate_cb(GtkWidget *widget,
                                         GtkAllocation *allocation)
 {
-       g_return_if_fail(allocation != NULL);
+       cm_return_if_fail(allocation != NULL);
 
        prefs_common.receivewin_width = allocation->width;
        prefs_common.receivewin_height = allocation->height;
@@ -413,6 +416,8 @@ static IncProgressDialog *inc_progress_dialog_create(gboolean autocheck)
        progress = progress_dialog_create();
        gtk_window_set_title(GTK_WINDOW(progress->window),
                             _("Retrieving new messages"));
+       g_signal_connect(G_OBJECT(progress->showlog_btn), "clicked",
+                        G_CALLBACK(inc_showlog_cb), dialog);
        g_signal_connect(G_OBJECT(progress->cancel_btn), "clicked",
                         G_CALLBACK(inc_cancel_cb), dialog);
        g_signal_connect(G_OBJECT(progress->window), "delete_event",
@@ -485,7 +490,7 @@ static void inc_progress_dialog_clear(IncProgressDialog *inc_dialog)
 
 static void inc_progress_dialog_destroy(IncProgressDialog *inc_dialog)
 {
-       g_return_if_fail(inc_dialog != NULL);
+       cm_return_if_fail(inc_dialog != NULL);
 
        inc_dialog_list = g_list_remove(inc_dialog_list, inc_dialog);
 
@@ -500,7 +505,7 @@ static IncSession *inc_session_new(PrefsAccount *account)
 {
        IncSession *session;
 
-       g_return_val_if_fail(account != NULL, NULL);
+       cm_return_val_if_fail(account != NULL, NULL);
 
        if (account->protocol != A_POP3)
                return NULL;
@@ -525,12 +530,24 @@ static IncSession *inc_session_new(PrefsAccount *account)
 
 static void inc_session_destroy(IncSession *session)
 {
-       g_return_if_fail(session != NULL);
+       cm_return_if_fail(session != NULL);
 
        session_destroy(session->session);
        g_free(session);
 }
 
+static gint pop3_get_port(Pop3Session *pop3_session)
+{
+#ifdef USE_GNUTLS
+       return pop3_session->ac_prefs->set_popport ?
+               pop3_session->ac_prefs->popport :
+               pop3_session->ac_prefs->ssl_pop == SSL_TUNNEL ? 995 : 110;
+#else
+       return pop3_session->ac_prefs->set_popport ?
+               pop3_session->ac_prefs->popport : 110;
+#endif
+}
+
 static gint inc_start(IncProgressDialog *inc_dialog)
 {
        IncSession *session;
@@ -552,32 +569,36 @@ static gint inc_start(IncProgressDialog *inc_dialog)
                session = qlist->data;
                pop3_session = POP3_SESSION(session->session); 
                pop3_session->user = g_strdup(pop3_session->ac_prefs->userid);
-               if (pop3_session->ac_prefs->passwd)
-                       pop3_session->pass =
-                               g_strdup(pop3_session->ac_prefs->passwd);
-               else {
-                       gchar *pass;
 
-                       if (inc_dialog->show_dialog)
-                               manage_window_focus_in
-                                       (inc_dialog->dialog->window,
-                                        NULL, NULL);
+               if (inc_dialog->show_dialog)
+                       manage_window_focus_in
+                               (inc_dialog->dialog->window,
+                                NULL, NULL);
+
+               if (password_get(pop3_session->user,
+                                       pop3_session->ac_prefs->recv_server,
+                                       "pop3", pop3_get_port(pop3_session),
+                                       &(pop3_session->pass))) {
+                       /* NOP */;
+               } else if ((pop3_session->pass = passwd_store_get_account(
+                                               pop3_session->ac_prefs->account_id, PWS_ACCOUNT_RECV)) == NULL) {
+                       gchar *pass;
 
                        pass = input_dialog_query_password_keep
                                (pop3_session->ac_prefs->recv_server,
                                 pop3_session->user,
                                 &(pop3_session->ac_prefs->session_passwd));
 
-                       if (inc_dialog->show_dialog)
-                               manage_window_focus_out
-                                       (inc_dialog->dialog->window,
-                                        NULL, NULL);
-
                        if (pass) {
                                pop3_session->pass = pass;
                        }
                }
 
+               if (inc_dialog->show_dialog)
+                       manage_window_focus_out
+                               (inc_dialog->dialog->window,
+                                NULL, NULL);
+
                qlist = next;
        }
 
@@ -677,7 +698,7 @@ static gint inc_start(IncProgressDialog *inc_dialog)
                        inbox = folder_get_default_inbox();
 
                /* get list of messages in processing */
-               processing = folder_get_default_processing();
+               processing = folder_get_default_processing(pop3_session->ac_prefs->account_id);
                folder_item_scan(processing);
                msglist = folder_item_get_msg_list(processing);
 
@@ -694,8 +715,7 @@ static gint inc_start(IncProgressDialog *inc_dialog)
 
                for(msglist_element = msglist; msglist_element != NULL; 
                    msglist_element = msglist_element->next) {
-                       MsgInfo *msginfo = (MsgInfo *)msglist_element->data;
-                       procmsg_msginfo_free(msginfo);
+                       procmsg_msginfo_free((MsgInfo**)&(msglist_element->data));
                }
                folder_item_update_thaw();
                
@@ -768,6 +788,7 @@ static IncState inc_pop3_session_do(IncSession *session)
        Pop3Session *pop3_session = POP3_SESSION(session->session);
        IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data;
        gchar *server;
+       gchar *account_name;
        gushort port;
        gchar *buf;
 
@@ -782,10 +803,10 @@ static IncState inc_pop3_session_do(IncSession *session)
        g_free(buf);
 
        server = pop3_session->ac_prefs->recv_server;
-#if (defined(USE_OPENSSL) || defined (USE_GNUTLS))
-       port = pop3_session->ac_prefs->set_popport ?
-               pop3_session->ac_prefs->popport :
-               pop3_session->ac_prefs->ssl_pop == SSL_TUNNEL ? 995 : 110;
+       account_name = pop3_session->ac_prefs->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)->nonblocking =
@@ -804,11 +825,10 @@ static IncState inc_pop3_session_do(IncSession *session)
                          G_ALERTDEFAULT) != G_ALERTALTERNATE)
                        return INC_CANCEL;
        }
-       port = pop3_session->ac_prefs->set_popport ?
-               pop3_session->ac_prefs->popport : 110;
 #endif
 
-       buf = g_strdup_printf(_("Connecting to POP3 server: %s..."), server);
+       buf = g_strdup_printf(_("Account '%s': Connecting to POP3 server: %s:%d..."),
+                               account_name, server, port);
        statuswindow_print_all("%s", buf);
        log_message(LOG_PROTOCOL, "%s\n", buf);
 
@@ -837,7 +857,7 @@ static IncState inc_pop3_session_do(IncSession *session)
                return INC_CONNECT_ERROR;
        }
 
-       while (session_is_connected(SESSION(pop3_session)) &&
+       while (session_is_running(SESSION(pop3_session)) &&
               session->inc_state != INC_CANCEL)
                gtk_main_iteration();
 
@@ -899,7 +919,7 @@ static void inc_progress_dialog_set_label(IncProgressDialog *inc_dialog,
        ProgressDialog *dialog = inc_dialog->dialog;
        Pop3Session *session;
 
-       g_return_if_fail(inc_session != NULL);
+       cm_return_if_fail(inc_session != NULL);
 
        session = POP3_SESSION(inc_session->session);
 
@@ -911,7 +931,7 @@ static void inc_progress_dialog_set_label(IncProgressDialog *inc_dialog,
        case POP3_GETAUTH_APOP:
                progress_dialog_set_label(dialog, _("Authenticating..."));
                statuswindow_pop_all();
-               statusbar_print_all(_("Retrieving messages from %s (%s) ..."),
+               statusbar_print_all(_("Retrieving messages from %s (%s)..."),
                                    SESSION(session)->server,
                                    session->ac_prefs->account_name);
                break;
@@ -946,7 +966,7 @@ static void inc_progress_dialog_set_label(IncProgressDialog *inc_dialog,
 static void inc_progress_dialog_set_progress(IncProgressDialog *inc_dialog,
                                             IncSession *inc_session)
 {
-       gchar buf[MSGBUFSIZE];
+       gchar buf[MESSAGEBUFSIZE];
        Pop3Session *pop3_session = POP3_SESSION(inc_session->session);
        gchar *total_size_str;
        gint cur_total;
@@ -970,13 +990,7 @@ static void inc_progress_dialog_set_progress(IncProgressDialog *inc_dialog,
        progress_dialog_set_fraction
                (inc_dialog->dialog, (total == 0) ? 0: (gfloat)cur_total / (gfloat)total);
 
-       g_snprintf(buf, sizeof(buf), "%d / %d",
-                  pop3_session->cur_msg, pop3_session->count);
-       gtk_progress_bar_set_text
-               (GTK_PROGRESS_BAR(inc_dialog->mainwin->progressbar), buf);
-       gtk_progress_bar_set_fraction
-               (GTK_PROGRESS_BAR(inc_dialog->mainwin->progressbar),
-                (total == 0) ? 0 : (gfloat)cur_total / (gfloat)total);
+       statusbar_progress_all(pop3_session->cur_msg, pop3_session->count, 1);
 
        if (pop3_session->cur_total_num > 0) {
                g_snprintf(buf, sizeof(buf),
@@ -1024,7 +1038,7 @@ static gint inc_recv_data_progressive(Session *session, guint cur_len,
        IncProgressDialog *inc_dialog;
        gint cur_total;
 
-       g_return_val_if_fail(inc_session != NULL, -1);
+       cm_return_val_if_fail(inc_session != NULL, -1);
 
        if (pop3_session->state != POP3_RETR &&
            pop3_session->state != POP3_RETR_RECV &&
@@ -1049,7 +1063,7 @@ static gint inc_recv_data_finished(Session *session, guint len, gpointer data)
        IncSession *inc_session = (IncSession *)data;
        IncProgressDialog *inc_dialog;
 
-       g_return_val_if_fail(inc_session != NULL, -1);
+       cm_return_val_if_fail(inc_session != NULL, -1);
 
        inc_dialog = (IncProgressDialog *)inc_session->data;
 
@@ -1067,7 +1081,7 @@ static gint inc_recv_message(Session *session, const gchar *msg, gpointer data)
        IncSession *inc_session = (IncSession *)data;
        IncProgressDialog *inc_dialog;
 
-       g_return_val_if_fail(inc_session != NULL, -1);
+       cm_return_val_if_fail(inc_session != NULL, -1);
 
        inc_dialog = (IncProgressDialog *)inc_session->data;
 
@@ -1101,7 +1115,7 @@ static gint inc_drop_message(Pop3Session *session, const gchar *file)
        IncSession *inc_session = (IncSession *)(SESSION(session)->data);
        gint msgnum;
 
-       g_return_val_if_fail(inc_session != NULL, -1);
+       cm_return_val_if_fail(inc_session != NULL, -1);
 
        if (session->ac_prefs->inbox) {
                inbox = folder_find_item_from_identifier
@@ -1116,7 +1130,7 @@ static gint inc_drop_message(Pop3Session *session, const gchar *file)
        }
 
        /* CLAWS: claws uses a global .processing folder for the filtering. */
-       dropfolder = folder_get_default_processing();
+       dropfolder = folder_get_default_processing(session->ac_prefs->account_id);
 
        /* add msg file to drop folder */
        if ((msgnum = folder_item_add_msg(
@@ -1136,7 +1150,6 @@ static void inc_put_error(IncState istate, Pop3Session *session)
 
        switch (istate) {
        case INC_CONNECT_ERROR:
-               log_msg = _("Connection failed.");
                fatal_error = TRUE;
                if (prefs_common.no_recv_err_panel)
                        break;
@@ -1206,7 +1219,7 @@ static void inc_put_error(IncState istate, Pop3Session *session)
        case INC_TIMEOUT:
                log_msg = _("Session timed out. You may be able to "
                            "recover by increasing the timeout value in "
-                           "Preferences/Other.");
+                           "Preferences/Other/Miscellaneous.");
                if (prefs_common.no_recv_err_panel)
                        break;
                err_msg = g_strdup_printf(_("Connection to %s:%d timed out."), 
@@ -1236,7 +1249,7 @@ static void inc_cancel(IncProgressDialog *dialog)
 {
        IncSession *session;
 
-       g_return_if_fail(dialog != NULL);
+       cm_return_if_fail(dialog != NULL);
 
        if (dialog->queue_list == NULL) {
                inc_progress_dialog_destroy(dialog);
@@ -1263,6 +1276,13 @@ void inc_cancel_all(void)
                inc_cancel((IncProgressDialog *)cur->data);
 }
 
+static void inc_showlog_cb(GtkWidget *widget, gpointer data)
+{
+       MainWindow *mainwin = mainwindow_get_mainwindow();
+
+       log_window_show(mainwin->logwin);
+}
+
 static void inc_cancel_cb(GtkWidget *widget, gpointer data)
 {
        inc_cancel((IncProgressDialog *)data);
@@ -1345,9 +1365,9 @@ static gint get_spool(FolderItem *dest, const gchar *mbox, PrefsAccount *account
        gint lockfd;
        gchar tmp_mbox[MAXPATHLEN + 1];
 
-       g_return_val_if_fail(dest != NULL, -1);
-       g_return_val_if_fail(mbox != NULL, -1);
-       g_return_val_if_fail(account != NULL, -1);
+       cm_return_val_if_fail(dest != NULL, -1);
+       cm_return_val_if_fail(mbox != NULL, -1);
+       cm_return_val_if_fail(account != NULL, -1);
 
        if (!is_file_exist(mbox) || (size = get_file_size(mbox)) == 0) {
                debug_print("%s: no messages in local mailbox.\n", mbox);
@@ -1392,14 +1412,8 @@ void inc_unlock_real(void)
 static guint autocheck_timer = 0;
 static gpointer autocheck_data = NULL;
 
-#ifdef MAEMO
-osso_context_t *get_osso_context(void);
-#endif
-
 static void inc_notify_cmd(gint new_msgs, gboolean notify)
 {
-
-#ifndef MAEMO
        gchar *buf, *numpos, *ret_str;
        gssize by_read = 0, by_written = 0;
 
@@ -1427,65 +1441,12 @@ static void inc_notify_cmd(gint new_msgs, gboolean notify)
        execute_command_line(buf, TRUE);
 
        g_free(buf);
-
-#else
-       if (new_msgs) {
-               if (prefs_common.maemo_play_sound)
-                       hildon_play_system_sound("/usr/share/sounds/ui-new_email.wav");
-               if (prefs_common.maemo_show_banner) {
-                       gchar *info = g_strdup_printf(ngettext("Claws Mail: %d new message",
-                                                  "Claws Mail: %d new messages",
-                                                  new_msgs), new_msgs);
-                       osso_system_note_infoprint(get_osso_context(), info, NULL);
-                       g_free(info);
-               }
-       }
-#endif
-}
-
-#if (defined(MAEMO) && defined(CONIC))
-static void maemo_connection_event(ConIcConnection *connection, 
-                                  ConIcConnectionEvent *event,
-                                  gpointer user_data)
-{
-       ConIcConnectionStatus status =
-               con_ic_connection_event_get_status(event);
-       MainWindow *mainwin = (MainWindow *)user_data;
-       switch(status) {
-       case CON_IC_STATUS_CONNECTED:
-               debug_print("we're connected\n");
-               main_window_toggle_work_offline(mainwin, FALSE, FALSE);
-               break;
-       default:
-               debug_print("we're disconnected\n");
-               main_window_toggle_work_offline(mainwin, TRUE, FALSE);
-               maemo_warned_offline = FALSE;
-               break;
-       }
 }
 
-#endif
-
 void inc_autocheck_timer_init(MainWindow *mainwin)
 {
-#if (defined(MAEMO) && defined(CONIC))
-       GValue *val = g_new0(GValue, 1);
-       maemo_connection = con_ic_connection_new();
-
-       g_value_init(val, G_TYPE_BOOLEAN);
-       g_value_set_boolean(val, TRUE);
-       g_object_set_property(G_OBJECT(maemo_connection),
-                       "automatic-connection-events", val);
-       g_free(val);    
-       g_signal_connect (maemo_connection, "connection-event",
-                         G_CALLBACK(maemo_connection_event), mainwin); 
-       con_ic_connection_connect (maemo_connection,
-               CON_IC_CONNECT_FLAG_AUTOMATICALLY_TRIGGERED);
-       autocheck_data = mainwin;
-#else
        autocheck_data = mainwin;
        inc_autocheck_timer_set();
-#endif
 }
 
 static void inc_autocheck_timer_set_interval(guint interval)
@@ -1495,14 +1456,12 @@ static void inc_autocheck_timer_set_interval(guint interval)
           the common preferences */
        if (prefs_common.autochk_newmail && autocheck_data
            && prefs_common.work_offline == FALSE) {
-#if GLIB_CHECK_VERSION(2,14,0)
                if (interval % 1000 == 0)
                        autocheck_timer =
                                g_timeout_add_seconds(interval/1000, inc_autocheck_func, autocheck_data);
                else
-#endif
-               autocheck_timer = g_timeout_add
-                       (interval, inc_autocheck_func, autocheck_data);
+                       autocheck_timer = g_timeout_add
+                               (interval, inc_autocheck_func, autocheck_data);
                debug_print("added timer = %d\n", autocheck_timer);
        }
 }
@@ -1510,10 +1469,6 @@ static void inc_autocheck_timer_set_interval(guint interval)
 void inc_autocheck_timer_set(void)
 {
        inc_autocheck_timer_set_interval(prefs_common.autochk_itv * 60000);
-#if (defined(MAEMO) && defined(CONIC))
-       con_ic_connection_connect (maemo_connection,
-               CON_IC_CONNECT_FLAG_AUTOMATICALLY_TRIGGERED);
-#endif
 }
 
 void inc_autocheck_timer_remove(void)
@@ -1553,22 +1508,6 @@ gboolean inc_offline_should_override(gboolean force_ask, const gchar *msg)
                return FALSE;
 #endif
 
-#if (defined(MAEMO) && defined(CONIC))
-       if (prefs_common.work_offline) {
-               if (force_ask && !maemo_warned_offline) {
-                       if (mainwindow_get_mainwindow())
-                               hildon_banner_show_information(
-                                       mainwindow_get_mainwindow()->window, 
-                                       NULL,
-                                       _("Unable to connect: you are offline."));
-                       maemo_warned_offline = TRUE;
-               }
-               return FALSE;
-       } else {
-               return TRUE;
-       }
-#endif 
-
        if (prefs_common.autochk_newmail)
                length = prefs_common.autochk_itv; /* minutes */