[gimp] libgimp: add the concept of "Auxiliary arguments" to GimpProcedure



commit c3efeae31d20b2a26a8f643156695d89c4f20c55
Author: Michael Natterer <mitch gimp org>
Date:   Tue Sep 24 12:39:02 2019 +0200

    libgimp: add the concept of "Auxiliary arguments" to GimpProcedure
    
    Aux arguments are arbitrary values the procedure wants managed and
    remembered across invocations in GimpProcedureConfig. They are not
    passed to run() and are not known to the PDB, they only exist in the
    procedure's config object.

 libgimp/gimp.def              |   3 +
 libgimp/gimpprocedure.c       | 158 ++++++++++++++++++++++++++++++++++++++++--
 libgimp/gimpprocedure.h       |   8 +++
 libgimp/gimpprocedureconfig.c |  16 +++--
 4 files changed, 175 insertions(+), 10 deletions(-)
---
diff --git a/libgimp/gimp.def b/libgimp/gimp.def
index be6b2ec6ae..ae87bf74f4 100644
--- a/libgimp/gimp.def
+++ b/libgimp/gimp.def
@@ -677,6 +677,8 @@ EXPORTS
        gimp_plug_in_set_translation_domain
        gimp_procedure_add_argument
        gimp_procedure_add_argument_from_property
+       gimp_procedure_add_aux_argument
+       gimp_procedure_add_aux_argument_from_property
        gimp_procedure_add_menu_path
        gimp_procedure_add_return_value
        gimp_procedure_add_return_value_from_property
@@ -690,6 +692,7 @@ EXPORTS
        gimp_procedure_extension_ready
        gimp_procedure_get_arguments
        gimp_procedure_get_authors
+       gimp_procedure_get_aux_arguments
        gimp_procedure_get_blurb
        gimp_procedure_get_copyright
        gimp_procedure_get_date
diff --git a/libgimp/gimpprocedure.c b/libgimp/gimpprocedure.c
index 749ae4b006..c3ae18c838 100644
--- a/libgimp/gimpprocedure.c
+++ b/libgimp/gimpprocedure.c
@@ -74,6 +74,9 @@ struct _GimpProcedurePrivate
   gint32            n_args;
   GParamSpec      **args;
 
+  gint32            n_aux_args;
+  GParamSpec      **aux_args;
+
   gint32            n_values;
   GParamSpec      **values;
 
@@ -224,6 +227,14 @@ gimp_procedure_finalize (GObject *object)
       g_clear_pointer (&procedure->priv->args, g_free);
     }
 
+  if (procedure->priv->aux_args)
+    {
+      for (i = 0; i < procedure->priv->n_aux_args; i++)
+        g_param_spec_unref (procedure->priv->aux_args[i]);
+
+      g_clear_pointer (&procedure->priv->aux_args, g_free);
+    }
+
   if (procedure->priv->values)
     {
       for (i = 0; i < procedure->priv->n_values; i++)
@@ -484,9 +495,27 @@ gimp_procedure_real_create_config (GimpProcedure  *procedure,
   type = g_type_from_name (type_name);
 
   if (! type)
-    type = gimp_config_type_register (GIMP_TYPE_PROCEDURE_CONFIG,
-                                      type_name,
-                                      args, n_args);
+    {
+      GParamSpec **config_args;
+      gint         n_config_args;
+
+      n_config_args = n_args + procedure->priv->n_aux_args;
+
+      config_args = g_new0 (GParamSpec *, n_config_args);
+
+      memcpy (config_args,
+              args,
+              n_args * sizeof (GParamSpec *));
+      memcpy (config_args + n_args,
+              procedure->priv->aux_args,
+              procedure->priv->n_aux_args * sizeof (GParamSpec *));
+
+      type = gimp_config_type_register (GIMP_TYPE_PROCEDURE_CONFIG,
+                                        type_name,
+                                        config_args, n_config_args);
+
+      g_free (config_args);
+    }
 
   g_free (type_name);
 
@@ -1132,6 +1161,15 @@ gimp_procedure_add_argument (GimpProcedure *procedure,
         return;
       }
 
+  for (i = 0; i < procedure->priv->n_aux_args; i++)
+    if (! strcmp (pspec->name, procedure->priv->aux_args[i]->name))
+      {
+        g_warning ("Argument with name '%s' already exists on procedure '%s'",
+                   pspec->name,
+                   gimp_procedure_get_name (procedure));
+        return;
+      }
+
   procedure->priv->args = g_renew (GParamSpec *, procedure->priv->args,
                                    procedure->priv->n_args + 1);
 
@@ -1151,9 +1189,9 @@ gimp_procedure_add_argument (GimpProcedure *procedure,
  * Add a new argument to @procedure according to the specifications of
  * the property @prop_name registered on @config.
  *
- * The arguments will be ordered according to the call order to
- * gimp_procedure_add_argument() and
- * gimp_procedure_add_argument_from_property().
+ * See gimp_procedure_add_argument() for details.
+ *
+ * Since: 3.0
  */
 void
 gimp_procedure_add_argument_from_property (GimpProcedure *procedure,
@@ -1173,6 +1211,91 @@ gimp_procedure_add_argument_from_property (GimpProcedure *procedure,
   gimp_procedure_add_argument (procedure, pspec);
 }
 
+/**
+ * gimp_procedure_add_aux_argument:
+ * @procedure: the #GimpProcedure.
+ * @pspec:     (transfer full): the argument specification.
+ *
+ * Add a new auxiliary argument to @procedure according to @pspec
+ * specifications.
+ *
+ * Auxiliary arguments are not passed to the @procedure in run() and
+ * are not known to the PDB. They are however members of the
+ * #GimpProcedureConfig created by gimp_procedure_create_config() and
+ * can be used to persistently store whatever last used values the
+ * @procedure wants to remember across invocations
+ *
+ * Since: 3.0
+ **/
+void
+gimp_procedure_add_aux_argument (GimpProcedure *procedure,
+                                 GParamSpec    *pspec)
+{
+  gint i;
+
+  g_return_if_fail (GIMP_IS_PROCEDURE (procedure));
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (gimp_is_canonical_identifier (pspec->name));
+
+  for (i = 0; i < procedure->priv->n_args; i++)
+    if (! strcmp (pspec->name, procedure->priv->args[i]->name))
+      {
+        g_warning ("Argument with name '%s' already exists on procedure '%s'",
+                   pspec->name,
+                   gimp_procedure_get_name (procedure));
+        return;
+      }
+
+  for (i = 0; i < procedure->priv->n_aux_args; i++)
+    if (! strcmp (pspec->name, procedure->priv->aux_args[i]->name))
+      {
+        g_warning ("Argument with name '%s' already exists on procedure '%s'",
+                   pspec->name,
+                   gimp_procedure_get_name (procedure));
+        return;
+      }
+
+  procedure->priv->aux_args = g_renew (GParamSpec *, procedure->priv->aux_args,
+                                       procedure->priv->n_aux_args + 1);
+
+  procedure->priv->aux_args[procedure->priv->n_aux_args] = pspec;
+
+  g_param_spec_ref_sink (pspec);
+
+  procedure->priv->n_aux_args++;
+}
+
+/**
+ * gimp_procedure_add_aux_argument_from_property:
+ * @procedure: the #GimpProcedure.
+ * @config:    a #GObject.
+ * @prop_name: property name in @config.
+ *
+ * Add a new auxiliaty argument to @procedure according to the
+ * specifications of the property @prop_name registered on @config.
+ *
+ * See gimp_procedure_add_aux_argument() for details.
+ *
+ * Since: 3.0
+ */
+void
+gimp_procedure_add_aux_argument_from_property (GimpProcedure *procedure,
+                                               GObject       *config,
+                                               const gchar   *prop_name)
+{
+  GParamSpec *pspec;
+
+  g_return_if_fail (GIMP_IS_PROCEDURE (procedure));
+  g_return_if_fail (G_IS_OBJECT (config));
+  g_return_if_fail (prop_name != NULL);
+
+  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (config), prop_name);
+
+  g_return_if_fail (pspec != NULL);
+
+  gimp_procedure_add_aux_argument (procedure, pspec);
+}
+
 /**
  * gimp_procedure_add_return_value:
  * @procedure: the #GimpProcedure.
@@ -1270,6 +1393,29 @@ gimp_procedure_get_arguments (GimpProcedure *procedure,
   return procedure->priv->args;
 }
 
+/**
+ * gimp_procedure_get_aux_arguments:
+ * @procedure:   A #GimpProcedure.
+ * @n_arguments: (out): Returns the number of auxiliary arguments.
+ *
+ * Returns: (transfer none) (array length=n_arguments): An array
+ *          of @GParamSpec in the order added with
+ *          gimp_procedure_add_aux_argument().
+ *
+ * Since: 3.0
+ **/
+GParamSpec **
+gimp_procedure_get_aux_arguments (GimpProcedure *procedure,
+                                  gint          *n_arguments)
+{
+  g_return_val_if_fail (GIMP_IS_PROCEDURE (procedure), NULL);
+  g_return_val_if_fail (n_arguments != NULL, NULL);
+
+  *n_arguments = procedure->priv->n_aux_args;
+
+  return procedure->priv->aux_args;
+}
+
 /**
  * gimp_procedure_get_return_values:
  * @procedure:       A #GimpProcedure.
diff --git a/libgimp/gimpprocedure.h b/libgimp/gimpprocedure.h
index 5ae852f3f8..70ca03da65 100644
--- a/libgimp/gimpprocedure.h
+++ b/libgimp/gimpprocedure.h
@@ -167,6 +167,12 @@ void             gimp_procedure_add_argument_from_property
                                                    (GimpProcedure        *procedure,
                                                     GObject              *config,
                                                     const gchar          *prop_name);
+void             gimp_procedure_add_aux_argument   (GimpProcedure        *procedure,
+                                                    GParamSpec           *pspec);
+void             gimp_procedure_add_aux_argument_from_property
+                                                   (GimpProcedure        *procedure,
+                                                    GObject              *config,
+                                                    const gchar          *prop_name);
 void             gimp_procedure_add_return_value   (GimpProcedure        *procedure,
                                                     GParamSpec           *pspec);
 void             gimp_procedure_add_return_value_from_property
@@ -176,6 +182,8 @@ void             gimp_procedure_add_return_value_from_property
 
 GParamSpec    ** gimp_procedure_get_arguments      (GimpProcedure        *procedure,
                                                     gint                 *n_arguments);
+GParamSpec    ** gimp_procedure_get_aux_arguments  (GimpProcedure        *procedure,
+                                                    gint                 *n_arguments);
 GParamSpec    ** gimp_procedure_get_return_values  (GimpProcedure        *procedure,
                                                     gint                 *n_return_values);
 
diff --git a/libgimp/gimpprocedureconfig.c b/libgimp/gimpprocedureconfig.c
index 780e9aa34f..ea6de49ba9 100644
--- a/libgimp/gimpprocedureconfig.c
+++ b/libgimp/gimpprocedureconfig.c
@@ -228,6 +228,8 @@ gimp_procedure_config_set_values (GimpProcedureConfig  *config,
 {
   GParamSpec **pspecs;
   guint        n_pspecs;
+  gint         n_aux_args;
+  gint         n_values;
   gint         i;
 
   g_return_if_fail (GIMP_IS_PROCEDURE_CONFIG (config));
@@ -235,10 +237,12 @@ gimp_procedure_config_set_values (GimpProcedureConfig  *config,
 
   pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config),
                                            &n_pspecs);
+  gimp_procedure_get_aux_arguments (config->priv->procedure, &n_aux_args);
+  n_values = gimp_value_array_length (values);
 
-  g_return_if_fail (n_pspecs == gimp_value_array_length (values));
+  g_return_if_fail (n_pspecs == n_values + n_aux_args);
 
-  for (i = 0; i < n_pspecs; i++)
+  for (i = 0; i < n_values; i++)
     {
       GParamSpec *pspec = pspecs[i];
       GValue     *value = gimp_value_array_index (values, i);
@@ -267,6 +271,8 @@ gimp_procedure_config_get_values (GimpProcedureConfig  *config,
 {
   GParamSpec **pspecs;
   guint        n_pspecs;
+  gint         n_aux_args;
+  gint         n_values;
   gint         i;
 
   g_return_if_fail (GIMP_IS_PROCEDURE_CONFIG (config));
@@ -274,10 +280,12 @@ gimp_procedure_config_get_values (GimpProcedureConfig  *config,
 
   pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config),
                                            &n_pspecs);
+  gimp_procedure_get_aux_arguments (config->priv->procedure, &n_aux_args);
+  n_values = gimp_value_array_length (values);
 
-  g_return_if_fail (n_pspecs == gimp_value_array_length (values));
+  g_return_if_fail (n_pspecs == n_values + n_aux_args);
 
-  for (i = 0; i < n_pspecs; i++)
+  for (i = 0; i < n_values; i++)
     {
       GParamSpec *pspec = pspecs[i];
       GValue     *value = gimp_value_array_index (values, i);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]