diff options
Diffstat (limited to 'plugins/mail-remote')
-rw-r--r-- | plugins/mail-remote/ChangeLog | 5 | ||||
-rw-r--r-- | plugins/mail-remote/Evolution-DataServer-Mail.idl | 66 | ||||
-rw-r--r-- | plugins/mail-remote/Makefile.am | 12 | ||||
-rw-r--r-- | plugins/mail-remote/client.c | 119 | ||||
-rw-r--r-- | plugins/mail-remote/e-corba-utils.c | 82 | ||||
-rw-r--r-- | plugins/mail-remote/e-corba-utils.h | 7 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-folder.c | 195 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-folder.h | 8 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-listener.c | 112 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-listener.h | 4 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-marshal.list | 3 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-messageiterator.c | 21 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-session.c | 237 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-session.h | 6 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-store.c | 356 | ||||
-rw-r--r-- | plugins/mail-remote/evolution-mail-store.h | 5 |
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_ */ |