From 1907cf0faa1b82a8e1bddf263f9b434f7009ac9c Mon Sep 17 00:00:00 2001 From: Not Zed Date: Thu, 19 May 2005 06:09:45 +0000 Subject: Initial, and un-finished work on importer plugin hooks. 2005-05-19 Not Zed * e-import.[ch]: Initial, and un-finished work on importer plugin hooks. svn path=/trunk/; revision=29384 --- e-util/ChangeLog | 5 + e-util/Makefile.am | 2 + e-util/e-import.c | 639 +++++++++++++++++++++++++++++++++++++++++++++++++++++ e-util/e-import.h | 262 ++++++++++++++++++++++ 4 files changed, 908 insertions(+) create mode 100644 e-util/e-import.c create mode 100644 e-util/e-import.h diff --git a/e-util/ChangeLog b/e-util/ChangeLog index 5f5c407550..610624fb3f 100644 --- a/e-util/ChangeLog +++ b/e-util/ChangeLog @@ -1,3 +1,8 @@ +2005-05-19 Not Zed + + * e-import.[ch]: Initial, and un-finished work on importer plugin + hooks. + 2005-05-16 Not Zed * Makefile.am: added e-error.[ch], removed e-error-tool, and added diff --git a/e-util/Makefile.am b/e-util/Makefile.am index 888cd47cd5..25db475676 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -39,6 +39,7 @@ eutilinclude_HEADERS = \ e-gui-utils.h \ e-html-utils.h \ e-icon-factory.h \ + e-import.h \ e-iterator.h \ e-list-iterator.h \ e-list.h \ @@ -78,6 +79,7 @@ libeutil_la_SOURCES = \ e-gui-utils.c \ e-html-utils.c \ e-icon-factory.c \ + e-import.c \ e-iterator.c \ e-list-iterator.c \ e-list.c \ diff --git a/e-util/e-import.c b/e-util/e-import.c new file mode 100644 index 0000000000..717805203e --- /dev/null +++ b/e-util/e-import.c @@ -0,0 +1,639 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Michael Zucchi + * + * Copyright 2005 Novell 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_IMPORT_H +#include +#endif + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "e-import.h" + +#include + +#include + +#define d(x) + +#define _PRIVATE(o) (g_type_instance_get_private ((GTypeInstance *)o, e_import_get_type())) + +struct _EImportImporters { + struct _EImportImporters *next, *prev; + + EImportImporter *importer; + EImportImporterFunc free; + void *data; +}; + +struct _EImportPrivate { + int dummy; +}; + +static GObjectClass *ep_parent; + +static void +ep_init(GObject *o) +{ + /*EImport *emp = (EImport *)o;*/ + struct _EImportPrivate *p; + + p = _PRIVATE(o); +} + +static void +ep_finalise(GObject *o) +{ + EImport *emp = (EImport *)o; + struct _EImportPrivate *p; + + p = _PRIVATE(emp); + + d(printf("finalising EImport %p\n", o)); + + g_free(emp->id); + + ((GObjectClass *)ep_parent)->finalize(o); +} + +static void +ec_target_free(EImport *ep, EImportTarget *t) +{ + switch (t->type) { + case E_IMPORT_TARGET_URI: { + EImportTargetURI *s = (EImportTargetURI *)t; + + g_free(s->uri_src); + g_free(s->uri_dest); + break; } + case E_IMPORT_TARGET_HOME: { + EImportTargetHome *s = (EImportTargetHome *)t; + + g_free(s->homedir); + break; } + } + + g_free(t); + g_object_unref(ep); +} + +static void +ec_set_target(EImport *emp, EImportTarget *target) +{ + EImportClass *k = (EImportClass *)G_OBJECT_GET_CLASS(emp); + struct _EImportImporters *ei; + + if (emp->target) + e_import_target_free(emp, target); + + emp->target = target; + emp->importer = NULL; + + if (target== NULL) + return; + + for (ei = (struct _EImportImporters *)k->importers.head; + ei->next; + ei = ei->next) { + if (ei->importer->type == target->type + && ei->importer->supported(emp, ei->importer, ei->importer->user_data)) { + emp->importer = ei->importer; + break; + } + } +} + +static void +ep_class_init(GObjectClass *klass) +{ + d(printf("EImport class init %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type))); + + g_type_class_add_private(klass, sizeof(struct _EImportPrivate)); + + klass->finalize = ep_finalise; + ((EImportClass *)klass)->set_target = ec_set_target; + ((EImportClass *)klass)->target_free = ec_target_free; +} + +static void +ep_base_init(GObjectClass *klass) +{ + e_dlist_init(&((EImportClass *)klass)->importers); +} + +/** + * e_import_get_type: + * + * Standard GObject method. Used to subclass for the concrete + * implementations. + * + * Return value: EImport type. + **/ +GType +e_import_get_type(void) +{ + static GType type = 0; + + if (type == 0) { + static const GTypeInfo info = { + sizeof(EImportClass), + (GBaseInitFunc)ep_base_init, NULL, + (GClassInitFunc)ep_class_init, NULL, NULL, + sizeof(EImport), 0, + (GInstanceInitFunc)ep_init + }; + ep_parent = g_type_class_ref(G_TYPE_OBJECT); + type = g_type_register_static(G_TYPE_OBJECT, "EImport", &info, 0); + } + + return type; +} + +/** + * e_import_construct: + * @ep: The instance to initialise. + * @id: The name of the instance. + * + * Used by implementing classes to initialise base parameters. + * + * Return value: @ep is returned. + **/ +EImport *e_import_construct(EImport *ep, const char *id) +{ + ep->id = g_strdup(id); + + return ep; +} + +/** + * e_import_import: + * @ei: + * @done: + * @data: + * + * Run the import function of the selected importer. Once the + * importer has finished, it MUST call the e_import_complete() + * function. This allows importers to run in synchronous or + * asynchronous mode. + * + * When complete, the @done callback will be called. + **/ +void +e_import_import(EImport *ei, EImportCompleteFunc done, void *data) +{ + g_return_if_fail(ei->importer != NULL); + g_return_if_fail(ei->target != NULL); + + ei->done = done; + ei->done_data = data; + + ei->importer->import(ei, ei->importer, ei->importer->user_data); +} + +/** + * e_import_get_widget: + * @ei: An import object on which the target has been set. + * + * Gets a widget that the importer uses to configure its + * destination. This widget should be packed into a container + * widget. + * + * Return value: NULL if the importer doesn't support/require + * a destination. + **/ +struct _GtkWidget * +e_import_get_widget(EImport *ei) +{ + g_return_val_if_fail(ei->importer != NULL, NULL); + g_return_val_if_fail(ei->target != NULL, NULL); + + return ei->importer->get_widget(ei, ei->importer, ei->importer->user_data); +} + +/** + * e_import_complete: + * @ei: + * + * Signify that an import is complete. This must be called by + * importer implementations when they are done. + **/ +void e_import_complete(EImport *ei) +{ + if (ei->done) + ei->done(ei, ei->done_data); +} + +/** + * e_import_set_target: + * @emp: An initialised EImport. + * @target: A target allocated from @emp. + * + * Sets the target object for the import window. Generally the target + * is set only once, and will supply its own "changed" signal which + * can be used to drive the modal. This is a virtual method so that + * the implementing class can connect to the changed signal and + * initiate a e_import_target_changed() call where appropriate. + **/ +void +e_import_set_target(EImport *emp, EImportTarget *target) +{ + if (emp->target != target) + ((EImportClass *)G_OBJECT_GET_CLASS(emp))->set_target(emp, target); +} + +/** + * e_import_get_importers: + * @emp: + * @target: + * + * Get a list of importers. If @target is supplied, then only + * importers which support the location specified by the target are + * listed. If @target is NULL, then all importers are listed. + * + * Return value: A list of importers. The list should be freed when + * no longer needed. + **/ +GSList * +e_import_get_importers(EImport *emp, EImportTarget *target) +{ + EImportClass *k = (EImportClass *)G_OBJECT_GET_CLASS(emp); + struct _EImportImporters *ei; + GSList *importers = NULL; + + for (ei = (struct _EImportImporters *)k->importers.head; + ei->next; + ei = ei->next) { + if (target == NULL + || (ei->importer->type == target->type + && ei->importer->supported(emp, ei->importer, ei->importer->user_data))) { + importers = g_slist_append(importers, ei->importer); + break; + } + } + + return importers; +} + +/* ********************************************************************** */ + +/** + * e_import_class_add_importer: + * @ec: An initialised implementing instance of EImport. + * @importer: Importer to add. + * @freefunc: If supplied, called to free the importer node + * when it is no longer needed. + * @data: Data for the callback. + * + **/ +void +e_import_class_add_importer(EImportClass *klass, EImportImporter *importer, EImportImporterFunc freefunc, void *data) +{ + struct _EImportImporters *node, *ei, *en; + + node = g_malloc(sizeof(*node)); + node->importer = importer; + node->free = freefunc; + node->data = data; + ei = (struct _EImportImporters *)klass->importers.head; + en = ei->next; + while (en && ei->importer->pri < importer->pri) { + ei = en; + en = en->next; + } + + node->next = ei->next; + node->next->prev = node; + node->prev = ei; + ei->next = node; +} + +void e_import_class_remove_importer(EImportClass *klass, EImportImporter *f) +{ + struct _EImportImporters *ei, *en; + + ei = (struct _EImportImporters *)klass->importers.head; + en = ei->next; + while (en) { + if (ei->importer == f) { + e_dlist_remove((EDListNode *)ei); + if (ei->free) + ei->free(f, ei->data); + g_free(ei); + } + ei = en; + en = en->next; + } +} + +/** + * e_import_target_new: + * @ep: Parent EImport object. + * @type: type, up to implementor + * @size: Size of object to allocate. + * + * Allocate a new import target suitable for this class. Implementing + * classes will define the actual content of the target. + **/ +void *e_import_target_new(EImport *ep, int type, size_t size) +{ + EImportTarget *t; + + g_assert(size >= sizeof(EImportTarget)); + + t = g_malloc0(size); + t->import = ep; + g_object_ref(ep); + t->type = type; + + return t; +} + +/** + * e_import_target_free: + * @ep: Parent EImport object. + * @o: The target to fre. + * + * Free a target. The implementing class can override this method to + * free custom targets. + **/ +void +e_import_target_free(EImport *ep, void *o) +{ + EImportTarget *t = o; + + ((EImportClass *)G_OBJECT_GET_CLASS(ep))->target_free(ep, t); +} + +EImportTargetURI *e_import_target_new_uri(EImport *ei, const char *suri, const char *duri) +{ + EImportTargetURI *t = e_import_target_new(ei, E_IMPORT_TARGET_URI, sizeof(*t)); + + t->uri_src = g_strdup(suri); + t->uri_dest = g_strdup(duri); + + return t; +} + +EImportTargetHome *e_import_target_new_home(EImport *ei, const char *home) +{ + EImportTargetHome *t = e_import_target_new(ei, E_IMPORT_TARGET_HOME, sizeof(*t)); + + t->homedir = g_strdup(home); + + return t; +} + +/* ********************************************************************** */ + +/* Import menu plugin handler */ + +/* + + + + + + + +*/ + +static void *emph_parent_class; +#define emph ((EImportHook *)eph) + +static const EImportHookTargetMask eih_no_masks[] = { + { 0 } +}; + +static const EImportHookTargetMap eih_targets[] = { + { "uri", E_IMPORT_TARGET_URI, eih_no_masks }, + { "home", E_IMPORT_TARGET_URI, eih_no_masks }, + { 0 } +}; + +static gboolean eih_supported(EImport *ei, EImportImporter *im, void *data) +{ + struct _EImportHookImporter *ihook = (EImportHookImporter *)im; + EImportHook *hook = im->user_data; + + return e_plugin_invoke(hook->hook.plugin, ihook->supported, ei) != NULL; +} + +static struct _GtkWidget *eih_get_widget(EImport *ei, EImportImporter *im, void *data) +{ + struct _EImportHookImporter *ihook = (EImportHookImporter *)im; + EImportHook *hook = im->user_data; + + return e_plugin_invoke(hook->hook.plugin, ihook->get_widget, ei); +} + +static void eih_import(EImport *ei, EImportImporter *im, void *data) +{ + struct _EImportHookImporter *ihook = (EImportHookImporter *)im; + EImportHook *hook = im->user_data; + + e_plugin_invoke(hook->hook.plugin, ihook->import, ei); +} + +static void +eih_free_importer(EImportImporter *im, void *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); + char *tmp; + + d(printf(" loading import item\n")); + item = g_malloc0(sizeof(*item)); + + tmp = xmlGetProp(root, "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->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; + + return item; +error: + d(printf("error!\n")); + eih_free_importer((EImportImporter *)item, NULL); + return NULL; +} + +static int +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(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) +{ + int i; + + ((GObjectClass *)klass)->finalize = emph_finalise; + klass->construct = emph_construct; + + /* this is actually an abstract implementation but list it anyway */ + 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, (void *)map->type, (void *)map); +} diff --git a/e-util/e-import.h b/e-util/e-import.h new file mode 100644 index 0000000000..e5bf9b393a --- /dev/null +++ b/e-util/e-import.h @@ -0,0 +1,262 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Authors: Michel Zucchi + * + * Copyright 2003 Ximian, Inc. (www.ximian.com) + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef __E_IMPORT_H__ +#define __E_IMPORT_H__ + +#include +#include "libedataserver/e-msgport.h" + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +struct _GtkWindow; +struct _GtkWidget; + +/* This is an importer function */ + +typedef struct _EImport EImport; +typedef struct _EImportClass EImportClass; + +typedef struct _EImportImporter EImportImporter; +typedef struct _EImportFactory EImportFactory; +typedef struct _EImportTarget EImportTarget; + +typedef void (*EImportCompleteFunc)(EImport *ei, void *data); + +typedef void (*EImportFactoryFunc)(EImport *ei, void *data); +typedef void (*EImportImporterFunc)(EImportImporter *importer, void *data); +typedef gboolean (*EImportSupportedFunc)(EImport *ei, EImportImporter *im, void *data); +typedef struct _GtkWidget *(*EImportWidgetFunc)(EImport *ei, EImportImporter *im, void *data); +typedef void (*EImportImportFunc)(EImport *ei, EImportImporter *im, void *data); + +/* The global target types, implementors may add additional ones */ +enum _e_import_target_t { + E_IMPORT_TARGET_URI, /* simple file */ + E_IMPORT_TARGET_HOME, /* a home-directory thing, i.e. old applications */ + E_IMPORT_TARGET_LAST = 256 +}; + +/** + * struct _EImportImporter - + * + * @type: target type + * @priority: Priority of importer. Higher values will be processed first. + * @supported: Callback to see if this target is supported by the importer. + * @get_widget: A widget factory for this importer, if it needs any extra information in the druid. It will update the target. + * @import: Run the import. + * @user_data: User data for the callbacks; + * + * Base importer description. + **/ +struct _EImportImporter { + enum _e_import_target_t type; + + int pri; + + EImportSupportedFunc supported; + EImportWidgetFunc get_widget; + EImportImportFunc import; + + void *user_data; + + /* ?? */ + char *name; + char *description; +}; + +/** + * struct _EImportTarget - importation context. + * + * @import: The parent object. + * @type: The type of target, defined by implementing classes. + * + * The base target object is used as the parent and placeholder for + * import context for a given importer. + **/ +struct _EImportTarget { + struct _EImport *import; + + guint32 type; + + /* implementation fields follow, depends on target type */ +}; + +typedef struct _EImportTargetURI EImportTargetURI; +typedef struct _EImportTargetHome EImportTargetHome; + +struct _EImportTargetURI { + struct _EImportTarget target; + + char *uri_src; + char *uri_dest; +}; + +struct _EImportTargetHome { + struct _EImportTarget target; + + char *homedir; +}; + +/** + * struct _EImport - An importer management object. + * + * @object: Superclass. + * @id: ID of importer. + * @target: The current target. + * @importer: The chosen importer for the target. + * + **/ +struct _EImport { + GObject object; + + char *id; + + EImportTarget *target; + EImportImporter *importer; + + EImportCompleteFunc done; + void *done_data; +}; + +/** + * struct _EImportClass - Importer manager abstract class. + * + * @object_class: Superclass. + * @factories: A list of factories registered on this type of + * importuration manager. + * @set_target: A virtual method used to set the target on the + * importuration manager. This is used by subclasses so they may hook + * into changes on the target to propery drive the manager. + * @target_free: A virtual method used to free the target in an + * implementation-defined way. + * + **/ +struct _EImportClass { + GObjectClass object_class; + + EDList importers; + + void (*set_target)(EImport *ep, EImportTarget *t); + void (*target_free)(EImport *ep, EImportTarget *t); +}; + +GType e_import_get_type(void); + +/* Static class methods */ +void e_import_class_add_importer(EImportClass *klass, EImportImporter *importer, EImportImporterFunc freefunc, void *data); +void e_import_class_remove_importer(EImportClass *klass, EImportImporter *f); + +GSList *e_import_get_importers(EImport *emp, EImportTarget *target); + +EImport *e_import_construct(EImport *, const char *id); +void e_import_import(EImport *ei, EImportCompleteFunc done, void *data); + +struct _GtkWidget *e_import_get_widget(EImport *ei); + +void e_import_set_target(EImport *emp, EImportTarget *target); +struct _GtkWidget *e_import_create_window(EImport *emp, struct _GtkWindow *parent, const char *title); +void e_import_complete(EImport *); + +void *e_import_target_new(EImport *ep, int type, size_t size); +void e_import_target_free(EImport *ep, void *o); + +EImportTargetURI *e_import_target_new_uri(EImport *ei, const char *suri, const char *duri); +EImportTargetHome *e_import_target_new_home(EImport *ei, const char *home); + +/* ********************************************************************** */ + +/* 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 */ + + char *supported; + char *get_widget; + char *import; +}; + +/** + * 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 *); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __E_IMPORT_H__ */ -- cgit v1.2.3