New function to save tree expanded state.

2003-11-24  Jeffrey Stedfast  <fejj@ximian.com>

	* em-folder-tree.c (em_folder_tree_save_state): New function to
	save tree expanded state.
	(em_folder_tree_queue_save_state): New function to queue saving of
	the expanded state.
	(em_folder_tree_construct): Connect to the row-collapsed signal.
	(tree_row_collapsed): Queue a save-state.
	(tree_row_expanded): Queue a save state.
	(em_folder_tree_get_folder_info__got): Queue a save-state.

svn path=/trunk/; revision=23485
This commit is contained in:
Jeffrey Stedfast
2003-11-25 03:54:13 +00:00
committed by Jeffrey Stedfast
parent 1b63055fb9
commit 30ff908fcd
4 changed files with 153 additions and 1 deletions

View File

@ -1,3 +1,14 @@
2003-11-24 Jeffrey Stedfast <fejj@ximian.com>
* em-folder-tree.c (em_folder_tree_save_state): New function to
save tree expanded state.
(em_folder_tree_queue_save_state): New function to queue saving of
the expanded state.
(em_folder_tree_construct): Connect to the row-collapsed signal.
(tree_row_collapsed): Queue a save-state.
(tree_row_expanded): Queue a save state.
(em_folder_tree_get_folder_info__got): Queue a save-state.
2003-11-25 Not Zed <NotZed@Ximian.com>
* em-folder-view.c (em_folder_view_print): set session on print

View File

@ -25,6 +25,8 @@
#include <config.h>
#endif
#include <string.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkstock.h>

View File

@ -64,6 +64,7 @@ struct _EMFolderTreeModel {
GHashTable *store_hash; /* maps CamelStore's to store-info's */
GHashTable *uri_hash; /* maps URI's to GtkTreeRowReferences */
GHashTable *expanded;
};
struct _EMFolderTreeModelClass {

View File

@ -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);
}