aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog26
-rw-r--r--mail/component-factory.c133
-rw-r--r--mail/mail-ops.c125
-rw-r--r--mail/mail-ops.h2
-rw-r--r--mail/mail-vfolder.c4
-rw-r--r--mail/mail.h3
-rw-r--r--mail/subscribe-dialog.c5
7 files changed, 190 insertions, 108 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 874cd6ddf4..c1beb752d4 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,29 @@
+2000-11-01 Dan Winship <danw@helixcode.com>
+
+ Make "Get Mail" even more functional on IMAP (scans all folders),
+ and do a first cut at folder tree highlighting (for IMAP/news
+ only).
+
+ * mail-ops.c (do_fetch_mail): For imap (sigh, we *still* shouldn't
+ be hardcoding that), rescan the store's folder tree, rescan each
+ changed folder for new messages, and update the shell folder tree.
+ (do_scan_subfolders): Update for component-factory.c changes, and
+ set folder display names and highlights appropriately when
+ building the storage.
+
+ * component-factory.c (add_storage): Make this static (was
+ mail_add_new_storage). Use camel_service_get_name for the name
+ rather than url->host. (Among other things, this lets you use a
+ single machine as both an IMAP server and a news server.)
+ (mail_lookup_storage): Hash storages based on their CamelStore
+ rather than the URL.
+ (factory_destroy): Disconnect each of the CamelStores in the
+ storages_hash.
+
+ * subscribe-dialog.c (cleanup_subscribe_folder):
+ * mail-vfolder.c (vfolder_refresh): Pass "highlighted" flag to
+ evolution_storage_new_folder
+
2000-11-01 Jeffrey Stedfast <fejj@helixcode.com>
* mail-ops.c (mail_op_report_status): Don't call the default
diff --git a/mail/component-factory.c b/mail/component-factory.c
index c1b09fed5e..dbff4b8c5c 100644
--- a/mail/component-factory.c
+++ b/mail/component-factory.c
@@ -151,12 +151,11 @@ owner_unset_cb (EvolutionShellComponent *shell_component, gpointer user_data)
}
static void
-hash_foreach (gpointer key,
- gpointer value,
- gpointer data)
+free_storage (gpointer service, gpointer storage, gpointer data)
{
- g_free (key);
- gtk_object_unref (GTK_OBJECT (value));
+ camel_service_disconnect (service, TRUE, NULL);
+ camel_object_unref (service);
+ gtk_object_unref (storage);
}
static void
@@ -173,7 +172,7 @@ factory_destroy (BonoboEmbeddable *embeddable,
g_warning ("Serious ref counting error");
factory = NULL;
- g_hash_table_foreach (storages_hash, hash_foreach, NULL);
+ g_hash_table_foreach (storages_hash, free_storage, NULL);
g_hash_table_destroy (storages_hash);
storages_hash = NULL;
@@ -223,7 +222,7 @@ component_factory_init (void)
factory = bonobo_generic_factory_new (COMPONENT_FACTORY_ID, factory_fn, NULL);
summary_factory = bonobo_generic_factory_new (SUMMARY_FACTORY_ID, summary_fn, NULL);
- storages_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ storages_hash = g_hash_table_new (NULL, NULL);
if (factory == NULL) {
e_notice (NULL, GNOME_MESSAGE_BOX_ERROR,
@@ -251,7 +250,37 @@ create_vfolder_storage (EvolutionShellComponent *shell_component)
vfolder_create_storage(shell_component);
}
-void
+static void
+add_storage (const char *uri, CamelService *store,
+ Evolution_Shell corba_shell, CamelException *ex)
+{
+ EvolutionStorage *storage;
+ EvolutionStorageResult res;
+ char *name;
+
+ name = camel_service_get_name (store, TRUE);
+ storage = evolution_storage_new (name);
+ g_free (name);
+
+ res = evolution_storage_register_on_shell (storage, corba_shell);
+
+ switch (res) {
+ case EVOLUTION_STORAGE_OK:
+ g_hash_table_insert (storages_hash, store, storage);
+ camel_object_ref (CAMEL_OBJECT (store));
+ mail_do_scan_subfolders (CAMEL_STORE (store), storage);
+ /* falllll */
+ case EVOLUTION_STORAGE_ERROR_ALREADYREGISTERED:
+ case EVOLUTION_STORAGE_ERROR_EXISTS:
+ return;
+ default:
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Cannot register storage with shell"));
+ break;
+ }
+}
+
+void
mail_load_storages (Evolution_Shell corba_shell, GSList *sources)
{
CamelException ex;
@@ -266,91 +295,57 @@ mail_load_storages (Evolution_Shell corba_shell, GSList *sources)
*/
for (iter = sources; iter; iter = iter->next) {
- CamelService *temp;
- CamelProvider *prov = NULL;
+ CamelService *store;
+ CamelProvider *prov;
svc = (MailConfigService *) iter->data;
if (svc->url == NULL || svc->url[0] == '\0')
continue;
- temp = camel_session_get_service (session, svc->url,
- CAMEL_PROVIDER_STORE, &ex);
- if (temp == NULL) {
+ store = camel_session_get_service (session, svc->url,
+ CAMEL_PROVIDER_STORE, &ex);
+ if (store == NULL) {
/* FIXME: real error dialog */
-
- g_warning ("couldn't get service %s: %s\n",
- svc->url, camel_exception_get_description (&ex));
+ g_warning ("couldn't get service %s: %s\n", svc->url,
+ camel_exception_get_description (&ex));
+ camel_exception_clear (&ex);
continue;
}
- prov = camel_service_get_provider (temp);
+ prov = camel_service_get_provider (store);
- /* FIXME: this case is ambiguous for things like the mbox provider,
- * which can really be a spool (/var/spool/mail/user) or a storage
- * (~/mail/, eg). That issue can't be resolved on the provider
- * level -- it's a per-URL problem.
+ /* FIXME: this case is ambiguous for things like the
+ * mbox provider, which can really be a spool
+ * (/var/spool/mail/user) or a storage (~/mail/, eg).
+ * That issue can't be resolved on the provider level
+ * -- it's a per-URL problem.
*/
-
- if (prov->flags & CAMEL_PROVIDER_IS_STORAGE && prov->flags & CAMEL_PROVIDER_IS_REMOTE) {
- mail_add_new_storage (svc->url, corba_shell, &ex);
-
+ if (prov->flags & CAMEL_PROVIDER_IS_STORAGE &&
+ prov->flags & CAMEL_PROVIDER_IS_REMOTE) {
+ add_storage (svc->url, store, corba_shell, &ex);
if (camel_exception_is_set (&ex)) {
/* FIXME: real error dialog */
g_warning ("Cannot load storage: %s",
camel_exception_get_description (&ex));
+ camel_exception_clear (&ex);
}
+ camel_object_unref (CAMEL_OBJECT (store));
}
-
- camel_object_unref (CAMEL_OBJECT (temp));
}
}
-void
-mail_add_new_storage (const char *uri, Evolution_Shell corba_shell, CamelException *ex)
+EvolutionStorage*
+mail_lookup_storage (CamelStore *store)
{
EvolutionStorage *storage;
- EvolutionStorageResult res;
- CamelURL *url;
-
- g_return_if_fail (uri && uri[0] != '\0');
-
- url = camel_url_new (uri, ex);
- if (url == NULL)
- return;
-
- if (url->host == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Bad storage URL (no server): %s"),
- uri);
- return;
- }
- storage = evolution_storage_new (url->host);
-
- res = evolution_storage_register_on_shell (storage, corba_shell);
-
- switch (res) {
- case EVOLUTION_STORAGE_OK:
- g_hash_table_insert (storages_hash, g_strdup(url->host), storage);
- mail_do_scan_subfolders (uri, storage);
- /* falllll */
- case EVOLUTION_STORAGE_ERROR_ALREADYREGISTERED:
- case EVOLUTION_STORAGE_ERROR_EXISTS:
- return;
- default:
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot register storage with shell"));
- break;
- }
-
- camel_url_free (url);
-}
-
-EvolutionStorage*
-mail_lookup_storage (CamelService *service)
-{
- EvolutionStorage *storage = g_hash_table_lookup (storages_hash, service->url->host);
+ /* Because the storages_hash holds a reference to each store
+ * used as a key in it, none of them will ever be gc'ed, meaning
+ * any call to camel_session_get_{service,store} with the same
+ * URL will always return the same object. So this works.
+ */
+ storage = g_hash_table_lookup (storages_hash, store);
if (storage)
gtk_object_ref (GTK_OBJECT (storage));
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index fcc9a7e5ae..e5c9140a15 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -116,6 +116,51 @@ mail_op_report_status (FilterDriver *driver, enum filter_status_t status, const
}
static void
+update_changed_folders (CamelStore *store, CamelFolderInfo *info,
+ EvolutionStorage *storage, const char *path,
+ CamelException *ex)
+{
+ CamelFolder *folder;
+ char *name, *display;
+
+ name = g_strdup_printf ("%s/%s", path, info->name);
+ if (info->url) {
+ if (info->unread_message_count > 0) {
+ display = g_strdup_printf ("%s (%d)", info->name,
+ info->unread_message_count);
+ evolution_storage_update_folder (storage, name,
+ display, TRUE);
+ g_free (display);
+ } else {
+ evolution_storage_update_folder (storage, name,
+ info->name, FALSE);
+ }
+
+ /* This is a bit of a hack... if the store is already
+ * caching the folder, then we update it. Otherwise
+ * we don't.
+ */
+ folder = CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS (store))->
+ lookup_folder (store, info->full_name);
+ if (folder) {
+ camel_folder_sync (folder, FALSE, ex);
+ if (!camel_exception_is_set (ex))
+ camel_folder_refresh_info (folder, ex);
+ camel_object_unref (CAMEL_OBJECT (folder));
+ }
+ }
+ if (!camel_exception_is_set (ex) && info->sibling) {
+ update_changed_folders (store, info->sibling, storage,
+ path, ex);
+ }
+ if (!camel_exception_is_set (ex) && info->child) {
+ update_changed_folders (store, info->child, storage,
+ name, ex);
+ }
+ g_free (name);
+}
+
+static void
do_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex)
{
fetch_mail_input_t *input = (fetch_mail_input_t *) in_data;
@@ -127,14 +172,29 @@ do_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex)
/* FIXME: This shouldn't be checking for "imap" specifically. */
if (!strncmp (input->source_url, "imap:", 5)) {
- folder = mail_tool_get_inbox (input->source_url, ex);
- if (folder) {
- camel_folder_sync (folder, FALSE, ex);
- if (!camel_exception_is_set (ex))
- camel_folder_refresh_info (folder, ex);
- camel_object_unref (CAMEL_OBJECT (folder));
+ CamelStore *store;
+ CamelFolderInfo *info;
+ EvolutionStorage *storage;
+
+ store = camel_session_get_store (session, input->source_url, ex);
+ if (!store)
+ return;
+ storage = mail_lookup_storage (store);
+ g_return_if_fail (storage != NULL);
+
+ info = camel_store_get_folder_info (store, NULL, FALSE,
+ TRUE, TRUE, ex);
+ if (!info) {
+ camel_object_unref (CAMEL_OBJECT (store));
+ gtk_object_unref (GTK_OBJECT (storage));
+ return;
}
-
+
+ update_changed_folders (store, info, storage, "", ex);
+ camel_store_free_folder_info (store, info);
+ camel_object_unref (CAMEL_OBJECT (store));
+ gtk_object_unref (GTK_OBJECT (storage));
+
data->empty = FALSE;
return;
}
@@ -1168,7 +1228,7 @@ mail_do_flag_all_messages (CamelFolder *source, gboolean invert,
typedef struct scan_subfolders_input_s
{
- gchar *source_uri;
+ CamelStore *store;
EvolutionStorage *storage;
}
scan_subfolders_input_t;
@@ -1178,6 +1238,7 @@ typedef struct scan_subfolders_folderinfo_s
char *path;
char *name;
char *uri;
+ gboolean highlighted;
}
scan_subfolders_folderinfo_t;
@@ -1191,13 +1252,14 @@ static gchar *
describe_scan_subfolders (gpointer in_data, gboolean gerund)
{
scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data;
+ char *name;
+ name = camel_service_get_name (CAMEL_SERVICE (input->store), TRUE);
if (gerund)
- return g_strdup_printf (_("Scanning folders in \"%s\""),
- input->source_uri);
+ return g_strdup_printf (_("Scanning folders in \"%s\""), name);
else
- return g_strdup_printf (_("Scan folders in \"%s\""),
- input->source_uri);
+ return g_strdup_printf (_("Scan folders in \"%s\""), name);
+ g_free (name);
}
static void
@@ -1207,10 +1269,10 @@ setup_scan_subfolders (gpointer in_data, gpointer op_data,
scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data;
scan_subfolders_op_t *data = (scan_subfolders_op_t *) op_data;
+ camel_object_ref (CAMEL_OBJECT (input->store));
gtk_object_ref (GTK_OBJECT (input->storage));
- data->new_folders = g_ptr_array_new ();
- gtk_object_ref (GTK_OBJECT(input->storage));
+ data->new_folders = g_ptr_array_new ();
}
static void
@@ -1220,7 +1282,14 @@ add_folders (GPtrArray *folders, const char *prefix, CamelFolderInfo *fi)
info = g_new (scan_subfolders_folderinfo_t, 1);
info->path = g_strdup_printf ("%s/%s", prefix, fi->name);
- info->name = g_strdup (fi->name);
+ if (fi->unread_message_count > 0) {
+ info->name = g_strdup_printf ("%s (%d)", fi->name,
+ fi->unread_message_count);
+ info->highlighted = TRUE;
+ } else {
+ info->name = g_strdup (fi->name);
+ info->highlighted = FALSE;
+ }
info->uri = g_strdup (fi->url);
g_ptr_array_add (folders, info);
if (fi->child)
@@ -1234,23 +1303,14 @@ do_scan_subfolders (gpointer in_data, gpointer op_data, CamelException *ex)
{
scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data;
scan_subfolders_op_t *data = (scan_subfolders_op_t *) op_data;
- CamelStore *store;
CamelFolderInfo *tree;
- store = camel_session_get_store (session, input->source_uri, ex);
- if (!store)
- return;
-
- tree = camel_store_get_folder_info (store, NULL, TRUE, TRUE, TRUE, ex);
+ tree = camel_store_get_folder_info (input->store, NULL, FALSE,
+ TRUE, TRUE, ex);
if (tree) {
add_folders (data->new_folders, "", tree);
- camel_store_free_folder_info (store, tree);
+ camel_store_free_folder_info (input->store, tree);
}
-
- /* FIXME: We intentionally lose a reference to the store here
- * for the benefit of the IMAP provider. Undo this when the
- * namespace situation is fixed.
- */
}
static void
@@ -1267,7 +1327,8 @@ cleanup_scan_subfolders (gpointer in_data, gpointer op_data,
evolution_storage_new_folder (input->storage, info->path,
info->name, "mail",
info->uri ? info->uri : "",
- _("(No description)"));
+ _("(No description)"),
+ info->highlighted);
g_free (info->uri);
g_free (info->name);
@@ -1277,7 +1338,7 @@ cleanup_scan_subfolders (gpointer in_data, gpointer op_data,
g_ptr_array_free (data->new_folders, TRUE);
gtk_object_unref (GTK_OBJECT (input->storage));
- g_free (input->source_uri);
+ camel_object_unref (CAMEL_OBJECT (input->store));
}
static const mail_operation_spec op_scan_subfolders = {
@@ -1289,15 +1350,15 @@ static const mail_operation_spec op_scan_subfolders = {
};
void
-mail_do_scan_subfolders (const gchar *source_uri, EvolutionStorage *storage)
+mail_do_scan_subfolders (CamelStore *store, EvolutionStorage *storage)
{
scan_subfolders_input_t *input;
- g_return_if_fail (source_uri != NULL);
+ g_return_if_fail (CAMEL_IS_STORE (store));
g_return_if_fail (EVOLUTION_IS_STORAGE (storage));
input = g_new (scan_subfolders_input_t, 1);
- input->source_uri = g_strdup (source_uri);
+ input->store = store;
input->storage = storage;
mail_operation_queue (&op_scan_subfolders, input, TRUE);
diff --git a/mail/mail-ops.h b/mail/mail-ops.h
index e61f5f87ce..e136465cff 100644
--- a/mail/mail-ops.h
+++ b/mail/mail-ops.h
@@ -54,7 +54,7 @@ void mail_do_flag_messages (CamelFolder *source, GPtrArray *uids,
guint32 mask, guint32 set);
void mail_do_flag_all_messages (CamelFolder *source, gboolean invert,
guint32 mask, guint32 set);
-void mail_do_scan_subfolders (const gchar *source_uri, EvolutionStorage *storage);
+void mail_do_scan_subfolders (CamelStore *store, EvolutionStorage *storage);
void mail_do_attach_message (CamelFolder *folder, const char *uid,
EMsgComposer *composer);
void mail_do_forward_message (CamelMimeMessage *basis, CamelFolder *source,
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index a0c3289806..5bdac810cc 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -91,7 +91,7 @@ vfolder_refresh(void)
path = g_strdup_printf("/%s", info->name);
evolution_storage_removed_folder(vfolder_storage, path);
evolution_storage_new_folder(vfolder_storage, path, g_basename(path),
- "mail", uri, info->name);
+ "mail", uri, info->name, FALSE);
g_free(uri);
g_free(path);
}
@@ -104,7 +104,7 @@ vfolder_refresh(void)
uri = g_strdup_printf("vfolder:%s", info->name);
path = g_strdup_printf("/%s", info->name);
evolution_storage_new_folder(vfolder_storage, path, g_basename(path),
- "mail", uri, info->name);
+ "mail", uri, info->name, FALSE);
g_free(uri);
g_free(path);
}
diff --git a/mail/mail.h b/mail/mail.h
index 54d1c6b123..5623297dc2 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -115,9 +115,8 @@ GtkWidget *mail_view_create (CamelFolder *source, const char *uid, CamelMimeMess
/* component factory for lack of a better place */
/*takes a GSList of MailConfigServices */
void mail_load_storages (Evolution_Shell corba_shell, GSList *sources);
-void mail_add_new_storage (const char *uri, Evolution_Shell corba_shell, CamelException *ex);
/* used in the subscribe dialog code */
-EvolutionStorage* mail_lookup_storage (CamelService *service);
+EvolutionStorage *mail_lookup_storage (CamelStore *store);
/* session */
void session_init (void);
diff --git a/mail/subscribe-dialog.c b/mail/subscribe-dialog.c
index 30327b0fef..e74ab4f1bd 100644
--- a/mail/subscribe-dialog.c
+++ b/mail/subscribe-dialog.c
@@ -319,7 +319,8 @@ cleanup_subscribe_folder (gpointer in_data, gpointer op_data,
data->path,
data->name, "mail",
data->url,
- _("(No description)") /* XXX */);
+ _("(No description)") /* XXX */,
+ FALSE);
if (input->cb)
input->cb (input->sc, !camel_exception_is_set(ex), input->cb_data);
@@ -838,7 +839,7 @@ build_tree (SubscribeDialog *sc, CamelStore *store)
gtk_object_unref (GTK_OBJECT (sc->storage));
sc->store = store;
- sc->storage = mail_lookup_storage (CAMEL_SERVICE (sc->store));
+ sc->storage = mail_lookup_storage (sc->store);
sc->folder_info = camel_store_get_folder_info (sc->store, sc->search_top, TRUE, TRUE, FALSE, ex);
if (camel_exception_is_set (ex)) {