diff options
-rw-r--r-- | mail/ChangeLog | 27 | ||||
-rw-r--r-- | mail/em-folder-tree-model.c | 99 | ||||
-rw-r--r-- | mail/em-folder-tree-model.h | 17 | ||||
-rw-r--r-- | mail/em-folder-tree.c | 33 | ||||
-rw-r--r-- | mail/mail-component.c | 27 |
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); |