From 48bebb6807aa14936ee82996ea7a749cb84b5956 Mon Sep 17 00:00:00 2001 From: Murray Cumming Date: Wed, 30 May 2007 12:27:26 +0000 Subject: [PATCH] 2007-05-30 Murray Cumming * src/modest-defs.h: Define MODEST_MCC1_VOLUMEPATH and MODEST_MCC1_VOLUMEPATH_URI. * src/modest-init.h: * src/modest-init.c: Made modest_init_local_folders() take a path and be public so we can iniitialize maildir folders on arbitrary volumes. * src/modest-local-folder-info.h: * src/modest-local-folder-info.c: (modest_local_folder_info_get_maildir_path): Add a path parameter. * src/modest-tny-account.c: (modest_tny_account_new_for_local_folders): Take a path parameter, though NULL still means the standard local-folders path on the local volume. * src/modest-tny-account-store.c: (modest_tny_account_store_instance_init): Connect to GnomeVfsVolumeMonitor signal so we can detect mount/unmount of the MMC1 card, and do an update of all accounts when that happens. (get_server_accounts): If the MMC1 card is mounted, create a store account for this too, so it shows up in the treeview. pmo-trunk-r1995 --- ChangeLog2 | 24 ++++++ src/modest-defs.h | 6 +- src/modest-init.c | 13 ++-- src/modest-init.h | 14 ++++ src/modest-local-folder-info.c | 4 +- src/modest-local-folder-info.h | 4 +- src/modest-tny-account-store.c | 166 +++++++++++++++++++++++++++++++--------- src/modest-tny-account.c | 55 +++++++++++-- src/modest-tny-account.h | 4 +- 9 files changed, 239 insertions(+), 51 deletions(-) diff --git a/ChangeLog2 b/ChangeLog2 index 4578cb1..0aceec2 100644 --- a/ChangeLog2 +++ b/ChangeLog2 @@ -1,3 +1,27 @@ +2007-05-30 Murray Cumming + + * src/modest-defs.h: Define MODEST_MCC1_VOLUMEPATH and MODEST_MCC1_VOLUMEPATH_URI. + + * src/modest-init.h: + * src/modest-init.c: Made modest_init_local_folders() take a + path and be public so we can iniitialize maildir folders on + arbitrary volumes. + + * src/modest-local-folder-info.h: + * src/modest-local-folder-info.c: + (modest_local_folder_info_get_maildir_path): Add a path parameter. + + * src/modest-tny-account.c: + (modest_tny_account_new_for_local_folders): Take a path parameter, though NULL + still means the standard local-folders path on the local volume. + + * src/modest-tny-account-store.c: + (modest_tny_account_store_instance_init): Connect to GnomeVfsVolumeMonitor + signal so we can detect mount/unmount of the MMC1 card, and do an update of + all accounts when that happens. + (get_server_accounts): If the MMC1 card is mounted, create a store account for + this too, so it shows up in the treeview. + 2007-05-28 Murray Cumming * src/maemo/modest-maemo-global-settings-dialog.c: diff --git a/src/modest-defs.h b/src/modest-defs.h index c12252f..2d91fc9 100644 --- a/src/modest-defs.h +++ b/src/modest-defs.h @@ -58,7 +58,11 @@ #define MODEST_PER_ACCOUNT_LOCAL_OUTBOX_FOLDERS_MAILDIR MODEST_PER_ACCOUNT_LOCAL_OUTBOX_FOLDER_ACCOUNT_ID_PREFIX #define MODEST_MMC_ACCOUNT_ID "mcc" -#define MODEST_MCC_ACCOUNT_MAILDIR "/media/mmc1/.Maildir" + +/* Without the trailing / because gnome-vfs reports mounted + * volume URIs without the trailing, and we want to match them: */ +#define MODEST_MCC1_VOLUMEPATH "/media/mmc1" +#define MODEST_MCC1_VOLUMEPATH_URI "file://" MODEST_MCC1_VOLUMEPATH /* configuration key definitions for modest */ #define MODEST_CONF_NAMESPACE "/apps/modest" diff --git a/src/modest-init.c b/src/modest-init.c index 37016d4..1dd4d87 100644 --- a/src/modest-init.c +++ b/src/modest-init.c @@ -50,7 +50,6 @@ #include "modest-tny-msg.h" static gboolean init_header_columns (ModestConf *conf, gboolean overwrite); -static gboolean init_local_folders (void); static gboolean init_default_account_maybe (ModestAccountMgr *acc_mgr); static void init_i18n (void); static void init_stock_icons (void); @@ -169,7 +168,7 @@ modest_init_init_core (void) init_default_settings (modest_runtime_get_conf ()); - if (!init_local_folders()) { + if (!modest_init_local_folders(NULL /* means $HOME */)) { modest_init_uninit (); g_printerr ("modest: failed to init local folders\n"); return FALSE; @@ -331,7 +330,9 @@ gboolean modest_init_one_local_folder (gchar *maildir_path) } /** - * init_local_folders: + * modest_init_local_folders: + * @location_filepath: The location at which the local-folders directory should be created, + * or NULL to specify $HOME. * * create the Local Folders folder under cache, if they * do not exist yet. @@ -339,10 +340,10 @@ gboolean modest_init_one_local_folder (gchar *maildir_path) * Returns: TRUE if the folder were already there, or * they were created, FALSE otherwise */ -static gboolean -init_local_folders (void) +gboolean +modest_init_local_folders (const gchar* location_filepath) { - gchar *maildir_path = modest_local_folder_info_get_maildir_path (); + gchar *maildir_path = modest_local_folder_info_get_maildir_path (location_filepath); /* Create each of the standard on-disk folders. * Per-account outbox folders will be created when first needed. */ diff --git a/src/modest-init.h b/src/modest-init.h index f5c9d43..911bb81 100644 --- a/src/modest-init.h +++ b/src/modest-init.h @@ -72,6 +72,19 @@ gboolean modest_init_init_ui (gint argc, gchar** argv); gboolean modest_init_uninit (void); /** + * modest_init_local_folders: + * @location_filepath: The location at which the local-folders directory should be created, + * or NULL to specify $HOME. + * + * create the Local Folders folder under cache, if they + * do not exist yet. + * + * Returns: TRUE if the folder were already there, or + * they were created, FALSE otherwise + */ +gboolean modest_init_local_folders (const gchar* location_filepath); + +/** * modest_init_one_local_folder: * * Create the directory structure for a maildir folder, @@ -80,6 +93,7 @@ gboolean modest_init_uninit (void); */ gboolean modest_init_one_local_folder (gchar *maildir_path); + G_END_DECLS #endif /*__MODEST_INIT_H__*/ diff --git a/src/modest-local-folder-info.c b/src/modest-local-folder-info.c index 9ab4465..9c646a7 100644 --- a/src/modest-local-folder-info.c +++ b/src/modest-local-folder-info.c @@ -105,9 +105,9 @@ modest_local_folder_info_get_type_display_name (TnyFolderType type) gchar * -modest_local_folder_info_get_maildir_path (void) +modest_local_folder_info_get_maildir_path (const gchar* location_filepath) { - return g_build_filename (g_get_home_dir(), + return g_build_filename (location_filepath ? location_filepath : g_get_home_dir(), MODEST_DIR, MODEST_LOCAL_FOLDERS_MAILDIR, NULL); diff --git a/src/modest-local-folder-info.h b/src/modest-local-folder-info.h index da0fe58..8dcae52 100644 --- a/src/modest-local-folder-info.h +++ b/src/modest-local-folder-info.h @@ -76,6 +76,8 @@ const gchar* modest_local_folder_info_get_type_display_name (TnyFolderType type) /** * modest_local_folder_info_get_maildir_path + * @location_filepath: The path at which the local-folders directory exists, + * or NULL to specify $HOME * * Get the path to the Maildir where the local folders are stored. * @@ -83,7 +85,7 @@ const gchar* modest_local_folder_info_get_type_display_name (TnyFolderType type) * string, which must be freed by the caller. * */ -gchar *modest_local_folder_info_get_maildir_path (void); +gchar *modest_local_folder_info_get_maildir_path (const gchar* location_filepath); /** * modest_per_account_local_outbox_folder_info_get_maildir_path diff --git a/src/modest-tny-account-store.c b/src/modest-tny-account-store.c index 79717d3..96d8e28 100644 --- a/src/modest-tny-account-store.c +++ b/src/modest-tny-account-store.c @@ -63,6 +63,8 @@ #endif #endif +#include + /* 'private'/'protected' functions */ static void modest_tny_account_store_class_init (ModestTnyAccountStoreClass *klass); //static void modest_tny_account_store_init (ModestTnyAccountStore *obj); @@ -181,6 +183,15 @@ modest_tny_account_store_class_init (ModestTnyAccountStoreClass *klass) } + +static void +on_vfs_volume_mounted(GnomeVFSVolumeMonitor *volume_monitor, + GnomeVFSVolume *volume, gpointer user_data); + +static void +on_vfs_volume_unmounted(GnomeVFSVolumeMonitor *volume_monitor, + GnomeVFSVolume *volume, gpointer user_data); + static void modest_tny_account_store_instance_init (ModestTnyAccountStore *obj) { @@ -198,10 +209,19 @@ modest_tny_account_store_instance_init (ModestTnyAccountStore *obj) */ priv->password_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + /* Respond to volume mounts and unmounts, such + * as the insertion/removal of the memory card: */ + GnomeVFSVolumeMonitor* monitor = + gnome_vfs_get_volume_monitor(); + g_signal_connect (G_OBJECT(monitor), "volume-mounted", + G_CALLBACK(on_vfs_volume_mounted), + obj); + g_signal_connect (G_OBJECT(monitor), "volume-unmounted", + G_CALLBACK(on_vfs_volume_unmounted), + obj); } - - static void account_list_free (GSList *accounts) { @@ -218,41 +238,95 @@ account_list_free (GSList *accounts) g_slist_free (accounts); } +static void +recreate_all_accounts (ModestTnyAccountStore *self) +{ + ModestTnyAccountStorePrivate *priv = + MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self); + + if (priv->store_accounts) { + account_list_free (priv->store_accounts); + priv->store_accounts = NULL; + get_server_accounts (TNY_ACCOUNT_STORE(self), + NULL, TNY_ACCOUNT_TYPE_STORE); + } + + if (priv->transport_accounts) { + account_list_free (priv->transport_accounts); + priv->transport_accounts = NULL; + get_server_accounts (TNY_ACCOUNT_STORE(self), NULL, + TNY_ACCOUNT_TYPE_TRANSPORT); + } +} + +static void +on_vfs_volume_mounted(GnomeVFSVolumeMonitor *volume_monitor, + GnomeVFSVolume *volume, gpointer user_data) +{ + ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(user_data); + + /* Check whether this was the external MMC1 card: */ + gchar *uri = gnome_vfs_volume_get_activation_uri (volume); + if (uri && (strcmp (uri, MODEST_MCC1_VOLUMEPATH_URI) == 0)) { + printf ("DEBUG: %s: MMC1 card mounted.\n", __FUNCTION__); + + /* TODO: Just add an account and emit (and respond to) + * TnyAccountStore::accountinserted signal? + */ + recreate_all_accounts (self); + + g_signal_emit (G_OBJECT(self), signals[ACCOUNT_UPDATE_SIGNAL], 0, + NULL); + } + + g_free (uri); +} + +static void +on_vfs_volume_unmounted(GnomeVFSVolumeMonitor *volume_monitor, + GnomeVFSVolume *volume, gpointer user_data) +{ + ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(user_data); + + /* Check whether this was the external MMC1 card: */ + gchar *uri = gnome_vfs_volume_get_activation_uri (volume); + if (uri && (strcmp (uri, MODEST_MCC1_VOLUMEPATH_URI) == 0)) { + printf ("DEBUG: %s: MMC1 card unmounted.\n", __FUNCTION__); + + /* TODO: Just add an account and emit (and respond to) + * TnyAccountStore::accountinserted signal? + */ + recreate_all_accounts (self); + + g_signal_emit (G_OBJECT(self), signals[ACCOUNT_UPDATE_SIGNAL], 0, + NULL); + } + + g_free (uri); +} static void on_account_removed (ModestAccountMgr *acc_mgr, const gchar *account, gboolean server_account, gpointer user_data) { - ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(user_data); - ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self); - + ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(user_data); + /* FIXME: make this more finegrained; changes do not really affect _all_ * accounts, and some do not affect tny accounts at all (such as 'last_update') */ - - account_list_free (priv->store_accounts); - get_server_accounts (TNY_ACCOUNT_STORE(self), NULL, TNY_ACCOUNT_TYPE_STORE); - - account_list_free (priv->transport_accounts); - get_server_accounts (TNY_ACCOUNT_STORE(self), NULL, - TNY_ACCOUNT_TYPE_TRANSPORT); - - /* TODO: Ref these when we add them? */ - g_slist_free (priv->store_accounts_outboxes); - priv->store_accounts_outboxes = NULL; + if (server_account) + recreate_all_accounts (self); g_signal_emit (G_OBJECT(self), signals[ACCOUNT_UPDATE_SIGNAL], 0, account); } - static void on_account_changed (ModestAccountMgr *acc_mgr, const gchar *account, const gchar *key, gboolean server_account, gpointer user_data) { ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(user_data); - ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self); /* Ignore the change if it's a change in the last_updated value */ if (g_str_has_suffix (key, MODEST_ACCOUNT_LAST_UPDATED)) @@ -261,21 +335,8 @@ on_account_changed (ModestAccountMgr *acc_mgr, const gchar *account, /* FIXME: make this more finegrained; changes do not really affect _all_ * accounts, and some do not affect tny accounts at all (such as 'last_update') */ - if (server_account) { - if (priv->store_accounts) { - account_list_free (priv->store_accounts); - priv->store_accounts = NULL; - get_server_accounts (TNY_ACCOUNT_STORE(self), - NULL, TNY_ACCOUNT_TYPE_STORE); - } - - if (priv->transport_accounts) { - account_list_free (priv->transport_accounts); - priv->transport_accounts = NULL; - get_server_accounts (TNY_ACCOUNT_STORE(self), NULL, - TNY_ACCOUNT_TYPE_TRANSPORT); - } - } + if (server_account) + recreate_all_accounts (self); g_signal_emit (G_OBJECT(self), signals[ACCOUNT_UPDATE_SIGNAL], 0, account); @@ -591,10 +652,45 @@ get_server_accounts (TnyAccountStore *self, TnyList *list, TnyAccountType type) if (type == TNY_ACCOUNT_TYPE_STORE) { /* Also add the local folder pseudo-account: */ TnyAccount *tny_account = - modest_tny_account_new_for_local_folders (priv->account_mgr, priv->session); + modest_tny_account_new_for_local_folders (priv->account_mgr, + priv->session, NULL); if (list) tny_list_prepend (list, G_OBJECT(tny_account)); accounts = g_slist_append (accounts, tny_account); /* cache it */ + + + /* Also add the Memory card account if it is mounted: */ + gboolean mmc_is_mounted = FALSE; + GnomeVFSVolumeMonitor* monitor = + gnome_vfs_get_volume_monitor(); + GList* list_volumes = gnome_vfs_volume_monitor_get_mounted_volumes (monitor); + GList *iter = list_volumes; + while (iter) { + GnomeVFSVolume *volume = (GnomeVFSVolume*)iter->data; + if (volume) { + if (!mmc_is_mounted) { + gchar *uri = gnome_vfs_volume_get_activation_uri (volume); + if (uri && (strcmp (uri, MODEST_MCC1_VOLUMEPATH_URI) == 0)) { + mmc_is_mounted = TRUE; + } + g_free (uri); + } + + gnome_vfs_volume_unref(volume); + } + + iter = g_list_next (iter); + } + g_list_free (list_volumes); + + if (mmc_is_mounted) { + TnyAccount *tny_account = + modest_tny_account_new_for_local_folders (priv->account_mgr, + priv->session, MODEST_MCC1_VOLUMEPATH); + if (list) + tny_list_prepend (list, G_OBJECT(tny_account)); + accounts = g_slist_append (accounts, tny_account); /* cache it */ + } } /* And add the connection-specific transport accounts, if any. @@ -1009,7 +1105,7 @@ modest_tny_account_store_get_tny_account_by_account (ModestTnyAccountStore *self if (!account) g_printerr ("modest: could not get tny %s account for %s (id=%s)\n", - type == TNY_ACCOUNT_TYPE_STORE? "store" : "transport", + type == TNY_ACCOUNT_TYPE_STORE ? "store" : "transport", account_name, id ? id : ""); return account; diff --git a/src/modest-tny-account.c b/src/modest-tny-account.c index 0e521fe..0db9025 100644 --- a/src/modest-tny-account.c +++ b/src/modest-tny-account.c @@ -40,6 +40,7 @@ #include #include #include +#include TnyFolder * @@ -400,10 +401,33 @@ modest_tny_account_new_from_account (ModestAccountMgr *account_mgr, const gchar return tny_account; } +#if 0 +static void +on_modest_file_system_info(HildonFileSystemInfoHandle *handle, + HildonFileSystemInfo *info, + const GError *error, gpointer data) +{ + if (info) { + printf("DEBUG: %s: display name=%s\n", __FUNCTION__, + hildon_file_system_info_get_display_name(info)); + } + else { + printf("DEBUG: %s: info is NULL.\n", __FUNCTION__); + } + + if (error) { + printf (" DEBUG: error=%s\n", error->message); + } +} +#endif + TnyAccount* -modest_tny_account_new_for_local_folders (ModestAccountMgr *account_mgr, TnySessionCamel *session) +modest_tny_account_new_for_local_folders (ModestAccountMgr *account_mgr, TnySessionCamel *session, const gchar* location_filepath) { + /* Make sure that the directories exist: */ + modest_init_local_folders (location_filepath); + TnyStoreAccount *tny_account; CamelURL *url; gchar *maildir, *url_string; @@ -420,7 +444,7 @@ modest_tny_account_new_for_local_folders (ModestAccountMgr *account_mgr, TnySess /* This path contains directories for each local folder. * We have created them so that TnyCamelStoreAccount can find them * and report a folder for each directory: */ - maildir = modest_local_folder_info_get_maildir_path (); + maildir = modest_local_folder_info_get_maildir_path (location_filepath); url = camel_url_new ("maildir:", NULL); camel_url_set_path (url, maildir); /* Needed by tinymail's DBC assertions */ @@ -430,9 +454,30 @@ modest_tny_account_new_for_local_folders (ModestAccountMgr *account_mgr, TnySess tny_account_set_url_string (TNY_ACCOUNT(tny_account), url_string); printf("DEBUG: %s:\n url=%s\n", __FUNCTION__, url_string); - tny_account_set_name (TNY_ACCOUNT(tny_account), MODEST_LOCAL_FOLDERS_DEFAULT_DISPLAY_NAME); - tny_account_set_id (TNY_ACCOUNT(tny_account), MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID); - tny_account_set_forget_pass_func (TNY_ACCOUNT(tny_account), forget_pass_dummy); + /* TODO: Use a more generic way of identifying memory card paths, + * and of marking accounts as memory card accounts, maybe + * via a derived TnyCamelStoreAccount ? */ + const gboolean is_mmc = + location_filepath && + (strcmp (location_filepath, MODEST_MCC1_VOLUMEPATH) == 0); + + /* TODO: Use hildon_file_system_info_async_new() to get the display name? */ +#if 0 + const gchar *uri = "file:///media/mmc1"; + /* HildonFileSystemInfoHandle *async_handle = */ + hildon_file_system_info_async_new(uri, + on_modest_file_system_info, NULL /* user_data */); +#endif + + const gchar *name = is_mmc ? _("Memory Card") : + MODEST_LOCAL_FOLDERS_DEFAULT_DISPLAY_NAME; + tny_account_set_name (TNY_ACCOUNT(tny_account), name); + + const gchar* id = is_mmc ? MODEST_MMC_ACCOUNT_ID : + MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID; + tny_account_set_id (TNY_ACCOUNT(tny_account), id); + + tny_account_set_forget_pass_func (TNY_ACCOUNT(tny_account), forget_pass_dummy); tny_account_set_pass_func (TNY_ACCOUNT(tny_account), get_pass_dummy); modest_tny_account_set_parent_modest_account_name_for_server_account ( diff --git a/src/modest-tny-account.h b/src/modest-tny-account.h index 55fe0af..2e4b056 100644 --- a/src/modest-tny-account.h +++ b/src/modest-tny-account.h @@ -68,13 +68,15 @@ modest_tny_account_new_from_account (ModestAccountMgr *account_mgr, const gchar * modest_tny_account_new_for_local_folders: * @account_mgr: a valid account mgr instance * @session: a tny camel session + * @location_filepath: The location at which the local-folders directory exists, or NULL to specify $HOME. * * get the local folders (pseudo) account; you should only need one such account. * * Returns: a new local folders TnyAccount or NULL in case of error. */ TnyAccount* modest_tny_account_new_for_local_folders (ModestAccountMgr *account_mgr, - TnySessionCamel *session); + TnySessionCamel *session, + const gchar* location_filepath); /** * modest_tny_account_new_for_per_account_local_outbox_folder: -- 1.7.9.5