aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shell/ChangeLog102
-rw-r--r--shell/Evolution-Storage.idl2
-rw-r--r--shell/Makefile.am4
-rw-r--r--shell/e-corba-storage-registry.c14
-rw-r--r--shell/e-corba-storage.c5
-rw-r--r--shell/e-folder.c29
-rw-r--r--shell/e-folder.h1
-rw-r--r--shell/e-local-folder.c34
-rw-r--r--shell/e-local-folder.h2
-rw-r--r--shell/e-shell.c2
-rw-r--r--shell/e-storage-set-view.c319
-rw-r--r--shell/e-storage-set.c194
-rw-r--r--shell/e-storage-set.h16
-rw-r--r--shell/e-storage.c170
-rw-r--r--shell/e-storage.h13
-rw-r--r--shell/evolution-shell-component.c12
-rw-r--r--shell/evolution-shell-component.h2
-rw-r--r--shell/evolution-storage.c395
-rw-r--r--shell/evolution-storage.h96
19 files changed, 1137 insertions, 275 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index e72c09712a..7f1746e625 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,105 @@
+2000-05-26 Ettore Perazzoli <ettore@helixcode.com>
+
+ * e-corba-storage.c (impl_StorageListener_new_folder): Set the
+ physical URI on the folder using `e_folder_set_physical_uri()'.
+
+ * e-local-folder.c (get_physical_uri): Removed.
+ (construct_loading_metadata): Use EFolder's `physical_uri' field
+ instead of ours, which is gone.
+ (save_metadata): Likewise.
+ (destroy): Don't free.
+
+ * e-local-folder.h: Removed `physical_uri' from `ELocalFolder'.
+
+ * e-folder.c: New member `physical_uri' in `EFolderPrivate'.
+ (init): Initialize to NULL.
+ (destroy): Free it.
+ (get_physical_uri): Removed.
+ (e_folder_set_physical_uri): New function.
+
+ * e-storage-set.c (e_storage_set_get_folder): Fix off-by-one error
+ in extracting the base name.
+
+ * e-storage.c: New member `path' in `Folder'.
+ (folder_destroy): Free it.
+ (folder_new): New arg. Initialize `path' from it.
+ (e_storage_construct): Updated accordingly.
+ (e_storage_new_folder): Likewise.
+ (e_storage_remove_folder): Remove the folder from the hash.
+
+ * e-storage-set-view.c (remove_node): New function.
+ (removed_storage_cb): Use it.
+ (new_folder_cb): New function, callback for the "new_folder"
+ signal on the EStorageSet.
+ (removed_folder_cb): New function, callback for the
+ "removed_folder" signal on the EStorageSet.
+ (e_storage_set_view_construct): Connect these signal handlers to
+ the respective signals on our model storage.
+
+ * e-storage-set.c (storage_new_folder_cb): New function, callback
+ for the "new_folder" signal on the storages.
+ (storage_removed_folder_cb): New function, callback for the
+ "removed_folder" signal on the storages.
+ (e_storage_set_add_storage): Connect them to the signals of the
+ storage being added.
+
+ * e-corba-storage-registry.c
+ (impl_StorageRegistry_register_storage): Throw an exception if
+ `e_storage_set_add_storage()' returns false.
+
+ * e-shell.c (setup_storages): Unref the local storage after adding
+ to the storage set.
+
+ * e-corba-storage-registry.c
+ (impl_StorageRegistry_register_storage): Unref the storage after
+ adding to the storage set.
+
+ * e-storage-set.c: New hash table `name_to_named_storage' in
+ `EStorageSetPrivate'.
+ (named_storage_new): New helper function.
+ (named_storage_destroy): New helper function.
+ (e_storage_set_add_storage): Use the hash table. Return value
+ changed to `gboolean'. Return FALSE if there is a storage with
+ that name already. Also, ref the storage.
+ (e_storage_set_remove_storage): Likewise [but of course don't ref
+ the storage].
+ (e_storage_set_get_storage): Use the `name_to_named_storage' hash
+ table.
+ (destroy): Destroy the `name_to_named_storage' hash.
+
+ * e-storage-set.h: New signals "new_folder", "removed_folder".
+
+ * e-storage.c (e_storage_get_watcher_for_path): Removed.
+ (get_watcher_for_path): Removed.
+ (class_init): Install signals "new_folder" and "removed_folder".
+ (e_storage_remove_folder): Emit "removed_folder".
+ (e_storage_new_folder): Emit "new_folder".
+
+ * e-storage.h: Removed method `get_watcher_for_path'. New signals
+ "new_folder", "removed_folder".
+
+ * e-storage-watcher.c: Removed.
+ * e-storage-watcher.h: Removed.
+
+ * e-corba-storage-registry.c (corba_class_init): Set the
+ Bonobo_Unknown evp parts.
+
+ * evolution-storage.c: New.
+ * evolution-storage.h: New.
+
+ * evolution-shell-component.c
+ (evolution_shell_component_get_owner): New.
+
+ * e-storage-set-view.c (new_storage_cb): New function.
+ (e_storage_set_view_construct): Connect to the "new_storage"
+ signal on the EStorageSet.
+ (removed_storage_cb): New function.
+ (e_storage_set_view_construct): Connect to the "removed_storage"
+ signal on the EStorageSet.
+
+ * e-storage-set-view.c (e_storage_set_view_construct): Make this
+ always look pretty, with Helix GNOME or without.
+
2000-05-25 Christopher James Lahey <clahey@helixcode.com>
* e-storage-set-view.c: Make this always look pretty, with Helix
diff --git a/shell/Evolution-Storage.idl b/shell/Evolution-Storage.idl
index d88db2f152..4e35e859bf 100644
--- a/shell/Evolution-Storage.idl
+++ b/shell/Evolution-Storage.idl
@@ -23,8 +23,6 @@ module Evolution {
interface Storage : Bonobo::Unknown {
attribute string name;
-
- void set_listener (in StorageListener storage_listener);
};
interface StorageListener {
diff --git a/shell/Makefile.am b/shell/Makefile.am
index d3f680b975..19134e59b8 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -62,12 +62,12 @@ evolution_SOURCES = \
e-storage-set-view.h \
e-storage-set.c \
e-storage-set.h \
- e-storage-watcher.c \
- e-storage-watcher.h \
e-storage.c \
e-storage.h \
evolution-shell-component.c \
evolution-shell-component.h \
+ evolution-storage.c \
+ evolution-storage.h \
main.c
Evolution-impl.o: Evolution.h
diff --git a/shell/e-corba-storage-registry.c b/shell/e-corba-storage-registry.c
index 51f845ea38..c3b259bb71 100644
--- a/shell/e-corba-storage-registry.c
+++ b/shell/e-corba-storage-registry.c
@@ -79,14 +79,23 @@ impl_StorageRegistry_register_storage (PortableServer_Servant servant,
EStorage *storage;
Evolution_StorageListener listener_interface;
+ g_print ("Shell: Registering storage -- %s\n", name);
+
bonobo_object = bonobo_object_from_servant (servant);
storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
priv = storage_registry->priv;
storage = e_corba_storage_new (storage_interface, name);
- /* FIXME check failure. */
- e_storage_set_add_storage (priv->storage_set, storage);
+ if (! e_storage_set_add_storage (priv->storage_set, storage)) {
+ CORBA_exception_set (ev,
+ CORBA_USER_EXCEPTION,
+ ex_Evolution_StorageRegistry_Exists,
+ NULL);
+ return CORBA_OBJECT_NIL;
+ }
+
+ gtk_object_unref (GTK_OBJECT (storage));
listener_interface = CORBA_Object_duplicate (e_corba_storage_get_StorageListener
(E_CORBA_STORAGE (storage)), ev);
@@ -161,6 +170,7 @@ corba_class_init (void)
vepv = &storage_registry_vepv;
vepv->_base_epv = base_epv;
+ vepv->Bonobo_Unknown_epv = bonobo_object_get_epv ();
vepv->Evolution_StorageRegistry_epv = epv;
}
diff --git a/shell/e-corba-storage.c b/shell/e-corba-storage.c
index 4048a6d272..00f1c575b0 100644
--- a/shell/e-corba-storage.c
+++ b/shell/e-corba-storage.c
@@ -109,13 +109,18 @@ impl_StorageListener_new_folder (PortableServer_Servant servant,
folder->type,
folder->description);
+ e_folder_set_physical_uri (e_folder, folder->physical_uri);
+
if (! e_storage_new_folder (storage, path, e_folder)) {
+ g_print ("Cannot register folder -- %s %s\n", path, folder->name);
CORBA_exception_set (ev,
CORBA_USER_EXCEPTION,
ex_Evolution_StorageListener_Exists,
NULL);
gtk_object_unref (GTK_OBJECT (e_folder));
}
+
+ g_print ("Folder registered successfully -- %s %s\n", path, folder->name);
}
static void
diff --git a/shell/e-folder.c b/shell/e-folder.c
index 722e865499..2e16c0896e 100644
--- a/shell/e-folder.c
+++ b/shell/e-folder.c
@@ -40,6 +40,7 @@ struct _EFolderPrivate {
char *name;
char *type;
char *description;
+ char *physical_uri;
};
#define EF_CLASS(obj) \
@@ -83,9 +84,7 @@ remove (EFolder *folder)
static const char *
get_physical_uri (EFolder *folder)
{
- g_warning ("`%s' does not implement `EFolder::get_physical_uri()'",
- gtk_type_name (GTK_OBJECT_TYPE (folder)));
- return NULL;
+ return folder->priv->physical_uri;
}
@@ -103,6 +102,7 @@ destroy (GtkObject *object)
g_free (priv->name);
g_free (priv->type);
g_free (priv->description);
+ g_free (priv->physical_uri);
g_free (priv);
@@ -141,9 +141,10 @@ init (EFolder *folder)
EFolderPrivate *priv;
priv = g_new (EFolderPrivate, 1);
- priv->type = NULL;
- priv->name = NULL;
- priv->description = NULL;
+ priv->type = NULL;
+ priv->name = NULL;
+ priv->description = NULL;
+ priv->physical_uri = NULL;
folder->priv = priv;
}
@@ -261,6 +262,20 @@ e_folder_set_description (EFolder *folder,
gtk_signal_emit (GTK_OBJECT (folder), signals[CHANGED]);
}
+void
+e_folder_set_physical_uri (EFolder *folder,
+ const char *physical_uri)
+{
+ g_return_if_fail (folder != NULL);
+ g_return_if_fail (E_IS_FOLDER (folder));
+ g_return_if_fail (physical_uri != NULL);
+
+ g_free (folder->priv->physical_uri);
+ folder->priv->physical_uri = g_strdup (physical_uri);
+
+ gtk_signal_emit (GTK_OBJECT (folder), signals[CHANGED]);
+}
+
const char *
e_folder_get_physical_uri (EFolder *folder)
@@ -268,7 +283,7 @@ e_folder_get_physical_uri (EFolder *folder)
g_return_val_if_fail (folder != NULL, NULL);
g_return_val_if_fail (E_IS_FOLDER (folder), NULL);
- return (* EF_CLASS (folder)->get_physical_uri) (folder);
+ return folder->priv->physical_uri;
}
diff --git a/shell/e-folder.h b/shell/e-folder.h
index cf49c68864..d7bbd6ba9e 100644
--- a/shell/e-folder.h
+++ b/shell/e-folder.h
@@ -84,6 +84,7 @@ const char *e_folder_get_description (EFolder *folder);
void e_folder_set_name (EFolder *folder, const char *name);
void e_folder_set_type_string (EFolder *folder, const char *type);
void e_folder_set_description (EFolder *folder, const char *description);
+void e_folder_set_physical_uri (EFolder *folder, const char *physical_uri);
#ifdef __cplusplus
}
diff --git a/shell/e-local-folder.c b/shell/e-local-folder.c
index b164eb1e95..23cd106390 100644
--- a/shell/e-local-folder.c
+++ b/shell/e-local-folder.c
@@ -56,6 +56,10 @@ static EFolderClass *parent_class = NULL;
#define METADATA_FILE_NAME "folder-metadata.xml"
#define METADATA_FILE_NAME_LEN 19
+struct _ELocalFolderPrivate {
+ int dummy;
+};
+
static char *
get_string_value (xmlNode *node,
@@ -90,6 +94,7 @@ construct_loading_metadata (ELocalFolder *local_folder,
char *type;
char *description;
char *metadata_path;
+ char *physical_uri;
folder = E_FOLDER (local_folder);
@@ -118,7 +123,9 @@ construct_loading_metadata (ELocalFolder *local_folder,
xmlFreeDoc (doc);
- local_folder->physical_uri = g_strconcat (URI_PREFIX, path, NULL);
+ physical_uri = g_strconcat (URI_PREFIX, path, NULL);
+ e_folder_set_physical_uri (folder, physical_uri);
+ g_free (physical_uri);
g_free (metadata_path);
@@ -142,7 +149,7 @@ save_metadata (ELocalFolder *local_folder)
xmlNewChild (root, NULL, (xmlChar *) "type", (xmlChar *) e_folder_get_type_string (folder));
xmlNewChild (root, NULL, (xmlChar *) "description", (xmlChar *) e_folder_get_description (folder));
- physical_path = local_folder->physical_uri + URI_PREFIX_LEN - 1;
+ physical_path = e_folder_get_physical_uri (folder) + URI_PREFIX_LEN - 1;
if (xmlSaveFile (physical_path, doc) < 0) {
xmlFreeDoc (doc);
@@ -154,28 +161,12 @@ save_metadata (ELocalFolder *local_folder)
}
-/* EFolder methods. */
-
-static const char *
-get_physical_uri (EFolder *folder)
-{
- ELocalFolder *local_folder;
-
- local_folder = E_LOCAL_FOLDER (folder);
- return local_folder->physical_uri;
-}
-
-
/* GtkObject methods. */
static void
destroy (GtkObject *object)
{
- ELocalFolder *folder;
-
- folder = E_LOCAL_FOLDER (object);
-
- g_free (folder->physical_uri);
+ /* No ELocalFolder-specific data to free. */
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
@@ -185,21 +176,16 @@ static void
class_init (ELocalFolderClass *klass)
{
GtkObjectClass *object_class;
- EFolderClass *folder_class;
parent_class = gtk_type_class (e_folder_get_type ());
object_class = GTK_OBJECT_CLASS (klass);
object_class->destroy = destroy;
-
- folder_class = E_FOLDER_CLASS (klass);
- folder_class->get_physical_uri = get_physical_uri;
}
static void
init (ELocalFolder *local_folder)
{
- local_folder->physical_uri = NULL;
}
diff --git a/shell/e-local-folder.h b/shell/e-local-folder.h
index 6092532791..b30a9f2a5c 100644
--- a/shell/e-local-folder.h
+++ b/shell/e-local-folder.h
@@ -48,8 +48,6 @@ typedef struct _ELocalFolderClass ELocalFolderClass;
struct _ELocalFolder {
EFolder parent;
-
- char *physical_uri;
};
struct _ELocalFolderClass {
diff --git a/shell/e-shell.c b/shell/e-shell.c
index ca1c44f576..ec61116534 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -165,6 +165,8 @@ setup_storages (EShell *shell)
priv->storage_set = e_storage_set_new (shell->priv->folder_type_registry);
e_storage_set_add_storage (priv->storage_set, local_storage);
+ gtk_object_unref (GTK_OBJECT (local_storage));
+
return setup_corba_storages (shell);
}
diff --git a/shell/e-storage-set-view.c b/shell/e-storage-set-view.c
index 5b5a11972a..95559e184a 100644
--- a/shell/e-storage-set-view.c
+++ b/shell/e-storage-set-view.c
@@ -90,6 +90,122 @@ static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
static GtkTargetList *target_list;
+/* Helper functions. */
+
+static gboolean
+add_node_to_hashes (EStorageSetView *storage_set_view,
+ const char *path,
+ GtkCTreeNode *node)
+{
+ EStorageSetViewPrivate *priv;
+ char *hash_path;
+
+ g_return_val_if_fail (g_path_is_absolute (path), FALSE);
+
+ priv = storage_set_view->priv;
+
+ if (g_hash_table_lookup (priv->path_to_ctree_node, path) != NULL) {
+ g_warning ("EStorageSetView: Node already existing while adding -- %s", path);
+ return FALSE;
+ }
+
+ g_print ("EStorageSetView: Adding -- %s\n", path);
+
+ hash_path = g_strdup (path);
+
+ g_hash_table_insert (priv->path_to_ctree_node, hash_path, node);
+ g_hash_table_insert (priv->ctree_node_to_path, node, hash_path);
+
+ return TRUE;
+}
+
+static GtkCTreeNode *
+remove_node_from_hashes (EStorageSetView *storage_set_view,
+ const char *path)
+{
+ EStorageSetViewPrivate *priv;
+ GtkCTreeNode *node;
+ char *hash_path;
+
+ priv = storage_set_view->priv;
+
+ node = g_hash_table_lookup (priv->path_to_ctree_node, path);
+ if (node == NULL) {
+ g_warning ("EStorageSetView: Node not found while removing -- %s", path);
+ return NULL;
+ }
+
+ g_print ("EStorageSetView: Removing -- %s\n", path);
+
+ hash_path = g_hash_table_lookup (priv->ctree_node_to_path, node);
+ g_free (hash_path);
+
+ g_hash_table_remove (priv->ctree_node_to_path, node);
+ g_hash_table_remove (priv->path_to_ctree_node, path);
+
+ return node;
+}
+
+static void
+get_pixmap_and_mask_for_folder (EStorageSetView *storage_set_view,
+ EFolder *folder,
+ GdkPixmap **pixmap_return,
+ GdkBitmap **mask_return)
+{
+ EFolderTypeRegistry *folder_type_registry;
+ EStorageSet *storage_set;
+ const char *type_name;
+ GdkPixbuf *icon_pixbuf;
+ GdkPixbuf *scaled_pixbuf;
+ GdkVisual *visual;
+ GdkGC *gc;
+
+ storage_set = storage_set_view->priv->storage_set;
+ folder_type_registry = e_storage_set_get_folder_type_registry (storage_set);
+
+ type_name = e_folder_get_type_string (folder);
+ icon_pixbuf = e_folder_type_registry_get_icon_for_type (folder_type_registry,
+ type_name, TRUE);
+
+ if (icon_pixbuf == NULL) {
+ *pixmap_return = NULL;
+ *mask_return = NULL;
+ return;
+ }
+
+ scaled_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (icon_pixbuf),
+ gdk_pixbuf_get_has_alpha (icon_pixbuf),
+ gdk_pixbuf_get_bits_per_sample (icon_pixbuf),
+ E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE);
+
+ gdk_pixbuf_scale (icon_pixbuf, scaled_pixbuf,
+ 0, 0, E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
+ 0.0, 0.0,
+ (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_width (icon_pixbuf),
+ (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_height (icon_pixbuf),
+ GDK_INTERP_HYPER);
+
+ visual = gdk_rgb_get_visual ();
+ *pixmap_return = gdk_pixmap_new (NULL,
+ E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
+ visual->depth);
+
+ gc = gdk_gc_new (*pixmap_return);
+ gdk_pixbuf_render_to_drawable (scaled_pixbuf, *pixmap_return, gc, 0, 0, 0, 0,
+ E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+ gdk_gc_unref (gc);
+
+ *mask_return = gdk_pixmap_new (NULL, E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE, 1);
+ gdk_pixbuf_render_threshold_alpha (scaled_pixbuf, *mask_return,
+ 0, 0, 0, 0,
+ E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
+ 0x7f);
+
+ gdk_pixbuf_unref (scaled_pixbuf);
+}
+
+
/* GtkObject methods. */
static void
@@ -317,6 +433,134 @@ drag_data_get (GtkWidget *widget,
}
+/* StorageSet signal handling. */
+
+static void
+new_storage_cb (EStorageSet *storage_set,
+ EStorage *storage,
+ void *data)
+{
+ EStorageSetView *storage_set_view;
+ EStorageSetViewPrivate *priv;
+ GtkCTreeNode *node;
+ char *text[2];
+ char *path;
+
+ storage_set_view = E_STORAGE_SET_VIEW (data);
+ priv = storage_set_view->priv;
+
+ path = g_strconcat (G_DIR_SEPARATOR_S, e_storage_get_name (storage), NULL);
+
+ text[0] = (char *) e_storage_get_name (storage); /* Yuck. */
+ text[1] = NULL;
+
+ node = gtk_ctree_insert_node (GTK_CTREE (storage_set_view), NULL, NULL,
+ text, 3, NULL, NULL, NULL, NULL, FALSE, TRUE);
+
+ if (! add_node_to_hashes (storage_set_view, path, node)) {
+ g_free (path);
+ gtk_ctree_remove_node (GTK_CTREE (storage_set_view), node);
+ return;
+ }
+
+ g_free (path);
+
+ /* FIXME: We want a more specialized sort, e.g. the local folders should always be
+ on top. */
+ gtk_ctree_sort_node (GTK_CTREE (storage_set_view), NULL);
+}
+
+static void
+removed_storage_cb (EStorageSet *storage_set,
+ EStorage *storage,
+ void *data)
+{
+ EStorageSetView *storage_set_view;
+ EStorageSetViewPrivate *priv;
+ GtkCTreeNode *node;
+ char *path;
+
+ storage_set_view = E_STORAGE_SET_VIEW (data);
+ priv = storage_set_view->priv;
+
+ path = g_strconcat (G_DIR_SEPARATOR_S, e_storage_get_name (storage), NULL);
+ node = remove_node_from_hashes (storage_set_view, path);
+ g_free (path);
+
+ gtk_ctree_remove_node (GTK_CTREE (storage_set_view), node);
+}
+
+static void
+new_folder_cb (EStorageSet *storage_set,
+ const char *path,
+ void *data)
+{
+ EStorageSetView *storage_set_view;
+ EStorageSetViewPrivate *priv;
+ GtkCTreeNode *parent_node;
+ GtkCTreeNode *node;
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+ char *text[2];
+ const char *last_separator;
+ char *parent_path;
+
+ g_return_if_fail (g_path_is_absolute (path));
+
+ storage_set_view = E_STORAGE_SET_VIEW (data);
+ priv = storage_set_view->priv;
+
+ last_separator = strrchr (path, G_DIR_SEPARATOR);
+
+ parent_path = g_strndup (path, last_separator - path);
+ parent_node = g_hash_table_lookup (priv->path_to_ctree_node, parent_path);
+ if (parent_node == NULL) {
+ g_print ("EStorageSetView: EStorageSet reported new subfolder for non-existing folder -- %s\n",
+ parent_path);
+ g_free (parent_path);
+ return;
+ }
+
+ g_free (parent_path);
+
+ if (parent_node == NULL)
+ return;
+
+ text[0] = (char *) last_separator + 1; /* Yuck. */
+ text[1] = NULL;
+
+ get_pixmap_and_mask_for_folder (storage_set_view,
+ e_storage_set_get_folder (storage_set, path),
+ &pixmap, &mask);
+ node = gtk_ctree_insert_node (GTK_CTREE (storage_set_view),
+ parent_node, NULL,
+ text, 3,
+ pixmap, mask, pixmap, mask,
+ FALSE, TRUE);
+
+ if (! add_node_to_hashes (storage_set_view, path, node)) {
+ gtk_ctree_remove_node (GTK_CTREE (storage_set_view), node);
+ return;
+ }
+
+ gtk_ctree_sort_node (GTK_CTREE (storage_set_view), parent_node);
+}
+
+static void
+removed_folder_cb (EStorageSet *storage_set,
+ const char *path,
+ void *data)
+{
+ EStorageSetView *storage_set_view;
+ GtkCTreeNode *node;
+
+ storage_set_view = E_STORAGE_SET_VIEW (data);
+
+ node = remove_node_from_hashes (storage_set_view, path);
+ gtk_ctree_remove_node (GTK_CTREE (storage_set_view), node);
+}
+
+
/* GtkCTree methods. */
static void
@@ -402,65 +646,6 @@ init (EStorageSetView *storage_set_view)
}
-static void
-get_pixmap_and_mask_for_folder (EStorageSetView *storage_set_view,
- EFolder *folder,
- GdkPixmap **pixmap_return,
- GdkBitmap **mask_return)
-{
- EFolderTypeRegistry *folder_type_registry;
- EStorageSet *storage_set;
- const char *type_name;
- GdkPixbuf *icon_pixbuf;
- GdkPixbuf *scaled_pixbuf;
- GdkVisual *visual;
- GdkGC *gc;
-
- storage_set = storage_set_view->priv->storage_set;
- folder_type_registry = e_storage_set_get_folder_type_registry (storage_set);
-
- type_name = e_folder_get_type_string (folder);
- icon_pixbuf = e_folder_type_registry_get_icon_for_type (folder_type_registry,
- type_name, TRUE);
-
- if (icon_pixbuf == NULL) {
- *pixmap_return = NULL;
- *mask_return = NULL;
- return;
- }
-
- scaled_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (icon_pixbuf),
- gdk_pixbuf_get_has_alpha (icon_pixbuf),
- gdk_pixbuf_get_bits_per_sample (icon_pixbuf),
- E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE);
-
- gdk_pixbuf_scale (icon_pixbuf, scaled_pixbuf,
- 0, 0, E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
- 0.0, 0.0,
- (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_width (icon_pixbuf),
- (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_height (icon_pixbuf),
- GDK_INTERP_HYPER);
-
- visual = gdk_rgb_get_visual ();
- *pixmap_return = gdk_pixmap_new (NULL,
- E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
- visual->depth);
-
- gc = gdk_gc_new (*pixmap_return);
- gdk_pixbuf_render_to_drawable (scaled_pixbuf, *pixmap_return, gc, 0, 0, 0, 0,
- E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
- GDK_RGB_DITHER_NORMAL, 0, 0);
- gdk_gc_unref (gc);
-
- *mask_return = gdk_pixmap_new (NULL, E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE, 1);
- gdk_pixbuf_render_threshold_alpha (scaled_pixbuf, *mask_return,
- 0, 0, 0, 0,
- E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
- 0x7f);
-
- gdk_pixbuf_unref (scaled_pixbuf);
-}
-
static int
folder_compare_cb (gconstpointer a, gconstpointer b)
{
@@ -519,7 +704,6 @@ insert_folders (EStorageSetView *storage_set_view,
text[1] = NULL;
get_pixmap_and_mask_for_folder (storage_set_view, folder, &pixmap, &mask);
-
node = gtk_ctree_insert_node (ctree, parent, NULL,
text, 3,
pixmap, mask, pixmap, mask,
@@ -561,9 +745,9 @@ e_storage_set_view_construct (EStorageSetView *storage_set_view,
/* Set up GtkCTree/GtkCList parameters. */
gtk_ctree_construct (ctree, 1, 0, NULL);
- /* This looks ugly with Helix GNOME unless we do this. */
- gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_NONE);
- gtk_ctree_set_expander_style (ctree, GTK_CTREE_EXPANDER_TRIANGLE);
+
+ gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
+ gtk_ctree_set_expander_style (ctree, GTK_CTREE_EXPANDER_SQUARE);
gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_BROWSE);
gtk_clist_set_row_height (GTK_CLIST (ctree), E_SHELL_MINI_ICON_SIZE);
@@ -571,6 +755,15 @@ e_storage_set_view_construct (EStorageSetView *storage_set_view,
gtk_object_ref (GTK_OBJECT (storage_set));
priv->storage_set = storage_set;
+
+ gtk_signal_connect (GTK_OBJECT (storage_set), "new_storage",
+ GTK_SIGNAL_FUNC (new_storage_cb), storage_set_view);
+ gtk_signal_connect (GTK_OBJECT (storage_set), "removed_storage",
+ GTK_SIGNAL_FUNC (removed_storage_cb), storage_set_view);
+ gtk_signal_connect (GTK_OBJECT (storage_set), "new_folder",
+ GTK_SIGNAL_FUNC (new_folder_cb), storage_set_view);
+ gtk_signal_connect (GTK_OBJECT (storage_set), "removed_folder",
+ GTK_SIGNAL_FUNC (removed_folder_cb), storage_set_view);
storage_list = e_storage_set_get_storage_list (storage_set);
diff --git a/shell/e-storage-set.c b/shell/e-storage-set.c
index d1adec19ce..7a71f518fe 100644
--- a/shell/e-storage-set.c
+++ b/shell/e-storage-set.c
@@ -37,23 +37,107 @@
#include "e-storage-set.h"
+#define PARENT_TYPE GTK_TYPE_OBJECT
+
+static GtkObjectClass *parent_class = NULL;
+
+/* This is just to make GHashTable happy. */
+struct _NamedStorage {
+ char *name;
+ EStorage *storage;
+};
+typedef struct _NamedStorage NamedStorage;
+
+struct _EStorageSetPrivate {
+ GList *storages;
+ GHashTable *name_to_named_storage;
+
+ EFolderTypeRegistry *folder_type_registry;
+};
+
enum {
NEW_STORAGE,
REMOVED_STORAGE,
+ NEW_FOLDER,
+ REMOVED_FOLDER,
LAST_SIGNAL
};
+static guint signals[LAST_SIGNAL] = { 0 };
+
-#define PARENT_TYPE GTK_TYPE_OBJECT
+static NamedStorage *
+named_storage_new (EStorage *storage)
+{
+ NamedStorage *new;
-static GtkObjectClass *parent_class = NULL;
-static guint signals[LAST_SIGNAL] = { 0 };
+ new = g_new (NamedStorage, 1);
+ new->name = g_strdup (e_storage_get_name (storage));
+ new->storage = storage;
-struct _EStorageSetPrivate {
- GList *storages;
+ return new;
+}
- EFolderTypeRegistry *folder_type_registry;
-};
+static void
+named_storage_destroy (NamedStorage *named_storage)
+{
+ g_free (named_storage->name);
+ g_free (named_storage);
+}
+
+
+/* Handling for signals coming from the EStorages. */
+
+static char *
+make_full_path (EStorage *storage,
+ const char *path)
+{
+ const char *storage_name;
+ char *full_path;
+
+ storage_name = e_storage_get_name (storage);
+
+ if (! g_path_is_absolute (path))
+ full_path = g_strconcat (G_DIR_SEPARATOR_S, storage_name,
+ G_DIR_SEPARATOR_S, path, NULL);
+ else
+ full_path = g_strconcat (G_DIR_SEPARATOR_S, storage_name,
+ path, NULL);
+
+ return full_path;
+}
+
+static void
+storage_new_folder_cb (EStorage *storage,
+ const char *path,
+ void *data)
+{
+ EStorageSet *storage_set;
+ char *full_path;
+
+ storage_set = E_STORAGE_SET (data);
+
+ full_path = make_full_path (storage, path);
+ g_print ("EStorageSet: New folder -- %s\n", full_path);
+ gtk_signal_emit (GTK_OBJECT (storage_set), signals[NEW_FOLDER], full_path);
+ g_free (full_path);
+}
+
+static void
+storage_removed_folder_cb (EStorage *storage,
+ const char *path,
+ void *data)
+{
+ EStorageSet *storage_set;
+ char *full_path;
+
+ storage_set = E_STORAGE_SET (data);
+
+ full_path = make_full_path (storage, path);
+ g_print ("EStorageSet: Removed folder -- %s\n", full_path);
+ gtk_signal_emit (GTK_OBJECT (storage_set), signals[REMOVED_FOLDER], full_path);
+ g_free (full_path);
+}
/* GtkObject methods. */
@@ -71,6 +155,9 @@ destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT (priv->folder_type_registry));
+ g_hash_table_foreach (priv->name_to_named_storage, (GHFunc) named_storage_destroy, NULL);
+ g_hash_table_destroy (priv->name_to_named_storage);
+
g_free (priv);
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
@@ -104,6 +191,22 @@ class_init (EStorageSetClass *klass)
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_POINTER);
+ signals[NEW_FOLDER] =
+ gtk_signal_new ("new_folder",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (EStorageSetClass, new_folder),
+ gtk_marshal_NONE__STRING,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_STRING);
+ signals[REMOVED_FOLDER] =
+ gtk_signal_new ("removed_folder",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (EStorageSetClass, removed_folder),
+ gtk_marshal_NONE__STRING,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_STRING);
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
@@ -114,9 +217,9 @@ init (EStorageSet *storage_set)
EStorageSetPrivate *priv;
priv = g_new (EStorageSetPrivate, 1);
-
- priv->storages = NULL;
- priv->folder_type_registry = NULL;
+ priv->storages = NULL;
+ priv->name_to_named_storage = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->folder_type_registry = NULL;
storage_set->priv = priv;
}
@@ -174,45 +277,72 @@ e_storage_set_get_storage_list (EStorageSet *storage_set)
* @storage_set:
* @storage:
*
- * Add @storage to @storage_set. Notice that this won't ref the @storage, so
- * after the call @storage_set actually owns @storage.
+ * Add @storage to @storage_set. Notice that will ref the storage.
**/
-void
+gboolean
e_storage_set_add_storage (EStorageSet *storage_set,
EStorage *storage)
{
EStorageSetPrivate *priv;
+ const char *storage_name;
+ NamedStorage *named_storage;
- g_return_if_fail (storage_set != NULL);
- g_return_if_fail (E_IS_STORAGE_SET (storage_set));
- g_return_if_fail (storage != NULL);
- g_return_if_fail (E_IS_STORAGE (storage));
+ g_return_val_if_fail (storage_set != NULL, FALSE);
+ g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), FALSE);
+ g_return_val_if_fail (storage != NULL, FALSE);
+ g_return_val_if_fail (E_IS_STORAGE (storage), FALSE);
priv = storage_set->priv;
+ storage_name = e_storage_get_name (storage);
+ if (g_hash_table_lookup (priv->name_to_named_storage, storage_name) != NULL)
+ return FALSE;
+
+ gtk_object_ref (GTK_OBJECT (storage));
+
+ gtk_signal_connect (GTK_OBJECT (storage), "new_folder",
+ GTK_SIGNAL_FUNC (storage_new_folder_cb), storage_set);
+ gtk_signal_connect (GTK_OBJECT (storage), "removed_folder",
+ GTK_SIGNAL_FUNC (storage_removed_folder_cb), storage_set);
+
priv->storages = g_list_append (priv->storages, storage);
+ named_storage = named_storage_new (storage);
+ g_hash_table_insert (priv->name_to_named_storage, named_storage->name, named_storage);
+
gtk_signal_emit (GTK_OBJECT (storage_set), signals[NEW_STORAGE], storage);
+
+ return TRUE;
}
-void
+gboolean
e_storage_set_remove_storage (EStorageSet *storage_set,
EStorage *storage)
{
EStorageSetPrivate *priv;
+ NamedStorage *named_storage;
- g_return_if_fail (storage_set != NULL);
- g_return_if_fail (E_IS_STORAGE_SET (storage_set));
- g_return_if_fail (storage != NULL);
- g_return_if_fail (E_IS_STORAGE (storage));
+ g_return_val_if_fail (storage_set != NULL, FALSE);
+ g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), FALSE);
+ g_return_val_if_fail (storage != NULL, FALSE);
+ g_return_val_if_fail (E_IS_STORAGE (storage), FALSE);
priv = storage_set->priv;
+ named_storage = g_hash_table_lookup (priv->name_to_named_storage,
+ e_storage_get_name (storage));
+ if (named_storage == NULL)
+ return FALSE;
+
+ g_hash_table_remove (priv->name_to_named_storage, named_storage->name);
+ named_storage_destroy (named_storage);
+
priv->storages = g_list_remove (priv->storages, storage);
gtk_signal_emit (GTK_OBJECT (storage_set), signals[REMOVED_STORAGE], storage);
-
gtk_object_unref (GTK_OBJECT (storage));
+
+ return TRUE;
}
EStorage *
@@ -220,7 +350,7 @@ e_storage_set_get_storage (EStorageSet *storage_set,
const char *name)
{
EStorageSetPrivate *priv;
- GList *p;
+ NamedStorage *named_storage;
g_return_val_if_fail (storage_set != NULL, NULL);
g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL);
@@ -228,17 +358,11 @@ e_storage_set_get_storage (EStorageSet *storage_set,
priv = storage_set->priv;
- for (p = priv->storages; p != NULL; p = p->next) {
- const char *storage_name;
- EStorage *storage;
-
- storage = E_STORAGE (p->data);
- storage_name = e_storage_get_name (storage);
- if (strcmp (storage_name, name) == 0)
- return storage;
- }
-
- return NULL;
+ named_storage = g_hash_table_lookup (priv->name_to_named_storage, name);
+ if (named_storage == NULL)
+ return NULL;
+ else
+ return named_storage->storage;
}
EFolder *
diff --git a/shell/e-storage-set.h b/shell/e-storage-set.h
index 500f3c31de..e41471764d 100644
--- a/shell/e-storage-set.h
+++ b/shell/e-storage-set.h
@@ -58,15 +58,13 @@ struct _EStorageSet {
struct _EStorageSetClass {
GtkObjectClass parent_class;
- /* Virtual methods. */
-
- void (* add_storage) (EStorageSet *storage_set, EStorage *storage);
- void (* remove_storage) (EStorageSet *storage_set, EStorage *storage);
-
/* Signals. */
- void (* new_storage) (EStorageSet *storage_set, EStorage *storage);
- void (* removed_storage) (EStorageSet *storage_set, EStorage *storage);
+ void (* new_storage) (EStorageSet *storage_set, EStorage *storage);
+ void (* removed_storage) (EStorageSet *storage_set, EStorage *storage);
+ /* FIXME? Inconsistency between storage and folders. */
+ void (* new_folder) (EStorageSet *storage_set, const char *path);
+ void (* removed_folder) (EStorageSet *storage_set, const char *path);
};
@@ -75,9 +73,9 @@ void e_storage_set_construct (EStorageSet *storage_set,
EFolderTypeRegistry *folder_type_registry);
EStorageSet *e_storage_set_new (EFolderTypeRegistry *folder_type_registry);
-void e_storage_set_add_storage (EStorageSet *storage_set,
+gboolean e_storage_set_add_storage (EStorageSet *storage_set,
EStorage *storage);
-void e_storage_set_remove_storage (EStorageSet *storage_set,
+gboolean e_storage_set_remove_storage (EStorageSet *storage_set,
EStorage *storage);
GList *e_storage_set_get_storage_list (EStorageSet *storage_set);
diff --git a/shell/e-storage.c b/shell/e-storage.c
index 974626e7b8..98ce48da70 100644
--- a/shell/e-storage.c
+++ b/shell/e-storage.c
@@ -41,35 +41,37 @@ static GtkObjectClass *parent_class = NULL;
#define ES_CLASS(obj) \
E_STORAGE_CLASS (GTK_OBJECT (obj)->klass)
-struct _WatcherList {
- char *path;
- GList *watchers;
-};
-typedef struct _WatcherList WatcherList;
-
/* This describes a folder and its children. */
struct _Folder {
struct _Folder *parent;
+
+ char *path;
EFolder *e_folder;
GList *subfolders;
};
typedef struct _Folder Folder;
struct _EStoragePrivate {
- GHashTable *path_to_watcher_list;
- GHashTable *watcher_to_watcher_list;
+ GHashTable *path_to_folder; /* Folder */
+};
- /* Every element here is a list of subfolders, hashed to the path of the parent. */
- GHashTable *path_to_folder;
+enum {
+ NEW_FOLDER,
+ REMOVED_FOLDER,
+ LAST_SIGNAL
};
+static guint signals[LAST_SIGNAL] = { 0 };
+
static Folder *
-folder_new (EFolder *e_folder)
+folder_new (EFolder *e_folder,
+ const char *path)
{
Folder *folder;
folder = g_new (Folder, 1);
+ folder->path = g_strdup (path);
folder->parent = NULL;
folder->e_folder = e_folder;
folder->subfolders = NULL;
@@ -98,6 +100,8 @@ folder_destroy (Folder *folder)
if (folder->parent != NULL)
folder_remove_subfolder (folder->parent, folder);
+ g_free (folder->path);
+
gtk_object_unref (GTK_OBJECT (folder->e_folder));
for (p = folder->subfolders; p != NULL; p = p->next)
@@ -106,62 +110,6 @@ folder_destroy (Folder *folder)
g_free (folder);
}
-
-/* Watcher management. */
-
-static void
-watcher_destroyed_cb (GtkObject *object,
- gpointer data)
-{
- EStorageWatcher *watcher;
- EStorage *storage;
- EStoragePrivate *priv;
- WatcherList *list;
-
- watcher = E_STORAGE_WATCHER (object);
- storage = E_STORAGE (data);
- priv = storage->priv;
-
- list = g_hash_table_lookup (priv->watcher_to_watcher_list, watcher);
- g_return_if_fail (list != NULL);
-
- list->watchers = g_list_remove (list->watchers, watcher);
-}
-
-static void
-free_watcher_list (EStorage *storage,
- WatcherList *watcher_list)
-{
- GtkObject *watcher_object;
- GList *p;
-
- for (p = watcher_list->watchers; p != NULL; p = p->next) {
- watcher_object = GTK_OBJECT (p->data);
- gtk_signal_disconnect_by_func (watcher_object, watcher_destroyed_cb, storage);
-
- gtk_object_destroy (watcher_object); /* Make sure it does not live when we are dead. */
- gtk_object_unref (watcher_object);
- }
-
- g_free (watcher_list->path);
-
- g_free (watcher_list);
-}
-
-static void
-hash_foreach_free_watcher_list (gpointer key,
- gpointer value,
- gpointer data)
-{
- WatcherList *watcher_list;
- EStorage *storage;
-
- storage = E_STORAGE (data);
- watcher_list = (WatcherList *) value;
-
- free_watcher_list (storage, watcher_list);
-}
-
static void
free_private (EStorage *storage)
{
@@ -169,10 +117,9 @@ free_private (EStorage *storage)
priv = storage->priv;
- g_hash_table_foreach (priv->path_to_watcher_list, hash_foreach_free_watcher_list, storage);
- g_hash_table_destroy (priv->path_to_watcher_list);
+ g_hash_table_foreach (priv->path_to_folder, (GHFunc) folder_destroy, NULL);
- g_hash_table_destroy (priv->watcher_to_watcher_list);
+ g_hash_table_destroy (priv->path_to_folder);
g_free (priv);
}
@@ -204,37 +151,6 @@ list_folders (EStorage *storage,
return list;
}
-static EStorageWatcher *
-get_watcher_for_path (EStorage *storage,
- const char *path)
-{
- EStoragePrivate *priv;
- EStorageWatcher *watcher;
- WatcherList *watcher_list;
-
- priv = storage->priv;
-
- watcher = e_storage_watcher_new (storage, path);
-
- watcher_list = g_hash_table_lookup (priv->path_to_watcher_list, path);
- if (watcher_list == NULL) {
- watcher_list = g_new (WatcherList, 1);
- watcher_list->path = g_strdup (path);
- watcher_list->watchers = NULL;
-
- g_hash_table_insert (priv->path_to_watcher_list, watcher_list->path, watcher_list);
- }
-
- g_hash_table_insert (priv->watcher_to_watcher_list, watcher, watcher_list);
-
- watcher_list->watchers = g_list_prepend (watcher_list->watchers, watcher);
-
- gtk_signal_connect (GTK_OBJECT (watcher), "destroy",
- GTK_SIGNAL_FUNC (watcher_destroyed_cb), storage);
-
- return watcher;
-}
-
static EFolder *
get_folder (EStorage *storage,
const char *path)
@@ -286,9 +202,27 @@ class_init (EStorageClass *class)
object_class->destroy = destroy;
class->list_folders = list_folders;
- class->get_watcher_for_path = get_watcher_for_path;
class->get_folder = get_folder;
class->get_name = get_name;
+
+ signals[NEW_FOLDER] =
+ gtk_signal_new ("new_folder",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (EStorageClass, new_folder),
+ gtk_marshal_NONE__STRING,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_STRING);
+ signals[REMOVED_FOLDER] =
+ gtk_signal_new ("removed_folder",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (EStorageClass, removed_folder),
+ gtk_marshal_NONE__STRING,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_STRING);
+
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
static void
@@ -297,10 +231,7 @@ init (EStorage *storage)
EStoragePrivate *priv;
priv = g_new (EStoragePrivate, 1);
-
- priv->path_to_watcher_list = g_hash_table_new (g_str_hash, g_str_equal);
- priv->watcher_to_watcher_list = g_hash_table_new (g_direct_hash, g_direct_equal);
- priv->path_to_folder = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->path_to_folder = g_hash_table_new (g_str_hash, g_str_equal);
storage->priv = priv;
}
@@ -318,8 +249,8 @@ e_storage_construct (EStorage *storage)
GTK_OBJECT_UNSET_FLAGS (GTK_OBJECT (storage), GTK_FLOATING);
- root_folder = folder_new (NULL);
- g_hash_table_insert (storage->priv->path_to_folder, G_DIR_SEPARATOR_S, root_folder);
+ root_folder = folder_new (NULL, G_DIR_SEPARATOR_S);
+ g_hash_table_insert (storage->priv->path_to_folder, root_folder->path, root_folder);
}
EStorage *
@@ -364,17 +295,6 @@ e_storage_list_folders (EStorage *storage,
return (* ES_CLASS (storage)->list_folders) (storage, path);
}
-EStorageWatcher *
-e_storage_get_watcher_for_path (EStorage *storage, const char *path)
-{
- g_return_val_if_fail (storage != NULL, NULL);
- g_return_val_if_fail (E_IS_STORAGE (storage), NULL);
- g_return_val_if_fail (path != NULL, NULL);
- g_return_val_if_fail (e_storage_path_is_absolute (path), NULL);
-
- return (* ES_CLASS (storage)->get_watcher_for_path) (storage, path);
-}
-
EFolder *
e_storage_get_folder (EStorage *storage,
const char *path)
@@ -440,10 +360,15 @@ e_storage_new_folder (EStorage *storage,
return FALSE;
}
- folder = folder_new (e_folder);
+ folder = folder_new (e_folder, full_path);
folder_add_subfolder (parent_folder, folder);
- g_hash_table_insert (priv->path_to_folder, full_path, folder);
+ g_hash_table_insert (priv->path_to_folder, folder->path, folder);
+
+ g_print ("EStorage: New folder -- %s\n", folder->path);
+ gtk_signal_emit (GTK_OBJECT (storage), signals[NEW_FOLDER], folder->path);
+
+ g_free (full_path);
return TRUE;
}
@@ -468,6 +393,9 @@ e_storage_remove_folder (EStorage *storage,
return FALSE;
}
+ gtk_signal_emit (GTK_OBJECT (storage), signals[REMOVED_FOLDER], path);
+
+ g_hash_table_remove (priv->path_to_folder, path);
folder_destroy (folder);
return TRUE;
diff --git a/shell/e-storage.h b/shell/e-storage.h
index 2639497854..478feef5a6 100644
--- a/shell/e-storage.h
+++ b/shell/e-storage.h
@@ -47,7 +47,6 @@ typedef struct _EStoragePrivate EStoragePrivate;
typedef struct _EStorageClass EStorageClass;
#include "e-folder.h"
-#include "e-storage-watcher.h"
struct _EStorage {
GtkObject parent;
@@ -58,11 +57,14 @@ struct _EStorage {
struct _EStorageClass {
GtkObjectClass parent_class;
+ /* Signals. */
+ void * (* new_folder) (EStorage *storage, const char *path);
+ void * (* removed_folder) (EStorage *storage, const char *path);
+
/* Virtual methods. */
- GList * (* list_folders) (EStorage *storage, const char *path);
- EStorageWatcher * (* get_watcher_for_path) (EStorage *storage, const char *path);
- EFolder * (* get_folder) (EStorage *storage, const char *path);
- const char * (* get_name) (EStorage *storage);
+ GList * (* list_folders) (EStorage *storage, const char *path);
+ EFolder * (* get_folder) (EStorage *storage, const char *path);
+ const char * (* get_name) (EStorage *storage);
};
@@ -74,7 +76,6 @@ gboolean e_storage_path_is_relative (const char *path);
gboolean e_storage_path_is_absolute (const char *path);
GList *e_storage_list_folders (EStorage *storage, const char *path);
-EStorageWatcher *e_storage_get_watcher_for_path (EStorage *storage, const char *path);
EFolder *e_storage_get_folder (EStorage *storage, const char *path);
const char *e_storage_get_name (EStorage *storage);
diff --git a/shell/evolution-shell-component.c b/shell/evolution-shell-component.c
index 9c0861e14a..71952d4300 100644
--- a/shell/evolution-shell-component.c
+++ b/shell/evolution-shell-component.c
@@ -224,7 +224,8 @@ corba_class_init (void)
epv->create_view = impl_ShellComponent_create_view;
vepv = &ShellComponent_vepv;
- vepv->Bonobo_Unknown_epv = bonobo_object_get_epv ();
+ vepv->_base_epv = base_epv;
+ vepv->Bonobo_Unknown_epv = bonobo_object_get_epv ();
vepv->Evolution_ShellComponent_epv = epv;
}
@@ -327,6 +328,15 @@ evolution_shell_component_new (const EvolutionShellComponentFolderType folder_ty
return new;
}
+Evolution_Shell
+evolution_shell_component_get_owner (EvolutionShellComponent *shell_component)
+{
+ g_return_val_if_fail (shell_component != NULL, CORBA_OBJECT_NIL);
+ g_return_val_if_fail (EVOLUTION_IS_SHELL_COMPONENT (shell_component), CORBA_OBJECT_NIL);
+
+ return shell_component->priv->corba_owner;
+}
+
E_MAKE_TYPE (evolution_shell_component, "EvolutionShellComponent", EvolutionShellComponent,
class_init, init, PARENT_TYPE)
diff --git a/shell/evolution-shell-component.h b/shell/evolution-shell-component.h
index 0922124606..4b00f5df0a 100644
--- a/shell/evolution-shell-component.h
+++ b/shell/evolution-shell-component.h
@@ -82,7 +82,7 @@ void evolution_shell_component_construct (EvolutionShellCom
EvolutionShellComponent *evolution_shell_component_new (const EvolutionShellComponentFolderType folder_types[],
EvolutionShellComponentCreateViewFn create_view_fn,
void *closure);
-Evolution_Shell evolution_shell_component_get_shell (EvolutionShellComponent *shell_component);
+Evolution_Shell evolution_shell_component_get_owner (EvolutionShellComponent *shell_component);
#ifdef __cplusplus
}
diff --git a/shell/evolution-storage.c b/shell/evolution-storage.c
new file mode 100644
index 0000000000..eab28ddfcb
--- /dev/null
+++ b/shell/evolution-storage.c
@@ -0,0 +1,395 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* evolution-storage.c
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ettore Perazzoli
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <bonobo.h>
+
+#include "Evolution.h"
+
+#include "e-util/e-util.h"
+
+#include "evolution-storage.h"
+
+
+#define PARENT_TYPE BONOBO_OBJECT_TYPE
+static BonoboObjectClass *parent_class = NULL;
+
+struct _EvolutionStoragePrivate {
+ char *name;
+
+ Evolution_StorageRegistry corba_storage_registry;
+ Evolution_StorageListener corba_storage_listener;
+};
+
+
+/* CORBA interface implementation. */
+
+static POA_Evolution_Storage__vepv Storage_vepv;
+
+static POA_Evolution_Storage *
+create_servant (void)
+{
+ POA_Evolution_Storage *servant;
+ CORBA_Environment ev;
+
+ servant = (POA_Evolution_Storage *) g_new0 (BonoboObjectServant, 1);
+ servant->vepv = &Storage_vepv;
+
+ CORBA_exception_init (&ev);
+
+ POA_Evolution_Storage__init ((PortableServer_Servant) servant, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_free (servant);
+ CORBA_exception_free (&ev);
+ return NULL;
+ }
+
+ CORBA_exception_free (&ev);
+
+ return servant;
+}
+
+static CORBA_char *
+impl_Storage__get_name (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ BonoboObject *bonobo_object;
+ EvolutionStorage *storage;
+ EvolutionStoragePrivate *priv;
+
+ bonobo_object = bonobo_object_from_servant (servant);
+ storage = EVOLUTION_STORAGE (bonobo_object);
+ priv = storage->priv;
+
+ return CORBA_string_dup (priv->name);
+}
+
+
+/* GtkObject methods. */
+
+static void
+destroy (GtkObject *object)
+{
+ EvolutionStorage *storage;
+ EvolutionStoragePrivate *priv;
+ CORBA_Environment ev;
+
+ storage = EVOLUTION_STORAGE (object);
+ priv = storage->priv;
+
+ g_free (priv->name);
+
+ CORBA_exception_init (&ev);
+
+ if (priv->corba_storage_registry != CORBA_OBJECT_NIL) {
+ Bonobo_Unknown_unref (priv->corba_storage_registry, &ev);
+ CORBA_Object_release (priv->corba_storage_registry, &ev);
+ }
+
+ if (priv->corba_storage_listener != CORBA_OBJECT_NIL) {
+ /* (This is not a Bonobo object, so no unref.) */
+ CORBA_Object_release (priv->corba_storage_listener, &ev);
+ }
+
+ CORBA_exception_free (&ev);
+
+ g_free (priv);
+}
+
+
+static void
+corba_class_init (void)
+{
+ POA_Evolution_Storage__vepv *vepv;
+ POA_Evolution_Storage__epv *epv;
+ PortableServer_ServantBase__epv *base_epv;
+
+ base_epv = g_new0 (PortableServer_ServantBase__epv, 1);
+ base_epv->_private = NULL;
+ base_epv->finalize = NULL;
+ base_epv->default_POA = NULL;
+
+ epv = g_new0 (POA_Evolution_Storage__epv, 1);
+ epv->_get_name = impl_Storage__get_name;
+
+ vepv = &Storage_vepv;
+ vepv->Bonobo_Unknown_epv = bonobo_object_get_epv ();
+ vepv->Evolution_Storage_epv = epv;
+}
+
+static void
+class_init (EvolutionStorageClass *klass)
+{
+ GtkObjectClass *object_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ object_class->destroy = destroy;
+
+ parent_class = gtk_type_class (bonobo_object_get_type ());
+
+ corba_class_init ();
+}
+
+static void
+init (EvolutionStorage *storage)
+{
+ EvolutionStoragePrivate *priv;
+
+ priv = g_new (EvolutionStoragePrivate, 1);
+ priv->name = NULL;
+ priv->corba_storage_listener = NULL;
+
+ storage->priv = priv;
+}
+
+
+void
+evolution_storage_construct (EvolutionStorage *storage,
+ Evolution_Storage corba_object,
+ const char *name)
+{
+ EvolutionStoragePrivate *priv;
+
+ g_return_if_fail (storage != NULL);
+ g_return_if_fail (EVOLUTION_IS_STORAGE (storage));
+ g_return_if_fail (corba_object != CORBA_OBJECT_NIL);
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (name[0] != '\0');
+
+ bonobo_object_construct (BONOBO_OBJECT (storage), corba_object);
+
+ priv = storage->priv;
+ priv->name = g_strdup (name);
+}
+
+EvolutionStorage *
+evolution_storage_new (const char *name)
+{
+ EvolutionStorage *new;
+ POA_Evolution_Storage *servant;
+ Evolution_Storage corba_object;
+
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (name[0] != '\0', NULL);
+
+ servant = create_servant ();
+ if (servant == NULL)
+ return NULL;
+
+ new = gtk_type_new (evolution_storage_get_type ());
+
+ corba_object = bonobo_object_activate_servant (BONOBO_OBJECT (new), servant);
+ evolution_storage_construct (new, corba_object, name);
+
+ return new;
+}
+
+EvolutionStorageResult
+evolution_storage_register (EvolutionStorage *evolution_storage,
+ Evolution_StorageRegistry corba_storage_registry)
+{
+ EvolutionStorageResult result;
+ Evolution_StorageListener corba_storage_listener;
+ Evolution_Storage corba_storage;
+ EvolutionStoragePrivate *priv;
+ CORBA_Environment ev;
+
+ g_return_val_if_fail (evolution_storage != NULL,
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (EVOLUTION_IS_STORAGE (evolution_storage),
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (corba_storage_registry != CORBA_OBJECT_NIL,
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+
+ priv = evolution_storage->priv;
+
+ if (priv->corba_storage_listener != CORBA_OBJECT_NIL)
+ return EVOLUTION_STORAGE_ERROR_ALREADYREGISTERED;
+
+ CORBA_exception_init (&ev);
+
+ corba_storage = bonobo_object_corba_objref (BONOBO_OBJECT (evolution_storage));
+ corba_storage_listener = Evolution_StorageRegistry_register_storage (corba_storage_registry,
+ corba_storage,
+ "pippo", &ev);
+
+ if (ev._major == CORBA_NO_EXCEPTION) {
+ Bonobo_Unknown_ref (corba_storage_registry, &ev);
+ priv->corba_storage_registry = CORBA_Object_duplicate (corba_storage_registry, &ev);
+
+ priv->corba_storage_listener = corba_storage_listener;
+
+ result = EVOLUTION_STORAGE_OK;
+ } else {
+ if (ev._major != CORBA_USER_EXCEPTION)
+ result = EVOLUTION_STORAGE_ERROR_CORBA;
+ else if (strcmp (CORBA_exception_id (&ev), ex_Evolution_StorageRegistry_Exists) == 0)
+ result = EVOLUTION_STORAGE_ERROR_EXISTS;
+ else
+ result = EVOLUTION_STORAGE_ERROR_GENERIC;
+ }
+
+ CORBA_exception_free (&ev);
+
+ return result;
+}
+
+EvolutionStorageResult
+evolution_storage_register_on_shell (EvolutionStorage *evolution_storage,
+ Evolution_Shell corba_shell)
+{
+ Evolution_StorageRegistry corba_storage_registry;
+ EvolutionStorageResult result;
+ CORBA_Environment ev;
+
+ g_return_val_if_fail (evolution_storage != NULL,
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (EVOLUTION_IS_STORAGE (evolution_storage),
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (corba_shell != CORBA_OBJECT_NIL,
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+
+ CORBA_exception_init (&ev);
+
+ corba_storage_registry = Bonobo_Unknown_query_interface (corba_shell,
+ "IDL:Evolution/StorageRegistry:1.0",
+ &ev);
+ if (corba_storage_registry == CORBA_OBJECT_NIL || ev._major != CORBA_NO_EXCEPTION) {
+ CORBA_exception_free (&ev);
+ return EVOLUTION_STORAGE_ERROR_NOREGISTRY;
+ }
+
+ result = evolution_storage_register (evolution_storage, corba_storage_registry);
+
+ Bonobo_Unknown_unref (corba_storage_registry, &ev);
+ CORBA_Object_release (corba_storage_registry, &ev);
+
+ CORBA_exception_free (&ev);
+
+ return result;
+}
+
+EvolutionStorageResult
+evolution_storage_new_folder (EvolutionStorage *evolution_storage,
+ const char *path,
+ const char *type,
+ const char *physical_uri,
+ const char *description)
+{
+ EvolutionStorageResult result;
+ EvolutionStoragePrivate *priv;
+ Evolution_Folder corba_folder;
+ CORBA_Environment ev;
+ const char *path_basename;
+ char *parent_path;
+
+ g_return_val_if_fail (evolution_storage != NULL,
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (EVOLUTION_IS_STORAGE (evolution_storage),
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (path != NULL, EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (g_path_is_absolute (path), EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (description != NULL, EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (type != NULL, EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (physical_uri != NULL, EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+
+ priv = evolution_storage->priv;
+
+ path_basename = g_basename (path);
+
+ /* Yuck. */
+ corba_folder.name = (CORBA_char *) path_basename;
+ corba_folder.description = (CORBA_char *) description;
+ corba_folder.type = (CORBA_char *) type;
+ corba_folder.physical_uri = (CORBA_char *) physical_uri;
+
+ if (path_basename - path > 1) {
+ parent_path = g_strndup (path, path_basename - path - 1);
+ } else {
+ parent_path = g_strdup (G_DIR_SEPARATOR_S);
+ }
+
+ CORBA_exception_init (&ev);
+
+ Evolution_StorageListener_new_folder (priv->corba_storage_listener, parent_path,
+ &corba_folder, &ev);
+
+ if (ev._major == CORBA_NO_EXCEPTION)
+ result = EVOLUTION_STORAGE_OK;
+ else if (ev._major != CORBA_USER_EXCEPTION)
+ result = EVOLUTION_STORAGE_ERROR_CORBA;
+ else if (strcmp (CORBA_exception_id (&ev), ex_Evolution_StorageListener_Exists) == 0)
+ result = EVOLUTION_STORAGE_ERROR_EXISTS;
+ else
+ result = EVOLUTION_STORAGE_ERROR_GENERIC;
+
+ CORBA_exception_free (&ev);
+
+ g_free (parent_path);
+
+ return result;
+}
+
+EvolutionStorageResult
+evolution_storage_removed_folder (EvolutionStorage *evolution_storage,
+ const char *path)
+{
+ EvolutionStorageResult result;
+ EvolutionStoragePrivate *priv;
+ CORBA_Environment ev;
+
+ g_return_val_if_fail (evolution_storage != NULL,
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (EVOLUTION_IS_STORAGE (evolution_storage),
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (path != NULL, EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+ g_return_val_if_fail (g_path_is_absolute (path), EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER);
+
+ priv = evolution_storage->priv;
+
+ if (priv->corba_storage_listener == CORBA_OBJECT_NIL)
+ return EVOLUTION_STORAGE_ERROR_NOTREGISTERED;
+
+ CORBA_exception_init (&ev);
+
+ Evolution_StorageListener_removed_folder (priv->corba_storage_listener, path, &ev);
+
+ if (ev._major == CORBA_NO_EXCEPTION)
+ result = EVOLUTION_STORAGE_OK;
+ else if (ev._major != CORBA_USER_EXCEPTION)
+ result = EVOLUTION_STORAGE_ERROR_CORBA;
+ else if (strcmp (CORBA_exception_id (&ev), ex_Evolution_StorageListener_NotFound) == 0)
+ result = EVOLUTION_STORAGE_ERROR_NOTFOUND;
+ else
+ result = EVOLUTION_STORAGE_ERROR_GENERIC;
+
+ CORBA_exception_free (&ev);
+
+ return result;
+}
+
+
+E_MAKE_TYPE (evolution_storage, "EvolutionStorage", EvolutionStorage, class_init, init, PARENT_TYPE)
diff --git a/shell/evolution-storage.h b/shell/evolution-storage.h
new file mode 100644
index 0000000000..40e678dd57
--- /dev/null
+++ b/shell/evolution-storage.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* evolution-storage.h
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ettore Perazzoli
+ */
+
+#ifndef __EVOLUTION_STORAGE_H__
+#define __EVOLUTION_STORAGE_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <bonobo/bonobo-object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+#define EVOLUTION_TYPE_STORAGE (evolution_storage_get_type ())
+#define EVOLUTION_STORAGE(obj) (GTK_CHECK_CAST ((obj), EVOLUTION_TYPE_STORAGE, EvolutionStorage))
+#define EVOLUTION_STORAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_STORAGE, EvolutionStorageClass))
+#define EVOLUTION_IS_STORAGE(obj) (GTK_CHECK_TYPE ((obj), EVOLUTION_TYPE_STORAGE))
+#define EVOLUTION_IS_STORAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_STORAGE))
+
+
+typedef struct _EvolutionStorage EvolutionStorage;
+typedef struct _EvolutionStoragePrivate EvolutionStoragePrivate;
+typedef struct _EvolutionStorageClass EvolutionStorageClass;
+
+enum _EvolutionStorageResult {
+ EVOLUTION_STORAGE_OK,
+ EVOLUTION_STORAGE_ERROR_ALREADYREGISTERED,
+ EVOLUTION_STORAGE_ERROR_NOTREGISTERED,
+ EVOLUTION_STORAGE_ERROR_NOREGISTRY,
+ EVOLUTION_STORAGE_ERROR_CORBA,
+ EVOLUTION_STORAGE_ERROR_EXISTS,
+ EVOLUTION_STORAGE_ERROR_INVALIDPARAMETER,
+ EVOLUTION_STORAGE_ERROR_NOTFOUND,
+ EVOLUTION_STORAGE_ERROR_GENERIC
+};
+typedef enum _EvolutionStorageResult EvolutionStorageResult;
+
+struct _EvolutionStorage {
+ BonoboObject parent;
+
+ EvolutionStoragePrivate *priv;
+};
+
+struct _EvolutionStorageClass {
+ BonoboObjectClass parent_class;
+};
+
+
+GtkType evolution_storage_get_type (void);
+void evolution_storage_construct (EvolutionStorage *storage,
+ Evolution_Storage corba_object,
+ const char *name);
+EvolutionStorage *evolution_storage_new (const char *name);
+
+EvolutionStorageResult evolution_storage_register (EvolutionStorage *storage,
+ Evolution_StorageRegistry corba_registry);
+EvolutionStorageResult evolution_storage_register_on_shell (EvolutionStorage *evolution_storage,
+ Evolution_Shell corba_shell);
+
+EvolutionStorageResult evolution_storage_new_folder (EvolutionStorage *evolution_storage,
+ const char *path,
+ const char *type,
+ const char *physical_uri,
+ const char *description);
+EvolutionStorageResult evolution_storage_removed_folder (EvolutionStorage *evolution_storage,
+ const char *path);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __EVOLUTION_STORAGE_H__ */