aboutsummaryrefslogtreecommitdiffstats
path: root/mail/em-folder-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/em-folder-tree.c')
-rw-r--r--mail/em-folder-tree.c140
1 files changed, 139 insertions, 1 deletions
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index fce291c5e1..dbcbb50eaa 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -41,6 +41,7 @@
#include <camel/camel-store.h>
#include <camel/camel-folder.h>
#include <camel/camel-stream-mem.h>
+#include <camel/camel-file-utils.h>
#include "e-util/e-mktemp.h"
#include "e-util/e-request.h"
@@ -49,6 +50,8 @@
#include "mail-mt.h"
#include "mail-ops.h"
#include "mail-tools.h"
+#include "mail-config.h"
+#include "mail-component.h"
#include "em-utils.h"
#include "em-popup.h"
@@ -92,6 +95,8 @@ struct _EMFolderTreePrivate {
char *selected_uri;
char *selected_path;
+ guint save_state_id;
+
/* dnd signal ids */
guint ddr, rdp, rd, ddg, ddd;
};
@@ -141,6 +146,10 @@ static void em_folder_tree_init (EMFolderTree *emft);
static void em_folder_tree_destroy (GtkObject *obj);
static void em_folder_tree_finalize (GObject *obj);
+static void em_folder_tree_save_state (EMFolderTree *emft);
+static void em_folder_tree_queue_save_state (EMFolderTree *emft);
+
+static void tree_row_collapsed (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *path, EMFolderTree *emft);
static void tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *path, EMFolderTree *emft);
static gboolean tree_button_press (GtkWidget *treeview, GdkEventButton *event, EMFolderTree *emft);
static void tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft);
@@ -349,6 +358,11 @@ em_folder_tree_destroy (GtkObject *obj)
priv->ddd = 0;
}
+ if (priv->save_state_id != 0) {
+ em_folder_tree_save_state ((EMFolderTree *) obj);
+ priv->save_state_id = 0;
+ }
+
priv->treeview = NULL;
priv->model = NULL;
@@ -402,6 +416,7 @@ em_folder_tree_construct (EMFolderTree *emft, EMFolderTreeModel *model)
gtk_widget_show ((GtkWidget *) priv->treeview);
g_signal_connect (priv->treeview, "row-expanded", G_CALLBACK (tree_row_expanded), emft);
+ g_signal_connect (priv->treeview, "row-collapsed", G_CALLBACK (tree_row_collapsed), emft);
g_signal_connect (priv->treeview, "button-press-event", G_CALLBACK (tree_button_press), emft);
selection = gtk_tree_view_get_selection ((GtkTreeView *) priv->treeview);
@@ -1023,6 +1038,8 @@ em_folder_tree_get_folder_info__got (struct _mail_msg *mm)
if (m->select_uri)
em_folder_tree_set_selected (m->emft, m->select_uri);
+
+ em_folder_tree_queue_save_state (m->emft);
}
static void
@@ -1063,8 +1080,10 @@ tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_p
COL_POINTER_CAMEL_STORE, &store,
COL_BOOL_LOAD_SUBDIRS, &load,
-1);
- if (!load)
+ if (!load) {
+ em_folder_tree_queue_save_state (emft);
return;
+ }
if (!path || !strcmp (path, "/"))
top = NULL;
@@ -1083,6 +1102,11 @@ tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_p
e_thread_put (mail_thread_new, (EMsg *) m);
}
+static void
+tree_row_collapsed (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_path, EMFolderTree *emft)
+{
+ em_folder_tree_queue_save_state (emft);
+}
#if 0
static void
@@ -2320,3 +2344,117 @@ em_folder_tree_get_model (EMFolderTree *emft)
return emft->priv->model;
}
+
+
+static void
+model_save_state (FILE *fp, struct _EMFolderTreePrivate *priv, GtkTreeModel *model, GtkTreeIter *node)
+{
+ struct _EMFolderTreeModelStoreInfo *si;
+ GtkTreePath *tree_path;
+ char *alias, *path;
+ EAccount *account;
+ CamelStore *store;
+ GtkTreeIter iter;
+
+ do {
+ tree_path = gtk_tree_model_get_path (model, node);
+ if (gtk_tree_view_row_expanded (priv->treeview, tree_path)) {
+ gtk_tree_model_get (model, node, COL_POINTER_CAMEL_STORE, &store, COL_STRING_FOLDER_PATH, &path, -1);
+ si = g_hash_table_lookup (priv->model->store_hash, store);
+ if ((account = mail_config_get_account_by_name (si->display_name))) {
+ alias = g_strdup_printf ("%s:%s", account->uid, path);
+ } else {
+ alias = g_strdup_printf ("%s:%s", si->display_name, path);
+ }
+ camel_file_util_encode_string (fp, alias);
+ g_free (alias);
+
+ if (gtk_tree_model_iter_children (model, &iter, node))
+ model_save_state (fp, priv, model, &iter);
+ }
+ gtk_tree_path_free (tree_path);
+ } while (gtk_tree_model_iter_next (model, node));
+}
+
+
+static void
+em_folder_tree_save_state (EMFolderTree *emft)
+{
+ struct _EMFolderTreePrivate *priv = emft->priv;
+ char *dirname, *filename, *tmpname;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ FILE *fp;
+ int fd;
+
+ if (priv->save_state_id != 0) {
+ g_source_remove (priv->save_state_id);
+ priv->save_state_id = 0;
+ }
+
+ model = gtk_tree_view_get_model (priv->treeview);
+
+ if (!gtk_tree_model_get_iter_first (model, &iter))
+ return;
+
+ dirname = (char *) mail_component_peek_base_directory (mail_component_peek ());
+ dirname = g_build_filename (dirname, "mail", "config", NULL);
+
+ if (camel_mkdir (dirname, 0777) == -1 && errno != EEXIST) {
+ g_free (dirname);
+ return;
+ }
+
+ tmpname = g_build_filename (dirname, "folder-tree.state~", NULL);
+ filename = g_build_filename (dirname, "folder-tree.state", NULL);
+ g_free (dirname);
+
+ if (!(fp = fopen (tmpname, "w+"))) {
+ g_free (filename);
+ g_free (tmpname);
+ return;
+ }
+
+ model_save_state (fp, priv, model, &iter);
+
+ if (fflush (fp) != 0)
+ goto exception;
+
+ if ((fd = fileno (fp)) == -1)
+ goto exception;
+
+ if (fsync (fd) == -1)
+ goto exception;
+
+ fclose (fp);
+ fp = NULL;
+
+ if (rename (tmpname, filename) == -1)
+ goto exception;
+
+ g_free (filename);
+ g_free (tmpname);
+
+ return;
+
+ exception:
+
+ if (fp != NULL)
+ fclose (fp);
+
+ unlink (tmpname);
+ g_free (tmpname);
+ g_free (filename);
+}
+
+
+static void
+em_folder_tree_queue_save_state (EMFolderTree *emft)
+{
+ struct _EMFolderTreePrivate *priv = emft->priv;
+
+ if (priv->save_state_id != 0)
+ return;
+
+ priv->save_state_id = g_timeout_add (1000, (GSourceFunc) em_folder_tree_save_state, emft);
+}