aboutsummaryrefslogtreecommitdiffstats
path: root/filter
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2008-01-10 19:19:37 +0800
committerMilan Crha <mcrha@src.gnome.org>2008-01-10 19:19:37 +0800
commitdd7bad07415b4b2a46d3bae6236838d52334f6fb (patch)
tree9a64bb9cd03b79fafe14ef7f8eee2399675fdd51 /filter
parent510eb1f01695c5d92df90bb3a2d2fbbc2bec8f40 (diff)
downloadgsoc2013-evolution-dd7bad07415b4b2a46d3bae6236838d52334f6fb.tar.gz
gsoc2013-evolution-dd7bad07415b4b2a46d3bae6236838d52334f6fb.tar.zst
gsoc2013-evolution-dd7bad07415b4b2a46d3bae6236838d52334f6fb.zip
** Fix for bug #211353
2008-01-10 Milan Crha <mcrha@redhat.com> ** Fix for bug #211353 * po/POTFILES.in: Added new file e-util/e-util-labels.c * mail/filtertypes.xml: * mail/vfoldertypes.xml: * mail/em-folder-view.c: * mail/em-folder-browser.c: * mail/em-mailer-prefs.h: * mail/em-mailer-prefs.c: * mail/mail-config.h: * mail/mail-config.c: * mail/mail-config.glade: * mail/message-list.c: Label tags are now generated based on label name when creating, except of first 5 labels. New menu option "New Label" in popup menu over message list and editing of labels has been changed in Preferences. Also renaming tab in Preferences for "Labels", not "Colors", and the tab label too. mail-config-label... functions was moved to e-util/e-util-labels.c/.h. * mail/message-list.etspec: Normalized columns has been moved by one when label column has been added. * filter/filter-option.h: * filter/filter-option.c: (filter_option_get_current), (filter_option_remove_all): New functions to be able to refill options even after initialization of the filter element. * filter/filter-label.c: Added support to notify changes on labels in runtime and use actual labels. * e-util/Makefile.am: * e-util/e-util-labels.h: * e-util/e-util-labels.c: New files to work with labels. svn path=/trunk/; revision=34788
Diffstat (limited to 'filter')
-rw-r--r--filter/ChangeLog11
-rw-r--r--filter/filter-label.c217
-rw-r--r--filter/filter-option.c23
-rw-r--r--filter/filter-option.h3
4 files changed, 208 insertions, 46 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog
index 95e18e332b..cff5724f0a 100644
--- a/filter/ChangeLog
+++ b/filter/ChangeLog
@@ -1,3 +1,14 @@
+2008-01-10 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #211353
+
+ * filter-option.h:
+ * filter-option.c: (filter_option_get_current),
+ (filter_option_remove_all): New functions to be able to refill options
+ even after initialization of the filter element.
+ * filter-label.c: Added support to notify changes on labels in runtime
+ and use actual labels.
+
2007-12-17 Srinivasa Ragavan <sragavan@novell.com>
* filter-label.c: (filter_label_count), (filter_label_label),
diff --git a/filter/filter-label.c b/filter/filter-label.c
index ca0ae005fe..d2d67baecd 100644
--- a/filter/filter-label.c
+++ b/filter/filter-label.c
@@ -38,6 +38,7 @@
#include "filter-label.h"
#include <libedataserver/e-sexp.h>
#include "e-util/e-util.h"
+#include "e-util/e-util-labels.h"
#define d(x)
@@ -47,10 +48,8 @@ static void filter_label_class_init (FilterLabelClass *klass);
static void filter_label_init (FilterLabel *label);
static void filter_label_finalise (GObject *obj);
-
static FilterElementClass *parent_class;
-
GType
filter_label_get_type (void)
{
@@ -75,6 +74,16 @@ filter_label_get_type (void)
return type;
}
+static GStaticMutex cache_lock = G_STATIC_MUTEX_INIT;
+static guint cache_notifier_id = 0;
+static GSList *tracked_filters = NULL;
+static GSList *labels_cache = NULL;
+static GConfClient *gconf_client = NULL;
+
+static void fill_cache (void);
+static void clear_cache (void);
+static void gconf_labels_changed (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data);
+
static void
filter_label_class_init (FilterLabelClass *klass)
{
@@ -93,12 +102,43 @@ static void
filter_label_init (FilterLabel *fl)
{
((FilterOption *) fl)->type = "label";
+
+ g_static_mutex_lock (&cache_lock);
+
+ if (!tracked_filters) {
+ fill_cache ();
+
+ gconf_client = gconf_client_get_default ();
+ gconf_client_add_dir (gconf_client, E_UTIL_LABELS_GCONF_KEY, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+ cache_notifier_id = gconf_client_notify_add (gconf_client, E_UTIL_LABELS_GCONF_KEY, gconf_labels_changed, NULL, NULL, NULL);
+ }
+
+ tracked_filters = g_slist_prepend (tracked_filters, fl);
+
+ g_static_mutex_unlock (&cache_lock);
}
static void
filter_label_finalise (GObject *obj)
{
G_OBJECT_CLASS (parent_class)->finalize (obj);
+
+ g_static_mutex_lock (&cache_lock);
+
+ tracked_filters = g_slist_remove (tracked_filters, obj);
+
+ if (!tracked_filters) {
+ clear_cache ();
+
+ if (cache_notifier_id)
+ gconf_client_notify_remove (gconf_client, cache_notifier_id);
+
+ cache_notifier_id = 0;
+ g_object_unref (gconf_client);
+ gconf_client = NULL;
+ }
+
+ g_static_mutex_unlock (&cache_lock);
}
/**
@@ -114,72 +154,157 @@ filter_label_new (void)
return (FilterLabel *) g_object_new (FILTER_TYPE_LABEL, NULL, NULL);
}
-static struct {
- char *title;
- char *value;
-} labels[] = {
- { N_("Important"), "important" },
- { N_("Work"), "work" },
- { N_("Personal"), "personal" },
- { N_("To Do"), "todo" },
- { N_("Later"), "later" },
-};
-
-int filter_label_count (void)
+/* ************************************************************************* */
+
+/* should already hold the lock when calling this function */
+static void
+fill_cache (void)
+{
+ labels_cache = e_util_labels_parse (NULL);
+}
+
+/* should already hold the lock when calling this function */
+static void
+clear_cache (void)
+{
+ e_util_labels_free (labels_cache);
+ labels_cache = NULL;
+}
+
+static void
+fill_options (FilterOption *fo)
+{
+ GSList *l;
+
+ g_static_mutex_lock (&cache_lock);
+
+ for (l = labels_cache; l; l = l->next) {
+ EUtilLabel *label = l->data;
+ const char *tag;
+ char *title;
+
+ if (!label)
+ continue;
+
+ title = e_str_without_underscores (label->name);
+ tag = label->tag;
+
+ if (tag && strncmp (tag, "$Label", 6) == 0)
+ tag += 6;
+
+ filter_option_add (fo, tag, title, NULL);
+
+ g_free (title);
+ }
+
+ g_static_mutex_unlock (&cache_lock);
+}
+
+static void
+regen_label_options (FilterOption *fo)
+{
+ char *current;
+
+ if (!fo)
+ return;
+
+ current = g_strdup (filter_option_get_current (fo));
+
+ filter_option_remove_all (fo);
+ fill_options (fo);
+
+ if (current)
+ filter_option_set_current (fo, current);
+
+ g_free (current);
+}
+
+static void
+gconf_labels_changed (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data)
+{
+ g_static_mutex_lock (&cache_lock);
+ clear_cache ();
+ fill_cache ();
+ g_static_mutex_unlock (&cache_lock);
+
+ g_slist_foreach (tracked_filters, (GFunc)regen_label_options, NULL);
+}
+
+/* ************************************************************************* */
+
+int
+filter_label_count (void)
{
- return sizeof (labels) / sizeof (labels[0]);
+ int res;
+
+ g_static_mutex_lock (&cache_lock);
+
+ res = g_slist_length (labels_cache);
+
+ g_static_mutex_unlock (&cache_lock);
+
+ return res;
}
const char *
filter_label_label (int i)
{
- if (i < 0 || i >= sizeof (labels) / sizeof (labels[0]))
- return NULL;
+ const char *res = NULL;
+ GSList *l;
+ EUtilLabel *label;
+
+ g_static_mutex_lock (&cache_lock);
+
+ l = g_slist_nth (labels_cache, i);
+
+ if (l)
+ label = l->data;
else
- return labels[i].value;
+ label = NULL;
+
+ if (label && label->tag) {
+ if (strncmp (label->tag, "$Label", 6) == 0)
+ res = label->tag + 6;
+ else
+ res = label->tag;
+ }
+
+ g_static_mutex_unlock (&cache_lock);
+
+ return res;
}
int
filter_label_index (const char *label)
{
int i;
+ GSList *l;
+
+ g_static_mutex_lock (&cache_lock);
+
+ for (i = 0, l = labels_cache; l; i++, l = l->next) {
+ EUtilLabel *lbl = l->data;
+ const char *tag = lbl->tag;
- for (i = 0; i < sizeof (labels) / sizeof (labels[0]); i++) {
- if (strcmp (labels[i].value, label) == 0)
- return i;
+ if (tag && strncmp (tag, "$Label", 6) == 0)
+ tag += 6;
+
+ if (tag && strcmp (tag, label) == 0)
+ break;
}
+ g_static_mutex_unlock (&cache_lock);
+
+ if (l)
+ return i;
+
return -1;
}
static void
xml_create (FilterElement *fe, xmlNodePtr node)
{
- FilterOption *fo = (FilterOption *) fe;
- GConfClient *gconf;
- GSList *list, *l;
- char *title, *p, *nounderscores_title;
- int i = 0;
-
FILTER_ELEMENT_CLASS (parent_class)->xml_create (fe, node);
- gconf = gconf_client_get_default ();
-
- l = list = gconf_client_get_list (gconf, "/apps/evolution/mail/labels", GCONF_VALUE_STRING, NULL);
- while (l != NULL) {
- title = (char *) l->data;
- if ((p = strrchr (title, ':')))
- *p++ = '\0';
-
- nounderscores_title = e_str_without_underscores (title);
-
- filter_option_add (fo, i < 5 ? labels[i++].value : (p ? p : "#ffffff"), nounderscores_title, NULL);
- g_free (title);
- g_free (nounderscores_title);
-
- l = l->next;
- }
- g_slist_free (list);
-
- g_object_unref (gconf);
+ fill_options ((FilterOption *) fe);
}
diff --git a/filter/filter-option.c b/filter/filter-option.c
index 2aea362bbc..f56943f22c 100644
--- a/filter/filter-option.c
+++ b/filter/filter-option.c
@@ -183,6 +183,29 @@ filter_option_add(FilterOption *fo, const char *value, const char *title, const
return op;
}
+const char *
+filter_option_get_current (FilterOption *option)
+{
+ g_return_val_if_fail (IS_FILTER_OPTION (option), NULL);
+
+ if (!option->current)
+ return NULL;
+
+ return option->current->value;
+}
+
+void
+filter_option_remove_all (FilterOption *fo)
+{
+ g_return_if_fail (IS_FILTER_OPTION (fo));
+
+ g_list_foreach (fo->options, (GFunc)free_option, NULL);
+ g_list_free (fo->options);
+ fo->options = NULL;
+
+ fo->current = NULL;
+}
+
static int
option_eq(FilterElement *fe, FilterElement *cm)
{
diff --git a/filter/filter-option.h b/filter/filter-option.h
index 58f984d8e4..a7a36151e0 100644
--- a/filter/filter-option.h
+++ b/filter/filter-option.h
@@ -64,6 +64,9 @@ FilterOption *filter_option_new (void);
/* methods */
void filter_option_set_current (FilterOption *option, const char *name);
+const char *filter_option_get_current (FilterOption *option);
+
struct _filter_option *filter_option_add (FilterOption *fo, const char *name, const char *title, const char *code);
+void filter_option_remove_all (FilterOption *fo);
#endif /* ! _FILTER_OPTION_H */