[evolution] I#406 - Use a special icon for a configured Archive folder



commit 2fa97de820634ac002784165bb122bc32e651235
Author: Milan Crha <mcrha redhat com>
Date:   Tue Apr 23 21:02:28 2019 +0200

    I#406 - Use a special icon for a configured Archive folder
    
    Closes https://gitlab.gnome.org/GNOME/evolution/issues/406

 src/libemail-engine/e-mail-session.c | 290 ++++++++++++++++++++++++++++++++
 src/libemail-engine/e-mail-session.h |  10 +-
 src/mail/em-folder-tree-model.c      | 316 +++++++++++++++++++++++++----------
 3 files changed, 525 insertions(+), 91 deletions(-)
---
diff --git a/src/libemail-engine/e-mail-session.c b/src/libemail-engine/e-mail-session.c
index 9dd93cea63..40e53395ce 100644
--- a/src/libemail-engine/e-mail-session.c
+++ b/src/libemail-engine/e-mail-session.c
@@ -88,6 +88,9 @@ struct _EMailSessionPrivate {
        GMutex used_services_lock;
        GCond used_services_cond;
        GHashTable *used_services;
+
+       GMutex archive_folders_hash_lock;
+       GHashTable *archive_folders_hash; /* ESource::uid ~> archive folder URI */
 };
 
 struct _AsyncContext {
@@ -129,6 +132,7 @@ enum {
        STORE_REMOVED,
        ALLOW_AUTH_PROMPT,
        GET_RECIPIENT_CERTIFICATE,
+       ARCHIVE_FOLDER_CHANGED,
        LAST_SIGNAL
 };
 
@@ -350,6 +354,152 @@ mail_session_resolve_popb4smtp (ESourceRegistry *registry,
        return pop_uid;
 }
 
+typedef struct _ArchiveFolderChangedData {
+       GWeakRef *session;
+       gchar *service_uid;
+       gchar *old_folder_uri;
+       gchar *new_folder_uri;
+} ArchiveFolderChangedData;
+
+static void
+archived_folder_changed_data_free (gpointer ptr)
+{
+       ArchiveFolderChangedData *data = ptr;
+
+       if (data) {
+               e_weak_ref_free (data->session);
+               g_free (data->service_uid);
+               g_free (data->old_folder_uri);
+               g_free (data->new_folder_uri);
+               g_free (data);
+       }
+}
+
+static gboolean
+mail_session_emit_archive_folder_changed_idle (gpointer user_data)
+{
+       ArchiveFolderChangedData *data = user_data;
+       EMailSession *session;
+
+       g_return_val_if_fail (data != NULL, FALSE);
+
+       session = g_weak_ref_get (data->session);
+       if (session) {
+               g_signal_emit (session, signals[ARCHIVE_FOLDER_CHANGED], 0,
+                       data->service_uid, data->old_folder_uri, data->new_folder_uri);
+
+               g_object_unref (session);
+       }
+
+       return FALSE;
+}
+
+static void
+mail_session_schedule_archive_folder_changed_locked (EMailSession *session,
+                                                    const gchar *service_uid,
+                                                    const gchar *old_folder_uri,
+                                                    const gchar *new_folder_uri)
+{
+       ArchiveFolderChangedData *data;
+
+       data = g_new0 (ArchiveFolderChangedData, 1);
+       data->session = e_weak_ref_new (session);
+       data->service_uid = g_strdup (service_uid);
+       data->old_folder_uri = g_strdup (old_folder_uri);
+       data->new_folder_uri = g_strdup (new_folder_uri);
+
+       g_idle_add_full (G_PRIORITY_LOW, mail_session_emit_archive_folder_changed_idle,
+               data, archived_folder_changed_data_free);
+}
+
+static void
+mail_session_remember_archive_folder (EMailSession *session,
+                                     const gchar *uid,
+                                     const gchar *folder_uri)
+{
+       g_return_if_fail (E_IS_MAIL_SESSION (session));
+       g_return_if_fail (uid != NULL);
+
+       g_mutex_lock (&session->priv->archive_folders_hash_lock);
+
+       if (session->priv->archive_folders_hash) {
+               gchar *old_folder_uri;
+
+               old_folder_uri = g_strdup (g_hash_table_lookup (session->priv->archive_folders_hash, uid));
+
+               if (g_strcmp0 (old_folder_uri, folder_uri) != 0) {
+                       g_hash_table_insert (session->priv->archive_folders_hash, g_strdup (uid), g_strdup 
(folder_uri));
+
+                       mail_session_schedule_archive_folder_changed_locked (session, uid, old_folder_uri, 
folder_uri);
+               }
+
+               g_free (old_folder_uri);
+       }
+
+       g_mutex_unlock (&session->priv->archive_folders_hash_lock);
+}
+
+static void
+mail_session_forget_archive_folder (EMailSession *session,
+                                   const gchar *uid)
+{
+       g_return_if_fail (E_IS_MAIL_SESSION (session));
+       g_return_if_fail (uid != NULL);
+
+       g_mutex_lock (&session->priv->archive_folders_hash_lock);
+
+       if (session->priv->archive_folders_hash) {
+               gchar *old_folder_uri;
+
+               old_folder_uri = g_strdup (g_hash_table_lookup (session->priv->archive_folders_hash, uid));
+
+               g_hash_table_remove (session->priv->archive_folders_hash, uid);
+
+               if (old_folder_uri && *old_folder_uri)
+                       mail_session_schedule_archive_folder_changed_locked (session, uid, old_folder_uri, 
NULL);
+
+               g_free (old_folder_uri);
+       }
+
+       g_mutex_unlock (&session->priv->archive_folders_hash_lock);
+}
+
+static void
+mail_session_archive_folder_notify_cb (ESourceExtension *extension,
+                                      GParamSpec *param,
+                                      EMailSession *session)
+{
+       ESource *source;
+
+       g_return_if_fail (E_IS_MAIL_SESSION (session));
+
+       source = e_source_extension_ref_source (extension);
+       if (source) {
+               gchar *archive_folder;
+
+               archive_folder = e_source_mail_account_dup_archive_folder (E_SOURCE_MAIL_ACCOUNT (extension));
+
+               mail_session_remember_archive_folder (session, e_source_get_uid (source), archive_folder);
+
+               g_free (archive_folder);
+               g_object_unref (source);
+       }
+}
+
+static void
+mail_session_local_archive_folder_changed_cb (GSettings *settings,
+                                             const gchar *key,
+                                             EMailSession *session)
+{
+       gchar *local_archive_folder;
+
+       g_return_if_fail (E_IS_MAIL_SESSION (session));
+
+       local_archive_folder = g_settings_get_string (settings, "local-archive-folder");
+       mail_session_remember_archive_folder (session, E_MAIL_SESSION_LOCAL_UID, local_archive_folder);
+       g_free (local_archive_folder);
+}
+
 static void
 mail_session_refresh_cb (ESource *source,
                          EMailSession *session)
@@ -465,6 +615,20 @@ mail_session_add_from_source (EMailSession *session,
                CAMEL_SESSION (session), uid,
                backend_name, type, &error);
 
+       if (type == CAMEL_PROVIDER_STORE &&
+           e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT)) {
+               ESourceMailAccount *extension;
+               gchar *archive_folder_uri;
+
+               extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+               archive_folder_uri = e_source_mail_account_dup_archive_folder (extension);
+               mail_session_remember_archive_folder (session, e_source_get_uid (source), archive_folder_uri);
+               g_free (archive_folder_uri);
+
+               g_signal_connect (extension, "notify::archive-folder",
+                       G_CALLBACK (mail_session_archive_folder_notify_cb), session);
+       }
+
        /* Our own CamelSession.add_service() method will handle the
         * new CamelService, so we only need to unreference it here. */
        if (service != NULL)
@@ -532,6 +696,17 @@ mail_session_source_removed_cb (ESourceRegistry *registry,
        uid = e_source_get_uid (source);
        service = camel_session_ref_service (camel_session, uid);
 
+       if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT)) {
+               ESourceMailAccount *extension;
+
+               extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+
+               g_signal_handlers_disconnect_by_func (extension,
+                       G_CALLBACK (mail_session_archive_folder_notify_cb), session);
+
+               mail_session_forget_archive_folder (session, e_source_get_uid (source));
+       }
+
        if (service != NULL) {
                camel_session_remove_service (camel_session, service);
                g_object_unref (service);
@@ -920,6 +1095,7 @@ static void
 mail_session_dispose (GObject *object)
 {
        EMailSessionPrivate *priv;
+       GSettings *settings;
 
        priv = E_MAIL_SESSION_GET_PRIVATE (object);
 
@@ -965,6 +1141,38 @@ mail_session_dispose (GObject *object)
                priv->vfolder_store = NULL;
        }
 
+       g_mutex_lock (&priv->archive_folders_hash_lock);
+
+       if (priv->archive_folders_hash) {
+               if (priv->registry) {
+                       GHashTableIter iter;
+                       gpointer key;
+
+                       g_hash_table_iter_init (&iter, priv->archive_folders_hash);
+                       while (g_hash_table_iter_next (&iter, &key, NULL)) {
+                               ESource *source;
+
+                               source = e_source_registry_ref_source (priv->registry, key);
+                               if (source) {
+                                       if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT)) 
{
+                                               ESourceExtension *extension;
+
+                                               extension = e_source_get_extension (source, 
E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+
+                                               g_signal_handlers_disconnect_by_func (extension,
+                                                       G_CALLBACK (mail_session_archive_folder_notify_cb), 
object);
+                                       }
+                                       g_object_unref (source);
+                               }
+                       }
+               }
+
+               g_hash_table_destroy (priv->archive_folders_hash);
+               priv->archive_folders_hash = NULL;
+       }
+
+       g_mutex_unlock (&priv->archive_folders_hash_lock);
+
        if (priv->registry != NULL) {
                g_signal_handler_disconnect (
                        priv->registry,
@@ -989,6 +1197,13 @@ mail_session_dispose (GObject *object)
                priv->registry = NULL;
        }
 
+       settings = e_util_ref_settings ("org.gnome.evolution.mail");
+
+       g_signal_handlers_disconnect_by_func (settings,
+               G_CALLBACK (mail_session_local_archive_folder_changed_cb), object);
+
+       g_object_unref (settings);
+
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (e_mail_session_parent_class)->dispose (object);
 }
@@ -1009,6 +1224,7 @@ mail_session_finalize (GObject *object)
 
        g_mutex_clear (&priv->preparing_flush_lock);
        g_mutex_clear (&priv->used_services_lock);
+       g_mutex_clear (&priv->archive_folders_hash_lock);
        g_cond_clear (&priv->used_services_cond);
 
        g_free (mail_data_dir);
@@ -1029,6 +1245,7 @@ mail_session_constructed (GObject *object)
        GSettings *settings;
        CamelProviderType provider_type;
        const gchar *extension_name;
+       gchar *local_archive_folder;
        gulong handler_id;
 
        session = E_MAIL_SESSION (object);
@@ -1165,6 +1382,13 @@ mail_session_constructed (GObject *object)
                        g_object_ref (session),
                        (GDestroyNotify) g_object_unref);
 
+       g_signal_connect (settings, "changed::local-archive-folder",
+               G_CALLBACK (mail_session_local_archive_folder_changed_cb), session);
+
+       local_archive_folder = g_settings_get_string (settings, "local-archive-folder");
+       mail_session_remember_archive_folder (session, E_MAIL_SESSION_LOCAL_UID, local_archive_folder);
+       g_free (local_archive_folder);
+
        g_object_unref (settings);
 }
 
@@ -1890,6 +2114,29 @@ e_mail_session_class_init (EMailSessionClass *class)
                G_TYPE_STRING, 2,
                G_TYPE_UINT,
                G_TYPE_STRING);
+
+       /**
+        * EMailSession::archive-folder-changed
+        * @session: the #EMailSession that emitted the signal
+        * @service_uid: UID of a #CamelService, whose archive folder setting changed
+        * @old_folder_uri: (nullable): an old archive folder URI, or %NULL, when none had been set already
+        * @new_folder_uri: (nullable): a new archive folder URI, or %NULL, when none had been set
+        *
+        * Notifies about changes in archive folders setup.
+        *
+        * Since: 3.34
+        **/
+       signals[ARCHIVE_FOLDER_CHANGED] = g_signal_new (
+               "archive-folder-changed",
+               G_OBJECT_CLASS_TYPE (object_class),
+               G_SIGNAL_RUN_FIRST,
+               G_STRUCT_OFFSET (EMailSessionClass, archive_folder_changed),
+               NULL, NULL,
+               NULL,
+               G_TYPE_NONE, 3,
+               G_TYPE_STRING,
+               G_TYPE_STRING,
+               G_TYPE_STRING);
 }
 
 static void
@@ -1924,9 +2171,12 @@ e_mail_session_init (EMailSession *session)
        session->priv->local_folder_uris =
                g_ptr_array_new_with_free_func (
                (GDestroyNotify) g_free);
+       session->priv->archive_folders_hash =
+               g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
        g_mutex_init (&session->priv->preparing_flush_lock);
        g_mutex_init (&session->priv->used_services_lock);
+       g_mutex_init (&session->priv->archive_folders_hash_lock);
        g_cond_init (&session->priv->used_services_cond);
 
        session->priv->used_services = g_hash_table_new (g_direct_hash, g_direct_equal);
@@ -2702,3 +2952,43 @@ e_mail_session_emit_allow_auth_prompt (EMailSession *session,
 
        g_signal_emit (session, signals[ALLOW_AUTH_PROMPT], 0, source);
 }
+
+/**
+ * e_mail_session_is_archive_folder:
+ * @session: an #EMailSession
+ * @folder_uri: a folder URI
+ *
+ * Returns: whether the @folder_uri is one of configured archive folders
+ *
+ * Since: 3.34
+ **/
+gboolean
+e_mail_session_is_archive_folder (EMailSession *session,
+                                 const gchar *folder_uri)
+{
+       CamelSession *camel_session;
+       GHashTableIter iter;
+       gpointer value;
+       gboolean is_archive_folder = FALSE;
+
+       g_return_val_if_fail (E_IS_MAIL_SESSION (session), FALSE);
+
+       if (!folder_uri || !*folder_uri)
+               return FALSE;
+
+       camel_session = CAMEL_SESSION (session);
+
+       g_mutex_lock (&session->priv->archive_folders_hash_lock);
+
+       g_hash_table_iter_init (&iter, session->priv->archive_folders_hash);
+       while (!is_archive_folder && g_hash_table_iter_next (&iter, NULL, &value)) {
+               const gchar *uri = value;
+
+               if (uri && *uri)
+                       is_archive_folder = e_mail_folder_uri_equal (camel_session, folder_uri, uri);
+       }
+
+       g_mutex_unlock (&session->priv->archive_folders_hash_lock);
+
+       return is_archive_folder;
+}
diff --git a/src/libemail-engine/e-mail-session.h b/src/libemail-engine/e-mail-session.h
index 7d72b31045..0e4f20d871 100644
--- a/src/libemail-engine/e-mail-session.h
+++ b/src/libemail-engine/e-mail-session.h
@@ -88,8 +88,13 @@ struct _EMailSessionClass {
                                                (EMailSession *session,
                                                 guint flags, /* bit-or of CamelRecipientCertificateFlags */
                                                 const gchar *email_address);
+       void            (*archive_folder_changed)
+                                               (EMailSession *session,
+                                                const gchar *service_uid,
+                                                const gchar *old_folder_uri,
+                                                const gchar *new_folder_uri);
        /* Padding for future expansion */
-       gpointer reserved[10];
+       gpointer reserved[9];
 };
 
 GType          e_mail_session_get_type         (void);
@@ -175,6 +180,9 @@ void                e_mail_session_unmark_service_used
 void           e_mail_session_emit_allow_auth_prompt
                                                (EMailSession *session,
                                                 ESource *source);
+gboolean       e_mail_session_is_archive_folder
+                                               (EMailSession *session,
+                                                const gchar *folder_uri);
 
 /* Useful GBinding transform functions */
 gboolean       e_binding_transform_service_to_source
diff --git a/src/mail/em-folder-tree-model.c b/src/mail/em-folder-tree-model.c
index 8269745644..8014c604e2 100644
--- a/src/mail/em-folder-tree-model.c
+++ b/src/mail/em-folder-tree-model.c
@@ -646,6 +646,223 @@ em_folder_tree_model_folder_tweaks_changed_cb (EMailFolderTweaks *tweaks,
                em_folder_tree_model_update_tweaks_foreach_cb, (gpointer) folder_uri);
 }
 
+static void
+folder_tree_model_get_special_folders_uri (ESourceRegistry *registry,
+                                          CamelStore *store,
+                                          gchar **drafts_folder_uri,
+                                          gchar **templates_folder_uri,
+                                          gchar **sent_folder_uri)
+{
+       ESource *source;
+       const gchar *extension_name;
+
+       /* In case we fail... */
+       *drafts_folder_uri = NULL;
+       *templates_folder_uri = NULL;
+       *sent_folder_uri = NULL;
+
+       source = em_utils_ref_mail_identity_for_store (registry, store);
+       if (source == NULL)
+               return;
+
+       extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+       if (e_source_has_extension (source, extension_name)) {
+               ESourceMailComposition *extension;
+
+               extension = e_source_get_extension (source, extension_name);
+
+               *drafts_folder_uri = e_source_mail_composition_dup_drafts_folder (extension);
+               *templates_folder_uri = e_source_mail_composition_dup_templates_folder (extension);
+       }
+
+       extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+       if (e_source_has_extension (source, extension_name)) {
+               ESourceMailSubmission *extension;
+
+               extension = e_source_get_extension (source, extension_name);
+
+               if (e_source_mail_submission_get_use_sent_folder (extension))
+                       *sent_folder_uri = e_source_mail_submission_dup_sent_folder (extension);
+       }
+
+       g_object_unref (source);
+}
+
+static const gchar *
+em_folder_tree_model_get_icon_name_for_folder_uri (EMFolderTreeModel *model,
+                                                  const gchar *folder_uri,
+                                                  CamelStore *store,
+                                                  const gchar *full_name,
+                                                  guint32 folder_flags)
+{
+       const gchar *icon_name = "folder";
+       CamelFolder *folder;
+       EMailSession *session;
+       MailFolderCache *folder_cache;
+       guint32 add_flags = 0;
+       gboolean folder_is_drafts = FALSE;
+       gboolean folder_is_templates = FALSE;
+       gboolean folder_is_archive = FALSE;
+
+       g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), icon_name);
+       g_return_val_if_fail (CAMEL_IS_STORE (store), icon_name);
+       g_return_val_if_fail (folder_uri != NULL, icon_name);
+
+       session = em_folder_tree_model_get_session (model);
+       if (!session)
+               return icon_name;
+
+       folder_cache = e_mail_session_get_folder_cache (session);
+
+       folder_is_archive = e_mail_session_is_archive_folder (session, folder_uri);
+
+       folder = mail_folder_cache_ref_folder (folder_cache, store, full_name);
+       if (folder) {
+               folder_is_drafts = em_utils_folder_is_drafts (e_mail_session_get_registry (session), folder);
+
+               g_object_unref (folder);
+       }
+
+       if (g_strcmp0 (camel_service_get_uid (CAMEL_SERVICE (store)), E_MAIL_SESSION_LOCAL_UID) == 0) {
+               if (strcmp (full_name, "Drafts") == 0) {
+                       folder_is_drafts = TRUE;
+               } else if (strcmp (full_name, "Templates") == 0) {
+                       folder_is_templates = TRUE;
+               } else if (strcmp (full_name, "Inbox") == 0) {
+                       folder_flags = (folder_flags & ~CAMEL_FOLDER_TYPE_MASK) | CAMEL_FOLDER_TYPE_INBOX;
+               } else if (strcmp (full_name, "Outbox") == 0) {
+                       folder_flags = (folder_flags & ~CAMEL_FOLDER_TYPE_MASK) | CAMEL_FOLDER_TYPE_OUTBOX;
+               } else if (strcmp (full_name, "Sent") == 0) {
+                       folder_flags = (folder_flags & ~CAMEL_FOLDER_TYPE_MASK) | CAMEL_FOLDER_TYPE_SENT;
+               }
+       }
+
+       if ((folder_flags & CAMEL_FOLDER_TYPE_MASK) == 0) {
+               gchar *drafts_folder_uri;
+               gchar *templates_folder_uri;
+               gchar *sent_folder_uri;
+
+               folder_tree_model_get_special_folders_uri (e_mail_session_get_registry (session), store,
+                       &drafts_folder_uri, &templates_folder_uri, &sent_folder_uri);
+
+               if (!folder_is_drafts && drafts_folder_uri != NULL) {
+                       folder_is_drafts = e_mail_folder_uri_equal (
+                               CAMEL_SESSION (session),
+                               folder_uri, drafts_folder_uri);
+               }
+
+               if (!folder_is_templates && templates_folder_uri != NULL) {
+                       folder_is_templates = e_mail_folder_uri_equal (
+                               CAMEL_SESSION (session),
+                               folder_uri, templates_folder_uri);
+               }
+
+               if (sent_folder_uri != NULL) {
+                       if (e_mail_folder_uri_equal (
+                               CAMEL_SESSION (session),
+                               folder_uri, sent_folder_uri)) {
+                               add_flags = CAMEL_FOLDER_TYPE_SENT;
+                       }
+               }
+
+               g_free (drafts_folder_uri);
+               g_free (templates_folder_uri);
+               g_free (sent_folder_uri);
+       }
+
+       /* Choose an icon name for the folder. */
+       icon_name = em_folder_utils_get_icon_name (folder_flags | add_flags);
+
+       if (g_str_equal (icon_name, "folder")) {
+               if (folder_is_drafts)
+                       icon_name = "accessories-text-editor";
+               else if (folder_is_templates)
+                       icon_name = "text-x-generic-template";
+               else if (folder_is_archive)
+                       icon_name = "mail-archive";
+       }
+
+       return icon_name;
+}
+
+static void
+em_folder_tree_model_update_folder_icon (EMFolderTreeModel *model,
+                                        const gchar *folder_uri)
+{
+       EMailSession *session;
+       CamelStore *store = NULL;
+       gchar *full_name = NULL;
+       GtkTreeRowReference *row;
+
+       g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+       g_return_if_fail (folder_uri != NULL);
+
+       session = em_folder_tree_model_get_session (model);
+       if (!session)
+               return;
+
+       if (!e_mail_folder_uri_parse (CAMEL_SESSION (session), folder_uri, &store, &full_name, NULL))
+               return;
+
+       row = em_folder_tree_model_get_row_reference (model, store, full_name);
+       if (row) {
+               EMEventTargetCustomIcon *target;
+               GtkTreeModel *tree_model;
+               GtkTreePath *path;
+               GtkTreeIter iter;
+               gchar *old_icon_name = NULL;
+               const gchar *new_icon_name;
+               guint32 folder_flags = 0;
+
+               tree_model = GTK_TREE_MODEL (model);
+
+               path = gtk_tree_row_reference_get_path (row);
+               gtk_tree_model_get_iter (tree_model, &iter, path);
+               gtk_tree_path_free (path);
+
+               gtk_tree_model_get (tree_model, &iter,
+                       COL_UINT_FLAGS, &folder_flags,
+                       COL_STRING_ICON_NAME, &old_icon_name,
+                       -1);
+
+               new_icon_name = em_folder_tree_model_get_icon_name_for_folder_uri (model, folder_uri, store, 
full_name, folder_flags);
+
+               if (g_strcmp0 (old_icon_name, new_icon_name) != 0) {
+                       gtk_tree_store_set (
+                               GTK_TREE_STORE (model), &iter,
+                               COL_STRING_ICON_NAME, new_icon_name, -1);
+               }
+
+               g_free (old_icon_name);
+
+               target = em_event_target_new_custom_icon (
+                       em_event_peek (), GTK_TREE_STORE (model), &iter,
+                       full_name, EM_EVENT_CUSTOM_ICON);
+               e_event_emit (
+                       (EEvent *) em_event_peek (), "folder.customicon",
+                       (EEventTarget *) target);
+       }
+
+       g_clear_object (&store);
+       g_clear_pointer (&full_name, g_free);
+}
+
+static void
+em_folder_tree_model_archive_folder_changed_cb (EMailSession *session,
+                                               const gchar *service_uid,
+                                               const gchar *old_folder_uri,
+                                               const gchar *new_folder_uri,
+                                               EMFolderTreeModel *model)
+{
+       g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+
+       if (old_folder_uri && *old_folder_uri)
+               em_folder_tree_model_update_folder_icon (model, old_folder_uri);
+
+       if (new_folder_uri && *new_folder_uri)
+               em_folder_tree_model_update_folder_icon (model, new_folder_uri);
+}
+
 static void
 folder_tree_model_selection_finalized_cb (EMFolderTreeModel *model)
 {
@@ -1105,9 +1322,9 @@ em_folder_tree_model_set_session (EMFolderTreeModel *model,
                MailFolderCache *folder_cache;
 
                folder_cache = e_mail_session_get_folder_cache (model->priv->session);
-               g_signal_handlers_disconnect_matched (
-                       folder_cache, G_SIGNAL_MATCH_DATA,
-                       0, 0, NULL, NULL, model);
+               g_signal_handlers_disconnect_by_data (folder_cache, model);
+
+               g_signal_handlers_disconnect_by_data (model->priv->session, model);
 
                g_object_unref (model->priv->session);
        }
@@ -1121,6 +1338,9 @@ em_folder_tree_model_set_session (EMFolderTreeModel *model,
                EMailAccountStore *account_store;
                MailFolderCache *folder_cache;
 
+               g_signal_connect (model->priv->session, "archive-folder-changed",
+                       G_CALLBACK (em_folder_tree_model_archive_folder_changed_cb), model);
+
                folder_cache = e_mail_session_get_folder_cache (session);
                account_store = e_mail_ui_session_get_account_store (
                        E_MAIL_UI_SESSION (session));
@@ -1162,48 +1382,6 @@ em_folder_tree_model_set_session (EMFolderTreeModel *model,
        g_object_notify (G_OBJECT (model), "session");
 }
 
-static void
-folder_tree_model_get_special_folders_uri (ESourceRegistry *registry,
-                                          CamelStore *store,
-                                          gchar **drafts_folder_uri,
-                                          gchar **templates_folder_uri,
-                                          gchar **sent_folder_uri)
-{
-       ESource *source;
-       const gchar *extension_name;
-
-       /* In case we fail... */
-       *drafts_folder_uri = NULL;
-       *templates_folder_uri = NULL;
-       *sent_folder_uri = NULL;
-
-       source = em_utils_ref_mail_identity_for_store (registry, store);
-       if (source == NULL)
-               return;
-
-       extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
-       if (e_source_has_extension (source, extension_name)) {
-               ESourceMailComposition *extension;
-
-               extension = e_source_get_extension (source, extension_name);
-
-               *drafts_folder_uri = e_source_mail_composition_dup_drafts_folder (extension);
-               *templates_folder_uri = e_source_mail_composition_dup_templates_folder (extension);
-       }
-
-       extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
-       if (e_source_has_extension (source, extension_name)) {
-               ESourceMailSubmission *extension;
-
-               extension = e_source_get_extension (source, extension_name);
-
-               if (e_source_mail_submission_get_use_sent_folder (extension))
-                       *sent_folder_uri = e_source_mail_submission_dup_sent_folder (extension);
-       }
-
-       g_object_unref (source);
-}
-
 void
 em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
                                       GtkTreeIter *iter,
@@ -1225,13 +1403,12 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
        const gchar *uid;
        const gchar *icon_name;
        const gchar *display_name;
-       guint32 flags, add_flags = 0;
+       guint32 flags;
        EMEventTargetCustomIcon *target;
+       gboolean store_is_local;
        gboolean load = FALSE;
        gboolean folder_is_drafts = FALSE;
        gboolean folder_is_outbox = FALSE;
-       gboolean folder_is_templates = FALSE;
-       gboolean store_is_local;
        gchar *uri;
 
        g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
@@ -1311,7 +1488,6 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
                        folder_is_drafts = TRUE;
                        display_name = _("Drafts");
                } else if (strcmp (fi->full_name, "Templates") == 0) {
-                       folder_is_templates = TRUE;
                        display_name = _("Templates");
                } else if (strcmp (fi->full_name, "Inbox") == 0) {
                        flags = (flags & ~CAMEL_FOLDER_TYPE_MASK) |
@@ -1328,48 +1504,8 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
                }
        }
 
-       if ((flags & CAMEL_FOLDER_TYPE_MASK) == 0) {
-               gchar *drafts_folder_uri;
-               gchar *templates_folder_uri;
-               gchar *sent_folder_uri;
-
-               folder_tree_model_get_special_folders_uri (registry, store,
-                       &drafts_folder_uri, &templates_folder_uri, &sent_folder_uri);
-
-               if (!folder_is_drafts && drafts_folder_uri != NULL) {
-                       folder_is_drafts = e_mail_folder_uri_equal (
-                               CAMEL_SESSION (session),
-                               uri, drafts_folder_uri);
-               }
-
-               if (!folder_is_templates && templates_folder_uri != NULL) {
-                       folder_is_templates = e_mail_folder_uri_equal (
-                               CAMEL_SESSION (session),
-                               uri, templates_folder_uri);
-               }
-
-               if (sent_folder_uri != NULL) {
-                       if (e_mail_folder_uri_equal (
-                               CAMEL_SESSION (session),
-                               uri, sent_folder_uri)) {
-                               add_flags = CAMEL_FOLDER_TYPE_SENT;
-                       }
-               }
-
-               g_free (drafts_folder_uri);
-               g_free (templates_folder_uri);
-               g_free (sent_folder_uri);
-       }
-
        /* Choose an icon name for the folder. */
-       icon_name = em_folder_utils_get_icon_name (flags | add_flags);
-
-       if (g_str_equal (icon_name, "folder")) {
-               if (folder_is_drafts)
-                       icon_name = "accessories-text-editor";
-               else if (folder_is_templates)
-                       icon_name = "text-x-generic-template";
-       }
+       icon_name = em_folder_tree_model_get_icon_name_for_folder_uri (model, uri, store, fi->full_name, 
flags);
 
        gtk_tree_store_set (
                tree_store, iter,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]