[gimp] libgimp: improve handling of procedure default values a lot
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] libgimp: improve handling of procedure default values a lot
- Date: Thu, 26 Sep 2019 17:27:19 +0000 (UTC)
commit 45e96a0ff461f20202655e74749dee43c9d08011
Author: Michael Natterer <mitch gimp org>
Date: Thu Sep 26 19:06:17 2019 +0200
libgimp: improve handling of procedure default values a lot
Add internal GimpProcedureConfig API to load/save "default values"
which are to be treated as if they were the hardcoded GParamSpec
defaults, but user-configurable. Also make all other load/save
functions available to other libgimp files.
In gimp_procedure_run(), if incomplete arguments are passed, don't
just complete them with the GParamSpec defaults, but look up the
user-saved defaults and use them if they exist. This happens before
everything else and brings back the PNG export feature of using
user-saved defaults also in non-interactive mode (but for all
procedures not just PNG export).
In GimpProcedureDialog, add "Load Defaults" and "Save Defaults"
buttons, they are the only way of managing the user-configurable
procedure defaults.
When clicking "Reset", show a popover with the reset options "Initial
Values" and "Factory Defaults".
libgimp/Makefile.am | 37 ++++----
libgimp/gimpprocedure.c | 22 ++++-
libgimp/gimpprocedureconfig-private.h | 43 +++++++++
libgimp/gimpprocedureconfig.c | 118 +++++++++++++++----------
libgimp/gimpproceduredialog.c | 160 +++++++++++++++++++++++++++++++---
5 files changed, 303 insertions(+), 77 deletions(-)
---
diff --git a/libgimp/Makefile.am b/libgimp/Makefile.am
index a14ad1fc74..b5745dc35e 100644
--- a/libgimp/Makefile.am
+++ b/libgimp/Makefile.am
@@ -105,25 +105,26 @@ libgimp_sources = \
libgimp-intl.h
libgimp_private_sources = \
- gimp-debug.c \
- gimp-debug.h \
- gimp-private.h \
- gimp-shm.c \
- gimp-shm.h \
- gimpgpparams.c \
- gimpgpparams.h \
- gimppdb-private.h \
- gimppdbprocedure.c \
- gimppdbprocedure.h \
- gimppixbuf.c \
- gimppixbuf.h \
- gimpplugin-private.h \
+ gimp-debug.c \
+ gimp-debug.h \
+ gimp-private.h \
+ gimp-shm.c \
+ gimp-shm.h \
+ gimpgpparams.c \
+ gimpgpparams.h \
+ gimppdb-private.h \
+ gimppdbprocedure.c \
+ gimppdbprocedure.h \
+ gimppixbuf.c \
+ gimppixbuf.h \
+ gimpplugin-private.h \
+ gimpprocedureconfig-private.h \
\
- gimpunit_pdb.c \
- gimpunit_pdb.h \
- gimppdb_pdb.c \
- gimppdb_pdb.h \
- gimpplugin_pdb.c \
+ gimpunit_pdb.c \
+ gimpunit_pdb.h \
+ gimppdb_pdb.c \
+ gimppdb_pdb.h \
+ gimpplugin_pdb.c \
gimpplugin_pdb.h
libgimp_extra_sources = \
diff --git a/libgimp/gimpprocedure.c b/libgimp/gimpprocedure.c
index c3ae18c838..86829bbd99 100644
--- a/libgimp/gimpprocedure.c
+++ b/libgimp/gimpprocedure.c
@@ -34,6 +34,7 @@
#include "gimppdb_pdb.h"
#include "gimpplugin_pdb.h"
#include "gimpprocedure-private.h"
+#include "gimpprocedureconfig-private.h"
#include "libgimp-intl.h"
@@ -1580,7 +1581,18 @@ gimp_procedure_run (GimpProcedure *procedure,
/* add missing args with default values */
if (gimp_value_array_length (args) < procedure->priv->n_args)
{
- GimpValueArray *complete = gimp_value_array_new (0);
+ GimpProcedureConfig *config;
+ GObjectClass *config_class = NULL;
+ GimpValueArray *complete;
+
+ /* if saved defaults exist, they override GParamSpec */
+ config = gimp_procedure_create_config (procedure);
+ if (_gimp_procedure_config_load_default (config, NULL))
+ config_class = G_OBJECT_GET_CLASS (config);
+ else
+ g_clear_object (&config);
+
+ complete = gimp_value_array_new (procedure->priv->n_args);
for (i = 0; i < procedure->priv->n_args; i++)
{
@@ -1595,6 +1607,12 @@ gimp_procedure_run (GimpProcedure *procedure,
g_value_copy (orig, &value);
}
+ else if (config &&
+ g_object_class_find_property (config_class, pspec->name))
+ {
+ g_object_get_property (G_OBJECT (config), pspec->name,
+ &value);
+ }
else
{
g_param_value_set_default (pspec, &value);
@@ -1604,6 +1622,8 @@ gimp_procedure_run (GimpProcedure *procedure,
g_value_unset (&value);
}
+ g_clear_object (&config);
+
/* call the procedure */
return_vals = GIMP_PROCEDURE_GET_CLASS (procedure)->run (procedure,
complete);
diff --git a/libgimp/gimpprocedureconfig-private.h b/libgimp/gimpprocedureconfig-private.h
new file mode 100644
index 0000000000..8db3d11425
--- /dev/null
+++ b/libgimp/gimpprocedureconfig-private.h
@@ -0,0 +1,43 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
+ *
+ * gimpprocedureconfig-private.h
+ * 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/>.
+ */
+
+#ifndef __GIMP_PROCEDURE_CONFIG_PRIVATE_H__
+#define __GIMP_PROCEDURE_CONFIG_PRIVATE_H__
+
+
+gboolean _gimp_procedure_config_load_default (GimpProcedureConfig *config,
+ GError **error);
+gboolean _gimp_procedure_config_save_default (GimpProcedureConfig *config,
+ GError **error);
+
+gboolean _gimp_procedure_config_load_last (GimpProcedureConfig *config,
+ GError **error);
+gboolean _gimp_procedure_config_save_last (GimpProcedureConfig *config,
+ GError **error);
+
+gboolean _gimp_procedure_config_load_parasite (GimpProcedureConfig *config,
+ GimpImage *image,
+ GError **error);
+gboolean _gimp_procedure_config_save_parasite (GimpProcedureConfig *config,
+ GimpImage *image);
+
+
+#endif /* __GIMP_PROCEDURE_CONFIG_PRIVATE_H__ */
diff --git a/libgimp/gimpprocedureconfig.c b/libgimp/gimpprocedureconfig.c
index 9ad0c0dcd4..7c8c902004 100644
--- a/libgimp/gimpprocedureconfig.c
+++ b/libgimp/gimpprocedureconfig.c
@@ -23,6 +23,8 @@
#include "gimp.h"
+#include "gimpprocedureconfig-private.h"
+
/**
* SECTION: gimpprocedureconfig
@@ -62,34 +64,16 @@ struct _GimpProcedureConfigPrivate
};
-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);
-
-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);
+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);
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GimpProcedureConfig, gimp_procedure_config,
@@ -358,8 +342,8 @@ gimp_procedure_config_begin_run (GimpProcedureConfig *config,
case GIMP_RUN_WITH_LAST_VALS:
if (image)
{
- loaded = gimp_procedure_config_load_parasite (config, image,
- &error);
+ loaded = _gimp_procedure_config_load_parasite (config, image,
+ &error);
if (! loaded && error)
{
g_printerr ("Loading last used values from parasite failed: %s\n",
@@ -369,7 +353,7 @@ gimp_procedure_config_begin_run (GimpProcedureConfig *config,
}
if (! loaded &&
- ! gimp_procedure_config_load_last (config, &error))
+ ! _gimp_procedure_config_load_last (config, &error) && error)
{
g_printerr ("Loading last used values from disk failed: %s\n",
error->message);
@@ -422,9 +406,9 @@ gimp_procedure_config_end_run (GimpProcedureConfig *config,
GError *error = NULL;
if (config->priv->image)
- gimp_procedure_config_save_parasite (config, config->priv->image);
+ _gimp_procedure_config_save_parasite (config, config->priv->image);
- if (! gimp_procedure_config_save_last (config, &error))
+ if (! _gimp_procedure_config_save_last (config, &error))
{
g_printerr ("Saving last used values to disk failed: %s\n",
error->message);
@@ -453,9 +437,48 @@ gimp_procedure_config_get_file (GimpProcedureConfig *config,
return file;
}
-static gboolean
-gimp_procedure_config_load_last (GimpProcedureConfig *config,
- GError **error)
+gboolean
+_gimp_procedure_config_load_default (GimpProcedureConfig *config,
+ GError **error)
+{
+ GFile *file = gimp_procedure_config_get_file (config, ".default");
+ gboolean success;
+
+ success = gimp_config_deserialize_file (GIMP_CONFIG (config),
+ file,
+ NULL, error);
+
+ if (! success && (*error)->code == GIMP_CONFIG_ERROR_OPEN_ENOENT)
+ {
+ g_clear_error (error);
+ }
+
+ g_object_unref (file);
+
+ return success;
+}
+
+gboolean
+_gimp_procedure_config_save_default (GimpProcedureConfig *config,
+ GError **error)
+{
+ GFile *file = gimp_procedure_config_get_file (config, ".default");
+ gboolean success;
+
+ success = gimp_config_serialize_to_file (GIMP_CONFIG (config),
+ file,
+ "settings",
+ "end of settings",
+ NULL, error);
+
+ g_object_unref (file);
+
+ return success;
+}
+
+gboolean
+_gimp_procedure_config_load_last (GimpProcedureConfig *config,
+ GError **error)
{
GFile *file = gimp_procedure_config_get_file (config, ".last");
gboolean success;
@@ -467,17 +490,16 @@ gimp_procedure_config_load_last (GimpProcedureConfig *config,
if (! success && (*error)->code == GIMP_CONFIG_ERROR_OPEN_ENOENT)
{
g_clear_error (error);
- success = TRUE;
}
g_object_unref (file);
- return TRUE;
+ return success;
}
-static gboolean
-gimp_procedure_config_save_last (GimpProcedureConfig *config,
- GError **error)
+gboolean
+_gimp_procedure_config_save_last (GimpProcedureConfig *config,
+ GError **error)
{
GFile *file = gimp_procedure_config_get_file (config, ".last");
gboolean success;
@@ -500,10 +522,10 @@ gimp_procedure_config_parasite_name (GimpProcedureConfig *config,
return g_strconcat (G_OBJECT_TYPE_NAME (config), suffix, NULL);
}
-static gboolean
-gimp_procedure_config_load_parasite (GimpProcedureConfig *config,
- GimpImage *image,
- GError **error)
+gboolean
+_gimp_procedure_config_load_parasite (GimpProcedureConfig *config,
+ GimpImage *image,
+ GError **error)
{
gchar *name;
GimpParasite *parasite;
@@ -524,9 +546,9 @@ gimp_procedure_config_load_parasite (GimpProcedureConfig *config,
return success;
}
-static gboolean
-gimp_procedure_config_save_parasite (GimpProcedureConfig *config,
- GimpImage *image)
+gboolean
+_gimp_procedure_config_save_parasite (GimpProcedureConfig *config,
+ GimpImage *image)
{
gchar *name;
GimpParasite *parasite;
diff --git a/libgimp/gimpproceduredialog.c b/libgimp/gimpproceduredialog.c
index 696f38bc12..594969323e 100644
--- a/libgimp/gimpproceduredialog.c
+++ b/libgimp/gimpproceduredialog.c
@@ -28,6 +28,8 @@
#include "gimp.h"
#include "gimpui.h"
+#include "gimpprocedureconfig-private.h"
+
#include "libgimp-intl.h"
@@ -46,18 +48,30 @@ struct _GimpProcedureDialogPrivate
{
GimpProcedure *procedure;
GimpProcedureConfig *config;
+ GimpProcedureConfig *initial_config;
+
+ GtkWidget *reset_popover;
};
-static void gimp_procedure_dialog_dispose (GObject *object);
-static void gimp_procedure_dialog_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_procedure_dialog_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
+static void gimp_procedure_dialog_dispose (GObject *object);
+static void gimp_procedure_dialog_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_procedure_dialog_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_procedure_dialog_reset_initial (GtkWidget *button,
+ GimpProcedureDialog *dialog);
+static void gimp_procedure_dialog_reset_factory (GtkWidget *button,
+ GimpProcedureDialog *dialog);
+static void gimp_procedure_dialog_load_defaults (GtkWidget *button,
+ GimpProcedureDialog *dialog);
+static void gimp_procedure_dialog_save_defaults (GtkWidget *button,
+ GimpProcedureDialog *dialog);
G_DEFINE_TYPE_WITH_PRIVATE (GimpProcedureDialog, gimp_procedure_dialog,
@@ -104,6 +118,9 @@ gimp_procedure_dialog_dispose (GObject *object)
g_clear_object (&dialog->priv->procedure);
g_clear_object (&dialog->priv->config);
+ g_clear_object (&dialog->priv->initial_config);
+
+ g_clear_pointer (&dialog->priv->reset_popover, gtk_widget_destroy);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -124,6 +141,10 @@ gimp_procedure_dialog_set_property (GObject *object,
case PROP_CONFIG:
dialog->priv->config = g_value_dup_object (value);
+
+ if (dialog->priv->config)
+ dialog->priv->initial_config =
+ gimp_config_duplicate (GIMP_CONFIG (dialog->priv->config));
break;
default:
@@ -166,6 +187,8 @@ gimp_procedure_dialog_new (GimpProcedure *procedure,
const gchar *help_id;
const gchar *ok_label;
gboolean use_header_bar;
+ GtkWidget *hbox;
+ GtkWidget *button;
g_return_val_if_fail (GIMP_IS_PROCEDURE (procedure), NULL);
g_return_val_if_fail (GIMP_IS_PROCEDURE_CONFIG (config), NULL);
@@ -214,6 +237,30 @@ gimp_procedure_dialog_new (GimpProcedure *procedure,
gimp_window_set_transient (GTK_WINDOW (dialog));
+ hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 12);
+ gtk_box_set_spacing (GTK_BOX (hbox), 6);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_START);
+ gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
+ hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ button = gtk_button_new_with_mnemonic (_("_Load Defaults"));
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (gimp_procedure_dialog_load_defaults),
+ dialog);
+
+ button = gtk_button_new_with_mnemonic (_("_Save Defaults"));
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (gimp_procedure_dialog_save_defaults),
+ dialog);
+
return GTK_WIDGET (dialog);
}
@@ -228,7 +275,42 @@ gimp_procedure_dialog_run (GimpProcedureDialog *dialog)
if (response == RESPONSE_RESET)
{
- gimp_config_reset (GIMP_CONFIG (dialog->priv->config));
+ if (! dialog->priv->reset_popover)
+ {
+ GtkWidget *button;
+ GtkWidget *vbox;
+
+ button = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog),
+ response);
+
+ dialog->priv->reset_popover = gtk_popover_new (button);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_container_add (GTK_CONTAINER (dialog->priv->reset_popover),
+ vbox);
+ gtk_widget_show (vbox);
+
+ button = gtk_button_new_with_mnemonic (_("Reset to _Initial "
+ "Values"));
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (gimp_procedure_dialog_reset_initial),
+ dialog);
+
+ button = gtk_button_new_with_mnemonic (_("Reset to _Factory "
+ "Defaults"));
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (gimp_procedure_dialog_reset_factory),
+ dialog);
+ }
+
+ gtk_popover_popup (GTK_POPOVER (dialog->priv->reset_popover));
}
else
{
@@ -236,3 +318,61 @@ gimp_procedure_dialog_run (GimpProcedureDialog *dialog)
}
}
}
+
+
+/* private functions */
+
+static void
+gimp_procedure_dialog_reset_initial (GtkWidget *button,
+ GimpProcedureDialog *dialog)
+{
+ gimp_config_copy (GIMP_CONFIG (dialog->priv->initial_config),
+ GIMP_CONFIG (dialog->priv->config),
+ 0);
+
+ gtk_popover_popdown (GTK_POPOVER (dialog->priv->reset_popover));
+}
+
+static void
+gimp_procedure_dialog_reset_factory (GtkWidget *button,
+ GimpProcedureDialog *dialog)
+{
+ gimp_config_reset (GIMP_CONFIG (dialog->priv->config));
+
+ gtk_popover_popdown (GTK_POPOVER (dialog->priv->reset_popover));
+}
+
+static void
+gimp_procedure_dialog_load_defaults (GtkWidget *button,
+ GimpProcedureDialog *dialog)
+{
+ GError *error = NULL;
+
+ if (! _gimp_procedure_config_load_default (dialog->priv->config, &error))
+ {
+ if (error)
+ {
+ g_printerr ("Loading default values from disk failed: %s\n",
+ error->message);
+ g_clear_error (&error);
+ }
+ else
+ {
+ g_printerr ("No default values found on disk\n");
+ }
+ }
+}
+
+static void
+gimp_procedure_dialog_save_defaults (GtkWidget *button,
+ GimpProcedureDialog *dialog)
+{
+ GError *error = NULL;
+
+ if (! _gimp_procedure_config_save_default (dialog->priv->config, &error))
+ {
+ g_printerr ("Saving default values to disk failed: %s\n",
+ error->message);
+ g_clear_error (&error);
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]