Fix 10170

Changes only to ScriptFu.

The third term (the default) of a SF-FONT etc. spec is now ignored.

Test case is SF>Test>Sphere.  There are still crashing issues
related but separate.
This commit is contained in:
bootchk
2023-09-26 13:19:17 -04:00
committed by Lloyd Konneker
parent 414f9f9abf
commit 355f665403
7 changed files with 180 additions and 278 deletions

View File

@ -1283,6 +1283,8 @@ script_fu_marshal_procedure_call (scheme *sc,
* ID's are unique across all instances of Resource.
*/
resource = gimp_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);
}

View File

@ -94,6 +94,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:
@ -102,6 +103,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:
@ -120,36 +128,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);
@ -176,6 +154,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.
@ -212,35 +197,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;
@ -482,6 +438,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 GimpResource, 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;
@ -580,25 +544,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 GimpResource */
GimpResource *resource;
gchar *name = NULL;
resource = g_value_get_object (gvalue);
if (resource)
name = gimp_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;
@ -644,6 +589,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;
@ -697,26 +648,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;
@ -879,6 +810,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)
{
GimpResource *resource;
if (resource_type == GIMP_TYPE_BRUSH)
resource = GIMP_RESOURCE (gimp_context_get_brush ());
else if (resource_type == GIMP_TYPE_FONT)
resource = GIMP_RESOURCE (gimp_context_get_font ());
else if (resource_type == GIMP_TYPE_GRADIENT)
resource = GIMP_RESOURCE (gimp_context_get_gradient ());
else if (resource_type == GIMP_TYPE_PALETTE)
resource = GIMP_RESOURCE (gimp_context_get_palette ());
else if (resource_type == GIMP_TYPE_PATTERN)
resource = GIMP_RESOURCE (gimp_context_get_pattern ());
else
{
g_warning ("%s: Failed get resource from context", G_STRFUNC);
arg->value.sfa_resource = -1;
return;
}
arg->value.sfa_resource = gimp_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.

View File

@ -36,4 +36,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__ */

View File

@ -35,6 +35,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"
@ -87,7 +88,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);
@ -173,6 +174,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.
@ -463,35 +466,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, GIMP_TYPE_FONT);
widget = script_fu_resource_widget (label_text,
&arg->value.sfa_resource,
GIMP_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, GIMP_TYPE_PALETTE);
widget = script_fu_resource_widget (label_text,
&arg->value.sfa_resource,
GIMP_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, GIMP_TYPE_PATTERN);
widget = script_fu_resource_widget (label_text,
&arg->value.sfa_resource,
GIMP_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, GIMP_TYPE_GRADIENT);
widget = script_fu_resource_widget (label_text,
&arg->value.sfa_resource,
GIMP_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, GIMP_TYPE_BRUSH);
widget = script_fu_resource_widget (label_text,
&arg->value.sfa_resource,
GIMP_TYPE_BRUSH);
break;
@ -592,37 +600,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;
GimpResource *resource;
resource = gimp_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, GIMP_TYPE_FONT))
{
result_widget = gimp_font_chooser_new (title, title, resource);
result_widget = gimp_font_chooser_new (title, "", NULL);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_BRUSH))
{
result_widget = gimp_brush_chooser_new (title, title, resource);
result_widget = gimp_brush_chooser_new (title, "", NULL);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_GRADIENT))
{
result_widget = gimp_gradient_chooser_new (title, title, resource);
result_widget = gimp_gradient_chooser_new (title, "", NULL);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_PALETTE))
{
result_widget = gimp_palette_chooser_new (title, title, resource);
result_widget = gimp_palette_chooser_new (title, "", NULL);
}
else if (g_type_is_a (resource_type, GIMP_TYPE_PATTERN))
{
result_widget = gimp_pattern_chooser_new (title, title, resource);
result_widget = gimp_pattern_chooser_new (title, "", NULL);
}
else
{
@ -633,11 +645,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;
@ -683,25 +695,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 (gimp_resource_get_name (resource));
/* Store integer ID, not pointer to Resource. We bind to integer ID. */
*id_pointer = gimp_resource_get_id (resource);
if (closing) script_fu_activate_main_dialog ();
}
@ -771,30 +779,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);
@ -820,20 +820,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);
@ -946,15 +945,8 @@ 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 GimpProcedureDialog.
* 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:

View File

@ -287,54 +287,18 @@ script_fu_parse_default_spec (scheme *sc,
break;
case SF_FONT:
if (!sc->vptr->is_string (default_spec))
return registration_error (sc, "font defaults must be strings");
arg->default_value.sfa_font =
g_strdup (sc->vptr->string_value (default_spec));
break;
case SF_PALETTE:
if (!sc->vptr->is_string (default_spec))
return registration_error (sc, "palette defaults must be strings");
arg->default_value.sfa_palette =
g_strdup (sc->vptr->string_value (default_spec));
break;
case SF_PATTERN:
if (!sc->vptr->is_string (default_spec))
return registration_error (sc, "pattern defaults must be strings");
arg->default_value.sfa_pattern =
g_strdup (sc->vptr->string_value (default_spec));
break;
case SF_BRUSH:
{
pointer brush_list;
if (!sc->vptr->is_list (sc, default_spec))
return registration_error (sc, "brush defaults must be a list");
/* In v2, the list had name, opacity, spacing, and paint_mode.
* In v3, we only use the name and the widget is a simple brush chooser.
* A script that wants user to choose opacity and spacing must
* use separate arguments for that.
* FUTURE: not a list, only a name
*/
brush_list = default_spec;
arg->default_value.sfa_brush =
g_strdup (sc->vptr->string_value (sc->vptr->pair_car (brush_list)));
}
break;
case SF_GRADIENT:
if (!sc->vptr->is_string (default_spec))
return registration_error (sc, "gradient defaults must be strings");
arg->default_value.sfa_gradient =
g_strdup (sc->vptr->string_value (default_spec));
/* 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:

View File

@ -50,6 +50,8 @@ typedef struct
gint history;
} SFEnum;
typedef gint32 SFResourceType;
typedef union
{
gint32 sfa_image;
@ -63,11 +65,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;

View File

@ -23,77 +23,57 @@
; SF-COLOR "label" "color"
;
; ----------------------------------------------------------------------
; SF-FONT
; creates a font-selection widget in the dialog. It returns a font.
; Resources: Brush, Font, Gradient, Palette, Pattern
;
; There are two gimp-text procedures to use a font:
; Resources are Gimp objects for installed data such as fonts.
; Resources have a unique integer ID for the lifetime of a Gimp session.
; In ScriptFu, a resource argument is bound to an integer ID.
;
; (gimp-text-font image drawable
; x-pos y-pos text border antialias size font)
; (gimp-text-get-extents-font text size font))
; Resources have names, often unique, but not always.
; For example, fonts from different collections of fonts might
; have the same names.
;
; Usage:
; SF-FONT "label" "font name"
; ScriptFu v3 does not let you name a default resource.
; In v2, the third term of a triplet named a default resource.
; In v3, the third term is just a placeholder and is ignored.
; This is compatible with v2 scripts, but any default
; in a v2 script will be ignored in v3.
; (Similarly as for SF-IMAGE.)
;
; In the code below, a default name is shown,
; but is ignored since v3.
; Some even name resources that are not installed with Gimp any longer.
;
; In non-interactive mode, a resource argument in ScriptFu
; is an integer ID passed by the caller.
;
; In interactive mode, the widget to choose a resource
; initially shows a resource from the context.
; The user can choose a different value.
;
; The resource chooser widgets are buttons.
; The choice is previewed in the label of the button,
; or in a preview window beside the button.
; Clicking the button shows another dialog for choosing.
; Clicking a preview window shows an enlarged view of the choice.
;
; ----------------------------------------------------------------------
; SF-BRUSH
; is only useful in interactive mode. It will create a widget in the control
; dialog. The widget consists of a preview area (which when pressed will
; produce a popup preview ) and a button with the "..." label. The button will
; popup a dialog where brushes can be selected and each of the
; characteristics of the brush can be modified.
;
; The actual value returned when the script is invoked is a list
; consisting of Brush name, opacity, spacing and brush mode in the same
; units as passed in as the default value.
;
; Usage:
; SF-BRUSH "Brush" '("Circle (03)" 100 44 0)
;
; Here the brush dialog will be popped up with a default brush of Circle (03)
; opacity 100 spacing 44 and paint mode of Normal (value 0).
; If this selection was unchanged the value passed to the function as a
; parameter would be '("Circle (03)" 100 44 0).
;
; SF-BRUSH "Brush to paint with" ""
; Note that v2 required a list for the third argument, the default.
; If you need the spacing attribute of the brush, get it from the brush.
; If you want to set opacity and mode when painting with the brush,
; declare more arguments and set them into a temporary context.
; ----------------------------------------------------------------------
; SF-PATTERN
; Only useful in interactive mode. It will create a widget in the control
; dialog. The widget consists of a preview area (which when pressed will
; produce a popup preview ) and a button with the "..." label. The button will
; popup a dialog where patterns can be selected.
;
; Usage:
; SF-PATTERN "Pattern" "Maple Leaves"
;
; The value returned when the script is invoked is a string containing the
; pattern name. If the above selection was not altered the string would
; contain "Maple Leaves"
;
; ----------------------------------------------------------------------
; SF-GRADIENT
; Only useful in interactive mode. It will create a widget in the control
; dialog. The widget consists of a button containing a preview of the selected
; gradient. If the button is pressed a gradient selection dialog will popup.
;
; Usage:
; SF-GRADIENT "Gradient" "Deep Sea"
;
; The value returned when the script is invoked is a string containing the
; gradient name. If the above selection was not altered the string would
; contain "Deep Sea"
;
; ----------------------------------------------------------------------
; SF-PALETTE
; Only useful in interactive mode. It will create a widget in the control
; dialog. The widget consists of a button containing a preview of the selected
; palette. If the button is pressed a palette selection dialog will popup.
;
; Usage:
; SF-PALETTE "Palette" "Named Colors"
;
; The value returned when the script is invoked is a string containing the
; palette name. If the above selection was not altered the string would
; contain "Named Colors"
; SF-FONT "Font to render with" ""
; SF-GRADIENT "Gradient to render with" ""
; SF-PALETTE "Palette to render with" ""
; SF-PATTERN "Pattern to render with" ""
;
; ----------------------------------------------------------------------
; SF-FILENAME