aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog16
-rw-r--r--mail/Makefile.am4
-rw-r--r--mail/component-factory.c19
-rw-r--r--mail/mail-offline-handler.c242
-rw-r--r--mail/mail-offline-handler.h70
-rw-r--r--mail/mail-ops.c95
-rw-r--r--mail/mail-ops.h5
-rw-r--r--mail/mail-send-recv.c4
-rw-r--r--mail/mail.h2
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);