aboutsummaryrefslogtreecommitdiffstats
path: root/filter/filter-label.c
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/filter-label.c
parent510eb1f01695c5d92df90bb3a2d2fbbc2bec8f40 (diff)
downloadgsoc2013-evolution-dd7bad07415b4b2a46d3bae6236838d52334f6fb.tar
gsoc2013-evolution-dd7bad07415b4b2a46d3bae6236838d52334f6fb.tar.gz
gsoc2013-evolution-dd7bad07415b4b2a46d3bae6236838d52334f6fb.tar.bz2
gsoc2013-evolution-dd7bad07415b4b2a46d3bae6236838d52334f6fb.tar.lz
gsoc2013-evolution-dd7bad07415b4b2a46d3bae6236838d52334f6fb.tar.xz
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/filter-label.c')
-rw-r--r--filter/filter-label.c217
1 files changed, 171 insertions, 46 deletions
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);
}