diff options
author | Milan Crha <mcrha@redhat.com> | 2008-01-10 19:19:37 +0800 |
---|---|---|
committer | Milan Crha <mcrha@src.gnome.org> | 2008-01-10 19:19:37 +0800 |
commit | dd7bad07415b4b2a46d3bae6236838d52334f6fb (patch) | |
tree | 9a64bb9cd03b79fafe14ef7f8eee2399675fdd51 | |
parent | 510eb1f01695c5d92df90bb3a2d2fbbc2bec8f40 (diff) | |
download | gsoc2013-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
-rw-r--r-- | e-util/ChangeLog | 8 | ||||
-rw-r--r-- | e-util/Makefile.am | 2 | ||||
-rw-r--r-- | e-util/e-util-labels.c | 551 | ||||
-rw-r--r-- | e-util/e-util-labels.h | 57 | ||||
-rw-r--r-- | filter/ChangeLog | 11 | ||||
-rw-r--r-- | filter/filter-label.c | 217 | ||||
-rw-r--r-- | filter/filter-option.c | 23 | ||||
-rw-r--r-- | filter/filter-option.h | 3 | ||||
-rw-r--r-- | mail/ChangeLog | 23 | ||||
-rw-r--r-- | mail/em-filter-i18n.h | 6 | ||||
-rw-r--r-- | mail/em-folder-browser.c | 29 | ||||
-rw-r--r-- | mail/em-folder-view.c | 25 | ||||
-rw-r--r-- | mail/em-mailer-prefs.c | 229 | ||||
-rw-r--r-- | mail/em-mailer-prefs.h | 3 | ||||
-rw-r--r-- | mail/filtertypes.xml | 4 | ||||
-rw-r--r-- | mail/mail-config.c | 428 | ||||
-rw-r--r-- | mail/mail-config.glade | 78 | ||||
-rw-r--r-- | mail/mail-config.h | 22 | ||||
-rw-r--r-- | mail/message-list.c | 25 | ||||
-rw-r--r-- | mail/message-list.etspec | 6 | ||||
-rw-r--r-- | mail/vfoldertypes.xml | 4 | ||||
-rw-r--r-- | po/ChangeLog | 4 | ||||
-rw-r--r-- | po/POTFILES.in | 1 |
23 files changed, 1047 insertions, 712 deletions
diff --git a/e-util/ChangeLog b/e-util/ChangeLog index 917525d8dd..335bdf1d13 100644 --- a/e-util/ChangeLog +++ b/e-util/ChangeLog @@ -1,3 +1,11 @@ +2008-01-10 Milan Crha <mcrha@redhat.com> + + ** Fix for bug #211353 + + * Makefile.am: + * e-util-labels.h: + * e-util-labels.c: New files to work with labels. + 2008-01-07 Milan Crha <mcrha@redhat.com> ** Fix for bug #507363 diff --git a/e-util/Makefile.am b/e-util/Makefile.am index 3031358452..3677d841d4 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -73,6 +73,7 @@ eutilinclude_HEADERS = \ e-text-event-processor-types.h \ e-text-event-processor.h \ e-util.h \ + e-util-labels.h \ e-util-marshal.h \ e-xml-utils.h @@ -111,6 +112,7 @@ libeutil_la_SOURCES = \ e-text-event-processor-emacs-like.c \ e-text-event-processor.c \ e-util.c \ + e-util-labels.c \ e-util-private.h \ e-xml-utils.c \ $(PLATFORM_SOURCES) diff --git a/e-util/e-util-labels.c b/e-util/e-util-labels.c new file mode 100644 index 0000000000..85225a93a5 --- /dev/null +++ b/e-util/e-util-labels.c @@ -0,0 +1,551 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* e-util-labels.c + * + * Copyright (C) 2007 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <glib/gi18n.h> + +#include <stdio.h> +#include <string.h> + +#include <gconf/gconf-client.h> + +#include <gtk/gtkbox.h> +#include <gtk/gtkcolorbutton.h> +#include <gtk/gtkdialog.h> +#include <gtk/gtkentry.h> +#include <gtk/gtklabel.h> +#include <gtk/gtkstock.h> +#include <gtk/gtktable.h> + +#include <camel/camel-utf8.h> + +#include "e-util-labels.h" +#include "e-dialog-utils.h" + +/* Note, the first element of each EUtilLabel must NOT be translated */ +EUtilLabel label_defaults[LABEL_DEFAULTS_NUM] = { + { "$Labelimportant", N_("I_mportant"), "#EF2929" }, /* red */ + { "$Labelwork", N_("_Work"), "#F57900" }, /* orange */ + { "$Labelpersonal", N_("_Personal"), "#4E9A06" }, /* green */ + { "$Labeltodo", N_("_To Do"), "#3465A4" }, /* blue */ + { "$Labellater", N_("_Later"), "#75507B" } /* purple */ +}; + +/** + * e_util_labels_parse + * Reads the setup from client and parses it to list of EUtilLabel objects. + * + * @param client The config client to be used for reading setup. + * Can be NULL, in that case it will use the default client. + * @return Newly allocated list of labels, should be freed with @ref e_util_labels_free. + **/ +GSList * +e_util_labels_parse (GConfClient *client) +{ + GSList *labels, *list, *head; + EUtilLabel *label; + char *buf; + int num = 0; + gboolean unref_client = client == NULL; + + labels = NULL; + + if (!client) + client = gconf_client_get_default (); + + head = gconf_client_get_list (client, E_UTIL_LABELS_GCONF_KEY, GCONF_VALUE_STRING, NULL); + + for (list = head; list; list = list->next) { + char *color, *name, *tag; + name = buf = list->data; + color = strrchr (buf, ':'); + + *color++ = '\0'; + tag = strchr (color, '|'); + if (tag) + *tag++ = '\0'; + + label = g_new (EUtilLabel, 1); + + /* Needed for Backward Compatibility */ + if (num < LABEL_DEFAULTS_NUM) { + label->name = g_strdup (_(buf)); + label->tag = g_strdup (label_defaults[num].tag); + num++; + } else if (!tag) { + g_free (buf); + g_free (label); + continue; + } else { + label->name = g_strdup (name); + label->tag = g_strdup (tag); + } + + label->colour = g_strdup (color); + labels = g_slist_prepend (labels, label); + + g_free (buf); + } + + if (head) + g_slist_free (head); + + while (num < LABEL_DEFAULTS_NUM) { + /* complete the list with defaults */ + label = g_new (EUtilLabel, 1); + label->tag = g_strdup (label_defaults[num].tag); + label->name = g_strdup (_(label_defaults[num].name)); + label->colour = g_strdup (label_defaults[num].colour); + + labels = g_slist_prepend (labels, label); + + num++; + } + + if (unref_client) + g_object_unref (client); + + return g_slist_reverse (labels); +} + +static void +free_label_struct (EUtilLabel *label) +{ + if (!label) + return; + + g_free (label->tag); + g_free (label->name); + g_free (label->colour); + g_free (label); +} + +/** + * e_util_labels_free + * Frees memory previously allocated by @ref e_util_labels_parse + * + * @param labels Labels list, previously allocated by @ref e_util_labels_parse + * It is safe to call with NULL. + **/ +void +e_util_labels_free (GSList *labels) +{ + if (!labels) + return; + + g_slist_foreach (labels, (GFunc)free_label_struct, NULL); + g_slist_free (labels); +} + +/* stores the actual cache to gconf */ +static gboolean +flush_labels_cache (GSList *labels, gboolean free_labels) +{ + GSList *l, *text_labels; + GConfClient *client; + + if (!labels) + return FALSE; + + text_labels = NULL; + + for (l = labels; l; l = l->next) { + EUtilLabel *label = l->data; + + if (label && label->tag && label->name && label->colour) + text_labels = g_slist_prepend (text_labels, g_strdup_printf ("%s:%s|%s", label->name, label->colour, label->tag)); + } + + if (!text_labels) { + if (free_labels) + e_util_labels_free (labels); + + return FALSE; + } + + text_labels = g_slist_reverse (text_labels); + + client = gconf_client_get_default (); + gconf_client_set_list (client, E_UTIL_LABELS_GCONF_KEY, GCONF_VALUE_STRING, text_labels, NULL); + g_object_unref (client); + + g_slist_foreach (text_labels, (GFunc)g_free, NULL); + g_slist_free (text_labels); + + if (free_labels) + e_util_labels_free (labels); + + /* not true if gconf failed to write; who cares */ + return TRUE; +} + +/** + * find_label + * + * Looks for label in labels cache by tag and returns actual pointer to cache. + * @param labels The cache of labels; comes from @ref e_util_labels_parse + * @param tag Tag of label you are looking for. + * @return Pointer to cache data if label with such tag exists or NULL. Do not free it! + **/ +static EUtilLabel * +find_label (GSList *labels, const char *tag) +{ + GSList *l; + + g_return_val_if_fail (tag != NULL, NULL); + + for (l = labels; l; l = l->next) { + EUtilLabel *label = l->data; + + if (label && label->tag && !strcmp (tag, label->tag)) + return label; + } + + return NULL; +} + + +static char * +tag_from_name (const char *name) +{ + /* this does thunderbird, just do not ask */ + char *s1, *s2, *p; + const char *bads = " ()/{%*<>\\\""; + + if (!name || !*name) + return NULL; + + s1 = g_strdup (name); + for (p = s1; p && *p; p++) { + if (strchr (bads, *p)) + *p = '_'; + } + + s2 = camel_utf8_utf7 (s1); + g_free (s1); + + s1 = g_ascii_strdown (s2, -1); + g_free (s2); + + return s1; +} + +/** + * e_util_labels_add + * Creates new label at the end of actual list of labels. + * + * @param name User readable name of this label. Should not be NULL. + * @param color Color assigned to this label. Should not be NULL. + * @return If succeeded then new label tag, NULL otherwise. + * Returned pointer should be freed with g_free. + * It will return NULL when the tag will be same as already existed. + * Tag name is generated in similar way as in Thunderbird. + **/ +char * +e_util_labels_add (const char *name, const GdkColor *color) +{ + EUtilLabel *label; + GSList *labels; + char *tag; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (color != NULL, NULL); + + labels = e_util_labels_parse (NULL); + tag = tag_from_name (name); + + if (!tag || find_label (labels, tag) != NULL) { + g_free (tag); + e_util_labels_free (labels); + return NULL; + } + + label = g_new0 (EUtilLabel, 1); + label->tag = g_strdup (tag); + label->name = g_strdup (name); + label->colour = gdk_color_to_string (color); + + labels = g_slist_append (labels, label); + + flush_labels_cache (labels, TRUE); + + return tag; +} + +/** + * e_util_labels_add_with_dlg + * This will open a dialog to add or edit label. + * + * @param parent Parent widget for the dialog. + * @param tag A tag for existing label to edit or NULL to add new label. + * @return Tag for newly added label or NULL, if something failed. + * Returned value should be freed with g_free. + **/ +char * +e_util_labels_add_with_dlg (GtkWindow *parent, const char *tag) +{ + GtkWidget *table, *dialog, *l, *e, *c; + const char *name; + GdkColor color; + gboolean is_edit = FALSE; + char *new_tag = NULL; + GSList *labels; + + table = gtk_table_new (2, 2, FALSE); + + labels = e_util_labels_parse (NULL); + name = tag ? e_util_labels_get_name (labels, tag) : NULL; + + l = gtk_label_new_with_mnemonic (_("Label _Name:")); + e = gtk_entry_new (); + c = gtk_color_button_new (); + + if (!tag || !e_util_labels_get_color (labels, tag, &color)) + memset (&color, 0xCD, sizeof (GdkColor)); + else + is_edit = TRUE; + + if (name) + gtk_entry_set_text (GTK_ENTRY (e), name); + + gtk_label_set_mnemonic_widget (GTK_LABEL (l), e); + gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.0); + gtk_color_button_set_color (GTK_COLOR_BUTTON (c), &color); + + gtk_table_attach (GTK_TABLE (table), l, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), e, 0, 1, 1, 2, 0, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), c, 1, 2, 1, 2, 0, 0, 0, 0); + gtk_container_set_border_width (GTK_CONTAINER (table), 10); + gtk_widget_show_all (table); + + dialog = gtk_dialog_new_with_buttons (is_edit ? _("Edit Label") : _("Add Label"), + parent, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + NULL); + + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0); + + while (!new_tag) { + const char *error = NULL; + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + name = gtk_entry_get_text (GTK_ENTRY (e)); + gtk_color_button_get_color (GTK_COLOR_BUTTON (c), &color); + + if (!name || !*name) + error = _("Label name cannot be empty."); + else if (is_edit) { + e_util_labels_set_data (tag, name, &color); + break; + } else if (!(new_tag = e_util_labels_add (name, &color))) + error = _("Label with same tag already exists. Rename your label please."); + else + break; + } else + break; + + if (error) + e_notice (parent, GTK_MESSAGE_ERROR, error); + } + + gtk_widget_destroy (dialog); + e_util_labels_free (labels); + + return new_tag; +} + +/** + * e_util_labels_remove + * + * @param tag Tag of the label to remove. + * @return Whether was removed. + **/ +gboolean +e_util_labels_remove (const char *tag) +{ + EUtilLabel *label; + GSList *labels; + + g_return_val_if_fail (tag != NULL, FALSE); + + labels = e_util_labels_parse (NULL); + label = find_label (labels, tag); + + if (!label) { + e_util_labels_free (labels); + return FALSE; + } + + labels = g_slist_remove (labels, label); + + free_label_struct (label); + + return flush_labels_cache (labels, TRUE); +} + +/** + * e_util_labels_set_data + * + * @param tag Tag of the label of our interest. + * @param name New name for the label. + * @param color New color for the label. + * @return Whether successfully saved. + **/ +gboolean +e_util_labels_set_data (const char *tag, const char *name, const GdkColor *color) +{ + EUtilLabel *label; + GSList *labels; + + g_return_val_if_fail (tag != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (color != NULL, FALSE); + + labels = e_util_labels_parse (NULL); + label = find_label (labels, tag); + + if (!label) { + e_util_labels_free (labels); + return FALSE; + } + + g_free (label->name); + label->name = g_strdup (name); + + g_free (label->colour); + label->colour = gdk_color_to_string (color); + + return flush_labels_cache (labels, TRUE); +} + +/** + * e_util_labels_is_system + * + * @return Whether the tag is one of default/system labels or not. + **/ +gboolean +e_util_labels_is_system (const char *tag) +{ + int i; + + if (!tag) + return FALSE; + + for (i = 0; i < LABEL_DEFAULTS_NUM; i++) { + if (strcmp (tag, label_defaults[i].tag) == 0) + return TRUE; + } + + return FALSE; +} + +/** + * e_util_labels_get_new_tag + * + * @param old_tag Tag of the label from old version of Evolution. + * @return New tag name equivalent with the old tag, or NULL if no such name existed before. + **/ +const char * +e_util_labels_get_new_tag (const char *old_tag) +{ + int i; + + if (!old_tag) + return NULL; + + for (i = 0; i < LABEL_DEFAULTS_NUM; i++) { + /* default labels have same name as those old, only with prefix "$Label" */ + if (!strcmp (old_tag, label_defaults[i].tag + 6)) + return label_defaults[i].tag; + } + + return NULL; +} + +/** + * e_util_labels_get_name + * + * @param labels Cache of labels from call of @ref e_util_labels_parse. + * The returned pointer will be taken from this list, so it's alive as long as the list. + * @param tag Tag of the label of our interest. + * @return Name of the label with that tag or NULL, if no such label exists. + **/ +const char * +e_util_labels_get_name (GSList *labels, const char *tag) +{ + EUtilLabel *label; + + g_return_val_if_fail (tag != NULL, NULL); + + label = find_label (labels, tag); + if (!label) + return NULL; + + return label->name; +} + +/** + * e_util_labels_get_color + * + * @param labels Cache of labels from call of @ref e_util_labels_parse. + * @param tag Tag of the label of our interest. + * @param color [out] Actual color of the label with that tag, or unchanged if failed. + * @return Whether found such label and color has been set. + **/ +gboolean +e_util_labels_get_color (GSList *labels, const char *tag, GdkColor *color) +{ + EUtilLabel *label; + + g_return_val_if_fail (tag != NULL, FALSE); + g_return_val_if_fail (color != NULL, FALSE); + + label = find_label (labels, tag); + if (!label) + return FALSE; + + return gdk_color_parse (label->colour, color); +} + +/** + * e_util_labels_get_color_str + * + * @param labels Cache of labels from call of @ref e_util_labels_parse. + * The returned pointer will be taken from this list, so it's alive as long as the list. + * @param tag Tag of the label of our interest. + * @return String representation of that label, or NULL, is no such label exists. + **/ +const char * +e_util_labels_get_color_str (GSList *labels, const char *tag) +{ + EUtilLabel *label; + + g_return_val_if_fail (tag != NULL, FALSE); + + label = find_label (labels, tag); + if (!label) + return FALSE; + + return label->colour; +} diff --git a/e-util/e-util-labels.h b/e-util/e-util-labels.h new file mode 100644 index 0000000000..97a49f4db3 --- /dev/null +++ b/e-util/e-util-labels.h @@ -0,0 +1,57 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* e-util-labels.h + * + * Copyright (C) 2007 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _E_UTIL_LABELS_H +#define _E_UTIL_LABELS_H + +#include <glib.h> +#include <gdk/gdkcolor.h> + +struct _GtkWindow; +struct _GConfClient; + +typedef struct { + char *tag; + char *name; + char *colour; +} EUtilLabel; + +#define E_UTIL_LABELS_GCONF_KEY "/apps/evolution/mail/labels" + +#define LABEL_DEFAULTS_NUM 5 +extern EUtilLabel label_defaults[LABEL_DEFAULTS_NUM]; + +GSList * e_util_labels_parse (struct _GConfClient *client); +void e_util_labels_free (GSList *labels); + +char * e_util_labels_add (const char *name, const GdkColor *color); +char * e_util_labels_add_with_dlg (struct _GtkWindow *parent, const char *tag); +gboolean e_util_labels_remove (const char *tag); +gboolean e_util_labels_set_data (const char *tag, const char *name, const GdkColor *color); + +gboolean e_util_labels_is_system (const char *tag); +const char *e_util_labels_get_new_tag (const char *old_tag); + +const char *e_util_labels_get_name (GSList *labels, const char *tag); +gboolean e_util_labels_get_color (GSList *labels, const char *tag, GdkColor *color); +const char *e_util_labels_get_color_str (GSList *labels, const char *tag); + +#endif /* _E_UTIL_LABELS_H */ 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 */ diff --git a/mail/ChangeLog b/mail/ChangeLog index 3315c1b57c..3f50c66c3f 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,26 @@ +2008-01-10 Milan Crha <mcrha@redhat.com> + + ** Fix for bug #211353 + + * filtertypes.xml: + * vfoldertypes.xml: + * em-folder-view.c: + * em-folder-browser.c: + * em-mailer-prefs.h: + * em-mailer-prefs.c: + * mail-config.h: + * mail-config.c: + * mail-config.glade: + * 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. + * message-list.etspec: Normalized columns has been moved by one + when label column has been added. + 2008-01-10 Srinivasa Ragavan <sragavan@novell.com> ** Most of the errors are now non-intrusive diff --git a/mail/em-filter-i18n.h b/mail/em-filter-i18n.h index 7f11882c97..7db8144860 100644 --- a/mail/em-filter-i18n.h +++ b/mail/em-filter-i18n.h @@ -3,7 +3,10 @@ char *s = N_("Adjust Score"); char *s = N_("Assign Color"); char *s = N_("Assign Score"); char *s = N_("Attachments"); +char *s = N_("BCC"); char *s = N_("Beep"); +char *s = N_("CC"); +char *s = N_("Completed On"); char *s = N_("contains"); char *s = N_("Copy to Folder"); char *s = N_("Date received"); @@ -32,6 +35,8 @@ char *s = N_("is greater than"); char *s = N_("is less than"); char *s = N_("is not"); char *s = N_("is not Flagged"); +char *s = N_("is not set"); +char *s = N_("is set"); char *s = N_("Junk"); char *s = N_("Junk Test"); char *s = N_("Label"); @@ -54,6 +59,7 @@ char *s = N_("returns less than"); char *s = N_("Run Program"); char *s = N_("Score"); char *s = N_("Sender"); +char *s = N_("Set Label"); char *s = N_("Set Status"); char *s = N_("Size (kB)"); char *s = N_("sounds like"); diff --git a/mail/em-folder-browser.c b/mail/em-folder-browser.c index 5b11c11a18..12d02e4b27 100644 --- a/mail/em-folder-browser.c +++ b/mail/em-folder-browser.c @@ -82,6 +82,7 @@ #include "e-util/e-util.h" #include "e-util/e-error.h" #include "e-util/e-util-private.h" +#include "e-util/e-util-labels.h" #include "em-utils.h" #include "em-composer-utils.h" #include "em-format-html-display.h" @@ -309,8 +310,8 @@ generate_viewoption_menu (GtkWidget *emfv) } /* Add the labels */ - for (l = mail_config_get_labels(), i = 0; l; l = l->next, i++) { - MailConfigLabel *label = l->data; + for (l = mail_config_get_labels (), i = 0; l; l = l->next, i++) { + EUtilLabel *label = l->data; if (label->name && *(label->name)) { char *str; GdkPixmap *pixmap; @@ -335,9 +336,8 @@ generate_viewoption_menu (GtkWidget *emfv) g_object_set_data (G_OBJECT (menu_item), "EsbItemId", GINT_TO_POINTER (VIEW_LABEL + (VIEW_ITEMS_MASK + 1) * i)); - /* label->tag starts with "$Label" so it's safe to do */ g_object_set_data (G_OBJECT (menu_item), "LabelTag", - g_strdup (label->tag + 6)); + g_strdup (strncmp (label->tag, "$Label", 6) == 0 ? label->tag + 6 : label->tag)); } gtk_widget_show (menu_item); @@ -379,9 +379,9 @@ viewoption_menu_generator () for (i = 0; emfb_view_items[i].search.id != -1; i++) g_array_append_vals (menu, &emfb_view_items[i], 1); - for (l = mail_config_get_labels(); l; l = l->next) { + for (l = mail_config_get_labels (); l; l = l->next) { ESearchBarItem item; - MailConfigLabel *label = l->data; + EUtilLabel *label = l->data; item.text = label->name; item.id = VIEW_LABEL; @@ -499,7 +499,7 @@ emfb_init(GObject *o) gtk_box_pack_start((GtkBox *)emfb, (GtkWidget *)emfb->search, FALSE, TRUE, 0); gconf = mail_config_get_gconf_client (); - emfb->priv->labels_change_notify_id = gconf_client_notify_add (gconf, "/apps/evolution/mail/labels", gconf_labels_changed, emfb, NULL, NULL); + emfb->priv->labels_change_notify_id = gconf_client_notify_add (gconf, E_UTIL_LABELS_GCONF_KEY, gconf_labels_changed, emfb, NULL, NULL); } emfb->priv->show_wide = gconf_client_get_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/display/show_wide", NULL); @@ -877,11 +877,16 @@ get_view_query (ESearchBar *esb, CamelFolder *folder, const char *folder_uri) GString *s = g_string_new ("(and"); for (l = mail_config_get_labels (); l; l = l->next) { - MailConfigLabel *label = (MailConfigLabel *)l->data; + EUtilLabel *label = (EUtilLabel *)l->data; - /* tag is always with "$Label" prefix */ - if (label && label->tag) - g_string_append_printf (s, " (match-all (not (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\"))))", label->tag + 6, label->tag + 6); + if (label && label->tag) { + const gchar *tag = label->tag; + + if (strncmp (tag, "$Label", 6) == 0) + tag += 6; + + g_string_append_printf (s, " (match-all (not (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\") (user-flag \"%s\"))))", tag, tag, tag); + } } g_string_append (s, ")"); @@ -891,7 +896,7 @@ get_view_query (ESearchBar *esb, CamelFolder *folder, const char *folder_uri) } break; case VIEW_LABEL: tag = (char *)g_object_get_data (G_OBJECT (menu_item), "LabelTag"); - view_sexp = g_strdup_printf ("(match-all (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\" )))", tag, tag); + view_sexp = g_strdup_printf ("(match-all (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\") (user-flag \"%s\")))", tag, tag, tag); duplicate = FALSE; break; case VIEW_MESSAGES_MARKED_AS_IMPORTANT: diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c index 97b7359402..c745ebf073 100644 --- a/mail/em-folder-view.c +++ b/mail/em-folder-view.c @@ -89,6 +89,7 @@ #include "e-util/e-print.h" #include "e-util/e-profile-event.h" #include "e-util/e-util-private.h" +#include "e-util/e-util-labels.h" #include "filter/filter-rule.h" @@ -1233,9 +1234,9 @@ emfv_popup_label_clear(EPopup *ep, EPopupItem *pitem, void *data) { EMFolderView *emfv = data; GSList *l; - MailConfigLabel *label; + EUtilLabel *label; - for (l = mail_config_get_labels(); l; l = l->next) { + for (l = mail_config_get_labels (); l; l = l->next) { label = l->data; emfv_unset_label(emfv, label->tag); } @@ -1253,6 +1254,18 @@ emfv_popup_label_set(EPopup *ep, EPopupItem *pitem, void *data) } static void +emfv_popup_label_new (EPopup *ep, EPopupItem *pitem, void *data) +{ + EMFolderView *emfv = data; + char *tag = e_util_labels_add_with_dlg (NULL, NULL); + + if (tag) { + emfv_set_label (emfv, tag); + g_free (tag); + } +} + +static void emfv_popup_add_sender(EPopup *ep, EPopupItem *pitem, void *data) { EMFolderView *emfv = data; @@ -1343,6 +1356,8 @@ static EPopupItem emfv_popup_items[] = { { E_POPUP_SUBMENU, "60.label.00", N_("_Label"), NULL, NULL, NULL, EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY }, { E_POPUP_ITEM, "60.label.00/00.label", N_("_None"), emfv_popup_label_clear, NULL, NULL, EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY }, { E_POPUP_BAR, "60.label.00/00.label.00", NULL, NULL, NULL, NULL }, + { E_POPUP_BAR, "60.label.00/01.label", NULL, NULL, NULL, NULL }, + { E_POPUP_ITEM, "60.label.00/01.label.00", N_("_New Label"), emfv_popup_label_new, NULL, NULL, EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY }, { E_POPUP_BAR, "70.emfv.06", NULL, NULL, NULL, NULL }, @@ -1381,7 +1396,7 @@ emfv_popup_labels_get_state_for_tag (EMFolderView *emfv, GPtrArray *uids, const if (camel_folder_get_message_user_flag (emfv->folder, uids->pdata[i], label_tag)) exists = TRUE; else { - const char *label = mail_config_get_new_label_tag (camel_folder_get_message_user_tag (emfv->folder, uids->pdata[i], "label")); + const char *label = e_util_labels_get_new_tag (camel_folder_get_message_user_tag (emfv->folder, uids->pdata[i], "label")); /* backward compatibility... */ if (label && !strcmp (label, label_tag)) @@ -1448,9 +1463,9 @@ emfv_popup(EMFolderView *emfv, GdkEvent *event, int on_display) if (!on_display) { GPtrArray *uids = message_list_get_selected (emfv->list); - for (l = mail_config_get_labels(); l; l = l->next) { + for (l = mail_config_get_labels (); l; l = l->next) { EPopupItem *item; - MailConfigLabel *label = l->data; + EUtilLabel *label = l->data; GdkPixmap *pixmap; GdkColor colour; GdkGC *gc; diff --git a/mail/em-mailer-prefs.c b/mail/em-mailer-prefs.c index ef4a6d64c8..85a2ce1e32 100644 --- a/mail/em-mailer-prefs.c +++ b/mail/em-mailer-prefs.c @@ -57,6 +57,7 @@ #include "libedataserverui/e-cell-renderer-color.h" #include "e-util/e-util-private.h" +#include "e-util/e-util-labels.h" #include "mail-config.h" #include "em-junk-hook.h" @@ -156,6 +157,12 @@ em_mailer_prefs_finalise (GObject *obj) g_object_unref (prefs->gui); + if (prefs->labels_change_notify_id) { + gconf_client_notify_remove (prefs->gconf, prefs->labels_change_notify_id); + + prefs->labels_change_notify_id = 0; + } + ((GObjectClass *)(parent_class))->finalize (obj); } @@ -191,31 +198,6 @@ enum { }; static void -label_name_edited_cb (GtkCellRendererText *cell, gchar *path_string, gchar *new_text, EMMailerPrefs *prefs) -{ - GtkTreeModel *model; - GtkTreeIter iter; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (prefs->label_tree)); - - gtk_tree_model_get_iter_from_string (model, &iter, path_string); - - g_strstrip (new_text); - - /* allow only nonempty texts and always strip spaces there */ - if (new_text && *new_text) { - gchar *tag = NULL; - - gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1); - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, LABEL_LIST_COLUMN_NAME, new_text, -1); - mail_config_set_label_name (tag, new_text); - - g_free (tag); - } -} - -static void label_sensitive_buttons (EMMailerPrefs *prefs) { gboolean can_remove = FALSE, have_selected = FALSE, locked; @@ -236,7 +218,7 @@ label_sensitive_buttons (EMMailerPrefs *prefs) gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1); - can_remove = tag && !mail_config_is_system_label (tag); + can_remove = tag && !e_util_labels_is_system (tag); have_selected = TRUE; g_free (tag); @@ -244,7 +226,7 @@ label_sensitive_buttons (EMMailerPrefs *prefs) } gtk_widget_set_sensitive (prefs->label_remove, !locked && can_remove); - gtk_widget_set_sensitive (prefs->label_color, !locked && have_selected); + gtk_widget_set_sensitive (prefs->label_edit, !locked && have_selected); } static void @@ -253,11 +235,77 @@ label_tree_cursor_changed (GtkWidget *widget, gpointer user_data) label_sensitive_buttons (user_data); } +static void +label_tree_refill (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data) +{ + EMMailerPrefs *prefs = (EMMailerPrefs *)user_data; + GSList *labels, *l; + GtkTreeSelection *selection; + GtkListStore *store; + GtkTreeModel *model; + GtkTreeIter last_iter; + gchar *last_path = NULL; + + g_return_if_fail (prefs != NULL); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree)); + if (gtk_tree_selection_get_selected (selection, &model, &last_iter)) + last_path = gtk_tree_model_get_string_from_iter (model, &last_iter); + + store = GTK_LIST_STORE (model); + gtk_list_store_clear (store); + + /* cannot use mail-config cache here, because it's (or can be) updated later than this function call */ + labels = e_util_labels_parse (client); + + for (l = labels; l; l = l->next) { + GdkColor color; + GtkTreeIter iter; + EUtilLabel *label = l->data; + + if (label->colour) + gdk_color_parse (label->colour, &color); + + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + LABEL_LIST_COLUMN_COLOR, label->colour ? &color : NULL, + LABEL_LIST_COLUMN_NAME, label->name, + LABEL_LIST_COLUMN_TAG, label->tag, + -1); + } + + if (last_path) { + gint children; + + children = gtk_tree_model_iter_n_children (model, NULL); + if (children > 0) { + GtkTreePath *path; + + if (!gtk_tree_model_get_iter_from_string (model, &last_iter, last_path)) + gtk_tree_model_iter_nth_child (model, &last_iter, NULL, children - 1); + + path = gtk_tree_model_get_path (model, &last_iter); + if (path) { + GtkTreeViewColumn *focus_col = gtk_tree_view_get_column (GTK_TREE_VIEW (prefs->label_tree), LABEL_LIST_COLUMN_NAME); + + gtk_tree_view_set_cursor (GTK_TREE_VIEW (prefs->label_tree), path, focus_col, FALSE); + gtk_tree_view_row_activated (GTK_TREE_VIEW (prefs->label_tree), path, focus_col); + gtk_tree_path_free (path); + } + } + + g_free (last_path); + } + + label_sensitive_buttons (prefs); + e_util_labels_free (labels); +} + static GtkListStore * init_label_tree (GtkWidget *label_tree, EMMailerPrefs *prefs, gboolean locked) { GtkListStore *store; - GSList *labels; GtkCellRenderer *renderer; gint col; @@ -277,31 +325,14 @@ init_label_tree (GtkWidget *label_tree, EMMailerPrefs *prefs, gboolean locked) renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Name"), renderer, "text", LABEL_LIST_COLUMN_NAME, NULL); - g_object_set (G_OBJECT (renderer), "editable", !locked, NULL); + g_object_set (G_OBJECT (renderer), "editable", FALSE, NULL); - if (!locked) { - g_signal_connect (renderer, "edited", G_CALLBACK (label_name_edited_cb), prefs); + if (!locked) g_signal_connect (label_tree, "cursor-changed", G_CALLBACK (label_tree_cursor_changed), prefs); - } - for (labels = mail_config_get_labels (); labels; labels = labels->next) { - GdkColor color; - GtkTreeIter iter; - MailConfigLabel *label = labels->data; + label_tree_refill (NULL, 0, NULL, prefs); - if (label->colour) - gdk_color_parse (label->colour, &color); - - gtk_list_store_append (store, &iter); - gtk_list_store_set ( - store, &iter, - LABEL_LIST_COLUMN_COLOR, label->colour ? &color : NULL, - LABEL_LIST_COLUMN_NAME, label->name, - LABEL_LIST_COLUMN_TAG, label->tag, - -1); - } - - label_sensitive_buttons (prefs); + prefs->labels_change_notify_id = gconf_client_notify_add (prefs->gconf, E_UTIL_LABELS_GCONF_KEY, label_tree_refill, prefs, NULL, NULL); return store; } @@ -309,45 +340,11 @@ init_label_tree (GtkWidget *label_tree, EMMailerPrefs *prefs, gboolean locked) static void label_add_cb (GtkWidget *widget, gpointer user_data) { - EMMailerPrefs *prefs = user_data; - GtkTreeModel *model; - GtkTreeIter iter; - char *tag, *name; - int tagid; - GtkTreePath *path; - GdkColor gray; - - g_return_if_fail (prefs != NULL); - - tag = mail_config_get_next_label_tag (&tagid); - - if (!tag) - return; - - memset (&gray, 0xCD, sizeof (GdkColor)); - name = g_strdup_printf ("%s %d", _("Label"), tagid); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (prefs->label_tree)); - - if (mail_config_add_label (tag, name, &gray)) { - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - LABEL_LIST_COLUMN_COLOR, &gray, - LABEL_LIST_COLUMN_NAME, name, - LABEL_LIST_COLUMN_TAG, tag, - -1); + char *tag; - path = gtk_tree_model_get_path (model, &iter); - if (path) { - GtkTreeViewColumn *focus_col = gtk_tree_view_get_column (GTK_TREE_VIEW (prefs->label_tree), LABEL_LIST_COLUMN_NAME); - - gtk_tree_view_set_cursor (GTK_TREE_VIEW (prefs->label_tree), path, focus_col, TRUE); - gtk_tree_view_row_activated (GTK_TREE_VIEW (prefs->label_tree), path, focus_col); - gtk_tree_path_free (path); - } - } + tag = e_util_labels_add_with_dlg (GTK_WINDOW (gtk_widget_get_toplevel (widget)), NULL); g_free (tag); - g_free (name); } static void @@ -366,36 +363,15 @@ label_remove_cb (GtkWidget *widget, gpointer user_data) gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1); - if (tag && !mail_config_is_system_label (tag)) { - gint children; - - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - mail_config_remove_label (tag); - - children = gtk_tree_model_iter_n_children (model, NULL); - if (children > 0) { - GtkTreePath *path; - - if (!gtk_list_store_iter_is_valid (GTK_LIST_STORE (model), &iter)) - gtk_tree_model_iter_nth_child (model, &iter, NULL, children - 1); - - path = gtk_tree_model_get_path (model, &iter); - if (path) { - GtkTreeViewColumn *focus_col = gtk_tree_view_get_column (GTK_TREE_VIEW (prefs->label_tree), LABEL_LIST_COLUMN_NAME); - - gtk_tree_view_set_cursor (GTK_TREE_VIEW (prefs->label_tree), path, focus_col, FALSE); - gtk_tree_view_row_activated (GTK_TREE_VIEW (prefs->label_tree), path, focus_col); - gtk_tree_path_free (path); - } - } - } + if (tag && !e_util_labels_is_system (tag)) + e_util_labels_remove (tag); g_free (tag); } } static void -label_color_cb (GtkWidget *widget, gpointer user_data) +label_edit_cb (GtkWidget *widget, gpointer user_data) { EMMailerPrefs *prefs = user_data; GtkTreeSelection *selection; @@ -406,32 +382,17 @@ label_color_cb (GtkWidget *widget, gpointer user_data) selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree)); if (gtk_tree_selection_get_selected (selection, &model, &iter)) { - GtkWidget *dialog; - GdkColor *color = NULL, color2; - - gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_COLOR, &color, -1); - - dialog = gtk_color_selection_dialog_new (_("Select color for label...")); - gtk_color_selection_set_current_color (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (dialog)->colorsel), color); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { - gtk_color_selection_get_current_color (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (dialog)->colorsel), &color2); - - if (!color || memcmp (color, &color2, sizeof(GdkColor)) != 0) { - gchar *tag = NULL; + gchar *tag = NULL; - gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, LABEL_LIST_COLUMN_COLOR, &color2, -1); + gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1); - mail_config_set_label_color (tag, &color2); + if (tag) { + char *str = e_util_labels_add_with_dlg (GTK_WINDOW (gtk_widget_get_toplevel (widget)), tag); - g_free (tag); - } + g_free (str); } - gtk_widget_destroy (dialog); - if (color) - gdk_color_free (color); + g_free (tag); } } @@ -1204,15 +1165,15 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs) G_CALLBACK (toggle_button_toggled)); /* Labels... */ - locked = !gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/labels", NULL); + locked = !gconf_client_key_is_writable (prefs->gconf, E_UTIL_LABELS_GCONF_KEY, NULL); prefs->label_add = glade_xml_get_widget (gui, "labelAdd"); + prefs->label_edit = glade_xml_get_widget (gui, "labelEdit"); prefs->label_remove = glade_xml_get_widget (gui, "labelRemove"); - prefs->label_color = glade_xml_get_widget (gui, "labelColor"); prefs->label_tree = glade_xml_get_widget (gui, "labelTree"); gtk_widget_set_sensitive (prefs->label_add, !locked); gtk_widget_set_sensitive (prefs->label_remove, !locked); - gtk_widget_set_sensitive (prefs->label_color, !locked); + gtk_widget_set_sensitive (prefs->label_edit, !locked); gtk_widget_set_sensitive (prefs->label_tree, !locked); prefs->label_list_store = init_label_tree (prefs->label_tree, prefs, locked); @@ -1220,7 +1181,7 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs) if (!locked) { g_signal_connect (G_OBJECT (prefs->label_add), "clicked", G_CALLBACK (label_add_cb), prefs); g_signal_connect (G_OBJECT (prefs->label_remove), "clicked", G_CALLBACK (label_remove_cb), prefs); - g_signal_connect (G_OBJECT (prefs->label_color), "clicked", G_CALLBACK (label_color_cb), prefs); + g_signal_connect (G_OBJECT (prefs->label_edit), "clicked", G_CALLBACK (label_edit_cb), prefs); } /* headers */ diff --git a/mail/em-mailer-prefs.h b/mail/em-mailer-prefs.h index a9a4327cb7..16df0a93f4 100644 --- a/mail/em-mailer-prefs.h +++ b/mail/em-mailer-prefs.h @@ -104,10 +104,11 @@ struct _EMMailerPrefs { /* Labels and Colours tab */ struct _GtkWidget *label_add; + struct _GtkWidget *label_edit; struct _GtkWidget *label_remove; - struct _GtkWidget *label_color; struct _GtkWidget *label_tree; struct _GtkListStore *label_list_store; + guint labels_change_notify_id; /* mail_config's notify id */ /* Headers tab */ struct _GtkButton *add_header; diff --git a/mail/filtertypes.xml b/mail/filtertypes.xml index 1f8d39b34c..74029112d1 100644 --- a/mail/filtertypes.xml +++ b/mail/filtertypes.xml @@ -523,13 +523,13 @@ <option value="is"> <title>is</title> <code> - (match-all (or (= (user-tag "label") ${versus}) (user-flag (+ "$Label" ${versus})))) + (match-all (or (= (user-tag "label") ${versus}) (user-flag (+ "$Label" ${versus})) (user-flag ${versus}))) </code> </option> <option value="is-not"> <title>is not</title> <code> - (match-all (not (or (= (user-tag "label") ${versus}) (user-flag (+ "$Label" ${versus}))))) + (match-all (not (or (= (user-tag "label") ${versus}) (user-flag (+ "$Label" ${versus})) (user-flag ${versus})))) </code> </option> </input> diff --git a/mail/mail-config.c b/mail/mail-config.c index ef9185ecbd..2a483750c8 100644 --- a/mail/mail-config.c +++ b/mail/mail-config.c @@ -58,6 +58,7 @@ #include <libedataserver/e-data-server-util.h> #include <e-util/e-util.h> #include <misc/e-gui-utils.h> +#include "e-util/e-util-labels.h" #include <libedataserver/e-account-list.h> #include <e-util/e-signature-list.h> @@ -76,17 +77,6 @@ #include "mail-mt.h" #include "mail-tools.h" -/* Note, the first element of each MailConfigLabel must NOT be translated */ -/* Note, the label tag should Always starts with prefix "$Label"! - It's also because filters and search folders, so beware people. */ -MailConfigLabel label_defaults[LABEL_DEFAULTS_NUM] = { - { "$Labelimportant", N_("I_mportant"), "#EF2929" }, /* red */ - { "$Labelwork", N_("_Work"), "#F57900" }, /* orange */ - { "$Labelpersonal", N_("_Personal"), "#4E9A06" }, /* green */ - { "$Labeltodo", N_("_To Do"), "#3465A4" }, /* blue */ - { "$Labellater", N_("_Later"), "#75507B" } /* purple */ -}; - typedef struct { GConfClient *gconf; @@ -139,123 +129,6 @@ mail_config_save_signatures (void) e_signature_list_save (config->signatures); } - -static void -config_clear_labels (void) -{ - MailConfigLabel *label; - GSList *list, *n; - - list = config->labels; - while (list != NULL) { - label = list->data; - g_free(label->tag); - g_free (label->name); - g_free (label->colour); - g_free (label); - - n = list->next; - g_slist_free_1 (list); - list = n; - } - - config->labels = NULL; -} - -static void -config_cache_labels (void) -{ - GSList *labels, *list, *head; - MailConfigLabel *label; - char *buf; - int num = 0; - - labels = NULL; - - head = gconf_client_get_list (config->gconf, "/apps/evolution/mail/labels", GCONF_VALUE_STRING, NULL); - - for (list = head; list; list = list->next) { - char *color, *name, *tag; - name = buf = list->data; - color = strrchr (buf, ':'); - - *color++ = '\0'; - tag = strchr (color, '|'); - if (tag) - *tag++ = '\0'; - - label = g_new (MailConfigLabel, 1); - - /* Needed for Backward Compatibility */ - if (num < LABEL_DEFAULTS_NUM) { - label->name = g_strdup (_(buf)); - label->tag = g_strdup (label_defaults[num].tag); - num++; - } else if (!tag) { - g_free (buf); - g_free (label); - continue; - } else { - label->name = g_strdup (name); - label->tag = g_strdup (tag); - } - - label->colour = g_strdup (color); - labels = g_slist_prepend (labels, label); - - g_free (buf); - } - - if (head) - g_slist_free (head); - - while (num < LABEL_DEFAULTS_NUM) { - /* complete the list with defaults */ - label = g_new (MailConfigLabel, 1); - label->tag = g_strdup (label_defaults[num].tag); - label->name = g_strdup (_(label_defaults[num].name)); - label->colour = g_strdup (label_defaults[num].colour); - - labels = g_slist_prepend (labels, label); - - num++; - } - - config->labels = g_slist_reverse (labels); -} - -/* stores the actual cache to gconf */ -static gboolean -config_cache_labels_flush (void) -{ - GSList *l, *text_labels; - - if (!config || !config->labels) - return FALSE; - - text_labels = NULL; - - for (l = config->labels; l; l = l->next) { - MailConfigLabel *label = l->data; - - if (label && label->tag && label->name && label->colour) - text_labels = g_slist_prepend (text_labels, g_strdup_printf ("%s:%s|%s", label->name, label->colour, label->tag)); - } - - if (!text_labels) - return FALSE; - - text_labels = g_slist_reverse (text_labels); - - gconf_client_set_list (config->gconf, "/apps/evolution/mail/labels", GCONF_VALUE_STRING, text_labels, NULL); - - g_slist_foreach (text_labels, (GFunc)g_free, NULL); - g_slist_free (text_labels); - - /* not true if gconf failed to write; who cares */ - return TRUE; -} - static void config_clear_mime_types (void) { @@ -344,11 +217,30 @@ config_write_style (void) } static void +config_clear_labels (void) +{ + if (!config) + return; + + e_util_labels_free (config->labels); + config->labels = NULL; +} + +static void +config_cache_labels (GConfClient *client) +{ + if (!config) + return; + + config->labels = e_util_labels_parse (client); +} + +static void gconf_labels_changed (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data) { config_clear_labels (); - config_cache_labels (); + config_cache_labels (client); } static void @@ -461,10 +353,10 @@ mail_config_init (void) config->citation_colour_notify_id = gconf_client_notify_add (config->gconf, "/apps/evolution/mail/display/citation_colour", gconf_style_changed, NULL, NULL, NULL); - gconf_client_add_dir (config->gconf, "/apps/evolution/mail/labels", + gconf_client_add_dir (config->gconf, E_UTIL_LABELS_GCONF_KEY, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); config->label_notify_id = - gconf_client_notify_add (config->gconf, "/apps/evolution/mail/labels", + gconf_client_notify_add (config->gconf, E_UTIL_LABELS_GCONF_KEY, gconf_labels_changed, NULL, NULL, NULL); gconf_client_add_dir (config->gconf, "/apps/evolution/mail/mime_types", @@ -473,7 +365,7 @@ mail_config_init (void) gconf_client_notify_add (config->gconf, "/apps/evolution/mail/mime_types", gconf_mime_types_changed, NULL, NULL, NULL); - config_cache_labels (); + config_cache_labels (config->gconf); config_cache_mime_types (); config->address_compress = gconf_client_get_bool (config->gconf, "/apps/evolution/mail/display/address_compress", NULL); config->address_count = gconf_client_get_int (config->gconf, "/apps/evolution/mail/display/address_count", NULL); @@ -651,36 +543,10 @@ mail_config_get_enable_magic_spacebar () return config->magic_spacebar; } -/* public Label functions */ - -/** - * config_get_label - * - * Looks for label in labels cache by tag and returns actual pointer to cache. - * @param tag Tag of label you are looking for. - * @return Pointer to cache data if label with such tag exists or NULL. Do not free it! - **/ -static MailConfigLabel * -config_get_label (const char *tag) -{ - GSList *l; - - g_return_val_if_fail (tag != NULL, NULL); - - for (l = config->labels; l; l = l->next) { - MailConfigLabel *label = l->data; - - if (label && label->tag && !strcmp (tag, label->tag)) - return label; - } - - return NULL; -} - /** * mail_config_get_labels * - * @return list of known labels, each member data is MailConfigLabel structure. + * @return list of known labels, each member data is EUtilLabel structure. * Returned list should not be freed, neither data inside it. **/ GSList * @@ -689,250 +555,6 @@ mail_config_get_labels (void) return config->labels; } -/** - * mail_config_get_next_label_tag - * - * @param id [out] if not NULL, then assigned used number of the next free tag. - * @return Next free tag, which can be used for new label. - * Returned pointer should be freed with g_free. - * - * @note All labels should always start with "$Label" string, it's very important - * for filters and search folders! - **/ -char * -mail_config_get_next_label_tag (int *id) -{ - char *tag = NULL; - int count = LABEL_DEFAULTS_NUM; - - /* who wants more than 100 labels? */ - while (!tag && count <= 100) { - count++; - tag = g_strdup_printf ("$Label%d", count); - - if (config_get_label (tag)) { - g_free (tag); - tag = NULL; - } - } - - if (id) - *id = count; - - return tag; -} - -/** - * mail_config_is_system_label - * - * @return Whether the tag is one of default/system labels or not. - **/ -gboolean -mail_config_is_system_label (const char *tag) -{ - int i; - - if (!tag) - return FALSE; - - for (i = 0; i < LABEL_DEFAULTS_NUM; i++) { - if (strcmp (tag, label_defaults[i].tag) == 0) - return TRUE; - } - - return FALSE; -} - -/** - * mail_config_add_label - * Creates new label at the end of actual list of labels. - * - * @param tag Unique identifier of this new label. - * @param name User readable name of this label. Should not be NULL. - * @param color Color assigned to this label. Should not be NULL. - * @return Whether was added. - **/ -gboolean -mail_config_add_label (const char *tag, const char *name, const GdkColor *color) -{ - MailConfigLabel *label; - - g_return_val_if_fail (tag != NULL, FALSE); - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (color != NULL, FALSE); - - if (config_get_label (tag) != NULL) - return FALSE; - - label = g_new0 (MailConfigLabel, 1); - label->tag = g_strdup (tag); - label->name = g_strdup (name); - label->colour = gdk_color_to_string (color); - - config->labels = g_slist_append (config->labels, label); - - return config_cache_labels_flush (); -} - -/** - * mail_config_remove_label - * - * @param tag Tag of the label to remove. - * @return Whether was removed. - **/ -gboolean -mail_config_remove_label (const char *tag) -{ - MailConfigLabel *label; - - g_return_val_if_fail (tag != NULL, FALSE); - - label = config_get_label (tag); - if (!label) - return FALSE; - - config->labels = g_slist_remove (config->labels, label); - - g_free (label); - - return config_cache_labels_flush (); -} - -/** - * mail_config_get_label_name - * - * @param tag Tag of the label of our interest. - * @return Name of the label with that tag or NULL, if no such label exists. - **/ -const char * -mail_config_get_label_name (const char *tag) -{ - MailConfigLabel *label; - - g_return_val_if_fail (tag != NULL, NULL); - - label = config_get_label (tag); - if (!label) - return NULL; - - return label->name; -} - -/** - * mail_config_get_label_color - * - * @param tag Tag of the label of our interest. - * @param color [out] Actual color of the label with that tag, or unchanged if failed. - * @return Whether found such label and color has been set. - **/ -gboolean -mail_config_get_label_color (const char *tag, GdkColor *color) -{ - MailConfigLabel *label; - - g_return_val_if_fail (tag != NULL, FALSE); - g_return_val_if_fail (color != NULL, FALSE); - - label = config_get_label (tag); - if (!label) - return FALSE; - - return gdk_color_parse (label->colour, color); -} - -/** - * mail_config_get_label_color_str - * - * @param tag Tag of the label of our interest. - * @return String representation of that label, or NULL, is no such label exists. - **/ -const char * -mail_config_get_label_color_str (const char *tag) -{ - MailConfigLabel *label; - - g_return_val_if_fail (tag != NULL, FALSE); - - label = config_get_label (tag); - if (!label) - return FALSE; - - return label->colour; -} - -/** - * mail_config_get_new_label_tag - * - * @param old_tag Tag of the label from old version of Evolution. - * @return New tag name equivalent with the old tag, or NULL if no such name existed before. - **/ -const char * -mail_config_get_new_label_tag (const char *old_tag) -{ - int i; - - if (!old_tag) - return NULL; - - for (i = 0; i < LABEL_DEFAULTS_NUM; i++) { - /* default labels have same name as those old, only with prefix "$Label" */ - if (!strcmp (old_tag, label_defaults[i].tag + 6)) - return label_defaults[i].tag; - } - - return NULL; -} - -/** - * mail_config_set_label_name - * - * @param tag Tag of the label of our interest. - * @param name New name for the label. - * @return Whether successfully saved. - **/ -gboolean -mail_config_set_label_name (const char *tag, const char *name) -{ - MailConfigLabel *label; - - g_return_val_if_fail (tag != NULL, FALSE); - g_return_val_if_fail (name != NULL, FALSE); - - label = config_get_label (tag); - if (!label) - return FALSE; - - g_free (label->name); - label->name = g_strdup (name); - - return config_cache_labels_flush (); -} - -/** - * mail_config_set_label_color - * - * @param tag Tag of the label of our interest. - * @param color New color for the label. - * @return Whether successfully saved. - **/ -gboolean -mail_config_set_label_color (const char *tag, const GdkColor *color) -{ - MailConfigLabel *label; - - g_return_val_if_fail (tag != NULL, FALSE); - g_return_val_if_fail (color != NULL, FALSE); - - label = config_get_label (tag); - if (!label) - return FALSE; - - g_free (label->colour); - label->colour = gdk_color_to_string (color); - - return config_cache_labels_flush (); -} - const char ** mail_config_get_allowable_mime_types (void) { diff --git a/mail/mail-config.glade b/mail/mail-config.glade index be41d9fb59..7e08e2b01b 100644 --- a/mail/mail-config.glade +++ b/mail/mail-config.glade @@ -5861,7 +5861,7 @@ For example: "Work" or "Personal"</property> <child> <widget class="GtkLabel" id="label502"> <property name="visible">True</property> - <property name="label" translatable="yes"><span weight="bold">Labels and Colors</span></property> + <property name="label" translatable="yes"><span weight="bold">Labels</span></property> <property name="use_underline">False</property> <property name="use_markup">True</property> <property name="justify">GTK_JUSTIFY_LEFT</property> @@ -6011,10 +6011,10 @@ For example: "Work" or "Personal"</property> </child> <child> - <widget class="GtkButton" id="labelRemove"> + <widget class="GtkButton" id="labelEdit"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="label">gtk-remove</property> + <property name="label">gtk-edit</property> <property name="use_stock">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <property name="focus_on_click">True</property> @@ -6027,78 +6027,16 @@ For example: "Work" or "Personal"</property> </child> <child> - <widget class="GtkButton" id="labelColor"> + <widget class="GtkButton" id="labelRemove"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="label">gtk-remove</property> + <property name="use_stock">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <property name="focus_on_click">True</property> - - <child> - <widget class="GtkAlignment" id="alignment36"> - <property name="visible">True</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <property name="top_padding">0</property> - <property name="bottom_padding">0</property> - <property name="left_padding">0</property> - <property name="right_padding">0</property> - - <child> - <widget class="GtkHBox" id="hbox243"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">2</property> - - <child> - <widget class="GtkImage" id="image11"> - <property name="visible">True</property> - <property name="stock">gtk-select-color</property> - <property name="icon_size">4</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label590"> - <property name="visible">True</property> - <property name="label" translatable="yes">C_olor</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> </widget> <packing> - <property name="padding">10</property> + <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> @@ -6138,7 +6076,7 @@ For example: "Work" or "Personal"</property> <child> <widget class="GtkLabel" id="lblColours"> <property name="visible">True</property> - <property name="label" translatable="yes">Colors</property> + <property name="label" translatable="yes">Labels</property> <property name="use_underline">True</property> <property name="use_markup">False</property> <property name="justify">GTK_JUSTIFY_CENTER</property> diff --git a/mail/mail-config.h b/mail/mail-config.h index 454a44f2bf..c08eaf34a4 100644 --- a/mail/mail-config.h +++ b/mail/mail-config.h @@ -25,7 +25,6 @@ #include <glib.h> #include <glib-object.h> -#include <gdk/gdkcolor.h> #include "camel/camel-provider.h" /* can't forward-declare enums, bah */ @@ -88,15 +87,6 @@ typedef enum { MAIL_CONFIG_XMAILER_RUPERT_APPROVED = 4 } MailConfigXMailerDisplayStyle; -typedef struct { - char *tag; - char *name; - char *colour; -} MailConfigLabel; - -#define LABEL_DEFAULTS_NUM 5 -extern MailConfigLabel label_defaults[LABEL_DEFAULTS_NUM]; - /* Configuration */ void mail_config_init (void); void mail_config_clear (void); @@ -109,17 +99,7 @@ struct _GConfClient *mail_config_get_gconf_client (void); gboolean mail_config_is_configured (void); gboolean mail_config_is_corrupt (void); -GSList * mail_config_get_labels (void); -char * mail_config_get_next_label_tag (int *id); -gboolean mail_config_is_system_label (const char *tag); -gboolean mail_config_add_label (const char *tag, const char *name, const GdkColor *color); -gboolean mail_config_remove_label (const char *tag); -const char *mail_config_get_label_name (const char *tag); -gboolean mail_config_get_label_color (const char *tag, GdkColor *color); -const char *mail_config_get_label_color_str (const char *tag); -const char *mail_config_get_new_label_tag (const char *old_tag); -gboolean mail_config_set_label_name (const char *tag, const char *name); -gboolean mail_config_set_label_color (const char *tag, const GdkColor *color); +GSList *mail_config_get_labels (void); const char **mail_config_get_allowable_mime_types (void); diff --git a/mail/message-list.c b/mail/message-list.c index 6920141b27..e81093cc93 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -52,6 +52,7 @@ #include "e-util/e-profile-event.h" #include "e-util/e-util-private.h" #include "e-util/e-util.h" +#include "e-util/e-util-labels.h" #include "misc/e-gui-utils.h" @@ -1244,29 +1245,27 @@ get_all_labels (CamelMessageInfo *msg_info, char **label_str, gboolean get_tags) const char *old_label; int count = 0; const CamelFlag *flag; + GSList *labels; + labels = mail_config_get_labels (); str = g_string_new (""); for (flag = camel_message_info_user_flags (msg_info); flag; flag = flag->next) { - /* We will be able to show in the column even unknown labels from - other Evolution, because every label starts with "$Label". - This doesn't apply for filters and search folders, but here - we can see that we should add new labels to this Evolution too. */ - if (strncmp (flag->name, "$Label", 6) == 0) { - const char *name = NULL; + const char *name = e_util_labels_get_name (labels, flag->name); + if (name) { if (str->len) g_string_append (str, ", "); - if (!get_tags) - name = mail_config_get_label_name (flag->name); + if (get_tags) + name = flag->name; - g_string_append (str, get_tags || !name ? flag->name : name); + g_string_append (str, name); count++; } } - old_label = mail_config_get_new_label_tag (camel_message_info_user_tag (msg_info, "label")); + old_label = e_util_labels_get_new_tag (camel_message_info_user_tag (msg_info, "label")); if (old_label != NULL) { const char *name = NULL; @@ -1275,9 +1274,9 @@ get_all_labels (CamelMessageInfo *msg_info, char **label_str, gboolean get_tags) g_string_append (str, ", "); if (!get_tags) - name = mail_config_get_label_name (old_label); + name = e_util_labels_get_name (labels, old_label); - g_string_append (str, get_tags || !name ? old_label : name); + g_string_append (str, (get_tags || !name) ? old_label : name); ++count; } @@ -1426,7 +1425,7 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, int col, void *model_data) if (colour == NULL) { if ((n = get_all_labels (msg_info, &labels_string, TRUE)) == 1) { - colour = mail_config_get_label_color_str (labels_string); + colour = e_util_labels_get_color_str (mail_config_get_labels (), labels_string); } else if (camel_message_info_flags(msg_info) & CAMEL_MESSAGE_FLAGGED) { /* FIXME: extract from the important.xpm somehow. */ colour = "#A7453E"; diff --git a/mail/message-list.etspec b/mail/message-list.etspec index 4581bc354f..bd2ec76554 100644 --- a/mail/message-list.etspec +++ b/mail/message-list.etspec @@ -7,15 +7,15 @@ <ETableColumn model_col="3" _title="Attachment" pixbuf="attachment" expansion="0.0" minimum_width="18" resizable="false" cell="render_attachment" compare="integer" /> - <ETableColumn model_col="4" compare_col="18" _title="From" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="10"/> + <ETableColumn model_col="4" compare_col="19" _title="From" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="10"/> - <ETableColumn model_col="5" compare_col="19" _title="Subject" expansion="1.6" minimum_width="32" resizable="true" cell="render_tree" compare="collate" search="string"/> + <ETableColumn model_col="5" compare_col="20" _title="Subject" expansion="1.6" minimum_width="32" resizable="true" cell="render_tree" compare="collate" search="string"/> <ETableColumn model_col="6" _title="Date" expansion="0.4" minimum_width="32" resizable="true" cell="render_date" compare="integer"/> <ETableColumn model_col="7" _title="Received" expansion="0.4" minimum_width="32" resizable="true" cell="render_date" compare="integer"/> - <ETableColumn model_col="8" compare_col="20" _title="To" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="5"/> + <ETableColumn model_col="8" compare_col="21" _title="To" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="5"/> <ETableColumn model_col="9" _title="Size" expansion="0.2" minimum_width="32" resizable="true" cell="render_size" compare="integer"/> diff --git a/mail/vfoldertypes.xml b/mail/vfoldertypes.xml index a0ef98a717..2ccb552cb5 100644 --- a/mail/vfoldertypes.xml +++ b/mail/vfoldertypes.xml @@ -260,13 +260,13 @@ <option value="is"> <title>is</title> <code> - (match-all (or (= (user-tag "label") ${versus}) (user-flag (+ "$Label" ${versus})))) + (match-all (or (= (user-tag "label") ${versus}) (user-flag (+ "$Label" ${versus})) (user-flag ${versus}))) </code> </option> <option value="is-not"> <title>is not</title> <code> - (match-all (not (or (= (user-tag "label") ${versus}) (user-flag (+ "$Label" ${versus}))))) + (match-all (not (or (= (user-tag "label") ${versus}) (user-flag (+ "$Label" ${versus})) (user-flag ${versus})))) </code> </option> </input> diff --git a/po/ChangeLog b/po/ChangeLog index a34c165cea..f927223e8e 100644 --- a/po/ChangeLog +++ b/po/ChangeLog @@ -1,3 +1,7 @@ +2008-01-10 Milan Crha <mcrha@redhat.com> + + * POTFILES.in: Added new file e-util/e-util-labels.c + 2008-01-09 Changwoo Ryu <cwryu@debian.org> * ko.po: Updated Korean translation. diff --git a/po/POTFILES.in b/po/POTFILES.in index ecacdf50a7..643b3578d4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -188,6 +188,7 @@ e-util/e-dialog-utils.c e-util/e-error.c e-util/e-print.c e-util/e-system.error.xml +e-util/e-util-labels.c filter/filter-datespec.c filter/filter-file.c filter/filter-input.c |