diff options
-rw-r--r-- | mail/ChangeLog | 13 | ||||
-rw-r--r-- | mail/message-list.c | 57 | ||||
-rw-r--r-- | widgets/table/ChangeLog | 18 | ||||
-rw-r--r-- | widgets/table/e-tree-table-adapter.c | 47 | ||||
-rw-r--r-- | widgets/table/e-tree-table-adapter.h | 4 | ||||
-rw-r--r-- | widgets/table/e-tree.c | 19 | ||||
-rw-r--r-- | widgets/table/e-tree.h | 4 |
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); |