aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog13
-rw-r--r--mail/message-list.c57
-rw-r--r--widgets/table/ChangeLog18
-rw-r--r--widgets/table/e-tree-table-adapter.c47
-rw-r--r--widgets/table/e-tree-table-adapter.h4
-rw-r--r--widgets/table/e-tree.c19
-rw-r--r--widgets/table/e-tree.h4
7 files changed, 139 insertions, 23 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index f64329f520..feeea7839d 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,16 @@
+2008-08-11 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #352695
+
+ * message-list.c: (struct _MessageListPrivate), (save_tree_state),
+ (load_tree_state), (on_model_row_changed), (message_list_init),
+ (message_list_construct), (struct _regen_list_msg), (regen_list_done),
+ (regen_list_free), (mail_regen_list): Be able to recognize whether
+ there has been any change on any row in a list and save expanded
+ state only in case there was any change. Also use in-memory storing
+ of the expanded state in case we do not want to rewrite full view
+ It's for searches only, and it's not stored between sessions.
+
2008-08-11 Srinivasa Ragavan <sragavan@novell.com>
** Part fix for bug #529743
diff --git a/mail/message-list.c b/mail/message-list.c
index d6d5ec7f50..73e2d30931 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -111,6 +111,7 @@ struct _MessageListPrivate {
gboolean destroyed;
gboolean thread_latest;
+ gboolean any_row_changed; /* save state before regen list when this is set to true */
};
static struct {
@@ -1798,6 +1799,8 @@ save_tree_state(MessageList *ml)
filename = mail_config_folder_to_cachename(ml->folder, "et-expanded-");
e_tree_save_expanded_state(ml->tree, filename);
g_free(filename);
+
+ ml->priv->any_row_changed = FALSE;
}
static void
@@ -1811,18 +1814,23 @@ load_tree_expand_all (MessageList *ml, gboolean state)
save_tree_state (ml);
}
static void
-load_tree_state (MessageList *ml)
+load_tree_state (MessageList *ml, xmlDoc *expand_state)
{
- char *filename;
-
if (ml->folder == NULL || ml->tree == NULL)
return;
- filename = mail_config_folder_to_cachename (ml->folder, "et-expanded-");
- e_tree_load_expanded_state (ml->tree, filename);
- g_free (filename);
-}
+ if (expand_state) {
+ e_tree_load_expanded_state_xml (ml->tree, expand_state);
+ } else {
+ char *filename;
+
+ filename = mail_config_folder_to_cachename (ml->folder, "et-expanded-");
+ e_tree_load_expanded_state (ml->tree, filename);
+ g_free (filename);
+ }
+ ml->priv->any_row_changed = FALSE;
+}
void
message_list_save_state (MessageList *ml)
@@ -2173,6 +2181,12 @@ ml_scrolled (GtkAdjustment *adj, MessageList *ml)
g_signal_emit (ml, message_list_signals[MESSAGE_LIST_SCROLLED], 0);
}
+static void
+on_model_row_changed (ETableModel *model, int row, MessageList *ml)
+{
+ ml->priv->any_row_changed = TRUE;
+}
+
/*
* GObject::init
*/
@@ -2213,6 +2227,7 @@ message_list_init (MessageList *message_list)
p->invisible = gtk_invisible_new();
p->destroyed = FALSE;
g_object_ref_sink(p->invisible);
+ p->any_row_changed = FALSE;
matom = gdk_atom_intern ("x-uid-list", FALSE);
gtk_selection_add_target(p->invisible, GDK_SELECTION_CLIPBOARD, matom, 0);
@@ -2430,6 +2445,8 @@ message_list_construct (MessageList *message_list)
atk_object_set_name(a11y, _("Messages"));
}
+ g_signal_connect (e_tree_get_table_adapter (message_list->tree), "model_row_changed", G_CALLBACK (on_model_row_changed), message_list);
+
g_signal_connect((message_list->tree), "cursor_activated",
G_CALLBACK (on_cursor_activated_cmd),
message_list);
@@ -3870,6 +3887,8 @@ struct _regen_list_msg {
GPtrArray *summary;
int last_row; /* last selected (cursor) row */
+
+ xmlDoc *expand_state; /* stored expanded state of the previous view */
};
/*
@@ -4128,10 +4147,14 @@ regen_list_done (struct _regen_list_msg *m)
e_profile_event_emit("list.buildtree", m->folder->full_name, 0);
if (m->dotree) {
- if (m->ml->just_set_folder)
+ if (m->ml->just_set_folder) {
m->ml->just_set_folder = FALSE;
- else /* Saving the tree state causes bug 352695 but fixes bug 387312 */
- save_tree_state (m->ml);
+ if (m->expand_state) {
+ /* rather load state from disk than use the memory data when changing folders */
+ xmlFreeDoc (m->expand_state);
+ m->expand_state = NULL;
+ }
+ }
build_tree (m->ml, m->tree, m->changes);
if (m->ml->thread_tree)
@@ -4144,7 +4167,7 @@ regen_list_done (struct _regen_list_msg *m)
else if (m->ml->collapse_all)
load_tree_expand_all (m->ml, FALSE);
else
- load_tree_state (m->ml);
+ load_tree_state (m->ml, m->expand_state);
m->ml->expand_all = 0;
m->ml->collapse_all = 0;
@@ -4189,6 +4212,7 @@ regen_list_done (struct _regen_list_msg *m)
e_tree_set_info_message (m->ml->tree, NULL);
g_signal_emit (m->ml, message_list_signals[MESSAGE_LIST_BUILT], 0);
+ m->ml->priv->any_row_changed = FALSE;
}
static void
@@ -4218,6 +4242,9 @@ regen_list_free (struct _regen_list_msg *m)
/* we have to poke this here as well since we might've been cancelled and regened wont get called */
m->ml->regen = g_list_remove(m->ml->regen, m);
+ if (m->expand_state)
+ xmlFreeDoc (m->expand_state);
+
g_object_unref(m->ml);
}
@@ -4316,6 +4343,7 @@ mail_regen_list (MessageList *ml, const char *search, const char *hideexpr, Came
m->folder = ml->folder;
camel_object_ref(m->folder);
m->last_row = -1;
+ m->expand_state = NULL;
if ((!m->hidedel || !m->dotree) && ml->thread_tree) {
camel_folder_thread_messages_unref(ml->thread_tree);
@@ -4332,6 +4360,13 @@ mail_regen_list (MessageList *ml, const char *search, const char *hideexpr, Came
e_tree_set_info_message (m->ml->tree, txt);
g_free (txt);
+ } else if (ml->priv->any_row_changed && m->dotree && !ml->just_set_folder && (!ml->search || g_str_equal (ml->search, " "))) {
+ /* there has been some change on any row, if it was an expand state change,
+ then let it save; if not, then nothing happen. */
+ message_list_save_state (ml);
+ } else if (m->dotree && !ml->just_set_folder) {
+ /* remember actual expand state and restore it after regen */
+ m->expand_state = e_tree_save_expanded_state_xml (ml->tree);
}
/* if we're busy already kick off timeout processing, so normal updates are immediate */
diff --git a/widgets/table/ChangeLog b/widgets/table/ChangeLog
index d5fe462ccd..47bba15e2a 100644
--- a/widgets/table/ChangeLog
+++ b/widgets/table/ChangeLog
@@ -1,3 +1,21 @@
+2008-08-11 Milan Crha <mcrha@redhat.com>
+
+ ** Part of fix for bug #352695
+
+ * e-tree-table-adapter.h:
+ (e_tree_table_adapter_save_expanded_state_xml),
+ (e_tree_table_adapter_load_expanded_state_xml):
+ * e-tree-table-adapter.c:
+ (e_tree_table_adapter_save_expanded_state_xml),
+ (e_tree_table_adapter_save_expanded_state),
+ (e_tree_table_adapter_load_expanded_state_xml),
+ (e_tree_table_adapter_load_expanded_state):
+ * e-tree.h: (e_tree_save_expanded_state_xml),
+ (e_tree_load_expanded_state_xml):
+ * e-tree.c: (e_tree_save_expanded_state_xml),
+ (e_tree_load_expanded_state_xml):
+ Be able to store expanded state also in memory, not only on the disk.
+
2008-07-15 Milan Crha <mcrha@redhat.com>
** Part of fix for bug #329821
diff --git a/widgets/table/e-tree-table-adapter.c b/widgets/table/e-tree-table-adapter.c
index 579b231bb3..b5567a0b95 100644
--- a/widgets/table/e-tree-table-adapter.c
+++ b/widgets/table/e-tree-table-adapter.c
@@ -912,14 +912,14 @@ save_expanded_state_func (gpointer keyp, gpointer value, gpointer data)
}
}
-void
-e_tree_table_adapter_save_expanded_state (ETreeTableAdapter *etta, const char *filename)
+xmlDoc *
+e_tree_table_adapter_save_expanded_state_xml (ETreeTableAdapter *etta)
{
TreeAndRoot tar;
xmlDocPtr doc;
xmlNode *root;
- g_return_if_fail(etta != NULL);
+ g_return_val_if_fail (etta != NULL, NULL);
doc = xmlNewDoc ((const unsigned char *)"1.0");
root = xmlNewDocNode (doc, NULL, (const unsigned char *)"expanded_state", NULL);
@@ -934,8 +934,21 @@ e_tree_table_adapter_save_expanded_state (ETreeTableAdapter *etta, const char *f
g_hash_table_foreach (etta->priv->nodes, save_expanded_state_func, &tar);
- e_xml_save_file (filename, doc);
- xmlFreeDoc (doc);
+ return doc;
+}
+
+void
+e_tree_table_adapter_save_expanded_state (ETreeTableAdapter *etta, const char *filename)
+{
+ xmlDoc *doc;
+
+ g_return_if_fail (etta != NULL);
+
+ doc = e_tree_table_adapter_save_expanded_state_xml (etta);
+ if (doc) {
+ e_xml_save_file (filename, doc);
+ xmlFreeDoc (doc);
+ }
}
static xmlDoc *
@@ -1022,18 +1035,14 @@ e_tree_table_adapter_load_all_expanded_state (ETreeTableAdapter *etta, gboolean
}
void
-e_tree_table_adapter_load_expanded_state (ETreeTableAdapter *etta, const char *filename)
+e_tree_table_adapter_load_expanded_state_xml (ETreeTableAdapter *etta, xmlDoc *doc)
{
- xmlDoc *doc;
xmlNode *root, *child;
gboolean model_default;
gboolean file_default = FALSE;
- g_return_if_fail(etta != NULL);
-
- doc = open_file(etta, filename);
- if (!doc)
- return;
+ g_return_if_fail (etta != NULL);
+ g_return_if_fail (doc != NULL);
root = xmlDocGetRootElement (doc);
@@ -1083,6 +1092,20 @@ e_tree_table_adapter_load_expanded_state (ETreeTableAdapter *etta, const char *f
g_free (id);
}
+}
+
+void
+e_tree_table_adapter_load_expanded_state (ETreeTableAdapter *etta, const char *filename)
+{
+ xmlDoc *doc;
+
+ g_return_if_fail(etta != NULL);
+
+ doc = open_file(etta, filename);
+ if (!doc)
+ return;
+
+ e_tree_table_adapter_load_expanded_state_xml (etta, doc);
xmlFreeDoc (doc);
diff --git a/widgets/table/e-tree-table-adapter.h b/widgets/table/e-tree-table-adapter.h
index cd23ba06bb..e7fed9c2a7 100644
--- a/widgets/table/e-tree-table-adapter.h
+++ b/widgets/table/e-tree-table-adapter.h
@@ -30,6 +30,7 @@
#include <table/e-tree-model.h>
#include <table/e-table-sort-info.h>
#include <table/e-table-header.h>
+#include <libxml/tree.h>
G_BEGIN_DECLS
@@ -89,6 +90,9 @@ void e_tree_table_adapter_save_expanded_state (ETreeTableAdapter
void e_tree_table_adapter_load_expanded_state (ETreeTableAdapter *etta,
const char *filename);
+xmlDoc *e_tree_table_adapter_save_expanded_state_xml (ETreeTableAdapter *etta);
+void e_tree_table_adapter_load_expanded_state_xml (ETreeTableAdapter *etta, xmlDoc *doc);
+
void e_tree_table_adapter_set_sort_info (ETreeTableAdapter *etta,
ETableSortInfo *sort_info);
diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c
index 8b685a724b..64f0bde2d1 100644
--- a/widgets/table/e-tree.c
+++ b/widgets/table/e-tree.c
@@ -2069,6 +2069,25 @@ e_tree_load_expanded_state (ETree *et, char *filename)
e_tree_table_adapter_load_expanded_state (et->priv->etta, filename);
}
+xmlDoc *
+e_tree_save_expanded_state_xml (ETree *et)
+{
+ g_return_val_if_fail (et != NULL, NULL);
+ g_return_val_if_fail (E_IS_TREE (et), NULL);
+
+ return e_tree_table_adapter_save_expanded_state_xml (et->priv->etta);
+}
+
+void
+e_tree_load_expanded_state_xml (ETree *et, xmlDoc *doc)
+{
+ g_return_if_fail (et != NULL);
+ g_return_if_fail (E_IS_TREE (et));
+ g_return_if_fail (doc != NULL);
+
+ e_tree_table_adapter_load_expanded_state_xml (et->priv->etta, doc);
+}
+
void
e_tree_load_all_expanded_state (ETree *et, gboolean state)
{
diff --git a/widgets/table/e-tree.h b/widgets/table/e-tree.h
index 6e736f1a0e..30bb0fdb40 100644
--- a/widgets/table/e-tree.h
+++ b/widgets/table/e-tree.h
@@ -286,6 +286,10 @@ void e_tree_save_expanded_state (ETree *et,
char *filename);
void e_tree_load_expanded_state (ETree *et,
char *filename);
+
+xmlDoc *e_tree_save_expanded_state_xml (ETree *et);
+void e_tree_load_expanded_state_xml (ETree *et, xmlDoc *doc);
+
int e_tree_row_count (ETree *et);
GtkWidget *e_tree_get_tooltip (ETree *et);
void e_tree_load_all_expanded_state (ETree *et, gboolean state);