aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog7
-rw-r--r--mail/component-factory.c26
-rw-r--r--shell/ChangeLog76
-rw-r--r--shell/e-folder.c1
-rw-r--r--shell/e-local-folder.c50
-rw-r--r--shell/e-local-folder.h13
-rw-r--r--shell/e-local-storage.c277
-rw-r--r--shell/e-local-storage.h8
-rw-r--r--shell/e-shell-folder-creation-dialog.c207
-rw-r--r--shell/e-shell.c2
-rw-r--r--shell/e-storage-set-view.c31
-rw-r--r--shell/e-storage-set-view.h13
-rw-r--r--shell/e-storage-set.c95
-rw-r--r--shell/e-storage-set.h45
-rw-r--r--shell/e-storage.c88
-rw-r--r--shell/e-storage.h49
-rw-r--r--shell/evolution-shell-component-client.c43
-rw-r--r--shell/evolution-shell-component.h29
18 files changed, 864 insertions, 196 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 555a156f2a..e5a7cac760 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,10 @@
+2000-06-10 Ettore Perazzoli <ettore@helixcode.com>
+
+ * component-factory.c (create_folder): New stub implementation for
+ the folder creation function in the EvolutionShellComponent we
+ expose [it simply returns success all the time].
+ (factory_fn): Pass this function to `evolution_shell_component_new'.
+
2000-06-09 Dan Winship <danw@helixcode.com>
* folder-browser.c (folder_browser_new): Add a serial number to
diff --git a/mail/component-factory.c b/mail/component-factory.c
index 0452efb846..ee69f0da84 100644
--- a/mail/component-factory.c
+++ b/mail/component-factory.c
@@ -94,6 +94,26 @@ create_view (EvolutionShellComponent *shell_component,
}
static void
+create_folder (EvolutionShellComponent *shell_component,
+ const char *physical_uri,
+ const char *type,
+ const Evolution_ShellComponentListener listener,
+ void *closure)
+{
+ CORBA_Environment ev;
+
+ /* FIXME: Implement. */
+
+ CORBA_exception_init (&ev);
+
+ Evolution_ShellComponentListener_report_result (listener,
+ Evolution_ShellComponentListener_OK,
+ &ev);
+
+ CORBA_exception_free (&ev);
+}
+
+static void
owner_set_cb (EvolutionShellComponent *shell_component,
Evolution_Shell shell_interface,
gpointer user_data)
@@ -130,7 +150,11 @@ factory_fn (BonoboGenericFactory *factory,
{
EvolutionShellComponent *shell_component;
- shell_component = evolution_shell_component_new (folder_types, create_view, NULL, NULL, NULL);
+ shell_component = evolution_shell_component_new (folder_types,
+ create_view,
+ create_folder,
+ NULL,
+ NULL);
gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set",
GTK_SIGNAL_FUNC (owner_set_cb), NULL);
diff --git a/shell/ChangeLog b/shell/ChangeLog
index 84edb7c42a..0b3897756a 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,79 @@
+2000-06-10 Ettore Perazzoli <ettore@helixcode.com>
+
+ * e-local-folder.c (save_metadata): Don't set the description in
+ the XML file if null. Compute the physical path correctly.
+
+ * e-folder.c (e_folder_construct): Allow NULL description.
+
+ * evolution-shell-component-client.c (init): Initalize
+ `listener_interface' to `CORBA_OBJECT_NIL' and `listener_servant'
+ to NULL.
+ (create_listener_interface): Return void and set the `servant' and
+ `listener_servant' fields directly.
+ (evolution_shell_component_client_async_create_folder): Updated
+ accordingly.
+
+ * e-shell-folder-creation-dialog.c: New struct `DialogData' to be
+ passed to the dialog's callbacks.
+ (dialog_data_destroy): New.
+ (e_shell_show_folder_creation_dialog): Set up a `DialogData'
+ object and pass it as the data for the signals.
+ (shell_destroy_cb): New handler for the "destroy" signal on the
+ shell.
+ (e_shell_show_folder_creation_dialog): Connect it.
+ (dialog_destroy_cb): New handler for the "destroy" signal on the
+ dialog; it frees the associated `DialogData'.
+ (e_shell_show_folder_creation_dialog): Connect it.
+ (async_create_cb): New function, callback for the async folder
+ creation function.
+ (entry_name_is_valid): New function to check if the entered folder
+ name is valid.
+ (dialog_clicked_cb): Check if the specified folder name is valid
+ and, if so, asynchronously create the new folder.
+ (add_folder_types): Set "type_name" data on each menu item.
+
+ * e-storage-set-view.c (e_storage_set_view_get_current_folder):
+ New function.
+
+ * e-storage-set.c (get_storage_for_path): New helper function.
+ (e_storage_set_get_folder): Use it.
+
+ * e-storage.c (e_storage_async_create_folder): Renamed from
+ `e_storage_create_folder'.
+ (e_storage_remove_folder): Renamed from `e_storage_remove_folder'.
+ (impl_create_create_folder): Renamed from `impl_create_folder'.
+ (impl_create_remove_folder): Renamed from `impl_remove_folder'.
+ (class_init): Updated accordingly.
+ (e_storage_result_to_string): New function.
+
+ * e-storage.h: `::create_folder' renamed to
+ `::async_create_folder'. `::remove_folder' renamed to
+ `::async_remove_folder'.
+
+ * evolution-shell-component.h: Return type of
+ `EvolutionShellComponentCreateFolderFn' and
+ `EvolutionShellComponentRemoveFolderFn' changed to `void'.
+
+ * e-local-storage.c: `EComponentRegistry component_registry'
+ replaced with `EFolderTypeRegistry folder_type_registry' in
+ `ELocalStoragePrivate'
+ (component_async_create_folder_callback): New function, to handle
+ the callback from EvolutionShellComponent.
+ (construct): Likewise.
+ (e_local_storage_open): Replaced @component_registry with
+ @folder_type_registry.
+ (impl_create_folder): Implemented.
+
+ * e-local-folder.c (e_local_folder_new): New.
+ (e_local_folder_construct): New.
+ (e_local_folder_save): Precondition: physical URI is not NULL.
+ (save_metadata): Unlink the metadata file if `xmlSaveFile()'
+ fails.
+
+ * e-storage.c (e_storage_create_folder): Precondition: @path is
+ absolute.
+ (e_storage_remove_folder): Likewise.
+
2000-06-09 Ettore Perazzoli <ettore@helixcode.com>
* e-shell-view-menu.c: Removed folder menu and "save as..." command.
diff --git a/shell/e-folder.c b/shell/e-folder.c
index 2e16c0896e..90bd886352 100644
--- a/shell/e-folder.c
+++ b/shell/e-folder.c
@@ -162,7 +162,6 @@ e_folder_construct (EFolder *folder,
g_return_if_fail (E_IS_FOLDER (folder));
g_return_if_fail (name != NULL);
g_return_if_fail (type != NULL);
- g_return_if_fail (description != NULL);
GTK_OBJECT_UNSET_FLAGS (GTK_OBJECT (folder), GTK_FLOATING);
diff --git a/shell/e-local-folder.c b/shell/e-local-folder.c
index 23cd106390..80cee7d7bc 100644
--- a/shell/e-local-folder.c
+++ b/shell/e-local-folder.c
@@ -138,7 +138,8 @@ save_metadata (ELocalFolder *local_folder)
EFolder *folder;
xmlDoc *doc;
xmlNode *root;
- const char *physical_path;
+ const char *physical_directory;
+ char *physical_path;
folder = E_FOLDER (local_folder);
@@ -146,16 +147,25 @@ save_metadata (ELocalFolder *local_folder)
root = xmlNewDocNode (doc, NULL, (xmlChar *) "efolder", NULL);
xmlDocSetRootElement (doc, root);
- xmlNewChild (root, NULL, (xmlChar *) "type", (xmlChar *) e_folder_get_type_string (folder));
- xmlNewChild (root, NULL, (xmlChar *) "description", (xmlChar *) e_folder_get_description (folder));
+ xmlNewChild (root, NULL, (xmlChar *) "type",
+ (xmlChar *) e_folder_get_type_string (folder));
- physical_path = e_folder_get_physical_uri (folder) + URI_PREFIX_LEN - 1;
+ if (e_folder_get_description (folder) != NULL)
+ xmlNewChild (root, NULL, (xmlChar *) "description",
+ (xmlChar *) e_folder_get_description (folder));
+
+ physical_directory = e_folder_get_physical_uri (folder) + URI_PREFIX_LEN - 1;
+ physical_path = g_concat_dir_and_file (physical_directory, METADATA_FILE_NAME);
if (xmlSaveFile (physical_path, doc) < 0) {
+ unlink (physical_path);
+ g_free (physical_path);
xmlFreeDoc (doc);
return FALSE;
}
+ g_free (physical_path);
+
xmlFreeDoc (doc);
return TRUE;
}
@@ -189,6 +199,37 @@ init (ELocalFolder *local_folder)
}
+void
+e_local_folder_construct (ELocalFolder *local_folder,
+ const char *name,
+ const char *type,
+ const char *description)
+{
+ g_return_if_fail (local_folder != NULL);
+ g_return_if_fail (E_IS_LOCAL_FOLDER (local_folder));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (type != NULL);
+
+ e_folder_construct (E_FOLDER (local_folder), name, type, description);
+}
+
+EFolder *
+e_local_folder_new (const char *name,
+ const char *type,
+ const char *description)
+{
+ ELocalFolder *local_folder;
+
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (type != NULL, NULL);
+
+ local_folder = gtk_type_new (e_local_folder_get_type ());
+
+ e_local_folder_construct (local_folder, name, type, description);
+
+ return E_FOLDER (local_folder);
+}
+
EFolder *
e_local_folder_new_from_path (const char *path)
{
@@ -211,6 +252,7 @@ e_local_folder_save (ELocalFolder *local_folder)
{
g_return_val_if_fail (local_folder != NULL, FALSE);
g_return_val_if_fail (E_IS_LOCAL_FOLDER (local_folder), FALSE);
+ g_return_val_if_fail (e_folder_get_physical_uri (E_FOLDER (local_folder)) != NULL, FALSE);
return save_metadata (local_folder);
}
diff --git a/shell/e-local-folder.h b/shell/e-local-folder.h
index b30a9f2a5c..aa9e79a990 100644
--- a/shell/e-local-folder.h
+++ b/shell/e-local-folder.h
@@ -55,9 +55,16 @@ struct _ELocalFolderClass {
};
-GtkType e_local_folder_get_type (void);
-EFolder *e_local_folder_new_from_path (const char *physical_path);
-gboolean e_local_folder_save (ELocalFolder *local_folder);
+GtkType e_local_folder_get_type (void);
+void e_local_folder_construct (ELocalFolder *local_folder,
+ const char *name,
+ const char *type,
+ const char *description);
+EFolder *e_local_folder_new (const char *name,
+ const char *type,
+ const char *description);
+EFolder *e_local_folder_new_from_path (const char *physical_path);
+gboolean e_local_folder_save (ELocalFolder *local_folder);
#ifdef __cplusplus
}
diff --git a/shell/e-local-storage.c b/shell/e-local-storage.c
index b97b25b8ec..05a142152e 100644
--- a/shell/e-local-storage.c
+++ b/shell/e-local-storage.c
@@ -25,6 +25,9 @@
*
* - If we have `.' or `..' as path elements, we lose.
*
+ * - If the LocalStorage is destroyed and an async operation on a shell component is
+ * pending, we get a callback on a bogus object. We need support for cancelling
+ * operations on the shell component.
*/
#ifdef HAVE_CONFIG_H
@@ -34,6 +37,7 @@
#define _POSIX_SOURCE /* Yuck. */
#include <dirent.h>
+#include <errno.h>
#include <string.h>
#include <sys/param.h>
#include <sys/types.h>
@@ -54,18 +58,17 @@ static EStorageClass *parent_class = NULL;
#define SUBFOLDER_DIR_NAME_LEN 10
struct _ELocalStoragePrivate {
- EComponentRegistry *component_registry;
+ EFolderTypeRegistry *folder_type_registry;
char *base_path;
};
/* Utility functions. */
-#if 0
-/* Translate a storage path into a real path on the file system. */
+/* Translate a storage path into a physical path on the file system. */
static char *
-get_real_path (ELocalStorage *local_storage,
- const char *path)
+get_physical_path (ELocalStorage *local_storage,
+ const char *path)
{
EStorage *storage;
ELocalStoragePrivate *priv;
@@ -80,7 +83,7 @@ get_real_path (ELocalStorage *local_storage,
/* @path is always absolute, so it starts with a slash. The base class should
make sure this is the case; if not, it's broken. */
- g_assert (*path != G_DIR_SEPARATOR);
+ g_assert (*path == G_DIR_SEPARATOR);
path++;
/* Calculate the length of the real path. */
@@ -93,7 +96,7 @@ get_real_path (ELocalStorage *local_storage,
real_path_len++; /* For the separating slash. */
/* Take account for the fact that we need to translate every separator into
- `children/'. */
+ `subfolders/'. */
p = path;
while (1) {
newp = strchr (p, G_DIR_SEPARATOR);
@@ -121,8 +124,10 @@ get_real_path (ELocalStorage *local_storage,
p = path;
while (1) {
newp = strchr (p, G_DIR_SEPARATOR);
- if (newp == NULL)
+ if (newp == NULL) {
+ strcpy (dp, p);
break;
+ }
memcpy (dp, p, newp - p + 1); /* `+ 1' to copy the slash too. */
dp += newp - p + 1;
@@ -141,7 +146,6 @@ get_real_path (ELocalStorage *local_storage,
return real_path;
}
-#endif
static gboolean
load_folders (ELocalStorage *local_storage,
@@ -230,6 +234,127 @@ load_all_folders (ELocalStorage *local_storage)
return load_folders (local_storage, NULL, G_DIR_SEPARATOR_S, base_path);
}
+static EStorageResult
+errno_to_storage_result (void)
+{
+ EStorageResult storage_result;
+
+ switch (errno) {
+ case EACCES:
+ case EROFS:
+ storage_result = E_STORAGE_PERMISSIONDENIED;
+ break;
+ case EEXIST:
+ storage_result = E_STORAGE_EXISTS;
+ break;
+ case ENOSPC:
+ storage_result = E_STORAGE_NOSPACE;
+ break;
+ default:
+ storage_result = E_STORAGE_GENERICERROR;
+ }
+
+ return storage_result;
+}
+
+static EStorageResult
+shell_component_result_to_storage_result (EvolutionShellComponentResult result)
+{
+ /* FIXME: Maybe we need better mapping here. */
+ switch (result) {
+ case EVOLUTION_SHELL_COMPONENT_OK:
+ return E_STORAGE_OK;
+ case EVOLUTION_SHELL_COMPONENT_NOTFOUND:
+ return E_STORAGE_NOTFOUND;
+ case EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE:
+ return E_STORAGE_UNSUPPORTEDTYPE;
+ case EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDOPERATION:
+ return E_STORAGE_UNSUPPORTEDOPERATION;
+ case EVOLUTION_SHELL_COMPONENT_EXISTS:
+ return E_STORAGE_EXISTS;
+ case EVOLUTION_SHELL_COMPONENT_PERMISSIONDENIED:
+ return E_STORAGE_PERMISSIONDENIED;
+ case EVOLUTION_SHELL_COMPONENT_ALREADYOWNED:
+ case EVOLUTION_SHELL_COMPONENT_BUSY:
+ case EVOLUTION_SHELL_COMPONENT_CORBAERROR:
+ case EVOLUTION_SHELL_COMPONENT_HASSUBFOLDERS:
+ case EVOLUTION_SHELL_COMPONENT_INTERNALERROR:
+ case EVOLUTION_SHELL_COMPONENT_INTERRUPTED:
+ case EVOLUTION_SHELL_COMPONENT_INVALIDARG:
+ case EVOLUTION_SHELL_COMPONENT_INVALIDURI:
+ case EVOLUTION_SHELL_COMPONENT_NOSPACE:
+ case EVOLUTION_SHELL_COMPONENT_NOTOWNED:
+ case EVOLUTION_SHELL_COMPONENT_UNKNOWNERROR:
+ default:
+ return E_STORAGE_GENERICERROR;
+ }
+}
+
+
+/* Callbacks for the async methods invoked on the `Evolution::ShellComponent's. */
+
+struct _AsyncCreateFolderCallbackData {
+ EStorage *storage;
+
+ char *parent_path;
+ char *name;
+ char *type;
+ char *description;
+ char *physical_uri;
+ char *physical_path;
+
+ EStorageResultCallback callback;
+ void *callback_data;
+};
+typedef struct _AsyncCreateFolderCallbackData AsyncCreateFolderCallbackData;
+
+static void
+component_async_create_folder_callback (EvolutionShellComponentClient *shell_component_client,
+ EvolutionShellComponentResult result,
+ void *data)
+{
+ AsyncCreateFolderCallbackData *callback_data;
+
+ callback_data = (AsyncCreateFolderCallbackData *) data;
+
+ if (result != EVOLUTION_SHELL_COMPONENT_OK) {
+ /* XXX: This assumes the component won't leave any files in the directory. */
+ rmdir (callback_data->physical_path);
+ } else {
+ EFolder *folder;
+
+ folder = e_local_folder_new (callback_data->name,
+ callback_data->type,
+ callback_data->description);
+
+ e_folder_set_physical_uri (folder, callback_data->physical_uri);
+
+ if (e_local_folder_save (E_LOCAL_FOLDER (folder))) {
+ e_storage_new_folder (callback_data->storage,
+ callback_data->parent_path,
+ folder);
+ } else {
+ rmdir (callback_data->physical_path);
+ gtk_object_unref (GTK_OBJECT (folder));
+ result = E_STORAGE_IOERROR;
+ }
+ }
+
+ bonobo_object_unref (BONOBO_OBJECT (shell_component_client));
+
+ (* callback_data->callback) (callback_data->storage,
+ shell_component_result_to_storage_result (result),
+ callback_data->callback_data);
+
+ g_free (callback_data->parent_path);
+ g_free (callback_data->name);
+ g_free (callback_data->type);
+ g_free (callback_data->description);
+ g_free (callback_data->physical_uri);
+ g_free (callback_data->physical_path);
+ g_free (callback_data);
+}
+
/* GtkObject methods. */
@@ -244,8 +369,8 @@ impl_destroy (GtkObject *object)
g_free (priv->base_path);
- if (priv->component_registry != NULL)
- gtk_object_unref (GTK_OBJECT (priv->component_registry));
+ if (priv->folder_type_registry != NULL)
+ gtk_object_unref (GTK_OBJECT (priv->folder_type_registry));
g_free (priv);
@@ -263,23 +388,107 @@ impl_get_name (EStorage *storage)
}
static void
-impl_create_folder (EStorage *storage,
- const char *path,
- const char *type,
- const char *description,
- EStorageResultCallback callback,
- void *data)
+impl_async_create_folder (EStorage *storage,
+ const char *path,
+ const char *type,
+ const char *description,
+ EStorageResultCallback callback,
+ void *data)
{
ELocalStorage *local_storage;
+ ELocalStoragePrivate *priv;
+ EvolutionShellComponentClient *component_client;
+ const char *folder_name;
+ AsyncCreateFolderCallbackData *callback_data;
+ char *physical_path;
+ char *physical_uri;
+ char *parent_path;
local_storage = E_LOCAL_STORAGE (storage);
+ priv = local_storage->priv;
+
+ component_client = e_folder_type_registry_get_handler_for_type (priv->folder_type_registry,
+ type);
+ if (component_client == NULL) {
+ (* callback) (storage, E_STORAGE_INVALIDTYPE, data);
+ return;
+ }
+
+ g_assert (g_path_is_absolute (path));
+
+ folder_name = g_basename (path);
+ if (folder_name == path + 1) {
+ /* We want a direct child of the root, so we don't need to create a
+ `subfolders' directory. */
+ physical_path = get_physical_path (local_storage, path);
+ parent_path = g_strdup (G_DIR_SEPARATOR_S);
+ } else {
+ char *parent_physical_path;
+ char *subfolders_directory_physical_path;
+
+ /* Create the `subfolders' subdirectory under the parent. */
+
+ parent_path = g_strndup (path, folder_name - path - 1);
+ parent_physical_path = get_physical_path (local_storage, parent_path);
+ subfolders_directory_physical_path = g_concat_dir_and_file (parent_physical_path,
+ SUBFOLDER_DIR_NAME);
+
+ if (! g_file_exists (subfolders_directory_physical_path)
+ && mkdir (subfolders_directory_physical_path, 0700) == -1) {
+ g_free (parent_path);
+ g_free (subfolders_directory_physical_path);
+ g_free (parent_physical_path);
+
+ (* callback) (storage, errno_to_storage_result (), data);
+ return;
+ }
+
+ physical_path = g_concat_dir_and_file (subfolders_directory_physical_path,
+ folder_name);
+ g_free (subfolders_directory_physical_path);
+ g_free (parent_physical_path);
+ }
+
+ /* Create the directory that holds the folder. */
+
+ if (mkdir (physical_path, 0700) == -1) {
+ g_free (physical_path);
+ (* callback) (storage, errno_to_storage_result (), data);
+ return;
+ }
+
+ /* Finally tell the component to do the job of creating the physical files in
+ it. */
+ /* FIXME: We should put the operations on a queue so that we can cancel them when
+ the ELocalStorage is destroyed. */
+
+ physical_uri = g_strconcat ("file://", physical_path, NULL);
+
+ callback_data = g_new (AsyncCreateFolderCallbackData, 1);
+ callback_data->storage = storage;
+ callback_data->parent_path = parent_path;
+ callback_data->name = g_strdup (folder_name);
+ callback_data->type = g_strdup (type);
+ callback_data->description = g_strdup (description);
+ callback_data->physical_uri = physical_uri;
+ callback_data->physical_path = physical_path;
+ callback_data->callback = callback;
+ callback_data->callback_data = data;
+
+ bonobo_object_ref (BONOBO_OBJECT (component_client));
+
+ evolution_shell_component_client_async_create_folder (component_client,
+ physical_path,
+ type,
+ component_async_create_folder_callback,
+ callback_data);
}
static void
-impl_remove_folder (EStorage *storage,
- const char *path,
- EStorageResultCallback callback,
- void *data)
+impl_async_remove_folder (EStorage *storage,
+ const char *path,
+ EStorageResultCallback callback,
+ void *data)
{
ELocalStorage *local_storage;
@@ -299,11 +508,11 @@ class_init (ELocalStorageClass *class)
object_class = GTK_OBJECT_CLASS (class);
storage_class = E_STORAGE_CLASS (class);
- object_class->destroy = impl_destroy;
+ object_class->destroy = impl_destroy;
- storage_class->get_name = impl_get_name;
- storage_class->create_folder = impl_create_folder;
- storage_class->remove_folder = impl_remove_folder;
+ storage_class->get_name = impl_get_name;
+ storage_class->async_create_folder = impl_async_create_folder;
+ storage_class->async_remove_folder = impl_async_remove_folder;
}
static void
@@ -314,7 +523,7 @@ init (ELocalStorage *local_storage)
priv = g_new (ELocalStoragePrivate, 1);
priv->base_path = NULL;
- priv->component_registry = NULL;
+ priv->folder_type_registry = NULL;
local_storage->priv = priv;
}
@@ -322,7 +531,7 @@ init (ELocalStorage *local_storage)
static gboolean
construct (ELocalStorage *local_storage,
- EComponentRegistry *component_registry,
+ EFolderTypeRegistry *folder_type_registry,
const char *base_path)
{
ELocalStoragePrivate *priv;
@@ -338,9 +547,9 @@ construct (ELocalStorage *local_storage,
g_return_val_if_fail (base_path_len != 0, FALSE);
- g_assert (priv->component_registry == NULL);
- gtk_object_ref (GTK_OBJECT (component_registry));
- priv->component_registry = component_registry;
+ g_assert (priv->folder_type_registry == NULL);
+ gtk_object_ref (GTK_OBJECT (folder_type_registry));
+ priv->folder_type_registry = folder_type_registry;
g_assert (priv->base_path == NULL);
priv->base_path = g_strndup (base_path, base_path_len);
@@ -349,18 +558,18 @@ construct (ELocalStorage *local_storage,
}
EStorage *
-e_local_storage_open (EComponentRegistry *component_registry,
+e_local_storage_open (EFolderTypeRegistry *folder_type_registry,
const char *base_path)
{
EStorage *new;
- g_return_val_if_fail (component_registry != NULL, NULL);
- g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), NULL);
+ g_return_val_if_fail (folder_type_registry != NULL, NULL);
+ g_return_val_if_fail (E_IS_FOLDER_TYPE_REGISTRY (folder_type_registry), NULL);
g_return_val_if_fail (base_path != NULL, NULL);
new = gtk_type_new (e_local_storage_get_type ());
- if (! construct (E_LOCAL_STORAGE (new), component_registry, base_path)) {
+ if (! construct (E_LOCAL_STORAGE (new), folder_type_registry, base_path)) {
gtk_object_unref (GTK_OBJECT (new));
return NULL;
}
diff --git a/shell/e-local-storage.h b/shell/e-local-storage.h
index feecda75a7..14a48cbdd4 100644
--- a/shell/e-local-storage.h
+++ b/shell/e-local-storage.h
@@ -28,7 +28,7 @@
#include <config.h>
#endif
-#include "e-component-registry.h"
+#include "e-folder-type-registry.h"
#include "e-storage.h"
#ifdef __cplusplus
@@ -58,9 +58,9 @@ struct _ELocalStorageClass {
GtkType e_local_storage_get_type (void);
-EStorage *e_local_storage_open (EComponentRegistry *component_registry,
- const char *base_path);
-const char *e_local_storage_get_base_path (ELocalStorage *storage);
+EStorage *e_local_storage_open (EFolderTypeRegistry *folder_type_registry,
+ const char *base_path);
+const char *e_local_storage_get_base_path (ELocalStorage *storage);
#ifdef __cplusplus
}
diff --git a/shell/e-shell-folder-creation-dialog.c b/shell/e-shell-folder-creation-dialog.c
index 6879922be1..342f65ff39 100644
--- a/shell/e-shell-folder-creation-dialog.c
+++ b/shell/e-shell-folder-creation-dialog.c
@@ -28,7 +28,9 @@
#include <gnome.h>
#include <glade/glade-xml.h>
+#include "e-util/e-gui-utils.h"
#include "e-util/e-util.h"
+
#include "widgets/misc/e-scroll-frame.h"
#include "e-storage-set.h"
@@ -37,29 +39,146 @@
#include "e-shell-folder-creation-dialog.h"
-#define GLADE_FILE_NAME E_GLADEDIR "/e-shell-folder-creation-dialog.glade"
+#define GLADE_FILE_NAME E_GLADEDIR "/e-shell-folder-creation-dialog.glade"
+
+
+/* Data for the callbacks. */
+struct _DialogData {
+ GtkWidget *dialog;
+ EShell *shell;
+ GtkWidget *folder_name_entry;
+ GtkWidget *storage_set_view;
+ GtkWidget *folder_type_option_menu;
+ GList *folder_types;
+};
+typedef struct _DialogData DialogData;
+
+static void
+dialog_data_destroy (DialogData *dialog_data)
+{
+ e_free_string_list (dialog_data->folder_types);
+ g_free (dialog_data);
+}
+
+
+/* Callback for the asynchronous folder creation function. */
+
+static void
+async_create_cb (EStorage *storage,
+ EStorageResult result,
+ void *data)
+{
+ DialogData *dialog_data;
+
+ dialog_data = (DialogData *) data;
+
+ if (result == E_STORAGE_OK) {
+ gtk_widget_destroy (dialog_data->dialog);
+ return;
+ }
+
+ e_notice (GTK_WINDOW (dialog_data->dialog), GNOME_MESSAGE_BOX_ERROR,
+ _("Cannot create the specified folder:\n%s"),
+ e_storage_result_to_string (result));
+}
+
+
+/* Sanity check for the user-specified folder name. */
+/* FIXME in the future we would like not to have the `G_DIR_SEPARATOR' limitation. */
+static gboolean
+entry_name_is_valid (GtkEntry *entry)
+{
+ const char *name;
+
+ name = gtk_entry_get_text (entry);
+
+ if (name == NULL || *name == '\0')
+ return FALSE;
+
+ if (strchr (name, G_DIR_SEPARATOR) != NULL)
+ return FALSE;
+
+ if (strcmp (name, ".") == 0 || strcmp (name, "..") == 0)
+ return FALSE;
+
+ return TRUE;
+}
-/* Dialog callbacks. */
+/* Dialog signal callbacks. */
static void
dialog_clicked_cb (GnomeDialog *dialog,
int button_number,
void *data)
{
- g_print ("Clicked -- %d\n", button_number);
- gnome_dialog_close (dialog);
+ DialogData *dialog_data;
+ EStorageSet *storage_set;
+ GtkWidget *folder_type_menu_item;
+ const char *folder_type;
+ const char *parent_path;
+ const char *folder_name;
+ char *path;
+
+ if (button_number != 0) {
+ gnome_dialog_close (dialog);
+ return;
+ }
+
+ dialog_data = (DialogData *) data;
+
+ if (! entry_name_is_valid (GTK_ENTRY (dialog_data->folder_name_entry))) {
+ /* FIXME: Explain better. */
+ e_notice (GTK_WINDOW (dialog), GNOME_MESSAGE_BOX_ERROR,
+ _("The specified folder name is not valid."));
+ return;
+ }
+
+ parent_path = e_storage_set_view_get_current_folder
+ (E_STORAGE_SET_VIEW (dialog_data->storage_set_view));
+ if (parent_path == NULL) {
+ gnome_dialog_close (dialog);
+ return;
+ }
+
+ folder_name = gtk_entry_get_text (GTK_ENTRY (dialog_data->folder_name_entry));
+ path = g_concat_dir_and_file (parent_path, folder_name);
+
+ storage_set = e_shell_get_storage_set (dialog_data->shell);
+
+ folder_type_menu_item = GTK_OPTION_MENU (dialog_data->folder_type_option_menu)->menu_item;
+ folder_type = gtk_object_get_data (GTK_OBJECT (folder_type_menu_item), "folder_type");
+
+ if (folder_type == NULL) {
+ g_warning ("Cannot get folder type for selected GtkOptionMenu item.");
+ return;
+ }
+
+ e_storage_set_async_create_folder (storage_set,
+ path,
+ folder_type,
+ NULL, /* description */
+ async_create_cb, dialog_data);
}
static void
dialog_close_cb (GnomeDialog *dialog,
void *data)
{
- g_print ("Closed\n");
gtk_widget_destroy (GTK_WIDGET (dialog));
}
static void
+dialog_destroy_cb (GtkObject *object,
+ void *data)
+{
+ DialogData *dialog_data;
+
+ dialog_data = (DialogData *) data;
+ dialog_data_destroy (dialog_data);
+}
+
+static void
folder_name_entry_changed_cb (GtkEditable *editable,
void *data)
{
@@ -76,16 +195,29 @@ folder_name_entry_changed_cb (GtkEditable *editable,
}
+/* Shell signal callbacks. */
+
+static void
+shell_destroy_cb (GtkObject *object,
+ void *data)
+{
+ GnomeDialog *dialog;
+
+ dialog = GNOME_DIALOG (data);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+
/* Dialog setup. */
static void
setup_dialog (GtkWidget *dialog,
GladeXML *gui,
EShell *shell,
- GtkWindow *parent)
+ GtkWindow *parent_window)
{
- if (parent != NULL)
- gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
+ if (parent_window != NULL)
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_window_set_title (GTK_WINDOW (dialog), _("Evolution - Create new folder"));
@@ -93,11 +225,6 @@ setup_dialog (GtkWidget *dialog,
gnome_dialog_set_default (GNOME_DIALOG (dialog), 0);
gnome_dialog_set_sensitive (GNOME_DIALOG (dialog), 0, FALSE);
- gtk_signal_connect (GTK_OBJECT (dialog), "clicked",
- GTK_SIGNAL_FUNC (dialog_clicked_cb), shell);
- gtk_signal_connect (GTK_OBJECT (dialog), "close",
- GTK_SIGNAL_FUNC (dialog_close_cb), shell);
-
gtk_widget_show (dialog);
}
@@ -116,7 +243,7 @@ setup_folder_name_entry (GtkWidget *dialog,
GTK_SIGNAL_FUNC (folder_name_entry_changed_cb), dialog);
}
-static void
+static GtkWidget *
add_storage_set_view (GtkWidget *dialog,
GladeXML *gui,
EShell *shell,
@@ -146,9 +273,11 @@ add_storage_set_view (GtkWidget *dialog,
gtk_widget_show (scroll_frame);
gtk_widget_show (storage_set_view);
+
+ return storage_set_view;
}
-static void
+static GList *
add_folder_types (GtkWidget *dialog,
GladeXML *gui,
EShell *shell)
@@ -156,7 +285,7 @@ add_folder_types (GtkWidget *dialog,
EFolderTypeRegistry *folder_type_registry;
GtkWidget *folder_type_option_menu;
GtkWidget *menu;
- GList *types;
+ GList *folder_types;
GList *p;
int default_item;
int i;
@@ -170,17 +299,17 @@ add_folder_types (GtkWidget *dialog,
folder_type_registry = e_shell_get_folder_type_registry (shell);
g_assert (folder_type_registry != NULL);
- types = e_folder_type_registry_get_type_names (folder_type_registry);
- if (types == NULL)
- return; /* Uh? */
+ folder_types = e_folder_type_registry_get_type_names (folder_type_registry);
+ if (folder_types == NULL)
+ return NULL; /* Uh? */
- types = g_list_sort (types, (GCompareFunc) g_strcasecmp);
+ folder_types = g_list_sort (folder_types, (GCompareFunc) g_strcasecmp);
/* FIXME: Use descriptive name (not in the registry's implementation yet). */
/* FIXME: Add icon (I don't feel like writing an alpha-capable thingie again). */
default_item = 0;
- for (p = types, i = 0; p != NULL; p = p->next, i++) {
+ for (p = folder_types, i = 0; p != NULL; p = p->next, i++) {
const char *type_name;
GtkWidget *menu_item;
@@ -190,13 +319,15 @@ add_folder_types (GtkWidget *dialog,
gtk_menu_append (GTK_MENU (menu), menu_item);
gtk_widget_show (menu_item);
+ gtk_object_set_data (GTK_OBJECT (menu_item), "folder_type", (void *) type_name);
+
if (strcmp (type_name, "mail") == 0)
default_item = i;
}
- e_free_string_list (types);
-
gtk_option_menu_set_history (GTK_OPTION_MENU (folder_type_option_menu), default_item);
+
+ return folder_types;
}
@@ -205,11 +336,14 @@ add_folder_types (GtkWidget *dialog,
open at once. Currently it relies on modality for this. */
void
e_shell_show_folder_creation_dialog (EShell *shell,
- GtkWindow *parent,
+ GtkWindow *parent_window,
const char *default_parent_folder)
{
GladeXML *gui;
GtkWidget *dialog;
+ GtkWidget *storage_set_view;
+ GList *folder_types;
+ DialogData *dialog_data;
g_return_if_fail (shell != NULL);
g_return_if_fail (E_IS_SHELL (shell));
@@ -223,11 +357,30 @@ e_shell_show_folder_creation_dialog (EShell *shell,
dialog = glade_xml_get_widget (gui, "create_folder_dialog");
- setup_dialog (dialog, gui, shell, parent);
+ setup_dialog (dialog, gui, shell, parent_window);
setup_folder_name_entry (dialog, gui, shell);
- add_storage_set_view (dialog, gui, shell, default_parent_folder);
- add_folder_types (dialog, gui, shell);
+ storage_set_view = add_storage_set_view (dialog, gui, shell, default_parent_folder);
+ folder_types = add_folder_types (dialog, gui, shell);
+
+ dialog_data = g_new (DialogData, 1);
+ dialog_data->dialog = dialog;
+ dialog_data->shell = shell;
+ dialog_data->folder_name_entry = glade_xml_get_widget (gui, "folder_name_entry");
+ dialog_data->storage_set_view = storage_set_view;
+ dialog_data->folder_type_option_menu = glade_xml_get_widget (gui, "folder_type_option_menu");
+ dialog_data->folder_types = folder_types;
+
+ gtk_signal_connect (GTK_OBJECT (dialog), "clicked",
+ GTK_SIGNAL_FUNC (dialog_clicked_cb), dialog_data);
+ gtk_signal_connect (GTK_OBJECT (dialog), "close",
+ GTK_SIGNAL_FUNC (dialog_close_cb), dialog_data);
+ gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+ GTK_SIGNAL_FUNC (dialog_destroy_cb), dialog_data);
+
+ gtk_signal_connect_while_alive (GTK_OBJECT (shell), "destroy",
+ GTK_SIGNAL_FUNC (shell_destroy_cb), dialog_data,
+ GTK_OBJECT (dialog));
gtk_object_unref (GTK_OBJECT (gui));
}
diff --git a/shell/e-shell.c b/shell/e-shell.c
index 03ae95c863..fcaa592a32 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -171,7 +171,7 @@ setup_local_storage (EShell *shell)
local_storage_path = g_concat_dir_and_file (priv->local_directory,
LOCAL_STORAGE_DIRECTORY);
- local_storage = e_local_storage_open (shell->priv->component_registry,
+ local_storage = e_local_storage_open (priv->folder_type_registry,
local_storage_path);
if (local_storage == NULL) {
g_warning (_("Cannot set up local storage -- %s"), local_storage_path);
diff --git a/shell/e-storage-set-view.c b/shell/e-storage-set-view.c
index 989f6c5f62..88e70e4f78 100644
--- a/shell/e-storage-set-view.c
+++ b/shell/e-storage-set-view.c
@@ -856,5 +856,36 @@ e_storage_set_view_set_current_folder (EStorageSetView *storage_set_view,
gtk_signal_emit (GTK_OBJECT (storage_set_view), signals[FOLDER_SELECTED], path);
}
+const char *
+e_storage_set_view_get_current_folder (EStorageSetView *storage_set_view)
+{
+ EStorageSetViewPrivate *priv;
+ GtkCList *clist;
+ GtkCTree *ctree;
+ GtkCTreeRow *ctree_row;
+ GtkCTreeNode *ctree_node;
+ const char *path;
+
+ g_return_val_if_fail (storage_set_view != NULL, NULL);
+ g_return_val_if_fail (E_IS_STORAGE_SET_VIEW (storage_set_view), NULL);
+
+ priv = storage_set_view->priv;
+
+ clist = GTK_CLIST (storage_set_view);
+ ctree = GTK_CTREE (storage_set_view);
+
+ if (clist->selection == NULL)
+ return NULL;
+
+ ctree_row = GTK_CTREE_ROW (clist->selection->data);
+ ctree_node = gtk_ctree_find_node_ptr (ctree, ctree_row);
+ if (ctree_node == NULL)
+ return NULL; /* Mmh? */
+
+ path = g_hash_table_lookup (priv->ctree_node_to_path, ctree_node);
+
+ return path;
+}
+
E_MAKE_TYPE (e_storage_set_view, "EStorageSetView", EStorageSetView, class_init, init, PARENT_TYPE)
diff --git a/shell/e-storage-set-view.h b/shell/e-storage-set-view.h
index d865eb426c..098de0d2a7 100644
--- a/shell/e-storage-set-view.h
+++ b/shell/e-storage-set-view.h
@@ -63,12 +63,13 @@ struct _EStorageSetViewClass {
};
-GtkType e_storage_set_view_get_type (void);
-GtkWidget *e_storage_set_view_new (EStorageSet *storage_set);
-void e_storage_set_view_construct (EStorageSetView *storage_set_view,
- EStorageSet *storage_set);
-void e_storage_set_view_set_current_folder (EStorageSetView *storage_set_view,
- const char *path);
+GtkType e_storage_set_view_get_type (void);
+GtkWidget *e_storage_set_view_new (EStorageSet *storage_set);
+void e_storage_set_view_construct (EStorageSetView *storage_set_view,
+ EStorageSet *storage_set);
+void e_storage_set_view_set_current_folder (EStorageSetView *storage_set_view,
+ const char *path);
+const char *e_storage_set_view_get_current_folder (EStorageSetView *storage_set_view);
#ifdef __cplusplus
}
diff --git a/shell/e-storage-set.c b/shell/e-storage-set.c
index 33dc366afe..a779023bab 100644
--- a/shell/e-storage-set.c
+++ b/shell/e-storage-set.c
@@ -153,6 +153,37 @@ storage_removed_folder_cb (EStorage *storage,
}
+static EStorage *
+get_storage_for_path (EStorageSet *storage_set,
+ const char *path,
+ const char **subpath_return)
+{
+ EStorage *storage;
+ char *storage_name;
+ const char *first_separator;
+
+ g_return_val_if_fail (g_path_is_absolute (path), NULL);
+
+ /* Skip initial separator. */
+ path++;
+
+ first_separator = strchr (path, G_DIR_SEPARATOR);
+
+ if (first_separator == NULL || first_separator == path || first_separator[1] == 0) {
+ *subpath_return = NULL;
+ return NULL;
+ }
+
+ storage_name = g_strndup (path, first_separator - path);
+ storage = e_storage_set_get_storage (storage_set, storage_name);
+ g_free (storage_name);
+
+ *subpath_return = first_separator;
+
+ return storage;
+}
+
+
/* GtkObject methods. */
static void
@@ -412,30 +443,16 @@ e_storage_set_get_folder (EStorageSet *storage_set,
const char *path)
{
EStorage *storage;
- const char *first_separator;
- char *storage_name;
+ const char *subpath;
g_return_val_if_fail (storage_set != NULL, NULL);
g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL);
g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (g_path_is_absolute (path), NULL);
- /* Skip initial separator. */
- path++;
-
- first_separator = strchr (path, G_DIR_SEPARATOR);
-
- if (first_separator == NULL || first_separator == path || first_separator[1] == 0)
- return NULL;
-
- storage_name = g_strndup (path, first_separator - path);
- storage = e_storage_set_get_storage (storage_set, storage_name);
- g_free (storage_name);
-
- if (storage == NULL)
- return NULL;
+ storage = get_storage_for_path (storage_set, path, &subpath);
- return e_storage_get_folder (storage, first_separator);
+ return e_storage_get_folder (storage, subpath);
}
@@ -453,6 +470,50 @@ e_storage_set_new_view (EStorageSet *storage_set)
}
+void
+e_storage_set_async_create_folder (EStorageSet *storage_set,
+ const char *path,
+ const char *type,
+ const char *description,
+ EStorageResultCallback callback,
+ void *data)
+{
+ EStorage *storage;
+ const char *subpath;
+
+ g_return_if_fail (storage_set != NULL);
+ g_return_if_fail (E_IS_STORAGE_SET (storage_set));
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (g_path_is_absolute (path));
+ g_return_if_fail (type != NULL);
+ g_return_if_fail (callback != NULL);
+
+ storage = get_storage_for_path (storage_set, path, &subpath);
+
+ e_storage_async_create_folder (storage, subpath, type, description, callback, data);
+}
+
+void
+e_storage_set_async_remove_folder (EStorageSet *storage_set,
+ const char *path,
+ EStorageResultCallback callback,
+ void *data)
+{
+ EStorage *storage;
+ const char *subpath;
+
+ g_return_if_fail (storage_set != NULL);
+ g_return_if_fail (E_IS_STORAGE_SET (storage_set));
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (g_path_is_absolute (path));
+ g_return_if_fail (callback != NULL);
+
+ storage = get_storage_for_path (storage_set, path, &subpath);
+
+ e_storage_async_remove_folder (storage, path, callback, data);
+}
+
+
EFolderTypeRegistry *
e_storage_set_get_folder_type_registry (EStorageSet *storage_set)
{
diff --git a/shell/e-storage-set.h b/shell/e-storage-set.h
index 9f9b38ac64..7731b5cafc 100644
--- a/shell/e-storage-set.h
+++ b/shell/e-storage-set.h
@@ -69,23 +69,34 @@ struct _EStorageSetClass {
GtkType e_storage_set_get_type (void);
-void e_storage_set_construct (EStorageSet *storage_set,
- EFolderTypeRegistry *folder_type_registry);
-EStorageSet *e_storage_set_new (EFolderTypeRegistry *folder_type_registry);
-
-gboolean e_storage_set_add_storage (EStorageSet *storage_set,
- EStorage *storage);
-gboolean e_storage_set_remove_storage (EStorageSet *storage_set,
- EStorage *storage);
-void e_storage_set_remove_all_storages (EStorageSet *storage_set);
-
-GList *e_storage_set_get_storage_list (EStorageSet *storage_set);
-EStorage *e_storage_set_get_storage (EStorageSet *storage_set,
- const char *storage_name);
-EFolder *e_storage_set_get_folder (EStorageSet *storage_set,
- const char *path);
-
-GtkWidget *e_storage_set_new_view (EStorageSet *storage_set);
+void e_storage_set_construct (EStorageSet *storage_set,
+ EFolderTypeRegistry *folder_type_registry);
+EStorageSet *e_storage_set_new (EFolderTypeRegistry *folder_type_registry);
+
+gboolean e_storage_set_add_storage (EStorageSet *storage_set,
+ EStorage *storage);
+gboolean e_storage_set_remove_storage (EStorageSet *storage_set,
+ EStorage *storage);
+void e_storage_set_remove_all_storages (EStorageSet *storage_set);
+
+GList *e_storage_set_get_storage_list (EStorageSet *storage_set);
+EStorage *e_storage_set_get_storage (EStorageSet *storage_set,
+ const char *storage_name);
+EFolder *e_storage_set_get_folder (EStorageSet *storage_set,
+ const char *path);
+
+GtkWidget *e_storage_set_new_view (EStorageSet *storage_set);
+
+void e_storage_set_async_create_folder (EStorageSet *storage_set,
+ const char *path,
+ const char *type,
+ const char *description,
+ EStorageResultCallback callback,
+ void *data);
+void e_storage_set_async_remove_folder (EStorageSet *storage_set,
+ const char *path,
+ EStorageResultCallback callback,
+ void *data);
EFolderTypeRegistry *e_storage_set_get_folder_type_registry (EStorageSet *storage_set);
diff --git a/shell/e-storage.c b/shell/e-storage.c
index b50a080fc4..30c0c6d667 100644
--- a/shell/e-storage.c
+++ b/shell/e-storage.c
@@ -218,21 +218,21 @@ impl_get_name (EStorage *storage)
}
static void
-impl_create_folder (EStorage *storage,
- const char *path,
- const char *type,
- const char *description,
- EStorageResultCallback callback,
- void *data)
+impl_async_create_folder (EStorage *storage,
+ const char *path,
+ const char *type,
+ const char *description,
+ EStorageResultCallback callback,
+ void *data)
{
(* callback) (storage, E_STORAGE_NOTIMPLEMENTED, data);
}
static void
-impl_remove_folder (EStorage *storage,
- const char *path,
- EStorageResultCallback callback,
- void *data)
+impl_async_remove_folder (EStorage *storage,
+ const char *path,
+ EStorageResultCallback callback,
+ void *data)
{
(* callback) (storage, E_STORAGE_NOTIMPLEMENTED, data);
}
@@ -250,11 +250,11 @@ class_init (EStorageClass *class)
object_class->destroy = destroy;
- class->list_folders = impl_list_folders;
- class->get_folder = impl_get_folder;
- class->get_name = impl_get_name;
- class->create_folder = impl_create_folder;
- class->remove_folder = impl_remove_folder;
+ class->list_folders = impl_list_folders;
+ class->get_folder = impl_get_folder;
+ class->get_name = impl_get_name;
+ class->async_create_folder = impl_async_create_folder;
+ class->async_remove_folder = impl_async_remove_folder;
signals[NEW_FOLDER] =
gtk_signal_new ("new_folder",
@@ -371,34 +371,68 @@ e_storage_get_name (EStorage *storage)
/* Folder operations. */
void
-e_storage_create_folder (EStorage *storage,
- const char *path,
- const char *type,
- const char *description,
- EStorageResultCallback callback,
- void *data)
+e_storage_async_create_folder (EStorage *storage,
+ const char *path,
+ const char *type,
+ const char *description,
+ EStorageResultCallback callback,
+ void *data)
{
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));
g_return_if_fail (type != NULL);
g_return_if_fail (callback != NULL);
- (* ES_CLASS (storage)->create_folder) (storage, path, type, description, callback, data);
+ (* ES_CLASS (storage)->async_create_folder) (storage, path, type, description, callback, data);
}
void
-e_storage_remove_folder (EStorage *storage,
- const char *path,
- EStorageResultCallback callback,
- void *data)
+e_storage_async_remove_folder (EStorage *storage,
+ const char *path,
+ EStorageResultCallback callback,
+ void *data)
{
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));
g_return_if_fail (callback != NULL);
- (* ES_CLASS (storage)->remove_folder) (storage, path, callback, data);
+ (* ES_CLASS (storage)->async_remove_folder) (storage, path, callback, data);
+}
+
+
+const char *
+e_storage_result_to_string (EStorageResult result)
+{
+ switch (result) {
+ case E_STORAGE_OK:
+ return _("No error");
+ case E_STORAGE_GENERICERROR:
+ return _("Generic error");
+ case E_STORAGE_EXISTS:
+ return _("A folder with the same name already exists");
+ case E_STORAGE_INVALIDTYPE:
+ return _("The specified folder type is not valid");
+ case E_STORAGE_IOERROR:
+ return _("I/O error");
+ case E_STORAGE_NOSPACE:
+ return _("Not enough space to create the folder");
+ case E_STORAGE_NOTFOUND:
+ return _("The specified folder was not found");
+ case E_STORAGE_NOTIMPLEMENTED:
+ return _("Function not implemented in this storage");
+ case E_STORAGE_PERMISSIONDENIED:
+ return _("Permission denied");
+ case E_STORAGE_UNSUPPORTEDOPERATION:
+ return _("Operation not supported");
+ case E_STORAGE_UNSUPPORTEDTYPE:
+ return _("The specified type is not supported in this storage");
+ default:
+ return _("Unknown error");
+ }
}
diff --git a/shell/e-storage.h b/shell/e-storage.h
index b144d0af5a..5422d6a9b4 100644
--- a/shell/e-storage.h
+++ b/shell/e-storage.h
@@ -48,10 +48,15 @@ typedef struct _EStorageClass EStorageClass;
enum _EStorageResult {
E_STORAGE_OK,
- E_STORAGE_NOTIMPLEMENTED,
- E_STORAGE_NOTFOUND,
+ E_STORAGE_GENERICERROR,
E_STORAGE_EXISTS,
- E_STORAGE_IO,
+ E_STORAGE_INVALIDTYPE,
+ E_STORAGE_IOERROR,
+ E_STORAGE_NOSPACE,
+ E_STORAGE_NOTFOUND,
+ E_STORAGE_NOTIMPLEMENTED,
+ E_STORAGE_PERMISSIONDENIED,
+ E_STORAGE_UNSUPPORTEDOPERATION,
E_STORAGE_UNSUPPORTEDTYPE
};
typedef enum _EStorageResult EStorageResult;
@@ -76,15 +81,15 @@ struct _EStorageClass {
/* Virtual methods. */
- GList * (* list_folders) (EStorage *storage, const char *path);
- EFolder * (* get_folder) (EStorage *storage, const char *path);
- const char * (* get_name) (EStorage *storage);
+ GList * (* list_folders) (EStorage *storage, const char *path);
+ EFolder * (* get_folder) (EStorage *storage, const char *path);
+ const char * (* get_name) (EStorage *storage);
- void (* create_folder) (EStorage *storage, const char *path,
- const char *type, const char *description,
- EStorageResultCallback callback, void *data);
- void (* remove_folder) (EStorage *storage, const char *path,
- EStorageResultCallback callback, void *data);
+ void (* async_create_folder) (EStorage *storage, const char *path,
+ const char *type, const char *description,
+ EStorageResultCallback callback, void *data);
+ void (* async_remove_folder) (EStorage *storage, const char *path,
+ EStorageResultCallback callback, void *data);
};
@@ -101,16 +106,18 @@ const char *e_storage_get_name (EStorage *storage);
/* Folder operations. */
-void e_storage_create_folder (EStorage *storage,
- const char *path,
- const char *type,
- const char *description,
- EStorageResultCallback callback,
- void *data);
-void e_storage_remove_folder (EStorage *storage,
- const char *path,
- EStorageResultCallback callback,
- void *data);
+void e_storage_async_create_folder (EStorage *storage,
+ const char *path,
+ const char *type,
+ const char *description,
+ EStorageResultCallback callback,
+ void *data);
+void e_storage_async_remove_folder (EStorage *storage,
+ const char *path,
+ EStorageResultCallback callback,
+ void *data);
+
+const char *e_storage_result_to_string (EStorageResult result);
/* Protected. C++ anyone? */
gboolean e_storage_new_folder (EStorage *storage, const char *path, EFolder *folder);
diff --git a/shell/evolution-shell-component-client.c b/shell/evolution-shell-component-client.c
index 53a4933142..29427501ab 100644
--- a/shell/evolution-shell-component-client.c
+++ b/shell/evolution-shell-component-client.c
@@ -137,13 +137,13 @@ dispatch_callback (EvolutionShellComponentClient *shell_component_client,
CORBA_exception_init (&ev);
- CORBA_Object_release (priv->listener_interface, &ev);
-
oid = PortableServer_POA_servant_to_id (bonobo_poa (), priv->listener_servant, &ev);
PortableServer_POA_deactivate_object (bonobo_poa (), oid, &ev);
POA_Evolution_ShellComponentListener__fini (priv->listener_servant, &ev);
CORBA_free (oid);
+ CORBA_Object_release (priv->listener_interface, &ev);
+
CORBA_exception_free (&ev);
priv->listener_servant = NULL;
@@ -251,34 +251,38 @@ free_ShellComponentListener_servant (PortableServer_Servant servant)
g_free (servant);
}
-static CORBA_Object
+static void
create_listener_interface (EvolutionShellComponentClient *shell_component_client)
{
- PortableServer_Servant servant;
+ EvolutionShellComponentClientPrivate *priv;
+ PortableServer_Servant listener_servant;
Evolution_ShellComponentListener corba_interface;
CORBA_Environment ev;
- servant = create_ShellComponentListener_servant (shell_component_client);
+ priv = shell_component_client->priv;
+
+ listener_servant = create_ShellComponentListener_servant (shell_component_client);
CORBA_exception_init (&ev);
- POA_Evolution_ShellComponentListener__init (servant, &ev);
+ POA_Evolution_ShellComponentListener__init (listener_servant, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- free_ShellComponentListener_servant (servant);
- return CORBA_OBJECT_NIL;
+ free_ShellComponentListener_servant (listener_servant);
+ return;
}
- CORBA_free (PortableServer_POA_activate_object (bonobo_poa (), servant, &ev));
+ CORBA_free (PortableServer_POA_activate_object (bonobo_poa (), listener_servant, &ev));
- corba_interface = PortableServer_POA_servant_to_reference (bonobo_poa (), servant, &ev);
+ corba_interface = PortableServer_POA_servant_to_reference (bonobo_poa (), listener_servant, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
corba_interface = CORBA_OBJECT_NIL;
- free_ShellComponentListener_servant (servant);
+ free_ShellComponentListener_servant (listener_servant);
}
CORBA_exception_free (&ev);
- return corba_interface;
+ priv->listener_servant = listener_servant;
+ priv->listener_interface = corba_interface;
}
@@ -319,8 +323,10 @@ init (EvolutionShellComponentClient *shell_component_client)
EvolutionShellComponentClientPrivate *priv;
priv = g_new (EvolutionShellComponentClientPrivate, 1);
- priv->callback = NULL;
- priv->callback_data = NULL;
+ priv->listener_interface = CORBA_OBJECT_NIL;
+ priv->listener_servant = NULL;
+ priv->callback = NULL;
+ priv->callback_data = NULL;
shell_component_client->priv = priv;
}
@@ -476,21 +482,20 @@ evolution_shell_component_client_async_create_folder (EvolutionShellComponentCli
return;
}
- priv->listener_interface = create_listener_interface (shell_component_client);
+ create_listener_interface (shell_component_client);
CORBA_exception_init (&ev);
corba_shell_component = bonobo_object_corba_objref (BONOBO_OBJECT (shell_component_client));
+ priv->callback = callback;
+ priv->callback_data = data;
+
Evolution_ShellComponent_async_create_folder (corba_shell_component,
priv->listener_interface,
physical_uri, type,
&ev);
- /* FIXME merge with create_listener_interface into separate init_for_callback() func. */
- priv->callback = callback;
- priv->callback_data = data;
-
CORBA_exception_free (&ev);
}
diff --git a/shell/evolution-shell-component.h b/shell/evolution-shell-component.h
index ec049fbd94..a1a70ebafa 100644
--- a/shell/evolution-shell-component.h
+++ b/shell/evolution-shell-component.h
@@ -70,20 +70,21 @@ enum _EvolutionShellComponentResult {
};
typedef enum _EvolutionShellComponentResult EvolutionShellComponentResult;
-typedef EvolutionShellComponentResult (* EvolutionShellComponentCreateViewFn) (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- BonoboControl **control_return,
- void *closure);
-typedef EvolutionShellComponentResult (* EvolutionShellComponentCreateFolderFn) (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const Evolution_ShellComponentListener listener,
- void *closure);
-typedef EvolutionShellComponentResult (* EvolutionShellComponentRemoveFolderFn) (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const Evolution_ShellComponentListener listener,
- void *closure);
+typedef EvolutionShellComponentResult (* EvolutionShellComponentCreateViewFn)
+ (EvolutionShellComponent *shell_component,
+ const char *physical_uri,
+ const char *type,
+ BonoboControl **control_return,
+ void *closure);
+typedef void (* EvolutionShellComponentCreateFolderFn) (EvolutionShellComponent *shell_component,
+ const char *physical_uri,
+ const char *type,
+ const Evolution_ShellComponentListener listener,
+ void *closure);
+typedef void (* EvolutionShellComponentRemoveFolderFn) (EvolutionShellComponent *shell_component,
+ const char *physical_uri,
+ const Evolution_ShellComponentListener listener,
+ void *closure);
struct _EvolutionShellComponentFolderType {
char *name;