aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-06-02 01:40:19 +0800
committerMatthew Barnes <mbarnes@redhat.com>2011-06-02 01:44:50 +0800
commita81d49be2f6e6a9cf08734ae8b5a47ef46723e80 (patch)
tree56f05a9a77fa788056ba4a38be5153c2d70688d4
parentefb9a4b7e1d7fa8834be8bfb165cb5b779b555b3 (diff)
downloadgsoc2013-evolution-a81d49be2f6e6a9cf08734ae8b5a47ef46723e80.tar.gz
gsoc2013-evolution-a81d49be2f6e6a9cf08734ae8b5a47ef46723e80.tar.zst
gsoc2013-evolution-a81d49be2f6e6a9cf08734ae8b5a47ef46723e80.zip
EMVFolderRule: Track folder URIs in a GQueue instead of GList.
Makes the logic a little cleaner. Do this also in mail-vfolder.c.
-rw-r--r--mail/em-vfolder-rule.c106
-rw-r--r--mail/em-vfolder-rule.h2
-rw-r--r--mail/mail-vfolder.c84
3 files changed, 97 insertions, 95 deletions
diff --git a/mail/em-vfolder-rule.c b/mail/em-vfolder-rule.c
index c458cc7648..2f9cc9d9f0 100644
--- a/mail/em-vfolder-rule.c
+++ b/mail/em-vfolder-rule.c
@@ -145,9 +145,10 @@ static void
vfolder_rule_finalize (GObject *object)
{
EMVFolderRule *rule = EM_VFOLDER_RULE (object);
+ gchar *uri;
- g_list_foreach (rule->sources, (GFunc) g_free, NULL);
- g_list_free (rule->sources);
+ while ((uri = g_queue_pop_head (&rule->sources)) != NULL)
+ g_free (uri);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (em_vfolder_rule_parent_class)->finalize (object);
@@ -221,7 +222,7 @@ em_vfolder_rule_add_source (EMVFolderRule *rule,
g_return_if_fail (EM_IS_VFOLDER_RULE (rule));
g_return_if_fail (uri);
- rule->sources = g_list_append (rule->sources, g_strdup (uri));
+ g_queue_push_tail (&rule->sources, g_strdup (uri));
e_filter_rule_emit_changed (E_FILTER_RULE (rule));
}
@@ -230,20 +231,16 @@ const gchar *
em_vfolder_rule_find_source (EMVFolderRule *rule,
const gchar *uri)
{
- GList *l;
+ GList *link;
g_return_val_if_fail (EM_IS_VFOLDER_RULE (rule), NULL);
/* only does a simple string or address comparison, should
probably do a decoded url comparison */
- l = rule->sources;
- while (l) {
- if (l->data == uri || !strcmp (l->data, uri))
- return l->data;
- l = l->next;
- }
+ link = g_queue_find_custom (
+ &rule->sources, uri, (GCompareFunc) strcmp);
- return NULL;
+ return (link != NULL) ? link->data : NULL;
}
void
@@ -255,8 +252,8 @@ em_vfolder_rule_remove_source (EMVFolderRule *rule,
g_return_if_fail (EM_IS_VFOLDER_RULE (rule));
found =(gchar *) em_vfolder_rule_find_source (rule, uri);
- if (found) {
- rule->sources = g_list_remove (rule->sources, found);
+ if (found != NULL) {
+ g_queue_remove (&rule->sources, found);
g_free (found);
e_filter_rule_emit_changed (E_FILTER_RULE (rule));
}
@@ -266,22 +263,19 @@ const gchar *
em_vfolder_rule_next_source (EMVFolderRule *rule,
const gchar *last)
{
- GList *node;
+ GList *link;
if (last == NULL) {
- node = rule->sources;
+ link = g_queue_peek_head_link (&rule->sources);
} else {
- node = g_list_find (rule->sources, (gchar *) last);
- if (node == NULL)
- node = rule->sources;
+ link = g_queue_find (&rule->sources, last);
+ if (link == NULL)
+ link = g_queue_peek_head_link (&rule->sources);
else
- node = g_list_next (node);
+ link = g_list_next (link);
}
- if (node)
- return (const gchar *) node->data;
-
- return NULL;
+ return (link != NULL) ? link->data : NULL;
}
static gint
@@ -299,7 +293,7 @@ validate (EFilterRule *fr, EAlert **alert)
/* We have to have at least one source set in the "specific" case.
Do not translate this string! */
if (((EMVFolderRule *) fr)->with == EM_VFOLDER_RULE_WITH_SPECIFIC &&
- ((EMVFolderRule *) fr)->sources == NULL) {
+ g_queue_is_empty (&((EMVFolderRule *) fr)->sources)) {
if (alert)
*alert = e_alert_new ("mail:vfolder-no-source", NULL);
return 0;
@@ -309,26 +303,35 @@ validate (EFilterRule *fr, EAlert **alert)
}
static gint
-list_eq (GList *al, GList *bl)
+queue_eq (GQueue *queue_a, GQueue *queue_b)
{
+ GList *link_a;
+ GList *link_b;
gint truth = TRUE;
- while (truth && al && bl) {
- gchar *a = al->data, *b = bl->data;
+ link_a = g_queue_peek_head_link (queue_a);
+ link_b = g_queue_peek_head_link (queue_b);
+
+ while (truth && link_a != NULL && link_b != NULL) {
+ gchar *uri_a = link_a->data;
+ gchar *uri_b = link_b->data;
+
+ truth = (strcmp (uri_a, uri_b)== 0);
- truth = strcmp (a, b)== 0;
- al = al->next;
- bl = bl->next;
+ link_a = g_list_next (link_a);
+ link_b = g_list_next (link_b);
}
- return truth && al == NULL && bl == NULL;
+ return truth && link_a == NULL && link_b == NULL;
}
static gint
vfolder_eq (EFilterRule *fr, EFilterRule *cm)
{
return E_FILTER_RULE_CLASS (em_vfolder_rule_parent_class)->eq (fr, cm)
- && list_eq (((EMVFolderRule *) fr)->sources, ((EMVFolderRule *) cm)->sources);
+ && queue_eq (
+ &((EMVFolderRule *) fr)->sources,
+ &((EMVFolderRule *) cm)->sources);
}
static xmlNodePtr
@@ -336,7 +339,7 @@ xml_encode (EFilterRule *fr)
{
EMVFolderRule *vr =(EMVFolderRule *) fr;
xmlNodePtr node, set, work;
- GList *l;
+ GList *head, *link;
node = E_FILTER_RULE_CLASS (em_vfolder_rule_parent_class)->xml_encode (fr);
g_return_val_if_fail (node != NULL, NULL);
@@ -345,12 +348,14 @@ xml_encode (EFilterRule *fr)
set = xmlNewNode(NULL, (const guchar *)"sources");
xmlAddChild (node, set);
xmlSetProp(set, (const guchar *)"with", (guchar *)with_names[vr->with]);
- l = vr->sources;
- while (l) {
- work = xmlNewNode(NULL, (const guchar *)"folder");
- xmlSetProp(work, (const guchar *)"uri", (guchar *)l->data);
+
+ head = g_queue_peek_head_link (&vr->sources);
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ const gchar *uri = link->data;
+
+ work = xmlNewNode (NULL, (const guchar *) "folder");
+ xmlSetProp (work, (const guchar *) "uri", (guchar *) uri);
xmlAddChild (set, work);
- l = l->next;
}
return node;
@@ -404,7 +409,7 @@ xml_decode (EFilterRule *fr, xmlNodePtr node, struct _ERuleContext *f)
if (!strcmp((gchar *)work->name, "folder")) {
tmp = (gchar *)xmlGetProp(work, (const guchar *)"uri");
if (tmp) {
- vr->sources = g_list_append (vr->sources, g_strdup (tmp));
+ g_queue_push_tail (&vr->sources, g_strdup (tmp));
xmlFree (tmp);
}
}
@@ -420,23 +425,19 @@ static void
rule_copy (EFilterRule *dest, EFilterRule *src)
{
EMVFolderRule *vdest, *vsrc;
- GList *node;
+ GList *head, *link;
+ gchar *uri;
vdest =(EMVFolderRule *) dest;
vsrc =(EMVFolderRule *) src;
- if (vdest->sources) {
- g_list_foreach (vdest->sources, (GFunc) g_free, NULL);
- g_list_free (vdest->sources);
- vdest->sources = NULL;
- }
-
- node = vsrc->sources;
- while (node) {
- gchar *uri = node->data;
+ while ((uri = g_queue_pop_head (&vdest->sources)) != NULL)
+ g_free (uri);
- vdest->sources = g_list_append (vdest->sources, g_strdup (uri));
- node = node->next;
+ head = g_queue_peek_head_link (&vsrc->sources);
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ const gchar *uri = link->data;
+ g_queue_push_tail (&vdest->sources, g_strdup (uri));
}
vdest->with = vsrc->with;
@@ -569,8 +570,7 @@ vfr_folder_response (EMFolderSelector *selector,
GtkTreeSelection *selection;
GtkTreeIter iter;
- data->vr->sources = g_list_append (
- data->vr->sources, g_strdup (uri));
+ g_queue_push_tail (&data->vr->sources, g_strdup (uri));
gtk_list_store_append (data->model, &iter);
urinice = format_source (uri);
diff --git a/mail/em-vfolder-rule.h b/mail/em-vfolder-rule.h
index fa6df8576e..ccbcbb10fe 100644
--- a/mail/em-vfolder-rule.h
+++ b/mail/em-vfolder-rule.h
@@ -67,7 +67,7 @@ struct _EMVFolderRule {
EMVFolderRulePrivate *priv;
em_vfolder_rule_with_t with;
- GList *sources; /* uri's of the source folders */
+ GQueue sources; /* uri's of the source folders */
};
struct _EMVFolderRuleClass {
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index c8e7babf5d..20c420a4f4 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -60,8 +60,12 @@ CamelStore *vfolder_store; /* the 1 static vfolder store */
/* lock for accessing shared resources (below) */
G_LOCK_DEFINE_STATIC (vfolder);
-static GList *source_folders_remote; /* list of source folder uri's - remote ones */
-static GList *source_folders_local; /* list of source folder uri's - local ones */
+/* list of source folder uri's - remote ones */
+static GQueue source_folders_remote = G_QUEUE_INIT;
+
+/* list of source folder uri's - local ones */
+static GQueue source_folders_local = G_QUEUE_INIT;
+
static GHashTable *vfolder_hash;
/* This is a slightly hacky solution to shutting down, we poll this variable in various
loops, and just quit processing if it is set. */
@@ -328,16 +332,21 @@ vfolder_adduri (EMailSession *session,
/* ********************************************************************** */
static GList *
-mv_find_folder (GList *l, EMailSession *session, const gchar *uri)
+mv_find_folder (GQueue *queue,
+ EMailSession *session,
+ const gchar *uri)
{
CamelSession *camel_session = CAMEL_SESSION (session);
+ GList *head, *link;
- while (l) {
- if (e_mail_folder_uri_equal (camel_session, l->data, uri))
+ head = g_queue_peek_head_link (queue);
+
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ if (e_mail_folder_uri_equal (camel_session, link->data, uri))
break;
- l = l->next;
}
- return l;
+
+ return link;
}
static gint
@@ -444,6 +453,7 @@ mail_vfolder_add_folder (EMailBackend *backend,
CamelVeeFolder *vf;
CamelProvider *provider;
GList *folders = NULL, *link;
+ GQueue *queue;
gint remote;
gint is_ignore;
gchar *uri;
@@ -452,6 +462,7 @@ mail_vfolder_add_folder (EMailBackend *backend,
provider = camel_service_get_provider (CAMEL_SERVICE (store));
remote = (provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0;
+ queue = remote ? &source_folders_remote : &source_folders_local;
if (folder_is_spethal (store, folder_name))
return;
@@ -468,30 +479,15 @@ mail_vfolder_add_folder (EMailBackend *backend,
if (CAMEL_IS_VEE_STORE (store)) {
is_ignore = TRUE;
} else if (remove) {
- if (remote) {
- if ((link = mv_find_folder (source_folders_remote, session, uri)) != NULL) {
- g_free (link->data);
- source_folders_remote = g_list_remove_link (
- source_folders_remote, link);
- }
- } else {
- if ((link = mv_find_folder (source_folders_local, session, uri)) != NULL) {
- g_free (link->data);
- source_folders_local = g_list_remove_link (
- source_folders_local, link);
- }
+ link = mv_find_folder (queue, session, uri);
+ if (link != NULL) {
+ g_free (link->data);
+ g_queue_delete_link (queue, link);
}
} else if (!is_ignore) {
/* we ignore drafts/sent/outbox here */
- if (remote) {
- if (mv_find_folder (source_folders_remote, session, uri) == NULL)
- source_folders_remote = g_list_prepend (
- source_folders_remote, g_strdup (uri));
- } else {
- if (mv_find_folder (source_folders_local, session, uri) == NULL)
- source_folders_local = g_list_prepend (
- source_folders_local, g_strdup (uri));
- }
+ if (mv_find_folder (queue, session, uri) == NULL)
+ g_queue_push_tail (queue, g_strdup (uri));
}
if (context == NULL)
@@ -572,6 +568,7 @@ mail_vfolder_delete_folder (EMailBackend *backend,
const gchar *source;
CamelVeeFolder *vf;
GString *changed;
+ GQueue *queue;
guint changed_count;
gchar *uri;
GList *link;
@@ -639,14 +636,18 @@ mail_vfolder_delete_folder (EMailBackend *backend,
}
done:
- if ((link = mv_find_folder (source_folders_remote, session, uri)) != NULL) {
+ queue = &source_folders_remote;
+ link = mv_find_folder (queue, session, uri);
+ if (link != NULL) {
g_free (link->data);
- source_folders_remote = g_list_remove_link (source_folders_remote, link);
+ g_queue_delete_link (queue, link);
}
- if ((link = mv_find_folder (source_folders_local, session, uri)) != NULL) {
+ queue = &source_folders_local;
+ link = mv_find_folder (queue, session, uri);
+ if (link != NULL) {
g_free (link->data);
- source_folders_local = g_list_remove_link (source_folders_local, link);
+ g_queue_delete_link (queue, link);
}
G_UNLOCK (vfolder);
@@ -761,13 +762,13 @@ mail_vfolder_rename_folder (CamelStore *store,
GList *
mail_vfolder_get_sources_local (void)
{
- return source_folders_local;
+ return g_queue_peek_head_link (&source_folders_local);
}
GList *
mail_vfolder_get_sources_remote (void)
{
- return source_folders_remote;
+ return g_queue_peek_head_link (&source_folders_remote);
}
/* ********************************************************************** */
@@ -776,7 +777,7 @@ static void context_rule_added (ERuleContext *ctx, EFilterRule *rule);
static void
rule_add_sources (EMailSession *session,
- GList *l,
+ GQueue *queue,
GList **sources_folderp,
GList **sources_urip)
{
@@ -784,11 +785,13 @@ rule_add_sources (EMailSession *session,
GList *sources_uri = *sources_urip;
MailFolderCache *folder_cache;
CamelFolder *newfolder;
+ GList *head, *link;
folder_cache = e_mail_session_get_folder_cache (session);
- while (l) {
- const gchar *uri = l->data;
+ head = g_queue_peek_head_link (queue);
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ const gchar *uri = link->data;
if (mail_folder_cache_get_folder_from_uri (
folder_cache, uri, &newfolder)) {
@@ -799,7 +802,6 @@ rule_add_sources (EMailSession *session,
sources_uri = g_list_append (
sources_uri, g_strdup (uri));
}
- l = l->next;
}
*sources_folderp = sources_folder;
@@ -849,7 +851,7 @@ rule_changed (EFilterRule *rule, CamelFolder *folder)
/* find any (currently available) folders, and add them to the ones to open */
rule_add_sources (
- session, ((EMVFolderRule *) rule)->sources,
+ session, &((EMVFolderRule *) rule)->sources,
&sources_folder, &sources_uri);
G_LOCK (vfolder);
@@ -858,14 +860,14 @@ rule_changed (EFilterRule *rule, CamelFolder *folder)
((EMVFolderRule *) rule)->with ==
EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE)
rule_add_sources (
- session, source_folders_local,
+ session, &source_folders_local,
&sources_folder, &sources_uri);
if (((EMVFolderRule *) rule)->with ==
EM_VFOLDER_RULE_WITH_REMOTE_ACTIVE ||
((EMVFolderRule *) rule)->with ==
EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE)
rule_add_sources (
- session, source_folders_remote,
+ session, &source_folders_remote,
&sources_folder, &sources_uri);
G_UNLOCK (vfolder);