Updated with upstream update
This commit is contained in:
@ -642,18 +642,17 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
gboolean permissive,
|
||||
gboolean deprecated)
|
||||
{
|
||||
PikaProcedure *procedure;
|
||||
PikaValueArray *args;
|
||||
PikaValueArray *values = NULL;
|
||||
gchar *proc_name;
|
||||
GParamSpec **arg_specs;
|
||||
gint n_arg_specs;
|
||||
gint actual_arg_count;
|
||||
gint consumed_arg_count = 0;
|
||||
gchar error_str[1024];
|
||||
gint i;
|
||||
pointer return_val = sc->NIL;
|
||||
|
||||
PikaProcedure *procedure;
|
||||
PikaProcedureConfig *config;
|
||||
PikaValueArray *values = NULL;
|
||||
gchar *proc_name;
|
||||
GParamSpec **arg_specs;
|
||||
gint n_arg_specs;
|
||||
gint actual_arg_count;
|
||||
gint consumed_arg_count = 0;
|
||||
gchar error_str[1024];
|
||||
gint i;
|
||||
pointer return_val = sc->NIL;
|
||||
|
||||
g_debug ("In %s()", G_STRFUNC);
|
||||
|
||||
@ -692,6 +691,7 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
return script_error (sc, error_str, 0);
|
||||
}
|
||||
|
||||
config = pika_procedure_create_config (procedure);
|
||||
arg_specs = pika_procedure_get_arguments (procedure, &n_arg_specs);
|
||||
actual_arg_count = sc->vptr->list_length (sc, a) - 1;
|
||||
|
||||
@ -724,8 +724,6 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
}
|
||||
|
||||
/* Marshall the supplied arguments */
|
||||
args = pika_value_array_new (n_arg_specs);
|
||||
|
||||
for (i = 0; i < n_arg_specs; i++)
|
||||
{
|
||||
GParamSpec *arg_spec = arg_specs[i];
|
||||
@ -756,34 +754,98 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
if (G_VALUE_HOLDS_INT (&value))
|
||||
{
|
||||
if (! sc->vptr->is_number (sc->vptr->pair_car (a)))
|
||||
return script_type_error (sc, "numeric", i, proc_name);
|
||||
{
|
||||
return script_type_error (sc, "numeric", i, proc_name);
|
||||
}
|
||||
else
|
||||
g_value_set_int (&value,
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (a)));
|
||||
{
|
||||
GParamSpecInt *ispec = G_PARAM_SPEC_INT (arg_spec);
|
||||
gint v = sc->vptr->ivalue (sc->vptr->pair_car (a));
|
||||
|
||||
if (v < ispec->minimum || v > ispec->maximum)
|
||||
{
|
||||
gchar error_message[1024];
|
||||
|
||||
g_snprintf (error_message, sizeof (error_message),
|
||||
"Invalid value %d for argument %d: expected value between %d and %d",
|
||||
v, i, ispec->minimum, ispec->maximum);
|
||||
return script_error (sc, error_message, 0);
|
||||
}
|
||||
|
||||
g_value_set_int (&value, v);
|
||||
}
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UINT (&value))
|
||||
{
|
||||
if (! sc->vptr->is_number (sc->vptr->pair_car (a)))
|
||||
return script_type_error (sc, "numeric", i, proc_name);
|
||||
{
|
||||
return script_type_error (sc, "numeric", i, proc_name);
|
||||
}
|
||||
else
|
||||
g_value_set_uint (&value,
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (a)));
|
||||
{
|
||||
GParamSpecUInt *ispec = G_PARAM_SPEC_UINT (arg_spec);
|
||||
gint v = sc->vptr->ivalue (sc->vptr->pair_car (a));
|
||||
|
||||
if (v < ispec->minimum || v > ispec->maximum)
|
||||
{
|
||||
gchar error_message[1024];
|
||||
|
||||
g_snprintf (error_message, sizeof (error_message),
|
||||
"Invalid value %d for argument %d: expected value between %d and %d",
|
||||
v, i, ispec->minimum, ispec->maximum);
|
||||
return script_error (sc, error_message, 0);
|
||||
}
|
||||
|
||||
g_value_set_uint (&value, v);
|
||||
}
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UCHAR (&value))
|
||||
{
|
||||
if (! sc->vptr->is_number (sc->vptr->pair_car (a)))
|
||||
return script_type_error (sc, "numeric", i, proc_name);
|
||||
{
|
||||
return script_type_error (sc, "numeric", i, proc_name);
|
||||
}
|
||||
else
|
||||
g_value_set_uchar (&value,
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (a)));
|
||||
{
|
||||
GParamSpecUChar *cspec = G_PARAM_SPEC_UCHAR (arg_spec);
|
||||
gint c = sc->vptr->ivalue (sc->vptr->pair_car (a));
|
||||
|
||||
if (c < cspec->minimum || c > cspec->maximum)
|
||||
{
|
||||
gchar error_message[1024];
|
||||
|
||||
g_snprintf (error_message, sizeof (error_message),
|
||||
"Invalid value %d for argument %d: expected value between %d and %d",
|
||||
c, i, cspec->minimum, cspec->maximum);
|
||||
return script_error (sc, error_message, 0);
|
||||
}
|
||||
|
||||
g_value_set_uchar (&value, c);
|
||||
}
|
||||
}
|
||||
else if (G_VALUE_HOLDS_DOUBLE (&value))
|
||||
{
|
||||
if (! sc->vptr->is_number (sc->vptr->pair_car (a)))
|
||||
return script_type_error (sc, "numeric", i, proc_name);
|
||||
{
|
||||
return script_type_error (sc, "numeric", i, proc_name);
|
||||
}
|
||||
else
|
||||
g_value_set_double (&value,
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (a)));
|
||||
{
|
||||
GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (arg_spec);
|
||||
gdouble d = sc->vptr->rvalue (sc->vptr->pair_car (a));
|
||||
|
||||
if (d < dspec->minimum || d > dspec->maximum)
|
||||
{
|
||||
gchar error_message[1024];
|
||||
|
||||
g_snprintf (error_message, sizeof (error_message),
|
||||
"Invalid value %f for argument %d: expected value between %f and %f",
|
||||
d, i, dspec->minimum, dspec->maximum);
|
||||
return script_error (sc, error_message, 0);
|
||||
}
|
||||
|
||||
g_value_set_double (&value, d);
|
||||
}
|
||||
}
|
||||
else if (G_VALUE_HOLDS_ENUM (&value))
|
||||
{
|
||||
@ -850,8 +912,7 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
{
|
||||
g_printerr (" ");
|
||||
for (j = 0; j < count; ++j)
|
||||
g_printerr (" \"%s\"",
|
||||
args[i].data.d_strv[j]);
|
||||
g_printerr (" \"%s\"", array[j]);
|
||||
g_printerr ("\n");
|
||||
}
|
||||
}
|
||||
@ -992,7 +1053,12 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
*/
|
||||
gint32 *array;
|
||||
|
||||
n_elements = PIKA_VALUES_GET_INT (args, i - 1);
|
||||
if (i == 0)
|
||||
return script_error (sc, "The first argument cannot be an array", a);
|
||||
else if (! g_type_is_a (arg_specs[i - 1]->value_type, G_TYPE_INT))
|
||||
return script_error (sc, "Array arguments must be preceded by an int argument (number of items)", a);
|
||||
|
||||
g_object_get (config, arg_specs[i - 1]->name, &n_elements, NULL);
|
||||
|
||||
if (n_elements > sc->vptr->vector_length (vector))
|
||||
return script_length_error_in_vector (sc, i, proc_name, n_elements, vector);
|
||||
@ -1058,7 +1124,12 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
{
|
||||
gdouble *array;
|
||||
|
||||
n_elements = PIKA_VALUES_GET_INT (args, i - 1);
|
||||
if (i == 0)
|
||||
return script_error (sc, "The first argument cannot be an array", a);
|
||||
else if (! g_type_is_a (arg_specs[i - 1]->value_type, G_TYPE_INT))
|
||||
return script_error (sc, "Array arguments must be preceded by an int argument (number of items)", a);
|
||||
|
||||
g_object_get (config, arg_specs[i - 1]->name, &n_elements, NULL);
|
||||
|
||||
if (n_elements > sc->vptr->vector_length (vector))
|
||||
return script_length_error_in_vector (sc, i, proc_name, n_elements, vector);
|
||||
@ -1142,7 +1213,12 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
{
|
||||
PikaRGB *array;
|
||||
|
||||
n_elements = PIKA_VALUES_GET_INT (args, i - 1);
|
||||
if (i == 0)
|
||||
return script_error (sc, "The first argument cannot be an array", a);
|
||||
else if (! g_type_is_a (arg_specs[i - 1]->value_type, G_TYPE_INT))
|
||||
return script_error (sc, "Array arguments must be preceded by an int argument (number of items)", a);
|
||||
|
||||
g_object_get (config, arg_specs[i - 1]->name, &n_elements, NULL);
|
||||
|
||||
if (n_elements > sc->vptr->vector_length (vector))
|
||||
return script_length_error_in_vector (sc, i, proc_name, n_elements, vector);
|
||||
@ -1275,6 +1351,8 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
* ID's are unique across all instances of Resource.
|
||||
*/
|
||||
resource = pika_resource_get_by_id (resource_id);
|
||||
if (resource == NULL)
|
||||
g_warning ("%s: passing null Resource, invalid ID.", G_STRFUNC);
|
||||
|
||||
g_value_set_object (&value, resource);
|
||||
}
|
||||
@ -1287,7 +1365,18 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
return implementation_error (sc, error_str, 0);
|
||||
}
|
||||
debug_gvalue (&value);
|
||||
pika_value_array_append (args, &value);
|
||||
if (g_param_value_validate (arg_spec, &value))
|
||||
{
|
||||
gchar error_message[1024];
|
||||
|
||||
g_snprintf (error_message, sizeof (error_message),
|
||||
"Invalid value for argument %d",
|
||||
i);
|
||||
g_value_unset (&value);
|
||||
|
||||
return script_error (sc, error_message, 0);
|
||||
}
|
||||
g_object_set_property (G_OBJECT (config), arg_specs[i]->name, &value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
@ -1296,9 +1385,9 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
return script_error (sc, "A script cannot refresh scripts", 0);
|
||||
|
||||
g_debug ("calling %s", proc_name);
|
||||
values = pika_pdb_run_procedure_array (pika_get_pdb (),
|
||||
proc_name, args);
|
||||
values = pika_procedure_run_config (procedure, config);
|
||||
g_debug ("done.");
|
||||
g_clear_object (&config);
|
||||
|
||||
/* Check the return status */
|
||||
if (! values)
|
||||
@ -1330,7 +1419,6 @@ script_fu_marshal_procedure_call (scheme *sc,
|
||||
pika_value_array_unref (values);
|
||||
|
||||
/* free arguments and values */
|
||||
pika_value_array_unref (args);
|
||||
|
||||
/* The callback is NULL except for script-fu-server. See explanation there. */
|
||||
if (post_command_callback != NULL)
|
||||
|
@ -98,6 +98,7 @@ script_fu_arg_free (SFArg *arg)
|
||||
|
||||
switch (arg->type)
|
||||
{
|
||||
/* Integer ID's: primitives not needing free. */
|
||||
case SF_IMAGE:
|
||||
case SF_DRAWABLE:
|
||||
case SF_LAYER:
|
||||
@ -106,6 +107,13 @@ script_fu_arg_free (SFArg *arg)
|
||||
case SF_DISPLAY:
|
||||
case SF_COLOR:
|
||||
case SF_TOGGLE:
|
||||
|
||||
case SF_BRUSH:
|
||||
case SF_FONT:
|
||||
case SF_GRADIENT:
|
||||
case SF_PALETTE:
|
||||
case SF_PATTERN:
|
||||
|
||||
break;
|
||||
|
||||
case SF_VALUE:
|
||||
@ -124,36 +132,6 @@ script_fu_arg_free (SFArg *arg)
|
||||
g_free (arg->value.sfa_file.filename);
|
||||
break;
|
||||
|
||||
/* FUTURE: font..gradient could all use the same code.
|
||||
* Since the type in the union are all the same: gchar*.
|
||||
* That is, group these cases with SF_VALUE.
|
||||
* But this method should go away altogether.
|
||||
*/
|
||||
case SF_FONT:
|
||||
g_free (arg->default_value.sfa_font);
|
||||
g_free (arg->value.sfa_font);
|
||||
break;
|
||||
|
||||
case SF_PALETTE:
|
||||
g_free (arg->default_value.sfa_palette);
|
||||
g_free (arg->value.sfa_palette);
|
||||
break;
|
||||
|
||||
case SF_PATTERN:
|
||||
g_free (arg->default_value.sfa_pattern);
|
||||
g_free (arg->value.sfa_pattern);
|
||||
break;
|
||||
|
||||
case SF_GRADIENT:
|
||||
g_free (arg->default_value.sfa_gradient);
|
||||
g_free (arg->value.sfa_gradient);
|
||||
break;
|
||||
|
||||
case SF_BRUSH:
|
||||
g_free (arg->default_value.sfa_brush);
|
||||
g_free (arg->value.sfa_brush);
|
||||
break;
|
||||
|
||||
case SF_OPTION:
|
||||
g_slist_free_full (arg->default_value.sfa_option.list,
|
||||
(GDestroyNotify) g_free);
|
||||
@ -180,6 +158,13 @@ script_fu_arg_reset (SFArg *arg, gboolean should_reset_ids)
|
||||
case SF_CHANNEL:
|
||||
case SF_VECTORS:
|
||||
case SF_DISPLAY:
|
||||
|
||||
case SF_BRUSH:
|
||||
case SF_FONT:
|
||||
case SF_GRADIENT:
|
||||
case SF_PALETTE:
|
||||
case SF_PATTERN:
|
||||
|
||||
if (should_reset_ids)
|
||||
{
|
||||
/* !!! Use field name "sfa_image"; all these cases have same type in union.
|
||||
@ -216,35 +201,6 @@ script_fu_arg_reset (SFArg *arg, gboolean should_reset_ids)
|
||||
value->sfa_file.filename = g_strdup (default_value->sfa_file.filename);
|
||||
break;
|
||||
|
||||
/* FUTURE: font..gradient could all use the same code.
|
||||
* Since the type in the union are all the same: gchar*.
|
||||
* That is, group these cases with SF_VALUE.
|
||||
*/
|
||||
case SF_FONT:
|
||||
g_free (value->sfa_font);
|
||||
value->sfa_font = g_strdup (default_value->sfa_font);
|
||||
break;
|
||||
|
||||
case SF_PALETTE:
|
||||
g_free (value->sfa_palette);
|
||||
value->sfa_palette = g_strdup (default_value->sfa_palette);
|
||||
break;
|
||||
|
||||
case SF_PATTERN:
|
||||
g_free (value->sfa_pattern);
|
||||
value->sfa_pattern = g_strdup (default_value->sfa_pattern);
|
||||
break;
|
||||
|
||||
case SF_GRADIENT:
|
||||
g_free (value->sfa_gradient);
|
||||
value->sfa_gradient = g_strdup (default_value->sfa_gradient);
|
||||
break;
|
||||
|
||||
case SF_BRUSH:
|
||||
g_free (value->sfa_brush);
|
||||
value->sfa_brush = g_strdup (default_value->sfa_brush);
|
||||
break;
|
||||
|
||||
case SF_OPTION:
|
||||
value->sfa_option.history = default_value->sfa_option.history;
|
||||
break;
|
||||
@ -486,6 +442,14 @@ script_fu_arg_append_repr_from_gvalue (SFArg *arg,
|
||||
case SF_CHANNEL:
|
||||
case SF_VECTORS:
|
||||
case SF_DISPLAY:
|
||||
|
||||
/* The GValue is a GObject of type inheriting PikaResource, having id prop */
|
||||
case SF_BRUSH:
|
||||
case SF_FONT:
|
||||
case SF_GRADIENT:
|
||||
case SF_PALETTE:
|
||||
case SF_PATTERN:
|
||||
|
||||
{
|
||||
GObject *object = g_value_get_object (gvalue);
|
||||
gint id = -1;
|
||||
@ -584,25 +548,6 @@ script_fu_arg_append_repr_from_gvalue (SFArg *arg,
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_FONT:
|
||||
case SF_PALETTE:
|
||||
case SF_PATTERN:
|
||||
case SF_GRADIENT:
|
||||
case SF_BRUSH:
|
||||
{
|
||||
/* The GValue is a GObject of type inheriting PikaResource */
|
||||
PikaResource *resource;
|
||||
gchar *name = NULL;
|
||||
|
||||
resource = g_value_get_object (gvalue);
|
||||
|
||||
if (resource)
|
||||
name = pika_resource_get_name (resource);
|
||||
|
||||
g_string_append_printf (result_string, "\"%s\"", name);
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_OPTION:
|
||||
append_int_repr_from_gvalue (result_string, gvalue);
|
||||
break;
|
||||
@ -648,6 +593,12 @@ script_fu_arg_append_repr_from_self (SFArg *arg,
|
||||
case SF_CHANNEL:
|
||||
case SF_VECTORS:
|
||||
case SF_DISPLAY:
|
||||
|
||||
case SF_BRUSH:
|
||||
case SF_FONT:
|
||||
case SF_GRADIENT:
|
||||
case SF_PALETTE:
|
||||
case SF_PATTERN:
|
||||
g_string_append_printf (result_string, "%d", arg_value->sfa_image);
|
||||
break;
|
||||
|
||||
@ -701,26 +652,6 @@ script_fu_arg_append_repr_from_self (SFArg *arg,
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_FONT:
|
||||
g_string_append_printf (result_string, "\"%s\"", arg_value->sfa_font);
|
||||
break;
|
||||
|
||||
case SF_PALETTE:
|
||||
g_string_append_printf (result_string, "\"%s\"", arg_value->sfa_palette);
|
||||
break;
|
||||
|
||||
case SF_PATTERN:
|
||||
g_string_append_printf (result_string, "\"%s\"", arg_value->sfa_pattern);
|
||||
break;
|
||||
|
||||
case SF_GRADIENT:
|
||||
g_string_append_printf (result_string, "\"%s\"", arg_value->sfa_gradient);
|
||||
break;
|
||||
|
||||
case SF_BRUSH:
|
||||
g_string_append_printf (result_string, "\"%s\"", arg_value->sfa_brush);
|
||||
break;
|
||||
|
||||
case SF_OPTION:
|
||||
g_string_append_printf (result_string, "%d", arg_value->sfa_option.history);
|
||||
break;
|
||||
@ -883,6 +814,38 @@ script_fu_arg_generate_name_and_nick (SFArg *arg,
|
||||
}
|
||||
|
||||
|
||||
/* Init the value of an SFArg that is a resource.
|
||||
* In case user does not touch a widget.
|
||||
* Cannot be called at registration time.
|
||||
* Init to value from context, the same as a widget
|
||||
* will do when passed a NULL initial resource.
|
||||
*/
|
||||
void
|
||||
script_fu_arg_init_resource (SFArg *arg, GType resource_type)
|
||||
{
|
||||
PikaResource *resource;
|
||||
|
||||
if (resource_type == PIKA_TYPE_BRUSH)
|
||||
resource = PIKA_RESOURCE (pika_context_get_brush ());
|
||||
else if (resource_type == PIKA_TYPE_FONT)
|
||||
resource = PIKA_RESOURCE (pika_context_get_font ());
|
||||
else if (resource_type == PIKA_TYPE_GRADIENT)
|
||||
resource = PIKA_RESOURCE (pika_context_get_gradient ());
|
||||
else if (resource_type == PIKA_TYPE_PALETTE)
|
||||
resource = PIKA_RESOURCE (pika_context_get_palette ());
|
||||
else if (resource_type == PIKA_TYPE_PATTERN)
|
||||
resource = PIKA_RESOURCE (pika_context_get_pattern ());
|
||||
else
|
||||
{
|
||||
g_warning ("%s: Failed get resource from context", G_STRFUNC);
|
||||
arg->value.sfa_resource = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
arg->value.sfa_resource = pika_resource_get_id (resource);
|
||||
}
|
||||
|
||||
|
||||
/* Set the default of a GParamSpec to a GFile for a path string.
|
||||
* The GFile is allocated and ownership is transferred to the GParamSpec.
|
||||
* The GFile is only a name and a so-named file might not exist.
|
||||
|
@ -40,4 +40,7 @@ void script_fu_arg_generate_name_and_nick (SFArg *arg,
|
||||
const gchar **name,
|
||||
const gchar **nick);
|
||||
|
||||
void script_fu_arg_init_resource (SFArg *arg,
|
||||
GType resource_type);
|
||||
|
||||
#endif /* __SCRIPT_FU_ARG__ */
|
||||
|
@ -98,20 +98,19 @@ script_fu_run_command (const gchar *command,
|
||||
* 2) adds actual args image, drawable, etc. for PikaImageProcedure
|
||||
*/
|
||||
PikaValueArray *
|
||||
script_fu_interpret_image_proc (
|
||||
PikaProcedure *procedure,
|
||||
SFScript *script,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args)
|
||||
script_fu_interpret_image_proc (PikaProcedure *procedure,
|
||||
SFScript *script,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
PikaProcedureConfig *config)
|
||||
{
|
||||
gchar *command;
|
||||
PikaValueArray *result = NULL;
|
||||
gboolean interpretation_result;
|
||||
GError *error = NULL;
|
||||
|
||||
command = script_fu_script_get_command_for_image_proc (script, image, n_drawables, drawables, args);
|
||||
command = script_fu_script_get_command_for_image_proc (script, image, n_drawables, drawables, config);
|
||||
|
||||
/* Take responsibility for handling errors from the scripts further calls to PDB.
|
||||
* ScriptFu does not show an error dialog, but forwards errors back to PIKA.
|
||||
|
@ -30,6 +30,6 @@ PikaValueArray *script_fu_interpret_image_proc (PikaProcedure *procedure,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args);
|
||||
PikaProcedureConfig *config);
|
||||
|
||||
#endif /* __SCRIPT_FU_COMMAND_H__ */
|
||||
|
@ -64,72 +64,37 @@ dump_properties (PikaProcedureConfig *config)
|
||||
g_free (pspecs);
|
||||
}
|
||||
|
||||
static gint
|
||||
get_length (PikaProcedureConfig *config)
|
||||
{
|
||||
GParamSpec **pspecs;
|
||||
guint n_pspecs;
|
||||
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config),
|
||||
&n_pspecs);
|
||||
g_free (pspecs);
|
||||
g_debug ("length config: %d", n_pspecs);
|
||||
|
||||
return n_pspecs;
|
||||
}
|
||||
|
||||
/* Fill a new (length zero) gva with new gvalues (empty but holding the correct type)
|
||||
from the config.
|
||||
*/
|
||||
static void
|
||||
fill_gva_from (PikaProcedureConfig *config,
|
||||
PikaValueArray *gva)
|
||||
{
|
||||
GParamSpec **pspecs;
|
||||
guint n_pspecs;
|
||||
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config),
|
||||
&n_pspecs);
|
||||
/* !!! Start at property 1 */
|
||||
for (guint i = 1; i < n_pspecs; i++)
|
||||
{
|
||||
g_debug ("%s %s\n", pspecs[i]->name, G_PARAM_SPEC_TYPE_NAME (pspecs[i]));
|
||||
/* append empty gvalue */
|
||||
pika_value_array_append (gva, NULL);
|
||||
}
|
||||
|
||||
g_free (pspecs);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_objects (PikaProcedureConfig *config)
|
||||
dump_objects (PikaProcedureConfig *config)
|
||||
{
|
||||
/* Check it will return non-null objects. */
|
||||
PikaValueArray *args;
|
||||
gint length;
|
||||
GParamSpec **pspecs;
|
||||
guint n_pspecs;
|
||||
|
||||
/* Need one less gvalue !!! */
|
||||
args = pika_value_array_new (get_length (config) - 1);
|
||||
/* The array still has length zero. */
|
||||
g_debug ("GVA length: %d", pika_value_array_length (args));
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config), &n_pspecs);
|
||||
|
||||
fill_gva_from (config, args);
|
||||
|
||||
pika_procedure_config_get_values (config, args);
|
||||
if (args == NULL)
|
||||
/* config will have at least 1 property: "procedure". */
|
||||
if (n_pspecs == 1)
|
||||
{
|
||||
g_debug ("config holds no values");
|
||||
return;
|
||||
}
|
||||
length = pika_value_array_length (args);
|
||||
|
||||
for (guint i = 1; i < length; i++)
|
||||
for (gint i = 1; i < n_pspecs; i++)
|
||||
{
|
||||
GValue *gvalue = pika_value_array_index (args, i);
|
||||
if (G_VALUE_HOLDS_OBJECT (gvalue))
|
||||
if (g_value_get_object (gvalue) == NULL)
|
||||
GParamSpec *pspec = pspecs[i];
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, pspec->value_type);
|
||||
g_object_get_property (G_OBJECT (config), pspec->name, &value);
|
||||
|
||||
if (G_VALUE_HOLDS_OBJECT (&value))
|
||||
if (g_value_get_object (&value) == NULL)
|
||||
g_debug ("gvalue %d holds NULL object", i);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
g_free (pspecs);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -152,18 +117,19 @@ script_fu_dialog_run (PikaProcedure *procedure,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *initial_args)
|
||||
PikaProcedureConfig *config)
|
||||
|
||||
{
|
||||
PikaValueArray *result = NULL;
|
||||
PikaProcedureDialog *dialog = NULL;
|
||||
PikaProcedureConfig *config = NULL;
|
||||
gboolean not_canceled;
|
||||
guint n_specs;
|
||||
|
||||
if ( (! G_IS_OBJECT (procedure)) || script == NULL)
|
||||
return pika_procedure_new_return_values (procedure, PIKA_PDB_EXECUTION_ERROR, NULL);
|
||||
|
||||
if ( pika_value_array_length (initial_args) < 1)
|
||||
g_free (g_object_class_list_properties (G_OBJECT_GET_CLASS (config), &n_specs));
|
||||
if (n_specs < 2)
|
||||
return pika_procedure_new_return_values (procedure, PIKA_PDB_EXECUTION_ERROR, NULL);
|
||||
|
||||
/* We don't prevent concurrent dialogs as in script-fu-interface.c.
|
||||
@ -179,22 +145,12 @@ script_fu_dialog_run (PikaProcedure *procedure,
|
||||
/* Script's menu label */
|
||||
pika_ui_init (script_fu_script_get_title (script));
|
||||
|
||||
config = pika_procedure_create_config (procedure);
|
||||
#if DEBUG_CONFIG_PROPERTIES
|
||||
dump_properties (config);
|
||||
g_debug ("Len of initial_args %i", pika_value_array_length (initial_args) );
|
||||
g_debug ("Len of initial_args %i", n_specs - 1);
|
||||
dump_objects (config);
|
||||
#endif
|
||||
|
||||
/* Get saved settings (last values) into the config.
|
||||
* Since run mode is INTERACTIVE, initial_args is moot.
|
||||
* Instead, last used values or default values populate the config.
|
||||
*/
|
||||
pika_procedure_config_begin_run (config, NULL, PIKA_RUN_INTERACTIVE, initial_args);
|
||||
#if DEBUG_CONFIG_PROPERTIES
|
||||
|
||||
dump_objects (config);
|
||||
#endif
|
||||
|
||||
/* Create a dialog having properties (describing arguments of the procedure)
|
||||
* taken from the config.
|
||||
*
|
||||
@ -220,22 +176,15 @@ script_fu_dialog_run (PikaProcedure *procedure,
|
||||
not_canceled = pika_procedure_dialog_run (dialog);
|
||||
/* Assert config holds validated arg values from a user interaction. */
|
||||
|
||||
#if DEBUG_CONFIG_PROPERTIES
|
||||
dump_objects (config);
|
||||
#endif
|
||||
#if DEBUG_CONFIG_PROPERTIES
|
||||
dump_objects (config);
|
||||
#endif
|
||||
|
||||
if (not_canceled)
|
||||
{
|
||||
PikaValueArray *final_args = pika_value_array_copy (initial_args);
|
||||
|
||||
/* Store config's values into final_args. */
|
||||
pika_procedure_config_get_values (config, final_args);
|
||||
|
||||
result = script_fu_interpret_image_proc (procedure, script,
|
||||
image, n_drawables, drawables,
|
||||
final_args);
|
||||
|
||||
pika_value_array_unref (final_args);
|
||||
config);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -244,13 +193,5 @@ script_fu_dialog_run (PikaProcedure *procedure,
|
||||
|
||||
gtk_widget_destroy ((GtkWidget*) dialog);
|
||||
|
||||
/* Persist config aka settings for the next run of the plugin.
|
||||
* Passing the PikaPDBStatus from result[0].
|
||||
* We must have a matching end_run for the begin_run, regardless of status.
|
||||
*/
|
||||
pika_procedure_config_end_run (config, g_value_get_enum (pika_value_array_index (result, 0)));
|
||||
|
||||
g_object_unref (config);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -30,6 +30,6 @@ PikaValueArray *script_fu_dialog_run (PikaProcedure *procedure,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args);
|
||||
PikaProcedureConfig *config);
|
||||
|
||||
#endif /* __SCRIPT_FU_DIALOG_H__ */
|
||||
|
@ -48,6 +48,24 @@
|
||||
};
|
||||
|
||||
|
||||
/* Called on event: language error in author's script,
|
||||
* in the Scheme arg spec for a PDB registered argument.
|
||||
* Returns an error which the caller must return to its caller.
|
||||
*/
|
||||
pointer registration_error (scheme *sc,
|
||||
const gchar *error)
|
||||
{
|
||||
gchar error_message[1024];
|
||||
|
||||
g_debug ("%s", error);
|
||||
/* Prefix with name of SF function that discovered error. */
|
||||
g_snprintf (error_message, sizeof (error_message),
|
||||
"script-fu-register: %s",
|
||||
error);
|
||||
return foreign_error (sc, error_message, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called on event: language error in the author's script.
|
||||
* Logs the error and returns a foreign_error.
|
||||
|
@ -22,6 +22,9 @@
|
||||
#ifndef __SCRIPT_FU_ERRORS_H__
|
||||
#define __SCRIPT_FU_ERRORS_H__
|
||||
|
||||
pointer registration_error (scheme *sc,
|
||||
const gchar *error_message);
|
||||
|
||||
pointer script_error (scheme *sc,
|
||||
const gchar *error_message,
|
||||
const pointer a);
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "script-fu-interface.h"
|
||||
#include "script-fu-scripts.h"
|
||||
#include "script-fu-script.h"
|
||||
#include "script-fu-arg.h"
|
||||
|
||||
#include "script-fu-intl.h"
|
||||
|
||||
@ -91,7 +92,7 @@ static void script_fu_resource_set_handler (gpointer data,
|
||||
gboolean closing);
|
||||
|
||||
static GtkWidget * script_fu_resource_widget (const gchar *title,
|
||||
gchar **id,
|
||||
gint32 *model,
|
||||
GType resource_type);
|
||||
|
||||
static void script_fu_flush_events (void);
|
||||
@ -177,6 +178,8 @@ script_fu_interface (SFScript *script,
|
||||
|
||||
static gboolean gtk_initted = FALSE;
|
||||
|
||||
g_debug ("%s", G_STRFUNC);
|
||||
|
||||
/* Simply return if there is already an interface. This is an
|
||||
* ugly workaround for the fact that we can not process two
|
||||
* scripts at a time.
|
||||
@ -467,35 +470,40 @@ script_fu_interface (SFScript *script,
|
||||
break;
|
||||
|
||||
case SF_FONT:
|
||||
widget = script_fu_resource_widget (_("Script-Fu Font Selection"),
|
||||
&arg->value.sfa_font,
|
||||
script_fu_arg_init_resource (arg, PIKA_TYPE_FONT);
|
||||
widget = script_fu_resource_widget (label_text,
|
||||
&arg->value.sfa_resource,
|
||||
PIKA_TYPE_FONT);
|
||||
break;
|
||||
|
||||
case SF_PALETTE:
|
||||
widget = script_fu_resource_widget (_("Script-Fu Palette Selection"),
|
||||
&arg->value.sfa_palette,
|
||||
script_fu_arg_init_resource (arg, PIKA_TYPE_PALETTE);
|
||||
widget = script_fu_resource_widget (label_text,
|
||||
&arg->value.sfa_resource,
|
||||
PIKA_TYPE_PALETTE);
|
||||
break;
|
||||
|
||||
case SF_PATTERN:
|
||||
left_align = TRUE;
|
||||
widget = script_fu_resource_widget (_("Script-Fu Pattern Selection"),
|
||||
&arg->value.sfa_pattern,
|
||||
script_fu_arg_init_resource (arg, PIKA_TYPE_PATTERN);
|
||||
widget = script_fu_resource_widget (label_text,
|
||||
&arg->value.sfa_resource,
|
||||
PIKA_TYPE_PATTERN);
|
||||
break;
|
||||
|
||||
case SF_GRADIENT:
|
||||
left_align = TRUE;
|
||||
widget = script_fu_resource_widget (_("Script-Fu Gradient Selection"),
|
||||
&arg->value.sfa_gradient,
|
||||
script_fu_arg_init_resource (arg, PIKA_TYPE_GRADIENT);
|
||||
widget = script_fu_resource_widget (label_text,
|
||||
&arg->value.sfa_resource,
|
||||
PIKA_TYPE_GRADIENT);
|
||||
break;
|
||||
|
||||
case SF_BRUSH:
|
||||
left_align = TRUE;
|
||||
widget = script_fu_resource_widget (_("Script-Fu Brush Selection"),
|
||||
&arg->value.sfa_brush,
|
||||
script_fu_arg_init_resource (arg, PIKA_TYPE_BRUSH);
|
||||
widget = script_fu_resource_widget (label_text,
|
||||
&arg->value.sfa_resource,
|
||||
PIKA_TYPE_BRUSH);
|
||||
break;
|
||||
|
||||
@ -596,37 +604,41 @@ script_fu_interface (SFScript *script,
|
||||
}
|
||||
|
||||
/* Return a widget for choosing a resource.
|
||||
* Generic on type.
|
||||
* Dispatch on resource type.
|
||||
* Widget will show initial choice from context.
|
||||
* Widget will update model if user touches widget.
|
||||
*/
|
||||
GtkWidget *
|
||||
static GtkWidget *
|
||||
script_fu_resource_widget (const gchar *title,
|
||||
gchar **id_handle,
|
||||
gint32 *model,
|
||||
GType resource_type)
|
||||
{
|
||||
GtkWidget *result_widget = NULL;
|
||||
PikaResource *resource;
|
||||
|
||||
resource = pika_resource_get_by_name (resource_type, *id_handle);
|
||||
g_debug ("%s type: %ld", G_STRFUNC, resource_type);
|
||||
|
||||
/* Passing NULL resource sets initial choice to resource from context.
|
||||
* Passing empty string for outer widget label, since we provide our own.
|
||||
*/
|
||||
if (g_type_is_a (resource_type, PIKA_TYPE_FONT))
|
||||
{
|
||||
result_widget = pika_font_select_button_new (title, resource);
|
||||
result_widget = pika_font_chooser_new (title, "", NULL);
|
||||
}
|
||||
else if (g_type_is_a (resource_type, PIKA_TYPE_BRUSH))
|
||||
{
|
||||
result_widget = pika_brush_select_button_new (title, resource);
|
||||
result_widget = pika_brush_chooser_new (title, "", NULL);
|
||||
}
|
||||
else if (g_type_is_a (resource_type, PIKA_TYPE_GRADIENT))
|
||||
{
|
||||
result_widget = pika_gradient_select_button_new (title, resource);
|
||||
result_widget = pika_gradient_chooser_new (title, "", NULL);
|
||||
}
|
||||
else if (g_type_is_a (resource_type, PIKA_TYPE_PALETTE))
|
||||
{
|
||||
result_widget = pika_palette_select_button_new (title, resource);
|
||||
result_widget = pika_palette_chooser_new (title, "", NULL);
|
||||
}
|
||||
else if (g_type_is_a (resource_type, PIKA_TYPE_PATTERN))
|
||||
{
|
||||
result_widget = pika_pattern_select_button_new (title, resource);
|
||||
result_widget = pika_pattern_chooser_new (title, "", NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -637,11 +649,11 @@ script_fu_resource_widget (const gchar *title,
|
||||
{
|
||||
/* All resource widgets emit signal resource-set
|
||||
* Connect to our handler which will be passed the id_handle,
|
||||
* the place to store the ID of the new choice of resource.
|
||||
* the model of the new choice of resource.
|
||||
*/
|
||||
g_signal_connect_swapped (result_widget, "resource-set",
|
||||
G_CALLBACK (script_fu_resource_set_handler),
|
||||
id_handle);
|
||||
model); /* data */
|
||||
}
|
||||
|
||||
return result_widget;
|
||||
@ -650,29 +662,10 @@ script_fu_resource_widget (const gchar *title,
|
||||
static void
|
||||
script_fu_interface_quit (SFScript *script)
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_return_if_fail (script != NULL);
|
||||
g_return_if_fail (sf_interface != NULL);
|
||||
|
||||
g_free (sf_interface->title);
|
||||
|
||||
for (i = 0; i < script->n_args; i++)
|
||||
switch (script->args[i].type)
|
||||
{
|
||||
case SF_FONT:
|
||||
case SF_PALETTE:
|
||||
case SF_PATTERN:
|
||||
case SF_GRADIENT:
|
||||
case SF_BRUSH:
|
||||
pika_resource_select_button_close_popup
|
||||
(PIKA_RESOURCE_SELECT_BUTTON (sf_interface->widgets[i]));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (sf_interface->widgets);
|
||||
g_free (sf_interface->last_command);
|
||||
|
||||
@ -706,25 +699,21 @@ script_fu_combo_callback (GtkWidget *widget,
|
||||
}
|
||||
|
||||
/* Handle resource-set signal.
|
||||
* Store id of newly chosen resource in SF local cache of args.
|
||||
* Store id of newly chosen resource in SF local cache of args,
|
||||
* at the integer location passed by pointer in "data"
|
||||
*
|
||||
* Note the callback is the same for all resource types.
|
||||
* The callback passes only the resource, and no attributes of the resource,
|
||||
* except it's ID.
|
||||
* The callback passes the resource, and no attributes of the resource.
|
||||
*/
|
||||
static void
|
||||
script_fu_resource_set_handler (gpointer data, /* callback "data" */
|
||||
gpointer resource,
|
||||
gboolean closing)
|
||||
{
|
||||
gchar **id_handle = data;
|
||||
gint32 *id_pointer = data;
|
||||
|
||||
/* Free any existing copy of the id string. */
|
||||
if (*id_handle)
|
||||
g_free (*id_handle);
|
||||
|
||||
/* We don't own the resource, nor its string. Copy the string. */
|
||||
*id_handle = g_strdup (pika_resource_get_name (resource));
|
||||
/* Store integer ID, not pointer to Resource. We bind to integer ID. */
|
||||
*id_pointer = pika_resource_get_id (resource);
|
||||
|
||||
if (closing) script_fu_activate_main_dialog ();
|
||||
}
|
||||
@ -794,30 +783,22 @@ script_fu_response (GtkWidget *widget,
|
||||
script_fu_flush_events ();
|
||||
}
|
||||
|
||||
/* Update model for all widgets that
|
||||
* don't have callbacks that update the model.
|
||||
* Only the text and string widgets don't.
|
||||
*
|
||||
* The model is the arg.value field.
|
||||
*/
|
||||
static void
|
||||
script_fu_ok (SFScript *script)
|
||||
script_fu_update_models (SFScript *script)
|
||||
{
|
||||
GString *output;
|
||||
gchar *command;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < script->n_args; i++)
|
||||
for (gint i = 0; i < script->n_args; i++)
|
||||
{
|
||||
SFArgValue *arg_value = &script->args[i].value;
|
||||
GtkWidget *widget = sf_interface->widgets[i];
|
||||
|
||||
switch (script->args[i].type)
|
||||
{
|
||||
case SF_IMAGE:
|
||||
case SF_DRAWABLE:
|
||||
case SF_LAYER:
|
||||
case SF_CHANNEL:
|
||||
case SF_VECTORS:
|
||||
case SF_DISPLAY:
|
||||
case SF_COLOR:
|
||||
case SF_TOGGLE:
|
||||
break;
|
||||
|
||||
case SF_VALUE:
|
||||
case SF_STRING:
|
||||
g_free (arg_value->sfa_value);
|
||||
@ -843,20 +824,19 @@ script_fu_ok (SFScript *script)
|
||||
FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_ADJUSTMENT:
|
||||
case SF_FILENAME:
|
||||
case SF_DIRNAME:
|
||||
case SF_FONT:
|
||||
case SF_PALETTE:
|
||||
case SF_PATTERN:
|
||||
case SF_GRADIENT:
|
||||
case SF_BRUSH:
|
||||
case SF_OPTION:
|
||||
case SF_ENUM:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Handler for event: OK button clicked. */
|
||||
static void
|
||||
script_fu_ok (SFScript *script)
|
||||
{
|
||||
GString *output;
|
||||
gchar *command;
|
||||
|
||||
script_fu_update_models (script);
|
||||
|
||||
command = script_fu_script_get_command (script);
|
||||
|
||||
@ -969,23 +949,16 @@ script_fu_reset (SFScript *script)
|
||||
value->sfa_file.filename);
|
||||
break;
|
||||
|
||||
/* Reset should get the initial/default value that the plugin author
|
||||
* declared by name in the SF- declaration.
|
||||
* Said name is a string stored in the default_value.sfa_font
|
||||
*
|
||||
* But this code goes away when ScriptFu uses PikaProcedureDialog.
|
||||
* Rather than make this temporary code do the correct thing,
|
||||
* instead simply pass NULL to reset to the value from context.
|
||||
* It is extremely unlikely that any user depends on or will notice
|
||||
* this temporaryily slightly changed behavior.
|
||||
/* Pass NULL to reset to the value from context.
|
||||
* Since v3, script author cannot specify default resource by name.
|
||||
*/
|
||||
case SF_FONT:
|
||||
case SF_PALETTE:
|
||||
case SF_PATTERN:
|
||||
case SF_GRADIENT:
|
||||
case SF_BRUSH:
|
||||
pika_resource_select_button_set_resource (PIKA_RESOURCE_SELECT_BUTTON (widget),
|
||||
NULL);
|
||||
pika_resource_chooser_set_resource (PIKA_RESOURCE_CHOOSER (widget),
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case SF_OPTION:
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include "script-fu-types.h"
|
||||
#include "script-fu-script.h"
|
||||
#include "script-fu-register.h"
|
||||
#include "script-fu-errors.h"
|
||||
|
||||
|
||||
/* Methods for a script's call to script-fu-register or script-fu-register-filter.
|
||||
* Such calls declare a PDB procedure, that ScriptFu will register in the PDB,
|
||||
@ -119,6 +121,263 @@ script_fu_script_new_from_metadata_args (scheme *sc,
|
||||
return script;
|
||||
}
|
||||
|
||||
|
||||
/* Parse a default spec from registration data.
|
||||
*
|
||||
* Side effects on arg.
|
||||
*
|
||||
* Returns sc->NIL on success.
|
||||
* Returns pointer to a foreign_error on parsing errors.
|
||||
*
|
||||
* A default_spec can be an atom or a list.
|
||||
* An atom is a single default value.
|
||||
* A list for SF-COLOR is also a default value.
|
||||
* In other cases, a list is a default and constraints.
|
||||
* Some constraints are declared to and enforced by the PDB.
|
||||
* Some constraints also convey to the widget for the arg.
|
||||
*
|
||||
* We check that each list is the correct length,
|
||||
* so we don't car off the end of the list.
|
||||
*
|
||||
* We don't check the types of list elements.
|
||||
* When they are not the correct type,
|
||||
* they are *some* scheme object and getting the numeric value
|
||||
* will return *some* value probably not the intended value,
|
||||
* but at least not a memory error or crash.
|
||||
*/
|
||||
static pointer
|
||||
script_fu_parse_default_spec (scheme *sc,
|
||||
pointer default_spec,
|
||||
SFArg *arg)
|
||||
{
|
||||
switch (arg->type)
|
||||
{
|
||||
case SF_IMAGE:
|
||||
case SF_DRAWABLE:
|
||||
case SF_LAYER:
|
||||
case SF_CHANNEL:
|
||||
case SF_VECTORS:
|
||||
case SF_DISPLAY:
|
||||
if (!sc->vptr->is_integer (default_spec))
|
||||
return registration_error (sc, "default IDs must be integers");
|
||||
|
||||
arg->default_value.sfa_image =
|
||||
sc->vptr->ivalue (default_spec);
|
||||
break;
|
||||
|
||||
case SF_COLOR:
|
||||
if (sc->vptr->is_string (default_spec))
|
||||
{
|
||||
if (! pika_rgb_parse_css (&arg->default_value.sfa_color,
|
||||
sc->vptr->string_value (default_spec),
|
||||
-1))
|
||||
return registration_error (sc, "invalid default color name");
|
||||
|
||||
pika_rgb_set_alpha (&arg->default_value.sfa_color, 1.0);
|
||||
}
|
||||
else if (sc->vptr->is_list (sc, default_spec) &&
|
||||
sc->vptr->list_length (sc, default_spec) == 3)
|
||||
{
|
||||
pointer color_list;
|
||||
guchar r, g, b;
|
||||
|
||||
color_list = default_spec;
|
||||
r = CLAMP (sc->vptr->ivalue (sc->vptr->pair_car (color_list)), 0, 255);
|
||||
color_list = sc->vptr->pair_cdr (color_list);
|
||||
g = CLAMP (sc->vptr->ivalue (sc->vptr->pair_car (color_list)), 0, 255);
|
||||
color_list = sc->vptr->pair_cdr (color_list);
|
||||
b = CLAMP (sc->vptr->ivalue (sc->vptr->pair_car (color_list)), 0, 255);
|
||||
|
||||
pika_rgb_set_uchar (&arg->default_value.sfa_color, r, g, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
return registration_error (sc, "color defaults must be a list of 3 integers or a color name");
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_TOGGLE:
|
||||
if (!sc->vptr->is_integer (default_spec))
|
||||
return registration_error (sc, "toggle default must be an integer value");
|
||||
|
||||
arg->default_value.sfa_toggle =
|
||||
(sc->vptr->ivalue (default_spec)) ? TRUE : FALSE;
|
||||
break;
|
||||
|
||||
case SF_VALUE:
|
||||
if (!sc->vptr->is_string (default_spec))
|
||||
return registration_error (sc, "value defaults must be strings");
|
||||
|
||||
arg->default_value.sfa_value =
|
||||
g_strdup (sc->vptr->string_value (default_spec));
|
||||
break;
|
||||
|
||||
case SF_STRING:
|
||||
case SF_TEXT:
|
||||
if (!sc->vptr->is_string (default_spec))
|
||||
return registration_error (sc, "string defaults must be strings");
|
||||
|
||||
arg->default_value.sfa_value =
|
||||
g_strdup (sc->vptr->string_value (default_spec));
|
||||
break;
|
||||
|
||||
case SF_ADJUSTMENT:
|
||||
{
|
||||
pointer adj_list;
|
||||
|
||||
if (!sc->vptr->is_list (sc, default_spec) &&
|
||||
sc->vptr->list_length (sc, default_spec) != 7)
|
||||
return registration_error (sc, "adjustment defaults must be a list of 7 elements");
|
||||
|
||||
adj_list = default_spec;
|
||||
arg->default_value.sfa_adjustment.value =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.lower =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.upper =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.step =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.page =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.digits =
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.type =
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (adj_list));
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_FILENAME:
|
||||
if (!sc->vptr->is_string (default_spec))
|
||||
return registration_error (sc, "filename defaults must be strings");
|
||||
/* fallthrough */
|
||||
|
||||
case SF_DIRNAME:
|
||||
if (!sc->vptr->is_string (default_spec))
|
||||
return registration_error (sc, "dirname defaults must be strings");
|
||||
|
||||
arg->default_value.sfa_file.filename =
|
||||
g_strdup (sc->vptr->string_value (default_spec));
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
{
|
||||
/* Replace POSIX slashes with Win32 backslashes. This
|
||||
* is just so script-fus can be written with only
|
||||
* POSIX directory separators.
|
||||
*/
|
||||
gchar *filename = arg->default_value.sfa_file.filename;
|
||||
|
||||
while (*filename)
|
||||
{
|
||||
if (*filename == '/')
|
||||
*filename = G_DIR_SEPARATOR;
|
||||
|
||||
filename++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SF_FONT:
|
||||
case SF_PALETTE:
|
||||
case SF_PATTERN:
|
||||
case SF_BRUSH:
|
||||
case SF_GRADIENT:
|
||||
/* Ignore default_spec given by author, it is just placeholder in script.
|
||||
* We can't look up resource by name at registration time.
|
||||
* The ParamSpecResource does not conveniently take a default.
|
||||
* It makes no sense to set objects for defaults.
|
||||
* Compare to SF_IMAGE.
|
||||
* Since v3.
|
||||
*/
|
||||
arg->default_value.sfa_resource = -1;
|
||||
break;
|
||||
|
||||
case SF_OPTION:
|
||||
{
|
||||
pointer option_list;
|
||||
|
||||
if (!sc->vptr->is_list (sc, default_spec) ||
|
||||
sc->vptr->list_length(sc, default_spec) < 1 )
|
||||
return registration_error (sc, "option defaults must be a non-empty list");
|
||||
|
||||
for (option_list = default_spec;
|
||||
option_list != sc->NIL;
|
||||
option_list = sc->vptr->pair_cdr (option_list))
|
||||
{
|
||||
pointer option = (sc->vptr->pair_car (option_list));
|
||||
if (sc->vptr->is_string (option))
|
||||
arg->default_value.sfa_option.list =
|
||||
g_slist_append (arg->default_value.sfa_option.list,
|
||||
g_strdup (sc->vptr->string_value (option)));
|
||||
else
|
||||
return registration_error (sc, "options must be strings");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_ENUM:
|
||||
{
|
||||
pointer option_list;
|
||||
const gchar *val;
|
||||
gchar *type_name;
|
||||
GEnumValue *enum_value;
|
||||
GType enum_type;
|
||||
|
||||
if (!sc->vptr->is_list (sc, default_spec))
|
||||
return registration_error (sc, "enum defaults must be a list");
|
||||
|
||||
option_list = default_spec;
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (option_list)))
|
||||
return registration_error (sc, "first element in enum defaults must be a type-name");
|
||||
|
||||
val = sc->vptr->string_value (sc->vptr->pair_car (option_list));
|
||||
|
||||
if (g_str_has_prefix (val, "Pika"))
|
||||
type_name = g_strdup (val);
|
||||
else
|
||||
type_name = g_strconcat ("Pika", val, NULL);
|
||||
|
||||
enum_type = g_type_from_name (type_name);
|
||||
if (! G_TYPE_IS_ENUM (enum_type))
|
||||
{
|
||||
g_free (type_name);
|
||||
return registration_error (sc, "first element in enum defaults must be the name of a registered type");
|
||||
}
|
||||
|
||||
arg->default_value.sfa_enum.type_name = type_name;
|
||||
|
||||
option_list = sc->vptr->pair_cdr (option_list);
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (option_list)))
|
||||
return registration_error (sc, "second element in enum defaults must be a string");
|
||||
|
||||
enum_value =
|
||||
g_enum_get_value_by_nick (g_type_class_peek (enum_type),
|
||||
sc->vptr->string_value (sc->vptr->pair_car (option_list)));
|
||||
if (enum_value)
|
||||
arg->default_value.sfa_enum.history = enum_value->value;
|
||||
}
|
||||
break;
|
||||
} /* end switch */
|
||||
|
||||
/* success */
|
||||
return sc->NIL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Traverse suffix of Scheme argument list,
|
||||
* creating SFArgs (formal arg specs) from triplets.
|
||||
*
|
||||
@ -145,300 +404,43 @@ script_fu_script_create_formal_args (scheme *sc,
|
||||
if (a != sc->NIL)
|
||||
{
|
||||
if (!sc->vptr->is_integer (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: argument types must be integer values", 0);
|
||||
return registration_error (sc, "argument types must be integers");
|
||||
|
||||
arg->type = sc->vptr->ivalue (sc->vptr->pair_car (a));
|
||||
a = sc->vptr->pair_cdr (a);
|
||||
}
|
||||
else
|
||||
return foreign_error (sc, "script-fu-register: missing type specifier", 0);
|
||||
return registration_error (sc, "missing type specifier");
|
||||
|
||||
if (a != sc->NIL)
|
||||
{
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: argument labels must be strings", 0);
|
||||
return registration_error (sc, "argument labels must be strings");
|
||||
|
||||
arg->label = g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a)));
|
||||
a = sc->vptr->pair_cdr (a);
|
||||
}
|
||||
else
|
||||
return foreign_error (sc, "script-fu-register: missing arguments label", 0);
|
||||
return registration_error (sc, "missing arguments label");
|
||||
|
||||
if (a != sc->NIL)
|
||||
{
|
||||
switch (arg->type)
|
||||
{
|
||||
case SF_IMAGE:
|
||||
case SF_DRAWABLE:
|
||||
case SF_LAYER:
|
||||
case SF_CHANNEL:
|
||||
case SF_VECTORS:
|
||||
case SF_DISPLAY:
|
||||
if (!sc->vptr->is_integer (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: default IDs must be integer values", 0);
|
||||
/* a is pointing into a sequence, grouped in three.
|
||||
* (car a) is the third part of three.
|
||||
* (cdr a) is the rest of the sequence
|
||||
*/
|
||||
pointer default_spec =sc->vptr->pair_car (a);
|
||||
pointer error = script_fu_parse_default_spec (sc, default_spec, arg);
|
||||
|
||||
arg->default_value.sfa_image =
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (a));
|
||||
break;
|
||||
|
||||
case SF_COLOR:
|
||||
if (sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
{
|
||||
if (! pika_rgb_parse_css (&arg->default_value.sfa_color,
|
||||
sc->vptr->string_value (sc->vptr->pair_car (a)),
|
||||
-1))
|
||||
return foreign_error (sc, "script-fu-register: invalid default color name", 0);
|
||||
|
||||
pika_rgb_set_alpha (&arg->default_value.sfa_color, 1.0);
|
||||
}
|
||||
else if (sc->vptr->is_list (sc, sc->vptr->pair_car (a)) &&
|
||||
sc->vptr->list_length(sc, sc->vptr->pair_car (a)) == 3)
|
||||
{
|
||||
pointer color_list;
|
||||
guchar r, g, b;
|
||||
|
||||
color_list = sc->vptr->pair_car (a);
|
||||
r = CLAMP (sc->vptr->ivalue (sc->vptr->pair_car (color_list)), 0, 255);
|
||||
color_list = sc->vptr->pair_cdr (color_list);
|
||||
g = CLAMP (sc->vptr->ivalue (sc->vptr->pair_car (color_list)), 0, 255);
|
||||
color_list = sc->vptr->pair_cdr (color_list);
|
||||
b = CLAMP (sc->vptr->ivalue (sc->vptr->pair_car (color_list)), 0, 255);
|
||||
|
||||
pika_rgb_set_uchar (&arg->default_value.sfa_color, r, g, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
return foreign_error (sc, "script-fu-register: color defaults must be a list of 3 integers or a color name", 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_TOGGLE:
|
||||
if (!sc->vptr->is_integer (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: toggle default must be an integer value", 0);
|
||||
|
||||
arg->default_value.sfa_toggle =
|
||||
(sc->vptr->ivalue (sc->vptr->pair_car (a))) ? TRUE : FALSE;
|
||||
break;
|
||||
|
||||
case SF_VALUE:
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: value defaults must be string values", 0);
|
||||
|
||||
arg->default_value.sfa_value =
|
||||
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a)));
|
||||
break;
|
||||
|
||||
case SF_STRING:
|
||||
case SF_TEXT:
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: string defaults must be string values", 0);
|
||||
|
||||
arg->default_value.sfa_value =
|
||||
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a)));
|
||||
break;
|
||||
|
||||
case SF_ADJUSTMENT:
|
||||
{
|
||||
pointer adj_list;
|
||||
|
||||
if (!sc->vptr->is_list (sc, a))
|
||||
return foreign_error (sc, "script-fu-register: adjustment defaults must be a list", 0);
|
||||
|
||||
adj_list = sc->vptr->pair_car (a);
|
||||
arg->default_value.sfa_adjustment.value =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.lower =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.upper =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.step =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.page =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.digits =
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (adj_list));
|
||||
|
||||
adj_list = sc->vptr->pair_cdr (adj_list);
|
||||
arg->default_value.sfa_adjustment.type =
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (adj_list));
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_FILENAME:
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: filename defaults must be string values", 0);
|
||||
/* fallthrough */
|
||||
|
||||
case SF_DIRNAME:
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: dirname defaults must be string values", 0);
|
||||
|
||||
arg->default_value.sfa_file.filename =
|
||||
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a)));
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
{
|
||||
/* Replace POSIX slashes with Win32 backslashes. This
|
||||
* is just so script-fus can be written with only
|
||||
* POSIX directory separators.
|
||||
*/
|
||||
gchar *filename = arg->default_value.sfa_file.filename;
|
||||
|
||||
while (*filename)
|
||||
{
|
||||
if (*filename == '/')
|
||||
*filename = G_DIR_SEPARATOR;
|
||||
|
||||
filename++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SF_FONT:
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: font defaults must be string values", 0);
|
||||
|
||||
arg->default_value.sfa_font =
|
||||
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a)));
|
||||
break;
|
||||
|
||||
case SF_PALETTE:
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: palette defaults must be string values", 0);
|
||||
|
||||
arg->default_value.sfa_palette =
|
||||
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a)));
|
||||
break;
|
||||
|
||||
case SF_PATTERN:
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: pattern defaults must be string values", 0);
|
||||
|
||||
arg->default_value.sfa_pattern =
|
||||
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a)));
|
||||
break;
|
||||
|
||||
case SF_BRUSH:
|
||||
{
|
||||
pointer brush_list;
|
||||
|
||||
if (!sc->vptr->is_list (sc, a))
|
||||
return foreign_error (sc, "script-fu-register: brush defaults must be a list", 0);
|
||||
|
||||
#ifdef OLD
|
||||
temporarily, still a list, but use only the name
|
||||
future: not a list, only a name
|
||||
|
||||
brush_list = sc->vptr->pair_car (a);
|
||||
arg->default_value.sfa_brush.name =
|
||||
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (brush_list)));
|
||||
|
||||
brush_list = sc->vptr->pair_cdr (brush_list);
|
||||
arg->default_value.sfa_brush.opacity =
|
||||
sc->vptr->rvalue (sc->vptr->pair_car (brush_list));
|
||||
|
||||
brush_list = sc->vptr->pair_cdr (brush_list);
|
||||
arg->default_value.sfa_brush.spacing =
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (brush_list));
|
||||
|
||||
brush_list = sc->vptr->pair_cdr (brush_list);
|
||||
arg->default_value.sfa_brush.paint_mode =
|
||||
sc->vptr->ivalue (sc->vptr->pair_car (brush_list));
|
||||
#else
|
||||
brush_list = sc->vptr->pair_car (a);
|
||||
arg->default_value.sfa_brush =
|
||||
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (brush_list)));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_GRADIENT:
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
|
||||
return foreign_error (sc, "script-fu-register: gradient defaults must be string values", 0);
|
||||
|
||||
arg->default_value.sfa_gradient =
|
||||
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a)));
|
||||
break;
|
||||
|
||||
case SF_OPTION:
|
||||
{
|
||||
pointer option_list;
|
||||
|
||||
if (!sc->vptr->is_list (sc, a))
|
||||
return foreign_error (sc, "script-fu-register: option defaults must be a list", 0);
|
||||
|
||||
for (option_list = sc->vptr->pair_car (a);
|
||||
option_list != sc->NIL;
|
||||
option_list = sc->vptr->pair_cdr (option_list))
|
||||
{
|
||||
arg->default_value.sfa_option.list =
|
||||
g_slist_append (arg->default_value.sfa_option.list,
|
||||
g_strdup (sc->vptr->string_value
|
||||
(sc->vptr->pair_car (option_list))));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_ENUM:
|
||||
{
|
||||
pointer option_list;
|
||||
const gchar *val;
|
||||
gchar *type_name;
|
||||
GEnumValue *enum_value;
|
||||
GType enum_type;
|
||||
|
||||
if (!sc->vptr->is_list (sc, a))
|
||||
return foreign_error (sc, "script-fu-register: enum defaults must be a list", 0);
|
||||
|
||||
option_list = sc->vptr->pair_car (a);
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (option_list)))
|
||||
return foreign_error (sc, "script-fu-register: first element in enum defaults must be a type-name", 0);
|
||||
|
||||
val = sc->vptr->string_value (sc->vptr->pair_car (option_list));
|
||||
|
||||
if (g_str_has_prefix (val, "Pika"))
|
||||
type_name = g_strdup (val);
|
||||
else
|
||||
type_name = g_strconcat ("Pika", val, NULL);
|
||||
|
||||
enum_type = g_type_from_name (type_name);
|
||||
if (! G_TYPE_IS_ENUM (enum_type))
|
||||
{
|
||||
g_free (type_name);
|
||||
return foreign_error (sc, "script-fu-register: first element in enum defaults must be the name of a registered type", 0);
|
||||
}
|
||||
|
||||
arg->default_value.sfa_enum.type_name = type_name;
|
||||
|
||||
option_list = sc->vptr->pair_cdr (option_list);
|
||||
if (!sc->vptr->is_string (sc->vptr->pair_car (option_list)))
|
||||
return foreign_error (sc, "script-fu-register: second element in enum defaults must be a string", 0);
|
||||
|
||||
enum_value =
|
||||
g_enum_get_value_by_nick (g_type_class_peek (enum_type),
|
||||
sc->vptr->string_value (sc->vptr->pair_car (option_list)));
|
||||
if (enum_value)
|
||||
arg->default_value.sfa_enum.history = enum_value->value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
a = sc->vptr->pair_cdr (a);
|
||||
if (error != sc->NIL)
|
||||
return error;
|
||||
else
|
||||
/* advance to next group of three in the sequence. */
|
||||
a = sc->vptr->pair_cdr (a);
|
||||
}
|
||||
else
|
||||
{
|
||||
return foreign_error (sc, "script-fu-register: missing default argument", 0);
|
||||
return registration_error (sc, "missing default argument");
|
||||
}
|
||||
} /* end for */
|
||||
|
||||
|
@ -57,17 +57,17 @@
|
||||
* Since 3.0
|
||||
*/
|
||||
PikaValueArray *
|
||||
script_fu_run_image_procedure ( PikaProcedure *procedure, /* PikaImageProcedure */
|
||||
PikaRunMode run_mode,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *other_args,
|
||||
gpointer data)
|
||||
script_fu_run_image_procedure (PikaProcedure *procedure, /* PikaImageProcedure */
|
||||
PikaRunMode run_mode,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
PikaProcedureConfig *config,
|
||||
gpointer data)
|
||||
{
|
||||
|
||||
PikaValueArray *result = NULL;
|
||||
SFScript *script;
|
||||
PikaValueArray *result = NULL;
|
||||
SFScript *script;
|
||||
|
||||
g_debug ("script_fu_run_image_procedure");
|
||||
script = script_fu_find_script (pika_procedure_get_name (procedure));
|
||||
@ -81,33 +81,36 @@ script_fu_run_image_procedure ( PikaProcedure *procedure, /* PikaImagePr
|
||||
{
|
||||
case PIKA_RUN_INTERACTIVE:
|
||||
{
|
||||
if (pika_value_array_length (other_args) > 0)
|
||||
guint n_specs;
|
||||
|
||||
g_free (g_object_class_list_properties (G_OBJECT_GET_CLASS (config), &n_specs));
|
||||
if (n_specs > 1)
|
||||
{
|
||||
/* Let user choose "other" args in a dialog, then interpret. Maintain a config. */
|
||||
result = script_fu_dialog_run (procedure, script, image, n_drawables, drawables, other_args);
|
||||
result = script_fu_dialog_run (procedure, script, image, n_drawables, drawables, config);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No "other" args for user to choose. No config to maintain. */
|
||||
result = script_fu_interpret_image_proc (procedure, script, image, n_drawables, drawables, other_args);
|
||||
result = script_fu_interpret_image_proc (procedure, script, image, n_drawables, drawables, config);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIKA_RUN_NONINTERACTIVE:
|
||||
{
|
||||
/* A call from another PDB procedure.
|
||||
* Use the given other_args, without interacting with user.
|
||||
* Use the given config, without interacting with user.
|
||||
* Since no user interaction, no config to maintain.
|
||||
*/
|
||||
result = script_fu_interpret_image_proc (procedure, script, image, n_drawables, drawables, other_args);
|
||||
result = script_fu_interpret_image_proc (procedure, script, image, n_drawables, drawables, config);
|
||||
break;
|
||||
}
|
||||
case PIKA_RUN_WITH_LAST_VALS:
|
||||
{
|
||||
/* User invoked from a menu "Filter>Run with last values".
|
||||
* Do not show dialog. other_args are already last values, from a config.
|
||||
* Do not show dialog. config are already last values.
|
||||
*/
|
||||
result = script_fu_interpret_image_proc (procedure, script, image, n_drawables, drawables, other_args);
|
||||
result = script_fu_interpret_image_proc (procedure, script, image, n_drawables, drawables, config);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -115,6 +118,7 @@ script_fu_run_image_procedure ( PikaProcedure *procedure, /* PikaImagePr
|
||||
result = pika_procedure_new_return_values (procedure, PIKA_PDB_CALLING_ERROR, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -128,14 +132,17 @@ script_fu_run_image_procedure ( PikaProcedure *procedure, /* PikaImagePr
|
||||
* Since prior to 3.0 but formerly named script_fu_script_proc
|
||||
*/
|
||||
PikaValueArray *
|
||||
script_fu_run_procedure (PikaProcedure *procedure,
|
||||
const PikaValueArray *args,
|
||||
gpointer data)
|
||||
script_fu_run_procedure (PikaProcedure *procedure,
|
||||
PikaProcedureConfig *config,
|
||||
gpointer data)
|
||||
{
|
||||
PikaPDBStatusType status = PIKA_PDB_SUCCESS;
|
||||
SFScript *script;
|
||||
PikaRunMode run_mode;
|
||||
GError *error = NULL;
|
||||
PikaPDBStatusType status = PIKA_PDB_SUCCESS;
|
||||
SFScript *script;
|
||||
GParamSpec **pspecs;
|
||||
guint n_pspecs;
|
||||
gint n_aux_args;
|
||||
PikaRunMode run_mode;
|
||||
GError *error = NULL;
|
||||
|
||||
script = script_fu_find_script (pika_procedure_get_name (procedure));
|
||||
|
||||
@ -144,7 +151,10 @@ script_fu_run_procedure (PikaProcedure *procedure,
|
||||
PIKA_PDB_CALLING_ERROR,
|
||||
NULL);
|
||||
|
||||
run_mode = PIKA_VALUES_GET_ENUM (args, 0);
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config), &n_pspecs);
|
||||
pika_procedure_get_aux_arguments (procedure, &n_aux_args);
|
||||
|
||||
g_object_get (config, "run-mode", &run_mode, NULL);
|
||||
|
||||
ts_set_run_mode (run_mode);
|
||||
|
||||
@ -155,7 +165,7 @@ script_fu_run_procedure (PikaProcedure *procedure,
|
||||
gint min_args = 0;
|
||||
|
||||
/* First, try to collect the standard script arguments... */
|
||||
min_args = script_fu_script_collect_standard_args (script, args);
|
||||
min_args = script_fu_script_collect_standard_args (script, pspecs, n_pspecs, config);
|
||||
|
||||
/* ...then acquire the rest of arguments (if any) with a dialog */
|
||||
if (script->n_args > min_args)
|
||||
@ -169,15 +179,18 @@ script_fu_run_procedure (PikaProcedure *procedure,
|
||||
}
|
||||
|
||||
case PIKA_RUN_NONINTERACTIVE:
|
||||
/* Make sure all the arguments are there */
|
||||
if (pika_value_array_length (args) != (script->n_args + 1))
|
||||
/* Verify actual args count equals declared arg count.
|
||||
* Scripts declare args except run_mode (SF hides it.)
|
||||
* pspecs have run_mode and one extra internal pspec, thus +2.
|
||||
*/
|
||||
if (n_pspecs != script->n_args + n_aux_args + 2)
|
||||
status = PIKA_PDB_CALLING_ERROR;
|
||||
|
||||
if (status == PIKA_PDB_SUCCESS)
|
||||
{
|
||||
gchar *command;
|
||||
|
||||
command = script_fu_script_get_command_from_params (script, args);
|
||||
command = script_fu_script_get_command_from_params (script, pspecs, n_pspecs, config);
|
||||
|
||||
/* run the command through the interpreter */
|
||||
if (! script_fu_run_command (command, &error))
|
||||
@ -196,7 +209,7 @@ script_fu_run_procedure (PikaProcedure *procedure,
|
||||
gchar *command;
|
||||
|
||||
/* First, try to collect the standard script arguments */
|
||||
script_fu_script_collect_standard_args (script, args);
|
||||
script_fu_script_collect_standard_args (script, pspecs, n_pspecs, config);
|
||||
|
||||
command = script_fu_script_get_command (script);
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#define __SCRIPT_FU_RUN_FUNC_H__
|
||||
|
||||
PikaValueArray *script_fu_run_procedure (PikaProcedure *procedure,
|
||||
const PikaValueArray *args,
|
||||
PikaProcedureConfig *config,
|
||||
gpointer data);
|
||||
|
||||
PikaValueArray *script_fu_run_image_procedure (PikaProcedure *procedure,
|
||||
@ -31,7 +31,7 @@ PikaValueArray *script_fu_run_image_procedure (PikaProcedure *procedure,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args,
|
||||
PikaProcedureConfig *config,
|
||||
gpointer data);
|
||||
|
||||
#endif /* __SCRIPT_FU_RUN_FUNC__ */
|
||||
|
@ -40,7 +40,9 @@
|
||||
*/
|
||||
|
||||
static gboolean script_fu_script_param_init (SFScript *script,
|
||||
const PikaValueArray *args,
|
||||
GParamSpec **pspecs,
|
||||
guint n_pspecs,
|
||||
PikaProcedureConfig *config,
|
||||
SFArgType type,
|
||||
gint n);
|
||||
static void script_fu_script_set_proc_metadata (
|
||||
@ -162,12 +164,11 @@ script_fu_script_create_PDB_procedure (PikaPlugIn *plug_in,
|
||||
g_debug ("script_fu_script_create_PDB_procedure: %s, plugin type %i, image_proc",
|
||||
script->name, plug_in_type);
|
||||
|
||||
procedure = pika_image_procedure_new (
|
||||
plug_in, script->name,
|
||||
plug_in_type,
|
||||
(PikaRunImageFunc) script_fu_run_image_procedure,
|
||||
script, /* user_data, pointer in extension-script-fu process */
|
||||
NULL);
|
||||
procedure = pika_image_procedure_new (plug_in, script->name,
|
||||
plug_in_type,
|
||||
(PikaRunImageFunc) script_fu_run_image_procedure,
|
||||
script, /* user_data, pointer in extension-script-fu process */
|
||||
NULL);
|
||||
|
||||
script_fu_script_set_proc_metadata (procedure, script);
|
||||
|
||||
@ -270,23 +271,25 @@ script_fu_script_reset (SFScript *script,
|
||||
|
||||
gint
|
||||
script_fu_script_collect_standard_args (SFScript *script,
|
||||
const PikaValueArray *args)
|
||||
GParamSpec **pspecs,
|
||||
guint n_pspecs,
|
||||
PikaProcedureConfig *config)
|
||||
{
|
||||
gint params_consumed = 0;
|
||||
|
||||
g_return_val_if_fail (script != NULL, 0);
|
||||
|
||||
/* the first parameter may be a DISPLAY id */
|
||||
if (script_fu_script_param_init (script,
|
||||
args, SF_DISPLAY,
|
||||
if (script_fu_script_param_init (script, pspecs, n_pspecs,
|
||||
config, SF_DISPLAY,
|
||||
params_consumed))
|
||||
{
|
||||
params_consumed++;
|
||||
}
|
||||
|
||||
/* an IMAGE id may come first or after the DISPLAY id */
|
||||
if (script_fu_script_param_init (script,
|
||||
args, SF_IMAGE,
|
||||
if (script_fu_script_param_init (script, pspecs, n_pspecs,
|
||||
config, SF_IMAGE,
|
||||
params_consumed))
|
||||
{
|
||||
params_consumed++;
|
||||
@ -294,17 +297,17 @@ script_fu_script_collect_standard_args (SFScript *script,
|
||||
/* and may be followed by a DRAWABLE, LAYER, CHANNEL or
|
||||
* VECTORS id
|
||||
*/
|
||||
if (script_fu_script_param_init (script,
|
||||
args, SF_DRAWABLE,
|
||||
if (script_fu_script_param_init (script, pspecs, n_pspecs,
|
||||
config, SF_DRAWABLE,
|
||||
params_consumed) ||
|
||||
script_fu_script_param_init (script,
|
||||
args, SF_LAYER,
|
||||
script_fu_script_param_init (script, pspecs, n_pspecs,
|
||||
config, SF_LAYER,
|
||||
params_consumed) ||
|
||||
script_fu_script_param_init (script,
|
||||
args, SF_CHANNEL,
|
||||
script_fu_script_param_init (script, pspecs, n_pspecs,
|
||||
config, SF_CHANNEL,
|
||||
params_consumed) ||
|
||||
script_fu_script_param_init (script,
|
||||
args, SF_VECTORS,
|
||||
script_fu_script_param_init (script, pspecs, n_pspecs,
|
||||
config, SF_VECTORS,
|
||||
params_consumed))
|
||||
{
|
||||
params_consumed++;
|
||||
@ -343,7 +346,9 @@ script_fu_script_get_command (SFScript *script)
|
||||
|
||||
gchar *
|
||||
script_fu_script_get_command_from_params (SFScript *script,
|
||||
const PikaValueArray *args)
|
||||
GParamSpec **pspecs,
|
||||
guint n_pspecs,
|
||||
PikaProcedureConfig *config)
|
||||
{
|
||||
GString *s;
|
||||
gint i;
|
||||
@ -355,13 +360,18 @@ script_fu_script_get_command_from_params (SFScript *script,
|
||||
|
||||
for (i = 0; i < script->n_args; i++)
|
||||
{
|
||||
GValue *value = pika_value_array_index (args, i + 1);
|
||||
GValue value = G_VALUE_INIT;
|
||||
GParamSpec *pspec = pspecs[i + 1];
|
||||
|
||||
g_value_init (&value, pspec->value_type);
|
||||
g_object_get_property (G_OBJECT (config), pspec->name, &value);
|
||||
|
||||
g_string_append_c (s, ' ');
|
||||
|
||||
script_fu_arg_append_repr_from_gvalue (&script->args[i],
|
||||
s,
|
||||
value);
|
||||
&value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
g_string_append_c (s, ')');
|
||||
@ -399,11 +409,15 @@ script_fu_script_get_command_for_image_proc (SFScript *script,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args)
|
||||
PikaProcedureConfig *config)
|
||||
{
|
||||
GString *s;
|
||||
GParamSpec **pspecs;
|
||||
guint n_pspecs;
|
||||
GString *s;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (script != NULL, NULL);
|
||||
g_return_val_if_fail (PIKA_IS_PROCEDURE_CONFIG (config), NULL);
|
||||
|
||||
s = g_string_new ("(");
|
||||
g_string_append (s, script->name);
|
||||
@ -424,20 +438,28 @@ script_fu_script_get_command_for_image_proc (SFScript *script,
|
||||
*/
|
||||
script_fu_command_append_drawables (s, n_drawables, drawables);
|
||||
|
||||
/* args contains the "other" args
|
||||
/* config contains the "other" args
|
||||
* Iterate over the PikaValueArray.
|
||||
* But script->args should be the same length, and types should match.
|
||||
*/
|
||||
for (guint i = 0; i < pika_value_array_length (args); i++)
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config), &n_pspecs);
|
||||
|
||||
/* config will have 1 additional property: "procedure". */
|
||||
for (i = 1; i < n_pspecs; i++)
|
||||
{
|
||||
GValue *value = pika_value_array_index (args, i);
|
||||
GParamSpec *pspec = pspecs[i];
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_string_append_c (s, ' ');
|
||||
script_fu_arg_append_repr_from_gvalue (&script->args[i],
|
||||
s,
|
||||
value);
|
||||
|
||||
g_value_init (&value, pspec->value_type);
|
||||
g_object_get_property (G_OBJECT (config), pspec->name, &value);
|
||||
script_fu_arg_append_repr_from_gvalue (&script->args[i - 1], s, &value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
g_string_append_c (s, ')');
|
||||
g_free (pspecs);
|
||||
|
||||
return g_string_free (s, FALSE);
|
||||
}
|
||||
@ -466,7 +488,9 @@ script_fu_script_infer_drawable_arity (SFScript *script)
|
||||
|
||||
static gboolean
|
||||
script_fu_script_param_init (SFScript *script,
|
||||
const PikaValueArray *args,
|
||||
GParamSpec **pspecs,
|
||||
guint n_pspecs,
|
||||
PikaProcedureConfig *config,
|
||||
SFArgType type,
|
||||
gint n)
|
||||
{
|
||||
@ -474,16 +498,20 @@ script_fu_script_param_init (SFScript *script,
|
||||
|
||||
if (script->n_args > n &&
|
||||
arg->type == type &&
|
||||
pika_value_array_length (args) > n + 1)
|
||||
/* The first pspec is "procedure", the second is "run-mode". */
|
||||
n_pspecs > n + 2)
|
||||
{
|
||||
GValue *value = pika_value_array_index (args, n + 1);
|
||||
GValue value = G_VALUE_INIT;
|
||||
GParamSpec *pspec = pspecs[n + 2];
|
||||
|
||||
g_value_init (&value, pspec->value_type);
|
||||
g_object_get_property (G_OBJECT (config), pspec->name, &value);
|
||||
switch (type)
|
||||
{
|
||||
case SF_IMAGE:
|
||||
if (PIKA_VALUE_HOLDS_IMAGE (value))
|
||||
if (PIKA_VALUE_HOLDS_IMAGE (&value))
|
||||
{
|
||||
PikaImage *image = g_value_get_object (value);
|
||||
PikaImage *image = g_value_get_object (&value);
|
||||
|
||||
arg->value.sfa_image = pika_image_get_id (image);
|
||||
return TRUE;
|
||||
@ -491,9 +519,9 @@ script_fu_script_param_init (SFScript *script,
|
||||
break;
|
||||
|
||||
case SF_DRAWABLE:
|
||||
if (PIKA_VALUE_HOLDS_DRAWABLE (value))
|
||||
if (PIKA_VALUE_HOLDS_DRAWABLE (&value))
|
||||
{
|
||||
PikaItem *item = g_value_get_object (value);
|
||||
PikaItem *item = g_value_get_object (&value);
|
||||
|
||||
arg->value.sfa_drawable = pika_item_get_id (item);
|
||||
return TRUE;
|
||||
@ -501,9 +529,9 @@ script_fu_script_param_init (SFScript *script,
|
||||
break;
|
||||
|
||||
case SF_LAYER:
|
||||
if (PIKA_VALUE_HOLDS_LAYER (value))
|
||||
if (PIKA_VALUE_HOLDS_LAYER (&value))
|
||||
{
|
||||
PikaItem *item = g_value_get_object (value);
|
||||
PikaItem *item = g_value_get_object (&value);
|
||||
|
||||
arg->value.sfa_layer = pika_item_get_id (item);
|
||||
return TRUE;
|
||||
@ -511,9 +539,9 @@ script_fu_script_param_init (SFScript *script,
|
||||
break;
|
||||
|
||||
case SF_CHANNEL:
|
||||
if (PIKA_VALUE_HOLDS_CHANNEL (value))
|
||||
if (PIKA_VALUE_HOLDS_CHANNEL (&value))
|
||||
{
|
||||
PikaItem *item = g_value_get_object (value);
|
||||
PikaItem *item = g_value_get_object (&value);
|
||||
|
||||
arg->value.sfa_channel = pika_item_get_id (item);
|
||||
return TRUE;
|
||||
@ -521,9 +549,9 @@ script_fu_script_param_init (SFScript *script,
|
||||
break;
|
||||
|
||||
case SF_VECTORS:
|
||||
if (PIKA_VALUE_HOLDS_VECTORS (value))
|
||||
if (PIKA_VALUE_HOLDS_VECTORS (&value))
|
||||
{
|
||||
PikaItem *item = g_value_get_object (value);
|
||||
PikaItem *item = g_value_get_object (&value);
|
||||
|
||||
arg->value.sfa_vectors = pika_item_get_id (item);
|
||||
return TRUE;
|
||||
@ -531,9 +559,9 @@ script_fu_script_param_init (SFScript *script,
|
||||
break;
|
||||
|
||||
case SF_DISPLAY:
|
||||
if (PIKA_VALUE_HOLDS_DISPLAY (value))
|
||||
if (PIKA_VALUE_HOLDS_DISPLAY (&value))
|
||||
{
|
||||
PikaDisplay *display = g_value_get_object (value);
|
||||
PikaDisplay *display = g_value_get_object (&value);
|
||||
|
||||
arg->value.sfa_display = pika_display_get_id (display);
|
||||
return TRUE;
|
||||
@ -543,6 +571,7 @@ script_fu_script_param_init (SFScript *script,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -43,17 +43,21 @@ void script_fu_script_reset (SFScript *scrip
|
||||
gboolean reset_ids);
|
||||
|
||||
gint script_fu_script_collect_standard_args (SFScript *script,
|
||||
const PikaValueArray *args);
|
||||
GParamSpec **pspecs,
|
||||
guint n_pspecs,
|
||||
PikaProcedureConfig *config);
|
||||
|
||||
gchar * script_fu_script_get_command (SFScript *script);
|
||||
gchar * script_fu_script_get_command_from_params (SFScript *script,
|
||||
const PikaValueArray *args);
|
||||
GParamSpec **pspecs,
|
||||
guint n_pspecs,
|
||||
PikaProcedureConfig *config);
|
||||
gchar * script_fu_script_get_command_for_image_proc (
|
||||
SFScript *script,
|
||||
PikaImage *image,
|
||||
guint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args);
|
||||
PikaProcedureConfig *config);
|
||||
|
||||
PikaProcedure * script_fu_script_create_PDB_procedure (PikaPlugIn *plug_in,
|
||||
SFScript *script,
|
||||
|
@ -54,6 +54,8 @@ typedef struct
|
||||
gint history;
|
||||
} SFEnum;
|
||||
|
||||
typedef gint32 SFResourceType;
|
||||
|
||||
typedef union
|
||||
{
|
||||
gint32 sfa_image;
|
||||
@ -67,11 +69,7 @@ typedef union
|
||||
gchar *sfa_value;
|
||||
SFAdjustment sfa_adjustment;
|
||||
SFFilename sfa_file;
|
||||
gchar *sfa_font;
|
||||
gchar *sfa_gradient;
|
||||
gchar *sfa_palette;
|
||||
gchar *sfa_pattern;
|
||||
gchar *sfa_brush;
|
||||
SFResourceType sfa_resource;
|
||||
SFOption sfa_option;
|
||||
SFEnum sfa_enum;
|
||||
} SFArgValue;
|
||||
|
Reference in New Issue
Block a user