From 13fb16f2793ee91099b1f2960c1875896991f1c4 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 21 Mar 2010 22:22:57 -0400 Subject: Demonstrate extending the EExtension API. Introduce e_extensible_list_extensions(), which provides extensible objects access to their own extensions, or a subset of them. Convert EShellBackend to an abstract EExtension subtype. EShell will load its extensions with e_extensible_load_extensions(), and then obtain a list of EShellBackend extensions as follows: shell_backends = e_extensible_list_extensions ( E_EXTENSIBLE (shell), E_TYPE_SHELL_BACKEND); Because EShellBackend is abstract, its GType is skipped while traversing the GType hierarchy to find EShell extensions. --- shell/e-shell-backend.c | 148 ++++++++++++------------------------------------ shell/e-shell-backend.h | 5 +- shell/e-shell.c | 34 +++++------ 3 files changed, 51 insertions(+), 136 deletions(-) (limited to 'shell') diff --git a/shell/e-shell-backend.c b/shell/e-shell-backend.c index ed354712d3..570e58db95 100644 --- a/shell/e-shell-backend.c +++ b/shell/e-shell-backend.c @@ -43,8 +43,6 @@ struct _EShellBackendPrivate { - gpointer shell; /* weak pointer */ - /* We keep a reference to corresponding EShellView subclass * since it keeps a reference back to us. This ensures the * subclass is not finalized before we are, otherwise it @@ -57,64 +55,39 @@ struct _EShellBackendPrivate { guint started : 1; }; -enum { - PROP_0, - PROP_SHELL -}; - enum { ACTIVITY_ADDED, LAST_SIGNAL }; -static gpointer parent_class; static guint signals[LAST_SIGNAL]; -static void -shell_backend_set_shell (EShellBackend *shell_backend, - EShell *shell) -{ - g_return_if_fail (shell_backend->priv->shell == NULL); - - shell_backend->priv->shell = shell; +G_DEFINE_ABSTRACT_TYPE (EShellBackend, e_shell_backend, E_TYPE_EXTENSION) - g_object_add_weak_pointer ( - G_OBJECT (shell_backend), - &shell_backend->priv->shell); -} - -static void -shell_backend_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) +static GObject * +shell_backend_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) { - switch (property_id) { - case PROP_SHELL: - shell_backend_set_shell ( - E_SHELL_BACKEND (object), - g_value_get_object (value)); - return; - } + EShellBackendPrivate *priv; + EShellBackendClass *class; + EShellViewClass *shell_view_class; + GObject *object; - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} + /* Chain up to parent's construct() method. */ + object = G_OBJECT_CLASS (e_shell_backend_parent_class)->constructor ( + type, n_construct_properties, construct_properties); -static void -shell_backend_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SHELL: - g_value_set_object ( - value, e_shell_backend_get_shell ( - E_SHELL_BACKEND (object))); - return; - } + class = E_SHELL_BACKEND_GET_CLASS (object); + priv = E_SHELL_BACKEND_GET_PRIVATE (object); - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + /* Install a reference to ourselves in the + * corresponding EShellViewClass structure. */ + shell_view_class = g_type_class_ref (class->shell_view_type); + shell_view_class->shell_backend = g_object_ref (object); + priv->shell_view_class = shell_view_class; + + return object; } static void @@ -124,19 +97,13 @@ shell_backend_dispose (GObject *object) priv = E_SHELL_BACKEND_GET_PRIVATE (object); - if (priv->shell != NULL) { - g_object_remove_weak_pointer ( - G_OBJECT (priv->shell), &priv->shell); - priv->shell = NULL; - } - if (priv->shell_view_class != NULL) { g_type_class_unref (priv->shell_view_class); priv->shell_view_class = NULL; } /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (parent_class)->dispose (object); + G_OBJECT_CLASS (e_shell_backend_parent_class)->dispose (object); } static void @@ -150,7 +117,7 @@ shell_backend_finalize (GObject *object) g_free (priv->data_dir); /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (parent_class)->finalize (object); + G_OBJECT_CLASS (e_shell_backend_parent_class)->finalize (object); } static const gchar * @@ -195,38 +162,24 @@ shell_backend_get_data_dir (EShellBackend *shell_backend) } static void -shell_backend_class_init (EShellBackendClass *class) +e_shell_backend_class_init (EShellBackendClass *class) { GObjectClass *object_class; + EExtensionClass *extension_class; - parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (EShellBackendPrivate)); object_class = G_OBJECT_CLASS (class); - object_class->set_property = shell_backend_set_property; - object_class->get_property = shell_backend_get_property; + object_class->constructor = shell_backend_constructor; object_class->dispose = shell_backend_dispose; object_class->finalize = shell_backend_finalize; + extension_class = E_EXTENSION_CLASS (class); + extension_class->extensible_type = E_TYPE_SHELL; + class->get_config_dir = shell_backend_get_config_dir; class->get_data_dir = shell_backend_get_data_dir; - /** - * EShellBackend:shell - * - * The #EShell singleton. - **/ - g_object_class_install_property ( - object_class, - PROP_SHELL, - g_param_spec_object ( - "shell", - _("Shell"), - _("The EShell singleton"), - E_TYPE_SHELL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - /** * EShellBackend::activity-added * @shell_backend: the #EShellBackend that emitted the signal @@ -245,44 +198,9 @@ shell_backend_class_init (EShellBackendClass *class) } static void -shell_backend_init (EShellBackend *shell_backend, - EShellBackendClass *class) +e_shell_backend_init (EShellBackend *shell_backend) { - EShellViewClass *shell_view_class; - shell_backend->priv = E_SHELL_BACKEND_GET_PRIVATE (shell_backend); - - /* Install a reference to ourselves in the corresponding - * EShellViewClass structure, */ - shell_view_class = g_type_class_ref (class->shell_view_type); - shell_view_class->shell_backend = g_object_ref (shell_backend); - shell_backend->priv->shell_view_class = shell_view_class; -} - -GType -e_shell_backend_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - const GTypeInfo type_info = { - sizeof (EShellBackendClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) shell_backend_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EShellBackend), - 0, /* n_preallocs */ - (GInstanceInitFunc) shell_backend_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - G_TYPE_OBJECT, "EShellBackend", &type_info, 0); - } - - return type; } /** @@ -364,9 +282,13 @@ e_shell_backend_get_data_dir (EShellBackend *shell_backend) EShell * e_shell_backend_get_shell (EShellBackend *shell_backend) { + EExtensible *extensible; + g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL); - return E_SHELL (shell_backend->priv->shell); + extensible = e_extension_get_extensible (E_EXTENSION (shell_backend)); + + return E_SHELL (extensible); } /** diff --git a/shell/e-shell-backend.h b/shell/e-shell-backend.h index df4abc8104..055a2a3322 100644 --- a/shell/e-shell-backend.h +++ b/shell/e-shell-backend.h @@ -24,6 +24,7 @@ #include #include +#include /* Standard GObject macros */ #define E_TYPE_SHELL_BACKEND \ @@ -60,7 +61,7 @@ typedef struct _EShellBackendPrivate EShellBackendPrivate; * functions below. **/ struct _EShellBackend { - GObject parent; + EExtension parent; EShellBackendPrivate *priv; }; @@ -94,7 +95,7 @@ struct _EShellBackend { * #EShellBackendClass contains a number of important settings for subclasses. **/ struct _EShellBackendClass { - GObjectClass parent_class; + EExtensionClass parent_class; GType shell_view_type; diff --git a/shell/e-shell.c b/shell/e-shell.c index c9dfd156e6..f877bca4ec 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -52,7 +52,7 @@ struct _EShellPrivate { GtkWidget *preferences_window; /* Shell Backends */ - GList *loaded_backends; + GList *loaded_backends; /* not referenced */ GHashTable *backends_by_name; GHashTable *backends_by_scheme; @@ -407,23 +407,14 @@ shell_split_and_insert_items (GHashTable *hash_table, } static void -shell_add_backend (GType type, - EShell *shell) +shell_process_backend (EShellBackend *shell_backend, + EShell *shell) { EShellBackendClass *class; - EShellBackend *shell_backend; GHashTable *backends_by_name; GHashTable *backends_by_scheme; const gchar *string; - shell_backend = g_object_new (type, "shell", shell, NULL); - - shell->priv->loaded_backends = g_list_insert_sorted ( - shell->priv->loaded_backends, shell_backend, - (GCompareFunc) e_shell_backend_compare); - - /* Bookkeeping */ - class = E_SHELL_BACKEND_GET_CLASS (shell_backend); backends_by_name = shell->priv->backends_by_name; backends_by_scheme = shell->priv->backends_by_scheme; @@ -601,10 +592,6 @@ shell_dispose (GObject *object) priv->preferences_window = NULL; } - g_list_foreach (priv->loaded_backends, (GFunc) g_object_unref, NULL); - g_list_free (priv->loaded_backends); - priv->loaded_backends = NULL; - if (priv->preparing_for_line_change != NULL) { g_object_remove_weak_pointer ( G_OBJECT (priv->preparing_for_line_change), @@ -629,6 +616,8 @@ shell_finalize (GObject *object) if (!unique_app_is_running (UNIQUE_APP (object))) e_file_lock_destroy (); + g_list_free (priv->loaded_backends); + g_free (priv->geometry); g_free (priv->module_directory); @@ -640,6 +629,7 @@ static void shell_constructed (GObject *object) { EShellPrivate *priv; + GList *list; priv = E_SHELL_GET_PRIVATE (object); @@ -659,11 +649,13 @@ shell_constructed (GObject *object) shell_load_modules (E_SHELL (object)); - e_type_traverse ( - E_TYPE_SHELL_BACKEND, (ETypeFunc) - shell_add_backend, object); - - e_extensible_load_extensions (E_EXTENSIBLE (object)); + /* Process shell backends. */ + list = g_list_sort ( + e_extensible_list_extensions ( + E_EXTENSIBLE (object), E_TYPE_SHELL_BACKEND), + (GCompareFunc) e_shell_backend_compare); + g_list_foreach (list, (GFunc) shell_process_backend, object); + priv->loaded_backends = list; } static UniqueResponse -- cgit v1.2.3