aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2009-06-14 03:07:00 +0800
committerMatthew Barnes <mbarnes@redhat.com>2009-06-14 03:07:00 +0800
commitab27aff72c64183166fc6207d2ef0142e1ab8c83 (patch)
tree6b95a26dedf3ca26ae70f9a2ff3ea466e42763dc
parent49ba34088bcdb9ab9cfae0c2b7fe11452fb60e24 (diff)
downloadgsoc2013-evolution-ab27aff72c64183166fc6207d2ef0142e1ab8c83.tar.gz
gsoc2013-evolution-ab27aff72c64183166fc6207d2ef0142e1ab8c83.tar.zst
gsoc2013-evolution-ab27aff72c64183166fc6207d2ef0142e1ab8c83.zip
Thought of a better way to copy folder tree state.
Revert the expanded tree model column and add a "selection"property to EMFolderTreeModel, which the sidebar sets. If set, all new EMFolderTree instances will automatically mimic its expanded and selected state.
-rw-r--r--mail/e-mail-reader.c4
-rw-r--r--mail/e-mail-shell-sidebar.c33
-rw-r--r--mail/em-composer-utils.c1
-rw-r--r--mail/em-folder-selection-button.c1
-rw-r--r--mail/em-folder-selection.c1
-rw-r--r--mail/em-folder-tree-model.c93
-rw-r--r--mail/em-folder-tree-model.h7
-rw-r--r--mail/em-folder-tree.c100
-rw-r--r--mail/em-folder-tree.h1
-rw-r--r--mail/em-folder-utils.c1
-rw-r--r--plugins/groupwise-features/install-shared.c1
-rw-r--r--plugins/groupwise-features/share-folder-common.c1
12 files changed, 162 insertions, 82 deletions
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index 94855ee68b..edea7cfa6f 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -167,8 +167,6 @@ action_mail_copy_cb (GtkAction *action,
folder = message_list->folder;
- em_folder_tree_clone_expanded (folder_tree);
-
em_folder_tree_set_excluded (
EM_FOLDER_TREE (folder_tree),
EMFT_EXCLUDE_NOSELECT | EMFT_EXCLUDE_VIRTUAL |
@@ -579,8 +577,6 @@ action_mail_move_cb (GtkAction *action,
folder = message_list->folder;
- em_folder_tree_clone_expanded (folder_tree);
-
em_folder_tree_set_excluded (
EM_FOLDER_TREE (folder_tree),
EMFT_EXCLUDE_NOSELECT | EMFT_EXCLUDE_VIRTUAL |
diff --git a/mail/e-mail-shell-sidebar.c b/mail/e-mail-shell-sidebar.c
index 7d2ef3475a..83e8b7d0a0 100644
--- a/mail/e-mail-shell-sidebar.c
+++ b/mail/e-mail-shell-sidebar.c
@@ -91,10 +91,6 @@ mail_shell_sidebar_restore_state (EMailShellSidebar *mail_shell_sidebar)
* (these are all stores) and expand those that have no
* corresponding "Expanded" key in the state file. This
* ensures that new stores are expanded by default.
- *
- * The expanded state is recorded and maintained in the tree model
- * so that folder trees in other contexts can duplicate it using
- * em_folder_tree_clone_expanded().
*/
/* Stage 1 */
@@ -135,12 +131,6 @@ mail_shell_sidebar_restore_state (EMailShellSidebar *mail_shell_sidebar)
gtk_tree_model_get_iter (tree_model, &iter, path);
gtk_tree_view_expand_row (tree_view, path, FALSE);
gtk_tree_path_free (path);
-
- /* The expanded column is used to clone the sidebar's
- * expanded state in other EMFolderTree instances. */
- gtk_tree_store_set (
- GTK_TREE_STORE (tree_model), &iter,
- COL_BOOL_EXPANDED, TRUE, -1);
}
g_strfreev (groups);
@@ -168,12 +158,6 @@ mail_shell_sidebar_restore_state (EMailShellSidebar *mail_shell_sidebar)
path = gtk_tree_model_get_path (tree_model, &iter);
gtk_tree_view_expand_row (tree_view, path, FALSE);
gtk_tree_path_free (path);
-
- /* The expanded column is used to clone the sidebar's
- * expanded state in other EMFolderTree instances. */
- gtk_tree_store_set (
- GTK_TREE_STORE (tree_model), &iter,
- COL_BOOL_EXPANDED, TRUE, -1);
}
g_free (group_name);
@@ -212,12 +196,6 @@ mail_shell_sidebar_row_collapsed_cb (EShellSidebar *shell_sidebar,
g_return_if_fail (is_store || is_folder);
- /* The expanded column is used to clone the sidebar's
- * expanded state in other EMFolderTree instances. */
- gtk_tree_store_set (
- GTK_TREE_STORE (model), iter,
- COL_BOOL_EXPANDED, FALSE, -1);
-
key = STATE_KEY_EXPANDED;
if (is_store)
group_name = g_strdup_printf ("Store %s", uri);
@@ -266,12 +244,6 @@ mail_shell_sidebar_row_expanded_cb (EShellSidebar *shell_sidebar,
g_return_if_fail (is_store || is_folder);
- /* The expanded column is used to clone the sidebar's
- * expanded state in other EMFolderTree instances. */
- gtk_tree_store_set (
- GTK_TREE_STORE (model), &iter,
- COL_BOOL_EXPANDED, TRUE, -1);
-
key = STATE_KEY_EXPANDED;
if (is_store)
group_name = g_strdup_printf ("Store %s", uri);
@@ -487,7 +459,10 @@ mail_shell_sidebar_constructed (GObject *object)
tree_view = GTK_TREE_VIEW (mail_shell_sidebar->priv->folder_tree);
selection = gtk_tree_view_get_selection (tree_view);
- mail_shell_sidebar_restore_state (mail_shell_sidebar);
+ if (em_folder_tree_model_get_selection (folder_tree_model) == NULL)
+ mail_shell_sidebar_restore_state (mail_shell_sidebar);
+
+ em_folder_tree_model_set_selection (folder_tree_model, selection);
g_signal_connect_swapped (
tree_view, "row-collapsed",
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index 6c35a4e7e8..4b1d9aedce 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -2408,7 +2408,6 @@ post_header_clicked_cb (EComposerPostHeader *header,
model = e_mail_shell_backend_get_folder_tree_model (mail_shell_backend);
folder_tree = em_folder_tree_new_with_model (model);
- em_folder_tree_clone_expanded (EM_FOLDER_TREE (folder_tree));
em_folder_tree_set_multiselect (EM_FOLDER_TREE (folder_tree), TRUE);
em_folder_tree_set_excluded (
diff --git a/mail/em-folder-selection-button.c b/mail/em-folder-selection-button.c
index ecdccc0af7..933393ae80 100644
--- a/mail/em-folder-selection-button.c
+++ b/mail/em-folder-selection-button.c
@@ -256,7 +256,6 @@ folder_selection_button_clicked (GtkButton *button)
emft = (EMFolderTree *) em_folder_tree_new_with_model (priv->model);
- em_folder_tree_clone_expanded (emft);
em_folder_tree_set_multiselect (emft, priv->multiple_select);
em_folder_tree_set_excluded (
emft, EMFT_EXCLUDE_NOSELECT |
diff --git a/mail/em-folder-selection.c b/mail/em-folder-selection.c
index 56c11bcfdf..5997eb6ca6 100644
--- a/mail/em-folder-selection.c
+++ b/mail/em-folder-selection.c
@@ -52,7 +52,6 @@ em_select_folder (EMFolderTreeModel *model,
/* XXX Do we leak this reference? */
emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
- em_folder_tree_clone_expanded (emft);
if (exclude)
em_folder_tree_set_excluded_func (emft, exclude, user_data);
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index f7886bdb2c..d7c5261a7c 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -63,6 +63,11 @@
struct _EMFolderTreeModelPrivate {
gpointer shell_backend; /* weak pointer */
+ /* This is set by EMailShellSidebar. It allows new EMFolderTree
+ * instances to initialize their selection and expanded states to
+ * mimic the sidebar. */
+ GtkTreeSelection *selection; /* weak reference */
+
EAccountList *accounts;
/* EAccount -> EMFolderTreeStoreInfo */
@@ -80,7 +85,8 @@ struct _EMFolderTreeModelPrivate {
enum {
PROP_0,
- PROP_SHELL_BACKEND
+ PROP_SHELL_BACKEND,
+ PROP_SELECTION
};
enum {
@@ -230,6 +236,14 @@ account_removed_cb (EAccountList *accounts,
}
static void
+folder_tree_model_selection_finalized_cb (EMFolderTreeModel *model)
+{
+ model->priv->selection = NULL;
+
+ g_object_notify (G_OBJECT (model), "selection");
+}
+
+static void
folder_tree_model_set_shell_backend (EMFolderTreeModel *model,
EShellBackend *shell_backend)
{
@@ -254,6 +268,12 @@ folder_tree_model_set_property (GObject *object,
EM_FOLDER_TREE_MODEL (object),
g_value_get_object (value));
return;
+
+ case PROP_SELECTION:
+ em_folder_tree_model_set_selection (
+ EM_FOLDER_TREE_MODEL (object),
+ g_value_get_object (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -272,12 +292,37 @@ folder_tree_model_get_property (GObject *object,
em_folder_tree_model_get_mail_shell_backend (
EM_FOLDER_TREE_MODEL (object)));
return;
+
+ case PROP_SELECTION:
+ g_value_set_object (
+ value,
+ em_folder_tree_model_get_selection (
+ EM_FOLDER_TREE_MODEL (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
+folder_tree_model_dispose (GObject *object)
+{
+ EMFolderTreeModelPrivate *priv;
+
+ priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (object);
+
+ if (priv->selection != NULL) {
+ g_object_weak_unref (
+ G_OBJECT (priv->selection), (GWeakNotify)
+ folder_tree_model_selection_finalized_cb, object);
+ priv->selection = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
folder_tree_model_finalize (GObject *object)
{
EMFolderTreeModelPrivate *priv;
@@ -308,6 +353,7 @@ folder_tree_model_class_init (EMFolderTreeModelClass *class)
object_class = G_OBJECT_CLASS (class);
object_class->set_property = folder_tree_model_set_property;
object_class->get_property = folder_tree_model_get_property;
+ object_class->dispose = folder_tree_model_dispose;
object_class->finalize = folder_tree_model_finalize;
g_object_class_install_property (
@@ -321,6 +367,16 @@ folder_tree_model_class_init (EMFolderTreeModelClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTION,
+ g_param_spec_object (
+ "selection",
+ "Selection",
+ NULL,
+ GTK_TYPE_TREE_SELECTION,
+ G_PARAM_READWRITE));
+
signals[LOADING_ROW] = g_signal_new (
"loading-row",
G_OBJECT_CLASS_TYPE (object_class),
@@ -369,7 +425,6 @@ folder_tree_model_init (EMFolderTreeModel *model)
G_TYPE_STRING, /* uri */
G_TYPE_UINT, /* unread count */
G_TYPE_UINT, /* flags */
- G_TYPE_BOOLEAN, /* is expanded in sidebar */
G_TYPE_BOOLEAN, /* is a store node */
G_TYPE_BOOLEAN, /* is a folder node */
G_TYPE_BOOLEAN, /* has not-yet-loaded subfolders */
@@ -457,6 +512,40 @@ em_folder_tree_model_get_mail_shell_backend (EMFolderTreeModel *model)
return model->priv->shell_backend;
}
+GtkTreeSelection *
+em_folder_tree_model_get_selection (EMFolderTreeModel *model)
+{
+ g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
+
+ return GTK_TREE_SELECTION (model->priv->selection);
+}
+
+void
+em_folder_tree_model_set_selection (EMFolderTreeModel *model,
+ GtkTreeSelection *selection)
+{
+ g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+
+ if (selection != NULL)
+ g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
+
+ if (model->priv->selection != NULL) {
+ g_object_weak_unref (
+ G_OBJECT (model->priv->selection), (GWeakNotify)
+ folder_tree_model_selection_finalized_cb, model);
+ model->priv->selection = NULL;
+ }
+
+ model->priv->selection = selection;
+
+ if (model->priv->selection != NULL)
+ g_object_weak_ref (
+ G_OBJECT (model->priv->selection), (GWeakNotify)
+ folder_tree_model_selection_finalized_cb, model);
+
+ g_object_notify (G_OBJECT (model), "selection");
+}
+
void
em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
GtkTreeIter *iter,
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index 036002d74b..899a6ee1d8 100644
--- a/mail/em-folder-tree-model.h
+++ b/mail/em-folder-tree-model.h
@@ -63,7 +63,6 @@ enum {
COL_UINT_UNREAD, /* unread count */
COL_UINT_FLAGS, /* FolderInfo.flags */
- COL_BOOL_EXPANDED, /* node is expanded in sidebar */
COL_BOOL_IS_STORE, /* toplevel store node? */
COL_BOOL_IS_FOLDER, /* folder (not a store) */
COL_BOOL_LOAD_SUBDIRS, /* %TRUE only if the store/folder
@@ -116,6 +115,12 @@ EMFolderTreeModel *
EMailShellBackend *
em_folder_tree_model_get_mail_shell_backend
(EMFolderTreeModel *model);
+GtkTreeSelection *
+ em_folder_tree_model_get_selection
+ (EMFolderTreeModel *model);
+void em_folder_tree_model_set_selection
+ (EMFolderTreeModel *model,
+ GtkTreeSelection *selection);
void em_folder_tree_model_set_folder_info
(EMFolderTreeModel *model,
GtkTreeIter *iter,
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index 0e0ff74417..b8ee5e354a 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -523,6 +523,51 @@ folder_tree_new (EMFolderTree *emft, EMFolderTreeModel *model)
}
static void
+folder_tree_copy_expanded_cb (GtkTreeView *unused,
+ GtkTreePath *path,
+ GtkTreeView *tree_view)
+{
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
+}
+
+static void
+folder_tree_copy_selection_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GtkTreeView *tree_view)
+{
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (tree_view);
+ gtk_tree_selection_select_path (selection, path);
+
+ /* Center the tree view on the selected path. */
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.0);
+}
+
+static void
+folder_tree_copy_state (EMFolderTree *emft,
+ EMFolderTreeModel *model)
+{
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+
+ selection = em_folder_tree_model_get_selection (model);
+ if (selection == NULL)
+ return;
+
+ tree_view = gtk_tree_selection_get_tree_view (selection);
+
+ gtk_tree_view_map_expanded_rows (
+ tree_view, (GtkTreeViewMappingFunc)
+ folder_tree_copy_expanded_cb, emft);
+
+ gtk_tree_selection_selected_foreach (
+ selection, (GtkTreeSelectionForeachFunc)
+ folder_tree_copy_selection_cb, emft);
+}
+
+static void
em_folder_tree_construct (EMFolderTree *emft, EMFolderTreeModel *model)
{
struct _EMFolderTreePrivate *priv = emft->priv;
@@ -530,6 +575,7 @@ em_folder_tree_construct (EMFolderTree *emft, EMFolderTreeModel *model)
priv->model = model;
folder_tree_new (emft, model);
+ folder_tree_copy_state (emft, model);
gtk_widget_show (GTK_WIDGET (emft));
g_signal_connect (emft, "row-expanded", G_CALLBACK (emft_tree_row_expanded), emft);
@@ -703,38 +749,6 @@ em_folder_tree_new_with_model (EMFolderTreeModel *model)
return (GtkWidget *) emft;
}
-static gboolean
-folder_tree_clone_expanded (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- GtkTreeView *tree_view)
-{
- gboolean expanded;
-
- gtk_tree_model_get (model, iter, COL_BOOL_EXPANDED, &expanded, -1);
-
- if (expanded)
- gtk_tree_view_expand_row (tree_view, path, FALSE);
- else
- gtk_tree_view_collapse_row (tree_view, path);
-
- return FALSE;
-}
-
-void
-em_folder_tree_clone_expanded (EMFolderTree *emft)
-{
- GtkTreeModel *model;
-
- g_return_if_fail (EM_IS_FOLDER_TREE (emft));
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
-
- gtk_tree_model_foreach (
- model, (GtkTreeModelForeachFunc)
- folder_tree_clone_expanded, emft);
-}
-
static void
tree_drag_begin (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
@@ -2042,7 +2056,8 @@ emft_tree_user_event (GtkTreeView *treeview, GdkEvent *e, EMFolderTree *emft)
}
static void
-emft_tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft)
+emft_tree_selection_changed (GtkTreeSelection *selection,
+ EMFolderTree *emft)
{
gchar *full_name, *uri;
GtkTreeModel *model;
@@ -2075,10 +2090,14 @@ emft_tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft)
}
void
-em_folder_tree_set_selected (EMFolderTree *emft, const gchar *uri, gboolean expand_only)
+em_folder_tree_set_selected (EMFolderTree *emft,
+ const gchar *uri,
+ gboolean expand_only)
{
GList *l = NULL;
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+
if (uri && uri[0])
l = g_list_append(l, (gpointer)uri);
@@ -2231,7 +2250,6 @@ em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
return;
}
-
gchar *
em_folder_tree_get_selected_uri (EMFolderTree *emft)
{
@@ -2246,8 +2264,10 @@ em_folder_tree_get_selected_uri (EMFolderTree *emft)
tree_view = GTK_TREE_VIEW (emft);
selection = gtk_tree_view_get_selection (tree_view);
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- gtk_tree_model_get(model, &iter, COL_STRING_URI, &uri, -1);
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COL_STRING_URI, &uri, -1);
return uri;
}
@@ -2266,8 +2286,10 @@ em_folder_tree_get_selected_path (EMFolderTree *emft)
tree_view = GTK_TREE_VIEW (emft);
selection = gtk_tree_view_get_selection (tree_view);
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- gtk_tree_model_get(model, &iter, COL_STRING_FULL_NAME, &name, -1);
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COL_STRING_FULL_NAME, &name, -1);
return name;
}
diff --git a/mail/em-folder-tree.h b/mail/em-folder-tree.h
index 91827ac397..132c9a0b5c 100644
--- a/mail/em-folder-tree.h
+++ b/mail/em-folder-tree.h
@@ -84,7 +84,6 @@ struct _EMFolderTreeClass {
GType em_folder_tree_get_type (void);
GtkWidget *em_folder_tree_new_with_model (EMFolderTreeModel *model);
-void em_folder_tree_clone_expanded (EMFolderTree *emft);
void em_folder_tree_enable_drag_and_drop (EMFolderTree *emft);
diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c
index fbd2450012..bdf67ecfa0 100644
--- a/mail/em-folder-utils.c
+++ b/mail/em-folder-utils.c
@@ -706,7 +706,6 @@ em_folder_utils_create_folder (CamelFolderInfo *folderinfo, EMFolderTree *emft,
model = e_mail_shell_backend_get_folder_tree_model (global_mail_shell_backend);
folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model);
- em_folder_tree_clone_expanded (folder_tree);
dialog = em_folder_selector_create_new (folder_tree, 0, _("Create Folder"), _("Specify where to create the folder:"));
if (folderinfo != NULL)
diff --git a/plugins/groupwise-features/install-shared.c b/plugins/groupwise-features/install-shared.c
index e9fd927894..d770afa2d4 100644
--- a/plugins/groupwise-features/install-shared.c
+++ b/plugins/groupwise-features/install-shared.c
@@ -166,7 +166,6 @@ accept_clicked(GnomeDruidPage *page, GtkWidget *druid, CamelMimeMessage *msg)
accept_data = g_new0(struct AcceptData, 1);
model = mail_component_peek_tree_model (NULL);
folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model);
- em_folder_tree_clone_expanded (folder_tree);
dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
uri = em_folder_tree_get_selected_uri(folder_tree);
diff --git a/plugins/groupwise-features/share-folder-common.c b/plugins/groupwise-features/share-folder-common.c
index 900d949251..2f50f3a0cb 100644
--- a/plugins/groupwise-features/share-folder-common.c
+++ b/plugins/groupwise-features/share-folder-common.c
@@ -383,7 +383,6 @@ create_shared_folder(EPopup *ep, EPopupItem *p, gpointer data)
model = mail_component_peek_tree_model (mail_component_peek ());
folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model);
- em_folder_tree_clone_expanded (folder_tree);
dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
uri = em_folder_tree_get_selected_uri(folder_tree);