Issue #12045: no defaults for plugin args of type File.

libgimpbase:

  - Mew GimpFileChooserAction enum type: basically a near-mapping of
    GtkFileChooserAction (GTK is not accessible from libgimpbase) with
    an added GIMP_FILE_CHOOSER_ACTION_ANY.
  - New GimpParamSpecFile param spec type: based off
    GimpParamSpecObject, it has a default value, but also a none_ok and
    action argument. This way, we can also know from the argument type
    if this is a file argument meant for selecting a normal file or a
    folder, or for saving into a file, or for creating a directory.

libgimp, plug-ins:

  - All existing file arguments (until now using a standard
    GParamSpecObject param with GFile value type) were moved to the new
    GimpParamSpecFile.
  - Script-Fu in particular will now generate the appropriate param type
    depending on whether it is an SF-FILENAME or SF-DIRNAME.
  - File arguments are now stored between runs as a URI rather than as a
    path. As far as I can tell, a GFile always has a URI, but not always
    a path (in particular remote file won't have a path).
This commit is contained in:
Jehan 2025-01-22 17:15:28 +01:00
parent b6d6ccecc7
commit 161b3c5331
29 changed files with 530 additions and 76 deletions

View file

@ -292,8 +292,11 @@ GIMP_IS_PARAM_SPEC_RUN_MODE (GParamSpec *pspec)
}
static inline gboolean
GIMP_IS_PARAM_SPEC_FILE (GParamSpec *pspec)
gimp_plug_in_is_file_spec (GParamSpec *pspec)
{
/* This will work both for GimpParamSpecFile specs and
* GParamSpecObject with a GFile value.
*/
return (G_IS_PARAM_SPEC_OBJECT (pspec) &&
pspec->value_type == G_TYPE_FILE);
}
@ -334,7 +337,7 @@ gimp_plug_in_set_file_proc_load_handler (GimpPlugIn *plug_in,
if (((procedure->num_args < 2) ||
(procedure->num_values < 1) ||
! GIMP_IS_PARAM_SPEC_RUN_MODE (procedure->args[0]) ||
! GIMP_IS_PARAM_SPEC_FILE (procedure->args[1]) ||
! gimp_plug_in_is_file_spec (procedure->args[1]) ||
(! proc->generic_file_proc &&
! GIMP_IS_PARAM_SPEC_IMAGE (procedure->values[0]))))
{
@ -393,7 +396,7 @@ gimp_plug_in_set_file_proc_save_handler (GimpPlugIn *plug_in,
if ((procedure->num_args < 4) ||
! GIMP_IS_PARAM_SPEC_RUN_MODE (procedure->args[0]) ||
! GIMP_IS_PARAM_SPEC_IMAGE (procedure->args[1]) ||
! GIMP_IS_PARAM_SPEC_FILE (procedure->args[2]) ||
! gimp_plug_in_is_file_spec (procedure->args[2]) ||
! GIMP_IS_PARAM_SPEC_EXPORT_OPTIONS (procedure->args[3]))
{
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_FAILED,
@ -592,7 +595,7 @@ gimp_plug_in_set_file_proc_handles_vector (GimpPlugIn *plug_in,
if (procedure->num_args < 4 ||
procedure->num_values < 1 ||
! GIMP_IS_PARAM_SPEC_RUN_MODE (procedure->args[0]) ||
! GIMP_IS_PARAM_SPEC_FILE (procedure->args[1]) ||
! gimp_plug_in_is_file_spec (procedure->args[1]) ||
! G_IS_PARAM_SPEC_INT (procedure->args[2]) ||
! G_IS_PARAM_SPEC_INT (procedure->args[3]) ||
! GIMP_IS_PARAM_SPEC_IMAGE (procedure->values[0]))

View file

@ -447,13 +447,6 @@ GIMP_IS_PARAM_SPEC_RUN_MODE (GParamSpec *pspec)
pspec->value_type == GIMP_TYPE_RUN_MODE);
}
static inline gboolean
GIMP_IS_PARAM_SPEC_FILE (GParamSpec *pspec)
{
return (G_IS_PARAM_SPEC_OBJECT (pspec) &&
pspec->value_type == G_TYPE_FILE);
}
static gboolean
gimp_plug_in_procedure_validate_args (GimpPlugInProcedure *proc,
Gimp *gimp,

View file

@ -1014,6 +1014,22 @@ plug_in_proc_arg_deserialize (GScanner *scanner,
goto error;
}
break;
case GP_PARAM_DEF_TYPE_FILE:
if (! gimp_scanner_parse_int (scanner,
(gint *) &param_def.meta.m_file.action) ||
! gimp_scanner_parse_int (scanner,
&param_def.meta.m_file.none_ok))
{
token = G_TOKEN_INT;
goto error;
}
if (! gimp_scanner_parse_string (scanner,
&param_def.meta.m_file.default_uri))
{
token = G_TOKEN_STRING;
goto error;
}
break;
}
@ -1082,6 +1098,10 @@ plug_in_proc_arg_deserialize (GScanner *scanner,
case GP_PARAM_DEF_TYPE_RESOURCE:
break;
case GP_PARAM_DEF_TYPE_FILE:
g_free (param_def.meta.m_file.default_uri);
break;
}
return token;
@ -1273,6 +1293,14 @@ plug_in_rc_write_proc_arg (GimpConfigWriter *writer,
param_def.meta.m_resource.default_to_context,
param_def.meta.m_resource.default_resource_id);
break;
case GP_PARAM_DEF_TYPE_FILE:
gimp_config_writer_printf (writer, "%d %d",
param_def.meta.m_file.action,
param_def.meta.m_file.none_ok);
gimp_config_writer_string (writer,
param_def.meta.m_file.default_uri);
break;
}
gimp_config_writer_close (writer);

View file

@ -21,6 +21,7 @@ static const GimpGetTypeFunc get_type_funcs[] =
gimp_desaturate_mode_get_type,
gimp_dodge_burn_type_get_type,
gimp_export_capabilities_get_type,
gimp_file_chooser_action_get_type,
gimp_fill_type_get_type,
gimp_foreground_extract_mode_get_type,
gimp_gradient_blend_color_space_get_type,
@ -86,6 +87,7 @@ static const gchar * const type_names[] =
"GimpDesaturateMode",
"GimpDodgeBurnType",
"GimpExportCapabilities",
"GimpFileChooserAction",
"GimpFillType",
"GimpForegroundExtractMode",
"GimpGradientBlendColorSpace",

View file

@ -248,6 +248,8 @@ gimp_export_procedure_constructed (GObject *object)
gimp_procedure_add_file_argument (procedure, "file",
"File",
"The file to export to",
GIMP_FILE_CHOOSER_ACTION_SAVE,
FALSE, NULL,
GIMP_PARAM_READWRITE);
_gimp_procedure_add_argument (procedure,

View file

@ -340,6 +340,25 @@ _gimp_gp_param_def_to_param_spec (const GPParamDef *param_def)
flags);
break;
case GP_PARAM_DEF_TYPE_FILE:
if (! strcmp (param_def->type_name, "GimpParamFile"))
{
GFile *file = NULL;
GParamSpec *pspec;
if (param_def->meta.m_file.default_uri &&
strlen (param_def->meta.m_file.default_uri) > 0)
file = g_file_new_for_uri (param_def->meta.m_file.default_uri);
pspec = gimp_param_spec_file (name, nick, blurb,
param_def->meta.m_file.action,
param_def->meta.m_file.none_ok,
file, flags);
g_clear_object (&file);
return pspec;
}
break;
}
g_warning ("%s: GParamSpec type unsupported '%s'", G_STRFUNC,
@ -647,6 +666,17 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec,
else
param_def->meta.m_resource.default_resource_id = 0;
}
else if (pspec_type == GIMP_TYPE_PARAM_FILE)
{
GimpParamSpecFile *fspec = GIMP_PARAM_SPEC_FILE (pspec);
GimpParamSpecObject *ospec = GIMP_PARAM_SPEC_OBJECT (pspec);
param_def->param_def_type = GP_PARAM_DEF_TYPE_FILE;
param_def->meta.m_file.none_ok = fspec->none_ok;
param_def->meta.m_file.default_uri =
ospec->_default_value ? g_file_get_uri (G_FILE (ospec->_default_value)) : NULL;
}
else if (GIMP_IS_PARAM_SPEC_CORE_OBJECT_ARRAY (pspec))
{
param_def->param_def_type = GP_PARAM_DEF_TYPE_ID_ARRAY;

View file

@ -114,6 +114,8 @@ gimp_load_procedure_constructed (GObject *object)
gimp_procedure_add_file_argument (procedure, "file",
"File",
"The file to load",
GIMP_FILE_CHOOSER_ACTION_OPEN,
FALSE, NULL,
GIMP_PARAM_READWRITE);
gimp_procedure_add_image_return_value (procedure, "image",

View file

@ -2276,11 +2276,14 @@ gimp_procedure_add_path_return_value (GimpProcedure *procedure,
/**
* gimp_procedure_add_file_argument:
* @procedure: the #GimpProcedure.
* @name: the name of the argument to be created.
* @nick: the label used in #GimpProcedureDialog.
* @blurb: a more detailed help description.
* @flags: argument flags.
* @procedure: The #GimpProcedure.
* @name: The name of the argument to be created.
* @nick: The label used in #GimpProcedureDialog.
* @blurb: A more detailed help description.
* @action: The type of file to expect.
* @none_ok: Whether %NULL is allowed.
* @default_file: (nullable): File to use if none is assigned.
* @flags: Argument flags.
*
* Add a new #GFile argument to @procedure.
*
@ -2291,20 +2294,27 @@ gimp_procedure_add_file_argument (GimpProcedure *procedure,
const gchar *name,
const gchar *nick,
const gchar *blurb,
GimpFileChooserAction action,
gboolean none_ok,
GFile *default_file,
GParamFlags flags)
{
_gimp_procedure_add_argument (procedure,
g_param_spec_object (name, nick, blurb,
G_TYPE_FILE, flags));
gimp_param_spec_file (name, nick, blurb,
action, none_ok,
default_file, flags));
}
/**
* gimp_procedure_add_file_aux_argument:
* @procedure: the #GimpProcedure.
* @name: the name of the argument to be created.
* @nick: the label used in #GimpProcedureDialog.
* @blurb: a more detailed help description.
* @flags: argument flags.
* @procedure: The #GimpProcedure.
* @name: The name of the argument to be created.
* @nick: The label used in #GimpProcedureDialog.
* @blurb: A more detailed help description.
* @action: The type of file to expect.
* @none_ok: Whether %NULL is allowed.
* @default_file: (nullable): File to use if none is assigned.
* @flags: Argument flags.
*
* Add a new #GFile auxiliary argument to @procedure.
*
@ -2315,11 +2325,15 @@ gimp_procedure_add_file_aux_argument (GimpProcedure *procedure,
const gchar *name,
const gchar *nick,
const gchar *blurb,
GimpFileChooserAction action,
gboolean none_ok,
GFile *default_file,
GParamFlags flags)
{
_gimp_procedure_add_aux_argument (procedure,
g_param_spec_object (name, nick, blurb,
G_TYPE_FILE, flags));
gimp_param_spec_file (name, nick, blurb,
action, none_ok,
default_file, flags));
}
/**
@ -2342,8 +2356,9 @@ gimp_procedure_add_file_return_value (GimpProcedure *procedure,
GParamFlags flags)
{
_gimp_procedure_add_return_value (procedure,
g_param_spec_object (name, nick, blurb,
G_TYPE_FILE, flags));
gimp_param_spec_file (name, nick, blurb,
GIMP_FILE_CHOOSER_ACTION_ANY,
TRUE, NULL, flags));
}
/**

View file

@ -998,11 +998,17 @@ void gimp_procedure_add_file_argument (GimpProcedure *procedure
const gchar *name,
const gchar *nick,
const gchar *blurb,
GimpFileChooserAction action,
gboolean none_ok,
GFile *default_value,
GParamFlags flags);
void gimp_procedure_add_file_aux_argument (GimpProcedure *procedure,
const gchar *name,
const gchar *nick,
const gchar *blurb,
GimpFileChooserAction action,
gboolean none_ok,
GFile *default_value,
GParamFlags flags);
void gimp_procedure_add_file_return_value (GimpProcedure *procedure,
const gchar *name,

View file

@ -657,11 +657,14 @@ gimp_procedure_dialog_set_ok_label (GimpProcedureDialog *dialog,
* non-editable color area with a label.
* * %GIMP_TYPE_COLOR_BUTTON: a color button with no label.
* * %GIMP_TYPE_COLOR_AREA: a color area with no label.
* - %GIMP_TYPE_PARAM_FILE:
* * %GTK_FILE_CHOOSER_BUTTON (default): generic file chooser widget
* using the action mode of the param spec.
* - %G_TYPE_PARAM_FILE:
* * %GTK_FILE_CHOOSER_BUTTON (default): generic file chooser button
* in %GTK_FILE_CHOOSER_ACTION_OPEN mode. Please use
* gimp_procedure_dialog_get_file_chooser() to create buttons in
* other modes.
* [method@ProcedureDialog.get_file_chooser] to create buttons in
* other modes or better, use a %GIMP_TYPE_PARAM_FILE argument.
*
* If the @widget_type is not supported for the actual type of
* @property, the function will fail. To keep the default, set to
@ -837,6 +840,13 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
gtk_widget_set_hexpand (widget, FALSE);
}
}
else if (GIMP_IS_PARAM_SPEC_FILE (pspec))
{
GimpParamSpecFile *fspec = GIMP_PARAM_SPEC_FILE (pspec);
widget = gimp_procedure_dialog_get_file_chooser (dialog, property,
(GtkFileChooserAction) fspec->action);
}
else if (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type == G_TYPE_FILE)
{
widget = gimp_prop_file_chooser_button_new (G_OBJECT (priv->config),
@ -1618,6 +1628,12 @@ gimp_procedure_dialog_get_label (GimpProcedureDialog *dialog,
* If a widget has already been created for this procedure, it will be
* returned instead (whatever its actual widget type).
*
* Note: it doesn't work for [enum@Gtk.FileChooserAction.SAVE] and
* [enum@Gtk.FileChooserAction.CREATE_FOLDER] @action yet.
*
* As for [enum@Gimp.FileChooserAction.ANY], it should never be used for
* a procedure argument if you intend to display a widget for it.
*
* Returns: (transfer none): the #GtkWidget representing @property. The
* object belongs to @dialog and must not be
* freed.
@ -1633,6 +1649,9 @@ gimp_procedure_dialog_get_file_chooser (GimpProcedureDialog *dialog,
g_return_val_if_fail (GIMP_IS_PROCEDURE_DIALOG (dialog), NULL);
g_return_val_if_fail (property != NULL, NULL);
g_return_val_if_fail (action != GIMP_FILE_CHOOSER_ACTION_ANY &&
action != GIMP_FILE_CHOOSER_ACTION_SAVE &&
action != GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER, NULL);
priv = gimp_procedure_dialog_get_instance_private (dialog);
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (priv->config),

View file

@ -85,6 +85,8 @@ gimp_thumbnail_procedure_constructed (GObject *object)
gimp_procedure_add_file_argument (procedure, "file",
"File",
"The file to load the thumbnail from",
GIMP_FILE_CHOOSER_ACTION_OPEN,
FALSE, NULL,
GIMP_PARAM_READWRITE);
gimp_procedure_add_int_argument (procedure, "thumb-size",

View file

@ -62,6 +62,7 @@ EXPORTS
gimp_escape_uline
gimp_export_capabilities_get_type
gimp_export_options_get_type
gimp_file_chooser_action_get_type
gimp_file_get_utf8_name
gimp_file_has_extension
gimp_file_show_in_file_manager
@ -132,6 +133,7 @@ EXPORTS
gimp_param_core_object_array_get_type
gimp_param_double_array_get_type
gimp_param_export_options_get_type
gimp_param_file_get_type
gimp_param_int32_array_get_type
gimp_param_memsize_get_type
gimp_param_object_get_type
@ -141,6 +143,7 @@ EXPORTS
gimp_param_spec_core_object_array
gimp_param_spec_double_array
gimp_param_spec_export_options
gimp_param_spec_file
gimp_param_spec_int32_array
gimp_param_spec_memsize
gimp_param_spec_object_duplicate

View file

@ -1960,6 +1960,42 @@ gimp_export_capabilities_get_type (void)
return type;
}
GType
gimp_file_chooser_action_get_type (void)
{
static const GEnumValue values[] =
{
{ GIMP_FILE_CHOOSER_ACTION_ANY, "GIMP_FILE_CHOOSER_ACTION_ANY", "any" },
{ GIMP_FILE_CHOOSER_ACTION_OPEN, "GIMP_FILE_CHOOSER_ACTION_OPEN", "open" },
{ GIMP_FILE_CHOOSER_ACTION_SAVE, "GIMP_FILE_CHOOSER_ACTION_SAVE", "save" },
{ GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER, "GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER", "select-folder" },
{ GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER, "GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER", "create-folder" },
{ 0, NULL, NULL }
};
static const GimpEnumDesc descs[] =
{
{ GIMP_FILE_CHOOSER_ACTION_ANY, "GIMP_FILE_CHOOSER_ACTION_ANY", NULL },
{ GIMP_FILE_CHOOSER_ACTION_OPEN, "GIMP_FILE_CHOOSER_ACTION_OPEN", NULL },
{ GIMP_FILE_CHOOSER_ACTION_SAVE, "GIMP_FILE_CHOOSER_ACTION_SAVE", NULL },
{ GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER, "GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER", NULL },
{ GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER, "GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER", NULL },
{ 0, NULL, NULL }
};
static GType type = 0;
if (G_UNLIKELY (! type))
{
type = g_enum_register_static ("GimpFileChooserAction", values);
gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp");
gimp_type_set_translation_context (type, "file-chooser-action");
gimp_enum_set_value_descriptions (type, descs);
}
return type;
}
/* Generated data ends here */

View file

@ -1338,6 +1338,33 @@ typedef enum
} GimpExportCapabilities;
/**
* GimpFileChooserAction:
* @GIMP_FILE_CHOOSER_ACTION_ANY: No restriction.
* @GIMP_FILE_CHOOSER_ACTION_OPEN: Opens an existing file.
* @GIMP_FILE_CHOOSER_ACTION_SAVE: Saves a file (over a new file or an existing one.
* @GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER: Picks an existing folder.
* @GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER: Picks an existing or new folder.
*
* A type of file to choose from when actions are expected to choose a
* file. This is basically a mapping to %GtkFileChooserAction except for
* [enum@Gimp.FileChooserAction.ANY] which should not be used for any
* GUI functions since we can't know what you are looking for.
**/
#define GIMP_TYPE_FILE_CHOOSER_ACTION (gimp_file_chooser_action_get_type ())
GType gimp_file_chooser_action_get_type (void) G_GNUC_CONST;
typedef enum
{
GIMP_FILE_CHOOSER_ACTION_ANY = -1,
GIMP_FILE_CHOOSER_ACTION_OPEN = 0,
GIMP_FILE_CHOOSER_ACTION_SAVE = 1,
GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER = 2,
GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER = 3,
} GimpFileChooserAction;
G_END_DECLS
#endif /* __GIMP_BASE_ENUMS_H__ */

View file

@ -21,6 +21,7 @@
#include "config.h"
#include <gegl.h>
#include <gio/gio.h>
#include <glib-object.h>
#include "gimpbasetypes.h"

View file

@ -216,6 +216,187 @@ gimp_param_spec_object_duplicate (GParamSpec *pspec)
}
/*
* GIMP_TYPE_PARAM_FILE
*/
static void gimp_param_file_class_init (GimpParamSpecObjectClass *klass);
static void gimp_param_file_init (GimpParamSpecFile *fspec);
static gboolean gimp_param_spec_file_validate (GParamSpec *pspec,
GValue *value);
static GParamSpec * gimp_param_spec_file_duplicate (GParamSpec *pspec);
/**
* gimp_param_file_get_type:
*
* Reveals the object type
*
* Returns: the #GType for a file param object.
*
* Since: 3.0
**/
GType
gimp_param_file_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GimpParamSpecObjectClass),
NULL, NULL,
(GClassInitFunc) gimp_param_file_class_init,
NULL, NULL,
sizeof (GimpParamSpecFile),
0,
(GInstanceInitFunc) gimp_param_file_init
};
type = g_type_register_static (GIMP_TYPE_PARAM_OBJECT,
"GimpParamFile", &info, 0);
}
return type;
}
static void
gimp_param_file_class_init (GimpParamSpecObjectClass *klass)
{
GParamSpecClass *pclass = G_PARAM_SPEC_CLASS (klass);
GimpParamSpecObjectClass *oclass = GIMP_PARAM_SPEC_OBJECT_CLASS (klass);
pclass->value_type = G_TYPE_FILE;
pclass->value_validate = gimp_param_spec_file_validate;
oclass->duplicate = gimp_param_spec_file_duplicate;
}
static void
gimp_param_file_init (GimpParamSpecFile *fspec)
{
fspec->none_ok = TRUE;
fspec->action = GIMP_FILE_CHOOSER_ACTION_OPEN;
}
static gboolean
gimp_param_spec_file_validate (GParamSpec *pspec,
GValue *value)
{
GimpParamSpecFile *fspec = GIMP_PARAM_SPEC_FILE (pspec);
GimpParamSpecObject *ospec = GIMP_PARAM_SPEC_OBJECT (pspec);
GFile *file = value->data[0].v_pointer;
gboolean modifying = FALSE;
if (file == NULL && ! fspec->none_ok && ospec->_default_value != NULL)
{
modifying = TRUE;
}
else if (file != NULL)
{
gboolean exists = g_file_query_exists (file, NULL);
GFileType type = g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL);
switch (fspec->action)
{
case GIMP_FILE_CHOOSER_ACTION_OPEN:
modifying = (! exists || type != G_FILE_TYPE_REGULAR);
break;
case GIMP_FILE_CHOOSER_ACTION_SAVE:
modifying = (exists && type != G_FILE_TYPE_REGULAR);
break;
case GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER:
modifying = (! exists || type != G_FILE_TYPE_DIRECTORY);
break;
case GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER:
modifying = (exists && type != G_FILE_TYPE_DIRECTORY);
break;
case GIMP_FILE_CHOOSER_ACTION_ANY:
break;
}
}
if (modifying)
{
g_clear_object (&file);
value->data[0].v_pointer = ospec->_default_value ? g_object_ref (ospec->_default_value) : NULL;
}
return modifying;
}
static GParamSpec *
gimp_param_spec_file_duplicate (GParamSpec *pspec)
{
GimpParamSpecObject *ospec;
GimpParamSpecFile *fspec;
GParamSpec *duplicate;
g_return_val_if_fail (GIMP_IS_PARAM_SPEC_FILE (pspec), NULL);
ospec = GIMP_PARAM_SPEC_OBJECT (pspec);
fspec = GIMP_PARAM_SPEC_FILE (pspec);
duplicate = gimp_param_spec_file (pspec->name,
g_param_spec_get_nick (pspec),
g_param_spec_get_blurb (pspec),
fspec->action, fspec->none_ok,
G_FILE (ospec->_default_value),
pspec->flags);
return duplicate;
}
/**
* gimp_param_spec_file:
* @name: Canonical name of the param
* @nick: Nickname of the param
* @blurb: Brief description of param.
* @action: The type of file to expect.
* @none_ok: Whether %NULL is allowed.
* @default_value: (nullable): File to use if none is assigned.
* @flags: a combination of #GParamFlags
*
* Creates a param spec to hold a file param.
* See g_param_spec_internal() for more information.
*
* Returns: (transfer full): a newly allocated #GParamSpec instance
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_file (const gchar *name,
const gchar *nick,
const gchar *blurb,
GimpFileChooserAction action,
gboolean none_ok,
GFile *default_value,
GParamFlags flags)
{
GimpParamSpecFile *fspec;
GimpParamSpecObject *ospec;
g_return_val_if_fail (default_value == NULL || G_IS_FILE (default_value), NULL);
fspec = g_param_spec_internal (GIMP_TYPE_PARAM_FILE,
name, nick, blurb, flags);
g_return_val_if_fail (fspec, NULL);
fspec->action = action;
fspec->none_ok = none_ok;
ospec = GIMP_PARAM_SPEC_OBJECT (fspec);
ospec->_has_default = TRUE;
/* Note that we don't check none_ok and allows even NULL as default
* value. What we won't allow will be trying to set a NULL value
* later.
*/
ospec->_default_value = default_value ? g_object_ref (G_OBJECT (default_value)) : NULL;
return G_PARAM_SPEC (fspec);
}
/*
* GIMP_TYPE_ARRAY
*/

View file

@ -152,6 +152,37 @@ gboolean gimp_param_spec_object_has_default (GParamSpec *pspec);
GParamSpec * gimp_param_spec_object_duplicate (GParamSpec *pspec);
/*
* GIMP_TYPE_PARAM_FILE
*/
#define GIMP_VALUE_HOLDS_FILE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_FILE))
#define GIMP_TYPE_PARAM_FILE (gimp_param_file_get_type ())
#define GIMP_PARAM_SPEC_FILE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_FILE, GimpParamSpecFile))
#define GIMP_IS_PARAM_SPEC_FILE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_FILE))
typedef struct _GimpParamSpecFile GimpParamSpecFile;
struct _GimpParamSpecFile
{
GimpParamSpecObject parent_instance;
/*< private >*/
GimpFileChooserAction action;
gboolean none_ok;
};
GType gimp_param_file_get_type (void) G_GNUC_CONST;
GParamSpec * gimp_param_spec_file (const gchar *name,
const gchar *nick,
const gchar *blurb,
GimpFileChooserAction action,
gboolean none_ok,
GFile *default_value,
GParamFlags flags);
/*
* GIMP_TYPE_ARRAY

View file

@ -19,6 +19,7 @@
#include "config.h"
#include <gegl.h>
#include <gio/gio.h>
#include <glib-object.h>
#include "gimpbasetypes.h"
@ -1293,6 +1294,21 @@ _gp_param_def_read (GIOChannel *channel,
user_data))
return FALSE;
break;
case GP_PARAM_DEF_TYPE_FILE:
if (! _gimp_wire_read_int32 (channel,
(guint32 *) &param_def->meta.m_file.action, 1,
user_data))
return FALSE;
if (! _gimp_wire_read_int32 (channel,
(guint32 *) &param_def->meta.m_file.none_ok, 1,
user_data))
return FALSE;
if (! _gimp_wire_read_string (channel,
&param_def->meta.m_file.default_uri, 1,
user_data))
return FALSE;
break;
}
return TRUE;
@ -1349,6 +1365,10 @@ _gp_param_def_destroy (GPParamDef *param_def)
case GP_PARAM_DEF_TYPE_RESOURCE:
break;
case GP_PARAM_DEF_TYPE_FILE:
g_free (param_def->meta.m_file.default_uri);
break;
}
}
@ -1641,6 +1661,21 @@ _gp_param_def_write (GIOChannel *channel,
user_data))
return FALSE;
break;
case GP_PARAM_DEF_TYPE_FILE:
if (! _gimp_wire_write_int32 (channel,
(guint32 *) &param_def->meta.m_file.action, 1,
user_data))
return FALSE;
if (! _gimp_wire_write_int32 (channel,
(guint32 *) &param_def->meta.m_file.none_ok, 1,
user_data))
return FALSE;
if (! _gimp_wire_write_string (channel,
&param_def->meta.m_file.default_uri, 1,
user_data))
return FALSE;
break;
}
return TRUE;

View file

@ -26,7 +26,7 @@ G_BEGIN_DECLS
/* Increment every time the protocol changes
*/
#define GIMP_PROTOCOL_VERSION 0x0114
#define GIMP_PROTOCOL_VERSION 0x0115
enum
@ -60,7 +60,8 @@ typedef enum
GP_PARAM_DEF_TYPE_ID,
GP_PARAM_DEF_TYPE_ID_ARRAY,
GP_PARAM_DEF_TYPE_EXPORT_OPTIONS,
GP_PARAM_DEF_TYPE_RESOURCE
GP_PARAM_DEF_TYPE_RESOURCE,
GP_PARAM_DEF_TYPE_FILE
} GPParamDefType;
typedef enum
@ -100,6 +101,7 @@ typedef struct _GPParamDefGeglColor GPParamDefGeglColor;
typedef struct _GPParamDefID GPParamDefID;
typedef struct _GPParamDefIDArray GPParamDefIDArray;
typedef struct _GPParamDefResource GPParamDefResource;
typedef struct _GPParamDefFile GPParamDefFile;
typedef struct _GPParam GPParam;
typedef struct _GPParamArray GPParamArray;
typedef struct _GPParamIDArray GPParamIDArray;
@ -239,6 +241,13 @@ struct _GPParamDefResource
gint32 default_resource_id;
};
struct _GPParamDefFile
{
GimpFileChooserAction action;
gint32 none_ok;
gchar *default_uri;
};
struct _GPParamDef
{
GPParamDefType param_def_type;
@ -262,6 +271,7 @@ struct _GPParamDef
GPParamDefIDArray m_id_array;
GPParamDefChoice m_choice;
GPParamDefResource m_resource;
GPParamDefFile m_file;
} meta;
};

View file

@ -25,6 +25,7 @@
#include <string.h>
#include <gegl.h>
#include <gio/gio.h>
#include <glib-object.h>
#include "gimpbasetypes.h"

View file

@ -23,6 +23,7 @@
#include <string.h>
#include <gegl.h>
#include <gio/gio.h>
#include <glib-object.h>
#include <gobject/gvaluecollector.h>

View file

@ -1135,7 +1135,7 @@ gimp_config_deserialize_file_value (GValue *value,
if (path)
{
GFile *file = g_file_new_for_path (path);
GFile *file = g_file_new_for_uri (path);
g_value_take_object (value, file);
g_free (path);

View file

@ -642,7 +642,7 @@ gimp_config_serialize_value (const GValue *value,
if (file)
{
gchar *path = g_file_get_path (file);
gchar *path = g_file_get_uri (file);
gchar *unexpand = NULL;
if (path)

View file

@ -652,6 +652,20 @@ package Gimp::CodeGen::enums;
GIMP_EXPORT_NEEDS_ALPHA => '1 << 9',
GIMP_EXPORT_NEEDS_CROP => '1 << 10' }
},
GimpFileChooserAction =>
{ contig => 0,
header => 'libgimpbase/gimpbaseenums.h',
symbols => [ qw(GIMP_FILE_CHOOSER_ACTION_ANY
GIMP_FILE_CHOOSER_ACTION_OPEN
GIMP_FILE_CHOOSER_ACTION_SAVE
GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER
GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER) ],
mapping => { GIMP_FILE_CHOOSER_ACTION_ANY => '-1',
GIMP_FILE_CHOOSER_ACTION_OPEN => '0',
GIMP_FILE_CHOOSER_ACTION_SAVE => '1',
GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER => '2',
GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER => '3' }
},
GimpColorManagementMode =>
{ contig => 1,
header => 'libgimpconfig/gimpconfigenums.h',

View file

@ -535,6 +535,8 @@ explorer_create_procedure (GimpPlugIn *plug_in,
_("Parameter File"),
_("The parameter file from which CML_explorer makes an image. "
"This argument is only used in non-interactive runs."),
GIMP_FILE_CHOOSER_ACTION_OPEN,
FALSE, NULL,
G_PARAM_READWRITE);
gimp_procedure_add_bytes_aux_argument (procedure, "settings-data",

View file

@ -157,6 +157,8 @@ cel_create_procedure (GimpPlugIn *plug_in,
gimp_procedure_add_file_argument (procedure, "palette-file",
_("_Palette file"),
_("KCF file to load palette from"),
GIMP_FILE_CHOOSER_ACTION_OPEN,
FALSE, NULL,
G_PARAM_READWRITE);
}
else if (! strcmp (name, EXPORT_PROC))
@ -193,6 +195,8 @@ cel_create_procedure (GimpPlugIn *plug_in,
gimp_procedure_add_file_argument (procedure, "palette-file",
_("_Palette file"),
_("File to save palette to"),
GIMP_FILE_CHOOSER_ACTION_SAVE,
FALSE, NULL,
G_PARAM_READWRITE);
}

View file

@ -431,6 +431,8 @@ raw_create_procedure (GimpPlugIn *plug_in,
gimp_procedure_add_file_argument (procedure, "palette-file",
_("_Palette File"),
_("The file containing palette data"),
GIMP_FILE_CHOOSER_ACTION_OPEN,
TRUE, NULL,
G_PARAM_READWRITE);
}
else if (! strcmp (name, LOAD_HGT_PROC))
@ -490,6 +492,8 @@ raw_create_procedure (GimpPlugIn *plug_in,
gimp_procedure_add_file_argument (procedure, "palette-file",
_("_Palette File"),
_("The file containing palette data"),
GIMP_FILE_CHOOSER_ACTION_OPEN,
TRUE, NULL,
G_PARAM_READWRITE);
}
else if (! strcmp (name, EXPORT_PROC))

View file

@ -273,9 +273,10 @@ fli_create_procedure (GimpPlugIn *plug_in,
"Jens Ch. Restemeier",
"1997");
gimp_procedure_add_file_argument (procedure, "file",
"File",
gimp_procedure_add_file_argument (procedure, "file", "File",
"The local file to get info about",
GIMP_FILE_CHOOSER_ACTION_OPEN,
FALSE, NULL,
G_PARAM_READWRITE);
gimp_procedure_add_int_return_value (procedure, "width",

View file

@ -370,6 +370,7 @@ script_fu_arg_add_argument (SFArg *arg,
{
GString *blurb_gstring = script_fu_arg_get_blurb (arg);
gchar *blurb = blurb_gstring->str;
GimpFileChooserAction action = GIMP_FILE_CHOOSER_ACTION_ANY;
switch (arg->type)
{
@ -492,17 +493,21 @@ script_fu_arg_add_argument (SFArg *arg,
break;
case SF_FILENAME:
action = GIMP_FILE_CHOOSER_ACTION_OPEN;
case SF_DIRNAME:
{
GParamSpec *pspec = NULL;
if (action == GIMP_FILE_CHOOSER_ACTION_ANY)
action = GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER;
gimp_procedure_add_file_argument (procedure, name,
nick, blurb,
action, TRUE, NULL,
G_PARAM_READWRITE |
GIMP_PARAM_NO_VALIDATE);
pspec = gimp_procedure_find_argument (procedure, name);
pspec_set_default_file (pspec, arg->default_value.sfa_file.filename);
/* FUTURE: Default not now appear in PDB browser, but appears in widgets? */
}
break;
@ -953,18 +958,14 @@ script_fu_arg_generate_name_and_nick (SFArg *arg,
static void
pspec_set_default_file (GParamSpec *pspec, const gchar *filepath)
{
GValue gvalue = G_VALUE_INIT;
GFile *gfile = NULL;
g_value_init (&gvalue, G_TYPE_FILE);
if (filepath != NULL && strlen (filepath) > 0)
gfile = g_file_new_for_path (filepath);
g_value_set_object (&gvalue, gfile);
/* FIXME this is not correct.
* value_set_default sets the value, not the pspec.
* Should be something like:
* gimp_param_spec_file_set_default (pspec, gfile);
*/
g_param_value_set_default (pspec, &gvalue);
gimp_param_spec_object_set_default (pspec, G_OBJECT (gfile));
g_clear_object (&gfile);
}
/* Append a string repr of an integer valued gvalue to given GString.