diff options
author | Not Zed <NotZed@Ximian.com> | 2002-05-15 20:39:17 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2002-05-15 20:39:17 +0800 |
commit | be2d7023bf9f5af1202e674e17978c75c08a6e7d (patch) | |
tree | 750e520d0dedbad45960eea63e79c8abb44007cb /mail/mail-offline-handler.c | |
parent | c1e8c1cf3a367d721973bd93d99be8279ab204de (diff) | |
download | gsoc2013-evolution-be2d7023bf9f5af1202e674e17978c75c08a6e7d.tar gsoc2013-evolution-be2d7023bf9f5af1202e674e17978c75c08a6e7d.tar.gz gsoc2013-evolution-be2d7023bf9f5af1202e674e17978c75c08a6e7d.tar.bz2 gsoc2013-evolution-be2d7023bf9f5af1202e674e17978c75c08a6e7d.tar.lz gsoc2013-evolution-be2d7023bf9f5af1202e674e17978c75c08a6e7d.tar.xz gsoc2013-evolution-be2d7023bf9f5af1202e674e17978c75c08a6e7d.tar.zst gsoc2013-evolution-be2d7023bf9f5af1202e674e17978c75c08a6e7d.zip |
Implement prep_offline for an individual folder. (set_offline_do): Only
2002-05-15 Not Zed <NotZed@Ximian.com>
* mail-ops.c (prep_offline_do):
(prep_offline_done):
(prep_offline_free):
(mail_prep_offline): Implement prep_offline for an individual
folder.
(set_offline_do): Only call disco_store_set_status or disconnect
for the store, dont do any offline prep stuff.
* mail-offline-handler.c: Applied patch from Ettore to hook in
extra offline interfaces.
(impl_destroy): Dont free listener here anymore, its removed, but
free sync table.
(mail_offline_handler_init): Same for setup.
(impl_syncFolder): Implement.
(sync_done): handles finalising synchronisation of 1 folder.
(sync_status): progress reporting, camel side.
(sync_timeout): progress reporting, gmainloop side.
(impl_cancelSyncFolder): Implement.
(impl_goOffline, storage_go_offline, went_offline): Dont copy the
listener to our struct - its an argument, not a member, so give
each thread its own copy.
svn path=/trunk/; revision=16799
Diffstat (limited to 'mail/mail-offline-handler.c')
-rw-r--r-- | mail/mail-offline-handler.c | 144 |
1 files changed, 118 insertions, 26 deletions
diff --git a/mail/mail-offline-handler.c b/mail/mail-offline-handler.c index 5217420570..a24f52a79c 100644 --- a/mail/mail-offline-handler.c +++ b/mail/mail-offline-handler.c @@ -38,7 +38,7 @@ static BonoboXObjectClass *parent_class = NULL; struct _MailOfflineHandlerPrivate { - GNOME_Evolution_OfflineProgressListener listener_interface; + GHashTable *sync_table; }; static gboolean @@ -107,37 +107,139 @@ impl_prepareForOffline (PortableServer_Servant servant, *active_connection_list = create_connection_list (); } +/* keep track of each sync in progress */ +struct _sync_info { + char *uri; /* uri of folder being synced */ + CamelOperation *cancel; /* progress report/cancellation object */ + GNOME_Evolution_SyncFolderProgressListener listener; + int pc; /* percent complete (0-100) */ + int lastpc; /* last percent reported, so we dont overreport */ + int id; /* timeout id */ +}; + static void -went_offline (CamelStore *store, void *data) +impl_cancelSyncFolder (PortableServer_Servant servant, + const GNOME_Evolution_Folder *folder, + CORBA_Environment *ev) { - MailOfflineHandler *offline_handler = data; + MailOfflineHandler *offline_handler; MailOfflineHandlerPrivate *priv; + struct _sync_info *info; + + offline_handler = MAIL_OFFLINE_HANDLER (bonobo_object_from_servant (servant)); + priv = offline_handler->priv; + + info = g_hash_table_lookup(priv->sync_table, folder->physicalUri); + if (info) + camel_operation_cancel(info->cancel); + else + g_warning("Shell tried to cancel sync of '%s': no such folder", folder->physicalUri); +} + +static int sync_timeout(struct _sync_info *info) +{ CORBA_Environment ev; - GNOME_Evolution_ConnectionList *connection_list; + if (info->pc != info->lastpc) { + CORBA_exception_init(&ev); + GNOME_Evolution_SyncFolderProgressListener_updateProgress(info->listener, info->pc/100.0, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_warning("Error updating offline progress"); + CORBA_exception_free(&ev); + info->lastpc = info->pc; + } + + return TRUE; +} + +static void sync_status(CamelOperation *op, const char *what, int pc, void *data) +{ + struct _sync_info *info = data; + + if (pc == CAMEL_OPERATION_START) + pc = 0; + else if (pc == CAMEL_OPERATION_END) + pc = 100; + + info->pc = pc; +} + +static void +sync_done(const char *uri, void *crap) +{ + CORBA_Environment ev; + struct _sync_info *info = crap; + + g_source_remove(info->id); + + CORBA_exception_init(&ev); + GNOME_Evolution_SyncFolderProgressListener_reportSuccess(info->listener, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_warning("Error sending offline completion: hang likely"); + CORBA_Object_release(info->listener, &ev); + CORBA_exception_free(&ev); + + g_free(info->uri); + camel_operation_unref(info->cancel); + g_free(info); +} + +static void +impl_syncFolder (PortableServer_Servant servant, + const GNOME_Evolution_Folder *folder, + const GNOME_Evolution_SyncFolderProgressListener progress_listener, + CORBA_Environment *ev) +{ + MailOfflineHandler *offline_handler; + MailOfflineHandlerPrivate *priv; + struct _sync_info *info; + + offline_handler = MAIL_OFFLINE_HANDLER(bonobo_object_from_servant (servant)); priv = offline_handler->priv; + info = g_malloc(sizeof(*info)); + info->listener = CORBA_Object_duplicate(progress_listener, ev); + info->pc = 0; + info->uri = g_strdup(folder->physicalUri); + info->id = g_timeout_add(500, (GSourceFunc)sync_timeout, info); + info->cancel = camel_operation_new(sync_status, info); + + g_hash_table_insert(priv->sync_table, info->uri, info); + + mail_prep_offline(info->uri, info->cancel, sync_done, info); +} + +static void +went_offline (CamelStore *store, void *data) +{ + CORBA_Environment ev; + GNOME_Evolution_ConnectionList *connection_list; + GNOME_Evolution_OfflineProgressListener listener = data; + connection_list = create_connection_list (); CORBA_exception_init (&ev); - - GNOME_Evolution_OfflineProgressListener_updateProgress (priv->listener_interface, connection_list, &ev); + GNOME_Evolution_OfflineProgressListener_updateProgress(listener, connection_list, &ev); if (ev._major != CORBA_NO_EXCEPTION) g_warning ("Error updating offline progress"); + CORBA_Object_release(listener, &ev); CORBA_exception_free (&ev); - - /* CORBA_free (connection_list); */ + CORBA_free (connection_list); } static void storage_go_offline (gpointer key, gpointer value, gpointer data) { CamelStore *store = key; - MailOfflineHandler *offline_handler = data; + GNOME_Evolution_OfflineProgressListener listener = data; + CORBA_Environment ev; - if (service_is_relevant (CAMEL_SERVICE (store), TRUE)) - mail_store_set_offline (store, TRUE, went_offline, offline_handler); + CORBA_exception_init(&ev); + if (service_is_relevant (CAMEL_SERVICE (store), TRUE)) { + mail_store_set_offline (store, TRUE, went_offline, CORBA_Object_duplicate(listener, &ev)); + } + CORBA_exception_free(&ev); } static void @@ -146,19 +248,15 @@ impl_goOffline (PortableServer_Servant servant, CORBA_Environment *ev) { MailOfflineHandler *offline_handler; - MailOfflineHandlerPrivate *priv; offline_handler = MAIL_OFFLINE_HANDLER (bonobo_object_from_servant (servant)); - priv = offline_handler->priv; - - priv->listener_interface = CORBA_Object_duplicate (progress_listener, ev); /* This will disable further auto-mail-check action. */ camel_session_set_online (session, FALSE); /* FIXME: If send/receive active, wait for it to finish */ - mail_storages_foreach (storage_go_offline, offline_handler); + mail_storages_foreach (storage_go_offline, progress_listener); } static void @@ -196,15 +294,7 @@ impl_destroy (GtkObject *object) offline_handler = MAIL_OFFLINE_HANDLER (object); priv = offline_handler->priv; - - if (priv->listener_interface != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - CORBA_Object_release (priv->listener_interface, &ev); - CORBA_exception_free (&ev); - } - + g_hash_table_destroy(priv->sync_table); g_free (priv); if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) @@ -225,6 +315,8 @@ mail_offline_handler_class_init (MailOfflineHandlerClass *klass) epv = & klass->epv; epv->_get_isOffline = impl__get_isOffline; epv->prepareForOffline = impl_prepareForOffline; + epv->syncFolder = impl_syncFolder; + epv->cancelSyncFolder = impl_cancelSyncFolder; epv->goOffline = impl_goOffline; epv->goOnline = impl_goOnline; @@ -237,7 +329,7 @@ mail_offline_handler_init (MailOfflineHandler *offline_handler) MailOfflineHandlerPrivate *priv; priv = g_new (MailOfflineHandlerPrivate, 1); - priv->listener_interface = CORBA_OBJECT_NIL; + priv->sync_table = g_hash_table_new(g_str_hash, g_str_equal); offline_handler->priv = priv; } |