aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mail-remote
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
parent0822a01317ed088a14aa9268f1d086ff73cb423c (diff)
downloadgsoc2013-evolution-c33282a6549d7f7d64a27a9d14e6e99b114053b9.tar.gz
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')
-rw-r--r--plugins/mail-remote/ChangeLog5
-rw-r--r--plugins/mail-remote/Evolution-DataServer-Mail.idl66
-rw-r--r--plugins/mail-remote/Makefile.am12
-rw-r--r--plugins/mail-remote/client.c119
-rw-r--r--plugins/mail-remote/e-corba-utils.c82
-rw-r--r--plugins/mail-remote/e-corba-utils.h7
-rw-r--r--plugins/mail-remote/evolution-mail-folder.c195
-rw-r--r--plugins/mail-remote/evolution-mail-folder.h8
-rw-r--r--plugins/mail-remote/evolution-mail-listener.c112
-rw-r--r--plugins/mail-remote/evolution-mail-listener.h4
-rw-r--r--plugins/mail-remote/evolution-mail-marshal.list3
-rw-r--r--plugins/mail-remote/evolution-mail-messageiterator.c21
-rw-r--r--plugins/mail-remote/evolution-mail-session.c237
-rw-r--r--plugins/mail-remote/evolution-mail-session.h6
-rw-r--r--plugins/mail-remote/evolution-mail-store.c356
-rw-r--r--plugins/mail-remote/evolution-mail-store.h5
16 files changed, 1033 insertions, 205 deletions
diff --git a/plugins/mail-remote/ChangeLog b/plugins/mail-remote/ChangeLog
index e144b4d7ac..21ad107acd 100644
--- a/plugins/mail-remote/ChangeLog
+++ b/plugins/mail-remote/ChangeLog
@@ -1,3 +1,8 @@
+2005-05-24 Not Zed <NotZed@Ximian.com>
+
+ * Lots more work. Now implements a full listener interface.
+ Filled out api.
+
2005-05-20 Not Zed <NotZed@Ximian.com>
* Lots of work, filled out functions, cleaned up idl to make the
diff --git a/plugins/mail-remote/Evolution-DataServer-Mail.idl b/plugins/mail-remote/Evolution-DataServer-Mail.idl
index bcadaacd47..ffd32f8594 100644
--- a/plugins/mail-remote/Evolution-DataServer-Mail.idl
+++ b/plugins/mail-remote/Evolution-DataServer-Mail.idl
@@ -14,7 +14,7 @@ module GNOME {
module Evolution {
module Mail {
exception NOT_SUPPORTED {
- string why;
+// string why;
};
exception FAILED {
@@ -43,13 +43,38 @@ module Mail {
interface Session;
- struct Message {
+ // **********************************************************************
+ // MessageInfo wrappers
+ typedef string UserFlag;
+ typedef sequence <UserFlag> UserFlags;
+
+ struct UserTag {
+ string name;
+ string value; // value == "" == unset
+ };
+ typedef sequence <UserTag> UserTags;
+
+ struct MessageInfo {
string uid;
string subject;
string to;
string from;
+ long flags; // CamelMessageInfo flag bits
+ UserFlags userFlags;
+ UserTags userTags;
};
- typedef sequence <Message> Messages;
+ typedef sequence <MessageInfo> MessageInfos;
+
+ // Used to pass to altering functions
+ struct MessageInfoSet {
+ string uid;
+ long flagSet; // values bits to set in the flags
+ long flagMask; // mask of bits to change in the flags
+ UserFlags userFlagSet;
+ UserFlags userFlagUnset;
+ UserTags userTags;
+ };
+ typedef sequence <MessageInfoSet> MessageInfoSets;
/* ********************************************************************** */
// NB: tiny subset of omg properties service
@@ -78,30 +103,46 @@ module Mail {
struct StoreChange {
ChangeType type;
- Folders folders;
+ FolderInfos folders;
};
typedef sequence <StoreChange> StoreChanges;
struct FolderChange {
ChangeType type;
- Messages messages;
+ MessageInfos messages;
};
typedef sequence <FolderChange> FolderChanges;
interface Listener : Bonobo::Unknown {
- oneway void sessionChanged(in Session session, in SessionChange change);
- oneway void storeChanged(in Session session, in Store store, in StoreChanges change);
+ oneway void sessionChanged(in Session session, in SessionChanges changes);
+ // maybe folder/store should be folderinfo/storeinfo?
+ oneway void storeChanged(in Session session, in Store store, in StoreChanges changes);
oneway void folderChanged(in Session session, in Store store, in Folder folder, in FolderChanges changes);
+
+ // session is closed/exited?
+ //oneway void closed();
};
/* ********************************************************************** */
interface Session : Bonobo::Unknown {
+ // Flags to pass to addListener
+ const long SESSION_ADDED = 1 << 0;
+ const long SESSION_CHANGED = 1 << 1;
+ const long SESSION_REMOVED = 1 << 2;
+ const long STORE_ADDED = 1 << 3;
+ const long STORE_CHANGED = 1 << 4;
+ const long STORE_REMOVED = 1 << 5;
+ const long FOLDER_ADDED = 1 << 6;
+ const long FOLDER_CHANGED = 1 << 7;
+ const long FOLDER_REMOVED = 1 << 8;
+
boolean getProperties(in PropertyNames names, out Properties props);
StoreInfos getStores(in string pattern);
- void addListener(in Listener listener);
+ /* flags defines what to listen to */
+ void addListener(in Listener listener, in long flags);
void removeListener(in Listener listener);
};
@@ -111,12 +152,12 @@ module Mail {
FolderInfos getFolders(in string pattern)
raises (NOT_SUPPORTED, FAILED);
- void sendMessage(in Bonobo::Stream msg, in string from, in string recipients)
+ void sendMessage(in Bonobo::Stream msg)
raises (NOT_SUPPORTED, FAILED);
};
interface MessageIterator : Bonobo::Unknown {
- Messages next(in long limit);
+ MessageInfos next(in long limit);
};
interface Folder : Bonobo::Unknown {
@@ -124,9 +165,10 @@ module Mail {
MessageIterator getMessages(in string pattern);
- Bonobo::Stream getMessage(in string uid);
+ void changeMessages(in MessageInfoSets infos);
-// void appendMessage(in MessageInfo info, in Bonobo::Stream msg);
+// Bonobo::Stream getMessage(in string uid);
+// void appendMessage(in MessageInfoSet info, in Bonobo::Stream msg);
};
};
};
diff --git a/plugins/mail-remote/Makefile.am b/plugins/mail-remote/Makefile.am
index ccdcae2348..8a43ea3473 100644
--- a/plugins/mail-remote/Makefile.am
+++ b/plugins/mail-remote/Makefile.am
@@ -23,6 +23,8 @@ liborg_gnome_evolution_mail_remote_la_SOURCES = \
evolution-mail-session.h \
evolution-mail-store.c \
evolution-mail-store.h \
+ evolution-mail-marshal.c \
+ evolution-mail-marshal.h \
mail-remote.c
liborg_gnome_evolution_mail_remote_la_LDFLAGS = -module -avoid-version
@@ -33,6 +35,7 @@ client_SOURCES = \
client_LDADD = \
$(EVOLUTION_MAIL_LIBS) \
evolution-mail-listener.o \
+ evolution-mail-marshal.o \
Evolution-DataServer-Mail-common.o \
Evolution-DataServer-Mail-stubs.o \
Evolution-DataServer-Mail-skels.o
@@ -59,8 +62,13 @@ $(IDL_GENERATED_H) $(IDL_GENERATED_C): $(IDL)
#idl_DATA = $(IDL)
+# marshallers for glib
+MARSHAL_GENERATED = evolution-mail-marshal.c evolution-mail-marshal.h
+@EVO_MARSHAL_RULE@
+
EXTRA_DIST = \
- $(IDL)
+ $(IDL) \
+ evolution-mail-marshal.list
-BUILT_SOURCES = $(IDL_GENERATED_H) $(IDL_GENERATED_C)
+BUILT_SOURCES = $(IDL_GENERATED_H) $(IDL_GENERATED_C) $(MARSHAL_GENERATED)
CLEANFILES = $(BUILT_SOURCES)
diff --git a/plugins/mail-remote/client.c b/plugins/mail-remote/client.c
index c2e2427250..fae7401a36 100644
--- a/plugins/mail-remote/client.c
+++ b/plugins/mail-remote/client.c
@@ -1,10 +1,15 @@
+#include <stdio.h>
+#include <string.h>
+
#include <libbonobo.h>
#include "Evolution-DataServer-Mail.h"
#include "evolution-mail-listener.h"
+#include <camel/camel-folder.h>
+
static EvolutionMailListener *listener;
static GNOME_Evolution_Mail_Session
@@ -24,7 +29,7 @@ get_session(void)
if (sess != CORBA_OBJECT_NIL) {
listener = evolution_mail_listener_new();
- GNOME_Evolution_Mail_Session_addListener(sess, bonobo_object_corba_objref((BonoboObject *)listener), &ev);
+ GNOME_Evolution_Mail_Session_addListener(sess, bonobo_object_corba_objref((BonoboObject *)listener), 0, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
printf("AddListener failed: %s\n", ev._id);
CORBA_exception_free(&ev);
@@ -34,6 +39,68 @@ get_session(void)
return sess;
}
+static void
+list_folder(GNOME_Evolution_Mail_Folder folder)
+{
+ CORBA_Environment ev = { 0 };
+ GNOME_Evolution_Mail_MessageIterator iter;
+ int more, total = 0;
+
+ iter = GNOME_Evolution_Mail_Folder_getMessages(folder, "", &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ printf("getmessages failed: %s\n", ev._id);
+ CORBA_exception_free(&ev);
+ return;
+ }
+
+ do {
+ GNOME_Evolution_Mail_MessageInfos *msgs;
+ int i;
+
+ msgs = GNOME_Evolution_Mail_MessageIterator_next(iter, 50, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ printf("msgs.next(): %s\n", ev._id);
+ CORBA_exception_free(&ev);
+ break;
+ }
+
+ /* NB: set the first 50 messages in private to unseen */
+ if (total == 0) {
+ GNOME_Evolution_Mail_MessageInfoSets *changes;
+ int j;
+
+ changes = GNOME_Evolution_Mail_MessageInfoSets__alloc();
+ changes->_length = msgs->_length;
+ changes->_maximum = msgs->_maximum;
+ changes->_buffer = GNOME_Evolution_Mail_MessageInfoSets_allocbuf(changes->_maximum);
+ for (j=0;j<msgs->_length;j++) {
+ changes->_buffer[j].uid = CORBA_string_dup(msgs->_buffer[j].uid);
+ changes->_buffer[j].flagSet = 0;
+ changes->_buffer[j].flagMask = CAMEL_MESSAGE_SEEN;
+ }
+ GNOME_Evolution_Mail_Folder_changeMessages(folder, changes, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ printf("changemessages failed: %s\n", ev._id);
+ CORBA_exception_free(&ev);
+ memset(&ev, 0, sizeof(ev));
+ }
+ }
+
+ total += msgs->_length;
+ more = msgs->_length == 50;
+#if 0
+ for (i=0;i<msgs->_length;i++) {
+ printf("uid: %s '%s'\n", msgs->_buffer[i].uid, msgs->_buffer[i].subject);
+ }
+#endif
+ CORBA_free(msgs);
+ } while (more);
+
+ CORBA_Object_release(iter, &ev);
+
+ printf("Got %d messages total\n", total);
+}
+
static int domain(void *data)
{
GNOME_Evolution_Mail_Session sess;
@@ -42,17 +109,19 @@ static int domain(void *data)
CORBA_Environment ev = { 0 };
int i, j, f;
-
sess = get_session();
stores = GNOME_Evolution_Mail_Session_getStores(sess, "", &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- printf("getStores failed\n");
- return 1;
+ printf("getStores failed: %s\n", ev._id);
+ CORBA_exception_free(&ev);
+ _exit(1);
+ return 0;
}
printf("Got %d stores\n", stores->_length);
for (i=0;i<stores->_length;i++) {
+#if 0
GNOME_Evolution_Mail_PropertyName namesarray[] = {
"name", "uid"
};
@@ -62,10 +131,12 @@ static int domain(void *data)
FALSE,
};
GNOME_Evolution_Mail_Properties *props;
+#endif
GNOME_Evolution_Mail_Store store = stores->_buffer[i].store;
printf("store %p '%s' uid '%s'\n", store, stores->_buffer[i].name, stores->_buffer[i].uid);
+#if 0
GNOME_Evolution_Mail_Store_getProperties(store, &names, &props, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
printf("getProperties failed\n");
@@ -73,9 +144,9 @@ static int domain(void *data)
}
for (j=0;j<props->_length;j++) {
- printf(" %s = (%s)", props->_buffer[j].name, ORBit_tk_to_name(props->_buffer[j].value._type->kind));
+ printf(" %s = (%s)", props->_buffer[j].name, (char *)ORBit_tk_to_name(props->_buffer[j].value._type->kind));
if (props->_buffer[j].value._type == TC_CORBA_string) {
- printf(" '%s'\n", props->_buffer[j].value._value);
+ printf(" '%s'\n", (char *)props->_buffer[j].value._value);
} else {
printf(" '%s' ", BONOBO_ARG_GET_STRING(&props->_buffer[j].value));
printf(" <unknonw type>\n");
@@ -83,13 +154,27 @@ static int domain(void *data)
}
CORBA_free(props);
-#if 0
- printf("attempt send mail to store\n");
- GNOME_Evolution_Mail_Store_sendMessage(store, NULL, "notzed@ximian.com", "notzed@novell.com, user@host", &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- printf("sendmessage failed\n");
- /* FIXME:L leaks ex data? */
- CORBA_exception_init(&ev);
+#endif
+
+#if 1
+ {
+ char *msg = "To: notzed@novell.com\r\n"
+ "Subject: This is a test from auto-send\r\n"
+ "\r\n"
+ "Blah blah, test message!\r\n";
+ BonoboObject *mem;
+
+ mem = bonobo_stream_mem_create(msg, strlen(msg), TRUE, FALSE);
+
+ printf("attempt send mail to store\n");
+ GNOME_Evolution_Mail_Store_sendMessage(store, bonobo_object_corba_objref(mem), &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ printf("sendmessage failed: %s\n", ev._id);
+ CORBA_exception_free(&ev);
+ CORBA_exception_init(&ev);
+ }
+
+ g_object_unref(mem);
}
#endif
@@ -102,7 +187,15 @@ static int domain(void *data)
for (f = 0; f<folders->_length;f++) {
printf("folder %p full:'%s' name:'%s'\n", folders->_buffer[f].folder, folders->_buffer[f].full_name, folders->_buffer[f].name);
}
+
+ for (f = 0; f<folders->_length;f++) {
+ if (!strcmp(folders->_buffer[f].full_name, "Private")) {
+ list_folder(folders->_buffer[f].folder);
+ }
+ }
+
}
+ CORBA_free(folders);
}
CORBA_free(stores);
diff --git a/plugins/mail-remote/e-corba-utils.c b/plugins/mail-remote/e-corba-utils.c
index d10c95e771..545ac425e3 100644
--- a/plugins/mail-remote/e-corba-utils.c
+++ b/plugins/mail-remote/e-corba-utils.c
@@ -2,6 +2,9 @@
#include "e-corba-utils.h"
#include "evolution-mail-store.h"
+#include "evolution-mail-folder.h"
+
+#include <camel/camel-folder-summary.h>
void
e_mail_property_set_string(GNOME_Evolution_Mail_Property *prop, const char *name, const char *val)
@@ -29,3 +32,82 @@ e_mail_storeinfo_set_store(GNOME_Evolution_Mail_StoreInfo *si, EvolutionMailStor
si->store = CORBA_Object_duplicate(bonobo_object_corba_objref((BonoboObject *)store), NULL);
}
+void
+e_mail_messageinfo_set_message(GNOME_Evolution_Mail_MessageInfo *mi, CamelMessageInfo *info)
+{
+ const CamelTag *tag;
+ const CamelFlag *flag;
+ int i;
+
+ mi->uid = CORBA_string_dup(camel_message_info_uid(info));
+ mi->subject = CORBA_string_dup(camel_message_info_subject(info));
+ mi->to = CORBA_string_dup(camel_message_info_to(info));
+ mi->from = CORBA_string_dup(camel_message_info_from(info));
+ mi->flags = camel_message_info_flags(info);
+
+ flag = camel_message_info_user_flags(info);
+ mi->userFlags._maximum = camel_flag_list_size((CamelFlag **)&flag);
+ mi->userFlags._length = mi->userFlags._maximum;
+ if (mi->userFlags._maximum) {
+ mi->userFlags._buffer = GNOME_Evolution_Mail_UserFlags_allocbuf(mi->userFlags._maximum);
+ CORBA_sequence_set_release(&mi->userFlags, CORBA_TRUE);
+
+ for (i=0;flag;flag = flag->next,i++) {
+ mi->userFlags._buffer[i] = CORBA_string_dup(flag->name);
+ g_assert(mi->userFlags._buffer[i]);
+ }
+ }
+
+ tag = camel_message_info_user_tags(info);
+ mi->userTags._maximum = camel_tag_list_size((CamelTag **)&tag);
+ mi->userTags._length = mi->userTags._maximum;
+ if (mi->userTags._maximum) {
+ mi->userTags._buffer = GNOME_Evolution_Mail_UserTags_allocbuf(mi->userTags._maximum);
+ CORBA_sequence_set_release(&mi->userFlags, CORBA_TRUE);
+
+ for (i=0;tag;tag = tag->next,i++) {
+ mi->userTags._buffer[i].name = CORBA_string_dup(tag->name);
+ mi->userTags._buffer[i].value = CORBA_string_dup(tag->value);
+ g_assert(mi->userTags._buffer[i].name);
+ g_assert(mi->userTags._buffer[i].value);
+ }
+ }
+}
+
+void
+e_mail_folderinfo_set_folder(GNOME_Evolution_Mail_FolderInfo *fi, EvolutionMailFolder *emf)
+{
+ fi->name = CORBA_string_dup(emf->name);
+ fi->full_name = CORBA_string_dup(emf->full_name);
+ fi->folder = CORBA_Object_duplicate(bonobo_object_corba_objref((BonoboObject *)emf), NULL);
+}
+
+int
+e_stream_bonobo_to_camel(Bonobo_Stream in, CamelStream *out)
+{
+ Bonobo_Stream_iobuf *buf;
+ CORBA_Environment ev;
+ int go;
+
+ do {
+ Bonobo_Stream_read(in, 4096, &buf, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ printf("stream read failed: %s\n", ev._id);
+ CORBA_exception_free(&ev);
+ return -1;
+ }
+
+ go = buf->_length > 0;
+ if (go && camel_stream_write(out, buf->_buffer, buf->_length) == -1) {
+ CORBA_free(buf);
+ return -1;
+ }
+
+ CORBA_free(buf);
+ } while (go);
+
+ camel_stream_reset(out);
+
+ return 0;
+}
+
diff --git a/plugins/mail-remote/e-corba-utils.h b/plugins/mail-remote/e-corba-utils.h
index 52b76b2255..b72e8043dd 100644
--- a/plugins/mail-remote/e-corba-utils.h
+++ b/plugins/mail-remote/e-corba-utils.h
@@ -5,10 +5,17 @@
#include "Evolution-DataServer-Mail.h"
struct _EvolutionMailStore;
+struct _EvolutionMailFolder;
+struct _CamelMessageInfo;
+struct _CamelStream;
void e_mail_property_set_string(GNOME_Evolution_Mail_Property *prop, const char *name, const char *val);
void e_mail_property_set_null(GNOME_Evolution_Mail_Property *prop, const char *name);
void e_mail_storeinfo_set_store(GNOME_Evolution_Mail_StoreInfo *si, struct _EvolutionMailStore *store);
+void e_mail_folderinfo_set_folder(GNOME_Evolution_Mail_FolderInfo *fi, struct _EvolutionMailFolder *emf);
+void e_mail_messageinfo_set_message(GNOME_Evolution_Mail_MessageInfo *mi, struct _CamelMessageInfo *info);
+
+int e_stream_bonobo_to_camel(Bonobo_Stream in, struct _CamelStream *out);
#endif /* !_E_CORBA_UTILS_H */
diff --git a/plugins/mail-remote/evolution-mail-folder.c b/plugins/mail-remote/evolution-mail-folder.c
index d85ab7de08..c121c3bf3f 100644
--- a/plugins/mail-remote/evolution-mail-folder.c
+++ b/plugins/mail-remote/evolution-mail-folder.c
@@ -31,11 +31,13 @@
#include <bonobo/bonobo-exception.h>
#include <bonobo/bonobo-arg.h>
#include "evolution-mail-folder.h"
+#include "evolution-mail-store.h"
+#include "evolution-mail-messageiterator.h"
+#include "evolution-mail-session.h"
-#include <libedataserver/e-account.h>
-
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Mail_Folder_Factory:" BASE_VERSION
-#define MAIL_FOLDER_ID "OAFIID:GNOME_Evolution_Mail_Folder:" BASE_VERSION
+#include <camel/camel-store.h>
+#include <camel/camel-folder.h>
+#include "e-corba-utils.h"
#define PARENT_TYPE bonobo_object_get_type ()
@@ -44,7 +46,9 @@ static BonoboObjectClass *parent_class = NULL;
#define _PRIVATE(o) (g_type_instance_get_private ((GTypeInstance *)o, evolution_mail_folder_get_type()))
struct _EvolutionMailFolderPrivate {
- int dummy;
+ CamelFolder *folder;
+
+ guint32 folder_changed;
};
/* GObject methods */
@@ -52,6 +56,14 @@ struct _EvolutionMailFolderPrivate {
static void
impl_dispose (GObject *object)
{
+ struct _EvolutionMailFolderPrivate *p = _PRIVATE(object);
+
+ if (p->folder) {
+ camel_object_remove_event(p->folder, p->folder_changed);
+ camel_object_unref(p->folder);
+ p->folder = NULL;
+ }
+
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
@@ -112,6 +124,78 @@ impl_getProperties(PortableServer_Servant _servant,
return ok;
}
+static GNOME_Evolution_Mail_MessageIterator
+impl_getMessages(PortableServer_Servant _servant, const CORBA_char * pattern, CORBA_Environment * ev)
+{
+ EvolutionMailFolder *emf = (EvolutionMailFolder *)bonobo_object_from_servant(_servant);
+ struct _CamelFolder *folder;
+ EvolutionMailMessageIterator *emi;
+ GNOME_Evolution_Mail_MessageIterator iter;
+
+ folder = evolution_mail_folder_get_folder(emf);
+ if (folder == NULL) {
+ GNOME_Evolution_Mail_FAILED *x;
+
+ x = GNOME_Evolution_Mail_FAILED__alloc();
+ x->why = CORBA_string_dup("Unable to open folder");
+ CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_FAILED, x);
+
+ return CORBA_OBJECT_NIL;
+ }
+
+ emi = evolution_mail_messageiterator_new(folder, pattern);
+ camel_object_unref(folder);
+
+ /* NB: How do we destroy the object once we're done? */
+
+ iter = bonobo_object_corba_objref((BonoboObject *)emi);
+
+ return iter;
+}
+
+static void
+impl_changeMessages(PortableServer_Servant _servant, const GNOME_Evolution_Mail_MessageInfoSets *infos, CORBA_Environment * ev)
+{
+ EvolutionMailFolder *emf = (EvolutionMailFolder *)bonobo_object_from_servant(_servant);
+ struct _CamelFolder *folder;
+ int i, j;
+
+ folder = evolution_mail_folder_get_folder(emf);
+ if (folder == NULL) {
+ GNOME_Evolution_Mail_FAILED *x;
+
+ x = GNOME_Evolution_Mail_FAILED__alloc();
+ x->why = CORBA_string_dup("Unable to open folder");
+ CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_FAILED, x);
+ return;
+ }
+
+ camel_folder_freeze(folder);
+ for (i=0;i<infos->_length;i++) {
+ CamelMessageInfo *mi;
+ GNOME_Evolution_Mail_MessageInfoSet *mis = &infos->_buffer[i];
+
+ mi = camel_folder_get_message_info(folder, mis->uid);
+ if (mi == NULL)
+ continue;
+
+ if (mis->flagMask)
+ camel_message_info_set_flags(mi, mis->flagMask, mis->flagSet);
+
+ for (j=0;j<mis->userFlagSet._length;j++)
+ camel_message_info_set_user_flag(mi, mis->userFlagSet._buffer[j], TRUE);
+ for (j=0;j<mis->userFlagUnset._length;j++)
+ camel_message_info_set_user_flag(mi, mis->userFlagUnset._buffer[j], FALSE);
+ for (j=0;j<mis->userTags._length;j++)
+ camel_message_info_set_user_tag(mi, mis->userTags._buffer[j].name, mis->userTags._buffer[j].value[0]?mis->userTags._buffer[j].value:NULL);
+
+ camel_message_info_free(mi);
+ }
+ camel_folder_thaw(folder);
+
+ camel_object_unref(folder);
+}
+
/* Initialization */
static void
@@ -123,6 +207,8 @@ evolution_mail_folder_class_init (EvolutionMailFolderClass *klass)
parent_class = g_type_class_peek_parent (klass);
epv->getProperties = impl_getProperties;
+ epv->getMessages = impl_getMessages;
+ epv->changeMessages = impl_changeMessages;
object_class->dispose = impl_dispose;
object_class->finalize = impl_finalize;
@@ -138,12 +224,109 @@ evolution_mail_folder_init(EvolutionMailFolder *component, EvolutionMailFolderCl
BONOBO_TYPE_FUNC_FULL (EvolutionMailFolder, GNOME_Evolution_Mail_Folder, PARENT_TYPE, evolution_mail_folder)
EvolutionMailFolder *
-evolution_mail_folder_new(const char *name, const char *full_name)
+evolution_mail_folder_new(EvolutionMailStore *ems, const char *name, const char *full_name)
{
EvolutionMailFolder *emf = g_object_new (EVOLUTION_MAIL_TYPE_FOLDER, NULL);
emf->name = g_strdup(name);
emf->full_name = g_strdup(full_name);
+ emf->store = ems;
+
return emf;
}
+
+static void
+emf_set_change(GNOME_Evolution_Mail_FolderChange *change, GNOME_Evolution_Mail_ChangeType how, CamelFolder *folder, GPtrArray *uids)
+{
+ int total = 0, i;
+
+ change->type = how;
+ change->messages._maximum = uids->len;
+ change->messages._buffer = GNOME_Evolution_Mail_MessageInfos_allocbuf(uids->len);
+
+ for (i=0;i<uids->len;i++) {
+ CamelMessageInfo *info = camel_folder_get_message_info(folder, uids->pdata[i]);
+
+ if (info) {
+ e_mail_messageinfo_set_message(&change->messages._buffer[total], info);
+ camel_message_info_free(info);
+ total++;
+ } else {
+ printf("couldn't get info for changed uid '%s'?\n", (char *)uids->pdata[i]);
+ }
+ }
+
+ change->messages._length = total;
+}
+
+static void
+emf_folder_changed(CamelObject *o, void *d, void *data)
+{
+ EvolutionMailFolder *emf = data;
+ CamelFolder *folder = (CamelFolder *)o;
+ CamelFolderChangeInfo *ci = d;
+ int count = 0;
+ GNOME_Evolution_Mail_FolderChanges *changes;
+ CORBA_long flags;
+
+ flags = evolution_mail_session_listening(emf->store->session);
+
+ if ((flags & (GNOME_Evolution_Mail_Session_FOLDER_ADDED|GNOME_Evolution_Mail_Session_FOLDER_CHANGED|GNOME_Evolution_Mail_Session_FOLDER_REMOVED)) == 0)
+ return;
+
+ changes = GNOME_Evolution_Mail_FolderChanges__alloc();
+ changes->_maximum = 3;
+ changes->_buffer = GNOME_Evolution_Mail_FolderChanges_allocbuf(3);
+ CORBA_sequence_set_release(changes, TRUE);
+
+ /* could be a race if a new listener is added */
+ if (ci->uid_added->len && (flags & GNOME_Evolution_Mail_Session_FOLDER_ADDED)) {
+ emf_set_change(&changes->_buffer[count], GNOME_Evolution_Mail_ADDED, folder, ci->uid_added);
+ count++;
+ }
+ if (ci->uid_removed->len && (flags & GNOME_Evolution_Mail_Session_FOLDER_REMOVED)) {
+ emf_set_change(&changes->_buffer[count], GNOME_Evolution_Mail_REMOVED, folder, ci->uid_removed);
+ count++;
+ }
+ if (ci->uid_changed->len && (flags & GNOME_Evolution_Mail_Session_FOLDER_CHANGED)) {
+ emf_set_change(&changes->_buffer[count], GNOME_Evolution_Mail_CHANGED, folder, ci->uid_changed);
+ count++;
+ }
+
+ changes->_length = count;
+
+ evolution_mail_session_folder_changed(emf->store->session,
+ bonobo_object_corba_objref((BonoboObject *)emf->store),
+ bonobo_object_corba_objref((BonoboObject *)emf),
+ changes);
+
+ CORBA_free(changes);
+}
+
+struct _CamelFolder *evolution_mail_folder_get_folder(EvolutionMailFolder *emf)
+{
+ struct _EvolutionMailFolderPrivate *p = _PRIVATE(emf);
+ CamelStore *store;
+ CamelException ex;
+
+ if (p->folder == NULL) {
+ store = evolution_mail_store_get_store(emf->store);
+ if (store == NULL)
+ return NULL;
+
+ camel_exception_init(&ex);
+ p->folder = camel_store_get_folder(store, emf->full_name, 0, &ex);
+ if (p->folder) {
+ p->folder_changed = camel_object_hook_event(p->folder, "folder_changed", emf_folder_changed, emf);
+ } else {
+ camel_exception_clear(&ex);
+ }
+ camel_object_unref(store);
+ }
+
+ if (p->folder)
+ camel_object_ref(p->folder);
+
+ return p->folder;
+}
diff --git a/plugins/mail-remote/evolution-mail-folder.h b/plugins/mail-remote/evolution-mail-folder.h
index 40f6139d79..398d3f2d42 100644
--- a/plugins/mail-remote/evolution-mail-folder.h
+++ b/plugins/mail-remote/evolution-mail-folder.h
@@ -31,7 +31,7 @@
#define EVOLUTION_MAIL_IS_FOLDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_MAIL_TYPE_FOLDER))
#define EVOLUTION_MAIL_IS_FOLDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_MAIL_TYPE_FOLDER))
-struct _EAccount;
+struct _EvolutionMailStore;
typedef struct _EvolutionMailFolder EvolutionMailFolder;
typedef struct _EvolutionMailFolderClass EvolutionMailFolderClass;
@@ -39,6 +39,8 @@ typedef struct _EvolutionMailFolderClass EvolutionMailFolderClass;
struct _EvolutionMailFolder {
BonoboObject parent;
+ struct _EvolutionMailStore *store;
+
char *full_name;
char *name;
};
@@ -51,6 +53,8 @@ struct _EvolutionMailFolderClass {
GType evolution_mail_folder_get_type(void);
-EvolutionMailFolder *evolution_mail_folder_new(const char *name, const char *full_name);
+EvolutionMailFolder *evolution_mail_folder_new(struct _EvolutionMailStore *ems, const char *name, const char *full_name);
+
+struct _CamelFolder *evolution_mail_folder_get_folder(EvolutionMailFolder *emf);
#endif /* _EVOLUTION_MAIL_FOLDER_H_ */
diff --git a/plugins/mail-remote/evolution-mail-listener.c b/plugins/mail-remote/evolution-mail-listener.c
index 26dac759ee..842edf4f4f 100644
--- a/plugins/mail-remote/evolution-mail-listener.c
+++ b/plugins/mail-remote/evolution-mail-listener.c
@@ -31,10 +31,10 @@
#include <bonobo/bonobo-exception.h>
#include "evolution-mail-listener.h"
-#include <libedataserver/e-account-list.h>
-
#include "evolution-mail-store.h"
+#include "evolution-mail-marshal.h"
+
#define PARENT_TYPE bonobo_object_get_type ()
static BonoboObjectClass *parent_class = NULL;
@@ -45,6 +45,15 @@ struct _EvolutionMailListenerPrivate {
int dummy;
};
+enum {
+ EML_SESSION_CHANGED,
+ EML_STORE_CHANGED,
+ EML_FOLDER_CHANGED,
+ EML_LAST_SIGNAL
+};
+
+static guint eml_signals[EML_LAST_SIGNAL];
+
/* GObject methods */
static void
@@ -60,39 +69,46 @@ impl_dispose (GObject *object)
static void
impl_finalize (GObject *object)
{
+ printf("EvolutionMailListener finalised!\n");
+
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
/* Evolution.Mail.Listener */
-
-static void
-impl_sessionChanged(PortableServer_Servant _servant,
- const GNOME_Evolution_Mail_Session session,
- const GNOME_Evolution_Mail_SessionChange *change, CORBA_Environment * ev)
+static const char *change_type_name(int type)
{
- EvolutionMailListener *ems = (EvolutionMailListener *)bonobo_object_from_servant(_servant);
- const char *what;
- int i;
-
- printf("session changed!\n");
- ems = ems;
-
- switch (change->type) {
+ switch (type) {
case GNOME_Evolution_Mail_ADDED:
- what = "added";
+ return "added";
break;
case GNOME_Evolution_Mail_CHANGED:
- what = "changed";
+ return "changed";
break;
case GNOME_Evolution_Mail_REMOVED:
- what = "removed";
+ return "removed";
break;
+ default:
+ return "";
}
+}
- printf("%d %s\n", change->stores._length, what);
- for (i=0;i<change->stores._length;i++) {
- printf("Store '%s' '%s'\n", change->stores._buffer[i].name, change->stores._buffer[i].uid);
+static void
+impl_sessionChanged(PortableServer_Servant _servant,
+ const GNOME_Evolution_Mail_Session session,
+ const GNOME_Evolution_Mail_SessionChanges *changes, CORBA_Environment * ev)
+{
+ EvolutionMailListener *eml = (EvolutionMailListener *)bonobo_object_from_servant(_servant);
+ int i, j;
+
+ printf("session changed!\n");
+ for (i=0;i<changes->_length;i++) {
+ printf(" %d %s", changes->_buffer[i].stores._length, change_type_name(changes->_buffer[i].type));
+ for (j=0;j<changes->_buffer[i].stores._length;j++) {
+ printf(" %s %s\n", changes->_buffer[i].stores._buffer[j].uid, changes->_buffer[i].stores._buffer[j].name);
+ }
}
+
+ g_signal_emit(eml, eml_signals[EML_SESSION_CHANGED], 0, session, changes);
}
static void
@@ -102,10 +118,18 @@ impl_storeChanged(PortableServer_Servant _servant,
const GNOME_Evolution_Mail_StoreChanges * changes,
CORBA_Environment * ev)
{
- EvolutionMailListener *ems = (EvolutionMailListener *)bonobo_object_from_servant(_servant);
+ EvolutionMailListener *eml = (EvolutionMailListener *)bonobo_object_from_servant(_servant);
+ int i, j;
printf("store changed!\n");
- ems = ems;
+ for (i=0;i<changes->_length;i++) {
+ printf(" %d %s", changes->_buffer[i].folders._length, change_type_name(changes->_buffer[i].type));
+ for (j=0;j<changes->_buffer[i].folders._length;j++) {
+ printf(" %s %s\n", changes->_buffer[i].folders._buffer[j].full_name, changes->_buffer[i].folders._buffer[j].name);
+ }
+ }
+
+ g_signal_emit(eml, eml_signals[EML_STORE_CHANGED], 0, session, store, changes);
}
static void
@@ -115,10 +139,18 @@ impl_folderChanged(PortableServer_Servant _servant,
const GNOME_Evolution_Mail_Folder folder,
const GNOME_Evolution_Mail_FolderChanges *changes, CORBA_Environment * ev)
{
- EvolutionMailListener *ems = (EvolutionMailListener *)bonobo_object_from_servant(_servant);
+ EvolutionMailListener *eml = (EvolutionMailListener *)bonobo_object_from_servant(_servant);
+ int i, j;
printf("folder changed!\n");
- ems = ems;
+ for (i=0;i<changes->_length;i++) {
+ printf(" %d %s", changes->_buffer[i].messages._length, change_type_name(changes->_buffer[i].type));
+ for (j=0;j<changes->_buffer[i].messages._length;j++) {
+ printf(" %s %s\n", changes->_buffer[i].messages._buffer[j].uid, changes->_buffer[i].messages._buffer[j].subject);
+ }
+ }
+
+ g_signal_emit(eml, eml_signals[EML_STORE_CHANGED], 0, session, store, folder, changes);
}
/* Initialization */
@@ -139,6 +171,36 @@ evolution_mail_listener_class_init (EvolutionMailListenerClass *klass)
object_class->finalize = impl_finalize;
g_type_class_add_private(klass, sizeof(struct _EvolutionMailListenerPrivate));
+
+ eml_signals[EML_SESSION_CHANGED] =
+ g_signal_new("session-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EvolutionMailListenerClass, session_changed),
+ NULL, NULL,
+ evolution_mail_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER, G_TYPE_POINTER);
+
+ eml_signals[EML_STORE_CHANGED] =
+ g_signal_new("store-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EvolutionMailListenerClass, store_changed),
+ NULL, NULL,
+ evolution_mail_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3,
+ G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
+
+ eml_signals[EML_FOLDER_CHANGED] =
+ g_signal_new("folder-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EvolutionMailListenerClass, folder_changed),
+ NULL, NULL,
+ evolution_mail_marshal_VOID__POINTER_POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 4,
+ G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
}
static void
diff --git a/plugins/mail-remote/evolution-mail-listener.h b/plugins/mail-remote/evolution-mail-listener.h
index c33d605c61..5dbf4aaf3a 100644
--- a/plugins/mail-remote/evolution-mail-listener.h
+++ b/plugins/mail-remote/evolution-mail-listener.h
@@ -43,6 +43,10 @@ struct _EvolutionMailListenerClass {
BonoboObjectClass parent_class;
POA_GNOME_Evolution_Mail_Listener__epv epv;
+
+ void (*session_changed)(const GNOME_Evolution_Mail_Session session, const GNOME_Evolution_Mail_SessionChange *change);
+ void (*store_changed)(const GNOME_Evolution_Mail_Session session, const GNOME_Evolution_Mail_Store store, const GNOME_Evolution_Mail_StoreChanges *);
+ void (*folder_changed)(const GNOME_Evolution_Mail_Session session, const GNOME_Evolution_Mail_Store store, const GNOME_Evolution_Mail_Folder folder, const GNOME_Evolution_Mail_FolderChanges *);
};
GType evolution_mail_listener_get_type(void);
diff --git a/plugins/mail-remote/evolution-mail-marshal.list b/plugins/mail-remote/evolution-mail-marshal.list
new file mode 100644
index 0000000000..14a6fbd358
--- /dev/null
+++ b/plugins/mail-remote/evolution-mail-marshal.list
@@ -0,0 +1,3 @@
+VOID:POINTER,POINTER
+VOID:POINTER,POINTER,POINTER
+VOID:POINTER,POINTER,POINTER,POINTER
diff --git a/plugins/mail-remote/evolution-mail-messageiterator.c b/plugins/mail-remote/evolution-mail-messageiterator.c
index d31c958217..8cf123640d 100644
--- a/plugins/mail-remote/evolution-mail-messageiterator.c
+++ b/plugins/mail-remote/evolution-mail-messageiterator.c
@@ -32,10 +32,7 @@
#include <camel/camel-folder.h>
-#include <libedataserver/e-account.h>
-
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Mail_MessageIterator_Factory:" BASE_VERSION
-#define MAIL_MESSAGEITERATOR_ID "OAFIID:GNOME_Evolution_Mail_MessageIterator:" BASE_VERSION
+#include "e-corba-utils.h"
#define PARENT_TYPE bonobo_object_get_type ()
@@ -63,6 +60,8 @@ impl_finalize (GObject *object)
{
struct _EvolutionMailMessageIteratorPrivate *p = _PRIVATE(object);
+ printf("EvolutionMailMessageIterator: finalise\n");
+
if (*p->expr)
camel_folder_search_free(p->folder, p->search);
else
@@ -75,12 +74,12 @@ impl_finalize (GObject *object)
}
/* Evolution.Mail.MessageIterator */
-static GNOME_Evolution_Mail_Messages *
+static GNOME_Evolution_Mail_MessageInfos *
impl_next(PortableServer_Servant _servant, const CORBA_long limit, CORBA_Environment * ev)
{
EvolutionMailMessageIterator *emf = (EvolutionMailMessageIterator *)bonobo_object_from_servant(_servant);
int i, j;
- GNOME_Evolution_Mail_Messages *msgs;
+ GNOME_Evolution_Mail_MessageInfos *msgs;
struct _EvolutionMailMessageIteratorPrivate *p = _PRIVATE(emf);
CamelException ex = { 0 };
@@ -98,9 +97,9 @@ impl_next(PortableServer_Servant _servant, const CORBA_long limit, CORBA_Environ
p->index = 0;
}
- msgs = GNOME_Evolution_Mail_Messages__alloc();
+ msgs = GNOME_Evolution_Mail_MessageInfos__alloc();
msgs->_maximum = MIN(limit, p->search->len - p->index);
- msgs->_buffer = GNOME_Evolution_Mail_Messages_allocbuf(msgs->_maximum);
+ msgs->_buffer = GNOME_Evolution_Mail_MessageInfos_allocbuf(msgs->_maximum);
CORBA_sequence_set_release(msgs, CORBA_TRUE);
j=0;
@@ -108,15 +107,13 @@ impl_next(PortableServer_Servant _servant, const CORBA_long limit, CORBA_Environ
CamelMessageInfo *info = camel_folder_get_message_info(p->folder, p->search->pdata[i]);
if (info) {
- msgs->_buffer[j].uid = CORBA_string_dup(camel_message_info_uid(info));
- msgs->_buffer[j].subject = CORBA_string_dup(camel_message_info_subject(info));
- msgs->_buffer[j].to = CORBA_string_dup(camel_message_info_to(info));
- msgs->_buffer[j].from = CORBA_string_dup(camel_message_info_from(info));
+ e_mail_messageinfo_set_message(&msgs->_buffer[j], info);
j++;
camel_message_info_free(info);
}
}
+ p->index = i;
msgs->_length = j;
return msgs;
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)
diff --git a/plugins/mail-remote/evolution-mail-session.h b/plugins/mail-remote/evolution-mail-session.h
index 0681f975ca..6b9ff61abc 100644
--- a/plugins/mail-remote/evolution-mail-session.h
+++ b/plugins/mail-remote/evolution-mail-session.h
@@ -49,4 +49,10 @@ struct _EvolutionMailSessionClass {
GType evolution_mail_session_get_type(void);
+CORBA_long evolution_mail_session_listening(EvolutionMailSession *ems);
+
+void evolution_mail_session_session_changed(EvolutionMailSession *ems, GNOME_Evolution_Mail_SessionChanges *changes);
+void evolution_mail_session_store_changed(EvolutionMailSession *ems, GNOME_Evolution_Mail_Store store, GNOME_Evolution_Mail_StoreChanges *changes);
+void evolution_mail_session_folder_changed(EvolutionMailSession *ems, GNOME_Evolution_Mail_Store store, GNOME_Evolution_Mail_Folder folder, GNOME_Evolution_Mail_FolderChanges *changes);
+
#endif /* _EVOLUTION_MAIL_SESSION_H_ */
diff --git a/plugins/mail-remote/evolution-mail-store.c b/plugins/mail-remote/evolution-mail-store.c
index 30d7b75cff..b5cfd3840d 100644
--- a/plugins/mail-remote/evolution-mail-store.c
+++ b/plugins/mail-remote/evolution-mail-store.c
@@ -40,14 +40,14 @@
#include <camel/camel-store.h>
#include <camel/camel-session.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-mime-message.h>
+#include <camel/camel-folder.h>
#include <e-util/e-account.h>
#include "mail/mail-component.h"
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Mail_Store_Factory:" BASE_VERSION
-#define MAIL_STORE_ID "OAFIID:GNOME_Evolution_Mail_Store:" BASE_VERSION
-
#define PARENT_TYPE bonobo_object_get_type ()
static BonoboObjectClass *parent_class = NULL;
@@ -56,7 +56,6 @@ static BonoboObjectClass *parent_class = NULL;
struct _EvolutionMailStorePrivate {
CamelStore *store;
- EvolutionMailSession *session;
GHashTable *folders;
/* sorted array of folders by full_name */
@@ -148,28 +147,33 @@ impl_getProperties(PortableServer_Servant _servant,
}
static void
-ems_add_folders(struct _EvolutionMailStorePrivate *p, CamelFolderInfo *fi)
+ems_add_folders(EvolutionMailStore *ems, CamelFolderInfo *fi, GPtrArray *added)
{
+ struct _EvolutionMailStorePrivate *p = _PRIVATE(ems);
+
while (fi) {
if (g_hash_table_lookup(p->folders, fi->full_name) == NULL) {
-
- /* FIXME: store of folder??? */
- EvolutionMailFolder *emf = evolution_mail_folder_new(fi->name, fi->full_name);
+ EvolutionMailFolder *emf = evolution_mail_folder_new(ems, fi->name, fi->full_name);
g_hash_table_insert(p->folders, emf->full_name, emf);
g_ptr_array_add(p->folders_array, emf);
+ if (added) {
+ g_object_ref(emf);
+ g_ptr_array_add(added, emf);
+ }
}
if (fi->child)
- ems_add_folders(p, fi->child);
+ ems_add_folders(ems, fi->child, added);
fi = fi->next;
}
}
static void
-ems_remove_folders(struct _EvolutionMailStorePrivate *p, CamelFolderInfo *fi)
+ems_remove_folders(EvolutionMailStore *ems, CamelFolderInfo *fi, GPtrArray *removed)
{
+ struct _EvolutionMailStorePrivate *p = _PRIVATE(ems);
EvolutionMailFolder *emf;
while (fi) {
@@ -177,13 +181,16 @@ ems_remove_folders(struct _EvolutionMailStorePrivate *p, CamelFolderInfo *fi)
if (emf) {
g_hash_table_remove(p->folders, fi->full_name);
g_ptr_array_remove(p->folders_array, emf);
- /* FIXME: pass emf to the store changed folder removed code */
+ if (removed)
+ g_ptr_array_add(removed, emf);
+ else
+ g_object_unref(emf);
} else {
g_warning("Folder removed I didn't know existed '%s'\n", fi->full_name);
}
if (fi->child)
- ems_remove_folders(p, fi->child);
+ ems_remove_folders(ems, fi->child, removed);
fi = fi->next;
}
@@ -205,6 +212,39 @@ ems_sort_folders(struct _EvolutionMailStorePrivate *p)
}
static void
+ems_set_changes(GNOME_Evolution_Mail_StoreChange *change, GNOME_Evolution_Mail_ChangeType how, GPtrArray *changed)
+{
+ int i;
+
+ change->type = how;
+ change->folders._maximum = changed->len;
+ change->folders._length = changed->len;
+ change->folders._buffer = GNOME_Evolution_Mail_FolderInfos_allocbuf(change->folders._maximum);
+ CORBA_sequence_set_release(&change->folders, TRUE);
+
+ for (i=0;i<changed->len;i++)
+ e_mail_folderinfo_set_folder(&change->folders._buffer[i], changed->pdata[i]);
+}
+
+static GNOME_Evolution_Mail_StoreChanges *
+ems_create_changes(EvolutionMailStore *ems, GNOME_Evolution_Mail_ChangeType how, GPtrArray *changed)
+{
+ GNOME_Evolution_Mail_StoreChanges *changes;
+
+ /* NB: we only ever create 1 changetype at the moment */
+
+ changes = GNOME_Evolution_Mail_StoreChanges__alloc();
+ changes->_maximum = 1;
+ changes->_length = 1;
+ changes->_buffer = GNOME_Evolution_Mail_StoreChanges_allocbuf(1);
+ CORBA_sequence_set_release(changes, TRUE);
+
+ ems_set_changes(&changes->_buffer[0], how, changed);
+
+ return changes;
+}
+
+static void
ems_folder_opened(CamelObject *o, void *d, void *data)
{
EvolutionMailStore *ems = data;
@@ -219,24 +259,54 @@ static void
ems_folder_subscribed(CamelObject *o, void *d, void *data)
{
EvolutionMailStore *ems = data;
- struct _EvolutionMailStorePrivate *p = _PRIVATE(ems);
CamelFolderInfo *fi = d;
+ GPtrArray *added = NULL;
+ int i;
+
+ if (evolution_mail_session_listening(ems->session) & GNOME_Evolution_Mail_Session_STORE_ADDED)
+ added = g_ptr_array_new();
+
+ ems_add_folders(ems, fi, added);
+
+ if (added) {
+ if (added->len) {
+ GNOME_Evolution_Mail_StoreChanges *changes = ems_create_changes(ems, GNOME_Evolution_Mail_ADDED, added);
- ems_add_folders(p, fi);
+ evolution_mail_session_store_changed(ems->session, bonobo_object_corba_objref((BonoboObject *)ems), changes);
+ CORBA_free(changes);
- /* FIXME: store folder added event */
+ for (i=0;i<added->len;i++)
+ g_object_unref(added->pdata[i]);
+ }
+ g_ptr_array_free(added, TRUE);
+ }
}
static void
ems_folder_unsubscribed(CamelObject *o, void *d, void *data)
{
EvolutionMailStore *ems = data;
- struct _EvolutionMailStorePrivate *p = _PRIVATE(ems);
CamelFolderInfo *fi = d;
+ GPtrArray *removed = NULL;
+ int i;
- ems_remove_folders(p, fi);
+ if (evolution_mail_session_listening(ems->session) & GNOME_Evolution_Mail_Session_STORE_REMOVED)
+ removed = g_ptr_array_new();
- /* FIXME: store folder deleted event */
+ ems_remove_folders(ems, fi, removed);
+
+ if (removed) {
+ if (removed->len) {
+ GNOME_Evolution_Mail_StoreChanges *changes = ems_create_changes(ems, GNOME_Evolution_Mail_REMOVED, removed);
+
+ evolution_mail_session_store_changed(ems->session, bonobo_object_corba_objref((BonoboObject *)ems), changes);
+ CORBA_free(changes);
+
+ for (i=0;i<removed->len;i++)
+ g_object_unref(removed->pdata[i]);
+ }
+ g_ptr_array_free(removed, TRUE);
+ }
}
static void
@@ -254,7 +324,29 @@ ems_folder_deleted(CamelObject *o, void *d, void *data)
CamelStore *store = (CamelStore *)o;
if (!camel_store_supports_subscriptions(store))
- ems_folder_subscribed(o, d, data);
+ ems_folder_unsubscribed(o, d, data);
+}
+
+static void
+get_folders(CamelFolderInfo *fi, GPtrArray *folders)
+{
+ while (fi) {
+ g_ptr_array_add(folders, fi);
+
+ if (fi->child)
+ get_folders(fi->child, folders);
+
+ fi = fi->next;
+ }
+}
+
+static int
+folder_cmp(const void *ap, const void *bp)
+{
+ const CamelFolderInfo *a = ((CamelFolderInfo **)ap)[0];
+ const CamelFolderInfo *b = ((CamelFolderInfo **)bp)[0];
+
+ return strcmp(a->full_name, b->full_name);
}
static void
@@ -263,22 +355,58 @@ ems_folder_renamed(CamelObject *o, void *d, void *data)
EvolutionMailStore *ems = data;
struct _EvolutionMailStorePrivate *p = _PRIVATE(ems);
CamelRenameInfo *reninfo = d;
- int i, oldlen;
+ int i, oldlen, newlen;
+ GPtrArray *renamed = NULL, *folders = g_ptr_array_new();
+ CamelFolderInfo *top;
+ GString *name = g_string_new("");
- oldlen = strlen(reninfo->old_base);
+ if (evolution_mail_session_listening(ems->session) & GNOME_Evolution_Mail_Session_STORE_CHANGED)
+ renamed = g_ptr_array_new();
- for (i=0;i<p->folders_array->len;i++) {
- EvolutionMailFolder *folder = p->folders_array->pdata[i];
+ /* flatten/sort folders to make sure they're in the right order */
+ get_folders(reninfo->new, folders);
+ qsort(folders->pdata, folders->len, sizeof(folders->pdata[0]), folder_cmp);
+ top = folders->pdata[0];
- if (!strcmp(folder->full_name, reninfo->old_base)
- || (strlen(folder->full_name) > oldlen
- && folder->full_name[oldlen] == '/'
- && strncmp(folder->full_name, reninfo->old_base, oldlen))) {
- /* renamed folder */
+ oldlen = strlen(reninfo->old_base);
+ newlen = strlen(top->full_name);
+
+ for (i=0;i<folders->len;i++) {
+ CamelFolderInfo *fi = folders->pdata[i];
+ EvolutionMailFolder *emf;
+
+ if (strlen(fi->full_name) >= newlen) {
+ g_string_printf(name, "%s%s", reninfo->old_base, fi->full_name + newlen);
+ if ((emf = g_hash_table_lookup(p->folders, name->str))) {
+ /* FIXME: locking / or api to rename */
+ g_hash_table_remove(p->folders, emf->full_name);
+ g_free(emf->full_name);
+ g_free(emf->name);
+ emf->full_name = g_strdup(fi->full_name);
+ emf->name = g_strdup(fi->name);
+ g_hash_table_insert(p->folders, emf->full_name, emf);
+
+ g_object_ref(emf);
+ g_ptr_array_add(renamed, emf);
+ }
}
}
- /* FIXME: store folder changed event? */
+ g_string_free(name, TRUE);
+ g_ptr_array_free(folders, TRUE);
+
+ if (renamed) {
+ if (renamed->len) {
+ GNOME_Evolution_Mail_StoreChanges *changes = ems_create_changes(ems, GNOME_Evolution_Mail_CHANGED, renamed);
+
+ evolution_mail_session_store_changed(ems->session, bonobo_object_corba_objref((BonoboObject *)ems), changes);
+ CORBA_free(changes);
+
+ for (i=0;i<renamed->len;i++)
+ g_object_unref(renamed->pdata[i]);
+ }
+ g_ptr_array_free(renamed, TRUE);
+ }
}
static GNOME_Evolution_Mail_FolderInfos *
@@ -292,48 +420,27 @@ impl_getFolders(PortableServer_Servant _servant,
CamelException ex = { 0 };
GNOME_Evolution_Mail_FolderInfos *folders = NULL;
int i;
+ CamelStore *store;
- if (p->store == NULL) {
- if (ems->account == NULL) {
- p->store = mail_component_peek_local_store(NULL);
- camel_object_ref(p->store);
- } else {
- const char *uri;
-
- uri = e_account_get_string(ems->account, E_ACCOUNT_SOURCE_URL);
- if (uri && *uri) {
- p->store = camel_session_get_store(p->session->session, uri, &ex);
- if (camel_exception_is_set(&ex)) {
- GNOME_Evolution_Mail_FAILED *x;
+ store = evolution_mail_store_get_store(ems);
+ if (store == NULL) {
+ GNOME_Evolution_Mail_FAILED *x;
- camel_exception_clear(&ex);
- x = GNOME_Evolution_Mail_FAILED__alloc();
- x->why = CORBA_string_dup("Unable to get store");
- CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_FAILED, x);
- return CORBA_OBJECT_NIL;
- }
- } else {
- CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_FAILED, NULL);
- return CORBA_OBJECT_NIL;
- }
- }
+ x = GNOME_Evolution_Mail_FAILED__alloc();
+ x->why = CORBA_string_dup("Unable to open store");
+ CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_FAILED, x);
- p->folder_opened = camel_object_hook_event(p->store, "folder_opened", ems_folder_opened, ems);
- p->folder_created = camel_object_hook_event(p->store, "folder_created", ems_folder_created, ems);
- p->folder_deleted = camel_object_hook_event(p->store, "folder_deleted", ems_folder_deleted, ems);
- p->folder_renamed = camel_object_hook_event(p->store, "folder_renamed", ems_folder_renamed, ems);
- p->folder_subscribed = camel_object_hook_event(p->store, "folder_subscribed", ems_folder_subscribed, ems);
- p->folder_unsubscribed = camel_object_hook_event(p->store, "folder_unsubscribed", ems_folder_unsubscribed, ems);
+ return CORBA_OBJECT_NIL;
}
if (p->folders == NULL) {
- fi = camel_store_get_folder_info(p->store, "", CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST, &ex);
+ fi = camel_store_get_folder_info(store, "", CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST, &ex);
if (fi) {
p->folders = g_hash_table_new(g_str_hash, g_str_equal);
p->folders_array = g_ptr_array_new();
- ems_add_folders(p, fi);
- camel_store_free_folder_info(p->store, fi);
+ ems_add_folders(ems, fi, NULL);
+ camel_store_free_folder_info(store, fi);
ems_sort_folders(p);
} else {
GNOME_Evolution_Mail_FAILED *x;
@@ -342,6 +449,7 @@ impl_getFolders(PortableServer_Servant _servant,
x->why = CORBA_string_dup("Unable to list folders");
CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_FAILED, x);
+ camel_object_unref(store);
return CORBA_OBJECT_NIL;
}
}
@@ -354,35 +462,81 @@ impl_getFolders(PortableServer_Servant _servant,
for (i=0;i<p->folders_array->len;i++) {
EvolutionMailFolder *emf = p->folders_array->pdata[i];
-
- folders->_buffer[i].name = CORBA_string_dup(emf->name);
- folders->_buffer[i].full_name = CORBA_string_dup(emf->full_name);
- folders->_buffer[i].folder = CORBA_Object_duplicate(bonobo_object_corba_objref((BonoboObject *)emf), NULL);
- /* object ref?? */
+
+ e_mail_folderinfo_set_folder(&folders->_buffer[i], emf);
}
+ camel_object_unref(store);
+
return folders;
}
static void
impl_sendMessage(PortableServer_Servant _servant,
- const Bonobo_Stream msg, const CORBA_char * from,
- const CORBA_char * recipients,
+ const Bonobo_Stream message,
CORBA_Environment * ev)
{
EvolutionMailStore *ems = (EvolutionMailStore *)bonobo_object_from_servant(_servant);
- struct _EvolutionMailStorePrivate *p = _PRIVATE(ems);
+ CamelException ex = { 0 };
+ CamelMimeMessage *msg;
+ CamelInternetAddress *from;
+ CamelMessageInfo *info;
+ CamelStream *mem;
+
+ if (ems->account == NULL
+ || ems->account->transport == NULL
+ || ems->account->transport->url == NULL) {
+#if 0
+ GNOME_Evolution_Mail_NOT_SUPPORTED *x;
- p = p;
+ x = GNOME_Evolution_Mail_NOT_SUPPORTED__alloc();
+ x->why = CORBA_string_dup(ex.desc);
+#endif
+ CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_NOT_SUPPORTED, NULL);
+ return;
+ }
+
+ mem = camel_stream_mem_new();
+ if (e_stream_bonobo_to_camel(message, mem) == -1) {
+ CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_FAILED, NULL);
+ return;
+ }
+
+ printf("Sending message '%.*s'\n", ((CamelStreamMem *)mem)->buffer->len, ((CamelStreamMem *)mem)->buffer->data);
+
+ msg = camel_mime_message_new();
+ if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)msg, mem) == -1) {
+ camel_object_unref(mem);
+ camel_object_unref(msg);
+ CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_FAILED, NULL);
+ return;
+ }
+ camel_object_unref(mem);
+
+ from = camel_internet_address_new();
+ camel_internet_address_add(from, ems->account->id->name, ems->account->id->address);
+ camel_mime_message_set_from(msg, from);
+ camel_object_unref(from);
+
+ camel_medium_set_header((CamelMedium *)msg, "X-Evolution-Account", ems->account->uid);
- printf("Sending message from '%s' to '%s'\n", from, recipients);
- if (ems->account == NULL) {
- printf("Local mail can only store ...\n");
- } else if (ems->account->transport && ems->account->transport->url) {
- printf("via '%s'\n", ems->account->transport->url);
+ if (msg->date == 0)
+ camel_mime_message_set_date(msg, CAMEL_MESSAGE_DATE_CURRENT, 0);
+
+ info = camel_message_info_new(NULL);
+ camel_message_info_set_flags(info, CAMEL_MESSAGE_SEEN, ~0);
+
+ camel_folder_append_message(mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX), msg, info, NULL, &ex);
+ camel_message_info_free(info);
+
+ if (camel_exception_is_set(&ex)) {
+ CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Mail_FAILED, NULL);
+ camel_exception_clear(&ex);
} else {
- printf("Account not setup for sending '%s'\n", ems->account->name);
+ /*mail_send();*/
}
+
+ camel_object_unref(msg);
}
/* Initialization */
@@ -419,6 +573,8 @@ evolution_mail_store_new(struct _EvolutionMailSession *s, struct _EAccount *ea)
struct _EvolutionMailStorePrivate *p;
static PortableServer_POA poa = NULL;
+ printf("EvolutionMailStore.new(\"%s\")\n", ea?ea->name:"local");
+
if (poa == NULL)
poa = bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL);
@@ -430,7 +586,7 @@ evolution_mail_store_new(struct _EvolutionMailSession *s, struct _EAccount *ea)
g_object_ref(ea);
}
- p->session = s;
+ ems->session = s;
return ems;
}
@@ -451,22 +607,38 @@ const char *evolution_mail_store_get_uid(EvolutionMailStore *ems)
return "local@local";
}
-#if 0
-static BonoboObject *
-factory (BonoboGenericFactory *factory,
- const char *component_id,
- void *closure)
+CamelStore *evolution_mail_store_get_store(EvolutionMailStore *ems)
{
- if (strcmp (component_id, MAIL_STORE_ID) == 0) {
- BonoboObject *object = BONOBO_OBJECT (g_object_new (EVOLUTION_MAIL_TYPE_STORE, NULL));
- bonobo_object_ref (object);
- return object;
+ struct _EvolutionMailStorePrivate *p = _PRIVATE(ems);
+
+ if (p->store == NULL) {
+ if (ems->account == NULL) {
+ p->store = mail_component_peek_local_store(NULL);
+ camel_object_ref(p->store);
+ } else {
+ const char *uri;
+ CamelException ex = { 0 };
+
+ uri = e_account_get_string(ems->account, E_ACCOUNT_SOURCE_URL);
+ if (uri && *uri) {
+ p->store = camel_session_get_store(ems->session->session, uri, &ex);
+ if (camel_exception_is_set(&ex)) {
+ camel_exception_clear(&ex);
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+ }
+
+ p->folder_opened = camel_object_hook_event(p->store, "folder_opened", ems_folder_opened, ems);
+ p->folder_created = camel_object_hook_event(p->store, "folder_created", ems_folder_created, ems);
+ p->folder_deleted = camel_object_hook_event(p->store, "folder_deleted", ems_folder_deleted, ems);
+ p->folder_renamed = camel_object_hook_event(p->store, "folder_renamed", ems_folder_renamed, ems);
+ p->folder_subscribed = camel_object_hook_event(p->store, "folder_subscribed", ems_folder_subscribed, ems);
+ p->folder_unsubscribed = camel_object_hook_event(p->store, "folder_unsubscribed", ems_folder_unsubscribed, ems);
}
-
- g_warning (FACTORY_ID ": Don't know what to do with %s", component_id);
- return NULL;
+ camel_object_ref(p->store);
+ return p->store;
}
-
-BONOBO_ACTIVATION_SHLIB_FACTORY (FACTORY_ID, "Evolution Calendar component factory", factory, NULL)
-#endif
diff --git a/plugins/mail-remote/evolution-mail-store.h b/plugins/mail-remote/evolution-mail-store.h
index db42bf407f..b0e8be8e84 100644
--- a/plugins/mail-remote/evolution-mail-store.h
+++ b/plugins/mail-remote/evolution-mail-store.h
@@ -40,6 +40,8 @@ typedef struct _EvolutionMailStoreClass EvolutionMailStoreClass;
struct _EvolutionMailStore {
BonoboObject parent;
+ struct _EvolutionMailSession *session;
+
struct _EAccount *account;
};
@@ -56,4 +58,7 @@ EvolutionMailStore *evolution_mail_store_new(struct _EvolutionMailSession *s, st
const char *evolution_mail_store_get_name(EvolutionMailStore *);
const char *evolution_mail_store_get_uid(EvolutionMailStore *);
+/* unref when done */
+struct _CamelStore *evolution_mail_store_get_store(EvolutionMailStore *ems);
+
#endif /* _EVOLUTION_MAIL_STORE_H_ */