diff --git a/app/pdb/drawable-filter-cmds.c b/app/pdb/drawable-filter-cmds.c index c4eab42207..b0a991d84e 100644 --- a/app/pdb/drawable-filter-cmds.c +++ b/app/pdb/drawable-filter-cmds.c @@ -186,6 +186,97 @@ drawable_filter_set_visible_invoker (GimpProcedure *procedure, error ? *error : NULL); } +static GimpValueArray * +drawable_filter_get_number_arguments_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpValueArray *return_vals; + const gchar *operation_name; + gint num_args = 0; + + operation_name = g_value_get_string (gimp_value_array_index (args, 0)); + + if (success) + { + if (gegl_has_operation (operation_name)) + { + guint n_properties; + + g_free (gegl_operation_list_properties (operation_name, &n_properties)); + num_args = (gint) n_properties; + } + else + { + success = FALSE; + } + } + + return_vals = gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); + + if (success) + g_value_set_int (gimp_value_array_index (return_vals, 1), num_args); + + return return_vals; +} + +static GimpValueArray * +drawable_filter_get_argument_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpValueArray *return_vals; + const gchar *operation_name; + gint arg_num; + GParamSpec *param_spec = NULL; + + operation_name = g_value_get_string (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)) + { + GParamSpec **specs; + guint n_properties; + + specs = gegl_operation_list_properties (operation_name, &n_properties); + + if (arg_num >= 0 && arg_num < n_properties) + { + param_spec = g_param_spec_ref (specs[arg_num]); + } + else + { + success = FALSE; + } + + g_free (specs); + } + else + { + success = FALSE; + } + } + + return_vals = gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); + + if (success) + g_value_take_param (gimp_value_array_index (return_vals, 1), param_spec); + + return return_vals; +} + static GimpValueArray * drawable_filter_delete_invoker (GimpProcedure *procedure, Gimp *gimp, @@ -374,6 +465,73 @@ register_drawable_filter_procs (GimpPDB *pdb) gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); + /* + * gimp-drawable-filter-get-number-arguments + */ + procedure = gimp_procedure_new (drawable_filter_get_number_arguments_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "gimp-drawable-filter-get-number-arguments"); + gimp_procedure_set_static_help (procedure, + "Queries for the number of arguments on the specified filter.", + "This procedure returns the number of arguments on the specified filter.\n" + "For specific information on each input argument, use 'gimp-drawable-filter-get-argument'.", + NULL); + gimp_procedure_set_static_attribution (procedure, + "Jehan", + "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_procedure_add_return_value (procedure, + g_param_spec_int ("num-args", + "num args", + "The number of input arguments", + G_MININT32, G_MAXINT32, 0, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + + /* + * gimp-drawable-filter-get-argument + */ + procedure = gimp_procedure_new (drawable_filter_get_argument_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "gimp-drawable-filter-get-argument"); + gimp_procedure_set_static_help (procedure, + "Queries for information on the specified filter's argument.", + "This procedure returns the #GParamSpec of filter's argument.", + NULL); + gimp_procedure_set_static_attribution (procedure, + "Jehan", + "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_procedure_add_argument (procedure, + g_param_spec_int ("arg-num", + "arg num", + "The argument number", + G_MININT32, G_MAXINT32, 0, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_return_value (procedure, + g_param_spec_param ("param-spec", + "param spec", + "The GParamSpec of the argument", + G_TYPE_PARAM, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + /* * gimp-drawable-filter-delete */ diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c index 8202d4e781..250080995b 100644 --- a/app/pdb/internal-procs.c +++ b/app/pdb/internal-procs.c @@ -30,7 +30,7 @@ #include "internal-procs.h" -/* 725 procedures registered total */ +/* 727 procedures registered total */ void internal_procs_init (GimpPDB *pdb) diff --git a/app/plug-in/gimpgpparams.c b/app/plug-in/gimpgpparams.c index 448d4c9b58..24e671413d 100644 --- a/app/plug-in/gimpgpparams.c +++ b/app/plug-in/gimpgpparams.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "libgimpbase/gimpbase.h" #include "libgimpcolor/gimpcolor.h" diff --git a/libgimp/gimp.def b/libgimp/gimp.def index 1a0a3a6759..71dd892ac6 100644 --- a/libgimp/gimp.def +++ b/libgimp/gimp.def @@ -211,8 +211,10 @@ EXPORTS gimp_drawable_equalize gimp_drawable_extract_component gimp_drawable_fill + gimp_drawable_filter_config_get_type gimp_drawable_filter_delete gimp_drawable_filter_get_by_id + gimp_drawable_filter_get_config gimp_drawable_filter_get_id gimp_drawable_filter_get_name gimp_drawable_filter_get_operation_name diff --git a/libgimp/gimp.h b/libgimp/gimp.h index 8f984d3f1d..bea4fe53ad 100644 --- a/libgimp/gimp.h +++ b/libgimp/gimp.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/libgimp/gimpdrawablefilter.c b/libgimp/gimpdrawablefilter.c index 376f921e3c..1ad868d3b7 100644 --- a/libgimp/gimpdrawablefilter.c +++ b/libgimp/gimpdrawablefilter.c @@ -37,11 +37,14 @@ enum struct _GimpDrawableFilter { - GObject parent_instance; - gint id; + GObject parent_instance; + gint id; + + GimpDrawableFilterConfig *config; }; +static void gimp_drawable_filter_finalize (GObject *object); static void gimp_drawable_filter_set_property (GObject *object, guint property_id, const GValue *value, @@ -64,6 +67,7 @@ gimp_drawable_filter_class_init (GimpDrawableFilterClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = gimp_drawable_filter_finalize; object_class->set_property = gimp_drawable_filter_set_property; object_class->get_property = gimp_drawable_filter_get_property; @@ -81,6 +85,17 @@ gimp_drawable_filter_class_init (GimpDrawableFilterClass *klass) static void gimp_drawable_filter_init (GimpDrawableFilter *drawable_filter) { + drawable_filter->config = NULL; +} + +static void +gimp_drawable_filter_finalize (GObject *object) +{ + GimpDrawableFilter *filter = GIMP_DRAWABLE_FILTER (object); + + g_clear_object (&filter->config); + + G_OBJECT_CLASS (parent_class)->finalize (object); } static void @@ -182,3 +197,61 @@ gimp_drawable_filter_is_valid (GimpDrawableFilter *filter) { return gimp_drawable_filter_id_is_valid (gimp_drawable_filter_get_id (filter)); } + +/** + * gimp_drawable_filter_get_config: + * @filter: A drawable filter. + * + * Get the #GimpConfig with properties that match @filter's arguments. + * + * Returns: (transfer none): The new #GimpConfig. + * + * Since: 3.0 + **/ +GimpDrawableFilterConfig * +gimp_drawable_filter_get_config (GimpDrawableFilter *filter) +{ + gchar *config_type_name; + gchar *op_name; + gchar *canonical_name; + GType config_type; + gint n_args; + + g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), NULL); + + if (filter->config) + return filter->config; + + op_name = gimp_drawable_filter_get_operation_name (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); + + if (! config_type) + { + GParamSpec **config_args; + + config_args = g_new0 (GParamSpec *, n_args); + + for (gint i = 0; i < n_args; i++) + { + GParamSpec *pspec; + + pspec = _gimp_drawable_filter_get_argument (op_name, i); + config_args[i] = pspec; + } + + config_type = gimp_config_type_register (GIMP_TYPE_DRAWABLE_FILTER_CONFIG, + config_type_name, config_args, n_args); + + g_free (config_args); + } + + g_free (op_name); + g_free (canonical_name); + + filter->config = g_object_new (config_type, NULL); + + return filter->config; +} diff --git a/libgimp/gimpdrawablefilter.h b/libgimp/gimpdrawablefilter.h index 6aeca281cd..1b5727a437 100644 --- a/libgimp/gimpdrawablefilter.h +++ b/libgimp/gimpdrawablefilter.h @@ -36,11 +36,12 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (GimpDrawableFilter, gimp_drawable_filter, GIMP, DRAWABLE_FILTER, GObject) -gint32 gimp_drawable_filter_get_id (GimpDrawableFilter *filter); -GimpDrawableFilter * gimp_drawable_filter_get_by_id (gint32 filter_id); +gint32 gimp_drawable_filter_get_id (GimpDrawableFilter *filter); +GimpDrawableFilter * gimp_drawable_filter_get_by_id (gint32 filter_id); -gboolean gimp_drawable_filter_is_valid (GimpDrawableFilter *filter); +gboolean gimp_drawable_filter_is_valid (GimpDrawableFilter *filter); +GimpDrawableFilterConfig * gimp_drawable_filter_get_config (GimpDrawableFilter *filter); G_END_DECLS diff --git a/libgimp/gimpdrawablefilter_pdb.c b/libgimp/gimpdrawablefilter_pdb.c index 2831128c42..fa3b548f05 100644 --- a/libgimp/gimpdrawablefilter_pdb.c +++ b/libgimp/gimpdrawablefilter_pdb.c @@ -227,6 +227,85 @@ gimp_drawable_filter_set_visible (GimpDrawableFilter *filter, return success; } +/** + * _gimp_drawable_filter_get_number_arguments: + * @operation_name: The procedure name. + * + * Queries for the number of arguments on the specified filter. + * + * This procedure returns the number of arguments on the specified + * filter. + * For specific information on each input argument, use + * gimp_drawable_filter_get_argument(). + * + * Returns: The number of input arguments. + * + * Since: 3.0 + **/ +gint +_gimp_drawable_filter_get_number_arguments (const gchar *operation_name) +{ + GimpValueArray *args; + GimpValueArray *return_vals; + gint num_args = 0; + + args = gimp_value_array_new_from_types (NULL, + G_TYPE_STRING, operation_name, + G_TYPE_NONE); + + return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), + "gimp-drawable-filter-get-number-arguments", + args); + gimp_value_array_unref (args); + + if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS) + num_args = GIMP_VALUES_GET_INT (return_vals, 1); + + gimp_value_array_unref (return_vals); + + return num_args; +} + +/** + * _gimp_drawable_filter_get_argument: + * @operation_name: The procedure name. + * @arg_num: The argument number. + * + * Queries for information on the specified filter's argument. + * + * This procedure returns the #GParamSpec of filter's argument. + * + * Returns: (transfer full): The GParamSpec of the argument. + * The returned value must be freed with g_param_spec_unref(). + * + * Since: 3.0 + **/ +GParamSpec * +_gimp_drawable_filter_get_argument (const gchar *operation_name, + 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, + G_TYPE_INT, arg_num, + G_TYPE_NONE); + + return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), + "gimp-drawable-filter-get-argument", + args); + gimp_value_array_unref (args); + + if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS) + param_spec = GIMP_VALUES_DUP_PARAM (return_vals, 1); + + gimp_value_array_unref (return_vals); + + return param_spec; +} + /** * gimp_drawable_filter_delete: * @filter: The filter to delete. diff --git a/libgimp/gimpdrawablefilter_pdb.h b/libgimp/gimpdrawablefilter_pdb.h index 694c556c01..bef1439ca4 100644 --- a/libgimp/gimpdrawablefilter_pdb.h +++ b/libgimp/gimpdrawablefilter_pdb.h @@ -32,13 +32,16 @@ G_BEGIN_DECLS /* For information look into the C source or the html documentation */ -gboolean gimp_drawable_filter_id_is_valid (gint filter_id); -gchar* gimp_drawable_filter_get_name (GimpDrawableFilter *filter); -gchar* gimp_drawable_filter_get_operation_name (GimpDrawableFilter *filter); -gboolean gimp_drawable_filter_get_visible (GimpDrawableFilter *filter); -gboolean gimp_drawable_filter_set_visible (GimpDrawableFilter *filter, - gboolean visible); -gboolean gimp_drawable_filter_delete (GimpDrawableFilter *filter); +gboolean gimp_drawable_filter_id_is_valid (gint filter_id); +gchar* gimp_drawable_filter_get_name (GimpDrawableFilter *filter); +gchar* gimp_drawable_filter_get_operation_name (GimpDrawableFilter *filter); +gboolean gimp_drawable_filter_get_visible (GimpDrawableFilter *filter); +gboolean gimp_drawable_filter_set_visible (GimpDrawableFilter *filter, + gboolean visible); +G_GNUC_INTERNAL gint _gimp_drawable_filter_get_number_arguments (const gchar *operation_name); +G_GNUC_INTERNAL GParamSpec* _gimp_drawable_filter_get_argument (const gchar *operation_name, + gint arg_num); +gboolean gimp_drawable_filter_delete (GimpDrawableFilter *filter); G_END_DECLS diff --git a/libgimp/gimpdrawablefilterconfig.c b/libgimp/gimpdrawablefilterconfig.c new file mode 100644 index 0000000000..a2fdf5891d --- /dev/null +++ b/libgimp/gimpdrawablefilterconfig.c @@ -0,0 +1,53 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball + * + * gimpdrawablefilterconfig.c + * Copyright (C) 2024 Jehan + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include "config.h" + +#include "gimp.h" + + +/** + * GimpDrawableFilterConfig: + * + * The base class for [class@DrawableFilter] specific config objects. + * + * A drawable filter config is created by a [class@DrawableFilter] using + * [method@DrawableFilter.get_config] and its properties match the + * filter's arguments in number, order and type. + * + * Since: 3.0 + **/ + + +G_DEFINE_ABSTRACT_TYPE (GimpDrawableFilterConfig, gimp_drawable_filter_config, G_TYPE_OBJECT) + +#define parent_class gimp_drawable_filter_config_parent_class + + +static void +gimp_drawable_filter_config_class_init (GimpDrawableFilterConfigClass *klass) +{ +} + +static void +gimp_drawable_filter_config_init (GimpDrawableFilterConfig *config) +{ +} diff --git a/libgimp/gimpdrawablefilterconfig.h b/libgimp/gimpdrawablefilterconfig.h new file mode 100644 index 0000000000..50a7f80576 --- /dev/null +++ b/libgimp/gimpdrawablefilterconfig.h @@ -0,0 +1,57 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball + * + * gimpdrawablefilterconfig.h + * Copyright (C) 2024 Jehan + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __GIMP_DRAWABLE_FILTER_CONFIG_H__ +#define __GIMP_DRAWABLE_FILTER_CONFIG_H__ + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +#define GIMP_TYPE_DRAWABLE_FILTER_CONFIG (gimp_drawable_filter_config_get_type ()) +G_DECLARE_DERIVABLE_TYPE (GimpDrawableFilterConfig, gimp_drawable_filter_config, GIMP, DRAWABLE_FILTER_CONFIG, GObject) + +struct _GimpDrawableFilterConfigClass +{ + GObjectClass parent_class; + + /* Padding for future expansion */ + void (* _gimp_reserved0) (void); + void (* _gimp_reserved1) (void); + void (* _gimp_reserved2) (void); + void (* _gimp_reserved3) (void); + void (* _gimp_reserved4) (void); + void (* _gimp_reserved5) (void); + void (* _gimp_reserved6) (void); + void (* _gimp_reserved7) (void); + void (* _gimp_reserved8) (void); + void (* _gimp_reserved9) (void); +}; + + +G_END_DECLS + +#endif /* __GIMP_DRAWABLE_FILTER_CONFIG_H__ */ diff --git a/libgimp/gimpgpparams-body.c b/libgimp/gimpgpparams-body.c index fe90ff7295..39fc8d6e28 100644 --- a/libgimp/gimpgpparams-body.c +++ b/libgimp/gimpgpparams-body.c @@ -87,7 +87,19 @@ _gimp_gp_param_def_to_param_spec (const GPParamDef *param_def) break; case GP_PARAM_DEF_TYPE_CHOICE: - if (! strcmp (param_def->type_name, "GimpParamChoice")) + if (! strcmp (param_def->type_name, "GimpParamChoice") || +#ifdef LIBGIMP_COMPILATION + /* Special case for GeglParamEnum which are passed from core + * as a GimpChoice because the internal enum type could not + * always be reconstructed (XXX some could, the ones created + * as global GEGL enum types, but I could not find how to + * differentiate them on the other side of the wire). + */ + ! strcmp (param_def->type_name, "GeglParamEnum") +#else + FALSE +#endif + ) { return gimp_param_spec_choice (name, nick, blurb, g_object_ref (param_def->meta.m_choice.choice), @@ -328,10 +340,19 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec, param_def->blurb = (gchar *) g_param_spec_get_blurb (pspec); param_def->flags = pspec->flags; - if (pspec_type == G_TYPE_PARAM_INT) + if (pspec_type == G_TYPE_PARAM_INT || +#ifdef LIBGIMP_COMPILATION + FALSE +#else + pspec_type == GEGL_TYPE_PARAM_INT +#endif + ) { GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec); + if (! strcmp (param_def->type_name, "GeglParamInt")) + param_def->type_name = "GParamInt"; + param_def->param_def_type = GP_PARAM_DEF_TYPE_INT; param_def->meta.m_int.min_val = ispec->minimum; @@ -368,6 +389,60 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec, param_def->meta.m_unit.allow_percent = uspec->allow_percent; param_def->meta.m_unit.default_val = gimp_unit_get_id (uspec->default_value); } +#ifndef LIBGIMP_COMPILATION + /* This trick is only for core side when it needs to send the param + * spec of an enum argument of a GEGL Operation, because for all enum + * types created with enum_start|end macros in GEGL code, we are not + * able to recreate the enum type on the other side of the wire. + * Callers for instance will typically use int values instead. + * What we do instead is to reuse GimpChoice (which was exactly + * created for such internal-only enums, though it was initially for + * plug-ins only. In particular it means the value nicks will be used + * to set such argument (as a string property). + */ + else if (GEGL_IS_PARAM_SPEC_ENUM (pspec)) + { + GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec); + GeglParamSpecEnum *gespec = GEGL_PARAM_SPEC_ENUM (pspec); + GimpChoice *choice = gimp_choice_new (); + GEnumClass *enum_class; + GEnumValue *value; + + param_def->param_def_type = GP_PARAM_DEF_TYPE_CHOICE; + param_def->meta.m_choice.default_val = NULL; + + enum_class = g_type_class_ref (value_type); + for (value = enum_class->values; + value->value_name; + value++) + { + GSList *iter; + + if (value->value < enum_class->minimum || value->value > enum_class->maximum) + continue; + + for (iter = gespec->excluded_values; iter; iter = iter->next) + if (GPOINTER_TO_INT (iter->data) == value->value) + break; + + if (iter != NULL) + /* Excluded value. */ + continue; + + if (espec->default_value == value->value) + param_def->meta.m_choice.default_val = (gchar *) value->value_nick; + else if (param_def->meta.m_choice.default_val == NULL) + /* Make double-sure defaults is set. */ + param_def->meta.m_choice.default_val = (gchar *) value->value_nick; + + gimp_choice_add (choice, value->value_nick, value->value, value->value_name, NULL); + } + + param_def->meta.m_choice.choice = choice; + + g_type_class_unref (enum_class); + } +#endif else if (G_IS_PARAM_SPEC_ENUM (pspec)) { GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec); @@ -384,10 +459,25 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec, param_def->meta.m_boolean.default_val = bspec->default_value; } - else if (pspec_type == G_TYPE_PARAM_DOUBLE) + else if (pspec_type == G_TYPE_PARAM_DOUBLE || +#ifdef LIBGIMP_COMPILATION + FALSE +#else + pspec_type == GEGL_TYPE_PARAM_DOUBLE +#endif + ) { GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec); + /* We only support passing various GEGL param types from app to + * libgimp so far. It's used to send GEGL operations' arguments + * specifications. + * We transform them into simpler GLib param types. Additional + * features of GEGL params are mostly for UI usage. + */ + if (! strcmp (param_def->type_name, "GeglParamDouble")) + param_def->type_name = "GParamDouble"; + param_def->param_def_type = GP_PARAM_DEF_TYPE_DOUBLE; param_def->meta.m_double.min_val = dspec->minimum; @@ -405,11 +495,18 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec, param_def->meta.m_choice.default_val = sspec->default_value; param_def->meta.m_choice.choice = cspec->choice; } - else if (G_IS_PARAM_SPEC_STRING (pspec)) + else if (G_IS_PARAM_SPEC_STRING (pspec) && +#ifdef LIBGIMP_COMPILATION + pspec_type != GEGL_TYPE_PARAM_STRING +#else + TRUE +#endif + ) { GParamSpecString *gsspec = G_PARAM_SPEC_STRING (pspec); - if (! strcmp (param_def->type_name, "GimpParamString")) + if (! strcmp (param_def->type_name, "GimpParamString") || + ! strcmp (param_def->type_name, "GeglParamString")) param_def->type_name = "GParamString"; param_def->param_def_type = GP_PARAM_DEF_TYPE_STRING; @@ -1641,6 +1738,9 @@ _gimp_gp_params_free (GPParam *params, break; case GP_PARAM_TYPE_PARAM_DEF: + if (params[i].data.d_param_def.param_def_type == GP_PARAM_DEF_TYPE_CHOICE && + g_strcmp0 (params[i].data.d_param_def.type_name, "GeglParamEnum") == 0) + g_clear_object (¶ms[i].data.d_param_def.meta.m_choice.choice); break; } } diff --git a/libgimp/gimpgpparams.c b/libgimp/gimpgpparams.c index 6af9df6931..fedbccadf0 100644 --- a/libgimp/gimpgpparams.c +++ b/libgimp/gimpgpparams.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "libgimpbase/gimpbase.h" #include "libgimpcolor/gimpcolor.h" diff --git a/libgimp/gimptypes.h b/libgimp/gimptypes.h index a66623dc2d..e1afbe1541 100644 --- a/libgimp/gimptypes.h +++ b/libgimp/gimptypes.h @@ -28,38 +28,39 @@ G_BEGIN_DECLS /* For information look into the html documentation */ -typedef struct _GimpPDB GimpPDB; -typedef struct _GimpPlugIn GimpPlugIn; -typedef struct _GimpProcedure GimpProcedure; -typedef struct _GimpBatchProcedure GimpBatchProcedure; -typedef struct _GimpImageProcedure GimpImageProcedure; -typedef struct _GimpFileProcedure GimpFileProcedure; -typedef struct _GimpVectorLoadProcedure GimpVectorLoadProcedure; -typedef struct _GimpLoadProcedure GimpLoadProcedure; -typedef struct _GimpExportProcedure GimpExportProcedure; -typedef struct _GimpThumbnailProcedure GimpThumbnailProcedure; -typedef struct _GimpProcedureConfig GimpProcedureConfig; +typedef struct _GimpPDB GimpPDB; +typedef struct _GimpPlugIn GimpPlugIn; +typedef struct _GimpProcedure GimpProcedure; +typedef struct _GimpBatchProcedure GimpBatchProcedure; +typedef struct _GimpImageProcedure GimpImageProcedure; +typedef struct _GimpFileProcedure GimpFileProcedure; +typedef struct _GimpVectorLoadProcedure GimpVectorLoadProcedure; +typedef struct _GimpLoadProcedure GimpLoadProcedure; +typedef struct _GimpExportProcedure GimpExportProcedure; +typedef struct _GimpThumbnailProcedure GimpThumbnailProcedure; +typedef struct _GimpProcedureConfig GimpProcedureConfig; -typedef struct _GimpImage GimpImage; -typedef struct _GimpItem GimpItem; -typedef struct _GimpDrawable GimpDrawable; -typedef struct _GimpGroupLayer GimpGroupLayer; -typedef struct _GimpLayer GimpLayer; -typedef struct _GimpChannel GimpChannel; -typedef struct _GimpLayerMask GimpLayerMask; -typedef struct _GimpSelection GimpSelection; -typedef struct _GimpTextLayer GimpTextLayer; -typedef struct _GimpPath GimpPath; -typedef struct _GimpDrawableFilter GimpDrawableFilter; +typedef struct _GimpImage GimpImage; +typedef struct _GimpItem GimpItem; +typedef struct _GimpDrawable GimpDrawable; +typedef struct _GimpGroupLayer GimpGroupLayer; +typedef struct _GimpLayer GimpLayer; +typedef struct _GimpChannel GimpChannel; +typedef struct _GimpLayerMask GimpLayerMask; +typedef struct _GimpSelection GimpSelection; +typedef struct _GimpTextLayer GimpTextLayer; +typedef struct _GimpPath GimpPath; +typedef struct _GimpDrawableFilter GimpDrawableFilter; +typedef struct _GimpDrawableFilterConfig GimpDrawableFilterConfig; -typedef struct _GimpDisplay GimpDisplay; +typedef struct _GimpDisplay GimpDisplay; -typedef struct _GimpResource GimpResource; -typedef struct _GimpBrush GimpBrush; -typedef struct _GimpFont GimpFont; -typedef struct _GimpGradient GimpGradient; -typedef struct _GimpPattern GimpPattern; -typedef struct _GimpPalette GimpPalette; +typedef struct _GimpResource GimpResource; +typedef struct _GimpBrush GimpBrush; +typedef struct _GimpFont GimpFont; +typedef struct _GimpGradient GimpGradient; +typedef struct _GimpPattern GimpPattern; +typedef struct _GimpPalette GimpPalette; /* FIXME move somewhere else */ diff --git a/libgimp/meson.build b/libgimp/meson.build index b1685146e8..1bf9c899d8 100644 --- a/libgimp/meson.build +++ b/libgimp/meson.build @@ -181,6 +181,7 @@ libgimp_sources_introspectable = [ 'gimpdisplay.c', 'gimpdrawable.c', 'gimpdrawablefilter.c', + 'gimpdrawablefilterconfig.c', 'gimpexportoptions.c', 'gimpfileprocedure.c', 'gimpfont.c', @@ -243,6 +244,7 @@ libgimp_headers_introspectable = [ 'gimpdisplay.h', 'gimpdrawable.h', 'gimpdrawablefilter.h', + 'gimpdrawablefilterconfig.h', 'gimpexportoptions.h', 'gimpfileprocedure.h', 'gimpfont.h', diff --git a/pdb/groups/drawable_filter.pdb b/pdb/groups/drawable_filter.pdb index 69a02c7bad..3349a00a04 100644 --- a/pdb/groups/drawable_filter.pdb +++ b/pdb/groups/drawable_filter.pdb @@ -160,6 +160,105 @@ CODE ); } +sub drawable_filter_get_number_arguments { + $blurb = <<'BLURB'; +Queries for the number of arguments on the specified filter. +BLURB + + $help = <<'HELP'; +This procedure returns the number of arguments on the specified filter. + +For specific information on each input argument, use gimp_drawable_filter_get_argument(). +HELP + + &jehan_pdb_misc('2024', '3.0'); + + $lib_private = 1; + + @inargs = ( + { name => 'operation_name', type => 'string', non_empty => 1, + desc => 'The procedure name' } + ); + + @outargs = ( + { name => 'num_args', type => 'int32', + desc => 'The number of input arguments' }, + ); + + %invoke = ( + code => <<'CODE' +{ + if (gegl_has_operation (operation_name)) + { + guint n_properties; + + g_free (gegl_operation_list_properties (operation_name, &n_properties)); + num_args = (gint) n_properties; + } + else + { + success = FALSE; + } +} +CODE + ); +} + +sub drawable_filter_get_argument { + $blurb = < 'operation_name', type => 'string', non_empty => 1, + desc => 'The procedure name' }, + { name => 'arg_num', type => 'int32', + desc => 'The argument number' } + ); + + @outargs = ( + { name => 'param_spec', type => 'param', + desc => "The GParamSpec of the argument" } + ); + + %invoke = ( + code => <= 0 && arg_num < n_properties) + { + param_spec = g_param_spec_ref (specs[arg_num]); + } + else + { + success = FALSE; + } + + g_free (specs); + } + else + { + success = FALSE; + } +} +CODE + ); +} + sub drawable_filter_delete { $blurb = 'Delete a drawable filter.'; @@ -211,6 +310,8 @@ CODE drawable_filter_get_operation_name drawable_filter_get_visible drawable_filter_set_visible + drawable_filter_get_number_arguments + drawable_filter_get_argument drawable_filter_delete); %exports = (app => [@procs], lib => [@procs]);