aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mail-remote/evolution-mail-session.c
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2005-05-24 17:39:24 +0800
committerMichael Zucci <zucchi@src.gnome.org>2005-05-24 17:39:24 +0800
commitc33282a6549d7f7d64a27a9d14e6e99b114053b9 (patch)
treea1e58438c102e24de7a38cb86cce1896802f4df2 /plugins/mail-remote/evolution-mail-session.c
parent0822a01317ed088a14aa9268f1d086ff73cb423c (diff)
downloadgsoc2013-evolution-c33282a6549d7f7d64a27a9d14e6e99b114053b9.tar
gsoc2013-evolution-c33282a6549d7f7d64a27a9d14e6e99b114053b9.tar.gz
gsoc2013-evolution-c33282a6549d7f7d64a27a9d14e6e99b114053b9.tar.bz2
gsoc2013-evolution-c33282a6549d7f7d64a27a9d14e6e99b114053b9.tar.lz
gsoc2013-evolution-c33282a6549d7f7d64a27a9d14e6e99b114053b9.tar.xz
gsoc2013-evolution-c33282a6549d7f7d64a27a9d14e6e99b114053b9.tar.zst
gsoc2013-evolution-c33282a6549d7f7d64a27a9d14e6e99b114053b9.zip
Lots more work. Now implements a full listener interface. Filled out api.
2005-05-24 Not Zed <NotZed@Ximian.com> * Lots more work. Now implements a full listener interface. Filled out api. svn path=/trunk/; revision=29406
Diffstat (limited to 'plugins/mail-remote/evolution-mail-session.c')
-rw-r--r--plugins/mail-remote/evolution-mail-session.c237
1 files changed, 196 insertions, 41 deletions
diff --git a/plugins/mail-remote/evolution-mail-session.c b/plugins/mail-remote/evolution-mail-session.c
index 7f1e854f1a..6cdee95b2b 100644
--- a/plugins/mail-remote/evolution-mail-session.c
+++ b/plugins/mail-remote/evolution-mail-session.c
@@ -38,21 +38,26 @@
#include <camel/camel-session.h>
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Mail_Session_Factory:" BASE_VERSION
-#define MAIL_SESSION_ID "OAFIID:GNOME_Evolution_Mail_Session:" BASE_VERSION
-
#define PARENT_TYPE bonobo_object_get_type ()
static BonoboObjectClass *parent_class = NULL;
#define _PRIVATE(o) (g_type_instance_get_private ((GTypeInstance *)o, evolution_mail_session_get_type()))
+struct _listener {
+ struct _listener *next;
+ struct _listener *prev;
+
+ CORBA_long flags;
+ GNOME_Evolution_Mail_Listener listener;
+};
+
struct _EvolutionMailSessionPrivate {
EAccountList *accounts;
GList *stores;
/* FIXME: locking */
- GSList *listeners;
+ EDList listeners;
guint account_added;
guint account_changed;
@@ -83,6 +88,8 @@ impl_dispose (GObject *object)
/* FIXME: Free accounts */
+ /* FIXME: free listners */
+
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
@@ -129,7 +136,6 @@ impl_getStores(PortableServer_Servant _servant,
seq->_length = len;
seq->_maximum = len;
seq->_buffer = GNOME_Evolution_Mail_StoreInfos_allocbuf(seq->_length);
-
CORBA_sequence_set_release(seq, TRUE);
l = p->stores;
@@ -146,14 +152,31 @@ impl_getStores(PortableServer_Servant _servant,
static void
impl_addListener(PortableServer_Servant _servant,
const GNOME_Evolution_Mail_Listener listener,
+ CORBA_long flags,
CORBA_Environment * ev)
{
EvolutionMailSession *ems = (EvolutionMailSession *)bonobo_object_from_servant(_servant);
struct _EvolutionMailSessionPrivate *p = _PRIVATE(ems);
+ struct _listener *l;
- printf("Adding listener to session\n");
+ printf("Adding listener to session %p\n", listener);
+ l = g_malloc0(sizeof(*l));
+ l->listener = CORBA_Object_duplicate(listener, ev);
+ l->flags = flags?flags:~0;
- p->listeners = g_slist_append(p->listeners, CORBA_Object_duplicate(listener, ev));
+ e_dlist_addtail(&p->listeners, (EDListNode *)l);
+}
+
+static void
+remove_listener(struct _listener *l)
+{
+ CORBA_Environment ev = { 0 };
+
+ CORBA_Object_release(l->listener, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION)
+ CORBA_exception_free(&ev);
+ e_dlist_remove((EDListNode *)l);
+ g_free(l);
}
static void
@@ -163,12 +186,20 @@ impl_removeListener(PortableServer_Servant _servant,
{
EvolutionMailSession *ems = (EvolutionMailSession *)bonobo_object_from_servant(_servant);
struct _EvolutionMailSessionPrivate *p = _PRIVATE(ems);
+ struct _listener *l;
printf("Removing listener from session\n");
- /* FIXME: need to use proper comparison function & free stuff, this works with orbit though */
- p->listeners = g_slist_remove(p->listeners, listener);
- CORBA_Object_release(listener, ev);
+ l = (struct _listener *)p->listeners.head;
+ while (l->next) {
+ /* FIXME: need to use proper comparison function & free stuff, this works with orbit though */
+ if (l->listener == listener) {
+ remove_listener(l);
+ break;
+ }
+
+ l = l->next;
+ }
}
/* Initialization */
@@ -194,33 +225,50 @@ evolution_mail_session_class_init (EvolutionMailSessionClass *klass)
}
static void
-ems_listener_event(EvolutionMailSession *ems, GNOME_Evolution_Mail_ChangeType how, EvolutionMailStore *store)
+ems_set_changes(GNOME_Evolution_Mail_SessionChange *change, GNOME_Evolution_Mail_ChangeType how, EvolutionMailStore *store)
{
- struct _EvolutionMailSessionPrivate *p = _PRIVATE(ems);
- GNOME_Evolution_Mail_SessionChange *change;
- GSList *l;
-
- for (l=p->listeners;l;l=g_slist_next(l)) {
- CORBA_Environment ev;
-
- change = GNOME_Evolution_Mail_SessionChange__alloc();
- change->type = how;
-
- change->stores._length = 1;
- change->stores._maximum = 1;
- change->stores._buffer = GNOME_Evolution_Mail_StoreInfos_allocbuf(change->stores._maximum);
- CORBA_sequence_set_release(&change->stores, TRUE);
- e_mail_storeinfo_set_store(&change->stores._buffer[0], store);
-
- GNOME_Evolution_Mail_Listener_sessionChanged(l->data, bonobo_object_corba_objref((BonoboObject *)ems), change, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- printf("listener.sessionChanged() failed: %s\n", ev._id);
- /* TODO: if it fails, remove the listener? */
- CORBA_exception_free(&ev);
- } else {
- printf("listener.sessionChanged() successful\n");
- }
+ change->type = how;
+ change->stores._length = 1;
+ change->stores._maximum = 1;
+ change->stores._buffer = GNOME_Evolution_Mail_StoreInfos_allocbuf(change->stores._maximum);
+ CORBA_sequence_set_release(&change->stores, TRUE);
+
+ e_mail_storeinfo_set_store(&change->stores._buffer[0], store);
+}
+
+static void
+ems_listener_session_event(EvolutionMailSession *ems, GNOME_Evolution_Mail_ChangeType how, EvolutionMailStore *store)
+{
+ GNOME_Evolution_Mail_SessionChanges *changes;
+ CORBA_long flags = 0;
+
+ switch (how) {
+ case GNOME_Evolution_Mail_ADDED:
+ flags = GNOME_Evolution_Mail_Session_SESSION_ADDED;
+ break;
+ case GNOME_Evolution_Mail_CHANGED:
+ flags = GNOME_Evolution_Mail_Session_SESSION_CHANGED;
+ break;
+ case GNOME_Evolution_Mail_REMOVED:
+ flags = GNOME_Evolution_Mail_Session_SESSION_REMOVED;
+ break;
}
+
+ if ((evolution_mail_session_listening(ems) & flags) == 0)
+ return;
+
+ /* NB: we only ever create 1 changetype at the moment */
+
+ changes = GNOME_Evolution_Mail_SessionChanges__alloc();
+ changes->_maximum = 1;
+ changes->_length = 1;
+ changes->_buffer = GNOME_Evolution_Mail_SessionChanges_allocbuf(1);
+ CORBA_sequence_set_release(changes, TRUE);
+ ems_set_changes(&changes->_buffer[0], how, store);
+
+ evolution_mail_session_session_changed(ems, changes);
+
+ CORBA_free(changes);
}
static void
@@ -234,7 +282,7 @@ ems_account_added(EAccountList *eal, EAccount *ea, EvolutionMailSession *ems)
printf("Account added %s\n", ea->uid);
store = evolution_mail_store_new(ems, ea);
p->stores = g_list_append(p->stores, store);
- ems_listener_event(ems, GNOME_Evolution_Mail_ADDED, store);
+ ems_listener_session_event(ems, GNOME_Evolution_Mail_ADDED, store);
}
}
@@ -257,17 +305,17 @@ ems_account_changed(EAccountList *eal, EAccount *ea, EvolutionMailSession *ems)
if (!ea->enabled) {
printf("Account changed, now disabled %s\n", ea->uid);
p->stores = g_list_remove(p->stores, store);
- ems_listener_event(ems, GNOME_Evolution_Mail_REMOVED, store);
+ ems_listener_session_event(ems, GNOME_Evolution_Mail_REMOVED, store);
g_object_unref(store);
} else {
printf("Account changed, dont know how %s\n", ea->uid);
- ems_listener_event(ems, GNOME_Evolution_Mail_CHANGED, store);
+ ems_listener_session_event(ems, GNOME_Evolution_Mail_CHANGED, store);
}
} else if (ea->enabled && is_storage(ea)) {
printf("Account changed, now added %s\n", ea->uid);
store = evolution_mail_store_new(ems, ea);
p->stores = g_list_append(p->stores, store);
- ems_listener_event(ems, GNOME_Evolution_Mail_ADDED, store);
+ ems_listener_session_event(ems, GNOME_Evolution_Mail_ADDED, store);
}
}
@@ -285,7 +333,7 @@ ems_account_removed(EAccountList *eal, EAccount *ea, EvolutionMailSession *ems)
if (store->account == ea) {
printf("Account removed %s\n", ea->uid);
p->stores = g_list_remove(p->stores, store);
- ems_listener_event(ems, GNOME_Evolution_Mail_REMOVED, store);
+ ems_listener_session_event(ems, GNOME_Evolution_Mail_REMOVED, store);
g_object_unref(store);
break;
}
@@ -299,7 +347,9 @@ evolution_mail_session_init (EvolutionMailSession *ems, EvolutionMailSessionClas
struct _EvolutionMailSessionPrivate *p = _PRIVATE(ems);
EIterator *iter;
- /* FIXME: listen to changes */
+ printf("EvolutionMailSession.init\n");
+
+ e_dlist_init(&p->listeners);
/* local store first */
p->stores = g_list_append(p->stores, evolution_mail_store_new(ems, NULL));
@@ -328,4 +378,109 @@ evolution_mail_session_init (EvolutionMailSession *ems, EvolutionMailSessionClas
ems->session = mail_component_peek_session(NULL);
}
+void
+evolution_mail_session_session_changed(EvolutionMailSession *ems, GNOME_Evolution_Mail_SessionChanges *changes)
+{
+ struct _EvolutionMailSessionPrivate *p = _PRIVATE(ems);
+ struct _listener *l, *n;
+ CORBA_Environment ev;
+
+ l=(struct _listener *)p->listeners.head;
+ n=l->next;
+ while (n) {
+ if (l->flags & (GNOME_Evolution_Mail_Session_SESSION_CHANGED|GNOME_Evolution_Mail_Session_SESSION_ADDED|GNOME_Evolution_Mail_Session_SESSION_REMOVED)) {
+ memset(&ev, 0, sizeof(ev));
+ GNOME_Evolution_Mail_Listener_sessionChanged(l->listener, bonobo_object_corba_objref((BonoboObject *)ems), changes, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ printf("listener.sessionChanged() failed, removing listener: %s\n", ev._id);
+ CORBA_exception_free(&ev);
+
+ remove_listener(l);
+ } else {
+ printf("listener.sessionChanged() successful\n");
+ }
+ }
+ l = n;
+ n = n->next;
+ }
+}
+
+void
+evolution_mail_session_store_changed(EvolutionMailSession *ems, GNOME_Evolution_Mail_Store store, GNOME_Evolution_Mail_StoreChanges *changes)
+{
+ struct _EvolutionMailSessionPrivate *p = _PRIVATE(ems);
+ struct _listener *l, *n;
+ CORBA_Environment ev;
+
+ l=(struct _listener *)p->listeners.head;
+ n=l->next;
+ while (n) {
+ if (l->flags & (GNOME_Evolution_Mail_Session_STORE_CHANGED|GNOME_Evolution_Mail_Session_STORE_ADDED|GNOME_Evolution_Mail_Session_STORE_REMOVED)) {
+ memset(&ev, 0, sizeof(ev));
+ GNOME_Evolution_Mail_Listener_storeChanged(l->listener, bonobo_object_corba_objref((BonoboObject *)ems),
+ store, changes, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ printf("listener.storeChanged() failed, removing listener: %s\n", ev._id);
+ CORBA_exception_free(&ev);
+
+ remove_listener(l);
+ } else {
+ printf("listener.storeChanged() successful\n");
+ }
+ }
+ l = n;
+ n = n->next;
+ }
+}
+
+void
+evolution_mail_session_folder_changed(EvolutionMailSession *ems, GNOME_Evolution_Mail_Store store, GNOME_Evolution_Mail_Folder folder, GNOME_Evolution_Mail_FolderChanges *changes)
+{
+ struct _EvolutionMailSessionPrivate *p = _PRIVATE(ems);
+ struct _listener *l, *n;
+ CORBA_Environment ev;
+
+ l=(struct _listener *)p->listeners.head;
+ n=l->next;
+ while (n) {
+ if (l->flags & (GNOME_Evolution_Mail_Session_FOLDER_CHANGED|GNOME_Evolution_Mail_Session_FOLDER_ADDED|GNOME_Evolution_Mail_Session_FOLDER_REMOVED)) {
+ memset(&ev, 0, sizeof(ev));
+ GNOME_Evolution_Mail_Listener_folderChanged(l->listener, bonobo_object_corba_objref((BonoboObject *)ems),
+ store, folder, changes, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ printf("listener.folderChanged() failed, removing listener: %s\n", ev._id);
+ CORBA_exception_free(&ev);
+ remove_listener(l);
+ } else {
+ printf("listener.folderChanged() successful\n");
+ }
+ }
+ l = n;
+ n = n->next;
+ }
+}
+
+/**
+ * evolution_mail_session_listening:
+ * @ems:
+ *
+ * Check if anything is listening for events. Used to optimise the
+ * code so it doesn't generate events if it doesn't need to.
+ *
+ * Return value:
+ **/
+CORBA_long evolution_mail_session_listening(EvolutionMailSession *ems)
+{
+ struct _EvolutionMailSessionPrivate *p = _PRIVATE(ems);
+ struct _listener *l;
+ CORBA_long flags = 0;
+
+ for (l=(struct _listener *)p->listeners.head;l->next;l=l->next)
+ flags |= l->flags;
+
+ return flags;
+}
+
BONOBO_TYPE_FUNC_FULL (EvolutionMailSession, GNOME_Evolution_Mail_Session, PARENT_TYPE, evolution_mail_session)