diff options
-rw-r--r-- | mail/ChangeLog | 16 | ||||
-rw-r--r-- | mail/Makefile.am | 4 | ||||
-rw-r--r-- | mail/component-factory.c | 19 | ||||
-rw-r--r-- | mail/mail-offline-handler.c | 242 | ||||
-rw-r--r-- | mail/mail-offline-handler.h | 70 | ||||
-rw-r--r-- | mail/mail-ops.c | 95 | ||||
-rw-r--r-- | mail/mail-ops.h | 5 | ||||
-rw-r--r-- | mail/mail-send-recv.c | 4 | ||||
-rw-r--r-- | mail/mail.h | 2 |
9 files changed, 453 insertions, 4 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index 019aec7066..6caf961a81 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,19 @@ +2001-05-09 Dan Winship <danw@ximian.com> + + * mail-offline-handler.c: New file, started by Ettore, finished by + me, to implement the GNOME_Evolution_Offline interface. + + * Makefile.am (evolution_mail_SOURCES): Add + mail-offline-handler.[ch] + + * mail-ops.c (mail_store_set_offline): Set a store online or + offline. + + * mail-send-recv.c (auto_timeout): Don't run auto-check-for-mail + while the session is offline. + + * component-factory.c (component_fn): Set up offline handler. + 2001-05-09 Christopher James Lahey <clahey@ximian.com> * importers/evolution-mbox-importer.c (load_file_fn): Made a const diff --git a/mail/Makefile.am b/mail/Makefile.am index ba4dc91d59..42fec42f49 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -77,6 +77,8 @@ evolution_mail_SOURCES = \ mail-mlist-magic.h \ mail-mt.c \ mail-mt.h \ + mail-offline-handler.c \ + mail-offline-handler.h \ mail-ops.c \ mail-ops.h \ mail-search.c \ @@ -104,11 +106,11 @@ evolution_mail_SOURCES = \ mail.h evolution_mail_LDADD = \ + $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/shell/libeshell.a \ $(top_builddir)/composer/libcomposer.a \ $(top_builddir)/widgets/misc/libemiscwidgets.a \ $(top_builddir)/camel/libcamel.la \ - $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/e-util/ename/libename.la \ $(top_builddir)/libibex/libibex.la \ $(top_builddir)/filter/libfilter.la \ diff --git a/mail/component-factory.c b/mail/component-factory.c index 759d7294f1..26796201a1 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -40,6 +40,7 @@ #include "mail-config.h" #include "mail-tools.h" #include "mail-ops.h" +#include "mail-offline-handler.h" #include "mail-local.h" #include "mail-session.h" #include "mail-mt.h" @@ -287,12 +288,13 @@ static BonoboObject * component_fn (BonoboGenericFactory *factory, void *closure) { EvolutionShellComponent *shell_component; + MailOfflineHandler *offline_handler; shell_component = evolution_shell_component_new (folder_types, create_view, create_folder, NULL, /* remove_folder_fn */ - NULL, /* copy_folder_fn */ + NULL, /* xfer_folder_fn */ NULL, /* populate_folder_context_menu_fn */ NULL, /* get_dnd_selection_fn */ NULL); @@ -306,6 +308,9 @@ component_fn (BonoboGenericFactory *factory, void *closure) gtk_signal_connect (GTK_OBJECT (shell_component), "destroy", GTK_SIGNAL_FUNC (owner_unset_cb), NULL); + offline_handler = mail_offline_handler_new (); + bonobo_object_add_interface (BONOBO_OBJECT (shell_component), BONOBO_OBJECT (offline_handler)); + return BONOBO_OBJECT (shell_component); } @@ -510,3 +515,15 @@ mail_lookup_storage (CamelStore *store) return storage; } + +int +mail_storages_count (void) +{ + return g_hash_table_size (storages_hash); +} + +void +mail_storages_foreach (GHFunc func, gpointer data) +{ + g_hash_table_foreach (storages_hash, func, data); +} diff --git a/mail/mail-offline-handler.c b/mail/mail-offline-handler.c new file mode 100644 index 0000000000..d26f2a6a86 --- /dev/null +++ b/mail/mail-offline-handler.c @@ -0,0 +1,242 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* mail-offline-handler.c + * + * Copyright (C) 2001 Ximian, Inc. + * + * 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 the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: + * Ettore Perazzoli <ettore@ximian.com> + * Dan Winship <danw@ximian.com> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "mail-offline-handler.h" +#include "mail.h" +#include "mail-ops.h" + +#include <gtk/gtkmain.h> + +#include <gal/util/e-util.h> + +#define PARENT_TYPE bonobo_x_object_get_type () +static BonoboXObjectClass *parent_class = NULL; + +struct _MailOfflineHandlerPrivate { + GNOME_Evolution_OfflineProgressListener listener_interface; +}; + +static void +add_connection (gpointer key, gpointer data, gpointer user_data) +{ + CamelService *service = key; + GNOME_Evolution_ConnectionList *list = user_data; + + if (!(service->provider->flags & CAMEL_PROVIDER_IS_REMOTE) || + !service->connected) + return; + + if (CAMEL_IS_DISCO_STORE (service) && + camel_disco_store_status (CAMEL_DISCO_STORE (service)) == CAMEL_DISCO_STORE_OFFLINE) + return; + + list->_buffer[list->_length].hostName = CORBA_string_dup (service->url->host); + list->_buffer[list->_length].type = CORBA_string_dup (service->provider->name); + list->_length++; +} + +static GNOME_Evolution_ConnectionList * +create_connection_list (void) +{ + GNOME_Evolution_ConnectionList *list; + + list = GNOME_Evolution_ConnectionList__alloc (); + list->_length = 0; + list->_maximum = mail_storages_count (); + list->_buffer = CORBA_sequence_GNOME_Evolution_Connection_allocbuf (list->_maximum); + + mail_storages_foreach (add_connection, list); + + return list; +} + +/* GNOME::Evolution::Offline methods. */ + +static CORBA_boolean +impl__get_isOffline (PortableServer_Servant servant, + CORBA_Environment *ev) +{ + return !camel_session_is_online (session); +} + +static void +impl_prepareForOffline (PortableServer_Servant servant, + GNOME_Evolution_ConnectionList **active_connection_list, + CORBA_Environment *ev) +{ + MailOfflineHandler *offline_handler; + MailOfflineHandlerPrivate *priv; + + offline_handler = MAIL_OFFLINE_HANDLER (bonobo_object_from_servant (servant)); + priv = offline_handler->priv; + + *active_connection_list = create_connection_list (); +} + +static void +went_offline (CamelStore *store, void *data) +{ + MailOfflineHandler *offline_handler = data; + MailOfflineHandlerPrivate *priv; + CORBA_Environment ev; + GNOME_Evolution_ConnectionList *connection_list; + + priv = offline_handler->priv; + + connection_list = create_connection_list (); + + CORBA_exception_init (&ev); + + GNOME_Evolution_OfflineProgressListener_updateProgress (priv->listener_interface, connection_list, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_warning ("Error updating offline progress"); + + CORBA_exception_free (&ev); + + /* CORBA_free (connection_list); */ +} + +static void +storage_go_offline (gpointer key, gpointer value, gpointer data) +{ + CamelStore *store = key; + MailOfflineHandler *offline_handler = data; + + mail_store_set_offline (store, TRUE, went_offline, offline_handler); +} + +static void +impl_goOffline (PortableServer_Servant servant, + const GNOME_Evolution_OfflineProgressListener progress_listener, + 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); +} + +static void +storage_go_online (gpointer key, gpointer value, gpointer data) +{ + CamelStore *store = key; + + mail_store_set_offline (store, FALSE, NULL, NULL); +} + +static void +impl_goOnline (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; + + mail_storages_foreach (storage_go_online, NULL); +} + +/* GtkObject methods. */ + +static void +impl_destroy (GtkObject *object) +{ + MailOfflineHandler *offline_handler; + MailOfflineHandlerPrivate *priv; + + 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_free (priv); + + if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +/* GTK+ type initialization. */ + +static void +mail_offline_handler_class_init (MailOfflineHandlerClass *klass) +{ + GtkObjectClass *object_class; + POA_GNOME_Evolution_Offline__epv *epv; + + object_class = GTK_OBJECT_CLASS (klass); + object_class->destroy = impl_destroy; + + epv = & klass->epv; + epv->_get_isOffline = impl__get_isOffline; + epv->prepareForOffline = impl_prepareForOffline; + epv->goOffline = impl_goOffline; + epv->goOnline = impl_goOnline; + + parent_class = gtk_type_class (PARENT_TYPE); +} + +static void +mail_offline_handler_init (MailOfflineHandler *offline_handler) +{ + MailOfflineHandlerPrivate *priv; + + priv = g_new (MailOfflineHandlerPrivate, 1); + priv->listener_interface = CORBA_OBJECT_NIL; + + offline_handler->priv = priv; +} + +MailOfflineHandler * +mail_offline_handler_new (void) +{ + MailOfflineHandler *new; + + new = gtk_type_new (mail_offline_handler_get_type ()); + + return new; +} + +BONOBO_X_TYPE_FUNC_FULL (MailOfflineHandler, GNOME_Evolution_Offline, PARENT_TYPE, mail_offline_handler); diff --git a/mail/mail-offline-handler.h b/mail/mail-offline-handler.h new file mode 100644 index 0000000000..6026805a5a --- /dev/null +++ b/mail/mail-offline-handler.h @@ -0,0 +1,70 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* mail-offline-handler.h + * + * Copyright (C) 2001 Ximian, Inc. + * + * 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 the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli <ettore@ximian.com> + */ + +#ifndef _MAIL_OFFLINE_HANDLER_H_ +#define _MAIL_OFFLINE_HANDLER_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <bonobo/bonobo-xobject.h> +#include "Evolution.h" + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define MAIL_TYPE_OFFLINE_HANDLER (mail_offline_handler_get_type ()) +#define MAIL_OFFLINE_HANDLER(obj) (GTK_CHECK_CAST ((obj), MAIL_TYPE_OFFLINE_HANDLER, MailOfflineHandler)) +#define MAIL_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), MAIL_TYPE_OFFLINE_HANDLER, MailOfflineHandlerClass)) +#define MAIL_IS_OFFLINE_HANDLER(obj) (GTK_CHECK_TYPE ((obj), MAIL_TYPE_OFFLINE_HANDLER)) +#define MAIL_IS_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), MAIL_TYPE_OFFLINE_HANDLER)) + + +typedef struct _MailOfflineHandler MailOfflineHandler; +typedef struct _MailOfflineHandlerPrivate MailOfflineHandlerPrivate; +typedef struct _MailOfflineHandlerClass MailOfflineHandlerClass; + +struct _MailOfflineHandler { + BonoboXObject parent; + + MailOfflineHandlerPrivate *priv; +}; + +struct _MailOfflineHandlerClass { + BonoboXObjectClass parent_class; + + POA_GNOME_Evolution_Offline__epv epv; +}; + + +GtkType mail_offline_handler_get_type (void); +MailOfflineHandler *mail_offline_handler_new (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _MAIL_OFFLINE_HANDLER_H_ */ diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 05ab7cbf4b..5b106636dc 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -1917,3 +1917,98 @@ mail_save_part(CamelMimePart *part, const char *path, return id; } + + +/* ** GO OFFLINE ***************************************************** */ + +struct _set_offline_msg { + struct _mail_msg msg; + + CamelStore *store; + gboolean offline; + void (*done)(CamelStore *store, void *data); + void *data; +}; + +static char *set_offline_desc(struct _mail_msg *mm, int done) +{ + struct _set_offline_msg *m = (struct _set_offline_msg *)mm; + char *service_name = camel_service_get_name (CAMEL_SERVICE (m->store), TRUE); + char *msg; + + msg = g_strdup_printf (_("Disconnecting from %s"), service_name); + g_free (service_name); + return msg; +} + +static void set_offline_do(struct _mail_msg *mm) +{ + struct _set_offline_msg *m = (struct _set_offline_msg *)mm; + + if (CAMEL_IS_DISCO_STORE (m->store) && + camel_disco_store_can_work_offline (CAMEL_DISCO_STORE (m->store))) { + if (m->offline) { + CamelFolder *inbox; + + /* FIXME. Something more generic here... */ + inbox = camel_store_get_inbox (m->store, NULL); + if (inbox) { + camel_disco_folder_prepare_for_offline ( + CAMEL_DISCO_FOLDER (inbox), + "(match-all (not (system-flag \"Seen\")))", + &mm->ex); + camel_object_unref (CAMEL_OBJECT (inbox)); + if (camel_exception_is_set (&mm->ex)) + return; + } + } + + camel_disco_store_set_status (CAMEL_DISCO_STORE (m->store), + m->offline ? CAMEL_DISCO_STORE_OFFLINE : + CAMEL_DISCO_STORE_ONLINE, &mm->ex); + } else { + if (m->offline) { + camel_service_disconnect (CAMEL_SERVICE (m->store), + TRUE, &mm->ex); + } + } +} + +static void set_offline_done(struct _mail_msg *mm) +{ + struct _set_offline_msg *m = (struct _set_offline_msg *)mm; + + if (m->done) + m->done(m->store, m->data); +} + +static void set_offline_free(struct _mail_msg *mm) +{ + struct _set_offline_msg *m = (struct _set_offline_msg *)mm; + + camel_object_unref((CamelObject *)m->store); +} + +static struct _mail_msg_op set_offline_op = { + set_offline_desc, + set_offline_do, + set_offline_done, + set_offline_free, +}; + +void +mail_store_set_offline (CamelStore *store, gboolean offline, + void (*done)(CamelStore *, void *data), + void *data) +{ + struct _set_offline_msg *m; + + m = mail_msg_new(&set_offline_op, NULL, sizeof(*m)); + m->store = store; + camel_object_ref((CamelObject *)store); + m->offline = offline; + m->data = data; + m->done = done; + + e_thread_put(mail_thread_queued, (EMsg *)m); +} diff --git a/mail/mail-ops.h b/mail/mail-ops.h index efca4faaab..e19051ab1b 100644 --- a/mail/mail-ops.h +++ b/mail/mail-ops.h @@ -140,6 +140,11 @@ void mail_filter_folder (CamelFolder *source_folder, GPtrArray *uids, /* convenience function for above */ void mail_filter_on_demand (CamelFolder *folder, GPtrArray *uids); +/* Work Offline */ +void mail_store_set_offline (CamelStore *store, gboolean offline, + void (*done)(CamelStore *, void *data), + void *data); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c index ded42cb6ff..f59f322a3d 100644 --- a/mail/mail-send-recv.c +++ b/mail/mail-send-recv.c @@ -647,7 +647,8 @@ auto_timeout(void *data) { struct _auto_data *info = data; - mail_receive_uri(info->uri, info->keep); + if (camel_session_is_online(session)) + mail_receive_uri(info->uri, info->keep); return TRUE; } @@ -784,4 +785,3 @@ void mail_receive_uri(const char *uri, int keep) } gtk_object_unref((GtkObject *)fc); } - diff --git a/mail/mail.h b/mail/mail.h index f0f2fa0ee6..a024ff23e4 100644 --- a/mail/mail.h +++ b/mail/mail.h @@ -70,3 +70,5 @@ void mail_load_storages (GNOME_Evolution_Shell shell, const GSList *sources, gbo void mail_hash_storage (CamelService *store, EvolutionStorage *storage); EvolutionStorage *mail_lookup_storage (CamelStore *store); +void mail_storages_foreach (GHFunc func, gpointer data); +int mail_storages_count (void); |