Issue #12568: support GIMP's GEGL operations with a custom config argument…
… in new filter API.
This commit is contained in:
@ -38,6 +38,8 @@
|
||||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "operations/gimp-operation-config.h"
|
||||
|
||||
#include "gegl/gimp-babl.h"
|
||||
#include "gegl/gimpapplicator.h"
|
||||
#include "gegl/gimp-gegl-utils.h"
|
||||
@ -769,9 +771,12 @@ gimp_drawable_filter_set_preview_split (GimpDrawableFilter *filter,
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is mostly for usage by libgimp API. The idea is to have
|
||||
/* This function is **ONLY** for usage by libgimp API. The idea is to have
|
||||
* a single function which updates a bunch of settings in a single call
|
||||
* and in particular a single rendering update.
|
||||
*
|
||||
* Also it does some funky config object switch for custom operations
|
||||
* which is only needed libgimp-side.
|
||||
*/
|
||||
gboolean
|
||||
gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
@ -786,8 +791,12 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
const GimpDrawable **auxinputs,
|
||||
GError **error)
|
||||
{
|
||||
GimpImage *image;
|
||||
GimpObject *settings = NULL;
|
||||
GeglNode *node = NULL;
|
||||
GParamSpec **pspecs;
|
||||
gchar *opname;
|
||||
guint n_parent_pspecs = 0;
|
||||
guint n_pspecs;
|
||||
gint n_values;
|
||||
gint n_auxinputs;
|
||||
@ -822,14 +831,55 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
|
||||
gegl_node_get (filter->operation, "operation", &opname, NULL);
|
||||
|
||||
pspecs = gegl_operation_list_properties (opname, &n_pspecs);
|
||||
for (gint i = 0; i < n_pspecs; i++)
|
||||
image = gimp_item_get_image (GIMP_ITEM (filter->drawable));
|
||||
node = gimp_drawable_filter_get_operation (filter);
|
||||
if (gimp_operation_config_is_custom (image->gimp, opname))
|
||||
{
|
||||
GObjectClass *klass;
|
||||
GObjectClass *parent_klass;
|
||||
|
||||
gegl_node_get (node,
|
||||
"config", &settings,
|
||||
NULL);
|
||||
klass = G_OBJECT_GET_CLASS (settings);
|
||||
parent_klass = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
|
||||
g_free (g_object_class_list_properties (parent_klass, &n_parent_pspecs));
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (settings), &n_pspecs);
|
||||
}
|
||||
else
|
||||
{
|
||||
pspecs = gegl_operation_list_properties (opname, &n_pspecs);
|
||||
}
|
||||
|
||||
for (gint i = n_parent_pspecs; i < n_pspecs; i++)
|
||||
{
|
||||
GParamSpec *target_pspec;
|
||||
GParamSpec *pspec = pspecs[i];
|
||||
GValue old_value = G_VALUE_INIT;
|
||||
gint j;
|
||||
|
||||
gegl_node_get_property (filter->operation, pspec->name, &old_value);
|
||||
if (settings)
|
||||
target_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (settings), pspec->name);
|
||||
else
|
||||
target_pspec = gegl_node_find_property (node, pspec->name);
|
||||
if (! target_pspec)
|
||||
{
|
||||
/* If this ever happens, this is more likely a bug in our
|
||||
* PDB code, unless someone tried to call the PDB procedure
|
||||
* directly with bad data.
|
||||
*/
|
||||
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
|
||||
/* TODO: localize after string freeze. */
|
||||
"GEGL operation '%s' has been called with a "
|
||||
"non-existent argument name '%s' (#%d).",
|
||||
opname, pspec->name, i);
|
||||
break;
|
||||
}
|
||||
|
||||
if (settings)
|
||||
g_object_get_property (G_OBJECT (settings), pspec->name, &old_value);
|
||||
else
|
||||
gegl_node_get_property (node, pspec->name, &old_value);
|
||||
|
||||
for (j = 0; j < n_values; j++)
|
||||
if (g_strcmp0 (pspec->name, propnames[j]) == 0)
|
||||
@ -897,7 +947,10 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
|
||||
if (g_param_values_cmp (pspec, new_value, &old_value) != 0)
|
||||
{
|
||||
gegl_node_set_property (filter->operation, pspec->name, new_value);
|
||||
if (settings)
|
||||
g_object_set_property (G_OBJECT (settings), pspec->name, new_value);
|
||||
else
|
||||
gegl_node_set_property (node, pspec->name, new_value);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
@ -913,7 +966,10 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
|
||||
g_value_init (&default_value, pspec->value_type);
|
||||
g_param_value_set_default (pspec, &default_value);
|
||||
gegl_node_set_property (filter->operation, pspec->name, &default_value);
|
||||
if (settings)
|
||||
g_object_set_property (G_OBJECT (settings), pspec->name, &default_value);
|
||||
else
|
||||
gegl_node_set_property (node, pspec->name, &default_value);
|
||||
changed = TRUE;
|
||||
|
||||
g_value_unset (&default_value);
|
||||
@ -951,7 +1007,7 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
GeglNode *src_node;
|
||||
GeglBuffer *buffer;
|
||||
|
||||
if (! gegl_node_has_pad (filter->operation, auxinputnames[i]))
|
||||
if (! gegl_node_has_pad (node, auxinputnames[i]))
|
||||
{
|
||||
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
|
||||
/* TODO: localize after string freeze. */
|
||||
@ -964,18 +1020,22 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
|
||||
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (auxinputs[i]));
|
||||
g_object_ref (buffer);
|
||||
src_node = gegl_node_new_child (gegl_node_get_parent (filter->operation),
|
||||
src_node = gegl_node_new_child (gegl_node_get_parent (node),
|
||||
"operation", "gegl:buffer-source",
|
||||
"buffer", buffer,
|
||||
NULL);
|
||||
g_object_unref (buffer);
|
||||
|
||||
gegl_node_connect (src_node, "output", filter->operation, auxinputnames[i]);
|
||||
gegl_node_connect (src_node, "output", node, auxinputnames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings)
|
||||
gegl_node_set (node, "config", settings, NULL);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (filter));
|
||||
|
||||
g_clear_object (&settings);
|
||||
g_free (pspecs);
|
||||
g_free (opname);
|
||||
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "core/gimpimage-undo-push.h"
|
||||
#include "core/gimpitem.h"
|
||||
#include "core/gimpparamspecs.h"
|
||||
#include "operations/gimp-operation-config.h"
|
||||
#include "operations/gimpoperationsettings.h"
|
||||
|
||||
#include "gimppdb.h"
|
||||
#include "gimppdberror.h"
|
||||
@ -387,18 +389,46 @@ drawable_filter_get_number_arguments_invoker (GimpProcedure *procedure,
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
GimpValueArray *return_vals;
|
||||
const gchar *operation_name;
|
||||
GimpDrawableFilter *filter;
|
||||
gint num_args = 0;
|
||||
|
||||
operation_name = g_value_get_string (gimp_value_array_index (args, 0));
|
||||
filter = g_value_get_object (gimp_value_array_index (args, 0));
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (gegl_has_operation (operation_name))
|
||||
GeglNode *node;
|
||||
const gchar *opname;
|
||||
|
||||
node = gimp_drawable_filter_get_operation (filter);
|
||||
opname = gegl_node_get_operation (node);
|
||||
|
||||
if (gegl_has_operation (opname))
|
||||
{
|
||||
guint n_properties;
|
||||
|
||||
g_free (gegl_operation_list_properties (operation_name, &n_properties));
|
||||
if (gimp_operation_config_is_custom (gimp, opname))
|
||||
{
|
||||
GimpObject *settings = NULL;
|
||||
GObjectClass *klass;
|
||||
GObjectClass *parent_klass;
|
||||
guint n_parent_properties;
|
||||
|
||||
gegl_node_get (node,
|
||||
"config", &settings,
|
||||
NULL);
|
||||
klass = G_OBJECT_GET_CLASS (settings);
|
||||
parent_klass = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
|
||||
|
||||
g_free (g_object_class_list_properties (parent_klass, &n_parent_properties));
|
||||
g_free (g_object_class_list_properties (klass, &n_properties));
|
||||
g_clear_object (&settings);
|
||||
n_properties -= n_parent_properties;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (gegl_operation_list_properties (opname, &n_properties));
|
||||
}
|
||||
|
||||
num_args = (gint) n_properties;
|
||||
}
|
||||
else
|
||||
@ -426,25 +456,49 @@ drawable_filter_get_pspec_invoker (GimpProcedure *procedure,
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
GimpValueArray *return_vals;
|
||||
const gchar *operation_name;
|
||||
GimpDrawableFilter *filter;
|
||||
gint arg_num;
|
||||
GParamSpec *param_spec = NULL;
|
||||
|
||||
operation_name = g_value_get_string (gimp_value_array_index (args, 0));
|
||||
filter = g_value_get_object (gimp_value_array_index (args, 0));
|
||||
arg_num = g_value_get_int (gimp_value_array_index (args, 1));
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (gegl_has_operation (operation_name))
|
||||
GimpObject *settings = NULL;
|
||||
GeglNode *node;
|
||||
const gchar *opname;
|
||||
|
||||
node = gimp_drawable_filter_get_operation (filter);
|
||||
opname = gegl_node_get_operation (node);
|
||||
|
||||
if (gegl_has_operation (opname))
|
||||
{
|
||||
GParamSpec **specs;
|
||||
guint n_properties;
|
||||
GParamSpec **specs;
|
||||
guint n_properties;
|
||||
guint n_parent_properties = 0;
|
||||
|
||||
specs = gegl_operation_list_properties (operation_name, &n_properties);
|
||||
|
||||
if (arg_num >= 0 && arg_num < n_properties)
|
||||
if (gimp_operation_config_is_custom (gimp, opname))
|
||||
{
|
||||
param_spec = g_param_spec_ref (specs[arg_num]);
|
||||
GObjectClass *klass;
|
||||
GObjectClass *parent_klass;
|
||||
|
||||
gegl_node_get (node,
|
||||
"config", &settings,
|
||||
NULL);
|
||||
klass = G_OBJECT_GET_CLASS (settings);
|
||||
parent_klass = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
|
||||
g_free (g_object_class_list_properties (parent_klass, &n_parent_properties));
|
||||
}
|
||||
|
||||
if (settings != NULL)
|
||||
specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (settings), &n_properties);
|
||||
else
|
||||
specs = gegl_operation_list_properties (opname, &n_properties);
|
||||
|
||||
if (arg_num >= 0 && n_parent_properties + arg_num < n_properties)
|
||||
{
|
||||
param_spec = g_param_spec_ref (specs[n_parent_properties + arg_num]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -457,6 +511,8 @@ drawable_filter_get_pspec_invoker (GimpProcedure *procedure,
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
g_clear_object (&settings);
|
||||
}
|
||||
|
||||
return_vals = gimp_procedure_get_return_values (procedure, success,
|
||||
@ -490,23 +546,50 @@ drawable_filter_get_arguments_invoker (GimpProcedure *procedure,
|
||||
const gchar *opname;
|
||||
GParamSpec **specs;
|
||||
guint n_specs;
|
||||
guint n_parent_properties = 0;
|
||||
GStrvBuilder *names_builder;
|
||||
GimpObject *settings = NULL;
|
||||
|
||||
node = gimp_drawable_filter_get_operation (filter);
|
||||
opname = gegl_node_get_operation (node);
|
||||
|
||||
specs = gegl_operation_list_properties (opname, &n_specs);
|
||||
if (gegl_has_operation (opname) &&
|
||||
gimp_operation_config_is_custom (gimp, opname))
|
||||
{
|
||||
GObjectClass *klass;
|
||||
GObjectClass *parent_klass;
|
||||
|
||||
gegl_node_get (node,
|
||||
"config", &settings,
|
||||
NULL);
|
||||
klass = G_OBJECT_GET_CLASS (settings);
|
||||
parent_klass = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
|
||||
g_free (g_object_class_list_properties (parent_klass, &n_parent_properties));
|
||||
}
|
||||
|
||||
if (settings != NULL)
|
||||
{
|
||||
specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (settings), &n_specs);
|
||||
n_specs -= n_parent_properties;
|
||||
}
|
||||
else
|
||||
{
|
||||
specs = gegl_operation_list_properties (opname, &n_specs);
|
||||
}
|
||||
|
||||
names_builder = g_strv_builder_new ();
|
||||
values = gimp_value_array_new (n_specs);
|
||||
|
||||
for (gint i = 0; i < n_specs; i++)
|
||||
{
|
||||
GParamSpec *pspec = specs[i];
|
||||
GParamSpec *pspec = specs[n_parent_properties + i];
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, pspec->value_type);
|
||||
gegl_node_get_property (node, pspec->name, &value);
|
||||
if (settings != NULL)
|
||||
g_object_get_property (G_OBJECT (settings), pspec->name, &value);
|
||||
else
|
||||
gegl_node_get_property (node, pspec->name, &value);
|
||||
|
||||
if (GEGL_IS_PARAM_SPEC_ENUM (pspec))
|
||||
{
|
||||
@ -553,6 +636,7 @@ drawable_filter_get_arguments_invoker (GimpProcedure *procedure,
|
||||
|
||||
g_strv_builder_unref (names_builder);
|
||||
g_free (specs);
|
||||
g_clear_object (&settings);
|
||||
}
|
||||
|
||||
return_vals = gimp_procedure_get_return_values (procedure, success,
|
||||
@ -958,12 +1042,11 @@ register_drawable_filter_procs (GimpPDB *pdb)
|
||||
"Jehan",
|
||||
"2024");
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_string ("operation-name",
|
||||
"operation name",
|
||||
"The procedure name",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_param_spec_drawable_filter ("filter",
|
||||
"filter",
|
||||
"The filter",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_return_value (procedure,
|
||||
g_param_spec_int ("num-args",
|
||||
"num args",
|
||||
@ -988,12 +1071,11 @@ register_drawable_filter_procs (GimpPDB *pdb)
|
||||
"Jehan",
|
||||
"2024");
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_string ("operation-name",
|
||||
"operation name",
|
||||
"The procedure name",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_param_spec_drawable_filter ("filter",
|
||||
"filter",
|
||||
"The filter",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_argument (procedure,
|
||||
g_param_spec_int ("arg-num",
|
||||
"arg num",
|
||||
|
@ -323,7 +323,7 @@ gimp_drawable_filter_get_config (GimpDrawableFilter *filter)
|
||||
canonical_name = gimp_canonicalize_identifier (op_name);
|
||||
config_type_name = g_strdup_printf ("GimpDrawableFilterConfig-%s", canonical_name);
|
||||
config_type = g_type_from_name (config_type_name);
|
||||
n_args = _gimp_drawable_filter_get_number_arguments (op_name);
|
||||
n_args = _gimp_drawable_filter_get_number_arguments (filter);
|
||||
|
||||
if (! config_type)
|
||||
{
|
||||
@ -335,7 +335,7 @@ gimp_drawable_filter_get_config (GimpDrawableFilter *filter)
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
|
||||
pspec = _gimp_drawable_filter_get_pspec (op_name, i);
|
||||
pspec = _gimp_drawable_filter_get_pspec (filter, i);
|
||||
config_args[i] = pspec;
|
||||
}
|
||||
|
||||
|
@ -416,7 +416,7 @@ _gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
|
||||
/**
|
||||
* _gimp_drawable_filter_get_number_arguments:
|
||||
* @operation_name: The procedure name.
|
||||
* @filter: The filter.
|
||||
*
|
||||
* Queries for the number of arguments on the specified filter.
|
||||
*
|
||||
@ -430,14 +430,14 @@ _gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
* Since: 3.0
|
||||
**/
|
||||
gint
|
||||
_gimp_drawable_filter_get_number_arguments (const gchar *operation_name)
|
||||
_gimp_drawable_filter_get_number_arguments (GimpDrawableFilter *filter)
|
||||
{
|
||||
GimpValueArray *args;
|
||||
GimpValueArray *return_vals;
|
||||
gint num_args = 0;
|
||||
|
||||
args = gimp_value_array_new_from_types (NULL,
|
||||
G_TYPE_STRING, operation_name,
|
||||
GIMP_TYPE_DRAWABLE_FILTER, filter,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
|
||||
@ -455,7 +455,7 @@ _gimp_drawable_filter_get_number_arguments (const gchar *operation_name)
|
||||
|
||||
/**
|
||||
* _gimp_drawable_filter_get_pspec:
|
||||
* @operation_name: The procedure name.
|
||||
* @filter: The filter.
|
||||
* @arg_num: The argument number.
|
||||
*
|
||||
* Queries for information on the specified filter's argument.
|
||||
@ -468,15 +468,15 @@ _gimp_drawable_filter_get_number_arguments (const gchar *operation_name)
|
||||
* Since: 3.0
|
||||
**/
|
||||
GParamSpec *
|
||||
_gimp_drawable_filter_get_pspec (const gchar *operation_name,
|
||||
gint arg_num)
|
||||
_gimp_drawable_filter_get_pspec (GimpDrawableFilter *filter,
|
||||
gint arg_num)
|
||||
{
|
||||
GimpValueArray *args;
|
||||
GimpValueArray *return_vals;
|
||||
GParamSpec *param_spec = NULL;
|
||||
|
||||
args = gimp_value_array_new_from_types (NULL,
|
||||
G_TYPE_STRING, operation_name,
|
||||
GIMP_TYPE_DRAWABLE_FILTER, filter,
|
||||
G_TYPE_INT, arg_num,
|
||||
G_TYPE_NONE);
|
||||
|
||||
|
@ -53,8 +53,8 @@ G_GNUC_INTERNAL gboolean _gimp_drawable_filter_update (GimpDraw
|
||||
GimpLayerColorSpace composite_space,
|
||||
const gchar **auxinputnames,
|
||||
const GimpDrawable **auxinputs);
|
||||
G_GNUC_INTERNAL gint _gimp_drawable_filter_get_number_arguments (const gchar *operation_name);
|
||||
G_GNUC_INTERNAL GParamSpec* _gimp_drawable_filter_get_pspec (const gchar *operation_name,
|
||||
G_GNUC_INTERNAL gint _gimp_drawable_filter_get_number_arguments (GimpDrawableFilter *filter);
|
||||
G_GNUC_INTERNAL GParamSpec* _gimp_drawable_filter_get_pspec (GimpDrawableFilter *filter,
|
||||
gint arg_num);
|
||||
G_GNUC_INTERNAL gchar** _gimp_drawable_filter_get_arguments (GimpDrawableFilter *filter,
|
||||
GimpValueArray **values);
|
||||
|
@ -372,8 +372,8 @@ HELP
|
||||
$lib_private = 1;
|
||||
|
||||
@inargs = (
|
||||
{ name => 'operation_name', type => 'string', non_empty => 1,
|
||||
desc => 'The procedure name' }
|
||||
{ name => 'filter', type => 'filter',
|
||||
desc => 'The filter' }
|
||||
);
|
||||
|
||||
@outargs = (
|
||||
@ -384,11 +384,39 @@ HELP
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (gegl_has_operation (operation_name))
|
||||
GeglNode *node;
|
||||
const gchar *opname;
|
||||
|
||||
node = gimp_drawable_filter_get_operation (filter);
|
||||
opname = gegl_node_get_operation (node);
|
||||
|
||||
if (gegl_has_operation (opname))
|
||||
{
|
||||
guint n_properties;
|
||||
|
||||
g_free (gegl_operation_list_properties (operation_name, &n_properties));
|
||||
if (gimp_operation_config_is_custom (gimp, opname))
|
||||
{
|
||||
GimpObject *settings = NULL;
|
||||
GObjectClass *klass;
|
||||
GObjectClass *parent_klass;
|
||||
guint n_parent_properties;
|
||||
|
||||
gegl_node_get (node,
|
||||
"config", &settings,
|
||||
NULL);
|
||||
klass = G_OBJECT_GET_CLASS (settings);
|
||||
parent_klass = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
|
||||
|
||||
g_free (g_object_class_list_properties (parent_klass, &n_parent_properties));
|
||||
g_free (g_object_class_list_properties (klass, &n_properties));
|
||||
g_clear_object (&settings);
|
||||
n_properties -= n_parent_properties;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (gegl_operation_list_properties (opname, &n_properties));
|
||||
}
|
||||
|
||||
num_args = (gint) n_properties;
|
||||
}
|
||||
else
|
||||
@ -414,8 +442,8 @@ HELP
|
||||
$lib_private = 1;
|
||||
|
||||
@inargs = (
|
||||
{ name => 'operation_name', type => 'string', non_empty => 1,
|
||||
desc => 'The procedure name' },
|
||||
{ name => 'filter', type => 'filter',
|
||||
desc => 'The filter' },
|
||||
{ name => 'arg_num', type => 'int32',
|
||||
desc => 'The argument number' }
|
||||
);
|
||||
@ -426,18 +454,42 @@ HELP
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<CODE
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (gegl_has_operation (operation_name))
|
||||
GimpObject *settings = NULL;
|
||||
GeglNode *node;
|
||||
const gchar *opname;
|
||||
|
||||
node = gimp_drawable_filter_get_operation (filter);
|
||||
opname = gegl_node_get_operation (node);
|
||||
|
||||
if (gegl_has_operation (opname))
|
||||
{
|
||||
GParamSpec **specs;
|
||||
guint n_properties;
|
||||
GParamSpec **specs;
|
||||
guint n_properties;
|
||||
guint n_parent_properties = 0;
|
||||
|
||||
specs = gegl_operation_list_properties (operation_name, &n_properties);
|
||||
|
||||
if (arg_num >= 0 && arg_num < n_properties)
|
||||
if (gimp_operation_config_is_custom (gimp, opname))
|
||||
{
|
||||
param_spec = g_param_spec_ref (specs[arg_num]);
|
||||
GObjectClass *klass;
|
||||
GObjectClass *parent_klass;
|
||||
|
||||
gegl_node_get (node,
|
||||
"config", &settings,
|
||||
NULL);
|
||||
klass = G_OBJECT_GET_CLASS (settings);
|
||||
parent_klass = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
|
||||
g_free (g_object_class_list_properties (parent_klass, &n_parent_properties));
|
||||
}
|
||||
|
||||
if (settings != NULL)
|
||||
specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (settings), &n_properties);
|
||||
else
|
||||
specs = gegl_operation_list_properties (opname, &n_properties);
|
||||
|
||||
if (arg_num >= 0 && n_parent_properties + arg_num < n_properties)
|
||||
{
|
||||
param_spec = g_param_spec_ref (specs[n_parent_properties + arg_num]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -450,6 +502,8 @@ HELP
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
g_clear_object (&settings);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
@ -486,23 +540,50 @@ HELP
|
||||
const gchar *opname;
|
||||
GParamSpec **specs;
|
||||
guint n_specs;
|
||||
guint n_parent_properties = 0;
|
||||
GStrvBuilder *names_builder;
|
||||
GimpObject *settings = NULL;
|
||||
|
||||
node = gimp_drawable_filter_get_operation (filter);
|
||||
opname = gegl_node_get_operation (node);
|
||||
|
||||
specs = gegl_operation_list_properties (opname, &n_specs);
|
||||
if (gegl_has_operation (opname) &&
|
||||
gimp_operation_config_is_custom (gimp, opname))
|
||||
{
|
||||
GObjectClass *klass;
|
||||
GObjectClass *parent_klass;
|
||||
|
||||
gegl_node_get (node,
|
||||
"config", &settings,
|
||||
NULL);
|
||||
klass = G_OBJECT_GET_CLASS (settings);
|
||||
parent_klass = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
|
||||
g_free (g_object_class_list_properties (parent_klass, &n_parent_properties));
|
||||
}
|
||||
|
||||
if (settings != NULL)
|
||||
{
|
||||
specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (settings), &n_specs);
|
||||
n_specs -= n_parent_properties;
|
||||
}
|
||||
else
|
||||
{
|
||||
specs = gegl_operation_list_properties (opname, &n_specs);
|
||||
}
|
||||
|
||||
names_builder = g_strv_builder_new ();
|
||||
values = gimp_value_array_new (n_specs);
|
||||
|
||||
for (gint i = 0; i < n_specs; i++)
|
||||
{
|
||||
GParamSpec *pspec = specs[i];
|
||||
GParamSpec *pspec = specs[n_parent_properties + i];
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, pspec->value_type);
|
||||
gegl_node_get_property (node, pspec->name, &value);
|
||||
if (settings != NULL)
|
||||
g_object_get_property (G_OBJECT (settings), pspec->name, &value);
|
||||
else
|
||||
gegl_node_get_property (node, pspec->name, &value);
|
||||
|
||||
if (GEGL_IS_PARAM_SPEC_ENUM (pspec))
|
||||
{
|
||||
@ -549,6 +630,7 @@ HELP
|
||||
|
||||
g_strv_builder_unref (names_builder);
|
||||
g_free (specs);
|
||||
g_clear_object (&settings);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
@ -600,6 +682,8 @@ CODE
|
||||
"core/gimpdrawable-filters.h"
|
||||
"core/gimpimage-undo-push.h"
|
||||
"core/gimpitem.h"
|
||||
"operations/gimp-operation-config.h"
|
||||
"operations/gimpoperationsettings.h"
|
||||
"gimppdberror.h"
|
||||
"gimp-intl.h");
|
||||
|
||||
|
Reference in New Issue
Block a user