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:
@ -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
|
||||
|
@ -93,6 +93,26 @@ create_view (EvolutionShellComponent *shell_component,
|
||||
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
|
||||
owner_set_cb (EvolutionShellComponent *shell_component,
|
||||
Evolution_Shell shell_interface,
|
||||
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -56,6 +56,13 @@ struct _ELocalFolderClass {
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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,17 +58,16 @@ 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,
|
||||
get_physical_path (ELocalStorage *local_storage,
|
||||
const char *path)
|
||||
{
|
||||
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
|
||||
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,7 +388,7 @@ impl_get_name (EStorage *storage)
|
||||
}
|
||||
|
||||
static void
|
||||
impl_create_folder (EStorage *storage,
|
||||
impl_async_create_folder (EStorage *storage,
|
||||
const char *path,
|
||||
const char *type,
|
||||
const char *description,
|
||||
@ -271,12 +396,96 @@ impl_create_folder (EStorage *storage,
|
||||
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,
|
||||
impl_async_remove_folder (EStorage *storage,
|
||||
const char *path,
|
||||
EStorageResultCallback callback,
|
||||
void *data)
|
||||
@ -302,8 +511,8 @@ class_init (ELocalStorageClass *class)
|
||||
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->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;
|
||||
}
|
||||
|
@ -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,7 +58,7 @@ struct _ELocalStorageClass {
|
||||
|
||||
|
||||
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 *e_local_storage_get_base_path (ELocalStorage *storage);
|
||||
|
||||
|
@ -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"
|
||||
@ -40,25 +42,142 @@
|
||||
#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
|
||||
dialog_clicked_cb (GnomeDialog *dialog,
|
||||
int button_number,
|
||||
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);
|
||||
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)
|
||||
@ -75,6 +194,19 @@ folder_name_entry_changed_cb (GtkEditable *editable,
|
||||
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. */
|
||||
|
||||
@ -82,10 +214,10 @@ 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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -69,6 +69,7 @@ void e_storage_set_view_construct (EStorageSetView *storage_set_
|
||||
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
|
||||
}
|
||||
|
@ -152,6 +152,37 @@ storage_removed_folder_cb (EStorage *storage,
|
||||
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. */
|
||||
|
||||
@ -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++;
|
||||
storage = get_storage_for_path (storage_set, path, &subpath);
|
||||
|
||||
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;
|
||||
|
||||
return e_storage_get_folder (storage, first_separator);
|
||||
return e_storage_get_folder (storage, subpath);
|
||||
}
|
||||
|
||||
|
||||
@ -452,6 +469,50 @@ e_storage_set_new_view (EStorageSet *storage_set)
|
||||
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 *
|
||||
e_storage_set_get_folder_type_registry (EStorageSet *storage_set)
|
||||
|
@ -87,6 +87,17 @@ EFolder *e_storage_set_get_folder (EStorageSet *storage_se
|
||||
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -218,7 +218,7 @@ impl_get_name (EStorage *storage)
|
||||
}
|
||||
|
||||
static void
|
||||
impl_create_folder (EStorage *storage,
|
||||
impl_async_create_folder (EStorage *storage,
|
||||
const char *path,
|
||||
const char *type,
|
||||
const char *description,
|
||||
@ -229,7 +229,7 @@ impl_create_folder (EStorage *storage,
|
||||
}
|
||||
|
||||
static void
|
||||
impl_remove_folder (EStorage *storage,
|
||||
impl_async_remove_folder (EStorage *storage,
|
||||
const char *path,
|
||||
EStorageResultCallback callback,
|
||||
void *data)
|
||||
@ -253,8 +253,8 @@ class_init (EStorageClass *class)
|
||||
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->async_create_folder = impl_async_create_folder;
|
||||
class->async_remove_folder = impl_async_remove_folder;
|
||||
|
||||
signals[NEW_FOLDER] =
|
||||
gtk_signal_new ("new_folder",
|
||||
@ -371,7 +371,7 @@ e_storage_get_name (EStorage *storage)
|
||||
/* Folder operations. */
|
||||
|
||||
void
|
||||
e_storage_create_folder (EStorage *storage,
|
||||
e_storage_async_create_folder (EStorage *storage,
|
||||
const char *path,
|
||||
const char *type,
|
||||
const char *description,
|
||||
@ -381,14 +381,15 @@ e_storage_create_folder (EStorage *storage,
|
||||
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,
|
||||
e_storage_async_remove_folder (EStorage *storage,
|
||||
const char *path,
|
||||
EStorageResultCallback callback,
|
||||
void *data)
|
||||
@ -396,9 +397,42 @@ e_storage_remove_folder (EStorage *storage,
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
@ -80,10 +85,10 @@ struct _EStorageClass {
|
||||
EFolder * (* get_folder) (EStorage *storage, const char *path);
|
||||
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,
|
||||
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);
|
||||
};
|
||||
|
||||
@ -101,17 +106,19 @@ const char *e_storage_get_name (EStorage *storage);
|
||||
|
||||
/* Folder operations. */
|
||||
|
||||
void e_storage_create_folder (EStorage *storage,
|
||||
void e_storage_async_create_folder (EStorage *storage,
|
||||
const char *path,
|
||||
const char *type,
|
||||
const char *description,
|
||||
EStorageResultCallback callback,
|
||||
void *data);
|
||||
void e_storage_remove_folder (EStorage *storage,
|
||||
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);
|
||||
gboolean e_storage_removed_folder (EStorage *storage, const char *path);
|
||||
|
@ -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,6 +323,8 @@ init (EvolutionShellComponentClient *shell_component_client)
|
||||
EvolutionShellComponentClientPrivate *priv;
|
||||
|
||||
priv = g_new (EvolutionShellComponentClientPrivate, 1);
|
||||
priv->listener_interface = CORBA_OBJECT_NIL;
|
||||
priv->listener_servant = NULL;
|
||||
priv->callback = NULL;
|
||||
priv->callback_data = NULL;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
@ -70,17 +70,18 @@ enum _EvolutionShellComponentResult {
|
||||
};
|
||||
typedef enum _EvolutionShellComponentResult EvolutionShellComponentResult;
|
||||
|
||||
typedef EvolutionShellComponentResult (* EvolutionShellComponentCreateViewFn) (EvolutionShellComponent *shell_component,
|
||||
typedef EvolutionShellComponentResult (* EvolutionShellComponentCreateViewFn)
|
||||
(EvolutionShellComponent *shell_component,
|
||||
const char *physical_uri,
|
||||
const char *type,
|
||||
BonoboControl **control_return,
|
||||
void *closure);
|
||||
typedef EvolutionShellComponentResult (* EvolutionShellComponentCreateFolderFn) (EvolutionShellComponent *shell_component,
|
||||
typedef void (* EvolutionShellComponentCreateFolderFn) (EvolutionShellComponent *shell_component,
|
||||
const char *physical_uri,
|
||||
const char *type,
|
||||
const Evolution_ShellComponentListener listener,
|
||||
void *closure);
|
||||
typedef EvolutionShellComponentResult (* EvolutionShellComponentRemoveFolderFn) (EvolutionShellComponent *shell_component,
|
||||
typedef void (* EvolutionShellComponentRemoveFolderFn) (EvolutionShellComponent *shell_component,
|
||||
const char *physical_uri,
|
||||
const Evolution_ShellComponentListener listener,
|
||||
void *closure);
|
||||
|
Reference in New Issue
Block a user