diff options
-rw-r--r-- | mail/ChangeLog | 23 | ||||
-rw-r--r-- | mail/em-folder-tree.c | 167 | ||||
-rw-r--r-- | mail/mail-config.c | 6 | ||||
-rw-r--r-- | mail/mail-config.h | 1 |
4 files changed, 193 insertions, 4 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index 1ee08023ec..45b30a2acf 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,26 @@ +2003-12-01 Jeffrey Stedfast <fejj@ximian.com> + + * em-folder-tree.c (em_folder_tree_get_folder_info__got): Make + sure our parent folder hasn't been unsubscribed or else we get a + segfault here if it has. + +03-11-28 Dave Camp <dave@ximian.com> + + * em-folder-tree.c (render_pixbuf): Set the pixbuf renderer + invisible for stores. + +2003-11-25 Jeffrey Stedfast <fejj@ximian.com> + + * mail-config.c (mail_config_get_account_by_uid): New function. + + * em-folder-tree.c (tree_store_set_folder_info): Expand the tree + node if the saved state tells us it was expanded the previous + session. + (em_folder_tree_load_state): Load the saved state. + (em_folder_tree_add_store): Conditionally expand the store node. + (em_folder_tree_new_with_model): Expand all the nodes that should + be expanded. + 2003-12-01 Radek Doulik <rodo@ximian.com> * em-folder-tree.c (render_pixbuf): use CAMEL_VTRASH_NAME, diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c index a5d1e718a7..48c71f164d 100644 --- a/mail/em-folder-tree.c +++ b/mail/em-folder-tree.c @@ -93,6 +93,8 @@ struct _EMFolderTreePrivate { GtkTreeView *treeview; EMFolderTreeModel *model; + GHashTable *expanded; + char *selected_uri; char *selected_path; @@ -123,7 +125,7 @@ enum DndDropType { }; static GtkTargetEntry drag_types[] = { - { "x-uid-list", 0, DND_DRAG_TYPE_FOLDER }, + { "x-folder", 0, DND_DRAG_TYPE_FOLDER }, { "text/uri-list", 0, DND_DRAG_TYPE_TEXT_URI_LIST }, }; @@ -275,7 +277,7 @@ render_pixbuf (GtkTreeViewColumn *column, GtkCellRenderer *renderer, pixbuf = folder_icons[FOLDER_ICON_NORMAL]; } - g_object_set (renderer, "pixbuf", pixbuf, NULL); + g_object_set (renderer, "pixbuf", pixbuf, "visible", !is_store, NULL); } static void @@ -309,17 +311,52 @@ render_display_name (GtkTreeViewColumn *column, GtkCellRenderer *renderer, g_free (display); } + +static gboolean +expanded_free (gpointer key, gpointer value, gpointer user_data) +{ + g_free (key); + return TRUE; +} + +static void +em_folder_tree_load_state (EMFolderTree *emft) +{ + struct _EMFolderTreePrivate *priv = emft->priv; + char *filename, *node; + const char *dirname; + FILE *fp; + + g_hash_table_foreach_remove (priv->expanded, expanded_free, NULL); + + /*dirname = mail_component_peek_base_directory (mail_component_peek ());*/ + dirname = "/home/null/.evolution"; + filename = g_build_filename (dirname, "mail", "config", "folder-tree.state", NULL); + if ((fp = fopen (filename, "r")) == NULL) { + g_free (filename); + return; + } + + while (camel_file_util_decode_string (fp, &node) != -1) + g_hash_table_insert (priv->expanded, node, GINT_TO_POINTER (TRUE)); + + fclose (fp); +} + static void em_folder_tree_init (EMFolderTree *emft) { struct _EMFolderTreePrivate *priv; priv = g_new0 (struct _EMFolderTreePrivate, 1); + priv->expanded = g_hash_table_new (g_str_hash, g_str_equal); priv->selected_uri = NULL; priv->selected_path = NULL; priv->treeview = NULL; priv->model = NULL; emft->priv = priv; + + em_folder_tree_load_state (emft); } static void @@ -327,6 +364,9 @@ em_folder_tree_finalize (GObject *obj) { EMFolderTree *emft = (EMFolderTree *) obj; + g_hash_table_foreach (emft->priv->expanded, (GHFunc) g_free, NULL); + g_hash_table_destroy (emft->priv->expanded); + g_free (emft->priv->selected_uri); g_free (emft->priv->selected_path); g_free (emft->priv); @@ -863,6 +903,72 @@ em_folder_tree_new (void) } +struct _gsbn { + struct _EMFolderTreeModelStoreInfo *si; + const char *name; +}; + +static void +get_store_by_name (CamelStore *store, struct _EMFolderTreeModelStoreInfo *si, struct _gsbn *gsbn) +{ + if (!strcmp (si->display_name, gsbn->name)) + gsbn->si = si; +} + +static void +expand_node (char *key, gpointer value, EMFolderTree *emft) +{ + struct _EMFolderTreePrivate *priv = emft->priv; + struct _EMFolderTreeModelStoreInfo *si; + GtkTreeRowReference *row; + GtkTreePath *path; + EAccount *account; + char *id, *p; + + if (!(p = strchr (key, ':'))) + return; + + id = g_strndup (key, p - key); + if ((account = mail_config_get_account_by_uid (id))) { + CamelException ex; + CamelStore *store; + + camel_exception_init (&ex); + store = (CamelStore *) camel_session_get_service (session, account->source->url, CAMEL_PROVIDER_STORE, &ex); + camel_exception_clear (&ex); + + if (store == NULL || !(si = g_hash_table_lookup (priv->model->store_hash, store))) { + if (store) + camel_object_unref (store); + g_free (id); + return; + } + } else { + struct _gsbn gsbn; + + gsbn.si = NULL; + gsbn.name = id; + + g_hash_table_foreach (priv->model->store_hash, (GHFunc) get_store_by_name, &gsbn); + if (!(si = gsbn.si)) { + g_free (id); + return; + } + } + + g_free (id); + + p++; + if (!strcmp (p, "/")) + row = si->row; + else if (!(row = g_hash_table_lookup (si->path_hash, p))) + return; + + path = gtk_tree_row_reference_get_path (row); + gtk_tree_view_expand_to_path (priv->treeview, path); + gtk_tree_path_free (path); +} + GtkWidget * em_folder_tree_new_with_model (EMFolderTreeModel *model) { @@ -872,6 +978,8 @@ em_folder_tree_new_with_model (EMFolderTreeModel *model) em_folder_tree_construct (emft, model); g_object_ref (model); + g_hash_table_foreach (emft->priv->expanded, (GHFunc) expand_node, emft); + return (GtkWidget *) emft; } @@ -884,16 +992,18 @@ tree_store_set_folder_info (GtkTreeStore *model, GtkTreeIter *iter, { GtkTreeRowReference *uri_row, *path_row; unsigned int unread; + EAccount *account; GtkTreePath *path; GtkTreeIter sub; gboolean load; + char *node; load = !fi->child && (fi->flags & CAMEL_FOLDER_CHILDREN) && !(fi->flags & CAMEL_FOLDER_NOINFERIORS); path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter); uri_row = gtk_tree_row_reference_new ((GtkTreeModel *) model, path); path_row = gtk_tree_row_reference_copy (uri_row); - gtk_tree_path_free (path); + /*gtk_tree_path_free (path);*/ g_hash_table_insert (priv->model->uri_hash, g_strdup (fi->url), uri_row); g_hash_table_insert (si->path_hash, g_strdup (fi->path), path_row); @@ -910,6 +1020,8 @@ tree_store_set_folder_info (GtkTreeStore *model, GtkTreeIter *iter, COL_BOOL_LOAD_SUBDIRS, load, -1); + node = fi->path; + if (fi->child) { fi = fi->child; @@ -930,7 +1042,36 @@ tree_store_set_folder_info (GtkTreeStore *model, GtkTreeIter *iter, COL_STRING_URI, fi->url, COL_UINT_UNREAD, 0, -1); +#if 0 + if ((account = mail_config_get_account_by_name (si->display_name))) + node = g_strdup_printf ("%s:%s", account->uid, fi->path); + else + node = g_strdup_printf ("%s:%s", si->display_name, fi->path); + + if (g_hash_table_lookup (priv->expanded, node)) { + printf ("expanding node '%s'\n", node); + path = gtk_tree_model_get_path ((GtkTreeModel *) model, &sub); + gtk_tree_view_expand_to_path (priv->treeview, path); + gtk_tree_path_free (path); + } + + g_free (node); +#endif } +#if 1 + if ((account = mail_config_get_account_by_name (si->display_name))) + node = g_strdup_printf ("%s:%s", account->uid, node); + else + node = g_strdup_printf ("%s:%s", si->display_name, node); + + if (g_hash_table_lookup (priv->expanded, node)) { + printf ("expanding node '%s'\n", node); + gtk_tree_view_expand_to_path (priv->treeview, path); + } + + gtk_tree_path_free (path); + g_free (node); +#endif } #if 0 @@ -998,6 +1139,10 @@ em_folder_tree_get_folder_info__got (struct _mail_msg *mm) if (priv->treeview == NULL) return; + /* check that our parent folder hasn't been deleted/unsubscribed */ + if (!gtk_tree_row_reference_is_valid (m->root)) + return; + if (!(si = g_hash_table_lookup (priv->model->store_hash, m->store))) { /* store has been removed in the interim - do nothing */ return; @@ -2136,7 +2281,8 @@ em_folder_tree_add_store (EMFolderTree *emft, CamelStore *store, const char *dis GtkTreeIter root, iter; GtkTreeStore *model; GtkTreePath *path; - char *uri; + EAccount *account; + char *node, *uri; g_return_if_fail (EM_IS_FOLDER_TREE (emft)); g_return_if_fail (CAMEL_IS_STORE (store)); @@ -2199,6 +2345,19 @@ em_folder_tree_add_store (EMFolderTree *emft, CamelStore *store, const char *dis g_free (uri); + if ((account = mail_config_get_account_by_name (display_name))) + node = g_strdup_printf ("%s:/", account->uid); + else + node = g_strdup_printf ("%s:/", display_name); + + if (g_hash_table_lookup (priv->expanded, node)) { + path = gtk_tree_model_get_path ((GtkTreeModel *) model, &iter); + gtk_tree_view_expand_to_path (priv->treeview, path); + gtk_tree_path_free (path); + } + + g_free (node); + /* listen to store events */ #define CAMEL_CALLBACK(func) ((CamelObjectEventHookFunc) func) si->created_id = camel_object_hook_event (store, "folder_created", CAMEL_CALLBACK (folder_created_cb), emft); diff --git a/mail/mail-config.c b/mail/mail-config.c index bb0b11be61..dfb9be8f1f 100644 --- a/mail/mail-config.c +++ b/mail/mail-config.c @@ -768,6 +768,12 @@ mail_config_get_account_by_name (const char *account_name) } EAccount * +mail_config_get_account_by_uid (const char *uid) +{ + return (EAccount *) e_account_list_find (config->accounts, E_ACCOUNT_FIND_UID, uid); +} + +EAccount * mail_config_get_account_by_source_url (const char *source_url) { CamelProvider *provider; diff --git a/mail/mail-config.h b/mail/mail-config.h index 5782efe8a6..36891eccb4 100644 --- a/mail/mail-config.h +++ b/mail/mail-config.h @@ -121,6 +121,7 @@ void mail_config_service_set_save_passwd (EAccountService *service, gboolean sav gboolean mail_config_find_account (EAccount *account); EAccount *mail_config_get_default_account (void); EAccount *mail_config_get_account_by_name (const char *account_name); +EAccount *mail_config_get_account_by_uid (const char *uid); EAccount *mail_config_get_account_by_source_url (const char *url); EAccount *mail_config_get_account_by_transport_url (const char *url); EAccountList *mail_config_get_accounts (void); |