aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog27
-rw-r--r--mail/em-folder-tree-model.c99
-rw-r--r--mail/em-folder-tree-model.h17
-rw-r--r--mail/em-folder-tree.c33
-rw-r--r--mail/mail-component.c27
5 files changed, 168 insertions, 35 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 83333215fe..c207619a65 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,30 @@
+2004-06-10 Jeffrey Stedfast <fejj@novell.com>
+
+ Fixes bug #58825. Ugh. Really Gross Hack (tm).
+
+ * em-folder-tree.c (emft_tree_row_expanded): If the store that we
+ are expanding matches the uri that we've been requested to select
+ (e.g. from before the store was added to the tree), then give the
+ uri to the get_folder_info_op.
+ (em_folder_tree_set_selected): If the store for the uri isn't in
+ the tree yet, save the uri for later.
+
+ * mail-component.c (folder_selected_cb): Set the selected state of
+ the folder-tree and save it.
+ (impl_createControls): Restore the selected state on the
+ folder-tree.
+
+ * em-folder-tree-model.c (em_folder_tree_model_set_selected): New
+ function to set the selected-uri saved state.
+ (em_folder_tree_model_get_selected): New function to get the
+ selected uri saved state.
+ (em_folder_tree_model_save_state): Renamed.
+
+ * em-folder-tree.c (emft_update_model_expanded_state): Don't let
+ path be NULL if the node is a store node (path == NULL for any
+ other case is a bug).
+ (emft_maybe_expand_row): Same.
+
2004-06-10 Not Zed <NotZed@Ximian.com>
* message-list.c (message_list_set_selected): use new
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index 0ea5ced173..aa32044b6f 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -281,8 +281,8 @@ em_folder_tree_model_finalize (GObject *obj)
EMFolderTreeModel *model = (EMFolderTreeModel *) obj;
g_free (model->filename);
- if (model->expanded)
- xmlFreeDoc (model->expanded);
+ if (model->state)
+ xmlFreeDoc (model->state);
g_hash_table_foreach (model->store_hash, store_hash_free, NULL);
g_hash_table_destroy (model->store_hash);
@@ -317,16 +317,16 @@ em_folder_tree_model_load_state (EMFolderTreeModel *model, const char *filename)
xmlNodePtr root, node;
struct stat st;
- if (model->expanded)
- xmlFreeDoc (model->expanded);
+ if (model->state)
+ xmlFreeDoc (model->state);
- if (stat (filename, &st) == 0 && (model->expanded = xmlParseFile (filename)))
+ if (stat (filename, &st) == 0 && (model->state = xmlParseFile (filename)))
return;
/* setup some defaults - expand "Local Folders" and "VFolders" */
- model->expanded = xmlNewDoc ("1.0");
- root = xmlNewDocNode (model->expanded, NULL, "tree-state", NULL);
- xmlDocSetRootElement (model->expanded, root);
+ model->state = xmlNewDoc ("1.0");
+ root = xmlNewDocNode (model->state, NULL, "tree-state", NULL);
+ xmlDocSetRootElement (model->state, root);
node = xmlNewChild (root, NULL, "node", NULL);
xmlSetProp (node, "name", "local");
@@ -915,7 +915,7 @@ em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const char *key)
const char *name;
char *buf, *p;
- node = model->expanded ? model->expanded->children : NULL;
+ node = model->state ? model->state->children : NULL;
if (!node || strcmp (node->name, "tree-state") != 0)
return FALSE;
@@ -924,7 +924,7 @@ em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const char *key)
if (p[-1] == '/')
p[-1] = '\0';
p = NULL;
-
+
do {
if ((p = strchr (name, '/')))
*p = '\0';
@@ -942,7 +942,7 @@ em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const char *key)
name = p ? p + 1 : NULL;
} while (name && node);
-
+
return FALSE;
}
@@ -954,14 +954,14 @@ em_folder_tree_model_set_expanded (EMFolderTreeModel *model, const char *key, gb
const char *name;
char *buf, *p;
- if (model->expanded == NULL)
- model->expanded = xmlNewDoc ("1.0");
+ if (model->state == NULL)
+ model->state = xmlNewDoc ("1.0");
- if (!model->expanded->children) {
- node = xmlNewDocNode (model->expanded, NULL, "tree-state", NULL);
- xmlDocSetRootElement (model->expanded, node);
+ if (!model->state->children) {
+ node = xmlNewDocNode (model->state, NULL, "tree-state", NULL);
+ xmlDocSetRootElement (model->state, node);
} else {
- node = model->expanded->children;
+ node = model->state->children;
}
name = buf = g_alloca (strlen (key) + 1);
@@ -993,11 +993,11 @@ em_folder_tree_model_set_expanded (EMFolderTreeModel *model, const char *key, gb
}
void
-em_folder_tree_model_save_expanded (EMFolderTreeModel *model)
+em_folder_tree_model_save_state (EMFolderTreeModel *model)
{
char *dirname;
- if (model->expanded == NULL)
+ if (model->state == NULL)
return;
dirname = g_path_get_dirname (model->filename);
@@ -1008,7 +1008,7 @@ em_folder_tree_model_save_expanded (EMFolderTreeModel *model)
g_free (dirname);
- e_xml_save_file (model->filename, model->expanded);
+ e_xml_save_file (model->filename, model->state);
}
@@ -1048,7 +1048,7 @@ em_folder_tree_model_expand_foreach (EMFolderTreeModel *model, EMFTModelExpandFu
{
xmlNodePtr root;
- root = model->expanded ? model->expanded->children : NULL;
+ root = model->state ? model->state->children : NULL;
if (!root || !root->children || strcmp (root->name, "tree-state") != 0)
return;
@@ -1092,3 +1092,60 @@ em_folder_tree_model_set_unread_count (EMFolderTreeModel *model, CamelStore *sto
gtk_tree_store_set ((GtkTreeStore *) model, &iter, COL_UINT_UNREAD, unread, -1);
}
+
+
+char *
+em_folder_tree_model_get_selected (EMFolderTreeModel *model)
+{
+ xmlNodePtr node;
+ char *buf, *uri;
+
+ node = model->state ? model->state->children : NULL;
+ if (!node || strcmp (node->name, "tree-state") != 0)
+ return FALSE;
+
+ node = node->children;
+ while (node != NULL) {
+ if (!strcmp (node->name, "selected"))
+ break;
+ node = node->next;
+ }
+
+ if (node == NULL)
+ return NULL;
+
+ buf = xmlGetProp (node, "uri");
+ uri = g_strdup (buf);
+ xmlFree (buf);
+
+ return uri;
+}
+
+
+void
+em_folder_tree_model_set_selected (EMFolderTreeModel *model, const char *uri)
+{
+ xmlNodePtr root, node;
+
+ if (model->state == NULL)
+ model->state = xmlNewDoc ("1.0");
+
+ if (!model->state->children) {
+ root = xmlNewDocNode (model->state, NULL, "tree-state", NULL);
+ xmlDocSetRootElement (model->state, node);
+ } else {
+ root = model->state->children;
+ }
+
+ node = root->children;
+ while (node != NULL) {
+ if (!strcmp (node->name, "selected"))
+ break;
+ node = node->next;
+ }
+
+ if (node == NULL)
+ node = xmlNewChild (root, NULL, "selected", NULL);
+
+ xmlSetProp (node, "uri", uri);
+}
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index 83d2490c36..db46741657 100644
--- a/mail/em-folder-tree-model.h
+++ b/mail/em-folder-tree-model.h
@@ -84,7 +84,7 @@ struct _EMFolderTreeModel {
GtkTreeStore parent_object;
char *filename; /* state filename */
- xmlDocPtr expanded; /* saved expanded state from previous session */
+ xmlDocPtr state; /* saved expanded state from previous session */
GHashTable *store_hash; /* maps CamelStore's to store-info's */
GHashTable *uri_hash; /* maps URI's to GtkTreeRowReferences */
@@ -103,13 +103,16 @@ struct _EMFolderTreeModelClass {
GtkTreePath *path,
GtkTreeIter *iter);
- void (* loaded_row) (EMFolderTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter);
+ void (* loaded_row) (EMFolderTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter);
void (* folder_added) (EMFolderTreeModel *model,
const char *path,
const char *uri);
+
+ void (* store_added) (EMFolderTreeModel *model,
+ const char *uri);
};
@@ -128,9 +131,13 @@ void em_folder_tree_model_remove_store (EMFolderTreeModel *model, CamelStore *st
void em_folder_tree_model_remove_folders (EMFolderTreeModel *model, struct _EMFolderTreeModelStoreInfo *si,
GtkTreeIter *toplevel);
+char *em_folder_tree_model_get_selected (EMFolderTreeModel *model);
+void em_folder_tree_model_set_selected (EMFolderTreeModel *model, const char *uri);
+
gboolean em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const char *key);
void em_folder_tree_model_set_expanded (EMFolderTreeModel *model, const char *key, gboolean expanded);
-void em_folder_tree_model_save_expanded (EMFolderTreeModel *model);
+
+void em_folder_tree_model_save_state (EMFolderTreeModel *model);
typedef void (* EMFTModelExpandFunc) (EMFolderTreeModel *model, const char *path, void *user_data);
void em_folder_tree_model_expand_foreach (EMFolderTreeModel *model, EMFTModelExpandFunc func, void *user_data);
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index 101e593b96..96d5677073 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -76,6 +76,8 @@ struct _EMFolderTreePrivate {
GtkTreeView *treeview;
EMFolderTreeModel *model;
+ char *select_uri; /* uri to load when the proper store/etc have been populated */
+
char *selected_uri;
char *selected_path;
@@ -372,6 +374,7 @@ em_folder_tree_finalize (GObject *obj)
emft->priv->lost_folders = NULL;
}
+ g_free (emft->priv->select_uri);
g_free (emft->priv->selected_uri);
g_free (emft->priv->selected_path);
g_free (emft->priv);
@@ -560,6 +563,7 @@ static void
emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTreeIter *iter, EMFolderTree *emft)
{
struct _EMFolderTreeModelStoreInfo *si;
+ gboolean is_store;
CamelStore *store;
EAccount *account;
char *path, *key;
@@ -567,8 +571,12 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
gtk_tree_model_get ((GtkTreeModel *) model, iter,
COL_STRING_FULL_NAME, &path,
COL_POINTER_CAMEL_STORE, &store,
+ COL_BOOL_IS_STORE, &is_store,
-1);
+ if (is_store)
+ path = "";
+
si = g_hash_table_lookup (model->store_hash, store);
if ((account = mail_config_get_account_by_name (si->display_name))) {
key = g_strdup_printf ("%s/%s", account->uid, path);
@@ -1685,6 +1693,7 @@ static void
emft_update_model_expanded_state (struct _EMFolderTreePrivate *priv, GtkTreeIter *iter, gboolean expanded)
{
struct _EMFolderTreeModelStoreInfo *si;
+ gboolean is_store;
CamelStore *store;
EAccount *account;
char *path, *key;
@@ -1692,8 +1701,12 @@ emft_update_model_expanded_state (struct _EMFolderTreePrivate *priv, GtkTreeIter
gtk_tree_model_get ((GtkTreeModel *) priv->model, iter,
COL_STRING_FULL_NAME, &path,
COL_POINTER_CAMEL_STORE, &store,
+ COL_BOOL_IS_STORE, &is_store,
-1);
+ if (is_store && path == NULL)
+ path = "";
+
si = g_hash_table_lookup (priv->model->store_hash, store);
if ((account = mail_config_get_account_by_name (si->display_name))) {
key = g_strdup_printf ("%s/%s", account->uid, path);
@@ -1714,8 +1727,10 @@ emft_tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *t
{
struct _EMFolderTreePrivate *priv = emft->priv;
struct _EMFolderTreeGetFolderInfo *m;
+ CamelStore *store, *store2;
+ char *select_uri = NULL;
GtkTreeModel *model;
- CamelStore *store;
+ CamelException ex;
gboolean load;
char *path;
@@ -1734,6 +1749,17 @@ emft_tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *t
return;
}
+ camel_exception_init (&ex);
+ if (priv->select_uri &&
+ (store2 = (CamelStore *) camel_session_get_service (session, priv->select_uri, CAMEL_PROVIDER_STORE, &ex))) {
+ if (store2 == store) {
+ select_uri = priv->select_uri;
+ priv->select_uri = NULL;
+ }
+ camel_object_unref (store2);
+ }
+ camel_exception_clear (&ex);
+
m = mail_msg_new (&get_folder_info_op, NULL, sizeof (struct _EMFolderTreeGetFolderInfo));
m->root = gtk_tree_row_reference_new (model, tree_path);
camel_object_ref (store);
@@ -1742,7 +1768,7 @@ emft_tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *t
g_object_ref(emft);
m->top = g_strdup (path);
m->flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE;
- m->select_uri = NULL;
+ m->select_uri = select_uri;
e_thread_put (mail_thread_new, (EMsg *) m);
}
@@ -2703,6 +2729,7 @@ em_folder_tree_set_selected (EMFolderTree *emft, const char *uri)
}
if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
+ priv->select_uri = g_strdup (uri);
camel_object_unref (store);
return;
}
@@ -2802,7 +2829,7 @@ emft_save_state (EMFolderTree *emft)
{
struct _EMFolderTreePrivate *priv = emft->priv;
- em_folder_tree_model_save_expanded (priv->model);
+ em_folder_tree_model_save_state (priv->model);
priv->save_state_id = 0;
return FALSE;
diff --git a/mail/mail-component.c b/mail/mail-component.c
index 028d45257c..da437f38fb 100644
--- a/mail/mail-component.c
+++ b/mail/mail-component.c
@@ -172,7 +172,8 @@ static void
mc_add_store(MailComponent *component, CamelStore *store, const char *name, void (*done)(CamelStore *store, CamelFolderInfo *info, void *data))
{
struct _store_info *si;
-
+ char *uri;
+
MAIL_COMPONENT_DEFAULT(component);
si = store_info_new(store, name);
@@ -329,10 +330,17 @@ mc_startup(MailComponent *mc)
static void
folder_selected_cb (EMFolderTree *emft, const char *path, const char *uri, guint32 flags, EMFolderView *view)
{
- if ((flags & CAMEL_FOLDER_NOSELECT) || !path || !strcmp (path, ""))
+ EMFolderTreeModel *model;
+
+ if ((flags & CAMEL_FOLDER_NOSELECT) || !path) {
em_folder_view_set_folder (view, NULL, NULL);
- else
+ } else {
+ model = em_folder_tree_get_model (emft);
+ em_folder_tree_model_set_selected (model, uri);
+ em_folder_tree_model_save_state (model);
+
em_folder_view_set_folder_uri (view, uri);
+ }
}
static int
@@ -526,19 +534,26 @@ impl_createControls (PortableServer_Servant servant,
GtkWidget *tree_widget, *vbox, *info;
GtkWidget *view_widget;
GtkWidget *statusbar_widget;
-
+ char *uri;
+
mail_session_set_interactive(TRUE);
mc_startup(mail_component);
view_widget = em_folder_browser_new ();
/* so error boxes have a parent if none supplied */
e_error_default_parent((GtkWindow *)view_widget);
-
+
tree_widget = (GtkWidget *) em_folder_tree_new_with_model (priv->model);
em_folder_tree_set_excluded ((EMFolderTree *) tree_widget, 0);
em_folder_tree_enable_drag_and_drop ((EMFolderTree *) tree_widget);
+
+ if ((uri = em_folder_tree_model_get_selected (priv->model))) {
+ em_folder_tree_set_selected ((EMFolderTree *) tree_widget, uri);
+ g_free (uri);
+ }
+
em_format_set_session ((EMFormat *) ((EMFolderView *) view_widget)->preview, session);
-
+
g_signal_connect (view_widget, "on-url", G_CALLBACK (view_on_url), mail_component);
em_folder_view_set_statusbar ((EMFolderView*)view_widget, FALSE);