Implemented folder creation dialog (File -> New -> Folder). To make

it really work though, the components should implement creation
functionality by passing an appropriate function pointer in
`e_shell_component_new()' for @create_folder_fn.

svn path=/trunk/; revision=3504
This commit is contained in:
Ettore Perazzoli
2000-06-10 17:56:46 +00:00
parent e8e0d04d0c
commit bbb6a6942f
18 changed files with 861 additions and 193 deletions

View File

@ -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> 2000-06-09 Dan Winship <danw@helixcode.com>
* folder-browser.c (folder_browser_new): Add a serial number to * folder-browser.c (folder_browser_new): Add a serial number to

View File

@ -93,6 +93,26 @@ create_view (EvolutionShellComponent *shell_component,
return EVOLUTION_SHELL_COMPONENT_OK; return EVOLUTION_SHELL_COMPONENT_OK;
} }
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 static void
owner_set_cb (EvolutionShellComponent *shell_component, owner_set_cb (EvolutionShellComponent *shell_component,
Evolution_Shell shell_interface, Evolution_Shell shell_interface,
@ -130,7 +150,11 @@ factory_fn (BonoboGenericFactory *factory,
{ {
EvolutionShellComponent *shell_component; 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_connect (GTK_OBJECT (shell_component), "owner_set",
GTK_SIGNAL_FUNC (owner_set_cb), NULL); GTK_SIGNAL_FUNC (owner_set_cb), NULL);

View File

@ -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> 2000-06-09 Ettore Perazzoli <ettore@helixcode.com>
* e-shell-view-menu.c: Removed folder menu and "save as..." command. * e-shell-view-menu.c: Removed folder menu and "save as..." command.

View File

@ -162,7 +162,6 @@ e_folder_construct (EFolder *folder,
g_return_if_fail (E_IS_FOLDER (folder)); g_return_if_fail (E_IS_FOLDER (folder));
g_return_if_fail (name != NULL); g_return_if_fail (name != NULL);
g_return_if_fail (type != NULL); g_return_if_fail (type != NULL);
g_return_if_fail (description != NULL);
GTK_OBJECT_UNSET_FLAGS (GTK_OBJECT (folder), GTK_FLOATING); GTK_OBJECT_UNSET_FLAGS (GTK_OBJECT (folder), GTK_FLOATING);

View File

@ -138,7 +138,8 @@ save_metadata (ELocalFolder *local_folder)
EFolder *folder; EFolder *folder;
xmlDoc *doc; xmlDoc *doc;
xmlNode *root; xmlNode *root;
const char *physical_path; const char *physical_directory;
char *physical_path;
folder = E_FOLDER (local_folder); folder = E_FOLDER (local_folder);
@ -146,16 +147,25 @@ save_metadata (ELocalFolder *local_folder)
root = xmlNewDocNode (doc, NULL, (xmlChar *) "efolder", NULL); root = xmlNewDocNode (doc, NULL, (xmlChar *) "efolder", NULL);
xmlDocSetRootElement (doc, root); xmlDocSetRootElement (doc, root);
xmlNewChild (root, NULL, (xmlChar *) "type", (xmlChar *) e_folder_get_type_string (folder)); xmlNewChild (root, NULL, (xmlChar *) "type",
xmlNewChild (root, NULL, (xmlChar *) "description", (xmlChar *) e_folder_get_description (folder)); (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) { if (xmlSaveFile (physical_path, doc) < 0) {
unlink (physical_path);
g_free (physical_path);
xmlFreeDoc (doc); xmlFreeDoc (doc);
return FALSE; return FALSE;
} }
g_free (physical_path);
xmlFreeDoc (doc); xmlFreeDoc (doc);
return TRUE; 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 * EFolder *
e_local_folder_new_from_path (const char *path) 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 (local_folder != NULL, FALSE);
g_return_val_if_fail (E_IS_LOCAL_FOLDER (local_folder), 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); return save_metadata (local_folder);
} }

View File

@ -56,6 +56,13 @@ struct _ELocalFolderClass {
GtkType e_local_folder_get_type (void); 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); EFolder *e_local_folder_new_from_path (const char *physical_path);
gboolean e_local_folder_save (ELocalFolder *local_folder); gboolean e_local_folder_save (ELocalFolder *local_folder);

View File

@ -25,6 +25,9 @@
* *
* - If we have `.' or `..' as path elements, we lose. * - 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 #ifdef HAVE_CONFIG_H
@ -34,6 +37,7 @@
#define _POSIX_SOURCE /* Yuck. */ #define _POSIX_SOURCE /* Yuck. */
#include <dirent.h> #include <dirent.h>
#include <errno.h>
#include <string.h> #include <string.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/types.h> #include <sys/types.h>
@ -54,17 +58,16 @@ static EStorageClass *parent_class = NULL;
#define SUBFOLDER_DIR_NAME_LEN 10 #define SUBFOLDER_DIR_NAME_LEN 10
struct _ELocalStoragePrivate { struct _ELocalStoragePrivate {
EComponentRegistry *component_registry; EFolderTypeRegistry *folder_type_registry;
char *base_path; char *base_path;
}; };
/* Utility functions. */ /* Utility functions. */
#if 0 /* Translate a storage path into a physical path on the file system. */
/* Translate a storage path into a real path on the file system. */
static char * static char *
get_real_path (ELocalStorage *local_storage, get_physical_path (ELocalStorage *local_storage,
const char *path) const char *path)
{ {
EStorage *storage; EStorage *storage;
@ -80,7 +83,7 @@ get_real_path (ELocalStorage *local_storage,
/* @path is always absolute, so it starts with a slash. The base class should /* @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. */ make sure this is the case; if not, it's broken. */
g_assert (*path != G_DIR_SEPARATOR); g_assert (*path == G_DIR_SEPARATOR);
path++; path++;
/* Calculate the length of the real 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. */ real_path_len++; /* For the separating slash. */
/* Take account for the fact that we need to translate every separator into /* Take account for the fact that we need to translate every separator into
`children/'. */ `subfolders/'. */
p = path; p = path;
while (1) { while (1) {
newp = strchr (p, G_DIR_SEPARATOR); newp = strchr (p, G_DIR_SEPARATOR);
@ -121,8 +124,10 @@ get_real_path (ELocalStorage *local_storage,
p = path; p = path;
while (1) { while (1) {
newp = strchr (p, G_DIR_SEPARATOR); newp = strchr (p, G_DIR_SEPARATOR);
if (newp == NULL) if (newp == NULL) {
strcpy (dp, p);
break; break;
}
memcpy (dp, p, newp - p + 1); /* `+ 1' to copy the slash too. */ memcpy (dp, p, newp - p + 1); /* `+ 1' to copy the slash too. */
dp += newp - p + 1; dp += newp - p + 1;
@ -141,7 +146,6 @@ get_real_path (ELocalStorage *local_storage,
return real_path; return real_path;
} }
#endif
static gboolean static gboolean
load_folders (ELocalStorage *local_storage, 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); 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. */ /* GtkObject methods. */
@ -244,8 +369,8 @@ impl_destroy (GtkObject *object)
g_free (priv->base_path); g_free (priv->base_path);
if (priv->component_registry != NULL) if (priv->folder_type_registry != NULL)
gtk_object_unref (GTK_OBJECT (priv->component_registry)); gtk_object_unref (GTK_OBJECT (priv->folder_type_registry));
g_free (priv); g_free (priv);
@ -263,7 +388,7 @@ impl_get_name (EStorage *storage)
} }
static void static void
impl_create_folder (EStorage *storage, impl_async_create_folder (EStorage *storage,
const char *path, const char *path,
const char *type, const char *type,
const char *description, const char *description,
@ -271,12 +396,96 @@ impl_create_folder (EStorage *storage,
void *data) void *data)
{ {
ELocalStorage *local_storage; 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); 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 static void
impl_remove_folder (EStorage *storage, impl_async_remove_folder (EStorage *storage,
const char *path, const char *path,
EStorageResultCallback callback, EStorageResultCallback callback,
void *data) void *data)
@ -302,8 +511,8 @@ class_init (ELocalStorageClass *class)
object_class->destroy = impl_destroy; object_class->destroy = impl_destroy;
storage_class->get_name = impl_get_name; storage_class->get_name = impl_get_name;
storage_class->create_folder = impl_create_folder; storage_class->async_create_folder = impl_async_create_folder;
storage_class->remove_folder = impl_remove_folder; storage_class->async_remove_folder = impl_async_remove_folder;
} }
static void static void
@ -314,7 +523,7 @@ init (ELocalStorage *local_storage)
priv = g_new (ELocalStoragePrivate, 1); priv = g_new (ELocalStoragePrivate, 1);
priv->base_path = NULL; priv->base_path = NULL;
priv->component_registry = NULL; priv->folder_type_registry = NULL;
local_storage->priv = priv; local_storage->priv = priv;
} }
@ -322,7 +531,7 @@ init (ELocalStorage *local_storage)
static gboolean static gboolean
construct (ELocalStorage *local_storage, construct (ELocalStorage *local_storage,
EComponentRegistry *component_registry, EFolderTypeRegistry *folder_type_registry,
const char *base_path) const char *base_path)
{ {
ELocalStoragePrivate *priv; ELocalStoragePrivate *priv;
@ -338,9 +547,9 @@ construct (ELocalStorage *local_storage,
g_return_val_if_fail (base_path_len != 0, FALSE); g_return_val_if_fail (base_path_len != 0, FALSE);
g_assert (priv->component_registry == NULL); g_assert (priv->folder_type_registry == NULL);
gtk_object_ref (GTK_OBJECT (component_registry)); gtk_object_ref (GTK_OBJECT (folder_type_registry));
priv->component_registry = component_registry; priv->folder_type_registry = folder_type_registry;
g_assert (priv->base_path == NULL); g_assert (priv->base_path == NULL);
priv->base_path = g_strndup (base_path, base_path_len); priv->base_path = g_strndup (base_path, base_path_len);
@ -349,18 +558,18 @@ construct (ELocalStorage *local_storage,
} }
EStorage * EStorage *
e_local_storage_open (EComponentRegistry *component_registry, e_local_storage_open (EFolderTypeRegistry *folder_type_registry,
const char *base_path) const char *base_path)
{ {
EStorage *new; EStorage *new;
g_return_val_if_fail (component_registry != NULL, NULL); g_return_val_if_fail (folder_type_registry != NULL, NULL);
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), NULL); g_return_val_if_fail (E_IS_FOLDER_TYPE_REGISTRY (folder_type_registry), NULL);
g_return_val_if_fail (base_path != NULL, NULL); g_return_val_if_fail (base_path != NULL, NULL);
new = gtk_type_new (e_local_storage_get_type ()); 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)); gtk_object_unref (GTK_OBJECT (new));
return NULL; return NULL;
} }

View File

@ -28,7 +28,7 @@
#include <config.h> #include <config.h>
#endif #endif
#include "e-component-registry.h" #include "e-folder-type-registry.h"
#include "e-storage.h" #include "e-storage.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -58,7 +58,7 @@ struct _ELocalStorageClass {
GtkType e_local_storage_get_type (void); GtkType e_local_storage_get_type (void);
EStorage *e_local_storage_open (EComponentRegistry *component_registry, EStorage *e_local_storage_open (EFolderTypeRegistry *folder_type_registry,
const char *base_path); const char *base_path);
const char *e_local_storage_get_base_path (ELocalStorage *storage); const char *e_local_storage_get_base_path (ELocalStorage *storage);

View File

@ -28,7 +28,9 @@
#include <gnome.h> #include <gnome.h>
#include <glade/glade-xml.h> #include <glade/glade-xml.h>
#include "e-util/e-gui-utils.h"
#include "e-util/e-util.h" #include "e-util/e-util.h"
#include "widgets/misc/e-scroll-frame.h" #include "widgets/misc/e-scroll-frame.h"
#include "e-storage-set.h" #include "e-storage-set.h"
@ -40,25 +42,142 @@
#define GLADE_FILE_NAME E_GLADEDIR "/e-shell-folder-creation-dialog.glade" #define GLADE_FILE_NAME E_GLADEDIR "/e-shell-folder-creation-dialog.glade"
/* Dialog callbacks. */ /* 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 signal callbacks. */
static void static void
dialog_clicked_cb (GnomeDialog *dialog, dialog_clicked_cb (GnomeDialog *dialog,
int button_number, int button_number,
void *data) void *data)
{ {
g_print ("Clicked -- %d\n", button_number); 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); 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 static void
dialog_close_cb (GnomeDialog *dialog, dialog_close_cb (GnomeDialog *dialog,
void *data) void *data)
{ {
g_print ("Closed\n");
gtk_widget_destroy (GTK_WIDGET (dialog)); 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 static void
folder_name_entry_changed_cb (GtkEditable *editable, folder_name_entry_changed_cb (GtkEditable *editable,
void *data) void *data)
@ -75,6 +194,19 @@ folder_name_entry_changed_cb (GtkEditable *editable,
gnome_dialog_set_sensitive (dialog, 0, FALSE); gnome_dialog_set_sensitive (dialog, 0, FALSE);
} }
/* 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. */ /* Dialog setup. */
@ -82,10 +214,10 @@ static void
setup_dialog (GtkWidget *dialog, setup_dialog (GtkWidget *dialog,
GladeXML *gui, GladeXML *gui,
EShell *shell, EShell *shell,
GtkWindow *parent) GtkWindow *parent_window)
{ {
if (parent != NULL) if (parent_window != NULL)
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent); gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_window_set_title (GTK_WINDOW (dialog), _("Evolution - Create new folder")); 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_default (GNOME_DIALOG (dialog), 0);
gnome_dialog_set_sensitive (GNOME_DIALOG (dialog), 0, FALSE); 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); gtk_widget_show (dialog);
} }
@ -116,7 +243,7 @@ setup_folder_name_entry (GtkWidget *dialog,
GTK_SIGNAL_FUNC (folder_name_entry_changed_cb), dialog); GTK_SIGNAL_FUNC (folder_name_entry_changed_cb), dialog);
} }
static void static GtkWidget *
add_storage_set_view (GtkWidget *dialog, add_storage_set_view (GtkWidget *dialog,
GladeXML *gui, GladeXML *gui,
EShell *shell, EShell *shell,
@ -146,9 +273,11 @@ add_storage_set_view (GtkWidget *dialog,
gtk_widget_show (scroll_frame); gtk_widget_show (scroll_frame);
gtk_widget_show (storage_set_view); gtk_widget_show (storage_set_view);
return storage_set_view;
} }
static void static GList *
add_folder_types (GtkWidget *dialog, add_folder_types (GtkWidget *dialog,
GladeXML *gui, GladeXML *gui,
EShell *shell) EShell *shell)
@ -156,7 +285,7 @@ add_folder_types (GtkWidget *dialog,
EFolderTypeRegistry *folder_type_registry; EFolderTypeRegistry *folder_type_registry;
GtkWidget *folder_type_option_menu; GtkWidget *folder_type_option_menu;
GtkWidget *menu; GtkWidget *menu;
GList *types; GList *folder_types;
GList *p; GList *p;
int default_item; int default_item;
int i; int i;
@ -170,17 +299,17 @@ add_folder_types (GtkWidget *dialog,
folder_type_registry = e_shell_get_folder_type_registry (shell); folder_type_registry = e_shell_get_folder_type_registry (shell);
g_assert (folder_type_registry != NULL); g_assert (folder_type_registry != NULL);
types = e_folder_type_registry_get_type_names (folder_type_registry); folder_types = e_folder_type_registry_get_type_names (folder_type_registry);
if (types == NULL) if (folder_types == NULL)
return; /* Uh? */ 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: Use descriptive name (not in the registry's implementation yet). */
/* FIXME: Add icon (I don't feel like writing an alpha-capable thingie again). */ /* FIXME: Add icon (I don't feel like writing an alpha-capable thingie again). */
default_item = 0; 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; const char *type_name;
GtkWidget *menu_item; GtkWidget *menu_item;
@ -190,13 +319,15 @@ add_folder_types (GtkWidget *dialog,
gtk_menu_append (GTK_MENU (menu), menu_item); gtk_menu_append (GTK_MENU (menu), menu_item);
gtk_widget_show (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) if (strcmp (type_name, "mail") == 0)
default_item = i; default_item = i;
} }
e_free_string_list (types);
gtk_option_menu_set_history (GTK_OPTION_MENU (folder_type_option_menu), default_item); 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. */ open at once. Currently it relies on modality for this. */
void void
e_shell_show_folder_creation_dialog (EShell *shell, e_shell_show_folder_creation_dialog (EShell *shell,
GtkWindow *parent, GtkWindow *parent_window,
const char *default_parent_folder) const char *default_parent_folder)
{ {
GladeXML *gui; GladeXML *gui;
GtkWidget *dialog; GtkWidget *dialog;
GtkWidget *storage_set_view;
GList *folder_types;
DialogData *dialog_data;
g_return_if_fail (shell != NULL); g_return_if_fail (shell != NULL);
g_return_if_fail (E_IS_SHELL (shell)); 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"); 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); setup_folder_name_entry (dialog, gui, shell);
add_storage_set_view (dialog, gui, shell, default_parent_folder); storage_set_view = add_storage_set_view (dialog, gui, shell, default_parent_folder);
add_folder_types (dialog, gui, shell); 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)); gtk_object_unref (GTK_OBJECT (gui));
} }

View File

@ -171,7 +171,7 @@ setup_local_storage (EShell *shell)
local_storage_path = g_concat_dir_and_file (priv->local_directory, local_storage_path = g_concat_dir_and_file (priv->local_directory,
LOCAL_STORAGE_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); local_storage_path);
if (local_storage == NULL) { if (local_storage == NULL) {
g_warning (_("Cannot set up local storage -- %s"), local_storage_path); g_warning (_("Cannot set up local storage -- %s"), local_storage_path);

View File

@ -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); 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) E_MAKE_TYPE (e_storage_set_view, "EStorageSetView", EStorageSetView, class_init, init, PARENT_TYPE)

View File

@ -69,6 +69,7 @@ void e_storage_set_view_construct (EStorageSetView *storage_set_
EStorageSet *storage_set); EStorageSet *storage_set);
void e_storage_set_view_set_current_folder (EStorageSetView *storage_set_view, void e_storage_set_view_set_current_folder (EStorageSetView *storage_set_view,
const char *path); const char *path);
const char *e_storage_set_view_get_current_folder (EStorageSetView *storage_set_view);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -152,6 +152,37 @@ storage_removed_folder_cb (EStorage *storage,
g_free (full_path); g_free (full_path);
} }
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. */ /* GtkObject methods. */
@ -412,30 +443,16 @@ e_storage_set_get_folder (EStorageSet *storage_set,
const char *path) const char *path)
{ {
EStorage *storage; EStorage *storage;
const char *first_separator; const char *subpath;
char *storage_name;
g_return_val_if_fail (storage_set != NULL, NULL); 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 (E_IS_STORAGE_SET (storage_set), NULL);
g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (g_path_is_absolute (path), NULL); g_return_val_if_fail (g_path_is_absolute (path), NULL);
/* Skip initial separator. */ storage = get_storage_for_path (storage_set, path, &subpath);
path++;
first_separator = strchr (path, G_DIR_SEPARATOR); return e_storage_get_folder (storage, subpath);
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;
return e_storage_get_folder (storage, first_separator);
} }
@ -452,6 +469,50 @@ e_storage_set_new_view (EStorageSet *storage_set)
return storage_set_view; return storage_set_view;
} }
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 * EFolderTypeRegistry *
e_storage_set_get_folder_type_registry (EStorageSet *storage_set) e_storage_set_get_folder_type_registry (EStorageSet *storage_set)

View File

@ -87,6 +87,17 @@ EFolder *e_storage_set_get_folder (EStorageSet *storage_se
GtkWidget *e_storage_set_new_view (EStorageSet *storage_set); 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); EFolderTypeRegistry *e_storage_set_get_folder_type_registry (EStorageSet *storage_set);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -218,7 +218,7 @@ impl_get_name (EStorage *storage)
} }
static void static void
impl_create_folder (EStorage *storage, impl_async_create_folder (EStorage *storage,
const char *path, const char *path,
const char *type, const char *type,
const char *description, const char *description,
@ -229,7 +229,7 @@ impl_create_folder (EStorage *storage,
} }
static void static void
impl_remove_folder (EStorage *storage, impl_async_remove_folder (EStorage *storage,
const char *path, const char *path,
EStorageResultCallback callback, EStorageResultCallback callback,
void *data) void *data)
@ -253,8 +253,8 @@ class_init (EStorageClass *class)
class->list_folders = impl_list_folders; class->list_folders = impl_list_folders;
class->get_folder = impl_get_folder; class->get_folder = impl_get_folder;
class->get_name = impl_get_name; class->get_name = impl_get_name;
class->create_folder = impl_create_folder; class->async_create_folder = impl_async_create_folder;
class->remove_folder = impl_remove_folder; class->async_remove_folder = impl_async_remove_folder;
signals[NEW_FOLDER] = signals[NEW_FOLDER] =
gtk_signal_new ("new_folder", gtk_signal_new ("new_folder",
@ -371,7 +371,7 @@ e_storage_get_name (EStorage *storage)
/* Folder operations. */ /* Folder operations. */
void void
e_storage_create_folder (EStorage *storage, e_storage_async_create_folder (EStorage *storage,
const char *path, const char *path,
const char *type, const char *type,
const char *description, const char *description,
@ -381,14 +381,15 @@ e_storage_create_folder (EStorage *storage,
g_return_if_fail (storage != NULL); g_return_if_fail (storage != NULL);
g_return_if_fail (E_IS_STORAGE (storage)); g_return_if_fail (E_IS_STORAGE (storage));
g_return_if_fail (path != NULL); 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 (type != NULL);
g_return_if_fail (callback != 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 void
e_storage_remove_folder (EStorage *storage, e_storage_async_remove_folder (EStorage *storage,
const char *path, const char *path,
EStorageResultCallback callback, EStorageResultCallback callback,
void *data) void *data)
@ -396,9 +397,42 @@ e_storage_remove_folder (EStorage *storage,
g_return_if_fail (storage != NULL); g_return_if_fail (storage != NULL);
g_return_if_fail (E_IS_STORAGE (storage)); g_return_if_fail (E_IS_STORAGE (storage));
g_return_if_fail (path != NULL); g_return_if_fail (path != NULL);
g_return_if_fail (g_path_is_absolute (path));
g_return_if_fail (callback != NULL); 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");
}
} }

View File

@ -48,10 +48,15 @@ typedef struct _EStorageClass EStorageClass;
enum _EStorageResult { enum _EStorageResult {
E_STORAGE_OK, E_STORAGE_OK,
E_STORAGE_NOTIMPLEMENTED, E_STORAGE_GENERICERROR,
E_STORAGE_NOTFOUND,
E_STORAGE_EXISTS, 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 E_STORAGE_UNSUPPORTEDTYPE
}; };
typedef enum _EStorageResult EStorageResult; typedef enum _EStorageResult EStorageResult;
@ -80,10 +85,10 @@ struct _EStorageClass {
EFolder * (* get_folder) (EStorage *storage, const char *path); EFolder * (* get_folder) (EStorage *storage, const char *path);
const char * (* get_name) (EStorage *storage); const char * (* get_name) (EStorage *storage);
void (* create_folder) (EStorage *storage, const char *path, void (* async_create_folder) (EStorage *storage, const char *path,
const char *type, const char *description, const char *type, const char *description,
EStorageResultCallback callback, void *data); EStorageResultCallback callback, void *data);
void (* remove_folder) (EStorage *storage, const char *path, void (* async_remove_folder) (EStorage *storage, const char *path,
EStorageResultCallback callback, void *data); EStorageResultCallback callback, void *data);
}; };
@ -101,17 +106,19 @@ const char *e_storage_get_name (EStorage *storage);
/* Folder operations. */ /* Folder operations. */
void e_storage_create_folder (EStorage *storage, void e_storage_async_create_folder (EStorage *storage,
const char *path, const char *path,
const char *type, const char *type,
const char *description, const char *description,
EStorageResultCallback callback, EStorageResultCallback callback,
void *data); void *data);
void e_storage_remove_folder (EStorage *storage, void e_storage_async_remove_folder (EStorage *storage,
const char *path, const char *path,
EStorageResultCallback callback, EStorageResultCallback callback,
void *data); void *data);
const char *e_storage_result_to_string (EStorageResult result);
/* Protected. C++ anyone? */ /* Protected. C++ anyone? */
gboolean e_storage_new_folder (EStorage *storage, const char *path, EFolder *folder); gboolean e_storage_new_folder (EStorage *storage, const char *path, EFolder *folder);
gboolean e_storage_removed_folder (EStorage *storage, const char *path); gboolean e_storage_removed_folder (EStorage *storage, const char *path);

View File

@ -137,13 +137,13 @@ dispatch_callback (EvolutionShellComponentClient *shell_component_client,
CORBA_exception_init (&ev); CORBA_exception_init (&ev);
CORBA_Object_release (priv->listener_interface, &ev);
oid = PortableServer_POA_servant_to_id (bonobo_poa (), priv->listener_servant, &ev); oid = PortableServer_POA_servant_to_id (bonobo_poa (), priv->listener_servant, &ev);
PortableServer_POA_deactivate_object (bonobo_poa (), oid, &ev); PortableServer_POA_deactivate_object (bonobo_poa (), oid, &ev);
POA_Evolution_ShellComponentListener__fini (priv->listener_servant, &ev); POA_Evolution_ShellComponentListener__fini (priv->listener_servant, &ev);
CORBA_free (oid); CORBA_free (oid);
CORBA_Object_release (priv->listener_interface, &ev);
CORBA_exception_free (&ev); CORBA_exception_free (&ev);
priv->listener_servant = NULL; priv->listener_servant = NULL;
@ -251,34 +251,38 @@ free_ShellComponentListener_servant (PortableServer_Servant servant)
g_free (servant); g_free (servant);
} }
static CORBA_Object static void
create_listener_interface (EvolutionShellComponentClient *shell_component_client) create_listener_interface (EvolutionShellComponentClient *shell_component_client)
{ {
PortableServer_Servant servant; EvolutionShellComponentClientPrivate *priv;
PortableServer_Servant listener_servant;
Evolution_ShellComponentListener corba_interface; Evolution_ShellComponentListener corba_interface;
CORBA_Environment ev; 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); CORBA_exception_init (&ev);
POA_Evolution_ShellComponentListener__init (servant, &ev); POA_Evolution_ShellComponentListener__init (listener_servant, &ev);
if (ev._major != CORBA_NO_EXCEPTION) { if (ev._major != CORBA_NO_EXCEPTION) {
free_ShellComponentListener_servant (servant); free_ShellComponentListener_servant (listener_servant);
return CORBA_OBJECT_NIL; 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) { if (ev._major != CORBA_NO_EXCEPTION) {
corba_interface = CORBA_OBJECT_NIL; corba_interface = CORBA_OBJECT_NIL;
free_ShellComponentListener_servant (servant); free_ShellComponentListener_servant (listener_servant);
} }
CORBA_exception_free (&ev); CORBA_exception_free (&ev);
return corba_interface; priv->listener_servant = listener_servant;
priv->listener_interface = corba_interface;
} }
@ -319,6 +323,8 @@ init (EvolutionShellComponentClient *shell_component_client)
EvolutionShellComponentClientPrivate *priv; EvolutionShellComponentClientPrivate *priv;
priv = g_new (EvolutionShellComponentClientPrivate, 1); priv = g_new (EvolutionShellComponentClientPrivate, 1);
priv->listener_interface = CORBA_OBJECT_NIL;
priv->listener_servant = NULL;
priv->callback = NULL; priv->callback = NULL;
priv->callback_data = NULL; priv->callback_data = NULL;
@ -476,21 +482,20 @@ evolution_shell_component_client_async_create_folder (EvolutionShellComponentCli
return; return;
} }
priv->listener_interface = create_listener_interface (shell_component_client); create_listener_interface (shell_component_client);
CORBA_exception_init (&ev); CORBA_exception_init (&ev);
corba_shell_component = bonobo_object_corba_objref (BONOBO_OBJECT (shell_component_client)); 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, Evolution_ShellComponent_async_create_folder (corba_shell_component,
priv->listener_interface, priv->listener_interface,
physical_uri, type, physical_uri, type,
&ev); &ev);
/* FIXME merge with create_listener_interface into separate init_for_callback() func. */
priv->callback = callback;
priv->callback_data = data;
CORBA_exception_free (&ev); CORBA_exception_free (&ev);
} }

View File

@ -70,17 +70,18 @@ enum _EvolutionShellComponentResult {
}; };
typedef enum _EvolutionShellComponentResult EvolutionShellComponentResult; typedef enum _EvolutionShellComponentResult EvolutionShellComponentResult;
typedef EvolutionShellComponentResult (* EvolutionShellComponentCreateViewFn) (EvolutionShellComponent *shell_component, typedef EvolutionShellComponentResult (* EvolutionShellComponentCreateViewFn)
(EvolutionShellComponent *shell_component,
const char *physical_uri, const char *physical_uri,
const char *type, const char *type,
BonoboControl **control_return, BonoboControl **control_return,
void *closure); void *closure);
typedef EvolutionShellComponentResult (* EvolutionShellComponentCreateFolderFn) (EvolutionShellComponent *shell_component, typedef void (* EvolutionShellComponentCreateFolderFn) (EvolutionShellComponent *shell_component,
const char *physical_uri, const char *physical_uri,
const char *type, const char *type,
const Evolution_ShellComponentListener listener, const Evolution_ShellComponentListener listener,
void *closure); void *closure);
typedef EvolutionShellComponentResult (* EvolutionShellComponentRemoveFolderFn) (EvolutionShellComponent *shell_component, typedef void (* EvolutionShellComponentRemoveFolderFn) (EvolutionShellComponent *shell_component,
const char *physical_uri, const char *physical_uri,
const Evolution_ShellComponentListener listener, const Evolution_ShellComponentListener listener,
void *closure); void *closure);