diff options
Diffstat (limited to 'camel')
-rw-r--r-- | camel/Makefile.am | 4 | ||||
-rw-r--r-- | camel/camel-digest-store.c | 21 | ||||
-rw-r--r-- | camel/camel-filter-driver.c | 23 | ||||
-rw-r--r-- | camel/camel-filter-search.c | 25 | ||||
-rw-r--r-- | camel/camel-folder-summary.c | 1 | ||||
-rw-r--r-- | camel/camel-folder-summary.h | 1 | ||||
-rw-r--r-- | camel/camel-folder.c | 16 | ||||
-rw-r--r-- | camel/camel-folder.h | 1 | ||||
-rw-r--r-- | camel/camel-junk-plugin.c | 75 | ||||
-rw-r--r-- | camel/camel-junk-plugin.h | 59 | ||||
-rw-r--r-- | camel/camel-session.h | 3 | ||||
-rw-r--r-- | camel/camel-store.c | 152 | ||||
-rw-r--r-- | camel/camel-store.h | 7 | ||||
-rw-r--r-- | camel/camel-vee-store.c | 23 | ||||
-rw-r--r-- | camel/camel-vtrash-folder.h | 1 |
15 files changed, 348 insertions, 64 deletions
diff --git a/camel/Makefile.am b/camel/Makefile.am index a1d00a1323..45d583f263 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -92,7 +92,7 @@ libcamel_la_SOURCES = \ camel-seekable-substream.c \ camel-service.c \ camel-session.c \ - camel-smime-context.c \ + camel-junk-plugin.c \ camel-store.c \ camel-store-summary.c \ camel-stream-buffer.c \ @@ -192,7 +192,7 @@ libcamelinclude_HEADERS = \ camel-seekable-substream.h \ camel-service.h \ camel-session.h \ - camel-smime-context.h \ + camel-junk-plugin.h \ camel-store.h \ camel-store-summary.h \ camel-stream-buffer.h \ diff --git a/camel/camel-digest-store.c b/camel/camel-digest-store.c index e3870e3672..833593ac9f 100644 --- a/camel/camel-digest-store.c +++ b/camel/camel-digest-store.c @@ -40,6 +40,8 @@ static void digest_delete_folder (CamelStore *store, const char *folder_name, Ca static void digest_rename_folder (CamelStore *store, const char *old, const char *new, CamelException *ex); static void digest_init_trash (CamelStore *store); static CamelFolder *digest_get_trash (CamelStore *store, CamelException *ex); +static void digest_init_junk (CamelStore *store); +static CamelFolder *digest_get_junk (CamelStore *store, CamelException *ex); static CamelFolderInfo *digest_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex); @@ -92,6 +94,8 @@ camel_digest_store_class_init (CamelDigestStoreClass *klass) store_class->init_trash = digest_init_trash; store_class->get_trash = digest_get_trash; + store_class->init_junk = digest_init_junk; + store_class->get_junk = digest_get_junk; } static void @@ -99,8 +103,8 @@ camel_digest_store_init (CamelDigestStore *obj) { CamelStore *store = (CamelStore *) obj; - /* we dont want a vtrash on this one */ - store->flags &= ~(CAMEL_STORE_VTRASH); + /* we dont want a vtrash and vjunk on this one */ + store->flags &= ~(CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK); } static void @@ -167,6 +171,19 @@ digest_get_trash (CamelStore *store, CamelException *ex) return NULL; } +static void +digest_init_junk (CamelStore *store) +{ + /* no-op */ + ; +} + +static CamelFolder * +digest_get_junk (CamelStore *store, CamelException *ex) +{ + return NULL; +} + static CamelFolderInfo * digest_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex) { diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c index ff6a8a88d2..cb968f20c8 100644 --- a/camel/camel-filter-driver.c +++ b/camel/camel-filter-driver.c @@ -254,7 +254,7 @@ camel_filter_driver_finalise (CamelObject *obj) if (p->defaultfolder) { camel_folder_thaw (p->defaultfolder); - camel_object_unref (p->defaultfolder); + camel_object_unref (CAMEL_OBJECT (p->defaultfolder)); } while ((node = (struct _filter_rule *)e_dlist_remhead(&p->rules))) { @@ -345,14 +345,14 @@ camel_filter_driver_set_default_folder (CamelFilterDriver *d, CamelFolder *def) if (p->defaultfolder) { camel_folder_thaw (p->defaultfolder); - camel_object_unref (p->defaultfolder); + camel_object_unref (CAMEL_OBJECT (p->defaultfolder)); } p->defaultfolder = def; if (p->defaultfolder) { camel_folder_freeze (p->defaultfolder); - camel_object_ref (p->defaultfolder); + camel_object_ref (CAMEL_OBJECT (p->defaultfolder)); } } @@ -809,7 +809,6 @@ pipe_message (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilte return NULL; } - static ESExpResult * do_shell (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *driver) { @@ -934,7 +933,7 @@ close_folder (void *key, void *value, void *data) if (folder != FOLDER_INVALID) { camel_folder_sync (folder, FALSE, p->ex); camel_folder_thaw (folder); - camel_object_unref (folder); + camel_object_unref (CAMEL_OBJECT (folder)); } report_status(driver, CAMEL_FILTER_STATUS_PROGRESS, g_hash_table_size(p->folders)* 100 / p->closed, _("Syncing folders")); @@ -1141,7 +1140,7 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, const char *mbox, co if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), mp) == -1) { camel_exception_set (ex, (errno==EINTR)?CAMEL_EXCEPTION_USER_CANCEL:CAMEL_EXCEPTION_SYSTEM, _("Cannot open message")); report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Failed on message %d"), i); - camel_object_unref (msg); + camel_object_unref (CAMEL_OBJECT (msg)); goto fail; } @@ -1150,7 +1149,7 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, const char *mbox, co last = camel_mime_parser_tell(mp); status = camel_filter_driver_filter_message (driver, msg, info, NULL, NULL, source_url, original_source_url ? original_source_url : source_url, ex); - camel_object_unref (msg); + camel_object_unref (CAMEL_OBJECT (msg)); if (camel_exception_is_set (ex) || status == -1) { report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Failed on message %d"), i); camel_message_info_free (info); @@ -1178,7 +1177,7 @@ fail: if (fd != -1) close (fd); if (mp) - camel_object_unref (mp); + camel_object_unref (CAMEL_OBJECT (mp)); return -1; } @@ -1352,7 +1351,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage struct _camel_header_raw *h; if (message) { - camel_object_ref (message); + camel_object_ref (CAMEL_OBJECT (message)); } else { message = camel_folder_get_message (source, uid, ex); if (!message) @@ -1369,7 +1368,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage uid = camel_message_info_uid (info); if (message) - camel_object_ref (message); + camel_object_ref (CAMEL_OBJECT (message)); } p->ex = ex; @@ -1458,7 +1457,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage } if (p->message) - camel_object_unref (p->message); + camel_object_unref (CAMEL_OBJECT (p->message)); if (freeinfo) camel_message_info_free (info); @@ -1470,7 +1469,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage camel_filter_driver_log (driver, FILTER_LOG_END, NULL); if (p->message) - camel_object_unref (p->message); + camel_object_unref (CAMEL_OBJECT (p->message)); if (freeinfo) camel_message_info_free (info); diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c index 8af3392e71..746c248352 100644 --- a/camel/camel-filter-search.c +++ b/camel/camel-filter-search.c @@ -91,6 +91,7 @@ static ESExpResult *get_current_date (struct _ESExp *f, int argc, struct _ESExpR static ESExpResult *header_source (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *get_size (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *pipe_message (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); +static ESExpResult *junk_test (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); /* builtin functions */ static struct { @@ -119,6 +120,7 @@ static struct { { "header-source", (ESExpFunc *) header_source, 0 }, { "get-size", (ESExpFunc *) get_size, 0 }, { "pipe-message", (ESExpFunc *) pipe_message, 0 }, + { "junk-test", (ESExpFunc *) junk_test, 0 }, }; @@ -563,7 +565,7 @@ run_command (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessa camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), stream); camel_stream_flush (stream); - camel_object_unref (stream); + camel_object_unref (CAMEL_OBJECT (stream)); result = waitpid (pid, &status, 0); @@ -609,6 +611,23 @@ pipe_message (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMess return r; } +static ESExpResult * +junk_test (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms) +{ + ESExpResult *r; + gboolean retval = FALSE; + + if (fms->session->junk_plugin != NULL) { + retval = camel_junk_plugin_check_junk (fms->session->junk_plugin, camel_filter_search_get_message (fms, f)); + + fprintf (stderr, "junk filter => %s\n", retval ? "*JUNK*" : "clean"); + } + r = e_sexp_result_new (f, ESEXP_RES_BOOL); + r->value.number = retval; + + return r; +} + /** * camel_filter_search_match: @@ -676,13 +695,13 @@ camel_filter_search_match (CamelSession *session, e_sexp_unref (sexp); if (fms.message) - camel_object_unref (fms.message); + camel_object_unref (CAMEL_OBJECT (fms.message)); return retval; error: if (fms.message) - camel_object_unref (fms.message); + camel_object_unref (CAMEL_OBJECT (fms.message)); e_sexp_unref (sexp); diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index 3ad9eb31ad..05b3f3a056 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -2503,6 +2503,7 @@ struct flag_names_t { { "flagged", CAMEL_MESSAGE_FLAGGED }, { "seen", CAMEL_MESSAGE_SEEN }, { "attachments", CAMEL_MESSAGE_ATTACHMENTS }, + { "junk", CAMEL_MESSAGE_JUNK }, { NULL, 0 } }; diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index 48713b1a3c..e57be75ae1 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -64,6 +64,7 @@ enum _CamelMessageFlags { CAMEL_MESSAGE_SEEN = 1<<4, CAMEL_MESSAGE_ATTACHMENTS = 1<<5, CAMEL_MESSAGE_ANSWERED_ALL = 1<<6, + CAMEL_MESSAGE_JUNK = 1<<7, /* following flags are for the folder, and are not really permanent flags */ CAMEL_MESSAGE_FOLDER_FLAGGED = 1<<16, /* for use by the folder implementation */ diff --git a/camel/camel-folder.c b/camel/camel-folder.c index f682ee25ca..aae2af0a64 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -549,7 +549,7 @@ get_unread_message_count(CamelFolder *folder) CamelMessageInfo *info = camel_folder_summary_index(folder->summary, i); if (info) { - if (!(info->flags & CAMEL_MESSAGE_SEEN)) + if (!(info->flags & CAMEL_MESSAGE_SEEN) && (!(info->flags & CAMEL_MESSAGE_JUNK) || (folder->folder_flags & CAMEL_FOLDER_IS_JUNK))) unread++; camel_folder_summary_info_free(folder->summary, info); } @@ -702,7 +702,7 @@ set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 s camel_folder_summary_touch(folder->summary); camel_folder_summary_info_free(folder->summary, info); - camel_object_trigger_event (folder, "message_changed", (char *) uid); + camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); } /** @@ -779,7 +779,7 @@ set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gb if (camel_flag_set(&info->user_flags, name, value)) { info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; camel_folder_summary_touch(folder->summary); - camel_object_trigger_event (folder, "message_changed", (char *) uid); + camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); } camel_folder_summary_info_free(folder->summary, info); } @@ -859,7 +859,7 @@ set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, con if (camel_tag_set(&info->user_tags, name, value)) { info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; camel_folder_summary_touch(folder->summary); - camel_object_trigger_event (folder, "message_changed", (char *) uid); + camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); } camel_folder_summary_info_free(folder->summary, info); } @@ -1289,7 +1289,7 @@ transfer_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, } camel_folder_append_message (dest, msg, info, transferred_uid, ex); - camel_object_unref (msg); + camel_object_unref (CAMEL_OBJECT (msg)); if (delete_original && !camel_exception_is_set (ex)) camel_folder_set_message_flags (source, uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0); @@ -1415,7 +1415,7 @@ camel_folder_delete (CamelFolder *folder) CAMEL_FOLDER_UNLOCK (folder, lock); - camel_object_trigger_event (folder, "deleted", NULL); + camel_object_trigger_event (CAMEL_OBJECT (folder), "deleted", NULL); } static void @@ -1451,7 +1451,7 @@ camel_folder_rename(CamelFolder *folder, const char *new) CF_CLASS (folder)->rename(folder, new); - camel_object_trigger_event (folder, "renamed", old); + camel_object_trigger_event (CAMEL_OBJECT (folder), "renamed", old); g_free(old); } @@ -1507,7 +1507,7 @@ thaw (CamelFolder * folder) CAMEL_FOLDER_UNLOCK(folder, change_lock); if (info) { - camel_object_trigger_event (folder, "folder_changed", info); + camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", info); camel_folder_change_info_free(info); } } diff --git a/camel/camel-folder.h b/camel/camel-folder.h index f1fe9bfb63..83df665147 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -103,6 +103,7 @@ struct _CamelFolder #define CAMEL_FOLDER_FILTER_RECENT (1<<2) #define CAMEL_FOLDER_HAS_BEEN_DELETED (1<<3) #define CAMEL_FOLDER_IS_TRASH (1<<4) +#define CAMEL_FOLDER_IS_JUNK (1<<5) typedef struct { CamelObjectClass parent_class; diff --git a/camel/camel-junk-plugin.c b/camel/camel-junk-plugin.c new file mode 100644 index 0000000000..a203b45c3e --- /dev/null +++ b/camel/camel-junk-plugin.c @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Author: + * Radek Doulik <rodo@ximian.com> + * + * Copyright 2003 Ximian, Inc. (www.ximian.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include <stdio.h> +#include <glib.h> +#include <camel/camel-junk-plugin.h> +#include <camel/camel-mime-message.h> + +#define d(x) x + +const char * +camel_junk_plugin_get_name (CamelJunkPlugin *csp) +{ + g_return_val_if_fail (csp->get_name != NULL, NULL); + + d(fprintf (stderr, "camel_junk_plugin_get_namen");) + + return (*csp->get_name) (); +} + +int +camel_junk_plugin_check_junk (CamelJunkPlugin *csp, CamelMimeMessage *message) +{ + g_return_val_if_fail (csp->check_junk != NULL, FALSE); + + d(fprintf (stderr, "camel_junk_plugin_check_junk\n");) + + return (*csp->check_junk) (message); +} + +void +camel_junk_plugin_report_junk (CamelJunkPlugin *csp, CamelMimeMessage *message) +{ + d(fprintf (stderr, "camel_junk_plugin_report_junk\n");) + + if (csp->report_junk) + (*csp->report_junk) (message); +} + +void +camel_junk_plugin_report_notjunk (CamelJunkPlugin *csp, CamelMimeMessage *message) +{ + d(fprintf (stderr, "camel_junk_plugin_report_notjunk\n");) + + if (csp->report_notjunk) + (*csp->report_notjunk) (message); +} + +void +camel_junk_plugin_commit_reports (CamelJunkPlugin *csp) +{ + d(fprintf (stderr, "camel_junk_plugin_commit_reports\n");) + + if (csp->commit_reports) + (*csp->commit_reports) (); +} diff --git a/camel/camel-junk-plugin.h b/camel/camel-junk-plugin.h new file mode 100644 index 0000000000..79d1bf6331 --- /dev/null +++ b/camel/camel-junk-plugin.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Author: + * Radek Doulik <rodo@ximian.com> + * + * Copyright 2003 Ximian, Inc. (www.ximian.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifndef _CAMEL_JUNK_PLUGIN_H +#define _CAMEL_JUNK_PLUGIN_H + +#define CAMEL_JUNK_PLUGIN(x) ((CamelJunkPlugin *) x) + +typedef struct _CamelJunkPlugin CamelJunkPlugin; +struct _CamelMimeMessage; + +struct _CamelJunkPlugin +{ + /* junk filter human readable name, translated */ + const char * (*get_name) (void); + + /* should be set to 1 */ + int api_version; + + /* when called, it should return TRUE if message is identified as junk, + FALSE otherwise */ + int (*check_junk) (struct _CamelMimeMessage *message); + + /* called when user identified a message to be junk */ + void (*report_junk) (struct _CamelMimeMessage *message); + + /* called when user identified a message not to be junk */ + void (*report_notjunk) (struct _CamelMimeMessage *message); + + /* called after one or more junk/ham(s) reported */ + void (*commit_reports) (void); +}; + +const char * camel_junk_plugin_get_name (CamelJunkPlugin *csp); +int camel_junk_plugin_check_junk (CamelJunkPlugin *csp, struct _CamelMimeMessage *message); +void camel_junk_plugin_report_junk (CamelJunkPlugin *csp, struct _CamelMimeMessage *message); +void camel_junk_plugin_report_notjunk (CamelJunkPlugin *csp, struct _CamelMimeMessage *message); +void camel_junk_plugin_commit_reports (CamelJunkPlugin *csp); + +#endif diff --git a/camel/camel-session.h b/camel/camel-session.h index b9416ddc8d..43abc614a8 100644 --- a/camel/camel-session.h +++ b/camel/camel-session.h @@ -35,6 +35,7 @@ extern "C" { #include <camel/camel-object.h> #include <camel/camel-provider.h> +#include <camel/camel-junk-plugin.h> #include <e-util/e-msgport.h> @@ -59,6 +60,8 @@ struct _CamelSession char *storage_path; GHashTable *providers, *modules; gboolean online; + + CamelJunkPlugin *junk_plugin; }; #ifdef ENABLE_THREADS diff --git a/camel/camel-store.c b/camel/camel-store.c index 96d840d2d3..07b75271e3 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -53,6 +53,9 @@ static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); static void init_trash (CamelStore *store); static CamelFolder *get_trash (CamelStore *store, CamelException *ex); +static void init_junk (CamelStore *store); +static CamelFolder *get_junk (CamelStore *store, CamelException *ex); + static CamelFolderInfo *create_folder (CamelStore *store, const char *parent_name, const char *folder_name, @@ -95,6 +98,8 @@ camel_store_class_init (CamelStoreClass *camel_store_class) camel_store_class->get_inbox = get_inbox; camel_store_class->init_trash = init_trash; camel_store_class->get_trash = get_trash; + camel_store_class->init_junk = init_junk; + camel_store_class->get_junk = get_junk; camel_store_class->create_folder = create_folder; camel_store_class->delete_folder = delete_folder; camel_store_class->rename_folder = rename_folder; @@ -132,8 +137,8 @@ camel_store_init (void *o) } else store->folders = NULL; - /* set vtrash on by default */ - store->flags = CAMEL_STORE_VTRASH; + /* set vtrash and vjunk on by default */ + store->flags = CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK; store->dir_sep = '/'; @@ -239,9 +244,11 @@ camel_store_get_folder (CamelStore *store, const char *folder_name, guint32 flag if (!folder) { folder = CS_CLASS (store)->get_folder (store, folder_name, flags, ex); if (folder) { - /* Add the folder to the vTrash folder if this store implements it */ + /* Add the folder to the vTrash/vJunk folder if this store implements it */ if (store->vtrash) camel_vee_folder_add_folder (CAMEL_VEE_FOLDER (store->vtrash), folder); + if (store->vjunk) + camel_vee_folder_add_folder (CAMEL_VEE_FOLDER (store->vjunk), folder); if (store->folders) camel_object_bag_add(store->folders, folder_name, folder); @@ -319,12 +326,14 @@ camel_store_delete_folder (CamelStore *store, const char *folder_name, CamelExce /* NB: Note similarity of this code to unsubscribe_folder */ - /* if we deleted a folder, force it out of the cache, and also out of the vtrash if setup */ + /* if we deleted a folder, force it out of the cache, and also out of the vtrash/vjunk if setup */ if (store->folders) { folder = camel_object_bag_get(store->folders, folder_name); if (folder) { if (store->vtrash) camel_vee_folder_remove_folder((CamelVeeFolder *)store->vtrash, folder); + if (store->vjunk) + camel_vee_folder_remove_folder((CamelVeeFolder *)store->vjunk, folder); camel_folder_delete (folder); } } @@ -424,7 +433,7 @@ camel_store_rename_folder (CamelStore *store, const char *old_name, const char * reninfo.old_base = (char *)old_name; reninfo.new = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder_info(store, new_name, flags, ex); if (reninfo.new != NULL) { - camel_object_trigger_event (store, "folder_renamed", &reninfo); + camel_object_trigger_event(CAMEL_OBJECT(store), "folder_renamed", &reninfo); ((CamelStoreClass *)((CamelObject *)store)->klass)->free_folder_info(store, reninfo.new); } } else { @@ -480,26 +489,46 @@ trash_finalize (CamelObject *trash, gpointer event_data, gpointer user_data) } static void -init_trash (CamelStore *store) +junk_finalize (CamelObject *junk, gpointer event_data, gpointer user_data) { - if ((store->flags & CAMEL_STORE_VTRASH) == 0) - return; + CamelStore *store = CAMEL_STORE (user_data); + + store->vjunk = NULL; +} - store->vtrash = camel_vtrash_folder_new (store, CAMEL_VTRASH_NAME); +/* FIXME: derive vjunk folder object from vee_folder */ +#include "camel-vee-store.h" +static CamelFolder * +camel_vjunk_folder_new (CamelStore *parent_store, const char *name) +{ + CamelFolder *vjunk; - if (store->vtrash) { + vjunk = (CamelFolder *)camel_object_new (camel_vee_folder_get_type ()); + vjunk->folder_flags |= CAMEL_FOLDER_IS_JUNK; + camel_vee_folder_construct (CAMEL_VEE_FOLDER (vjunk), parent_store, name, + CAMEL_STORE_FOLDER_PRIVATE | CAMEL_STORE_FOLDER_CREATE | CAMEL_STORE_VEE_FOLDER_AUTO); + camel_vee_folder_set_expression((CamelVeeFolder *)vjunk, "(match-all (system-flag \"Junk\"))"); + + return vjunk; +} + +static void +init_trash_or_junk (CamelStore *store, CamelFolder *folder, void (*finalize) (CamelObject *o, gpointer event_data, gpointer user_data)) +{ + CamelFolder *folder = NULL; + + if (folder) { /* FIXME: this should probably use the object bag or another one ? ... */ - /* attach to the finalise event of the vtrash */ - camel_object_hook_event (store->vtrash, "finalize", - trash_finalize, store); + /* attach to the finalise event of the vtrash/vjunk */ + camel_object_hook_event (CAMEL_OBJECT (folder), "finalize", finalize, store); - /* add all the pre-opened folders to the vtrash */ + /* add all the pre-opened folders to the vtrash/vjunk */ if (store->folders) { GPtrArray *folders = camel_object_bag_list(store->folders); int i; for (i=0;i<folders->len;i++) { - camel_vee_folder_add_folder (CAMEL_VEE_FOLDER (store->vtrash), (CamelFolder *)folders->pdata[i]); + camel_vee_folder_add_folder (CAMEL_VEE_FOLDER (folder), (CamelFolder *)folders->pdata[i]); camel_object_unref(folders->pdata[i]); } g_ptr_array_free(folders, TRUE); @@ -507,19 +536,38 @@ init_trash (CamelStore *store) } } +static void +init_trash (CamelStore *store) +{ + if ((store->flags & CAMEL_STORE_VTRASH) == 0) + return; + + store->vtrash = camel_vtrash_folder_new (store, CAMEL_VTRASH_NAME); + init_trash_or_junk (store, store->vtrash, trash_finalize); +} + +static void +init_junk (CamelStore *store) +{ + if ((store->flags & CAMEL_STORE_VJUNK) == 0) + return; + + store->vjunk = camel_vjunk_folder_new (store, CAMEL_VJUNK_NAME); + init_trash_or_junk (store, store->vjunk, junk_finalize); +} static CamelFolder * get_trash (CamelStore *store, CamelException *ex) { if (store->vtrash) { - camel_object_ref (store->vtrash); + camel_object_ref (CAMEL_OBJECT (store->vtrash)); return store->vtrash; } else { CS_CLASS (store)->init_trash (store); if (store->vtrash) { /* We don't ref here because we don't want the store to own a ref on the trash folder */ - /*camel_object_ref (store->vtrash);*/ + /*camel_object_ref (CAMEL_OBJECT (store->vtrash));*/ return store->vtrash; } else { w(g_warning ("This store does not support vTrash.")); @@ -528,6 +576,26 @@ get_trash (CamelStore *store, CamelException *ex) } } +static CamelFolder * +get_junk (CamelStore *store, CamelException *ex) +{ + if (store->vjunk) { + camel_object_ref (CAMEL_OBJECT (store->vjunk)); + return store->vjunk; + } else { + CS_CLASS (store)->init_junk (store); + if (store->vjunk) { + /* We don't ref here because we don't want the + store to own a ref on the junk folder */ + /*camel_object_ref (CAMEL_OBJECT (store->vjunk));*/ + return store->vjunk; + } else { + w(g_warning ("This store does not support vJunk.")); + return NULL; + } + } +} + /** * camel_store_get_trash: * @store: a CamelStore @@ -551,6 +619,29 @@ camel_store_get_trash (CamelStore *store, CamelException *ex) return folder; } +/** + * camel_store_get_junk: + * @store: a CamelStore + * @ex: a CamelException + * + * Return value: the folder in the store into which junk is + * delivered, or %NULL if no such folder exists. + **/ +CamelFolder * +camel_store_get_junk (CamelStore *store, CamelException *ex) +{ + CamelFolder *folder; + + if ((store->flags & CAMEL_STORE_VJUNK) == 0) + return NULL; + + CAMEL_STORE_LOCK(store, folder_lock); + folder = CS_CLASS (store)->get_junk (store, ex); + CAMEL_STORE_UNLOCK(store, folder_lock); + + return folder; +} + static void store_sync (CamelStore *store, CamelException *ex) { @@ -776,7 +867,7 @@ CamelFolderInfo * camel_folder_info_build (GPtrArray *folders, const char *namespace, char separator, gboolean short_names) { - CamelFolderInfo *fi, *pfi, *top = NULL, *tail = NULL; + CamelFolderInfo *fi, *pfi, *top = NULL; GHashTable *hash; char *name, *p, *pname; int i, nlen; @@ -854,15 +945,9 @@ camel_folder_info_build (GPtrArray *folders, const char *namespace, g_hash_table_insert (hash, pname, pfi); g_ptr_array_add (folders, pfi); } - tail = pfi->child; - if (tail == NULL) { - pfi->child = fi; - } else { - while (tail->sibling) - tail = tail->sibling; - tail->sibling = fi; - } + fi->sibling = pfi->child; fi->parent = pfi; + pfi->child = fi; } else if (!top) top = fi; } @@ -870,18 +955,13 @@ camel_folder_info_build (GPtrArray *folders, const char *namespace, g_hash_table_destroy (hash); /* Link together the top-level folders */ - tail = top; for (i = 0; i < folders->len; i++) { fi = folders->pdata[i]; if (fi->parent || fi == top) continue; - if (tail == NULL) { - tail = fi; - top = fi; - } else { - tail->sibling = fi; - tail = fi; - } + if (top) + fi->sibling = top; + top = fi; } return top; @@ -1015,12 +1095,14 @@ camel_store_unsubscribe_folder (CamelStore *store, /* NB: Note similarity of this code to delete_folder */ - /* if we deleted a folder, force it out of the cache, and also out of the vtrash if setup */ + /* if we deleted a folder, force it out of the cache, and also out of the vtrash/vjunk if setup */ if (store->folders) { folder = camel_object_bag_get(store->folders, folder_name); if (folder) { if (store->vtrash) camel_vee_folder_remove_folder((CamelVeeFolder *)store->vtrash, folder); + if (store->vjunk) + camel_vee_folder_remove_folder((CamelVeeFolder *)store->vjunk, folder); camel_folder_delete (folder); } } diff --git a/camel/camel-store.h b/camel/camel-store.h index 4a0fb416f0..2b65751aac 100644 --- a/camel/camel-store.h +++ b/camel/camel-store.h @@ -83,6 +83,7 @@ typedef struct _CamelRenameInfo { #define CAMEL_STORE_SUBSCRIPTIONS (1 << 0) #define CAMEL_STORE_VTRASH (1 << 1) #define CAMEL_STORE_FILTER_INBOX (1 << 2) +#define CAMEL_STORE_VJUNK (1 << 3) struct _CamelStore { @@ -90,6 +91,7 @@ struct _CamelStore struct _CamelStorePrivate *priv; CamelFolder *vtrash; + CamelFolder *vjunk; CamelObjectBag *folders; @@ -127,6 +129,9 @@ typedef struct { void (*init_trash) (CamelStore *store); CamelFolder * (*get_trash) (CamelStore *store, CamelException *ex); + void (*init_junk) (CamelStore *store); + CamelFolder * (*get_junk) (CamelStore *store, + CamelException *ex); CamelFolderInfo *(*create_folder) (CamelStore *store, const char *parent_name, @@ -175,6 +180,8 @@ CamelFolder * camel_store_get_inbox (CamelStore *store, CamelException *ex); CamelFolder * camel_store_get_trash (CamelStore *store, CamelException *ex); +CamelFolder * camel_store_get_junk (CamelStore *store, + CamelException *ex); CamelFolderInfo *camel_store_create_folder (CamelStore *store, const char *parent_name, diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c index 3ad39237e0..b13522b8de 100644 --- a/camel/camel-vee-store.c +++ b/camel/camel-vee-store.c @@ -37,6 +37,8 @@ static void vee_delete_folder(CamelStore *store, const char *folder_name, CamelE static void vee_rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex); static void vee_init_trash (CamelStore *store); static CamelFolder *vee_get_trash (CamelStore *store, CamelException *ex); +static void vee_init_junk (CamelStore *store); +static CamelFolder *vee_get_junk (CamelStore *store, CamelException *ex); static CamelFolderInfo *vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex); @@ -80,6 +82,8 @@ camel_vee_store_class_init (CamelVeeStoreClass *klass) store_class->init_trash = vee_init_trash; store_class->get_trash = vee_get_trash; + store_class->init_junk = vee_init_junk; + store_class->get_junk = vee_get_junk; } static void @@ -87,8 +91,8 @@ camel_vee_store_init (CamelVeeStore *obj) { CamelStore *store = (CamelStore *)obj; - /* we dont want a vtrash on this one */ - store->flags &= ~(CAMEL_STORE_VTRASH); + /* we dont want a vtrash/vjunk on this one */ + store->flags &= ~(CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK); } static void @@ -183,6 +187,19 @@ vee_get_trash (CamelStore *store, CamelException *ex) return NULL; } +static void +vee_init_junk (CamelStore *store) +{ + /* no-op */ + ; +} + +static CamelFolder * +vee_get_junk (CamelStore *store, CamelException *ex) +{ + return NULL; +} + static CamelFolderInfo * vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex) { @@ -268,6 +285,8 @@ vee_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex if (store->vtrash) camel_vee_folder_remove_folder((CamelVeeFolder *)store->vtrash, folder); + if (store->vjunk) + camel_vee_folder_remove_folder((CamelVeeFolder *)store->vjunk, folder); if ((((CamelVeeFolder *)folder)->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) { /* what about now-empty parents? ignore? */ diff --git a/camel/camel-vtrash-folder.h b/camel/camel-vtrash-folder.h index f0441c4c82..089c969e71 100644 --- a/camel/camel-vtrash-folder.h +++ b/camel/camel-vtrash-folder.h @@ -33,6 +33,7 @@ extern "C" { #include <camel/camel-vee-folder.h> #define CAMEL_VTRASH_NAME "Trash" +#define CAMEL_VJUNK_NAME "Junk" #define CAMEL_VTRASH_FOLDER(obj) CAMEL_CHECK_CAST (obj, camel_vtrash_folder_get_type (), CamelVTrashFolder) #define CAMEL_VTRASH_FOLDER_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vtrash_folder_get_type (), CamelVTrashFolderClass) |