app: extensions can now bundle various data.

Extensions work for brushes, dynamics, MyPaint brushes, patterns,
gradients, palettes and tool presets.
More to come, but this is a first and working proof-of-concept.
This commit is contained in:
Jehan 2018-07-02 20:33:59 +02:00
parent b70424b20a
commit a8a0408eb6
9 changed files with 529 additions and 25 deletions

View File

@ -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),

View File

@ -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 */

View File

@ -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);

View File

@ -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))
{

View File

@ -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,

View File

@ -29,6 +29,7 @@ typedef enum
GIMP_EXTENSION_BAD_APPDATA,
GIMP_EXTENSION_BAD_ID,
GIMP_EXTENSION_NO_VERSION,
GIMP_EXTENSION_BAD_PATH
} GimpExtensionErrorCode;

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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