From d0a6ed17b65560ed07ed005b38fab449dc507aef Mon Sep 17 00:00:00 2001 From: Not Zed Date: Mon, 3 Jun 2002 02:56:35 +0000 Subject: setup/free the mech string. 2002-06-02 Not Zed * camel-sasl.c (camel_sasl_new): (camel_sasl_finalize): setup/free the mech string. * camel-sasl.h: Added 'mech' mechanism string. 2002-06-01 Not Zed * providers/imap/camel-imap-folder.c (imap_getv): Implement. Only the object_description arg. (camel_imap_folder_get_type): Init parent_class holder. * providers/local/camel-local-folder.c (local_getv): Implement, object_description arg. * camel-folder.c (folder_getv): Implement, add a bunch of args you can get -> camel_folder_get_unread_count etc will be going RSN i hope. (camel_folder_finalize): Free cached description string. * camel-object.c (cobject_getv): Implement CAMEL_OBJECT_ARG_DESCRIPTION, just return the classname of the object. (camel_object_getv): (camel_object_get): (camel_object_setv): (camel_object_set): Take object = void *, to simplify usage. (camel_object_setv): Removed unecessary locals. (camel_object_getv): Same. (camel_object_free): New method, free an arg, upto implementations whether args are static/const or not. (cobject_free): Implement a dummy do nothing free. 2002-05-31 Not Zed * camel-vee-folder.c (camel_vee_folder_get_location): new function to get the real location (folder) (and uid) of a vfolder object. Using the folderinfo, since we already have it, maybe it should use the uid. svn path=/trunk/; revision=17073 --- camel/ChangeLog | 41 +++++++++ camel/camel-arg.c | 1 + camel/camel-folder.c | 128 +++++++++++++++++++++++++++-- camel/camel-folder.h | 27 ++++++ camel/camel-object.c | 64 +++++++++++++-- camel/camel-object.h | 22 ++++- camel/camel-private.h | 1 - camel/camel-sasl.c | 4 +- camel/camel-sasl.h | 1 + camel/camel-vee-folder.c | 32 ++++++++ camel/camel-vee-folder.h | 2 + camel/providers/imap/camel-imap-folder.c | 46 ++++++++++- camel/providers/local/camel-local-folder.c | 63 ++++++++++++++ 13 files changed, 408 insertions(+), 24 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index dd1f8cd40c..6961bdd7fe 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,44 @@ +2002-06-02 Not Zed + + * camel-sasl.c (camel_sasl_new): + (camel_sasl_finalize): setup/free the mech string. + + * camel-sasl.h: Added 'mech' mechanism string. + +2002-06-01 Not Zed + + * providers/imap/camel-imap-folder.c (imap_getv): Implement. Only + the object_description arg. + (camel_imap_folder_get_type): Init parent_class holder. + + * providers/local/camel-local-folder.c (local_getv): Implement, + object_description arg. + + * camel-folder.c (folder_getv): Implement, add a bunch of args you + can get -> camel_folder_get_unread_count etc will be going RSN i + hope. + (camel_folder_finalize): Free cached description string. + + * camel-object.c (cobject_getv): Implement + CAMEL_OBJECT_ARG_DESCRIPTION, just return the classname of the + object. + (camel_object_getv): + (camel_object_get): + (camel_object_setv): + (camel_object_set): Take object = void *, to simplify usage. + (camel_object_setv): Removed unecessary locals. + (camel_object_getv): Same. + (camel_object_free): New method, free an arg, upto implementations + whether args are static/const or not. + (cobject_free): Implement a dummy do nothing free. + +2002-05-31 Not Zed + + * camel-vee-folder.c (camel_vee_folder_get_location): new function + to get the real location (folder) (and uid) of a vfolder object. + Using the folderinfo, since we already have it, maybe it should + use the uid. + 2002-05-31 Jeffrey Stedfast * providers/imap/camel-imap-folder.c (get_content): When the part diff --git a/camel/camel-arg.c b/camel/camel-arg.c index bc6ececd2e..d642fb751a 100644 --- a/camel/camel-arg.c +++ b/camel/camel-arg.c @@ -122,3 +122,4 @@ fail: return more; } + diff --git a/camel/camel-folder.c b/camel/camel-folder.c index 05d765ce7a..f0162646c0 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -74,6 +74,8 @@ static gint get_unread_message_count (CamelFolder *folder); static void expunge (CamelFolder *folder, CamelException *ex); +static int folder_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args); +static void folder_free(CamelObject *o, guint32 tag, void *val); static void append_message (CamelFolder *folder, CamelMimeMessage *message, @@ -116,8 +118,7 @@ static gboolean message_changed (CamelObject *object, static void camel_folder_class_init (CamelFolderClass *camel_folder_class) { - CamelObjectClass *camel_object_class = - CAMEL_OBJECT_CLASS (camel_folder_class); + CamelObjectClass *camel_object_class = CAMEL_OBJECT_CLASS (camel_folder_class); parent_class = camel_type_get_global_classfuncs (camel_object_get_type ()); @@ -157,6 +158,10 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class) camel_folder_class->is_frozen = is_frozen; /* virtual method overload */ + camel_object_class->getv = folder_getv; + camel_object_class->free = folder_free; + + /* events */ camel_object_class_add_event(camel_object_class, "folder_changed", folder_changed); camel_object_class_add_event(camel_object_class, "message_changed", message_changed); camel_object_class_add_event(camel_object_class, "deleted", NULL); @@ -181,9 +186,11 @@ static void camel_folder_finalize (CamelObject *object) { CamelFolder *camel_folder = CAMEL_FOLDER (object); + struct _CamelFolderPrivate *p = camel_folder->priv; - g_free (camel_folder->name); - g_free (camel_folder->full_name); + g_free(camel_folder->name); + g_free(camel_folder->full_name); + g_free(camel_folder->description); if (camel_folder->parent_store) camel_object_unref (CAMEL_OBJECT (camel_folder->parent_store)); @@ -191,12 +198,12 @@ camel_folder_finalize (CamelObject *object) if (camel_folder->summary) camel_object_unref((CamelObject *)camel_folder->summary); - camel_folder_change_info_free(camel_folder->priv->changed_frozen); + camel_folder_change_info_free(p->changed_frozen); #ifdef ENABLE_THREADS - e_mutex_destroy(camel_folder->priv->lock); - e_mutex_destroy(camel_folder->priv->change_lock); + e_mutex_destroy(p->lock); + e_mutex_destroy(p->change_lock); #endif - g_free(camel_folder->priv); + g_free(p); } CamelType @@ -300,6 +307,111 @@ camel_folder_refresh_info (CamelFolder *folder, CamelException *ex) CAMEL_FOLDER_UNLOCK(folder, lock); } +static int +folder_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args) +{ + CamelFolder *folder = (CamelFolder *)object; + int i, count=args->argc; + guint32 tag; + + for (i=0;iargc;i++) { + CamelArgGet *arg = &args->argv[i]; + + tag = arg->tag; + + switch (tag & CAMEL_ARG_TAG) { + /* CamelObject args */ + case CAMEL_OBJECT_ARG_DESCRIPTION: + if (folder->description == NULL) + folder->description = g_strdup_printf("%s", folder->full_name); + *arg->ca_str = folder->description; + break; + + /* CamelFolder args */ + case CAMEL_FOLDER_ARG_NAME: + *arg->ca_str = folder->name; + break; + case CAMEL_FOLDER_ARG_FULL_NAME: + *arg->ca_str = folder->full_name; + break; + case CAMEL_FOLDER_ARG_STORE: + *arg->ca_object = folder->parent_store; + break; + case CAMEL_FOLDER_ARG_PERMANENTFLAGS: + *arg->ca_int = folder->permanent_flags; + break; + case CAMEL_FOLDER_ARG_TOTAL: + *arg->ca_int = camel_folder_summary_count(folder->summary); + break; + case CAMEL_FOLDER_ARG_UNREAD: { + int j, unread = 0, count; + CamelMessageInfo *info; + + count = camel_folder_summary_count(folder->summary); + for (j=0; jsummary, j))) { + if (!(info->flags & CAMEL_MESSAGE_SEEN)) + unread++; + camel_folder_summary_info_free(folder->summary, info); + } + } + + *arg->ca_int = unread; + break; } + case CAMEL_FOLDER_ARG_UID_ARRAY: { + int j, count; + CamelMessageInfo *info; + GPtrArray *array; + + count = camel_folder_summary_count(folder->summary); + array = g_ptr_array_new(); + g_ptr_array_set_size(array, count); + for (j=0; jsummary, j))) { + array->pdata[i] = g_strdup(camel_message_info_uid(info)); + camel_folder_summary_info_free(folder->summary, info); + } + } + *arg->ca_ptr = array; + break; } + case CAMEL_FOLDER_ARG_INFO_ARRAY: + *arg->ca_ptr = camel_folder_summary_array(folder->summary); + break; + default: + count--; + continue; + } + + arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE; + } + + if (count) + return parent_class->getv(object, ex, args); + + return 0; +} + +static void +folder_free(CamelObject *o, guint32 tag, void *val) +{ + CamelFolder *folder = (CamelFolder *)o; + + switch (tag & CAMEL_ARG_TAG) { + case CAMEL_FOLDER_ARG_UID_ARRAY: { + GPtrArray *array = val; + int i; + + for (i=0; ilen; i++) + g_free(array->pdata[i]); + g_ptr_array_free(array, TRUE); + break; } + case CAMEL_FOLDER_ARG_INFO_ARRAY: + camel_folder_summary_array_free(folder->summary, val); + break; + default: + parent_class->free(o, tag, val); + } +} static const char * get_name (CamelFolder *folder) diff --git a/camel/camel-folder.h b/camel/camel-folder.h index e437b1d87a..ebaf080457 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -42,6 +42,30 @@ extern "C" { typedef struct _CamelFolderChangeInfo CamelFolderChangeInfo; +enum { + CAMEL_FOLDER_ARG_FIRST = CAMEL_ARG_FIRST + 0x1000, + CAMEL_FOLDER_ARG_NAME = CAMEL_FOLDER_ARG_FIRST, + CAMEL_FOLDER_ARG_FULL_NAME, + CAMEL_FOLDER_ARG_STORE, + CAMEL_FOLDER_ARG_PERMANENTFLAGS, + CAMEL_FOLDER_ARG_TOTAL, + CAMEL_FOLDER_ARG_UNREAD, + CAMEL_FOLDER_ARG_UID_ARRAY, + CAMEL_FOLDER_ARG_INFO_ARRAY, +}; + +enum { + CAMEL_FOLDER_NAME = CAMEL_FOLDER_ARG_NAME | CAMEL_ARG_STR, + CAMEL_FOLDER_FULL_NAME = CAMEL_FOLDER_ARG_FULL_NAME | CAMEL_ARG_STR, + CAMEL_FOLDER_STORE = CAMEL_FOLDER_ARG_STORE | CAMEL_ARG_OBJ, + CAMEL_FOLDER_PERMANENTFLAGS = CAMEL_FOLDER_ARG_PERMANENTFLAGS | CAMEL_ARG_INT, + CAMEL_FOLDER_TOTAL = CAMEL_FOLDER_ARG_TOTAL | CAMEL_ARG_INT, + CAMEL_FOLDER_UNREAD = CAMEL_FOLDER_ARG_UNREAD | CAMEL_ARG_INT, + /* should we only get static data? not stuff that needs to be free'd? */ + CAMEL_FOLDER_UID_ARRAY = CAMEL_FOLDER_ARG_UID_ARRAY | CAMEL_ARG_PTR, + CAMEL_FOLDER_INFO_ARRAY = CAMEL_FOLDER_ARG_INFO_ARRAY | CAMEL_ARG_PTR, +}; + struct _CamelFolderChangeInfo { GPtrArray *uid_added; GPtrArray *uid_removed; @@ -57,8 +81,11 @@ struct _CamelFolder struct _CamelFolderPrivate *priv; + /* get these via the :get() method, they might not be set otherwise */ char *name; char *full_name; + char *description; + CamelStore *parent_store; CamelFolderSummary *summary; diff --git a/camel/camel-object.c b/camel/camel-object.c index 48a77971f7..eebcbf35d2 100644 --- a/camel/camel-object.c +++ b/camel/camel-object.c @@ -202,6 +202,21 @@ cobject_finalise(CamelObject *o) static int cobject_getv(CamelObject *o, CamelException *ex, CamelArgGetV *args) { + int i; + guint32 tag; + + for (i=0;iargc;i++) { + CamelArgGet *arg = &args->argv[i]; + + tag = arg->tag; + + switch (tag & CAMEL_ARG_TAG) { + case CAMEL_OBJECT_ARG_DESCRIPTION: + *arg->ca_str = (char *)o->klass->name; + break; + } + } + /* could have flags or stuff here? */ return 0; } @@ -213,6 +228,12 @@ cobject_setv(CamelObject *o, CamelException *ex, CamelArgV *args) return 0; } +static void +cobject_free(CamelObject *o, guint32 tag, void *value) +{ + /* do nothing */ +} + static void cobject_class_init(CamelObjectClass *klass) { @@ -220,6 +241,7 @@ cobject_class_init(CamelObjectClass *klass) klass->getv = cobject_getv; klass->setv = cobject_setv; + klass->free = cobject_free; camel_object_class_add_event(klass, "finalize", NULL); } @@ -871,9 +893,10 @@ trigger: } /* get/set arg methods */ -int camel_object_set(CamelObject *o, CamelException *ex, ...) +int camel_object_set(void *vo, CamelException *ex, ...) { CamelArgV args; + CamelObject *o = vo; CamelObjectClass *klass = o->klass; int ret = 0; @@ -891,15 +914,16 @@ int camel_object_set(CamelObject *o, CamelException *ex, ...) return ret; } -int camel_object_setv(CamelObject *o, CamelException *ex, CamelArgV *args) +int camel_object_setv(void *vo, CamelException *ex, CamelArgV *args) { - g_return_val_if_fail(CAMEL_IS_OBJECT(o), -1); + g_return_val_if_fail(CAMEL_IS_OBJECT(vo), -1); - return o->klass->setv(o, ex, args); + return ((CamelObject *)vo)->klass->setv(vo, ex, args); } -int camel_object_get(CamelObject *o, CamelException *ex, ...) +int camel_object_get(void *vo, CamelException *ex, ...) { + CamelObject *o = vo; CamelArgGetV args; CamelObjectClass *klass = o->klass; int ret = 0; @@ -918,13 +942,35 @@ int camel_object_get(CamelObject *o, CamelException *ex, ...) return ret; } -int camel_object_getv(CamelObject *o, CamelException *ex, CamelArgGetV *args) +int camel_object_getv(void *vo, CamelException *ex, CamelArgGetV *args) { - CamelObjectClass *klass = o->klass; + g_return_val_if_fail(CAMEL_IS_OBJECT(vo), -1); - g_return_val_if_fail(CAMEL_IS_OBJECT(o), -1); + return ((CamelObject *)vo)->klass->getv(vo, ex, args); +} + +/* free an arg object, you can only free objects 1 at a time */ +void camel_object_free(void *vo, guint32 tag, void *value) +{ + g_return_if_fail(CAMEL_IS_OBJECT(vo)); + + /* We could also handle freeing of args differently + + Add a 'const' bit to the arg type field, + specifying that the object should not be freed. + + And, add free handlers for any pointer objects which are + not const. The free handlers would be hookpairs off of the + class. + + Then we handle the basic types OBJ,STR here, and pass PTR + types to their appropriate handler, without having to pass + through the invocation heirarchy of the free method. + + This would also let us copy and do other things with args + we can't do, but i can't see a use for that yet ... */ - return klass->getv(o, ex, args); + ((CamelObject *)vo)->klass->free(vo, tag, value); } static void diff --git a/camel/camel-object.h b/camel/camel-object.h index cf574fe9f6..fddc778dd3 100644 --- a/camel/camel-object.h +++ b/camel/camel-object.h @@ -88,6 +88,15 @@ typedef void (*CamelObjectEventHookFunc) (CamelObject *, gpointer, gpointer); #define CAMEL_INVALID_TYPE (NULL) +/* camel object args */ +enum { + CAMEL_OBJECT_ARG_DESCRIPTION = CAMEL_ARG_FIRST, +}; + +enum { + CAMEL_OBJECT_DESCRIPTION = CAMEL_OBJECT_ARG_DESCRIPTION | CAMEL_ARG_STR, +}; + enum _CamelObjectFlags { CAMEL_OBJECT_DESTROY = (1<<0), }; @@ -147,6 +156,8 @@ struct _CamelObjectClass /* get/set interface */ int (*setv)(struct _CamelObject *, struct _CamelException *ex, CamelArgV *args); int (*getv)(struct _CamelObject *, struct _CamelException *ex, CamelArgGetV *args); + /* we only free 1 at a time, and only pointer types, obviously */ + void (*free)(struct _CamelObject *, guint32 tag, void *ptr); }; /* The type system .... it's pretty simple..... */ @@ -196,10 +207,13 @@ void camel_object_unhook_event(CamelObject *obj, const char *name, CamelObjectEv void camel_object_trigger_event(CamelObject *obj, const char *name, void *event_data); /* get/set methods */ -int camel_object_set(CamelObject *obj, struct _CamelException *ex, ...); -int camel_object_setv(CamelObject *obj, struct _CamelException *ex, CamelArgV *); -int camel_object_get(CamelObject *obj, struct _CamelException *ex, ...); -int camel_object_getv(CamelObject *obj, struct _CamelException *ex, CamelArgGetV *); +int camel_object_set(void *obj, struct _CamelException *ex, ...); +int camel_object_setv(void *obj, struct _CamelException *ex, CamelArgV *); +int camel_object_get(void *obj, struct _CamelException *ex, ...); +int camel_object_getv(void *obj, struct _CamelException *ex, CamelArgGetV *); + +/* free a bunch of objects, list must be 0 terminated */ +void camel_object_free(void *vo, guint32 tag, void *value); #ifdef __cplusplus } diff --git a/camel/camel-private.h b/camel/camel-private.h index 81cf2a4dad..55b5cd5f5e 100644 --- a/camel/camel-private.h +++ b/camel/camel-private.h @@ -43,7 +43,6 @@ struct _CamelFolderPrivate { EMutex *lock; EMutex *change_lock; #endif - /* must require the 'change_lock' to access this */ int frozen; struct _CamelFolderChangeInfo *changed_frozen; /* queues changed events */ diff --git a/camel/camel-sasl.c b/camel/camel-sasl.c index 1ce1286be1..6cc8a144e5 100644 --- a/camel/camel-sasl.c +++ b/camel/camel-sasl.c @@ -59,6 +59,7 @@ static void camel_sasl_finalize (CamelSasl *sasl) { g_free (sasl->service_name); + g_free(sasl->mech); camel_object_unref (CAMEL_OBJECT (sasl->service)); } @@ -206,7 +207,8 @@ camel_sasl_new (const char *service_name, const char *mechanism, CamelService *s sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_NTLM_TYPE); else return NULL; - + + sasl->mech = g_strdup(mechanism); sasl->service_name = g_strdup (service_name); sasl->service = service; camel_object_ref (CAMEL_OBJECT (service)); diff --git a/camel/camel-sasl.h b/camel/camel-sasl.h index 38b9a8f02b..2b5db5c447 100644 --- a/camel/camel-sasl.h +++ b/camel/camel-sasl.h @@ -42,6 +42,7 @@ typedef struct _CamelSasl { CamelObject parent_object; char *service_name; + char *mech; /* mechanism */ CamelService *service; gboolean authenticated; } CamelSasl; diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c index 11912e3637..2ef25935b8 100644 --- a/camel/camel-vee-folder.c +++ b/camel/camel-vee-folder.c @@ -512,6 +512,38 @@ camel_vee_folder_hash_folder(CamelFolder *folder, char buffer[8]) } } +/** + * camel_vee_folder_get_location: + * @vf: + * @vinfo: + * @realuid: if not NULL, set to the uid of the real message, must be + * g_free'd by caller. + * + * Find the real folder (and uid) + * + * Return value: + **/ +CamelFolder * +camel_vee_folder_get_location(CamelVeeFolder *vf, const CamelVeeMessageInfo *vinfo, char **realuid) +{ + /* locking? yes? no? although the vfolderinfo is valid when obtained + the folder in it might not necessarily be so ...? */ + if (CAMEL_IS_VEE_FOLDER(vinfo->folder)) { + CamelFolder *folder; + const CamelVeeMessageInfo *vfinfo; + + vfinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(vinfo->folder, camel_message_info_uid(vinfo)+8); + folder = camel_vee_folder_get_location((CamelVeeFolder *)vinfo->folder, vfinfo, realuid); + camel_folder_free_message_info(vinfo->folder, (CamelMessageInfo *)vfinfo); + return folder; + } else { + if (realuid) + *realuid = g_strdup(camel_message_info_uid(vinfo)+8); + + return vinfo->folder; + } +} + static void vee_refresh_info(CamelFolder *folder, CamelException *ex) { CamelVeeFolder *vf = (CamelVeeFolder *)folder; diff --git a/camel/camel-vee-folder.h b/camel/camel-vee-folder.h index 8d6770b4bc..3339b3a1d9 100644 --- a/camel/camel-vee-folder.h +++ b/camel/camel-vee-folder.h @@ -68,6 +68,8 @@ CamelType camel_vee_folder_get_type (void); CamelFolder *camel_vee_folder_new (CamelStore *parent_store, const char *name, guint32 flags); void camel_vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags); +CamelFolder *camel_vee_folder_get_location(CamelVeeFolder *vf, const CamelVeeMessageInfo *vinfo, char **realuid); + void camel_vee_folder_add_folder (CamelVeeFolder *vf, CamelFolder *sub); void camel_vee_folder_remove_folder (CamelVeeFolder *vf, CamelFolder *sub); void camel_vee_folder_set_folders (CamelVeeFolder *vf, GList *folders); diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 076066782f..1855ce2e8b 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -76,6 +76,8 @@ static CamelDiscoFolderClass *disco_folder_class = NULL; static void imap_finalize (CamelObject *object); +static int imap_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args); + static void imap_rescan (CamelFolder *folder, int exists, CamelException *ex); static void imap_refresh_info (CamelFolder *folder, CamelException *ex); static void imap_sync_online (CamelFolder *folder, CamelException *ex); @@ -119,6 +121,8 @@ static void imap_search_free (CamelFolder *folder, GPtrArray *uid static void imap_thaw (CamelFolder *folder); +static CamelObjectClass *parent_class; + GData *parse_fetch_response (CamelImapFolder *imap_folder, char *msg_att); static void @@ -130,6 +134,8 @@ camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class) disco_folder_class = CAMEL_DISCO_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_disco_folder_get_type ())); /* virtual method overload */ + ((CamelObjectClass *)camel_imap_folder_class)->getv = imap_getv; + camel_folder_class->get_message = imap_get_message; camel_folder_class->rename = imap_rename; camel_folder_class->search_by_expression = imap_search_by_expression; @@ -180,8 +186,9 @@ camel_imap_folder_get_type (void) static CamelType camel_imap_folder_type = CAMEL_INVALID_TYPE; if (camel_imap_folder_type == CAMEL_INVALID_TYPE) { + parent_class = camel_disco_folder_get_type(); camel_imap_folder_type = - camel_type_register (CAMEL_DISCO_FOLDER_TYPE, "CamelImapFolder", + camel_type_register (parent_class, "CamelImapFolder", sizeof (CamelImapFolder), sizeof (CamelImapFolderClass), (CamelObjectClassInitFunc) camel_imap_folder_class_init, @@ -387,6 +394,43 @@ imap_finalize (CamelObject *object) g_free(imap_folder->priv); } +static int +imap_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args) +{ + CamelFolder *folder = (CamelFolder *)object; + int i, count=args->argc; + guint32 tag; + + for (i=0;iargc;i++) { + CamelArgGet *arg = &args->argv[i]; + + tag = arg->tag; + + switch (tag & CAMEL_ARG_TAG) { + /* CamelObject args */ + case CAMEL_OBJECT_ARG_DESCRIPTION: + if (folder->description == NULL) { + CamelURL *uri = ((CamelService *)folder->parent_store)->url; + + /* what if the full name doesn't incclude /'s? does it matter? */ + folder->description = g_strdup_printf("%s@%s:%s", uri->user, uri->host, folder->full_name); + } + *arg->ca_str = folder->description; + break; + default: + count--; + continue; + } + + arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE; + } + + if (count) + return ((CamelObjectClass *)parent_class)->getv(object, ex, args); + + return 0; +} + static void imap_rename (CamelFolder *folder, const char *new) { diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c index 3ae6c74873..c12e9d5da7 100644 --- a/camel/providers/local/camel-local-folder.c +++ b/camel/providers/local/camel-local-folder.c @@ -65,6 +65,8 @@ static CamelFolderClass *parent_class = NULL; #define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) #define CLOCALS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) +static int local_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args); + static int local_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex); static void local_unlock(CamelLocalFolder *lf); @@ -83,12 +85,15 @@ static void camel_local_folder_class_init(CamelLocalFolderClass * camel_local_folder_class) { CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_local_folder_class); + CamelObjectClass *oklass = (CamelObjectClass *)camel_local_folder_class; parent_class = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs(camel_folder_get_type())); /* virtual method definition */ /* virtual method overload */ + oklass->getv = local_getv; + camel_folder_class->sync = local_sync; camel_folder_class->expunge = local_expunge; @@ -296,6 +301,64 @@ int camel_local_folder_unlock(CamelLocalFolder *lf) return 0; } +static int +local_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args) +{ + CamelFolder *folder = (CamelFolder *)object; + int i, count=args->argc; + guint32 tag; + + for (i=0;iargc;i++) { + CamelArgGet *arg = &args->argv[i]; + + tag = arg->tag; + + switch (tag & CAMEL_ARG_TAG) { + /* CamelObject args */ + case CAMEL_OBJECT_ARG_DESCRIPTION: + if (folder->description == NULL) { + char *tmp, *path; + + /* check some common prefixes to shorten the name */ + tmp = ((CamelService *)folder->parent_store)->url->path; + if (tmp == NULL) + goto skip; + + path = alloca(strlen(tmp)+strlen(folder->full_name)+1); + sprintf(path, "%s/%s", tmp, folder->full_name); + + if ((tmp = getenv("HOME")) && strncmp(tmp, path, strlen(tmp)) == 0) + /* $HOME relative path + protocol string */ + folder->description = g_strdup_printf(_("~%s (%s)"), path+strlen(tmp), + ((CamelService *)folder->parent_store)->url->protocol); + else if ((tmp = "/var/spool/mail") && strncmp(tmp, path, strlen(tmp)) == 0) + /* /var/spool/mail relative path + protocol */ + folder->description = g_strdup_printf(_("mailbox:%s (%s)"), path+strlen(tmp), + ((CamelService *)folder->parent_store)->url->protocol); + else if ((tmp = "/var/mail") && strncmp(tmp, path, strlen(tmp)) == 0) + folder->description = g_strdup_printf(_("mailbox:%s (%s)"), path+strlen(tmp), + ((CamelService *)folder->parent_store)->url->protocol); + else + /* a full path + protocol */ + folder->description = g_strdup_printf(_("%s (%s)"), path, + ((CamelService *)folder->parent_store)->url->protocol); + } + *arg->ca_str = folder->description; + break; + default: skip: + count--; + continue; + } + + arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE; + } + + if (count) + return ((CamelObjectClass *)parent_class)->getv(object, ex, args); + + return 0; +} + static int local_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex) { -- cgit v1.2.3