diff --git a/app/core/gimp-modules.c b/app/core/gimp-modules.c index a10e4ee797..129a9ce217 100644 --- a/app/core/gimp-modules.c +++ b/app/core/gimp-modules.c @@ -157,10 +157,15 @@ add_to_inhibit_string (gpointer data, GimpModule *module = data; GString *str = user_data; - if (module->load_inhibit) + if (! gimp_module_get_auto_load (module)) { + GFile *file = gimp_module_get_file (module); + gchar *path = g_file_get_path (file); + g_string_append_c (str, G_SEARCHPATH_SEPARATOR); - g_string_append (str, module->filename); + g_string_append (str, path); + + g_free (path); } } diff --git a/app/dialogs/module-dialog.c b/app/dialogs/module-dialog.c index 6ea0d53189..045ae61da4 100644 --- a/app/dialogs/module-dialog.c +++ b/app/dialogs/module-dialog.c @@ -333,7 +333,7 @@ dialog_enabled_toggled (GtkCellRendererToggle *celltoggle, if (module) { - gimp_module_set_load_inhibit (module, ! module->load_inhibit); + gimp_module_set_auto_load (module, ! gimp_module_get_auto_load (module)); g_object_unref (module); private->gimp->write_modulerc = TRUE; @@ -346,11 +346,14 @@ dialog_list_item_update (ModuleDialog *private, GtkTreeIter *iter, GimpModule *module) { + const GimpModuleInfo *info = gimp_module_get_info (module); + GFile *file = gimp_module_get_file (module); + gtk_list_store_set (private->list, iter, - COLUMN_NAME, (module->info ? - gettext (module->info->purpose) : - gimp_filename_to_utf8 (module->filename)), - COLUMN_ENABLED, ! module->load_inhibit, + COLUMN_NAME, (info ? + gettext (info->purpose) : + gimp_file_get_utf8_name (file)), + COLUMN_ENABLED, gimp_module_get_auto_load (module), COLUMN_MODULE, module, -1); } @@ -419,13 +422,14 @@ dialog_info_update (GimpModuleDB *db, GimpModule *module, ModuleDialog *private) { - GtkTreeModel *model = GTK_TREE_MODEL (private->list); - GtkTreeIter iter; - const gchar *text[N_INFOS] = { NULL, }; - gchar *location = NULL; - gboolean iter_valid; - gint i; - gboolean show_error; + GtkTreeModel *model = GTK_TREE_MODEL (private->list); + const GimpModuleInfo *info; + GtkTreeIter iter; + const gchar *text[N_INFOS] = { NULL, }; + const gchar *location = NULL; + gboolean iter_valid; + gint i; + gboolean show_error; for (iter_valid = gtk_tree_model_get_iter_first (model, &iter); iter_valid; @@ -461,33 +465,35 @@ dialog_info_update (GimpModuleDB *db, return; } - if (module->on_disk) - location = g_filename_display_name (module->filename); + if (gimp_module_is_on_disk (module)) + location = gimp_file_get_utf8_name (gimp_module_get_file (module)); - if (module->info) + info = gimp_module_get_info (module); + + if (info) { - text[INFO_AUTHOR] = module->info->author; - text[INFO_VERSION] = module->info->version; - text[INFO_DATE] = module->info->date; - text[INFO_COPYRIGHT] = module->info->copyright; - text[INFO_LOCATION] = module->on_disk ? location : _("Only in memory"); + text[INFO_AUTHOR] = info->author; + text[INFO_VERSION] = info->version; + text[INFO_DATE] = info->date; + text[INFO_COPYRIGHT] = info->copyright; + text[INFO_LOCATION] = gimp_module_is_on_disk (module) ? + location : _("Only in memory"); } else { - text[INFO_LOCATION] = (module->on_disk ? - location : _("No longer available")); + text[INFO_LOCATION] = gimp_module_is_on_disk (module) ? + location : _("No longer available"); } for (i = 0; i < N_INFOS; i++) gtk_label_set_text (GTK_LABEL (private->label[i]), text[i] ? text[i] : "--"); - g_free (location); /* Show errors */ - show_error = (module->state == GIMP_MODULE_STATE_ERROR && - module->last_module_error); + show_error = (gimp_module_get_state (module) == GIMP_MODULE_STATE_ERROR && + gimp_module_get_last_error (module)); gtk_label_set_text (GTK_LABEL (private->error_label), - show_error ? module->last_module_error : NULL); + show_error ? gimp_module_get_last_error (module) : NULL); gtk_widget_set_visible (private->error_box, show_error); } diff --git a/devel-docs/libgimpmodule/Makefile.am b/devel-docs/libgimpmodule/Makefile.am index ddb60afda9..66e9b15e8b 100644 --- a/devel-docs/libgimpmodule/Makefile.am +++ b/devel-docs/libgimpmodule/Makefile.am @@ -43,12 +43,12 @@ GTKDOC_CFLAGS = \ @CFLAGS@ \ -I$(top_srcdir) \ -I$(top_builddir) \ - @GLIB_CFLAGS@ \ + @GIO_CFLAGS@ \ @GMODULE_NO_EXPORT_CFLAGS@ GTKDOC_LIBS = \ $(top_builddir)/libgimpmodule/libgimpmodule-$(GIMP_API_VERSION).la \ - @GLIB_LIBS@ \ + @GIO_LIBS@ \ @GMODULE_NO_EXPORT_LIBS@ diff --git a/devel-docs/libgimpmodule/libgimpmodule3-sections.txt b/devel-docs/libgimpmodule/libgimpmodule3-sections.txt index ec7daa2776..747635679c 100644 --- a/devel-docs/libgimpmodule/libgimpmodule3-sections.txt +++ b/devel-docs/libgimpmodule/libgimpmodule3-sections.txt @@ -1,6 +1,5 @@
gimpmodule -GimpModule GimpModuleInfo GimpModuleState GimpModuleQueryFunc @@ -10,15 +9,18 @@ GimpModuleError GIMP_MODULE_ABI_VERSION GimpModule gimp_module_new -gimp_module_modified gimp_module_query_module -gimp_module_set_load_inhibit -gimp_module_state_name -gimp_module_info_new -gimp_module_info_copy -gimp_module_info_free +gimp_module_get_file +gimp_module_get_auto_load +gimp_module_set_auto_load +gimp_module_is_loaded +gimp_module_is_on_disk +gimp_module_get_info +gimp_module_get_last_error +gimp_module_get_state gimp_module_error_quark +GimpModule GimpModuleClass GimpModulePrivate GIMP_MODULE @@ -32,7 +34,6 @@ GIMP_MODULE_GET_CLASS
gimpmoduledb -GimpModuleDB GimpModuleDB gimp_module_db_new gimp_module_db_get_modules @@ -43,6 +44,7 @@ gimp_module_db_get_load_inhibit gimp_module_db_load gimp_module_db_refresh +GimpModuleDB GimpModuleDBClass GimpModuleDBPrivate GIMP_MODULE_DB diff --git a/devel-docs/libgimpmodule/libgimpmodule3.types b/devel-docs/libgimpmodule/libgimpmodule3.types index f9aa6670ca..389ec65740 100644 --- a/devel-docs/libgimpmodule/libgimpmodule3.types +++ b/devel-docs/libgimpmodule/libgimpmodule3.types @@ -1,4 +1,4 @@ -#include +#include #include gimp_module_get_type diff --git a/libgimpmodule/gimpmodule.c b/libgimpmodule/gimpmodule.c index 3bd8f67834..3a3ea55ede 100644 --- a/libgimpmodule/gimpmodule.c +++ b/libgimpmodule/gimpmodule.c @@ -39,7 +39,11 @@ * loading using #GModule. * @see_also: #GModule, #GTypeModule * - * A #GTypeModule subclass which implements module loading using #GModule. + * #GimpModule is a generic mechanism to dynamically load modules into + * GIMP. It is a #GTypeModule subclass, implementing module loading + * using #GModule. #GimpModule does not know which functionality is + * implemented by the modules, it just provides a framework to get + * arbitrary #GType implementations loaded from disk. **/ @@ -50,6 +54,25 @@ enum }; +struct _GimpModulePrivate +{ + GFile *file; /* path to the module */ + gboolean auto_load; /* auto-load the module on creation */ + gboolean verbose; /* verbose error reporting */ + + GimpModuleInfo *info; /* returned values from module_query */ + GimpModuleState state; /* what's happened to the module */ + gchar *last_error; + + gboolean on_disk; /* TRUE if file still exists */ + + GModule *module; /* handle on the module */ + + GimpModuleQueryFunc query_module; + GimpModuleRegisterFunc register_module; +}; + + static void gimp_module_finalize (GObject *object); static gboolean gimp_module_load (GTypeModule *module); @@ -59,9 +82,19 @@ static gboolean gimp_module_open (GimpModule *module); static gboolean gimp_module_close (GimpModule *module); static void gimp_module_set_last_error (GimpModule *module, const gchar *error_str); +static void gimp_module_modified (GimpModule *module); + +static GimpModuleInfo * gimp_module_info_new (guint32 abi_version, + const gchar *purpose, + const gchar *author, + const gchar *version, + const gchar *copyright, + const gchar *date); +static GimpModuleInfo * gimp_module_info_copy (const GimpModuleInfo *info); +static void gimp_module_info_free (GimpModuleInfo *info); -G_DEFINE_TYPE (GimpModule, gimp_module, G_TYPE_TYPE_MODULE) +G_DEFINE_TYPE_WITH_PRIVATE (GimpModule, gimp_module, G_TYPE_TYPE_MODULE) #define parent_class gimp_module_parent_class @@ -94,18 +127,9 @@ gimp_module_class_init (GimpModuleClass *klass) static void gimp_module_init (GimpModule *module) { - module->filename = NULL; - module->verbose = FALSE; - module->state = GIMP_MODULE_STATE_ERROR; - module->on_disk = FALSE; - module->load_inhibit = FALSE; + module->priv = gimp_module_get_instance_private (module); - module->module = NULL; - module->info = NULL; - module->last_module_error = NULL; - - module->query_module = NULL; - module->register_module = NULL; + module->priv->state = GIMP_MODULE_STATE_ERROR; } static void @@ -113,9 +137,9 @@ gimp_module_finalize (GObject *object) { GimpModule *module = GIMP_MODULE (object); - g_clear_pointer (&module->info, gimp_module_info_free); - g_clear_pointer (&module->last_module_error, g_free); - g_clear_pointer (&module->filename, g_free); + g_clear_object (&module->priv->file); + g_clear_pointer (&module->priv->info, gimp_module_info_free); + g_clear_pointer (&module->priv->last_error, g_free); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -126,12 +150,12 @@ gimp_module_load (GTypeModule *module) GimpModule *gimp_module = GIMP_MODULE (module); gpointer func; - g_return_val_if_fail (gimp_module->filename != NULL, FALSE); - g_return_val_if_fail (gimp_module->module == NULL, FALSE); + g_return_val_if_fail (gimp_module->priv->file != NULL, FALSE); + g_return_val_if_fail (gimp_module->priv->module == NULL, FALSE); - if (gimp_module->verbose) + if (gimp_module->priv->verbose) g_print ("Loading module '%s'\n", - gimp_filename_to_utf8 (gimp_module->filename)); + gimp_file_get_utf8_name (gimp_module->priv->file)); if (! gimp_module_open (gimp_module)) return FALSE; @@ -140,41 +164,42 @@ gimp_module_load (GTypeModule *module) return FALSE; /* find the gimp_module_register symbol */ - if (! g_module_symbol (gimp_module->module, "gimp_module_register", &func)) + if (! g_module_symbol (gimp_module->priv->module, "gimp_module_register", + &func)) { gimp_module_set_last_error (gimp_module, "Missing gimp_module_register() symbol"); g_message (_("Module '%s' load error: %s"), - gimp_filename_to_utf8 (gimp_module->filename), - gimp_module->last_module_error); + gimp_file_get_utf8_name (gimp_module->priv->file), + gimp_module->priv->last_error); gimp_module_close (gimp_module); - gimp_module->state = GIMP_MODULE_STATE_ERROR; + gimp_module->priv->state = GIMP_MODULE_STATE_ERROR; return FALSE; } - gimp_module->register_module = func; + gimp_module->priv->register_module = func; - if (! gimp_module->register_module (module)) + if (! gimp_module->priv->register_module (module)) { gimp_module_set_last_error (gimp_module, "gimp_module_register() returned FALSE"); g_message (_("Module '%s' load error: %s"), - gimp_filename_to_utf8 (gimp_module->filename), - gimp_module->last_module_error); + gimp_file_get_utf8_name (gimp_module->priv->file), + gimp_module->priv->last_error); gimp_module_close (gimp_module); - gimp_module->state = GIMP_MODULE_STATE_LOAD_FAILED; + gimp_module->priv->state = GIMP_MODULE_STATE_LOAD_FAILED; return FALSE; } - gimp_module->state = GIMP_MODULE_STATE_LOADED; + gimp_module->priv->state = GIMP_MODULE_STATE_LOADED; return TRUE; } @@ -184,11 +209,11 @@ gimp_module_unload (GTypeModule *module) { GimpModule *gimp_module = GIMP_MODULE (module); - g_return_if_fail (gimp_module->module != NULL); + g_return_if_fail (gimp_module->priv->module != NULL); - if (gimp_module->verbose) + if (gimp_module->priv->verbose) g_print ("Unloading module '%s'\n", - gimp_filename_to_utf8 (gimp_module->filename)); + gimp_file_get_utf8_name (gimp_module->priv->file)); gimp_module_close (gimp_module); } @@ -198,31 +223,31 @@ gimp_module_unload (GTypeModule *module) /** * gimp_module_new: - * @filename: The filename of a loadable module. - * @load_inhibit: Pass %TRUE to exclude this module from auto-loading. - * @verbose: Pass %TRUE to enable debugging output. + * @file: A #GFile pointing to a loadable module. + * @auto_load: Pass %TRUE to exclude this module from auto-loading. + * @verbose: Pass %TRUE to enable debugging output. * * Creates a new #GimpModule instance. * * Returns: The new #GimpModule object. **/ GimpModule * -gimp_module_new (const gchar *filename, - gboolean load_inhibit, - gboolean verbose) +gimp_module_new (GFile *file, + gboolean auto_load, + gboolean verbose) { GimpModule *module; - g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (g_file_is_native (file), NULL); module = g_object_new (GIMP_TYPE_MODULE, NULL); - module->filename = g_strdup (filename); - module->load_inhibit = load_inhibit ? TRUE : FALSE; - module->verbose = verbose ? TRUE : FALSE; - module->on_disk = TRUE; + module->priv->file = g_object_ref (file); + module->priv->auto_load = auto_load ? TRUE : FALSE; + module->priv->verbose = verbose ? TRUE : FALSE; - if (! module->load_inhibit) + if (module->priv->auto_load) { if (gimp_module_load (G_TYPE_MODULE (module))) gimp_module_unload (G_TYPE_MODULE (module)); @@ -231,21 +256,173 @@ gimp_module_new (const gchar *filename, { if (verbose) g_print ("Skipping module '%s'\n", - gimp_filename_to_utf8 (filename)); + gimp_file_get_utf8_name (file)); - module->state = GIMP_MODULE_STATE_NOT_LOADED; + module->priv->state = GIMP_MODULE_STATE_NOT_LOADED; } return module; } +/** + * gimp_module_get_file: + * @module: A #GimpModule + * + * Returns #GFile of the @module, + * + * Returns: The @module's #GFile. + * + * Since: 3.0 + **/ +GFile * +gimp_module_get_file (GimpModule *module) +{ + g_return_val_if_fail (GIMP_IS_MODULE (module), NULL); + + return module->priv->file; +} + +/** + * gimp_module_set_auto_load: + * @module: A #GimpModule + * @auto_load: Pass %FALSE to exclude this module from auto-loading + * + * Sets the @auto_load property if the module. Emits "modified". + * + * Since: 3.0 + **/ +void +gimp_module_set_auto_load (GimpModule *module, + gboolean auto_load) +{ + g_return_if_fail (GIMP_IS_MODULE (module)); + + if (auto_load != module->priv->auto_load) + { + module->priv->auto_load = auto_load ? TRUE : FALSE; + + gimp_module_modified (module); + } +} + +/** + * gimp_module_get_auto_load: + * @module: A #GimpModule + * + * Returns whether this @module in automatically loaded at startup. + * + * Returns: The @module's 'auto_load' property. + * + * Since: 3.0 + **/ +gboolean +gimp_module_get_auto_load (GimpModule *module) +{ + g_return_val_if_fail (GIMP_IS_MODULE (module), FALSE); + + return module->priv->auto_load; +} + +/** + * gimp_module_is_on_disk: + * @module: A #GimpModule + * + * Returns: Whether the @module is present on diak. + * + * Since: 3.0 + **/ +gboolean +gimp_module_is_on_disk (GimpModule *module) +{ + gboolean old_on_disk; + + g_return_val_if_fail (GIMP_IS_MODULE (module), FALSE); + + old_on_disk = module->priv->on_disk; + + module->priv->on_disk = + (g_file_query_file_type (module->priv->file, + G_FILE_QUERY_INFO_NONE, NULL) == + G_FILE_TYPE_REGULAR); + + if (module->priv->on_disk != old_on_disk) + gimp_module_modified (module); + + return module->priv->on_disk; +} + +/** + * gimp_module_is_loaded: + * @module: A #GimpModule + * + * Returns: Whether the @module is currently loaded. + * + * Since: 3.0 + **/ +gboolean +gimp_module_is_loaded (GimpModule *module) +{ + g_return_val_if_fail (GIMP_IS_MODULE (module), FALSE); + + return module->priv->module != NULL; +} + +/** + * gimp_module_get_info: + * @module: A #GimpModule + * + * Returns: (transfer none): The @module's #GimpModuleInfo as provided + * by the actual module, or %NULL. + * + * Since: 3.0 + **/ +const GimpModuleInfo * +gimp_module_get_info (GimpModule *module) +{ + g_return_val_if_fail (GIMP_IS_MODULE (module), NULL); + + return module->priv->info; +} + +/** + * gimp_module_get_state: + * @module: A #GimpModule + * + * Returns: The @module's state. + * + * Since: 3.0 + **/ +GimpModuleState +gimp_module_get_state (GimpModule *module) +{ + g_return_val_if_fail (GIMP_IS_MODULE (module), GIMP_MODULE_STATE_ERROR); + + return module->priv->state; +} + +/** + * gimp_module_get_last_error: + * @module: A #GimpModule + * + * Returns: The @module's last error message. + * + * Since: 3.0 + **/ +const gchar * +gimp_module_get_last_error (GimpModule *module) +{ + g_return_val_if_fail (GIMP_IS_MODULE (module), NULL); + + return module->priv->last_error; +} + /** * gimp_module_query_module: * @module: A #GimpModule. * * Queries the module without actually registering any of the types it - * may implement. After successful query, the @info field of the - * #GimpModule struct will be available for further inspection. + * may implement. After successful query, gimp_module_get_info() can be + * used to get further about the module. * * Returns: %TRUE on success. **/ @@ -258,7 +435,7 @@ gimp_module_query_module (GimpModule *module) g_return_val_if_fail (GIMP_IS_MODULE (module), FALSE); - if (! module->module) + if (! module->priv->module) { if (! gimp_module_open (module)) return FALSE; @@ -267,30 +444,26 @@ gimp_module_query_module (GimpModule *module) } /* find the gimp_module_query symbol */ - if (! g_module_symbol (module->module, "gimp_module_query", &func)) + if (! g_module_symbol (module->priv->module, "gimp_module_query", &func)) { gimp_module_set_last_error (module, "Missing gimp_module_query() symbol"); g_message (_("Module '%s' load error: %s"), - gimp_filename_to_utf8 (module->filename), - module->last_module_error); + gimp_file_get_utf8_name (module->priv->file), + module->priv->last_error); gimp_module_close (module); - module->state = GIMP_MODULE_STATE_ERROR; + module->priv->state = GIMP_MODULE_STATE_ERROR; return FALSE; } - module->query_module = func; + module->priv->query_module = func; - if (module->info) - { - gimp_module_info_free (module->info); - module->info = NULL; - } + g_clear_pointer (&module->priv->info, gimp_module_info_free); - info = module->query_module (G_TYPE_MODULE (module)); + info = module->priv->query_module (G_TYPE_MODULE (module)); if (! info || info->abi_version != GIMP_MODULE_ABI_VERSION) { @@ -300,16 +473,16 @@ gimp_module_query_module (GimpModule *module) "gimp_module_query() returned NULL"); g_message (_("Module '%s' load error: %s"), - gimp_filename_to_utf8 (module->filename), - module->last_module_error); + gimp_file_get_utf8_name (module->priv->file), + module->priv->last_error); gimp_module_close (module); - module->state = GIMP_MODULE_STATE_ERROR; + module->priv->state = GIMP_MODULE_STATE_ERROR; return FALSE; } - module->info = gimp_module_info_copy (info); + module->priv->info = gimp_module_info_copy (info); if (close_module) return gimp_module_close (module); @@ -317,68 +490,6 @@ gimp_module_query_module (GimpModule *module) return TRUE; } -/** - * gimp_module_modified: - * @module: A #GimpModule. - * - * Emits the "modified" signal. Call it whenever you have modified the module - * manually (which you shouldn't do). - **/ -void -gimp_module_modified (GimpModule *module) -{ - g_return_if_fail (GIMP_IS_MODULE (module)); - - g_signal_emit (module, module_signals[MODIFIED], 0); -} - -/** - * gimp_module_set_load_inhibit: - * @module: A #GimpModule. - * @load_inhibit: Pass %TRUE to exclude this module from auto-loading. - * - * Sets the @load_inhibit property if the module. Emits "modified". - **/ -void -gimp_module_set_load_inhibit (GimpModule *module, - gboolean load_inhibit) -{ - g_return_if_fail (GIMP_IS_MODULE (module)); - - if (load_inhibit != module->load_inhibit) - { - module->load_inhibit = load_inhibit ? TRUE : FALSE; - - gimp_module_modified (module); - } -} - -/** - * gimp_module_state_name: - * @state: A #GimpModuleState. - * - * Returns the translated textual representation of a #GimpModuleState. - * The returned string must not be freed. - * - * Returns: The @state's name. - **/ -const gchar * -gimp_module_state_name (GimpModuleState state) -{ - static const gchar * const statenames[] = - { - N_("Module error"), - N_("Loaded"), - N_("Load failed"), - N_("Not loaded") - }; - - g_return_val_if_fail (state >= GIMP_MODULE_STATE_ERROR && - state <= GIMP_MODULE_STATE_NOT_LOADED, NULL); - - return gettext (statenames[state]); -} - /** * gimp_module_error_quark: * @@ -400,16 +511,20 @@ gimp_module_error_quark (void) static gboolean gimp_module_open (GimpModule *module) { - module->module = g_module_open (module->filename, 0); + gchar *path = g_file_get_path (module->priv->file); - if (! module->module) + module->priv->module = g_module_open (path, 0); + + g_free (path); + + if (! module->priv->module) { - module->state = GIMP_MODULE_STATE_ERROR; + module->priv->state = GIMP_MODULE_STATE_ERROR; gimp_module_set_last_error (module, g_module_error ()); g_message (_("Module '%s' load error: %s"), - gimp_filename_to_utf8 (module->filename), - module->last_module_error); + gimp_file_get_utf8_name (module->priv->file), + module->priv->last_error); return FALSE; } @@ -420,12 +535,12 @@ gimp_module_open (GimpModule *module) static gboolean gimp_module_close (GimpModule *module) { - g_module_close (module->module); /* FIXME: error handling */ - module->module = NULL; - module->query_module = NULL; - module->register_module = NULL; + g_module_close (module->priv->module); /* FIXME: error handling */ + module->priv->module = NULL; + module->priv->query_module = NULL; + module->priv->register_module = NULL; - module->state = GIMP_MODULE_STATE_NOT_LOADED; + module->priv->state = GIMP_MODULE_STATE_NOT_LOADED; return TRUE; } @@ -434,10 +549,18 @@ static void gimp_module_set_last_error (GimpModule *module, const gchar *error_str) { - if (module->last_module_error) - g_free (module->last_module_error); + if (module->priv->last_error) + g_free (module->priv->last_error); - module->last_module_error = g_strdup (error_str); + module->priv->last_error = g_strdup (error_str); +} + +static void +gimp_module_modified (GimpModule *module) +{ + g_return_if_fail (GIMP_IS_MODULE (module)); + + g_signal_emit (module, module_signals[MODIFIED], 0); } @@ -456,7 +579,7 @@ gimp_module_set_last_error (GimpModule *module, * * Returns: The new #GimpModuleInfo struct. **/ -GimpModuleInfo * +static GimpModuleInfo * gimp_module_info_new (guint32 abi_version, const gchar *purpose, const gchar *author, @@ -484,7 +607,7 @@ gimp_module_info_new (guint32 abi_version, * * Returns: The new copy. **/ -GimpModuleInfo * +static GimpModuleInfo * gimp_module_info_copy (const GimpModuleInfo *info) { g_return_val_if_fail (info != NULL, NULL); @@ -503,7 +626,7 @@ gimp_module_info_copy (const GimpModuleInfo *info) * * Frees the passed #GimpModuleInfo. **/ -void +static void gimp_module_info_free (GimpModuleInfo *info) { g_return_if_fail (info != NULL); diff --git a/libgimpmodule/gimpmodule.def b/libgimpmodule/gimpmodule.def index 5b7fc0b0bc..380498bfa2 100644 --- a/libgimpmodule/gimpmodule.def +++ b/libgimpmodule/gimpmodule.def @@ -9,12 +9,14 @@ EXPORTS gimp_module_db_set_load_inhibit gimp_module_db_set_verbose gimp_module_error_quark + gimp_module_get_auto_load + gimp_module_get_file + gimp_module_get_info + gimp_module_get_last_error + gimp_module_get_state gimp_module_get_type - gimp_module_info_copy - gimp_module_info_free - gimp_module_info_new - gimp_module_modified + gimp_module_is_loaded + gimp_module_is_on_disk gimp_module_new gimp_module_query_module - gimp_module_set_load_inhibit - gimp_module_state_name + gimp_module_set_auto_load diff --git a/libgimpmodule/gimpmodule.h b/libgimpmodule/gimpmodule.h index 9e8e8f4f5c..783b07dedf 100644 --- a/libgimpmodule/gimpmodule.h +++ b/libgimpmodule/gimpmodule.h @@ -160,47 +160,11 @@ G_MODULE_EXPORT gboolean gimp_module_register (GTypeModule *module typedef struct _GimpModulePrivate GimpModulePrivate; typedef struct _GimpModuleClass GimpModuleClass; -/** - * GimpModule: - * @filename: - * @verbose: - * @state: - * @on_disk: - * @load_inhibit: - * @info: - * @last_module_error: - * - * #GimpModule is a generic mechanism to dynamically load modules into - * GIMP. It is a #GTypeModule subclass, implementing module loading - * using #GModule. #GimpModule does not know which functionality is - * implemented by the modules, it just provides a framework to get - * arbitrary #GType implementations loaded from disk. - **/ struct _GimpModule { GTypeModule parent_instance; GimpModulePrivate *priv; - - /* FIXME MOVE TO PRIVATE */ - /*< public >*/ - gchar *filename; /* path to the module */ - gboolean verbose; /* verbose error reporting */ - GimpModuleState state; /* what's happened to the module */ - gboolean on_disk; /* TRUE if file still exists */ - gboolean load_inhibit; /* user requests not to load at boot time */ - - /* stuff from now on may be NULL depending on the state the module is in */ - /*< private >*/ - GModule *module; /* handle on the module */ - - /*< public >*/ - GimpModuleInfo *info; /* returned values from module_query */ - gchar *last_module_error; - - /*< private >*/ - GimpModuleQueryFunc query_module; - GimpModuleRegisterFunc register_module; }; struct _GimpModuleClass @@ -221,31 +185,26 @@ struct _GimpModuleClass }; -GType gimp_module_get_type (void) G_GNUC_CONST; +GType gimp_module_get_type (void) G_GNUC_CONST; -GimpModule * gimp_module_new (const gchar *filename, - gboolean load_inhibit, - gboolean verbose); +GimpModule * gimp_module_new (GFile *file, + gboolean auto_load, + gboolean verbose); -gboolean gimp_module_query_module (GimpModule *module); +GFile * gimp_module_get_file (GimpModule *module); -void gimp_module_modified (GimpModule *module); -void gimp_module_set_load_inhibit (GimpModule *module, - gboolean load_inhibit); +void gimp_module_set_auto_load (GimpModule *module, + gboolean auto_load); +gboolean gimp_module_get_auto_load (GimpModule *module); -const gchar * gimp_module_state_name (GimpModuleState state); +gboolean gimp_module_is_on_disk (GimpModule *module); +gboolean gimp_module_is_loaded (GimpModule *module); +const GimpModuleInfo * gimp_module_get_info (GimpModule *module); +GimpModuleState gimp_module_get_state (GimpModule *module); +const gchar * gimp_module_get_last_error (GimpModule *module); -/* GimpModuleInfo functions */ - -GimpModuleInfo * gimp_module_info_new (guint32 abi_version, - const gchar *purpose, - const gchar *author, - const gchar *version, - const gchar *copyright, - const gchar *date); -GimpModuleInfo * gimp_module_info_copy (const GimpModuleInfo *info); -void gimp_module_info_free (GimpModuleInfo *info); +gboolean gimp_module_query_module (GimpModule *module); G_END_DECLS diff --git a/libgimpmodule/gimpmoduledb.c b/libgimpmodule/gimpmoduledb.c index 00539a5baf..9758229361 100644 --- a/libgimpmodule/gimpmoduledb.c +++ b/libgimpmodule/gimpmoduledb.c @@ -30,6 +30,8 @@ #include "gimpmodule.h" #include "gimpmoduledb.h" +#include "libgimp/libgimp-intl.h" + /** * SECTION: gimpmoduledb @@ -49,8 +51,6 @@ enum LAST_SIGNAL }; -#define DUMP_DB FALSE - struct _GimpModuleDBPrivate { @@ -60,8 +60,6 @@ struct _GimpModuleDBPrivate gboolean verbose; }; -#define GET_PRIVATE(obj) (((GimpModuleDB *) (obj))->priv) - static void gimp_module_db_finalize (GObject *object); @@ -70,15 +68,11 @@ static void gimp_module_db_load_directory (GimpModuleDB *db, static void gimp_module_db_load_module (GimpModuleDB *db, GFile *file); -static GimpModule * gimp_module_db_module_find_by_path (GimpModuleDB *db, - const char *fullpath); +static GimpModule * gimp_module_db_module_find_by_file (GimpModuleDB *db, + GFile *file); static void gimp_module_db_module_dump_func (gpointer data, gpointer user_data); -static void gimp_module_db_module_on_disk_func (gpointer data, - gpointer user_data); -static void gimp_module_db_module_remove_func (gpointer data, - gpointer user_data); static void gimp_module_db_module_modified (GimpModule *module, GimpModuleDB *db); @@ -145,24 +139,18 @@ gimp_module_db_init (GimpModuleDB *db) static void gimp_module_db_finalize (GObject *object) { - GimpModuleDBPrivate *priv = GET_PRIVATE (object); + GimpModuleDB *db = GIMP_MODULE_DB (object); + GList *list; - if (priv->modules) + for (list = db->priv->modules; list; list = g_list_next (list)) { - GList *list; - - for (list = priv->modules; list; list = g_list_next (list)) - { - g_signal_handlers_disconnect_by_func (list->data, - gimp_module_db_module_modified, - object); - } - - g_list_free (priv->modules); - priv->modules = NULL; + g_signal_handlers_disconnect_by_func (list->data, + gimp_module_db_module_modified, + object); } - g_clear_pointer (&priv->load_inhibit, g_free); + g_clear_pointer (&db->priv->modules, g_list_free); + g_clear_pointer (&db->priv->load_inhibit, g_free); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -205,7 +193,7 @@ gimp_module_db_get_modules (GimpModuleDB *db) { g_return_val_if_fail (GIMP_IS_MODULE_DB (db), NULL); - return GET_PRIVATE (db)->modules; + return db->priv->modules; } /** @@ -223,7 +211,7 @@ gimp_module_db_set_verbose (GimpModuleDB *db, { g_return_if_fail (GIMP_IS_MODULE_DB (db)); - GET_PRIVATE (db)->verbose = verbose ? TRUE : FALSE; + db->priv->verbose = verbose ? TRUE : FALSE; } /** @@ -241,13 +229,14 @@ gimp_module_db_get_verbose (GimpModuleDB *db) { g_return_val_if_fail (GIMP_IS_MODULE_DB (db), FALSE); - return GET_PRIVATE (db)->verbose; + return db->priv->verbose; } static gboolean -is_in_inhibit_list (const gchar *filename, +is_in_inhibit_list (GFile *file, const gchar *inhibit_list) { + gchar *filename; gchar *p; gint pathlen; const gchar *start; @@ -256,9 +245,14 @@ is_in_inhibit_list (const gchar *filename, if (! inhibit_list || ! strlen (inhibit_list)) return FALSE; + filename = g_file_get_path (file); + p = strstr (inhibit_list, filename); - if (!p) - return FALSE; + if (! p) + { + g_free (filename); + return FALSE; + } /* we have a substring, but check for colons either side */ start = p; @@ -274,6 +268,8 @@ is_in_inhibit_list (const gchar *filename, pathlen = strlen (filename); + g_free (filename); + if ((end - start) == pathlen) return TRUE; @@ -293,25 +289,24 @@ void gimp_module_db_set_load_inhibit (GimpModuleDB *db, const gchar *load_inhibit) { - GimpModuleDBPrivate *priv; - GList *list; + GList *list; g_return_if_fail (GIMP_IS_MODULE_DB (db)); - priv = GET_PRIVATE (db); + if (db->priv->load_inhibit) + g_free (db->priv->load_inhibit); - if (priv->load_inhibit) - g_free (priv->load_inhibit); + db->priv->load_inhibit = g_strdup (load_inhibit); - priv->load_inhibit = g_strdup (load_inhibit); - - for (list = priv->modules; list; list = g_list_next (list)) + for (list = db->priv->modules; list; list = g_list_next (list)) { GimpModule *module = list->data; + gboolean inhibit; - gimp_module_set_load_inhibit (module, - is_in_inhibit_list (module->filename, - load_inhibit)); + inhibit =is_in_inhibit_list (gimp_module_get_file (module), + load_inhibit); + + gimp_module_set_auto_load (module, ! inhibit); } } @@ -329,7 +324,7 @@ gimp_module_db_get_load_inhibit (GimpModuleDB *db) { g_return_val_if_fail (GIMP_IS_MODULE_DB (db), NULL); - return GET_PRIVATE (db)->load_inhibit; + return db->priv->load_inhibit; } /** @@ -346,13 +341,9 @@ void gimp_module_db_load (GimpModuleDB *db, const gchar *module_path) { - GimpModuleDBPrivate *priv; - g_return_if_fail (GIMP_IS_MODULE_DB (db)); g_return_if_fail (module_path != NULL); - priv = GET_PRIVATE (db); - if (g_module_supported ()) { GList *path; @@ -368,8 +359,8 @@ gimp_module_db_load (GimpModuleDB *db, g_list_free_full (path, (GDestroyNotify) g_object_unref); } - if (DUMP_DB) - g_list_foreach (priv->modules, gimp_module_db_module_dump_func, NULL); + if (FALSE) + g_list_foreach (db->priv->modules, gimp_module_db_module_dump_func, NULL); } /** @@ -389,22 +380,31 @@ void gimp_module_db_refresh (GimpModuleDB *db, const gchar *module_path) { - GimpModuleDBPrivate *priv; - GList *kill_list = NULL; + GList *list; g_return_if_fail (GIMP_IS_MODULE_DB (db)); g_return_if_fail (module_path != NULL); - priv = GET_PRIVATE (db); + list = db->priv->modules; - /* remove modules we don't have on disk anymore */ - g_list_foreach (priv->modules, - gimp_module_db_module_on_disk_func, - &kill_list); - g_list_foreach (kill_list, - gimp_module_db_module_remove_func, - db); - g_list_free (kill_list); + while (list) + { + GimpModule *module = list->data; + + list = g_list_next (list); + + if (! gimp_module_is_on_disk (module) && + ! gimp_module_is_loaded (module)) + { + g_signal_handlers_disconnect_by_func (module, + gimp_module_db_module_modified, + db); + + db->priv->modules = g_list_remove (db->priv->modules, module); + + g_signal_emit (db, db_signals[REMOVE], 0, module); + } + } /* walk filesystem and add new things we find */ gimp_module_db_load (db, module_path); @@ -452,52 +452,42 @@ static void gimp_module_db_load_module (GimpModuleDB *db, GFile *file) { - GimpModuleDBPrivate *priv = GET_PRIVATE (db); - GimpModule *module; - gchar *path; - gboolean load_inhibit; + GimpModule *module; + gboolean load_inhibit; if (! gimp_file_has_extension (file, "." G_MODULE_SUFFIX)) return; - path = g_file_get_path (file); - /* don't load if we already know about it */ - if (gimp_module_db_module_find_by_path (db, path)) - { - g_free (path); - return; - } + if (gimp_module_db_module_find_by_file (db, file)) + return; - load_inhibit = is_in_inhibit_list (path, priv->load_inhibit); + load_inhibit = is_in_inhibit_list (file, db->priv->load_inhibit); - module = gimp_module_new (path, - load_inhibit, - priv->verbose); - - g_free (path); + module = gimp_module_new (file, + ! load_inhibit, + db->priv->verbose); g_signal_connect (module, "modified", G_CALLBACK (gimp_module_db_module_modified), db); - priv->modules = g_list_append (priv->modules, module); + db->priv->modules = g_list_append (db->priv->modules, module); g_signal_emit (db, db_signals[ADD], 0, module); } static GimpModule * -gimp_module_db_module_find_by_path (GimpModuleDB *db, - const char *fullpath) +gimp_module_db_module_find_by_file (GimpModuleDB *db, + GFile *file) { - GimpModuleDBPrivate *priv = GET_PRIVATE (db); - GList *list; + GList *list; - for (list = priv->modules; list; list = g_list_next (list)) + for (list = db->priv->modules; list; list = g_list_next (list)) { GimpModule *module = list->data; - if (! strcmp (module->filename, fullpath)) + if (g_file_equal (file, gimp_module_get_file (module))) return module; } @@ -508,75 +498,44 @@ static void gimp_module_db_module_dump_func (gpointer data, gpointer user_data) { - GimpModule *module = data; + static const gchar * const statenames[] = + { + N_("Module error"), + N_("Loaded"), + N_("Load failed"), + N_("Not loaded") + }; + + GimpModule *module = data; + const GimpModuleInfo *info = gimp_module_get_info (module); g_print ("\n%s: %s\n", - gimp_filename_to_utf8 (module->filename), - gimp_module_state_name (module->state)); + gimp_file_get_utf8_name (gimp_module_get_file (module)), + gettext (statenames[gimp_module_get_state (module)])); +#if 0 g_print (" module: %p lasterr: %s query: %p register: %p\n", module->module, module->last_module_error ? module->last_module_error : "NONE", module->query_module, module->register_module); +#endif - if (module->info) + if (info) { g_print (" purpose: %s\n" " author: %s\n" " version: %s\n" " copyright: %s\n" " date: %s\n", - module->info->purpose ? module->info->purpose : "NONE", - module->info->author ? module->info->author : "NONE", - module->info->version ? module->info->version : "NONE", - module->info->copyright ? module->info->copyright : "NONE", - module->info->date ? module->info->date : "NONE"); + info->purpose ? info->purpose : "NONE", + info->author ? info->author : "NONE", + info->version ? info->version : "NONE", + info->copyright ? info->copyright : "NONE", + info->date ? info->date : "NONE"); } } -static void -gimp_module_db_module_on_disk_func (gpointer data, - gpointer user_data) -{ - GimpModule *module = data; - GList **kill_list = user_data; - gboolean old_on_disk; - - old_on_disk = module->on_disk; - - module->on_disk = g_file_test (module->filename, G_FILE_TEST_IS_REGULAR); - - /* if it's not on the disk, and it isn't in memory, mark it to be - * removed later. - */ - if (! module->on_disk && ! module->module) - { - *kill_list = g_list_append (*kill_list, module); - module = NULL; - } - - if (module && module->on_disk != old_on_disk) - gimp_module_modified (module); -} - -static void -gimp_module_db_module_remove_func (gpointer data, - gpointer user_data) -{ - GimpModule *module = data; - GimpModuleDB *db = user_data; - GimpModuleDBPrivate *priv = GET_PRIVATE (db); - - g_signal_handlers_disconnect_by_func (module, - gimp_module_db_module_modified, - db); - - priv->modules = g_list_remove (priv->modules, module); - - g_signal_emit (db, db_signals[REMOVE], 0, module); -} - static void gimp_module_db_module_modified (GimpModule *module, GimpModuleDB *db) diff --git a/po-libgimp/POTFILES.in b/po-libgimp/POTFILES.in index b2e752f4c1..81acab8f36 100644 --- a/po-libgimp/POTFILES.in +++ b/po-libgimp/POTFILES.in @@ -34,6 +34,7 @@ libgimpconfig/gimpconfigwriter.c libgimpconfig/gimpscanner.c libgimpmodule/gimpmodule.c +libgimpmodule/gimpmoduledb.c libgimpthumb/gimpthumb-utils.c libgimpthumb/gimpthumbnail.c