Simplified the code of the dbus 'mailto:' handler, to remove redundant
[modest] / src / modest-tny-account-store.c
index b96c249..94b1f46 100644 (file)
@@ -52,7 +52,7 @@
 #include <widgets/modest-window-mgr.h>
 #include <modest-account-settings-dialog.h>
 #include <maemo/modest-maemo-utils.h>
-
+#include <modest-signal-mgr.h>
 
 #include "modest-tny-account-store.h"
 #include "modest-tny-platform-factory.h"
@@ -125,17 +125,13 @@ struct _ModestTnyAccountStorePrivate {
        TnySessionCamel    *session;
        TnyDevice          *device;
 
-       gulong acc_inserted_handler;
-       gulong acc_changed_handler;
-       gulong acc_removed_handler;
-       gulong volume_mounted_handler;
-       gulong volume_unmounted_handler;
+       GSList *sighandlers;
        
        /* We cache the lists of accounts here */
        TnyList             *store_accounts;
        TnyList             *transport_accounts;
        TnyList             *store_accounts_outboxes;
-
+       
        /* Matches transport accounts and outbox folder */
        GHashTable          *outbox_of_transport;
 };
@@ -267,6 +263,7 @@ modest_tny_account_store_instance_init (ModestTnyAccountStore *obj)
        priv->account_mgr            = NULL;
        priv->session                = NULL;
        priv->device                 = NULL;
+       priv->sighandlers            = NULL;
        
        priv->outbox_of_transport = g_hash_table_new_full (g_direct_hash,
                                                           g_direct_equal,
@@ -290,14 +287,15 @@ modest_tny_account_store_instance_init (ModestTnyAccountStore *obj)
        /* This is a singleton, so it does not need to be unrefed. */
        monitor = gnome_vfs_get_volume_monitor();
 
-       priv->volume_mounted_handler = g_signal_connect (G_OBJECT(monitor), 
-                                                        "volume-mounted",
-                                                        G_CALLBACK(on_vfs_volume_mounted),
-                                                        obj);
-
-       priv->volume_unmounted_handler = g_signal_connect (G_OBJECT(monitor), "volume-unmounted",
-                                                          G_CALLBACK(on_vfs_volume_unmounted),
-                                                          obj);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, 
+                                                      G_OBJECT(monitor), 
+                                                      "volume-mounted",
+                                                      G_CALLBACK(on_vfs_volume_mounted),
+                                                      obj);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, 
+                                                      G_OBJECT(monitor), "volume-unmounted",
+                                                      G_CALLBACK(on_vfs_volume_unmounted),
+                                                      obj);
 }
 
 /* disconnect the list of TnyAccounts */
@@ -441,24 +439,22 @@ modest_tny_account_store_forget_password_in_memory (ModestTnyAccountStore *self,
        }
 }
 
-
-static gboolean
-update_tny_account_for_account (ModestTnyAccountStore *self, ModestAccountMgr *acc_mgr,
-                               const gchar *account_name, TnyAccountType type)
+static void
+on_account_changed (ModestAccountMgr *acc_mgr, 
+                   const gchar *account_name, 
+                   TnyAccountType account_type,
+                   gpointer user_data)
 {
+       ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(user_data);
        ModestTnyAccountStorePrivate *priv;
        TnyList* account_list;
        gboolean found = FALSE;
        TnyIterator *iter = NULL;
 
-       g_return_val_if_fail (self, FALSE);
-       g_return_val_if_fail (account_name, FALSE);
-       g_return_val_if_fail (type == TNY_ACCOUNT_TYPE_STORE || 
-                             type == TNY_ACCOUNT_TYPE_TRANSPORT,
-                             FALSE);
-
        priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
-       account_list = (type == TNY_ACCOUNT_TYPE_STORE ? priv->store_accounts : priv->transport_accounts);
+       account_list = (account_type == TNY_ACCOUNT_TYPE_STORE ? 
+                       priv->store_accounts : 
+                       priv->transport_accounts);
        
        iter = tny_list_create_iterator (account_list);
        while (!tny_iterator_is_done (iter) && !found) {
@@ -469,11 +465,9 @@ update_tny_account_for_account (ModestTnyAccountStore *self, ModestAccountMgr *a
 
                        if (conn_status != TNY_CONNECTION_STATUS_RECONNECTING &&
                            conn_status != TNY_CONNECTION_STATUS_INIT) {
-                               const gchar* parent_name;
-                               parent_name = modest_tny_account_get_parent_modest_account_name_for_server_account (tny_account);
-                               if (parent_name && strcmp (parent_name, account_name) == 0) {
+                               if (!strcmp (tny_account_get_id (tny_account), account_name)) {
                                        found = TRUE;
-                                       modest_tny_account_update_from_account (tny_account, acc_mgr, account_name, type);
+                                       modest_tny_account_update_from_account (tny_account);
                                        g_signal_emit (G_OBJECT(self), signals[ACCOUNT_CHANGED_SIGNAL], 0, tny_account);
                                }
                        }
@@ -484,28 +478,6 @@ update_tny_account_for_account (ModestTnyAccountStore *self, ModestAccountMgr *a
 
        if (iter)
                g_object_unref (iter);
-       
-       return found;
-}
-
-
-static void
-on_account_changed (ModestAccountMgr *acc_mgr, 
-                   const gchar *account_name, 
-                   gpointer user_data)
-{
-       ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(user_data);
-
-/*     g_debug ("DEBUG: modest: %s\n", __FUNCTION__); */
-
-/*     /\* Ignore the change if it's a change in the last_updated value *\/ */
-/*     if (key && g_str_has_suffix ((const gchar *) key, MODEST_ACCOUNT_LAST_UPDATED)) */
-/*             return; */
-       
-       if (!update_tny_account_for_account (self, acc_mgr, account_name, TNY_ACCOUNT_TYPE_STORE))
-               g_warning ("%s: failed to update store account for %s", __FUNCTION__, account_name);
-       if (!update_tny_account_for_account (self, acc_mgr, account_name, TNY_ACCOUNT_TYPE_TRANSPORT))
-               g_warning ("%s: failed to update transport account for %s", __FUNCTION__, account_name);
 }
 
 static void 
@@ -567,6 +539,7 @@ show_wrong_password_dialog (TnyAccount *account)
                dialog = modest_account_settings_dialog_new ();
                modest_account_settings_dialog_set_account_name (dialog, modest_account_name);
                modest_account_settings_dialog_switch_to_user_info (dialog);
+               modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
                
                g_hash_table_insert (priv->account_settings_dialog_hash, g_strdup (modest_account_name), dialog);
                
@@ -574,8 +547,7 @@ show_wrong_password_dialog (TnyAccount *account)
        }
        
        /* Show an explanatory temporary banner: */
-       hildon_banner_show_information ( 
-               GTK_WIDGET(dialog), NULL, _("mcen_ib_username_pw_incorrect"));
+       hildon_banner_show_information (GTK_WIDGET(dialog), NULL, _("mcen_ib_username_pw_incorrect"));
                
        if (created_dialog) {
                /* Forget it when it closes: */
@@ -666,8 +638,8 @@ get_password (TnyAccount *account, const gchar * prompt_not_used, gboolean *canc
 
        /* If the password is not already there, try ModestConf */
        if (!already_asked) {
-               pwd  = modest_server_account_get_password (priv->account_mgr,
-                                                     server_account_name);
+               pwd  = modest_account_mgr_get_server_account_password (priv->account_mgr,
+                                                                      server_account_name);
                g_hash_table_insert (priv->password_hash, g_strdup (server_account_name), g_strdup (pwd));
        }
 
@@ -678,7 +650,7 @@ get_password (TnyAccount *account, const gchar * prompt_not_used, gboolean *canc
                 * then show a banner and the account settings dialog so it can be corrected:
                 */
                const gboolean settings_have_password = 
-                       modest_server_account_get_has_password (priv->account_mgr, server_account_name);
+                       modest_account_mgr_get_server_account_has_password (priv->account_mgr, server_account_name);
                printf ("DEBUG: modest: %s: settings_have_password=%d\n", __FUNCTION__, settings_have_password);
                if (settings_have_password) {
                        /* The password must be wrong, so show the account settings dialog so it can be corrected: */
@@ -708,18 +680,9 @@ get_password (TnyAccount *account, const gchar * prompt_not_used, gboolean *canc
                         * but we need to tell tinymail about the username too: */
                        tny_account_set_user (account, username);
                        
-                       /* Do not save the password in gconf, 
-                        * because the UI spec says "The password will never be saved in the account": */
-                       /*
-                       if (remember) {
-                               printf ("%s: Storing username=%s, password=%s\n", 
-                                       __FUNCTION__, username, pwd);
-                               modest_server_account_set_username (priv->account_mgr, server_account_name,
-                                                              username);
-                               modest_server_account_set_password (priv->account_mgr, server_account_name,
-                                                              pwd);
-                       }
-                       */
+                       /* Do not save the password in gconf, because
+                        * the UI spec says "The password will never
+                        * be saved in the account": */
 
                        /* We need to dup the string even knowing that
                           it's already a dup of the contents of an
@@ -743,6 +706,38 @@ get_password (TnyAccount *account, const gchar * prompt_not_used, gboolean *canc
        return pwd;
 }
 
+void 
+modest_tny_account_store_forget_already_asked (ModestTnyAccountStore *self, TnyAccount *account)
+{
+       g_return_if_fail (account);
+         
+       ModestTnyAccountStorePrivate *priv;
+       gchar *pwd = NULL;
+       gpointer pwd_ptr = NULL;
+       gboolean already_asked = FALSE;
+               
+       const gchar *server_account_name = tny_account_get_id (account);
+
+       priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
+       
+       /* This hash map stores passwords, including passwords that are not stored in gconf. */
+       pwd_ptr = (gpointer)&pwd; /* pwd_ptr so the compiler does not complained about
+                                  * type-punned ptrs...*/
+       already_asked = priv->password_hash && 
+                               g_hash_table_lookup_extended (priv->password_hash,
+                                                     server_account_name,
+                                                     NULL,
+                                                     (gpointer*)&pwd_ptr);
+
+       if (already_asked) {
+               g_hash_table_remove (priv->password_hash, server_account_name);         
+               g_free (pwd);
+               pwd = NULL;
+       }
+
+       return;
+}
+
 /* tinymail calls this if the connection failed due to an incorrect password.
  * And it seems to call this for any general connection failure. */
 static void
@@ -779,7 +774,6 @@ forget_password (TnyAccount *account)
 static void
 modest_tny_account_store_finalize (GObject *obj)
 {
-       GnomeVFSVolumeMonitor *volume_monitor;
        ModestTnyAccountStore *self        = MODEST_TNY_ACCOUNT_STORE(obj);
        ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
 
@@ -801,33 +795,10 @@ modest_tny_account_store_finalize (GObject *obj)
                priv->outbox_of_transport = NULL;
        }
 
-
-       /* Disconnect VFS signals */
-       volume_monitor = gnome_vfs_get_volume_monitor ();
-       if (g_signal_handler_is_connected (volume_monitor, 
-                                          priv->volume_mounted_handler))
-               g_signal_handler_disconnect (volume_monitor, 
-                                            priv->volume_mounted_handler);
-       if (g_signal_handler_is_connected (volume_monitor, 
-                                          priv->volume_unmounted_handler))
-               g_signal_handler_disconnect (volume_monitor, 
-                                            priv->volume_unmounted_handler);
+       modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
+       priv->sighandlers = NULL;       
 
        if (priv->account_mgr) {
-               /* Disconnect signals */
-               if (g_signal_handler_is_connected (priv->account_mgr, 
-                                                  priv->acc_inserted_handler))
-                       g_signal_handler_disconnect (priv->account_mgr, 
-                                                    priv->acc_inserted_handler);
-               if (g_signal_handler_is_connected (priv->account_mgr, 
-                                                  priv->acc_changed_handler))
-                       g_signal_handler_disconnect (priv->account_mgr, 
-                                                    priv->acc_changed_handler);
-               if (g_signal_handler_is_connected (priv->account_mgr, 
-                                                  priv->acc_removed_handler))
-                       g_signal_handler_disconnect (priv->account_mgr, 
-                                                    priv->acc_removed_handler);
-
                g_object_unref (G_OBJECT(priv->account_mgr));
                priv->account_mgr = NULL;
        }
@@ -942,14 +913,17 @@ modest_tny_account_store_new (ModestAccountMgr *account_mgr,
 
        /* Set the ui locker */ 
        tny_session_camel_set_ui_locker (priv->session,  tny_gtk_lockable_new ());
-               
+       
        /* Connect signals */
-       priv->acc_inserted_handler = g_signal_connect (G_OBJECT(account_mgr), "account_inserted",
-                                                     G_CALLBACK (on_account_inserted), obj);
-       priv->acc_changed_handler = g_signal_connect (G_OBJECT(account_mgr), "account_changed",
-                                                     G_CALLBACK (on_account_changed), obj);
-       priv->acc_removed_handler = g_signal_connect (G_OBJECT(account_mgr), "account_removed",
-                                                     G_CALLBACK (on_account_removed), obj);
+       priv->sighandlers  =  modest_signal_mgr_connect (priv->sighandlers,
+                                                        G_OBJECT(account_mgr), "account_inserted",
+                                                        G_CALLBACK (on_account_inserted), obj);
+       priv->sighandlers  =  modest_signal_mgr_connect (priv->sighandlers,
+                                                        G_OBJECT(account_mgr), "account_changed",
+                                                        G_CALLBACK (on_account_changed), obj);
+       priv->sighandlers  =  modest_signal_mgr_connect (priv->sighandlers,
+                                                        G_OBJECT(account_mgr), "account_removed",
+                                                        G_CALLBACK (on_account_removed), obj);
 
        /* Create the lists of accounts */
        priv->store_accounts = tny_simple_list_new ();
@@ -1463,6 +1437,16 @@ modest_tny_account_store_get_local_folders_account (ModestTnyAccountStore *self)
        return account;
 }
 
+TnyAccount*
+modest_tny_account_store_get_mmc_folders_account (ModestTnyAccountStore *self)
+{
+       g_return_val_if_fail (MODEST_IS_TNY_ACCOUNT_STORE (self), NULL);
+       
+       return modest_tny_account_store_get_tny_account_by (self, MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
+                                                           MODEST_MMC_ACCOUNT_ID);
+
+}
+
 /*********************************************************************************/
 static void
 add_existing_accounts (ModestTnyAccountStore *self)
@@ -1562,7 +1546,6 @@ add_outbox_from_transport_account_to_global_outbox (ModestTnyAccountStore *self,
        g_object_unref (per_account_outbox);
 }
 
-
 /*
  * This function will be used for both adding new accounts and for the
  * initialization. In the initialization we do not want to emit
@@ -1583,39 +1566,36 @@ insert_account (ModestTnyAccountStore *self,
        store_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_STORE);
        transport_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_TRANSPORT);
 
-       /* Add to the list, and notify the observers */
-       if (store_account) {
-               tny_list_append (priv->store_accounts, G_OBJECT (store_account));
-               if (notify)
-                       g_signal_emit (G_OBJECT (self), signals [ACCOUNT_INSERTED_SIGNAL], 0, store_account);
-               g_object_unref (store_account);
-       }
+       g_assert (store_account);
+       g_assert (transport_account);
 
-       /* Add to the list, and notify the observers */
-       if (transport_account) {
-               /* Add account to the list */
-               tny_list_append (priv->transport_accounts, G_OBJECT (transport_account));
-               g_assert (TNY_IS_ACCOUNT (transport_account));
-
-               /* Create a new pseudo-account with an outbox for this
-                  transport account and add it to the global outbox
-                  in the local account */
-               add_outbox_from_transport_account_to_global_outbox (self, account, transport_account);
-
-               if (notify) {
-                       TnyAccount *local_account = NULL;
+       /* Add accounts to the lists */
+       tny_list_append (priv->store_accounts, G_OBJECT (store_account));
+       tny_list_append (priv->transport_accounts, G_OBJECT (transport_account));
 
-                       /* Notify that the local account changed */
-                       local_account = modest_tny_account_store_get_local_folders_account (self);
-                       g_signal_emit (G_OBJECT (self), signals [ACCOUNT_CHANGED_SIGNAL], 0, local_account);
-                       g_object_unref (local_account);
-                       
-                       /* Notify the observers about the new account */
-                       g_signal_emit (G_OBJECT (self), signals [ACCOUNT_INSERTED_SIGNAL], 0, transport_account);
-               }
-
-               g_object_unref (transport_account);
+       /* Create a new pseudo-account with an outbox for this
+          transport account and add it to the global outbox
+          in the local account */
+       add_outbox_from_transport_account_to_global_outbox (self, account, transport_account);
+       
+       /* Notify the observers. We do it after everything is
+          created */
+       if (notify) {
+               TnyAccount *local_account = NULL;
+               
+               /* Notify the observers about the new server & transport accounts */
+               g_signal_emit (G_OBJECT (self), signals [ACCOUNT_INSERTED_SIGNAL], 0, store_account);   
+               g_signal_emit (G_OBJECT (self), signals [ACCOUNT_INSERTED_SIGNAL], 0, transport_account);
+
+               /* Notify that the local account changed */
+               local_account = modest_tny_account_store_get_local_folders_account (self);
+               g_signal_emit (G_OBJECT (self), signals [ACCOUNT_CHANGED_SIGNAL], 0, local_account);
+               g_object_unref (local_account);
        }
+
+       /* Frees */
+       g_object_unref (store_account);
+       g_object_unref (transport_account);
 }
 
 static void
@@ -1736,3 +1716,49 @@ add_connection_specific_transport_accounts (ModestTnyAccountStore *self)
                iter = g_slist_next (iter);
        }
 }
+
+TnyMsg *
+modest_tny_account_store_find_msg_in_outboxes (ModestTnyAccountStore *self, 
+                                              const gchar *uri,
+                                              TnyAccount **ac_out)
+{
+       TnyIterator *acc_iter;
+       ModestTnyAccountStorePrivate *priv;
+       TnyMsg *msg = NULL;
+       TnyAccount *msg_account = NULL;
+
+       g_return_val_if_fail (MODEST_IS_TNY_ACCOUNT_STORE (self), NULL);
+       priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE (self);
+
+       acc_iter = tny_list_create_iterator (priv->store_accounts_outboxes);
+       while (!msg && !tny_iterator_is_done (acc_iter)) {
+               TnyList *folders = tny_simple_list_new ();
+               TnyAccount *account = TNY_ACCOUNT (tny_iterator_get_current (acc_iter));
+               TnyIterator *folders_iter = NULL;
+
+               tny_folder_store_get_folders (TNY_FOLDER_STORE (account), folders, NULL, NULL);
+               folders_iter = tny_list_create_iterator (folders);
+
+               while (msg == NULL && !tny_iterator_is_done (folders_iter)) {
+                       TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (folders_iter));
+                       msg = tny_folder_find_msg (folder, uri, NULL);
+
+                       if (msg)
+                               msg_account = g_object_ref (account);
+
+                       g_object_unref (folder);
+                       tny_iterator_next (folders_iter);
+               }
+
+               g_object_unref (folders);
+               g_object_unref (account);
+               tny_iterator_next (acc_iter);
+       }
+
+       g_object_unref (acc_iter);
+
+       if (ac_out != NULL)
+               *ac_out = msg_account;
+
+       return msg;
+}