aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/Makefile.am4
-rw-r--r--camel/camel-digest-store.c21
-rw-r--r--camel/camel-filter-driver.c23
-rw-r--r--camel/camel-filter-search.c25
-rw-r--r--camel/camel-folder-summary.c1
-rw-r--r--camel/camel-folder-summary.h1
-rw-r--r--camel/camel-folder.c16
-rw-r--r--camel/camel-folder.h1
-rw-r--r--camel/camel-junk-plugin.c75
-rw-r--r--camel/camel-junk-plugin.h59
-rw-r--r--camel/camel-session.h3
-rw-r--r--camel/camel-store.c152
-rw-r--r--camel/camel-store.h7
-rw-r--r--camel/camel-vee-store.c23
-rw-r--r--camel/camel-vtrash-folder.h1
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)