2019-09-20 18:31:11 +08:00
|
|
|
/* LIBGIMP - The GIMP Library
|
|
|
|
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
|
|
|
|
*
|
|
|
|
* gimpprocedureconfig.c
|
|
|
|
* Copyright (C) 2019 Michael Natterer <mitch@gimp.org>
|
|
|
|
*
|
|
|
|
* This library is free software: you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 3 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library. If not, see
|
|
|
|
* <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "gimp.h"
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SECTION: gimpprocedureconfig
|
|
|
|
* @title: GimpProcedureConfig
|
|
|
|
* @short_description: Config object for procedure arguments
|
|
|
|
*
|
|
|
|
* #GimpProcedureConfig base class for #GimpProcedure-specific config
|
|
|
|
* objects and the main interface to manage aspects of
|
|
|
|
* #GimpProcedure's arguments such as persistency of the last used
|
2019-09-22 01:10:46 +08:00
|
|
|
* arguments across GIMP sessions.
|
2019-09-20 18:31:11 +08:00
|
|
|
*
|
|
|
|
* A #GimpProcedureConfig is created by a #GimpProcedure using
|
|
|
|
* gimp_procedure_create_config() and its properties match the
|
|
|
|
* procedure's arguments in number, order and type.
|
|
|
|
*
|
|
|
|
* It implements the #GimpConfig interface and therefore has all its
|
|
|
|
* serialization and deserialization features.
|
|
|
|
*
|
|
|
|
* Since: 3.0
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PROP_0,
|
|
|
|
PROP_PROCEDURE,
|
|
|
|
N_PROPS
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct _GimpProcedureConfigPrivate
|
|
|
|
{
|
|
|
|
GimpProcedure *procedure;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void gimp_procedure_config_constructed (GObject *object);
|
|
|
|
static void gimp_procedure_config_dispose (GObject *object);
|
|
|
|
static void gimp_procedure_config_set_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec);
|
|
|
|
static void gimp_procedure_config_get_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec);
|
|
|
|
|
|
|
|
static GFile * gimp_procedure_config_get_file (GimpProcedureConfig *config,
|
|
|
|
const gchar *extension);
|
|
|
|
static gboolean gimp_procedure_config_load_last (GimpProcedureConfig *config,
|
|
|
|
GError **error);
|
|
|
|
static gboolean gimp_procedure_config_save_last (GimpProcedureConfig *config,
|
|
|
|
GError **error);
|
|
|
|
|
2019-09-24 01:28:04 +08:00
|
|
|
static gchar * gimp_procedure_config_parasite_name
|
|
|
|
(GimpProcedureConfig *config,
|
|
|
|
const gchar *suffix);
|
|
|
|
static gboolean gimp_procedure_config_load_parasite
|
|
|
|
(GimpProcedureConfig *config,
|
|
|
|
GimpImage *image,
|
|
|
|
GError **error);
|
|
|
|
static gboolean gimp_procedure_config_save_parasite
|
|
|
|
(GimpProcedureConfig *config,
|
|
|
|
GimpImage *image);
|
2019-09-20 18:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GimpProcedureConfig, gimp_procedure_config,
|
|
|
|
G_TYPE_OBJECT)
|
|
|
|
|
|
|
|
#define parent_class gimp_procedure_config_parent_class
|
|
|
|
|
|
|
|
static GParamSpec *props[N_PROPS] = { NULL, };
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_procedure_config_class_init (GimpProcedureConfigClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->constructed = gimp_procedure_config_constructed;
|
|
|
|
object_class->dispose = gimp_procedure_config_dispose;
|
|
|
|
object_class->set_property = gimp_procedure_config_set_property;
|
|
|
|
object_class->get_property = gimp_procedure_config_get_property;
|
|
|
|
|
|
|
|
props[PROP_PROCEDURE] =
|
|
|
|
g_param_spec_object ("procedure",
|
|
|
|
"Procedure",
|
|
|
|
"The procedure this config object is used for",
|
|
|
|
GIMP_TYPE_PROCEDURE,
|
|
|
|
GIMP_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY);
|
|
|
|
|
|
|
|
g_object_class_install_properties (object_class, N_PROPS, props);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_procedure_config_init (GimpProcedureConfig *config)
|
|
|
|
{
|
|
|
|
config->priv = gimp_procedure_config_get_instance_private (config);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_procedure_config_constructed (GObject *object)
|
|
|
|
{
|
|
|
|
GimpProcedureConfig *config = GIMP_PROCEDURE_CONFIG (object);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (parent_class)->constructed (object);
|
|
|
|
|
|
|
|
g_assert (GIMP_IS_PROCEDURE (config->priv->procedure));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_procedure_config_dispose (GObject *object)
|
|
|
|
{
|
|
|
|
GimpProcedureConfig *config = GIMP_PROCEDURE_CONFIG (object);
|
|
|
|
|
|
|
|
g_clear_object (&config->priv->procedure);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_procedure_config_set_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GimpProcedureConfig *config = GIMP_PROCEDURE_CONFIG (object);
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case PROP_PROCEDURE:
|
|
|
|
config->priv->procedure = g_value_dup_object (value);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_procedure_config_get_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GimpProcedureConfig *config = GIMP_PROCEDURE_CONFIG (object);
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case PROP_PROCEDURE:
|
|
|
|
g_value_set_object (value, config->priv->procedure);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* public functions */
|
|
|
|
|
2019-09-21 01:33:50 +08:00
|
|
|
/**
|
|
|
|
* gimp_procedure_config_get_procedure:
|
|
|
|
* @config: a #GimpProcedureConfig
|
|
|
|
*
|
|
|
|
* This function returns the #GimpProcedure which created @config, see
|
|
|
|
* gimp_procedure_create_config().
|
|
|
|
*
|
|
|
|
* Returns: The #GimpProcedure which created @config.
|
|
|
|
*
|
|
|
|
* Since: 3.0
|
|
|
|
**/
|
|
|
|
GimpProcedure *
|
|
|
|
gimp_procedure_config_get_procedure (GimpProcedureConfig *config)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_PROCEDURE_CONFIG (config), NULL);
|
|
|
|
|
|
|
|
return config->priv->procedure;
|
|
|
|
}
|
|
|
|
|
2019-09-20 18:31:11 +08:00
|
|
|
/**
|
|
|
|
* gimp_procedure_config_set_values:
|
|
|
|
* @config: a #GimpProcedureConfig
|
|
|
|
* @values: a #GimpValueArray
|
|
|
|
*
|
|
|
|
* Sets the values from @values on @config's properties.
|
|
|
|
*
|
|
|
|
* The number, order and types of values in @values must match the
|
|
|
|
* number, order and types of @config's properties.
|
|
|
|
*
|
|
|
|
* This function is meant to be used on @values which are passed as
|
|
|
|
* arguments to the run() function of the #GimpProcedure which created
|
|
|
|
* this @config. See gimp_procedure_create_config().
|
|
|
|
*
|
|
|
|
* Since: 3.0
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_procedure_config_set_values (GimpProcedureConfig *config,
|
|
|
|
const GimpValueArray *values)
|
|
|
|
{
|
|
|
|
GParamSpec **pspecs;
|
|
|
|
guint n_pspecs;
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_PROCEDURE_CONFIG (config));
|
|
|
|
g_return_if_fail (values != NULL);
|
|
|
|
|
|
|
|
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config),
|
|
|
|
&n_pspecs);
|
|
|
|
|
|
|
|
g_return_if_fail (n_pspecs == gimp_value_array_length (values));
|
|
|
|
|
|
|
|
for (i = 0; i < n_pspecs; i++)
|
|
|
|
{
|
|
|
|
GParamSpec *pspec = pspecs[i];
|
|
|
|
GValue *value = gimp_value_array_index (values, i);
|
|
|
|
|
|
|
|
g_object_set_property (G_OBJECT (config), pspec->name, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (pspecs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_procedure_config_get_values:
|
|
|
|
* @config: a #GimpProcedureConfig
|
|
|
|
* @values: a #GimpValueArray
|
|
|
|
*
|
|
|
|
* Gets the values from @config's properties and stores them in
|
|
|
|
* @values.
|
|
|
|
*
|
|
|
|
* See gimp_procedure_config_set_values().
|
|
|
|
*
|
|
|
|
* Since: 3.0
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_procedure_config_get_values (GimpProcedureConfig *config,
|
|
|
|
GimpValueArray *values)
|
|
|
|
{
|
|
|
|
GParamSpec **pspecs;
|
|
|
|
guint n_pspecs;
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_PROCEDURE_CONFIG (config));
|
|
|
|
g_return_if_fail (values != NULL);
|
|
|
|
|
|
|
|
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config),
|
|
|
|
&n_pspecs);
|
|
|
|
|
|
|
|
g_return_if_fail (n_pspecs == gimp_value_array_length (values));
|
|
|
|
|
|
|
|
for (i = 0; i < n_pspecs; i++)
|
|
|
|
{
|
|
|
|
GParamSpec *pspec = pspecs[i];
|
|
|
|
GValue *value = gimp_value_array_index (values, i);
|
|
|
|
|
|
|
|
g_object_get_property (G_OBJECT (config), pspec->name, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (pspecs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_procedure_config_begin_run:
|
|
|
|
* @config: a #GimpProcedureConfig
|
2019-09-24 01:28:04 +08:00
|
|
|
* @image: a #GimpImage or %NULL
|
2019-09-20 18:31:11 +08:00
|
|
|
* @run_mode: the #GimpRunMode passed to a #GimpProcedure's run()
|
|
|
|
* @args: the #GimpValueArray passed to a #GimpProcedure's run()
|
|
|
|
*
|
|
|
|
* Populates @config with values for a #GimpProcedure's run(),
|
|
|
|
* depending on @run_mode.
|
|
|
|
*
|
|
|
|
* If @run_mode is %GIMP_RUN_INTERACTIVE or %GIMP_RUN_WITH_LAST_VALS,
|
|
|
|
* the saved values from the procedure's last run() are loaded and set
|
2019-09-24 01:28:04 +08:00
|
|
|
* on @config. If @image is not %NULL, the last used values for this
|
|
|
|
* image are tried first, and if no image-spesicic values are found
|
|
|
|
* the globally saved last used values are used. If no saved last used
|
|
|
|
* values are found, the procedure's default argument values are used.
|
2019-09-20 18:31:11 +08:00
|
|
|
*
|
|
|
|
* If @run_mode is %GIMP_RUN_NONINTERACTIVE, the contents of @args are
|
|
|
|
* set on @config using gimp_procedure_config_set_values().
|
|
|
|
*
|
|
|
|
* After calling this function, the @args passed to run() should be
|
|
|
|
* left alone and @config be treated as the procedure's arguments.
|
|
|
|
*
|
|
|
|
* It is possible to get @config's resulting values back into @args by
|
|
|
|
* calling gimp_procedure_config_get_values(), as long as modified
|
|
|
|
* @args are written back to @config using
|
|
|
|
* gimp_procedure_config_set_values() before the call to
|
|
|
|
* gimp_procedure_config_end_run().
|
|
|
|
*
|
|
|
|
* This function should be used at the beginning of a procedure's
|
|
|
|
* run() and be paired with a call to gimp_procedure_config_end_run()
|
|
|
|
* at the end of run().
|
|
|
|
*
|
|
|
|
* Since: 3.0
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_procedure_config_begin_run (GimpProcedureConfig *config,
|
2019-09-24 01:28:04 +08:00
|
|
|
GimpImage *image,
|
2019-09-20 18:31:11 +08:00
|
|
|
GimpRunMode run_mode,
|
|
|
|
const GimpValueArray *args)
|
|
|
|
{
|
2019-09-24 01:28:04 +08:00
|
|
|
gboolean loaded = FALSE;
|
|
|
|
GError *error = NULL;
|
2019-09-20 18:31:11 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_PROCEDURE_CONFIG (config));
|
2019-09-24 01:28:04 +08:00
|
|
|
g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image));
|
2019-09-20 18:31:11 +08:00
|
|
|
g_return_if_fail (args != NULL);
|
|
|
|
|
|
|
|
switch (run_mode)
|
|
|
|
{
|
|
|
|
case GIMP_RUN_INTERACTIVE :
|
|
|
|
case GIMP_RUN_WITH_LAST_VALS:
|
2019-09-24 01:28:04 +08:00
|
|
|
if (image)
|
|
|
|
{
|
|
|
|
loaded = gimp_procedure_config_load_parasite (config, image,
|
|
|
|
&error);
|
|
|
|
if (! loaded && error)
|
|
|
|
{
|
|
|
|
g_printerr ("Loading last used values from parasite failed: %s\n",
|
|
|
|
error->message);
|
|
|
|
g_clear_error (&error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! loaded &&
|
|
|
|
! gimp_procedure_config_load_last (config, &error))
|
2019-09-20 18:31:11 +08:00
|
|
|
{
|
2019-09-24 01:28:04 +08:00
|
|
|
g_printerr ("Loading last used values from disk failed: %s\n",
|
2019-09-20 18:31:11 +08:00
|
|
|
error->message);
|
|
|
|
g_clear_error (&error);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_RUN_NONINTERACTIVE:
|
|
|
|
gimp_procedure_config_set_values (config, args);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_procedure_config_end_run:
|
|
|
|
* @config: a #GimpProcedureConfig
|
2019-09-24 01:28:04 +08:00
|
|
|
* @image: a #GimpImage or %NULL
|
2019-09-20 18:31:11 +08:00
|
|
|
* @run_mode: the #GimpRunMode passed to a #GimpProcedure's run()
|
|
|
|
*
|
|
|
|
* This function is the counterpart of
|
|
|
|
* gimp_procedure_conig_begin_run() and should be used upon successful
|
|
|
|
* completion of a procedure's run(), before returning
|
|
|
|
* %GIMP_PDB_SUCCESS return values.
|
|
|
|
*
|
|
|
|
* If @run_mode is %GIMP_RUN_INTERACTIVE, @config is saved as last
|
2019-09-24 01:28:04 +08:00
|
|
|
* used values to be used when the procedure runs again. Additionally,
|
|
|
|
* if @image is not %NULL, @config is attached to @image as last used
|
|
|
|
* values for this image using a #GimpParasite and
|
|
|
|
* gimp_image_attach_parasite().
|
2019-09-20 18:31:11 +08:00
|
|
|
*
|
|
|
|
* If @run_mode is not %GIMP_RUN_NONINTERACTIVE, this function also
|
|
|
|
* conveniently calls gimp_display_flush(), which is what most
|
|
|
|
* procedures want and doesn't do any harm if called redundantly.
|
|
|
|
*
|
|
|
|
* See gimp_procedure_config_begin_run().
|
|
|
|
*
|
|
|
|
* Since: 3.0
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_procedure_config_end_run (GimpProcedureConfig *config,
|
2019-09-24 01:28:04 +08:00
|
|
|
GimpImage *image,
|
2019-09-20 18:31:11 +08:00
|
|
|
GimpRunMode run_mode)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_PROCEDURE_CONFIG (config));
|
2019-09-24 01:28:04 +08:00
|
|
|
g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image));
|
2019-09-20 18:31:11 +08:00
|
|
|
|
|
|
|
if (run_mode != GIMP_RUN_NONINTERACTIVE)
|
|
|
|
gimp_displays_flush ();
|
|
|
|
|
|
|
|
if (run_mode == GIMP_RUN_INTERACTIVE)
|
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
|
2019-09-24 01:28:04 +08:00
|
|
|
if (image)
|
|
|
|
gimp_procedure_config_save_parasite (config, image);
|
|
|
|
|
2019-09-20 18:31:11 +08:00
|
|
|
if (! gimp_procedure_config_save_last (config, &error))
|
|
|
|
{
|
2019-09-24 01:28:04 +08:00
|
|
|
g_printerr ("Saving last used values to disk failed: %s\n",
|
2019-09-20 18:31:11 +08:00
|
|
|
error->message);
|
|
|
|
g_clear_error (&error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* private functions */
|
|
|
|
|
|
|
|
static GFile *
|
|
|
|
gimp_procedure_config_get_file (GimpProcedureConfig *config,
|
|
|
|
const gchar *extension)
|
|
|
|
{
|
|
|
|
GFile *file;
|
|
|
|
gchar *basename;
|
|
|
|
|
|
|
|
basename = g_strconcat (G_OBJECT_TYPE_NAME (config), extension, NULL);
|
|
|
|
file = gimp_directory_file ("plug-in-settings", basename, NULL);
|
|
|
|
g_free (basename);
|
|
|
|
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_procedure_config_load_last (GimpProcedureConfig *config,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
GFile *file = gimp_procedure_config_get_file (config, ".last");
|
|
|
|
gboolean success;
|
|
|
|
|
2019-09-21 18:53:38 +08:00
|
|
|
success = gimp_config_deserialize_file (GIMP_CONFIG (config),
|
|
|
|
file,
|
|
|
|
NULL, error);
|
2019-09-20 18:31:11 +08:00
|
|
|
|
|
|
|
if (! success && (*error)->code == GIMP_CONFIG_ERROR_OPEN_ENOENT)
|
|
|
|
{
|
|
|
|
g_clear_error (error);
|
|
|
|
success = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_object_unref (file);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_procedure_config_save_last (GimpProcedureConfig *config,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
GFile *file = gimp_procedure_config_get_file (config, ".last");
|
|
|
|
gboolean success;
|
|
|
|
|
2019-09-21 18:53:38 +08:00
|
|
|
success = gimp_config_serialize_to_file (GIMP_CONFIG (config),
|
|
|
|
file,
|
|
|
|
"settings",
|
|
|
|
"end of settings",
|
|
|
|
NULL, error);
|
2019-09-20 18:31:11 +08:00
|
|
|
|
|
|
|
g_object_unref (file);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
2019-09-24 01:28:04 +08:00
|
|
|
|
|
|
|
static gchar *
|
|
|
|
gimp_procedure_config_parasite_name (GimpProcedureConfig *config,
|
|
|
|
const gchar *suffix)
|
|
|
|
{
|
|
|
|
return g_strconcat (G_OBJECT_TYPE_NAME (config), suffix, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_procedure_config_load_parasite (GimpProcedureConfig *config,
|
|
|
|
GimpImage *image,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gchar *name;
|
|
|
|
GimpParasite *parasite;
|
|
|
|
gboolean success;
|
|
|
|
|
|
|
|
name = gimp_procedure_config_parasite_name (config, "-last");
|
|
|
|
parasite = gimp_image_get_parasite (image, name);
|
|
|
|
g_free (name);
|
|
|
|
|
|
|
|
if (! parasite)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
success = gimp_config_deserialize_parasite (GIMP_CONFIG (config),
|
|
|
|
parasite,
|
|
|
|
NULL, error);
|
|
|
|
gimp_parasite_free (parasite);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_procedure_config_save_parasite (GimpProcedureConfig *config,
|
|
|
|
GimpImage *image)
|
|
|
|
{
|
|
|
|
gchar *name;
|
|
|
|
GimpParasite *parasite;
|
|
|
|
|
|
|
|
name = gimp_procedure_config_parasite_name (config, "-last");
|
|
|
|
parasite = gimp_config_serialize_to_parasite (GIMP_CONFIG (config),
|
|
|
|
name,
|
|
|
|
GIMP_PARASITE_PERSISTENT,
|
|
|
|
NULL);
|
|
|
|
g_free (name);
|
|
|
|
|
|
|
|
if (! parasite)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
gimp_image_attach_parasite (image, parasite);
|
|
|
|
gimp_parasite_free (parasite);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|