[evolution] Whoops, too soon to kill EImportHook just yet.



commit 5507f4dbbd489c5f2bf841207a27efca53d5233b
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Sep 26 11:26:17 2009 -0400

    Whoops, too soon to kill EImportHook just yet.

 e-util/e-import.c |  239 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 e-util/e-import.h |   70 ++++++++++++++++
 2 files changed, 309 insertions(+), 0 deletions(-)
---
diff --git a/e-util/e-import.c b/e-util/e-import.c
index 08747cd..fbc21b2 100644
--- a/e-util/e-import.c
+++ b/e-util/e-import.c
@@ -363,3 +363,242 @@ e_import_target_new_home (EImport *ei)
 	return e_import_target_new (
 		ei, E_IMPORT_TARGET_HOME, sizeof (EImportTargetHome));
 }
+
+/* ********************************************************************** */
+
+/* Import menu plugin handler */
+
+/*
+<e-plugin
+  class="org.gnome.mail.plugin.import:1.0"
+  id="org.gnome.mail.plugin.import.item:1.0"
+  type="shlib"
+  location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
+  name="imap"
+  description="IMAP4 and IMAP4v1 mail store">
+  <hook class="org.gnome.mail.importMenu:1.0"
+        handler="HandleImport">
+  <menu id="any" target="select">
+   <item
+    type="item|toggle|radio|image|submenu|bar"
+    active
+    path="foo/bar"
+    label="label"
+    icon="foo"
+    activate="ep_view_emacs"/>
+  </menu>
+  </extension>
+
+*/
+
+static gpointer emph_parent_class;
+#define emph ((EImportHook *)eph)
+
+static const EImportHookTargetMask eih_no_masks[] = {
+	{ NULL }
+};
+
+static const EImportHookTargetMap eih_targets[] = {
+	{ "uri", E_IMPORT_TARGET_URI, eih_no_masks },
+	{ "home", E_IMPORT_TARGET_HOME, eih_no_masks },
+	{ NULL }
+};
+
+static gboolean eih_supported(EImport *ei, EImportTarget *target, EImportImporter *im)
+{
+	struct _EImportHookImporter *ihook = (EImportHookImporter *)im;
+	EImportHook *hook = im->user_data;
+
+	return e_plugin_invoke(hook->hook.plugin, ihook->supported, target) != NULL;
+}
+
+static GtkWidget *eih_get_widget(EImport *ei, EImportTarget *target, EImportImporter *im)
+{
+	struct _EImportHookImporter *ihook = (EImportHookImporter *)im;
+	EImportHook *hook = im->user_data;
+
+	return e_plugin_invoke(hook->hook.plugin, ihook->get_widget, target);
+}
+
+static void eih_import(EImport *ei, EImportTarget *target, EImportImporter *im)
+{
+	struct _EImportHookImporter *ihook = (EImportHookImporter *)im;
+	EImportHook *hook = im->user_data;
+
+	e_plugin_invoke(hook->hook.plugin, ihook->import, target);
+}
+
+static void eih_cancel(EImport *ei, EImportTarget *target, EImportImporter *im)
+{
+	struct _EImportHookImporter *ihook = (EImportHookImporter *)im;
+	EImportHook *hook = im->user_data;
+
+	e_plugin_invoke(hook->hook.plugin, ihook->cancel, target);
+}
+
+static void
+eih_free_importer(EImportImporter *im, gpointer data)
+{
+	EImportHookImporter *ihook = (EImportHookImporter *)im;
+
+	g_free(ihook->supported);
+	g_free(ihook->get_widget);
+	g_free(ihook->import);
+	g_free(ihook);
+}
+
+static struct _EImportHookImporter *
+emph_construct_importer(EPluginHook *eph, xmlNodePtr root)
+{
+	struct _EImportHookImporter *item;
+	EImportHookTargetMap *map;
+	EImportHookClass *klass = (EImportHookClass *)G_OBJECT_GET_CLASS(eph);
+	gchar *tmp;
+
+	d(printf("  loading import item\n"));
+	item = g_malloc0(sizeof(*item));
+
+	tmp = (gchar *)xmlGetProp(root, (const guchar *)"target");
+	if (tmp == NULL)
+		goto error;
+	map = g_hash_table_lookup(klass->target_map, tmp);
+	xmlFree(tmp);
+	if (map == NULL)
+		goto error;
+
+	item->importer.type = map->id;
+	item->supported = e_plugin_xml_prop(root, "supported");
+	item->get_widget = e_plugin_xml_prop(root, "get-widget");
+	item->import = e_plugin_xml_prop(root, "import");
+	item->cancel = e_plugin_xml_prop(root, "cancel");
+
+	item->importer.name = e_plugin_xml_prop(root, "name");
+	item->importer.description = e_plugin_xml_prop(root, "description");
+
+	item->importer.user_data = eph;
+
+	if (item->import == NULL || item->supported == NULL)
+		goto error;
+
+	item->importer.supported = eih_supported;
+	item->importer.import = eih_import;
+	if (item->get_widget)
+		item->importer.get_widget = eih_get_widget;
+	if (item->cancel)
+		item->importer.cancel = eih_cancel;
+
+	return item;
+error:
+	d(printf("error!\n"));
+	eih_free_importer((EImportImporter *)item, NULL);
+	return NULL;
+}
+
+static gint
+emph_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root)
+{
+	xmlNodePtr node;
+	EImportClass *klass;
+
+	d(printf("loading import hook\n"));
+
+	if (((EPluginHookClass *)emph_parent_class)->construct(eph, ep, root) == -1)
+		return -1;
+
+	klass = ((EImportHookClass *)G_OBJECT_GET_CLASS(eph))->import_class;
+
+	node = root->children;
+	while (node) {
+		if (strcmp((gchar *)node->name, "importer") == 0) {
+			struct _EImportHookImporter *ihook;
+
+			ihook = emph_construct_importer(eph, node);
+			if (ihook) {
+				e_import_class_add_importer(klass, &ihook->importer, eih_free_importer, eph);
+				emph->importers = g_slist_append(emph->importers, ihook);
+			}
+		}
+		node = node->next;
+	}
+
+	eph->plugin = ep;
+
+	return 0;
+}
+
+static void
+emph_finalise(GObject *o)
+{
+	/*EPluginHook *eph = (EPluginHook *)o;*/
+
+	/* free importers? */
+
+	((GObjectClass *)emph_parent_class)->finalize(o);
+}
+
+static void
+emph_class_init(EPluginHookClass *klass)
+{
+	gint i;
+
+	((GObjectClass *)klass)->finalize = emph_finalise;
+	klass->construct = emph_construct;
+
+	/** @HookClass: Evolution Importers
+	 * @Id: org.gnome.evolution.import:1.0
+	 * @Target: EImportTarget
+	 *
+	 * A hook for data importers.
+	 **/
+
+	klass->id = "org.gnome.evolution.import:1.0";
+
+	d(printf("EImportHook: init class %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type)));
+
+	((EImportHookClass *)klass)->target_map = g_hash_table_new(g_str_hash, g_str_equal);
+	((EImportHookClass *)klass)->import_class = g_type_class_ref(e_import_get_type());
+
+	for (i=0;eih_targets[i].type;i++)
+		e_import_hook_class_add_target_map((EImportHookClass *)klass, &eih_targets[i]);
+}
+
+/**
+ * e_import_hook_get_type:
+ *
+ * Standard GObject function to get the object type.
+ *
+ * Return value: The EImportHook class type.
+ **/
+GType
+e_import_hook_get_type(void)
+{
+	static GType type = 0;
+
+	if (!type) {
+		static const GTypeInfo info = {
+			sizeof(EImportHookClass), NULL, NULL, (GClassInitFunc) emph_class_init, NULL, NULL,
+			sizeof(EImportHook), 0, (GInstanceInitFunc) NULL,
+		};
+
+		emph_parent_class = g_type_class_ref(e_plugin_hook_get_type());
+		type = g_type_register_static(e_plugin_hook_get_type(), "EImportHook", &info, 0);
+	}
+
+	return type;
+}
+
+/**
+ * e_import_hook_class_add_target_map:
+ *
+ * @klass: The dervied EimportHook class.
+ * @map: A map used to describe a single EImportTarget type for this
+ * class.
+ *
+ * Add a targe tmap to a concrete derived class of EImport.  The
+ * target map enumates the target types available for the implenting
+ * class.
+ **/
+void e_import_hook_class_add_target_map(EImportHookClass *klass, const EImportHookTargetMap *map)
+{
+	g_hash_table_insert(klass->target_map, (gpointer)map->type, (gpointer)map);
+}
diff --git a/e-util/e-import.h b/e-util/e-import.h
index 8215604..b0ffe3b 100644
--- a/e-util/e-import.h
+++ b/e-util/e-import.h
@@ -185,6 +185,76 @@ void e_import_target_free(EImport *ep, gpointer o);
 EImportTargetURI *e_import_target_new_uri(EImport *ei, const gchar *suri, const gchar *duri);
 EImportTargetHome *e_import_target_new_home(EImport *ei);
 
+/* ********************************************************************** */
+
+/* import plugin target, they are closely integrated */
+
+/* To implement a basic import plugin, you just need to subclass
+   this and initialise the class target type tables */
+
+#include "e-util/e-plugin.h"
+
+typedef struct _EPluginHookTargetMap EImportHookTargetMap;
+typedef struct _EPluginHookTargetKey EImportHookTargetMask;
+
+typedef struct _EImportHook EImportHook;
+typedef struct _EImportHookClass EImportHookClass;
+
+typedef struct _EImportHookImporter EImportHookImporter;
+
+struct _EImportHookImporter {
+	EImportImporter importer;
+
+	/* user_data == EImportHook */
+
+	gchar *supported;
+	gchar *get_widget;
+	gchar *import;
+	gchar *cancel;
+};
+
+/**
+ * struct _EImportHook - Plugin hook for importuration windows.
+ *
+ * @hook: Superclass.
+ * @groups: A list of EImportHookGroup's of all importuration windows
+ * this plugin hooks into.
+ *
+ **/
+struct _EImportHook {
+	EPluginHook hook;
+
+	GSList *importers;
+};
+
+/**
+ * struct _EImportHookClass - Abstract class for importuration window
+ * plugin hooks.
+ *
+ * @hook_class: Superclass.
+ * @target_map: A table of EImportHookTargetMap structures describing
+ * the possible target types supported by this class.
+ * @import_class: The EImport derived class that this hook
+ * implementation drives.
+ *
+ * This is an abstract class defining the plugin hook point for
+ * importuration windows.
+ *
+ **/
+struct _EImportHookClass {
+	EPluginHookClass hook_class;
+
+	/* EImportHookTargetMap by .type */
+	GHashTable *target_map;
+	/* the import class these imports's belong to */
+	EImportClass *import_class;
+};
+
+GType e_import_hook_get_type(void);
+
+/* for implementors */
+void e_import_hook_class_add_target_map(EImportHookClass *klass, const EImportHookTargetMap *);
+
 G_END_DECLS
 
 #endif /* __E_IMPORT_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]