[evolution] Bug 203955 - Custom icon/text color for Mail folders
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Bug 203955 - Custom icon/text color for Mail folders
- Date: Mon, 11 Mar 2019 11:09:20 +0000 (UTC)
commit 4e123e6f513094f3224528f312d1308c6622f8a5
Author: Milan Crha <mcrha redhat com>
Date: Mon Mar 11 12:10:04 2019 +0100
Bug 203955 - Custom icon/text color for Mail folders
Closes https://bugzilla.gnome.org/show_bug.cgi?id=203955
src/mail/CMakeLists.txt | 2 +
src/mail/e-mail-folder-tweaks.c | 292 ++++++++++++++++++++++++++++++++++++
src/mail/e-mail-folder-tweaks.h | 86 +++++++++++
src/mail/em-folder-properties.c | 324 +++++++++++++++++++++++++++++++++++++---
src/mail/em-folder-tree-model.c | 116 ++++++++++++++
src/mail/em-folder-tree-model.h | 14 +-
src/mail/em-folder-tree.c | 39 +++--
7 files changed, 837 insertions(+), 36 deletions(-)
---
diff --git a/src/mail/CMakeLists.txt b/src/mail/CMakeLists.txt
index 32cb8a7923..fa60d1091d 100644
--- a/src/mail/CMakeLists.txt
+++ b/src/mail/CMakeLists.txt
@@ -66,6 +66,7 @@ set(SOURCES
e-mail-display-popup-extension.c
e-mail-folder-create-dialog.c
e-mail-folder-pane.c
+ e-mail-folder-tweaks.c
e-mail-free-form-exp.c
e-mail-junk-options.c
e-mail-label-action.c
@@ -154,6 +155,7 @@ set(HEADERS
e-mail-enums.h
e-mail-folder-create-dialog.h
e-mail-folder-pane.h
+ e-mail-folder-tweaks.h
e-mail-free-form-exp.h
e-mail-junk-options.h
e-mail-label-action.h
diff --git a/src/mail/e-mail-folder-tweaks.c b/src/mail/e-mail-folder-tweaks.c
new file mode 100644
index 0000000000..2b4f754106
--- /dev/null
+++ b/src/mail/e-mail-folder-tweaks.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "evolution-config.h"
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "libemail-engine/libemail-engine.h"
+
+#include "e-mail-folder-tweaks.h"
+
+#define KEY_TEXT_COLOR "Color"
+#define KEY_ICON_FILENAME "Icon"
+
+struct _EMailFolderTweaksPrivate {
+ gchar *config_filename;
+ GKeyFile *config;
+ gboolean saving;
+};
+
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (EMailFolderTweaks, e_mail_folder_tweaks, G_TYPE_OBJECT)
+
+static gboolean
+mail_folder_tweaks_save_idle_cb (gpointer user_data)
+{
+ EMailFolderTweaks *tweaks = user_data;
+ GError *error = NULL;
+
+ g_return_val_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks), FALSE);
+
+ if (!g_key_file_save_to_file (tweaks->priv->config, tweaks->priv->config_filename, &error)) {
+ g_warning ("%s: Failed to save tweaks to '%s': %s", G_STRFUNC,
+ tweaks->priv->config_filename, error ? error->message : "Unknown error");
+ g_clear_error (&error);
+ }
+
+ tweaks->priv->saving = FALSE;
+
+ return FALSE;
+}
+
+static void
+mail_folder_tweaks_schedule_save (EMailFolderTweaks *tweaks)
+{
+ g_return_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks));
+
+ if (!tweaks->priv->saving) {
+ tweaks->priv->saving = TRUE;
+
+ g_idle_add_full (G_PRIORITY_LOW, mail_folder_tweaks_save_idle_cb, g_object_ref (tweaks),
g_object_unref);
+ }
+}
+
+static gchar *
+mail_folder_tweaks_dup_string (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri,
+ const gchar *key)
+{
+ g_return_val_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks), NULL);
+ g_return_val_if_fail (folder_uri != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ return g_key_file_get_string (tweaks->priv->config, folder_uri, key, NULL);
+}
+
+static void
+mail_folder_tweaks_set_string (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri,
+ const gchar *key,
+ const gchar *value)
+{
+ gboolean changed;
+
+ g_return_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks));
+ g_return_if_fail (folder_uri != NULL);
+ g_return_if_fail (key != NULL);
+
+ if (!value || !*value) {
+ changed = g_key_file_remove_key (tweaks->priv->config, folder_uri, key, NULL);
+ if (changed) {
+ gchar **keys;
+
+ keys = g_key_file_get_keys (tweaks->priv->config, folder_uri, NULL, NULL);
+
+ /* Remove the whole group, if it's the last key in it */
+ if (!keys || !keys[0]) {
+ g_key_file_remove_group (tweaks->priv->config, folder_uri, NULL);
+ }
+
+ g_strfreev (keys);
+ }
+ } else {
+ gchar *stored;
+
+ stored = mail_folder_tweaks_dup_string (tweaks, folder_uri, key);
+ changed = g_strcmp0 (stored, value) != 0;
+ g_free (stored);
+
+ if (changed)
+ g_key_file_set_string (tweaks->priv->config, folder_uri, key, value);
+ }
+
+ if (changed) {
+ mail_folder_tweaks_schedule_save (tweaks);
+
+ g_signal_emit (tweaks, signals[CHANGED], 0, folder_uri, NULL);
+ }
+}
+
+static GObject *
+e_mail_folder_tweaks_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ static GWeakRef singleton;
+ GObject *result;
+
+ result = g_weak_ref_get (&singleton);
+ if (!result) {
+ result = G_OBJECT_CLASS (e_mail_folder_tweaks_parent_class)->constructor (type,
n_construct_properties, construct_properties);
+
+ if (result)
+ g_weak_ref_set (&singleton, result);
+ }
+
+ return result;
+}
+
+static void
+e_mail_folder_tweaks_finalize (GObject *object)
+{
+ EMailFolderTweaks *tweaks = E_MAIL_FOLDER_TWEAKS (object);
+
+ g_free (tweaks->priv->config_filename);
+ g_key_file_free (tweaks->priv->config);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_mail_folder_tweaks_parent_class)->finalize (object);
+}
+
+static void
+e_mail_folder_tweaks_class_init (EMailFolderTweaksClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (EMailFolderTweaksPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructor = e_mail_folder_tweaks_constructor;
+ object_class->finalize = e_mail_folder_tweaks_finalize;
+
+ signals[CHANGED] = g_signal_new (
+ "changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMailFolderTweaksClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+}
+
+static void
+e_mail_folder_tweaks_init (EMailFolderTweaks *tweaks)
+{
+ tweaks->priv = G_TYPE_INSTANCE_GET_PRIVATE (tweaks, E_TYPE_MAIL_FOLDER_TWEAKS,
EMailFolderTweaksPrivate);
+ tweaks->priv->config_filename = g_build_filename (mail_session_get_config_dir (),
"folder-tweaks.ini", NULL);
+ tweaks->priv->config = g_key_file_new ();
+
+ /* Ignore errors */
+ g_key_file_load_from_file (tweaks->priv->config, tweaks->priv->config_filename, G_KEY_FILE_NONE,
NULL);
+}
+
+EMailFolderTweaks *
+e_mail_folder_tweaks_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_FOLDER_TWEAKS, NULL);
+}
+
+void
+e_mail_folder_tweaks_remove_for_folders (EMailFolderTweaks *tweaks,
+ const gchar *top_folder_uri)
+{
+ gboolean changed = FALSE;
+ gchar **groups;
+ gint ii;
+
+ g_return_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks));
+ g_return_if_fail (top_folder_uri != NULL);
+
+ groups = g_key_file_get_groups (tweaks->priv->config, NULL);
+
+ if (!groups)
+ return;
+
+ for (ii = 0; groups[ii]; ii++) {
+ if (g_str_has_prefix (groups[ii], top_folder_uri)) {
+ changed = g_key_file_remove_group (tweaks->priv->config, groups[ii], NULL);
+ }
+ }
+
+ g_strfreev (groups);
+
+ if (changed)
+ mail_folder_tweaks_schedule_save (tweaks);
+}
+
+gboolean
+e_mail_folder_tweaks_get_color (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri,
+ GdkRGBA *out_rgba)
+{
+ gchar *stored;
+ gboolean success;
+
+ g_return_val_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks), FALSE);
+ g_return_val_if_fail (folder_uri != NULL, FALSE);
+ g_return_val_if_fail (out_rgba != NULL, FALSE);
+
+ stored = mail_folder_tweaks_dup_string (tweaks, folder_uri, KEY_TEXT_COLOR);
+ if (!stored)
+ return FALSE;
+
+ success = gdk_rgba_parse (out_rgba, stored);
+
+ g_free (stored);
+
+ return success;
+}
+
+void
+e_mail_folder_tweaks_set_color (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri,
+ const GdkRGBA *rgba)
+{
+ gchar *value;
+
+ g_return_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks));
+ g_return_if_fail (folder_uri != NULL);
+
+ if (rgba)
+ value = gdk_rgba_to_string (rgba);
+ else
+ value = NULL;
+
+ mail_folder_tweaks_set_string (tweaks, folder_uri, KEY_TEXT_COLOR, value);
+
+ g_free (value);
+}
+
+gchar *
+e_mail_folder_tweaks_dup_icon_filename (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri)
+{
+ g_return_val_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks), FALSE);
+ g_return_val_if_fail (folder_uri != NULL, FALSE);
+
+ return mail_folder_tweaks_dup_string (tweaks, folder_uri, KEY_ICON_FILENAME);
+}
+
+void
+e_mail_folder_tweaks_set_icon_filename (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri,
+ const gchar *icon_filename)
+{
+ g_return_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks));
+ g_return_if_fail (folder_uri != NULL);
+
+ mail_folder_tweaks_set_string (tweaks, folder_uri, KEY_ICON_FILENAME, icon_filename);
+}
diff --git a/src/mail/e-mail-folder-tweaks.h b/src/mail/e-mail-folder-tweaks.h
new file mode 100644
index 0000000000..23fc379cbf
--- /dev/null
+++ b/src/mail/e-mail-folder-tweaks.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef E_MAIL_FOLDER_TWEAKS_H
+#define E_MAIL_FOLDER_TWEAKS_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_FOLDER_TWEAKS \
+ (e_mail_folder_tweaks_get_type ())
+#define E_MAIL_FOLDER_TWEAKS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_FOLDER_TWEAKS, EMailFolderTweaks))
+#define E_MAIL_FOLDER_TWEAKS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_FOLDER_TWEAKS, EMailFolderTweaksClass))
+#define E_IS_MAIL_FOLDER_TWEAKS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_FOLDER_TWEAKS))
+#define E_IS_MAIL_FOLDER_TWEAKS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_FOLDER_TWEAKS))
+#define E_MAIL_FOLDER_TWEAKS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_FOLDER_TWEAKS, EMailFolderTweaksClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailFolderTweaks EMailFolderTweaks;
+typedef struct _EMailFolderTweaksClass EMailFolderTweaksClass;
+typedef struct _EMailFolderTweaksPrivate EMailFolderTweaksPrivate;
+
+struct _EMailFolderTweaks {
+ /*< private >*/
+ GObject parent;
+ EMailFolderTweaksPrivate *priv;
+};
+
+struct _EMailFolderTweaksClass {
+ /*< private >*/
+ GObjectClass parent_class;
+
+ void (* changed) (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri);
+};
+
+GType e_mail_folder_tweaks_get_type (void);
+
+EMailFolderTweaks *
+ e_mail_folder_tweaks_new (void);
+void e_mail_folder_tweaks_remove_for_folders
+ (EMailFolderTweaks *tweaks,
+ const gchar *top_folder_uri);
+gboolean e_mail_folder_tweaks_get_color (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri,
+ GdkRGBA *out_rgba);
+void e_mail_folder_tweaks_set_color (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri,
+ const GdkRGBA *rgba);
+gchar * e_mail_folder_tweaks_dup_icon_filename
+ (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri);
+void e_mail_folder_tweaks_set_icon_filename
+ (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri,
+ const gchar *icon_filename);
+
+G_END_DECLS
+
+#endif /* E_MAIL_FOLDER_TWEAKS_H */
diff --git a/src/mail/em-folder-properties.c b/src/mail/em-folder-properties.c
index 1be107ba46..a1a77c6cce 100644
--- a/src/mail/em-folder-properties.c
+++ b/src/mail/em-folder-properties.c
@@ -35,6 +35,7 @@
#include <e-util/e-util.h>
#include "e-mail-backend.h"
+#include "e-mail-folder-tweaks.h"
#include "e-mail-label-dialog.h"
#include "e-mail-notes.h"
#include "e-mail-ui-session.h"
@@ -85,6 +86,258 @@ emfp_free (EConfig *ec,
g_slist_free (items);
}
+typedef struct _FolderTweaksData {
+ gchar *folder_uri;
+ EMailFolderTweaks *tweaks; /* referenced */
+ GtkWidget *widget; /* not referenced */
+} FolderTweaksData;
+
+static FolderTweaksData *
+folder_tweaks_data_new (const gchar *folder_uri,
+ EMailFolderTweaks *tweaks,
+ GtkWidget *widget)
+{
+ FolderTweaksData *ftd;
+
+ ftd = g_new0 (FolderTweaksData, 1);
+ ftd->folder_uri = g_strdup (folder_uri);
+ ftd->tweaks = g_object_ref (tweaks);
+ ftd->widget = widget;
+
+ return ftd;
+}
+
+static void
+folder_tweaks_data_free (gpointer ptr,
+ GClosure *closure)
+{
+ FolderTweaksData *ftd = ptr;
+
+ if (ftd) {
+ g_free (ftd->folder_uri);
+ g_object_unref (ftd->tweaks);
+ g_free (ftd);
+ }
+}
+
+static void
+tweaks_custom_icon_check_toggled_cb (GtkToggleButton *toggle_button,
+ FolderTweaksData *ftd)
+{
+ GtkWidget *image;
+
+ g_return_if_fail (ftd != NULL);
+
+ if (!gtk_toggle_button_get_active (toggle_button)) {
+ e_mail_folder_tweaks_set_icon_filename (ftd->tweaks, ftd->folder_uri, NULL);
+ return;
+ }
+
+ image = gtk_button_get_image (GTK_BUTTON (ftd->widget));
+
+ if (image && gtk_image_get_storage_type (GTK_IMAGE (image))) {
+ GIcon *icon = NULL;
+
+ gtk_image_get_gicon (GTK_IMAGE (image), &icon, NULL);
+
+ if (G_IS_FILE_ICON (icon)) {
+ GFile *file;
+
+ file = g_file_icon_get_file (G_FILE_ICON (icon));
+ if (file) {
+ gchar *filename;
+
+ filename = g_file_get_path (file);
+ if (filename) {
+ e_mail_folder_tweaks_set_icon_filename (ftd->tweaks, ftd->folder_uri,
filename);
+
+ g_free (filename);
+ }
+ }
+ }
+ }
+}
+
+static void
+tweaks_custom_icon_button_clicked_cb (GtkWidget *button,
+ FolderTweaksData *ftd)
+{
+ GtkWidget *dialog;
+ GtkWidget *toplevel;
+ GFile *file;
+
+ toplevel = gtk_widget_get_toplevel (button);
+ dialog = e_image_chooser_dialog_new (_("Select Custom Icon"),
+ GTK_IS_WINDOW (toplevel) ? GTK_WINDOW (toplevel) : NULL);
+
+ file = e_image_chooser_dialog_run (E_IMAGE_CHOOSER_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog);
+
+ if (file) {
+ gchar *filename;
+
+ filename = g_file_get_path (file);
+ if (filename) {
+ GtkWidget *image;
+ GIcon *custom_icon;
+
+ image = gtk_button_get_image (GTK_BUTTON (button));
+ custom_icon = g_file_icon_new (file);
+
+ gtk_image_set_from_gicon (GTK_IMAGE (image), custom_icon, GTK_ICON_SIZE_BUTTON);
+
+ g_clear_object (&custom_icon);
+
+ e_mail_folder_tweaks_set_icon_filename (ftd->tweaks, ftd->folder_uri, filename);
+
+ g_free (filename);
+ }
+
+ g_object_unref (file);
+ }
+}
+
+static void
+emfp_add_tweaks_custom_icon_row (GtkBox *vbox,
+ const gchar *folder_uri,
+ EMailFolderTweaks *tweaks)
+{
+ GtkWidget *checkbox;
+ GtkWidget *button;
+ GtkWidget *image;
+ GtkWidget *hbox;
+ gchar *icon_filename;
+
+ g_return_if_fail (GTK_IS_BOX (vbox));
+ g_return_if_fail (folder_uri != NULL);
+ g_return_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks));
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
+ gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
+
+ checkbox = gtk_check_button_new_with_mnemonic (_("_Use custom icon"));
+ gtk_box_pack_start (GTK_BOX (hbox), checkbox, FALSE, FALSE, 0);
+
+ button = gtk_button_new ();
+ image = gtk_image_new_from_icon_name (NULL, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (button), image);
+ gtk_button_set_always_show_image (GTK_BUTTON (button), TRUE);
+
+ icon_filename = e_mail_folder_tweaks_dup_icon_filename (tweaks, folder_uri);
+ if (icon_filename &&
+ g_file_test (icon_filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+ GFile *file;
+ GIcon *custom_icon;
+
+ file = g_file_new_for_path (icon_filename);
+ custom_icon = g_file_icon_new (file);
+
+ g_clear_object (&file);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), TRUE);
+ gtk_image_set_from_gicon (GTK_IMAGE (image), custom_icon, GTK_ICON_SIZE_BUTTON);
+
+ g_clear_object (&custom_icon);
+ }
+
+ g_free (icon_filename);
+
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+
+ e_binding_bind_property (
+ checkbox, "active",
+ button, "sensitive",
+ G_BINDING_DEFAULT |
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect_data (checkbox, "toggled",
+ G_CALLBACK (tweaks_custom_icon_check_toggled_cb),
+ folder_tweaks_data_new (folder_uri, tweaks, button), folder_tweaks_data_free, 0);
+
+ g_signal_connect_data (button, "clicked",
+ G_CALLBACK (tweaks_custom_icon_button_clicked_cb),
+ folder_tweaks_data_new (folder_uri, tweaks, NULL), folder_tweaks_data_free, 0);
+
+ gtk_widget_show_all (hbox);
+}
+
+static void
+tweaks_text_color_check_toggled_cb (GtkToggleButton *toggle_button,
+ FolderTweaksData *ftd)
+{
+ g_return_if_fail (ftd != NULL);
+
+ if (gtk_toggle_button_get_active (toggle_button)) {
+ GdkRGBA rgba;
+
+ gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (ftd->widget), &rgba);
+
+ e_mail_folder_tweaks_set_color (ftd->tweaks, ftd->folder_uri, &rgba);
+ } else {
+ e_mail_folder_tweaks_set_color (ftd->tweaks, ftd->folder_uri, NULL);
+ }
+}
+
+static void
+tweaks_text_color_button_color_set_cb (GtkColorButton *col_button,
+ FolderTweaksData *ftd)
+{
+ GdkRGBA rgba;
+
+ g_return_if_fail (ftd != NULL);
+
+ gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (col_button), &rgba);
+
+ e_mail_folder_tweaks_set_color (ftd->tweaks, ftd->folder_uri, &rgba);
+}
+
+static void
+emfp_add_tweaks_text_color_row (GtkBox *vbox,
+ const gchar *folder_uri,
+ EMailFolderTweaks *tweaks)
+{
+ GtkWidget *checkbox;
+ GtkWidget *button;
+ GtkWidget *hbox;
+ GdkRGBA rgba;
+
+ g_return_if_fail (GTK_IS_BOX (vbox));
+ g_return_if_fail (folder_uri != NULL);
+ g_return_if_fail (E_IS_MAIL_FOLDER_TWEAKS (tweaks));
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
+ gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
+
+ checkbox = gtk_check_button_new_with_mnemonic (_("Use te_xt color"));
+ gtk_box_pack_start (GTK_BOX (hbox), checkbox, FALSE, FALSE, 0);
+
+ button = gtk_color_button_new ();
+
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+
+ if (e_mail_folder_tweaks_get_color (tweaks, folder_uri, &rgba)) {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), TRUE);
+ gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (button), &rgba);
+ }
+
+ e_binding_bind_property (
+ checkbox, "active",
+ button, "sensitive",
+ G_BINDING_DEFAULT |
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect_data (checkbox, "toggled",
+ G_CALLBACK (tweaks_text_color_check_toggled_cb),
+ folder_tweaks_data_new (folder_uri, tweaks, button), folder_tweaks_data_free, 0);
+
+ g_signal_connect_data (button, "color-set",
+ G_CALLBACK (tweaks_text_color_button_color_set_cb),
+ folder_tweaks_data_new (folder_uri, tweaks, NULL), folder_tweaks_data_free, 0);
+
+ gtk_widget_show_all (hbox);
+}
+
static void
mail_identity_combo_box_changed_cb (GtkComboBox *combo_box,
EMailSendAccountOverride *account_override)
@@ -462,6 +715,39 @@ emfp_get_folder_item (EConfig *ec,
return table;
}
+static GtkWidget *
+emfp_get_appearance_item (EConfig *ec,
+ EConfigItem *item,
+ GtkWidget *parent,
+ GtkWidget *old,
+ gint position,
+ gpointer user_data)
+{
+ AsyncContext *context = user_data;
+ GtkBox *vbox;
+ EMailFolderTweaks *tweaks;
+ gchar *folder_uri;
+
+ if (old)
+ return old;
+
+ vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6));
+ gtk_widget_show (GTK_WIDGET (vbox));
+
+ gtk_box_pack_start (GTK_BOX (parent), GTK_WIDGET (vbox), TRUE, TRUE, 0);
+
+ tweaks = e_mail_folder_tweaks_new ();
+ folder_uri = e_mail_folder_uri_from_folder (context->folder);
+
+ emfp_add_tweaks_custom_icon_row (vbox, folder_uri, tweaks);
+ emfp_add_tweaks_text_color_row (vbox, folder_uri, tweaks);
+
+ g_clear_object (&tweaks);
+ g_free (folder_uri);
+
+ return GTK_WIDGET (vbox);
+}
+
static const gchar *
emfp_autoarchive_config_to_string (EAutoArchiveConfig config)
{
@@ -1076,22 +1362,22 @@ emfp_get_labels_item (EConfig *ec,
return GTK_WIDGET (grid);
}
-#define EMFP_FOLDER_SECTION (2)
-
static EMConfigItem emfp_items[] = {
{ E_CONFIG_BOOK, (gchar *) "", NULL },
{ E_CONFIG_PAGE, (gchar *) "00.general", (gchar *) N_("General") },
{ E_CONFIG_SECTION, (gchar *) "00.general/00.folder", NULL /* set by code */ },
{ E_CONFIG_ITEM, (gchar *) "00.general/00.folder/00.info", NULL, emfp_get_folder_item },
+ { E_CONFIG_PAGE, (gchar *) "10.appearance", (gchar *) N_("Appearance") },
+ { E_CONFIG_SECTION, (gchar *) "10.appearance/00.folder", NULL },
+ { E_CONFIG_ITEM, (gchar *) "10.appearance/00.folder/00.appearance", NULL, emfp_get_appearance_item },
/* Translators: "Archive" is a noun (This is a tab heading in the mail folder properties) */
- { E_CONFIG_PAGE, (gchar *) "10.autoarchive", (gchar *) N_("Archive") },
- { E_CONFIG_SECTION, (gchar *) "10.autoarchive/00.folder", NULL },
- { E_CONFIG_ITEM, (gchar *) "10.autoarchive/00.folder/00.info", NULL, emfp_get_autoarchive_item },
- { E_CONFIG_PAGE, (gchar *) "20.labels", (gchar *) N_("Labels") },
- { E_CONFIG_SECTION, (gchar *) "20.labels/00.folder", NULL },
- { E_CONFIG_ITEM, (gchar *) "20.labels/00.folder/00.labels", NULL, emfp_get_labels_item }
+ { E_CONFIG_PAGE, (gchar *) "20.autoarchive", (gchar *) N_("Archive") },
+ { E_CONFIG_SECTION, (gchar *) "20.autoarchive/00.folder", NULL },
+ { E_CONFIG_ITEM, (gchar *) "20.autoarchive/00.folder/00.info", NULL, emfp_get_autoarchive_item },
+ { E_CONFIG_PAGE, (gchar *) "30.labels", (gchar *) N_("Labels") },
+ { E_CONFIG_SECTION, (gchar *) "30.labels/00.folder", NULL },
+ { E_CONFIG_ITEM, (gchar *) "30.labels/00.folder/00.labels", NULL, emfp_get_labels_item }
};
-static gboolean emfp_items_translated = FALSE;
static void
emfp_dialog_run (AsyncContext *context)
@@ -1107,6 +1393,7 @@ emfp_dialog_run (AsyncContext *context)
gboolean store_is_local;
gboolean hide_deleted;
GSettings *settings;
+ const gchar *folder_label;
const gchar *name;
const gchar *uid;
@@ -1152,18 +1439,17 @@ emfp_dialog_run (AsyncContext *context)
|| !strcmp (name, "Inbox")
|| !strcmp (name, "Outbox")
|| !strcmp (name, "Sent"))) {
- emfp_items[EMFP_FOLDER_SECTION].label = gettext (name);
- if (!emfp_items_translated) {
- for (i = 0; i < G_N_ELEMENTS (emfp_items); i++) {
- if (emfp_items[i].label)
- emfp_items[i].label = _(emfp_items[i].label);
- }
- emfp_items_translated = TRUE;
- }
+ folder_label = _(name);
} else if (!strcmp (name, "INBOX"))
- emfp_items[EMFP_FOLDER_SECTION].label = _("Inbox");
+ folder_label = _("Inbox");
else
- emfp_items[EMFP_FOLDER_SECTION].label = (gchar *) name;
+ folder_label = name;
+
+ for (i = 0; i < G_N_ELEMENTS (emfp_items); i++) {
+ if (emfp_items[i].type == E_CONFIG_SECTION &&
+ g_str_has_suffix (emfp_items[i].path, "/00.folder"))
+ emfp_items[i].label = (gchar *) folder_label;
+ }
dialog = gtk_dialog_new_with_buttons (
_("Folder Properties"),
diff --git a/src/mail/em-folder-tree-model.c b/src/mail/em-folder-tree-model.c
index a1d2b74c00..cc56965ed9 100644
--- a/src/mail/em-folder-tree-model.c
+++ b/src/mail/em-folder-tree-model.c
@@ -64,6 +64,8 @@ struct _EMFolderTreeModelPrivate {
/* CamelStore -> StoreInfo */
GHashTable *store_index;
GMutex store_index_lock;
+
+ EMailFolderTweaks *folder_tweaks;
};
typedef struct _FolderUnreadInfo {
@@ -523,8 +525,18 @@ folder_tree_model_service_removed (EMailAccountStore *account_store,
CamelService *service,
EMFolderTreeModel *folder_tree_model)
{
+ EMailFolderTweaks *tweaks;
+ gchar *top_folder_uri;
+
em_folder_tree_model_remove_store (
folder_tree_model, CAMEL_STORE (service));
+
+ top_folder_uri = e_mail_folder_uri_build (CAMEL_STORE (service), "");
+ tweaks = em_folder_tree_model_get_folder_tweaks (folder_tree_model);
+
+ e_mail_folder_tweaks_remove_for_folders (tweaks, top_folder_uri);
+
+ g_free (top_folder_uri);
}
static void
@@ -586,6 +598,44 @@ folder_tree_model_spinner_pulse_cb (gpointer user_data)
return G_SOURCE_CONTINUE;
}
+static gboolean
+em_folder_tree_model_update_tweaks_foreach_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ const gchar *given_folder_uri = user_data;
+ gchar *stored_folder_uri = NULL;
+
+ gtk_tree_model_get (model, iter, COL_STRING_FOLDER_URI, &stored_folder_uri, -1);
+
+ if (!stored_folder_uri ||
+ g_strcmp0 (stored_folder_uri, given_folder_uri) != 0) {
+ g_free (stored_folder_uri);
+ return FALSE;
+ }
+
+ g_free (stored_folder_uri);
+
+ em_folder_tree_model_update_row_tweaks (EM_FOLDER_TREE_MODEL (model), iter);
+
+ return TRUE;
+}
+
+static void
+em_folder_tree_model_folder_tweaks_changed_cb (EMailFolderTweaks *tweaks,
+ const gchar *folder_uri,
+ gpointer user_data)
+{
+ EMFolderTreeModel *model = user_data;
+
+ g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+ g_return_if_fail (folder_uri != NULL);
+
+ gtk_tree_model_foreach (GTK_TREE_MODEL (model),
+ em_folder_tree_model_update_tweaks_foreach_cb, (gpointer) folder_uri);
+}
+
static void
folder_tree_model_selection_finalized_cb (EMFolderTreeModel *model)
{
@@ -676,6 +726,9 @@ folder_tree_model_dispose (GObject *object)
priv->account_store = NULL;
}
+ g_signal_handlers_disconnect_by_func (priv->folder_tweaks,
+ em_folder_tree_model_folder_tweaks_changed_cb, object);
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (em_folder_tree_model_parent_class)->dispose (object);
}
@@ -689,6 +742,7 @@ folder_tree_model_finalize (GObject *object)
g_hash_table_destroy (priv->store_index);
g_mutex_clear (&priv->store_index_lock);
+ g_clear_object (&priv->folder_tweaks);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (em_folder_tree_model_parent_class)->finalize (object);
@@ -713,8 +767,13 @@ folder_tree_model_constructed (GObject *object)
G_TYPE_BOOLEAN, /* status icon visible */
G_TYPE_UINT, /* status spinner pulse */
G_TYPE_BOOLEAN, /* status spinner visible */
+ G_TYPE_STRING, /* COL_STRING_FOLDER_URI */
+ G_TYPE_ICON, /* COL_GICON_CUSTOM_ICON */
+ GDK_TYPE_RGBA /* COL_RGBA_FOREGROUND_RGBA */
};
+ g_warn_if_fail (G_N_ELEMENTS (col_types) == NUM_COLUMNS);
+
gtk_tree_store_set_column_types (
GTK_TREE_STORE (object), NUM_COLUMNS, col_types);
gtk_tree_sortable_set_default_sort_func (
@@ -917,8 +976,12 @@ em_folder_tree_model_init (EMFolderTreeModel *model)
model->priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (model);
model->priv->store_index = store_index;
+ model->priv->folder_tweaks = e_mail_folder_tweaks_new ();
g_mutex_init (&model->priv->store_index_lock);
+
+ g_signal_connect (model->priv->folder_tweaks, "changed",
+ G_CALLBACK (em_folder_tree_model_folder_tweaks_changed_cb), model);
}
EMFolderTreeModel *
@@ -960,6 +1023,14 @@ em_folder_tree_model_free_default (void)
em_folder_tree_manage_default (FALSE);
}
+EMailFolderTweaks *
+em_folder_tree_model_get_folder_tweaks (EMFolderTreeModel *model)
+{
+ g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
+
+ return model->priv->folder_tweaks;
+}
+
GtkTreeSelection *
em_folder_tree_model_get_selection (EMFolderTreeModel *model)
{
@@ -1301,8 +1372,11 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
COL_BOOL_LOAD_SUBDIRS, load,
COL_UINT_UNREAD_LAST_SEL, 0,
COL_BOOL_IS_DRAFT, folder_is_drafts,
+ COL_STRING_FOLDER_URI, uri,
-1);
+ em_folder_tree_model_update_row_tweaks (model, iter);
+
g_free (uri);
uri = NULL;
@@ -1948,3 +2022,45 @@ em_folder_tree_model_user_marked_unread (EMFolderTreeModel *model,
COL_UINT_UNREAD_LAST_SEL, unread,
COL_UINT_UNREAD, unread, -1);
}
+
+void
+em_folder_tree_model_update_row_tweaks (EMFolderTreeModel *model,
+ GtkTreeIter *iter)
+{
+ GIcon *custom_icon = NULL;
+ GdkRGBA *foreground = NULL, rgba;
+ gchar *folder_uri = NULL, *icon_filename;
+
+ g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+ g_return_if_fail (iter != NULL);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
+ COL_STRING_FOLDER_URI, &folder_uri,
+ -1);
+
+ if (!folder_uri)
+ return;
+
+ if (e_mail_folder_tweaks_get_color (model->priv->folder_tweaks, folder_uri, &rgba))
+ foreground = &rgba;
+
+ icon_filename = e_mail_folder_tweaks_dup_icon_filename (model->priv->folder_tweaks, folder_uri);
+ if (icon_filename &&
+ g_file_test (icon_filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+ GFile *file;
+
+ file = g_file_new_for_path (icon_filename);
+ custom_icon = g_file_icon_new (file);
+
+ g_clear_object (&file);
+ }
+
+ gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ COL_GICON_CUSTOM_ICON, custom_icon,
+ COL_RGBA_FOREGROUND_RGBA, foreground,
+ -1);
+
+ g_clear_object (&custom_icon);
+ g_free (icon_filename);
+ g_free (folder_uri);
+}
diff --git a/src/mail/em-folder-tree-model.h b/src/mail/em-folder-tree-model.h
index 325e3a5ad8..0d9c5b99cf 100644
--- a/src/mail/em-folder-tree-model.h
+++ b/src/mail/em-folder-tree-model.h
@@ -27,6 +27,8 @@
#include <libemail-engine/libemail-engine.h>
+#include <mail/e-mail-folder-tweaks.h>
+
/* Standard GObject macros */
#define EM_TYPE_FOLDER_TREE_MODEL \
(em_folder_tree_model_get_type ())
@@ -57,7 +59,7 @@ enum {
COL_OBJECT_CAMEL_STORE, /* CamelStore object */
COL_STRING_FULL_NAME, /* if node is a folder, the full path
* name of the folder, no leading / */
- COL_STRING_ICON_NAME, /* icon name for the folder */
+ COL_STRING_ICON_NAME, /* icon name for the folder, see COL_GICON_CUSTOM_ICON */
COL_UINT_UNREAD, /* unread count */
COL_UINT_FLAGS, /* FolderInfo.flags */
@@ -75,6 +77,10 @@ enum {
COL_STATUS_SPINNER_PULSE,
COL_STATUS_SPINNER_VISIBLE,
+ COL_STRING_FOLDER_URI, /* folder URI */
+ COL_GICON_CUSTOM_ICON, /* a custom icon to use for the folder; NULL to use
COL_STRING_ICON_NAME */
+ COL_RGBA_FOREGROUND_RGBA, /* GdkRGBA for the foreground color; can be NULL */
+
NUM_COLUMNS
};
@@ -102,6 +108,9 @@ EMFolderTreeModel *
EMFolderTreeModel *
em_folder_tree_model_get_default (void);
void em_folder_tree_model_free_default (void);
+EMailFolderTweaks *
+ em_folder_tree_model_get_folder_tweaks
+ (EMFolderTreeModel *model);
GtkTreeSelection *
em_folder_tree_model_get_selection
(EMFolderTreeModel *model);
@@ -146,6 +155,9 @@ void em_folder_tree_model_user_marked_unread
(EMFolderTreeModel *model,
CamelFolder *folder,
guint n_marked);
+void em_folder_tree_model_update_row_tweaks
+ (EMFolderTreeModel *model,
+ GtkTreeIter *iter);
G_END_DECLS
diff --git a/src/mail/em-folder-tree.c b/src/mail/em-folder-tree.c
index 3a9dd2eacf..9dc305c700 100644
--- a/src/mail/em-folder-tree.c
+++ b/src/mail/em-folder-tree.c
@@ -893,15 +893,13 @@ folder_tree_render_icon (GtkTreeViewColumn *column,
GtkTreeIter *iter)
{
GtkTreeSelection *selection;
- GtkTreePath *drag_dest_row;
GtkWidget *tree_view;
- GIcon *icon;
+ GIcon *icon, *custom_icon = NULL;
guint unread;
guint old_unread;
gchar *icon_name;
gboolean is_selected;
gboolean is_drafts = FALSE;
- gboolean is_drag_dest = FALSE;
gboolean show_new_mail_emblem;
guint32 fi_flags = 0;
@@ -912,29 +910,32 @@ folder_tree_render_icon (GtkTreeViewColumn *column,
COL_UINT_UNREAD, &unread,
COL_BOOL_IS_DRAFT, &is_drafts,
COL_UINT_FLAGS, &fi_flags,
+ COL_GICON_CUSTOM_ICON, &custom_icon,
-1);
- if (icon_name == NULL)
+ if (!icon_name && !custom_icon)
return;
tree_view = gtk_tree_view_column_get_tree_view (column);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
is_selected = gtk_tree_selection_iter_is_selected (selection, iter);
- gtk_tree_view_get_drag_dest_row (
- GTK_TREE_VIEW (tree_view), &drag_dest_row, NULL);
- if (drag_dest_row != NULL) {
- GtkTreePath *path;
+ if (!custom_icon && g_strcmp0 (icon_name, "folder") == 0) {
+ GtkTreePath *drag_dest_row;
+ gboolean is_drag_dest = FALSE;
- path = gtk_tree_model_get_path (model, iter);
- if (gtk_tree_path_compare (path, drag_dest_row) == 0)
- is_drag_dest = TRUE;
- gtk_tree_path_free (path);
+ gtk_tree_view_get_drag_dest_row (GTK_TREE_VIEW (tree_view), &drag_dest_row, NULL);
+ if (drag_dest_row != NULL) {
+ GtkTreePath *path;
- gtk_tree_path_free (drag_dest_row);
- }
+ path = gtk_tree_model_get_path (model, iter);
+ if (gtk_tree_path_compare (path, drag_dest_row) == 0)
+ is_drag_dest = TRUE;
+ gtk_tree_path_free (path);
+
+ gtk_tree_path_free (drag_dest_row);
+ }
- if (g_strcmp0 (icon_name, "folder") == 0) {
if (is_selected) {
g_free (icon_name);
icon_name = g_strdup ("folder-open");
@@ -944,7 +945,10 @@ folder_tree_render_icon (GtkTreeViewColumn *column,
}
}
- icon = g_themed_icon_new (icon_name);
+ if (custom_icon)
+ icon = g_object_ref (custom_icon);
+ else
+ icon = g_themed_icon_new (icon_name);
show_new_mail_emblem =
(unread > old_unread) &&
@@ -969,6 +973,7 @@ folder_tree_render_icon (GtkTreeViewColumn *column,
g_object_set (renderer, "gicon", icon, NULL);
+ g_clear_object (&custom_icon);
g_object_unref (icon);
g_free (icon_name);
}
@@ -1333,6 +1338,8 @@ folder_tree_constructed (GObject *object)
renderer = priv->text_renderer;
g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_add_attribute (
+ column, renderer, "foreground-rgba", COL_RGBA_FOREGROUND_RGBA);
gtk_tree_view_column_set_cell_data_func (
column, renderer, (GtkTreeCellDataFunc)
folder_tree_render_display_name, NULL, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]