diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ChangeLog | 19 | ||||
-rw-r--r-- | shell/e-local-storage.c | 159 |
2 files changed, 133 insertions, 45 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index 070b72638a..6abf2cc700 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,20 @@ +2002-06-25 Ettore Perazzoli <ettore@ximian.com> + + [Fix #10681, Incorrect behavior when deleting a hierarchy of local + folders.] + + * e-local-storage.c: Change the ASyncRemoveFolderCallbackData + struct to have only storage and next_paths_to_delete members. + (remove_folder_step): New. + (component_async_remove_folder_callback): Start deletion for the + next path in next_paths_to_delete, so we handle recursion + properly. + (create_subfolder_list): New. + (remove_folder): Create the list with create_subfolder_list, + initialize the ASyncRemoveFolderCallbackData with the + next_paths_to_delete list and do the first deletion. This way we + handle recursion properly. + 2002-06-26 Iain <iain@ximian.com> * e-shell-importer.c (show_import_wizard): Only let the dialog be @@ -32,6 +49,8 @@ 2002-06-24 Ettore Perazzoli <ettore@ximian.com> + * e-local-storage.c (remove_folder): Removed arg @physical_uri. + * e-shell-folder-selection-dialog.c (impl_clicked): Pass default_type to e_shell_show_folder_creation_dialog() properly. [Patch by Christian Kreibich <christian@whoop.org>.] diff --git a/shell/e-local-storage.c b/shell/e-local-storage.c index 46965f43a8..a521f5503a 100644 --- a/shell/e-local-storage.c +++ b/shell/e-local-storage.c @@ -449,9 +449,7 @@ create_folder (ELocalStorage *local_storage, struct _AsyncRemoveFolderCallbackData { EStorage *storage; - - char *path; - char *physical_path; + GList *next_paths_to_delete; }; typedef struct _AsyncRemoveFolderCallbackData AsyncRemoveFolderCallbackData; @@ -500,55 +498,139 @@ remove_folder_directory (ELocalStorage *local_storage, return E_STORAGE_OK; } +static gboolean remove_folder_step (AsyncRemoveFolderCallbackData *callback_data); + static void component_async_remove_folder_callback (EvolutionShellComponentClient *shell_component_client, EvolutionShellComponentResult result, void *data) { + ELocalStoragePrivate *priv; AsyncRemoveFolderCallbackData *callback_data; EStorageResult storage_result; + gboolean success; + const char *path; callback_data = (AsyncRemoveFolderCallbackData *) data; + priv = E_LOCAL_STORAGE (callback_data->storage)->priv; + path = (const char *) callback_data->next_paths_to_delete->data; storage_result = shell_component_result_to_storage_result (result); - /* If result == HASSUBFOLDERS then recurse delete the subfolders dir? */ - - /* FIXME: Handle errors */ if (result == EVOLUTION_SHELL_COMPONENT_OK) { - ELocalStoragePrivate *priv; + result = remove_folder_directory (E_LOCAL_STORAGE (callback_data->storage), path); + e_storage_removed_folder (E_STORAGE (callback_data->storage), path); + + g_print ("...Removed %s!\n", path); + + evolution_storage_removed_folder (EVOLUTION_STORAGE (priv->bonobo_interface), path); + } else { + /* FIXME: Handle errors. */ + g_print ("...Error removing %s!\n", path); + } + + bonobo_object_unref (BONOBO_OBJECT (shell_component_client)); - priv = E_LOCAL_STORAGE (callback_data->storage)->priv; + /* Now go on and delete the next subfolder in the list that still + exists, deallocating the elements in the list in the process. */ + do { + char *path; - result = remove_folder_directory (E_LOCAL_STORAGE (callback_data->storage), - callback_data->path); + path = callback_data->next_paths_to_delete->data; + g_free (path); - e_storage_removed_folder (E_STORAGE (callback_data->storage), - callback_data->path); + callback_data->next_paths_to_delete + = g_list_remove_link (callback_data->next_paths_to_delete, + callback_data->next_paths_to_delete); + + /* Check if we are done. */ + if (callback_data->next_paths_to_delete == NULL) { + g_free (callback_data); + return; + } - evolution_storage_removed_folder (EVOLUTION_STORAGE (priv->bonobo_interface), - callback_data->path); + /* Remove the folder; if the folder has disappeared from the + tree for some reason (this is an async callback!), just go + on with the next one. */ + success = remove_folder_step (callback_data); + } while (! success); +} + +static gboolean +remove_folder_step (AsyncRemoveFolderCallbackData *callback_data) +{ + EvolutionShellComponentClient *client; + ELocalStoragePrivate *priv; + EFolder *folder; + const char *path; + const char *type; + char *physical_path; + char *physical_uri; + + g_assert (callback_data->next_paths_to_delete != NULL); + path = (const char *) callback_data->next_paths_to_delete->data; + + folder = e_storage_get_folder (callback_data->storage, path); + if (folder == NULL) + return FALSE; + + priv = E_LOCAL_STORAGE (callback_data->storage)->priv; + + physical_path = e_path_to_physical (priv->base_path, path); + physical_uri = g_strconcat ("file://", physical_path, NULL); + + type = e_folder_get_type_string (folder); + client = e_folder_type_registry_get_handler_for_type (priv->folder_type_registry, type); + + bonobo_object_ref (BONOBO_OBJECT (client)); + + g_print ("Removing %s...\n", path); + + evolution_shell_component_client_async_remove_folder (client, physical_uri, type, + component_async_remove_folder_callback, + callback_data); + + g_free (physical_path); + g_free (physical_uri); + + return TRUE; +} + +static GList * +create_subfolder_list (ELocalStorage *local_storage, + const char *path) +{ + GList *subfolders; + GList *list; + GList *p; + + subfolders = e_storage_get_subfolder_paths (E_STORAGE (local_storage), path); + + list = NULL; + for (p = subfolders; p != NULL; p = p->next) { + char *path; + + path = (char *) p->data; + + list = g_list_concat (list, create_subfolder_list (local_storage, path)); + list = g_list_append (list, path); } - bonobo_object_unref (BONOBO_OBJECT (shell_component_client)); + g_list_free (subfolders); - g_free (callback_data->path); - g_free (callback_data->physical_path); - g_free (callback_data); + return list; } static EStorageResult remove_folder (ELocalStorage *local_storage, - const char *path, - const char *physical_uri) + const char *path) { ELocalStoragePrivate *priv; EStorage *storage; AsyncRemoveFolderCallbackData *callback_data; EvolutionShellComponentClient *component_client; EFolder *folder; - char *physical_path, *physical_uri_mem = NULL; - GList *subfolder_paths; + GList *next_paths_to_delete; GList *p; priv = local_storage->priv; @@ -564,30 +646,17 @@ remove_folder (ELocalStorage *local_storage, if (component_client == NULL) return E_STORAGE_INVALIDTYPE; - physical_path = e_path_to_physical (priv->base_path, path); - - if (!physical_uri) - physical_uri = physical_uri_mem = g_strconcat ("file://", physical_path, NULL); - - /* Recursively remove the subfolders */ - subfolder_paths = e_storage_get_subfolder_paths (storage, path); - - for (p = subfolder_paths; p; p = p->next) - remove_folder (local_storage, p->data, NULL); + next_paths_to_delete = create_subfolder_list (E_LOCAL_STORAGE (storage), path); + next_paths_to_delete = g_list_append (next_paths_to_delete, g_strdup (path)); callback_data = g_new (AsyncRemoveFolderCallbackData, 1); - callback_data->storage = E_STORAGE (local_storage); - callback_data->path = g_strdup (path); - callback_data->physical_path = physical_path; - - bonobo_object_ref (BONOBO_OBJECT (component_client)); + callback_data->storage = E_STORAGE (local_storage); + callback_data->next_paths_to_delete = next_paths_to_delete; - evolution_shell_component_client_async_remove_folder (component_client, - physical_uri, - e_folder_get_type_string (folder), - component_async_remove_folder_callback, - callback_data); - g_free (physical_uri_mem); + if (! remove_folder_step (callback_data)) { + /* Eek, something wacky happened. */ + return EVOLUTION_SHELL_COMPONENT_UNKNOWNERROR; + } return EVOLUTION_SHELL_COMPONENT_OK; } @@ -654,7 +723,7 @@ impl_async_remove_folder (EStorage *storage, local_storage = E_LOCAL_STORAGE (storage); - result = remove_folder (local_storage, path, NULL); + result = remove_folder (local_storage, path); if (callback != NULL) (* callback) (E_STORAGE (local_storage), result, data); @@ -953,7 +1022,7 @@ bonobo_interface_remove_folder_cb (EvolutionStorage *storage, local_storage = E_LOCAL_STORAGE (data); - return remove_folder (local_storage, path, physical_uri); + return remove_folder (local_storage, path); } static void |