aboutsummaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ChangeLog16
-rw-r--r--shell/e-folder.c21
-rw-r--r--shell/e-folder.h2
-rw-r--r--shell/e-storage.c93
4 files changed, 96 insertions, 36 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index 52d7c1724c..556428e0f6 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,19 @@
+2003-04-15 Dan Winship <danw@ximian.com>
+
+ * e-folder.c (e_folder_get_has_subfolders,
+ e_folder_set_has_subfolders): new boolean flag.
+
+ * e-storage.c (EStoragePrivate, impl_finalize, init): Remove the
+ pseudofolders hash
+ (e_storage_async_open_folder): Replace the pseudofolders test with
+ a test of whether the folder has the "has_subfolders" flag set.
+ (e_storage_new_folder): Likewise (for the folder's parent).
+ (e_storage_declare_has_subfolders): Set "has_subfolders" on the
+ folder.
+ (e_storage_get_has_subfolders): Check "has_subfolders" on the
+ folder.
+ Should fix #33919.
+
2003-04-14 Not Zed <NotZed@Ximian.com>
* glade/e-active-connection-dialog.glade: fix the title of the
diff --git a/shell/e-folder.c b/shell/e-folder.c
index 0568308488..8226170e92 100644
--- a/shell/e-folder.c
+++ b/shell/e-folder.c
@@ -57,6 +57,7 @@ struct _EFolderPrivate {
unsigned int self_highlight : 1;
unsigned int is_stock : 1;
unsigned int can_sync_offline : 1;
+ unsigned int has_subfolders : 1;
/* Custom icon for this folder; if NULL the folder will just use the
icon for its type. */
@@ -181,6 +182,7 @@ init (EFolder *folder)
priv->self_highlight = FALSE;
priv->is_stock = FALSE;
priv->can_sync_offline = FALSE;
+ priv->has_subfolders = FALSE;
priv->custom_icon_name = NULL;
folder->priv = priv;
@@ -299,6 +301,14 @@ e_folder_get_can_sync_offline (EFolder *folder)
return folder->priv->can_sync_offline;
}
+gboolean
+e_folder_get_has_subfolders (EFolder *folder)
+{
+ g_return_val_if_fail (E_IS_FOLDER (folder), FALSE);
+
+ return folder->priv->has_subfolders;
+}
+
/**
* e_folder_get_custom_icon:
* @folder: An EFolder
@@ -444,6 +454,17 @@ e_folder_set_can_sync_offline (EFolder *folder,
g_signal_emit (folder, signals[CHANGED], 0);
}
+void
+e_folder_set_has_subfolders (EFolder *folder,
+ gboolean has_subfolders)
+{
+ g_return_if_fail (E_IS_FOLDER (folder));
+
+ folder->priv->has_subfolders = !! has_subfolders;
+
+ g_signal_emit (folder, signals[CHANGED], 0);
+}
+
/**
* e_folder_set_custom_icon_name:
* @folder: An EFolder
diff --git a/shell/e-folder.h b/shell/e-folder.h
index bf7db6c063..53308fb62f 100644
--- a/shell/e-folder.h
+++ b/shell/e-folder.h
@@ -81,6 +81,7 @@ int e_folder_get_unread_count (EFolder *folder);
gboolean e_folder_get_highlighted (EFolder *folder);
gboolean e_folder_get_is_stock (EFolder *folder);
gboolean e_folder_get_can_sync_offline (EFolder *folder);
+gboolean e_folder_get_has_subfolders (EFolder *folder);
const char *e_folder_get_custom_icon_name (EFolder *folder);
int e_folder_get_sorting_priority (EFolder *folder);
@@ -92,6 +93,7 @@ void e_folder_set_unread_count (EFolder *folder, int unread_count);
void e_folder_set_child_highlight (EFolder *folder, gboolean highlighted);
void e_folder_set_is_stock (EFolder *folder, gboolean is_stock);
void e_folder_set_can_sync_offline (EFolder *folder, gboolean can_sync_offline);
+void e_folder_set_has_subfolders (EFolder *folder, gboolean has_subfolders);
void e_folder_set_custom_icon (EFolder *folder, const char *icon_name);
void e_folder_set_sorting_priority (EFolder *folder, int sorting_priority);
diff --git a/shell/e-storage.c b/shell/e-storage.c
index 1f54ee5afa..f4a8e5ff26 100644
--- a/shell/e-storage.c
+++ b/shell/e-storage.c
@@ -53,9 +53,6 @@ struct _EStoragePrivate {
/* The set of folders we have in this storage. */
EFolderTree *folder_tree;
- /* The pseudofolders representing un-filled-in subtrees */
- GHashTable *pseudofolders;
-
/* Internal name of the storage */
char *name;
};
@@ -132,13 +129,6 @@ folder_changed_cb (EFolder *folder,
/* GObject methods. */
static void
-free_folder (gpointer path, gpointer folder, gpointer user_data)
-{
- g_free (path);
- /* folders will have been freed by e_folder_tree_destroy */
-}
-
-static void
impl_finalize (GObject *object)
{
EStorage *storage;
@@ -149,10 +139,6 @@ impl_finalize (GObject *object)
if (priv->folder_tree != NULL)
e_folder_tree_destroy (priv->folder_tree);
- if (priv->pseudofolders) {
- g_hash_table_foreach (priv->pseudofolders, free_folder, NULL);
- g_hash_table_destroy (priv->pseudofolders);
- }
g_free (priv->name);
@@ -322,7 +308,6 @@ init (EStorage *storage)
priv = g_new (EStoragePrivate, 1);
priv->folder_tree = e_folder_tree_new (folder_destroy_notify, NULL);
- priv->pseudofolders = g_hash_table_new (g_str_hash, g_str_equal);
priv->name = NULL;
storage->priv = priv;
@@ -494,12 +479,23 @@ e_storage_async_open_folder (EStorage *storage,
EStorageDiscoveryCallback callback,
void *data)
{
+ EStoragePrivate *priv;
+ EFolder *folder;
+
g_return_if_fail (storage != NULL);
g_return_if_fail (E_IS_STORAGE (storage));
g_return_if_fail (path != NULL);
g_return_if_fail (g_path_is_absolute (path));
- if (g_hash_table_lookup (storage->priv->pseudofolders, path) == NULL) {
+ priv = storage->priv;
+
+ folder = e_folder_tree_get_folder (priv->folder_tree, path);
+ if (folder == NULL) {
+ (* callback) (storage, E_STORAGE_NOTFOUND, path, data);
+ return;
+ }
+
+ if (! e_folder_get_has_subfolders (folder)) {
(* callback) (storage, E_STORAGE_OK, path, data);
return;
}
@@ -676,6 +672,24 @@ e_storage_get_path_for_physical_uri (EStorage *storage,
/* These functions are used by subclasses to add and remove folders from the
state stored in the storage object. */
+static void
+remove_subfolders_except (EStorage *storage, const char *path, const char *except)
+{
+ EStoragePrivate *priv;
+ GList *subfolders, *f;
+ const char *folder_path;
+
+ priv = storage->priv;
+
+ subfolders = e_folder_tree_get_subfolders (priv->folder_tree, path);
+ for (f = subfolders; f; f = f->next) {
+ folder_path = f->data;
+ if (!except || strcmp (folder_path, except) != 0)
+ e_storage_removed_folder (storage, folder_path);
+ }
+ e_free_string_list (subfolders);
+}
+
gboolean
e_storage_new_folder (EStorage *storage,
const char *path,
@@ -683,7 +697,7 @@ e_storage_new_folder (EStorage *storage,
{
EStoragePrivate *priv;
char *parent_path, *p;
- gpointer stored_path, pseudofolder;
+ EFolder *parent;
g_return_val_if_fail (storage != NULL, FALSE);
g_return_val_if_fail (E_IS_STORAGE (storage), FALSE);
@@ -697,17 +711,18 @@ e_storage_new_folder (EStorage *storage,
if (! e_folder_tree_add (priv->folder_tree, path, e_folder))
return FALSE;
+ /* If this is the child of a folder that has a pseudo child,
+ * remove the pseudo child now.
+ */
p = strrchr (path, '/');
if (p && p != path)
parent_path = g_strndup (path, p - path);
else
parent_path = g_strdup ("/");
- if (g_hash_table_lookup_extended (priv->pseudofolders, parent_path,
- &stored_path, &pseudofolder) &&
- pseudofolder != e_folder) {
- g_hash_table_remove (priv->pseudofolders, parent_path);
- g_free (stored_path);
- e_storage_removed_folder (storage, e_folder_get_physical_uri (pseudofolder));
+ parent = e_folder_tree_get_folder (priv->folder_tree, parent_path);
+ if (parent && e_folder_get_has_subfolders (parent)) {
+ remove_subfolders_except (storage, parent_path, path);
+ e_folder_set_has_subfolders (parent, FALSE);
}
g_free (parent_path);
@@ -732,9 +747,9 @@ e_storage_declare_has_subfolders (EStorage *storage,
const char *message)
{
EStoragePrivate *priv;
- GList *subfolders, *f;
- EFolder *pseudofolder;
+ EFolder *parent, *pseudofolder;
char *pseudofolder_path;
+ gboolean ok;
g_return_val_if_fail (storage != NULL, FALSE);
g_return_val_if_fail (E_IS_STORAGE (storage), FALSE);
@@ -744,16 +759,13 @@ e_storage_declare_has_subfolders (EStorage *storage,
priv = storage->priv;
- if (g_hash_table_lookup (priv->pseudofolders, path))
+ parent = e_folder_tree_get_folder (priv->folder_tree, path);
+ if (parent == NULL)
+ return FALSE;
+ if (e_folder_get_has_subfolders (parent))
return TRUE;
- subfolders = e_folder_tree_get_subfolders (priv->folder_tree, path);
- if (subfolders != NULL) {
- for (f = subfolders; f; f = f->next)
- e_storage_removed_folder (storage, f->data);
- g_list_free (subfolders);
- /* FIXME: close parent */
- }
+ remove_subfolders_except (storage, path, NULL);
pseudofolder = e_folder_new (message, "working", "");
if (strcmp (path, "/") == 0)
@@ -762,9 +774,15 @@ e_storage_declare_has_subfolders (EStorage *storage,
pseudofolder_path = g_strdup_printf ("%s/%s", path, message);
e_folder_set_physical_uri (pseudofolder, pseudofolder_path);
- g_hash_table_insert (priv->pseudofolders, g_strdup (path), pseudofolder);
+ ok = e_storage_new_folder (storage, pseudofolder_path, pseudofolder);
+ g_free (pseudofolder_path);
+ if (!ok) {
+ g_object_unref (pseudofolder);
+ return FALSE;
+ }
- return e_storage_new_folder (storage, pseudofolder_path, pseudofolder);
+ e_folder_set_has_subfolders (parent, TRUE);
+ return TRUE;
}
gboolean
@@ -772,6 +790,7 @@ e_storage_get_has_subfolders (EStorage *storage,
const char *path)
{
EStoragePrivate *priv;
+ EFolder *folder;
g_return_val_if_fail (storage != NULL, FALSE);
g_return_val_if_fail (E_IS_STORAGE (storage), FALSE);
@@ -780,7 +799,9 @@ e_storage_get_has_subfolders (EStorage *storage,
priv = storage->priv;
- return g_hash_table_lookup (priv->pseudofolders, path) != NULL;
+ folder = e_folder_tree_get_folder (priv->folder_tree, path);
+
+ return folder && e_folder_get_has_subfolders (folder);
}
gboolean