diff options
Diffstat (limited to 'e-util')
-rw-r--r-- | e-util/e-marshal.list | 2 | ||||
-rw-r--r-- | e-util/e-plugin.c | 112 | ||||
-rw-r--r-- | e-util/e-util.c | 41 | ||||
-rw-r--r-- | e-util/e-util.h | 5 |
4 files changed, 93 insertions, 67 deletions
diff --git a/e-util/e-marshal.list b/e-util/e-marshal.list index d6a3f0cb55..c4426d46d7 100644 --- a/e-util/e-marshal.list +++ b/e-util/e-marshal.list @@ -1,4 +1,4 @@ -BOOLEAN:BOXED,POINTER,POINTER +BOOLEAN:BOXED,STRING BOOLEAN:INT,INT,OBJECT,INT,INT,UINT BOOLEAN:INT,POINTER,INT,OBJECT,INT,INT,UINT BOOLEAN:NONE diff --git a/e-util/e-plugin.c b/e-util/e-plugin.c index 5d77decfd9..49a15da651 100644 --- a/e-util/e-plugin.c +++ b/e-util/e-plugin.c @@ -31,6 +31,7 @@ #include "e-plugin.h" #include "e-util-private.h" +#include "e-util.h" /* plugin debug */ #define pd(x) @@ -487,79 +488,50 @@ e_plugin_add_load_path(const gchar *path) } static void -plugin_load_subclasses (void) +plugin_load_subclass (GType type, + GHashTable *hash_table) { - GType *children; - guint n_children, ii; - - ep_types = g_hash_table_new (g_str_hash, g_str_equal); - eph_types = g_hash_table_new (g_str_hash, g_str_equal); - ep_plugins = g_hash_table_new (g_str_hash, g_str_equal); - - /* Load EPlugin subclasses. */ - - children = g_type_children (E_TYPE_PLUGIN, &n_children); - - for (ii = 0; ii < n_children; ii++) { - EPluginClass *class; - - class = g_type_class_ref (children[ii]); - g_hash_table_insert (ep_types, (gpointer) class->type, class); - } + EPluginClass *class; - g_free (children); + class = g_type_class_ref (type); + g_hash_table_insert (hash_table, (gpointer) class->type, class); } static void -plugin_load_hook_subclasses (GType parent_type) +plugin_hook_load_subclass (GType type, + GHashTable *hash_table) { - GType *children; - guint n_children, ii; - - children = g_type_children (parent_type, &n_children); - - for (ii = 0; ii < n_children; ii++) { - EPluginHookClass *hook_class; - EPluginHookClass *dupe_class; - gpointer key; - - /* First load the child's children. */ - plugin_load_hook_subclasses (children[ii]); - - /* Skip abstract types. */ - if (G_TYPE_IS_ABSTRACT (children[ii])) - continue; - - hook_class = g_type_class_ref (children[ii]); - - /* Sanity check the hook class. */ - if (hook_class->id == NULL || *hook_class->id == '\0') { - g_warning ( - "%s has no hook ID, so skipping", - G_OBJECT_CLASS_NAME (hook_class)); - g_type_class_unref (hook_class); - continue; - } - - /* Check for class ID collisions. */ - dupe_class = g_hash_table_lookup (eph_types, hook_class->id); - if (dupe_class != NULL) { - g_warning ( - "%s and %s have the same hook " - "ID ('%s'), so skipping %s", - G_OBJECT_CLASS_NAME (dupe_class), - G_OBJECT_CLASS_NAME (hook_class), - hook_class->id, - G_OBJECT_CLASS_NAME (hook_class)); - g_type_class_unref (hook_class); - continue; - } + EPluginHookClass *hook_class; + EPluginHookClass *dupe_class; + gpointer key; + + hook_class = g_type_class_ref (type); + + /* Sanity check the hook class. */ + if (hook_class->id == NULL || *hook_class->id == '\0') { + g_warning ( + "%s has no hook ID, so skipping", + G_OBJECT_CLASS_NAME (hook_class)); + g_type_class_unref (hook_class); + return; + } - key = (gpointer) hook_class->id; - g_hash_table_insert (eph_types, key, hook_class); + /* Check for class ID collisions. */ + dupe_class = g_hash_table_lookup (hash_table, hook_class->id); + if (dupe_class != NULL) { + g_warning ( + "%s and %s have the same hook " + "ID ('%s'), so skipping %s", + G_OBJECT_CLASS_NAME (dupe_class), + G_OBJECT_CLASS_NAME (hook_class), + hook_class->id, + G_OBJECT_CLASS_NAME (hook_class)); + g_type_class_unref (hook_class); + return; } - g_free (children); + key = (gpointer) hook_class->id; + g_hash_table_insert (hash_table, key, hook_class); } /** @@ -580,11 +552,19 @@ e_plugin_load_plugins(void) if (eph_types != NULL) return 0; + ep_types = g_hash_table_new (g_str_hash, g_str_equal); + eph_types = g_hash_table_new (g_str_hash, g_str_equal); + ep_plugins = g_hash_table_new (g_str_hash, g_str_equal); + /* We require that all GTypes for EPlugin and EPluginHook * subclasses be registered prior to loading any plugins. * It greatly simplifies the loading process. */ - plugin_load_subclasses (); - plugin_load_hook_subclasses (E_TYPE_PLUGIN_HOOK); + e_type_traverse ( + E_TYPE_PLUGIN, (ETypeFunc) + plugin_load_subclass, ep_types); + e_type_traverse ( + E_TYPE_PLUGIN_HOOK, (ETypeFunc) + plugin_hook_load_subclass, eph_types); client = gconf_client_get_default (); ep_disabled = gconf_client_get_list ( diff --git a/e-util/e-util.c b/e-util/e-util.c index 57ec251c55..3c004e57cb 100644 --- a/e-util/e-util.c +++ b/e-util/e-util.c @@ -407,6 +407,47 @@ e_radio_action_get_current_action (GtkRadioAction *radio_action) } /** + * e_type_traverse: + * @parent_type: the root #GType to traverse from + * @func: the function to call for each visited #GType + * @user_data: user data to pass to the function + * + * Calls @func for all instantiable subtypes of @parent_type. + * + * This is often useful for extending functionality by way of #EModule. + * A module may register a subtype of @parent_type in its e_module_load() + * function. Then later on the application will call e_type_traverse() + * to instantiate all registered subtypes of @parent_type. + **/ +void +e_type_traverse (GType parent_type, + ETypeFunc func, + gpointer user_data) +{ + GType *children; + guint n_children, ii; + + g_return_if_fail (func != NULL); + + children = g_type_children (parent_type, &n_children); + + for (ii = 0; ii < n_children; ii++) { + GType type = children[ii]; + + /* Recurse over the child's children. */ + e_type_traverse (type, func, user_data); + + /* Skip abstract types. */ + if (G_TYPE_IS_ABSTRACT (type)) + continue; + + func (type, user_data); + } + + g_free (children); +} + +/** * e_str_without_underscores: * @s: the string to strip underscores from. * diff --git a/e-util/e-util.h b/e-util/e-util.h index 33bc940df7..1e2320914e 100644 --- a/e-util/e-util.h +++ b/e-util/e-util.h @@ -41,6 +41,8 @@ typedef enum { E_FOCUS_END } EFocus; +typedef void (*ETypeFunc) (GType type, gpointer user_data); + const gchar * e_get_user_data_dir (void); const gchar * e_get_accels_filename (void); void e_show_uri (GtkWindow *parent, @@ -59,6 +61,9 @@ void e_action_group_remove_all_actions (GtkActionGroup *action_group); GtkRadioAction *e_radio_action_get_current_action (GtkRadioAction *radio_action); +void e_type_traverse (GType parent_type, + ETypeFunc func, + gpointer user_data); gchar * e_str_without_underscores (const gchar *s); gint e_str_compare (gconstpointer x, |