diff --git a/app/core/gimp-data-factories.c b/app/core/gimp-data-factories.c index 709157e091..3467a4986a 100644 --- a/app/core/gimp-data-factories.c +++ b/app/core/gimp-data-factories.c @@ -69,6 +69,7 @@ gimp_data_factories_init (Gimp *gimp) GIMP_TYPE_BRUSH, "brush-path", "brush-path-writable", + "brush-paths", gimp_brush_new, gimp_brush_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->brush_factory), @@ -109,6 +110,7 @@ gimp_data_factories_init (Gimp *gimp) GIMP_TYPE_DYNAMICS, "dynamics-path", "dynamics-path-writable", + "dynamics-paths", gimp_dynamics_new, gimp_dynamics_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->dynamics_factory), @@ -124,6 +126,7 @@ gimp_data_factories_init (Gimp *gimp) GIMP_TYPE_MYBRUSH, "mypaint-brush-path", "mypaint-brush-path-writable", + "mypaint-brush-paths", NULL, NULL); gimp_object_set_static_name (GIMP_OBJECT (gimp->mybrush_factory), @@ -139,6 +142,7 @@ gimp_data_factories_init (Gimp *gimp) GIMP_TYPE_PATTERN, "pattern-path", "pattern-path-writable", + "pattern-paths", NULL, gimp_pattern_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->pattern_factory), @@ -157,6 +161,7 @@ gimp_data_factories_init (Gimp *gimp) GIMP_TYPE_GRADIENT, "gradient-path", "gradient-path-writable", + "gradient-paths", gimp_gradient_new, gimp_gradient_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->gradient_factory), @@ -177,6 +182,7 @@ gimp_data_factories_init (Gimp *gimp) GIMP_TYPE_PALETTE, "palette-path", "palette-path-writable", + "palette-paths", gimp_palette_new, gimp_palette_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->palette_factory), @@ -198,6 +204,7 @@ gimp_data_factories_init (Gimp *gimp) GIMP_TYPE_TOOL_PRESET, "tool-preset-path", "tool-preset-path-writable", + "tool-preset-paths", gimp_tool_preset_new, NULL); gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_preset_factory), diff --git a/app/core/gimpdatafactory.c b/app/core/gimpdatafactory.c index c7599699d6..47956d3c17 100644 --- a/app/core/gimpdatafactory.c +++ b/app/core/gimpdatafactory.c @@ -50,6 +50,7 @@ enum PROP_DATA_TYPE, PROP_PATH_PROPERTY_NAME, PROP_WRITABLE_PROPERTY_NAME, + PROP_EXT_PROPERTY_NAME, PROP_NEW_FUNC, PROP_GET_STANDARD_FUNC }; @@ -65,6 +66,7 @@ struct _GimpDataFactoryPrivate gchar *path_property_name; gchar *writable_property_name; + gchar *ext_property_name; GimpDataNewFunc data_new_func; GimpDataGetStandardFunc data_get_standard_func; @@ -154,6 +156,13 @@ gimp_data_factory_class_init (GimpDataFactoryClass *klass) GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_EXT_PROPERTY_NAME, + g_param_spec_string ("ext-property-name", + NULL, NULL, + NULL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_NEW_FUNC, g_param_spec_pointer ("new-func", NULL, NULL, @@ -226,6 +235,10 @@ gimp_data_factory_set_property (GObject *object, priv->writable_property_name = g_value_dup_string (value); break; + case PROP_EXT_PROPERTY_NAME: + priv->ext_property_name = g_value_dup_string (value); + break; + case PROP_NEW_FUNC: priv->data_new_func = g_value_get_pointer (value); break; @@ -266,6 +279,10 @@ gimp_data_factory_get_property (GObject *object, g_value_set_string (value, priv->writable_property_name); break; + case PROP_EXT_PROPERTY_NAME: + g_value_set_string (value, priv->ext_property_name); + break; + case PROP_NEW_FUNC: g_value_set_pointer (value, priv->data_new_func); break; @@ -298,6 +315,7 @@ gimp_data_factory_finalize (GObject *object) g_clear_pointer (&priv->path_property_name, g_free); g_clear_pointer (&priv->writable_property_name, g_free); + g_clear_pointer (&priv->ext_property_name, g_free); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -487,6 +505,12 @@ gimp_data_factory_data_init (GimpDataFactory *factory, G_CALLBACK (gimp_data_factory_path_notify), factory, 0); g_free (signal_name); + + signal_name = g_strdup_printf ("notify::%s", priv->ext_property_name); + g_signal_connect_object (priv->gimp->extension_manager, signal_name, + G_CALLBACK (gimp_data_factory_path_notify), + factory, 0); + g_free (signal_name); } static void @@ -842,6 +866,21 @@ gimp_data_factory_get_data_path_writable (GimpDataFactory *factory) return list; } +const GList * +gimp_data_factory_get_data_path_ext (GimpDataFactory *factory) +{ + GimpDataFactoryPrivate *priv = GET_PRIVATE (factory); + GList *list = NULL; + + g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL); + + g_object_get (priv->gimp->extension_manager, + priv->ext_property_name, &list, + NULL); + + return list; +} + /* private functions */ diff --git a/app/core/gimpdatafactory.h b/app/core/gimpdatafactory.h index 577faa3529..62679351df 100644 --- a/app/core/gimpdatafactory.h +++ b/app/core/gimpdatafactory.h @@ -116,6 +116,7 @@ GimpContainer * gimp_data_factory_get_container_obsolete GList * gimp_data_factory_get_data_path (GimpDataFactory *factory); GList * gimp_data_factory_get_data_path_writable (GimpDataFactory *factory); +const GList * gimp_data_factory_get_data_path_ext (GimpDataFactory *factory); diff --git a/app/core/gimpdataloaderfactory.c b/app/core/gimpdataloaderfactory.c index 409f91e0a3..b04b22f6b1 100644 --- a/app/core/gimpdataloaderfactory.c +++ b/app/core/gimpdataloaderfactory.c @@ -232,6 +232,7 @@ gimp_data_loader_factory_new (Gimp *gimp, GType data_type, const gchar *path_property_name, const gchar *writable_property_name, + const gchar *ext_property_name, GimpDataNewFunc new_func, GimpDataGetStandardFunc get_standard_func) { @@ -239,12 +240,14 @@ gimp_data_loader_factory_new (Gimp *gimp, g_return_val_if_fail (g_type_is_a (data_type, GIMP_TYPE_DATA), NULL); g_return_val_if_fail (path_property_name != NULL, NULL); g_return_val_if_fail (writable_property_name != NULL, NULL); + g_return_val_if_fail (ext_property_name != NULL, NULL); return g_object_new (GIMP_TYPE_DATA_LOADER_FACTORY, "gimp", gimp, "data-type", data_type, "path-property-name", path_property_name, "writable-property-name", writable_property_name, + "ext-property-name", ext_property_name, "new-func", new_func, "get-standard-func", get_standard_func, NULL); @@ -316,12 +319,27 @@ gimp_data_loader_factory_load (GimpDataFactory *factory, GimpContext *context, GHashTable *cache) { - GList *path; - GList *writable_path; - GList *list; + const GList *ext_path; + GList *path; + GList *writable_path; + GList *list; path = gimp_data_factory_get_data_path (factory); writable_path = gimp_data_factory_get_data_path_writable (factory); + ext_path = gimp_data_factory_get_data_path_ext (factory); + + for (list = (GList *) ext_path; list; list = g_list_next (list)) + { + /* Adding data from extensions. + * Consider these always non-writable (even when the directory is + * writable, since writability of extension is only taken into + * account for extension update). + */ + gimp_data_loader_factory_load_directory (factory, context, cache, + FALSE, + list->data, + list->data); + } for (list = path; list; list = g_list_next (list)) { diff --git a/app/core/gimpdataloaderfactory.h b/app/core/gimpdataloaderfactory.h index 43f0d9c509..77b5ad5793 100644 --- a/app/core/gimpdataloaderfactory.h +++ b/app/core/gimpdataloaderfactory.h @@ -57,11 +57,12 @@ struct _GimpDataLoaderFactoryClass GType gimp_data_loader_factory_get_type (void) G_GNUC_CONST; -GimpDataFactory * gimp_data_loader_factory_new (Gimp *gimp, - GType data_type, - const gchar *path_property_name, - const gchar *writable_property_name, - GimpDataNewFunc new_func, +GimpDataFactory * gimp_data_loader_factory_new (Gimp *gimp, + GType data_type, + const gchar *path_property_name, + const gchar *writable_property_name, + const gchar *ext_property_name, + GimpDataNewFunc new_func, GimpDataGetStandardFunc get_standard_func); void gimp_data_loader_factory_add_loader (GimpDataFactory *factory, diff --git a/app/core/gimpextension-error.h b/app/core/gimpextension-error.h index c81fd6fb0f..92000091b6 100644 --- a/app/core/gimpextension-error.h +++ b/app/core/gimpextension-error.h @@ -29,6 +29,7 @@ typedef enum GIMP_EXTENSION_BAD_APPDATA, GIMP_EXTENSION_BAD_ID, GIMP_EXTENSION_NO_VERSION, + GIMP_EXTENSION_BAD_PATH } GimpExtensionErrorCode; diff --git a/app/core/gimpextension.c b/app/core/gimpextension.c index 16f43aaf52..21b21bd06b 100644 --- a/app/core/gimpextension.c +++ b/app/core/gimpextension.c @@ -44,19 +44,32 @@ struct _GimpExtensionPrivate AsApp *app; gboolean writable; + + /* Extension metadata. */ + GList *brush_paths; + GList *dynamics_paths; + GList *mypaint_brush_paths; + GList *pattern_paths; + GList *gradient_paths; + GList *palette_paths; + GList *tool_preset_paths; }; -static void gimp_extension_finalize (GObject *object); -static void gimp_extension_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void gimp_extension_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); +static void gimp_extension_finalize (GObject *object); +static void gimp_extension_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_extension_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static GList * gimp_extension_validate_paths (GimpExtension *extension, + const gchar *paths, + gboolean as_directories, + GError **error); G_DEFINE_TYPE (GimpExtension, gimp_extension, GIMP_TYPE_OBJECT) @@ -99,6 +112,8 @@ gimp_extension_finalize (GObject *object) { GimpExtension *extension = GIMP_EXTENSION (object); + gimp_extension_stop (extension); + g_free (extension->p->path); if (extension->p->app) g_object_unref (extension->p->app); @@ -256,3 +271,246 @@ gimp_extension_load (GimpExtension *extension, return success; } + +gboolean +gimp_extension_run (GimpExtension *extension, + GError **error) +{ + GHashTable *metadata; + gchar *value; + + g_return_val_if_fail (extension->p->app != NULL, FALSE); + g_return_val_if_fail (error && *error == NULL, FALSE); + + gimp_extension_stop (extension); + metadata = as_app_get_metadata (extension->p->app); + + value = g_hash_table_lookup (metadata, "GIMP::brush-path"); + extension->p->brush_paths = gimp_extension_validate_paths (extension, + value, TRUE, + error); + + if (! (*error)) + { + value = g_hash_table_lookup (metadata, "GIMP::dynamics-path"); + extension->p->dynamics_paths = gimp_extension_validate_paths (extension, + value, TRUE, + error); + } + if (! (*error)) + { + value = g_hash_table_lookup (metadata, "GIMP::mypaint-brush-path"); + extension->p->mypaint_brush_paths = gimp_extension_validate_paths (extension, + value, TRUE, + error); + } + if (! (*error)) + { + value = g_hash_table_lookup (metadata, "GIMP::pattern-path"); + extension->p->pattern_paths = gimp_extension_validate_paths (extension, + value, TRUE, + error); + } + if (! (*error)) + { + value = g_hash_table_lookup (metadata, "GIMP::gradient-path"); + extension->p->gradient_paths = gimp_extension_validate_paths (extension, + value, TRUE, + error); + } + if (! (*error)) + { + value = g_hash_table_lookup (metadata, "GIMP::palette-path"); + extension->p->palette_paths = gimp_extension_validate_paths (extension, + value, TRUE, + error); + } + if (! (*error)) + { + value = g_hash_table_lookup (metadata, "GIMP::tool-preset-path"); + extension->p->tool_preset_paths = gimp_extension_validate_paths (extension, + value, TRUE, + error); + } + + if (*error) + gimp_extension_stop (extension); + + return (*error == NULL); +} + +void +gimp_extension_stop (GimpExtension *extension) +{ + g_list_free_full (extension->p->brush_paths, g_object_unref); + extension->p->brush_paths = NULL; + g_list_free_full (extension->p->dynamics_paths, g_object_unref); + extension->p->dynamics_paths = NULL; + g_list_free_full (extension->p->mypaint_brush_paths, g_object_unref); + extension->p->brush_paths = NULL; + g_list_free_full (extension->p->pattern_paths, g_object_unref); + extension->p->pattern_paths = NULL; + g_list_free_full (extension->p->gradient_paths, g_object_unref); + extension->p->gradient_paths = NULL; + g_list_free_full (extension->p->palette_paths, g_object_unref); + extension->p->palette_paths = NULL; + g_list_free_full (extension->p->tool_preset_paths, g_object_unref); + extension->p->tool_preset_paths = NULL; +} + +GList * +gimp_extension_get_brush_paths (GimpExtension *extension) +{ + return extension->p->brush_paths; +} + +GList * +gimp_extension_get_dynamics_paths (GimpExtension *extension) +{ + return extension->p->dynamics_paths; +} + +GList * +gimp_extension_get_mypaint_brush_paths (GimpExtension *extension) +{ + return extension->p->mypaint_brush_paths; +} + +GList * +gimp_extension_get_pattern_paths (GimpExtension *extension) +{ + return extension->p->pattern_paths; +} + +GList * +gimp_extension_get_gradient_paths (GimpExtension *extension) +{ + return extension->p->gradient_paths; +} + +GList * +gimp_extension_get_palette_paths (GimpExtension *extension) +{ + return extension->p->palette_paths; +} + +GList * +gimp_extension_get_tool_preset_paths (GimpExtension *extension) +{ + return extension->p->tool_preset_paths; +} + +/** + * gimp_extension_validate_paths: + * @extension: the #GimpExtension + * @path: A list of directories separated by ':'. + * @error: + * + * Very similar to gimp_path_parse() except that we don't use + * G_SEARCHPATH_SEPARATOR as path separator, because it must not be + * os-dependent. + * Also we only allow relative path which are children of the main + * extension directory (we do not allow extensions to list external + * folders). + * + * Returns: A #GList of #GFile as listed in @path. + **/ +static GList * +gimp_extension_validate_paths (GimpExtension *extension, + const gchar *paths, + gboolean as_directories, + GError **error) +{ + gchar **patharray; + GList *list = NULL; + gint i; + + g_return_val_if_fail (error && *error == NULL, FALSE); + + if (!paths || ! (*paths)) + return NULL; + + patharray = g_strsplit (paths, ":", 0); + + for (i = 0; patharray[i]; i++) + { + /* Note: appstream-glib is supposed to return everything as UTF-8, + * so we should not have to bother about this. */ + gchar *path; + GFile *file; + GFile *ext_dir; + + if (g_path_is_absolute (patharray[i])) + { + *error = g_error_new (GIMP_EXTENSION_ERROR, + GIMP_EXTENSION_BAD_PATH, + _("'%s' is not a relative path."), + patharray[i]); + break; + } + path = g_build_filename (extension->p->path, patharray[i], NULL); + file = g_file_new_for_path (path); + g_free (path); + + ext_dir = g_file_new_for_path (extension->p->path); + + if (! g_file_has_parent (file, ext_dir)) + { + /* Even with relative paths, it is easy to trick the system + * and leak out of the extension. So check actual kinship. + */ + *error = g_error_new (GIMP_EXTENSION_ERROR, + GIMP_EXTENSION_BAD_PATH, + _("'%s' is not a child of the extension."), + patharray[i]); + g_object_unref (ext_dir); + g_object_unref (file); + break; + } + g_object_unref (ext_dir); + + if (as_directories) + { + if (g_file_query_file_type (file, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL) != G_FILE_TYPE_DIRECTORY) + { + *error = g_error_new (GIMP_EXTENSION_ERROR, + GIMP_EXTENSION_BAD_PATH, + _("'%s' is not a directory."), + patharray[i]); + g_object_unref (file); + break; + } + } + else + { + if (g_file_query_file_type (file, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL) != G_FILE_TYPE_REGULAR) + { + *error = g_error_new (GIMP_EXTENSION_ERROR, + GIMP_EXTENSION_BAD_PATH, + _("'%s' is not a valid file."), + patharray[i]); + g_object_unref (file); + break; + } + } + + g_return_val_if_fail (path != NULL, NULL); + if (g_list_find_custom (list, file, (GCompareFunc) g_file_equal)) + { + /* Silently ignore duplicate paths. */ + g_object_unref (file); + continue; + } + + list = g_list_prepend (list, file); + } + + g_strfreev (patharray); + list = g_list_reverse (list); + + return list; +} diff --git a/app/core/gimpextension.h b/app/core/gimpextension.h index 2b0123c9af..8811ce34ad 100644 --- a/app/core/gimpextension.h +++ b/app/core/gimpextension.h @@ -50,11 +50,21 @@ struct _GimpExtensionClass GType gimp_extension_get_type (void) G_GNUC_CONST; -GimpExtension * gimp_extension_new (const gchar *dir, - gboolean writable); +GimpExtension * gimp_extension_new (const gchar *dir, + gboolean writable); -gboolean gimp_extension_load (GimpExtension *extension, - GError **error); +gboolean gimp_extension_load (GimpExtension *extension, + GError **error); +gboolean gimp_extension_run (GimpExtension *extension, + GError **error); +void gimp_extension_stop (GimpExtension *extension); + +GList * gimp_extension_get_brush_paths (GimpExtension *extension); +GList * gimp_extension_get_dynamics_paths (GimpExtension *extension); +GList * gimp_extension_get_mypaint_brush_paths (GimpExtension *extension); +GList * gimp_extension_get_pattern_paths (GimpExtension *extension); +GList * gimp_extension_get_gradient_paths (GimpExtension *extension); +GList * gimp_extension_get_palette_paths (GimpExtension *extension); +GList * gimp_extension_get_tool_preset_paths (GimpExtension *extension); #endif /* __GIMP_EXTENSION_H__ */ - diff --git a/app/core/gimpextensionmanager.c b/app/core/gimpextensionmanager.c index 9abff635a5..8c29c74240 100644 --- a/app/core/gimpextensionmanager.c +++ b/app/core/gimpextensionmanager.c @@ -45,7 +45,14 @@ enum { PROP_0, - PROP_GIMP + PROP_GIMP, + PROP_BRUSH_PATHS, + PROP_DYNAMICS_PATHS, + PROP_MYPAINT_BRUSH_PATHS, + PROP_PATTERN_PATHS, + PROP_GRADIENT_PATHS, + PROP_PALETTE_PATHS, + PROP_TOOL_PRESET_PATHS, }; struct _GimpExtensionManagerPrivate @@ -59,6 +66,15 @@ struct _GimpExtensionManagerPrivate /* Running extensions */ GHashTable *active_extensions; + + /* Metadata properties */ + GList *brush_paths; + GList *dynamics_paths; + GList *mypaint_brush_paths; + GList *pattern_paths; + GList *gradient_paths; + GList *palette_paths; + GList *tool_preset_paths; }; static void gimp_extension_manager_finalize (GObject *object); @@ -71,6 +87,7 @@ static void gimp_extension_manager_get_property (GObject *object, GValue *value, GParamSpec *pspec); +static void gimp_extension_manager_refresh (GimpExtensionManager *manager); static void gimp_extension_manager_search_directory (GimpExtensionManager *manager, GFile *directory, gboolean system_dir); @@ -94,6 +111,35 @@ gimp_extension_manager_class_init (GimpExtensionManagerClass *klass) GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_BRUSH_PATHS, + g_param_spec_pointer ("brush-paths", + NULL, NULL, + GIMP_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_DYNAMICS_PATHS, + g_param_spec_pointer ("dynamics-paths", + NULL, NULL, + GIMP_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_MYPAINT_BRUSH_PATHS, + g_param_spec_pointer ("mypaint-brush-paths", + NULL, NULL, + GIMP_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_PATTERN_PATHS, + g_param_spec_pointer ("pattern-paths", + NULL, NULL, + GIMP_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_GRADIENT_PATHS, + g_param_spec_pointer ("gradient-paths", + NULL, NULL, + GIMP_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_PALETTE_PATHS, + g_param_spec_pointer ("palette-paths", + NULL, NULL, + GIMP_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_TOOL_PRESET_PATHS, + g_param_spec_pointer ("tool-preset-paths", + NULL, NULL, + GIMP_PARAM_READWRITE)); + g_type_class_add_private (klass, sizeof (GimpExtensionManagerPrivate)); } @@ -130,6 +176,27 @@ gimp_extension_manager_set_property (GObject *object, case PROP_GIMP: manager->p->gimp = g_value_get_object (value); break; + case PROP_BRUSH_PATHS: + manager->p->brush_paths = g_value_get_pointer (value); + break; + case PROP_DYNAMICS_PATHS: + manager->p->dynamics_paths = g_value_get_pointer (value); + break; + case PROP_MYPAINT_BRUSH_PATHS: + manager->p->mypaint_brush_paths = g_value_get_pointer (value); + break; + case PROP_PATTERN_PATHS: + manager->p->pattern_paths = g_value_get_pointer (value); + break; + case PROP_GRADIENT_PATHS: + manager->p->gradient_paths = g_value_get_pointer (value); + break; + case PROP_PALETTE_PATHS: + manager->p->palette_paths = g_value_get_pointer (value); + break; + case PROP_TOOL_PRESET_PATHS: + manager->p->tool_preset_paths = g_value_get_pointer (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -150,6 +217,27 @@ gimp_extension_manager_get_property (GObject *object, case PROP_GIMP: g_value_set_object (value, manager->p->gimp); break; + case PROP_BRUSH_PATHS: + g_value_set_pointer (value, manager->p->brush_paths); + break; + case PROP_DYNAMICS_PATHS: + g_value_set_pointer (value, manager->p->dynamics_paths); + break; + case PROP_MYPAINT_BRUSH_PATHS: + g_value_set_pointer (value, manager->p->mypaint_brush_paths); + break; + case PROP_PATTERN_PATHS: + g_value_set_pointer (value, manager->p->pattern_paths); + break; + case PROP_GRADIENT_PATHS: + g_value_set_pointer (value, manager->p->gradient_paths); + break; + case PROP_PALETTE_PATHS: + g_value_set_pointer (value, manager->p->palette_paths); + break; + case PROP_TOOL_PRESET_PATHS: + g_value_set_pointer (value, manager->p->tool_preset_paths); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -200,11 +288,20 @@ gimp_extension_manager_initialize (GimpExtensionManager *manager) if (! g_hash_table_contains (manager->p->active_extensions, gimp_object_get_name (list->data))) { + GError *error = NULL; + g_hash_table_insert (manager->p->active_extensions, (gpointer) gimp_object_get_name (list->data), list->data); - /* TODO: do whatever is needed to make extension "active". */ + if (! gimp_extension_run (list->data, &error)) + { + g_hash_table_remove (manager->p->active_extensions, list->data); + if (error) + g_printerr ("Extension '%s' failed to run: %s\n", + gimp_object_get_name (list->data), + error->message); + } } } for (list = manager->p->sys_extensions; list; list = g_list_next (list)) @@ -212,12 +309,84 @@ gimp_extension_manager_initialize (GimpExtensionManager *manager) if (! g_hash_table_contains (manager->p->active_extensions, gimp_object_get_name (list->data))) { + GError *error = NULL; + g_hash_table_insert (manager->p->active_extensions, (gpointer) gimp_object_get_name (list->data), list->data); - /* TODO: do whatever is needed to make extension "active". */ + + if (! gimp_extension_run (list->data, &error)) + { + g_hash_table_remove (manager->p->active_extensions, list->data); + if (error) + g_printerr ("Extension '%s' failed to run: %s\n", + gimp_object_get_name (list->data), + error->message); + } } } + + gimp_extension_manager_refresh (manager); +} + +static void +gimp_extension_manager_refresh (GimpExtensionManager *manager) +{ + GHashTableIter iter; + gpointer key; + gpointer value; + GList *brush_paths = NULL; + GList *dynamics_paths = NULL; + GList *mypaint_brush_paths = NULL; + GList *pattern_paths = NULL; + GList *gradient_paths = NULL; + GList *palette_paths = NULL; + GList *tool_preset_paths = NULL; + + g_hash_table_iter_init (&iter, manager->p->active_extensions); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + GimpExtension *extension = value; + GList *new_paths; + + new_paths = g_list_copy_deep (gimp_extension_get_brush_paths (extension), + (GCopyFunc) g_object_ref, NULL); + brush_paths = g_list_concat (brush_paths, new_paths); + + new_paths = g_list_copy_deep (gimp_extension_get_dynamics_paths (extension), + (GCopyFunc) g_object_ref, NULL); + dynamics_paths = g_list_concat (dynamics_paths, new_paths); + + new_paths = g_list_copy_deep (gimp_extension_get_mypaint_brush_paths (extension), + (GCopyFunc) g_object_ref, NULL); + mypaint_brush_paths = g_list_concat (mypaint_brush_paths, new_paths); + + new_paths = g_list_copy_deep (gimp_extension_get_pattern_paths (extension), + (GCopyFunc) g_object_ref, NULL); + pattern_paths = g_list_concat (pattern_paths, new_paths); + + new_paths = g_list_copy_deep (gimp_extension_get_gradient_paths (extension), + (GCopyFunc) g_object_ref, NULL); + gradient_paths = g_list_concat (gradient_paths, new_paths); + + new_paths = g_list_copy_deep (gimp_extension_get_palette_paths (extension), + (GCopyFunc) g_object_ref, NULL); + palette_paths = g_list_concat (palette_paths, new_paths); + + new_paths = g_list_copy_deep (gimp_extension_get_tool_preset_paths (extension), + (GCopyFunc) g_object_ref, NULL); + tool_preset_paths = g_list_concat (tool_preset_paths, new_paths); + } + + g_object_set (manager, + "brush-paths", brush_paths, + "dynamics-paths", dynamics_paths, + "mypaint-brush-paths", brush_paths, + "pattern-paths", pattern_paths, + "gradient-paths", gradient_paths, + "palette-paths", palette_paths, + "tool-preset-paths", tool_preset_paths, + NULL); } static void