[evolution] Bug 773038 - Correct unread message indicator for collapsed stores
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Bug 773038 - Correct unread message indicator for collapsed stores
- Date: Wed, 18 Jan 2017 18:29:51 +0000 (UTC)
commit 4ac1c705459da624379785a90916df7d41ea6e0d
Author: Milan Crha <mcrha redhat com>
Date: Wed Jan 18 19:28:45 2017 +0100
Bug 773038 - Correct unread message indicator for collapsed stores
src/libemail-engine/e-mail-utils.c | 103 ++++++++++++++++++++++++++++--------
src/libemail-engine/e-mail-utils.h | 3 +
src/mail/em-folder-tree-model.c | 98 ++++++++--------------------------
src/mail/em-folder-tree-model.h | 3 -
src/mail/em-folder-tree.c | 44 ++++++++++++++-
5 files changed, 149 insertions(+), 102 deletions(-)
---
diff --git a/src/libemail-engine/e-mail-utils.c b/src/libemail-engine/e-mail-utils.c
index 888f420..9be8b04 100644
--- a/src/libemail-engine/e-mail-utils.c
+++ b/src/libemail-engine/e-mail-utils.c
@@ -48,6 +48,41 @@
#define d(x)
+static gboolean
+e_mail_utils_folder_uri_is_drafts (ESourceRegistry *registry,
+ CamelSession *session,
+ const gchar *folder_uri)
+{
+ GList *sources, *link;
+ gboolean is_drafts = FALSE;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
+ g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE);
+ g_return_val_if_fail (folder_uri != NULL, FALSE);
+
+ sources = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_MAIL_COMPOSITION);
+
+ for (link = sources; link; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceMailComposition *extension;
+ const gchar *drafts_folder_uri;
+
+ extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_COMPOSITION);
+
+ drafts_folder_uri = e_source_mail_composition_get_drafts_folder (extension);
+
+ if (drafts_folder_uri != NULL)
+ is_drafts = e_mail_folder_uri_equal (session, folder_uri, drafts_folder_uri);
+
+ if (is_drafts)
+ break;
+ }
+
+ g_list_free_full (sources, g_object_unref);
+
+ return is_drafts;
+}
+
/**
* em_utils_folder_is_drafts:
* @registry: an #ESourceRegistry
@@ -64,10 +99,8 @@ em_utils_folder_is_drafts (ESourceRegistry *registry,
CamelFolder *local_drafts_folder;
CamelSession *session;
CamelStore *store;
- GList *list, *iter;
gchar *folder_uri;
gboolean is_drafts = FALSE;
- const gchar *extension_name;
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
@@ -85,33 +118,59 @@ em_utils_folder_is_drafts (ESourceRegistry *registry,
folder_uri = e_mail_folder_uri_from_folder (folder);
- extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
- list = e_source_registry_list_sources (registry, extension_name);
+ is_drafts = e_mail_utils_folder_uri_is_drafts (registry, session, folder_uri);
- for (iter = list; iter != NULL; iter = g_list_next (iter)) {
- ESource *source = E_SOURCE (iter->data);
- ESourceExtension *extension;
- const gchar *drafts_folder_uri;
+ g_free (folder_uri);
- extension = e_source_get_extension (source, extension_name);
+exit:
+ g_object_unref (session);
- drafts_folder_uri =
- e_source_mail_composition_get_drafts_folder (
- E_SOURCE_MAIL_COMPOSITION (extension));
+ return is_drafts;
+}
- if (drafts_folder_uri != NULL)
- is_drafts = e_mail_folder_uri_equal (
- session, folder_uri, drafts_folder_uri);
+/**
+ * em_utils_folder_name_is_drafts:
+ * @registry: an #ESourceRegistry
+ * @store: a #CamelStore
+ * @folder_name: a folder name
+ *
+ * Decides if @folder_name of the @store is a Drafts folder.
+ *
+ * Returns %TRUE if this is a Drafts folder or %FALSE otherwise.
+ *
+ * Since: 3.24
+ **/
+gboolean
+em_utils_folder_name_is_drafts (ESourceRegistry *registry,
+ CamelStore *store,
+ const gchar *folder_name)
+{
+ CamelSession *session;
+ CamelFolder *local_drafts_folder;
+ gchar *folder_uri, *local_drafts_uri;
+ gboolean is_drafts;
- if (is_drafts)
- break;
- }
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (folder_name != NULL, FALSE);
- g_list_free_full (list, (GDestroyNotify) g_object_unref);
- g_free (folder_uri);
+ folder_uri = e_mail_folder_uri_build (store, folder_name);
+ g_return_val_if_fail (folder_uri != NULL, FALSE);
-exit:
- g_object_unref (session);
+ session = camel_service_ref_session (CAMEL_SERVICE (store));
+
+ local_drafts_folder =
+ e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_DRAFTS);
+
+ local_drafts_uri = e_mail_folder_uri_from_folder (local_drafts_folder);
+
+ is_drafts = g_strcmp0 (local_drafts_uri, folder_uri) == 0 ||
+ e_mail_utils_folder_uri_is_drafts (registry, session, folder_uri);
+
+ g_clear_object (&session);
+ g_free (local_drafts_uri);
+ g_free (folder_uri);
return is_drafts;
}
diff --git a/src/libemail-engine/e-mail-utils.h b/src/libemail-engine/e-mail-utils.h
index ac90883..48f9de7 100644
--- a/src/libemail-engine/e-mail-utils.h
+++ b/src/libemail-engine/e-mail-utils.h
@@ -33,6 +33,9 @@ typedef void (*EMailUtilsSortSourcesFunc) (GList **psources,
gboolean em_utils_folder_is_drafts (ESourceRegistry *registry,
CamelFolder *folder);
+gboolean em_utils_folder_name_is_drafts (ESourceRegistry *registry,
+ CamelStore *store,
+ const gchar *folder_name);
gboolean em_utils_folder_is_templates (ESourceRegistry *registry,
CamelFolder *folder);
gboolean em_utils_folder_is_sent (ESourceRegistry *registry,
diff --git a/src/mail/em-folder-tree-model.c b/src/mail/em-folder-tree-model.c
index 2d76046..a1d4a60 100644
--- a/src/mail/em-folder-tree-model.c
+++ b/src/mail/em-folder-tree-model.c
@@ -800,6 +800,7 @@ folder_tree_model_set_unread_count (EMFolderTreeModel *model,
GtkTreeIter iter;
StoreInfo *si;
guint old_unread = 0;
+ gboolean unread_increased = FALSE, is_drafts = FALSE;
g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
g_return_if_fail (CAMEL_IS_STORE (store));
@@ -828,6 +829,8 @@ folder_tree_model_set_unread_count (EMFolderTreeModel *model,
saved_fu_info = g_hash_table_lookup (si->full_hash_unread, full);
+ unread_increased = unread > saved_fu_info->unread;
+
fu_info->unread_last_sel = MIN (saved_fu_info->unread_last_sel, unread);
fu_info->is_drafts = saved_fu_info->is_drafts;
fu_info->fi_flags = saved_fu_info->fi_flags;
@@ -841,6 +844,8 @@ folder_tree_model_set_unread_count (EMFolderTreeModel *model,
if (folder) {
fu_info->is_drafts = em_utils_folder_is_drafts (e_mail_session_get_registry
(model->priv->session), folder);
g_object_unref (folder);
+ } else {
+ fu_info->is_drafts = em_utils_folder_name_is_drafts
(e_mail_session_get_registry (model->priv->session), store, full);
}
if (!mail_folder_cache_get_folder_info_flags (folder_cache, store, full, &flags))
@@ -849,6 +854,8 @@ folder_tree_model_set_unread_count (EMFolderTreeModel *model,
fu_info->fi_flags = flags;
}
+ is_drafts = fu_info->is_drafts;
+
g_hash_table_insert (si->full_hash_unread, g_strdup (full), fu_info);
goto exit;
@@ -860,7 +867,11 @@ folder_tree_model_set_unread_count (EMFolderTreeModel *model,
gtk_tree_model_get (
tree_model, &iter,
- COL_UINT_UNREAD_LAST_SEL, &old_unread, -1);
+ COL_UINT_UNREAD_LAST_SEL, &old_unread,
+ COL_BOOL_IS_DRAFT, &is_drafts,
+ -1);
+
+ unread_increased = unread > old_unread;
gtk_tree_store_set (
GTK_TREE_STORE (model), &iter,
@@ -878,6 +889,18 @@ folder_tree_model_set_unread_count (EMFolderTreeModel *model,
}
exit:
+ if (unread_increased && !is_drafts && gtk_tree_row_reference_valid (si->row)) {
+ path = gtk_tree_row_reference_get_path (si->row);
+ gtk_tree_model_get_iter (tree_model, &iter, path);
+ gtk_tree_path_free (path);
+
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), &iter,
+ COL_UINT_UNREAD, 0,
+ COL_UINT_UNREAD_LAST_SEL, 1,
+ -1);
+ }
+
store_info_unref (si);
}
@@ -1923,76 +1946,3 @@ em_folder_tree_model_user_marked_unread (EMFolderTreeModel *model,
COL_UINT_UNREAD_LAST_SEL, unread,
COL_UINT_UNREAD, unread, -1);
}
-
-static gboolean
-folder_tree_model_eval_children_has_unread_mismatch (GtkTreeModel *model,
- GtkTreeIter *root)
-{
- guint unread, unread_last_sel;
- GtkTreeIter iter;
-
- if (!gtk_tree_model_iter_children (model, &iter, root))
- return FALSE;
-
- do {
- gtk_tree_model_get (model, &iter,
- COL_UINT_UNREAD, &unread,
- COL_UINT_UNREAD_LAST_SEL, &unread_last_sel,
- -1);
-
- if (unread != ~0 && unread > unread_last_sel)
- return TRUE;
-
- if (gtk_tree_model_iter_has_child (model, &iter))
- if (folder_tree_model_eval_children_has_unread_mismatch (model, &iter))
- return TRUE;
- } while (gtk_tree_model_iter_next (model, &iter));
-
- return FALSE;
-}
-
-gboolean
-em_folder_tree_model_has_unread_mismatch (GtkTreeModel *model,
- GtkTreeIter *store_iter)
-{
- StoreInfo *si;
- CamelStore *store = NULL;
- gboolean is_store = FALSE;
- gboolean has_unread_mismatch = FALSE;
-
- g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), FALSE);
- g_return_val_if_fail (store_iter != NULL, FALSE);
-
- gtk_tree_model_get (model, store_iter,
- COL_BOOL_IS_STORE, &is_store,
- COL_OBJECT_CAMEL_STORE, &store,
- -1);
-
- if (is_store) {
- si = folder_tree_model_store_index_lookup (EM_FOLDER_TREE_MODEL (model), store);
- if (si) {
- GHashTableIter hash_iter;
- gpointer value;
-
- g_hash_table_iter_init (&hash_iter, si->full_hash_unread);
- while (g_hash_table_iter_next (&hash_iter, NULL, &value)) {
- FolderUnreadInfo *fu_info = value;
-
- if (fu_info && !fu_info->is_drafts && (fu_info->fi_flags &
CAMEL_FOLDER_VIRTUAL) == 0 &&
- fu_info->unread > fu_info->unread_last_sel) {
- has_unread_mismatch = TRUE;
- break;
- }
- }
-
- store_info_unref (si);
- }
-
- has_unread_mismatch = has_unread_mismatch ||
- folder_tree_model_eval_children_has_unread_mismatch (model, store_iter);
- }
-
- g_clear_object (&store);
-
- return has_unread_mismatch;
-}
diff --git a/src/mail/em-folder-tree-model.h b/src/mail/em-folder-tree-model.h
index e04f5b5..325e3a5 100644
--- a/src/mail/em-folder-tree-model.h
+++ b/src/mail/em-folder-tree-model.h
@@ -146,9 +146,6 @@ void em_folder_tree_model_user_marked_unread
(EMFolderTreeModel *model,
CamelFolder *folder,
guint n_marked);
-gboolean em_folder_tree_model_has_unread_mismatch
- (GtkTreeModel *model,
- GtkTreeIter *store_iter);
G_END_DECLS
diff --git a/src/mail/em-folder-tree.c b/src/mail/em-folder-tree.c
index 5f3d662..8117227 100644
--- a/src/mail/em-folder-tree.c
+++ b/src/mail/em-folder-tree.c
@@ -749,12 +749,43 @@ folder_tree_render_store_icon (GtkTreeViewColumn *column,
g_object_get (text_renderer, "is-expanded", &expanded, NULL);
/* The second prerequisite: it's not expanded and children has unread mismatch. */
- if (!expanded)
- children_has_unread_mismatch = em_folder_tree_model_has_unread_mismatch (model, iter);
+ if (!expanded) {
+ guint unread, unread_last_sel;
+
+ gtk_tree_model_get (model, iter,
+ COL_UINT_UNREAD, &unread,
+ COL_UINT_UNREAD_LAST_SEL, &unread_last_sel,
+ -1);
+
+ children_has_unread_mismatch = unread != unread_last_sel;
+ }
g_object_set (renderer, "visible", !expanded && children_has_unread_mismatch, NULL);
}
+static void
+folder_tree_reset_store_unread_value_cb (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path,
+ gpointer user_data)
+{
+ GtkTreeIter parent;
+ GtkTreeModel *model;
+
+ g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+
+ model = gtk_tree_view_get_model (tree_view);
+ if (!model)
+ return;
+
+ if (!gtk_tree_model_iter_parent (model, &parent, iter)) {
+ gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ COL_UINT_UNREAD_LAST_SEL, 0,
+ COL_UINT_UNREAD, 0,
+ -1);
+ }
+}
+
static gboolean
subdirs_contain_unread (GtkTreeModel *model,
GtkTreeIter *root)
@@ -972,10 +1003,11 @@ folder_tree_selection_changed_cb (EMFolderTree *folder_tree,
COL_UINT_UNREAD_LAST_SEL, &old_unread, -1);
/* Sync unread counts to distinguish new incoming mail. */
- if (unread != old_unread)
+ if (unread != old_unread) {
gtk_tree_store_set (
GTK_TREE_STORE (model), &iter,
COL_UINT_UNREAD_LAST_SEL, unread, -1);
+ }
exit:
g_signal_emit (
@@ -1351,6 +1383,12 @@ folder_tree_constructed (GObject *object)
folder_tree_copy_state (EM_FOLDER_TREE (object));
gtk_widget_show (GTK_WIDGET (object));
+
+ g_signal_connect (tree_view, "row-expanded",
+ G_CALLBACK (folder_tree_reset_store_unread_value_cb), NULL);
+
+ g_signal_connect (tree_view, "row-collapsed",
+ G_CALLBACK (folder_tree_reset_store_unread_value_cb), NULL);
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]