libgimp: new fill_start() and fill_end() class method for GimpProcedureDialog.

Instead of filling default GUI for a specific type of plug-in procedure in
fill_list(), we add 2 methods:

* fill_start() is ensured to run once (and only once) before any fill_list()
  code runs.
* fill_end() is ensured to run once (and only once) after all fill_list() ran.

This takes care of 2 kind of GUI bugs which we could have:

1. First if no explicit fill were run (i.e. neither gimp_procedure_dialog_fill()
   nor gimp_procedure_dialog_fill_list() were ever run), then the default
   interface would not be added to the dialog. Yet this case could happen when
   we don't want anything else but the default GUI (this will be the case in the
   upcoming file-wmf-load GUI).
2. Second if at the opposite, you fill several times fill functions (I hadn't
   thought of this, but noticed some already started to do this in our ported
   plug-ins), we obviously don't want the default GUI to be added several times
   either.
This commit is contained in:
Jehan 2024-04-24 14:00:54 +02:00
parent 9a2774f7f9
commit dd6acc86fb
4 changed files with 200 additions and 104 deletions

View File

@ -43,6 +43,9 @@ struct _GimpExportProcedureDialogPrivate
static void gimp_export_procedure_dialog_finalize (GObject *object);
static void gimp_export_procedure_dialog_fill_end (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config);
static void gimp_export_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
@ -67,6 +70,7 @@ gimp_export_procedure_dialog_class_init (GimpExportProcedureDialogClass *klass)
proc_dialog_class = GIMP_PROCEDURE_DIALOG_CLASS (klass);
object_class->finalize = gimp_export_procedure_dialog_finalize;
proc_dialog_class->fill_end = gimp_export_procedure_dialog_fill_end;
proc_dialog_class->fill_list = gimp_export_procedure_dialog_fill_list;
}
@ -94,49 +98,20 @@ gimp_export_procedure_dialog_finalize (GObject *object)
}
static void
gimp_export_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties)
gimp_export_procedure_dialog_fill_end (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config)
{
GimpExportProcedureDialog *export_dialog;
GimpExportProcedure *export_procedure;
GtkWidget *content_area;
GList *properties2 = NULL;
GList *iter;
GIMP_PROCEDURE_DIALOG_CLASS (parent_class)->fill_end (dialog, procedure, config);
export_dialog = GIMP_EXPORT_PROCEDURE_DIALOG (dialog);
export_procedure = GIMP_EXPORT_PROCEDURE (procedure);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
for (iter = properties; iter; iter = iter->next)
{
gchar *propname = iter->data;
if ((gimp_export_procedure_get_support_exif (export_procedure) &&
g_strcmp0 (propname, "save-exif") == 0) ||
(gimp_export_procedure_get_support_iptc (export_procedure) &&
g_strcmp0 (propname, "save-iptc") == 0) ||
(gimp_export_procedure_get_support_xmp (export_procedure) &&
g_strcmp0 (propname, "save-xmp") == 0) ||
(gimp_export_procedure_get_support_profile (export_procedure) &&
g_strcmp0 (propname, "save-color-profile") == 0) ||
(gimp_export_procedure_get_support_thumbnail (export_procedure) &&
g_strcmp0 (propname, "save-thumbnail") == 0) ||
(gimp_export_procedure_get_support_comment (export_procedure) &&
(g_strcmp0 (propname, "save-comment") == 0 ||
g_strcmp0 (propname, "gimp-comment") == 0)) ||
g_list_find (export_dialog->priv->additional_metadata, propname))
/* Ignoring the standards and custom metadata. */
continue;
properties2 = g_list_prepend (properties2, propname);
}
properties2 = g_list_reverse (properties2);
GIMP_PROCEDURE_DIALOG_CLASS (parent_class)->fill_list (dialog, procedure, config, properties2);
g_list_free (properties2);
if (gimp_export_procedure_get_support_exif (export_procedure) ||
gimp_export_procedure_get_support_iptc (export_procedure) ||
gimp_export_procedure_get_support_xmp (export_procedure) ||
@ -255,7 +230,7 @@ gimp_export_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
/* Custom metadata: n_metadata items per line. */
left = 0;
for (iter = export_dialog->priv->additional_metadata; iter; iter = iter->next)
for (GList *iter = export_dialog->priv->additional_metadata; iter; iter = iter->next)
{
widget = gimp_procedure_dialog_get_widget (dialog, iter->data, G_TYPE_NONE);
gtk_grid_attach (GTK_GRID (grid), widget, left, top, 6 / n_metadata, 1);
@ -325,6 +300,48 @@ gimp_export_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
}
}
static void
gimp_export_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties)
{
GimpExportProcedureDialog *export_dialog;
GimpExportProcedure *export_procedure;
GList *properties2 = NULL;
GList *iter;
export_dialog = GIMP_EXPORT_PROCEDURE_DIALOG (dialog);
export_procedure = GIMP_EXPORT_PROCEDURE (procedure);
for (iter = properties; iter; iter = iter->next)
{
gchar *propname = iter->data;
if ((gimp_export_procedure_get_support_exif (export_procedure) &&
g_strcmp0 (propname, "save-exif") == 0) ||
(gimp_export_procedure_get_support_iptc (export_procedure) &&
g_strcmp0 (propname, "save-iptc") == 0) ||
(gimp_export_procedure_get_support_xmp (export_procedure) &&
g_strcmp0 (propname, "save-xmp") == 0) ||
(gimp_export_procedure_get_support_profile (export_procedure) &&
g_strcmp0 (propname, "save-color-profile") == 0) ||
(gimp_export_procedure_get_support_thumbnail (export_procedure) &&
g_strcmp0 (propname, "save-thumbnail") == 0) ||
(gimp_export_procedure_get_support_comment (export_procedure) &&
(g_strcmp0 (propname, "save-comment") == 0 ||
g_strcmp0 (propname, "gimp-comment") == 0)) ||
g_list_find (export_dialog->priv->additional_metadata, propname))
/* Ignoring the standards and custom metadata. */
continue;
properties2 = g_list_prepend (properties2, propname);
}
properties2 = g_list_reverse (properties2);
GIMP_PROCEDURE_DIALOG_CLASS (parent_class)->fill_list (dialog, procedure, config, properties2);
g_list_free (properties2);
}
static gpointer
gimp_export_procedure_dialog_edit_metadata_thread (gpointer data)
{

View File

@ -68,6 +68,9 @@ struct _GimpProcedureDialogPrivate
GtkSizeGroup *label_group;
GHashTable *sensitive_data;
gboolean fill_started;
gboolean fill_ended;
};
typedef struct GimpProcedureDialogSensitiveData
@ -89,49 +92,54 @@ typedef struct GimpProcedureDialogSensitiveData2
} GimpProcedureDialogSensitiveData2;
static GObject * gimp_procedure_dialog_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_properties);
static void gimp_procedure_dialog_constructed (GObject *object);
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 GObject * gimp_procedure_dialog_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_properties);
static void gimp_procedure_dialog_constructed (GObject *object);
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_real_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties);
static void gimp_procedure_dialog_real_fill_start (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config);
static void gimp_procedure_dialog_real_fill_end (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config);
static void gimp_procedure_dialog_real_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties);
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);
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);
static gboolean gimp_procedure_dialog_check_mnemonic (GimpProcedureDialog *dialog,
GtkWidget *widget,
const gchar *id,
const gchar *core_id);
static GtkWidget *
gimp_procedure_dialog_fill_container_list (GimpProcedureDialog *dialog,
const gchar *container_id,
GtkContainer *container,
GList *properties);
static gboolean gimp_procedure_dialog_check_mnemonic (GimpProcedureDialog *dialog,
GtkWidget *widget,
const gchar *id,
const gchar *core_id);
static GtkWidget * gimp_procedure_dialog_fill_container_list (GimpProcedureDialog *dialog,
const gchar *container_id,
GtkContainer *container,
GList *properties);
static void gimp_procedure_dialog_set_sensitive_if_in_cb (GObject *config,
GParamSpec *param_spec,
GimpProcedureDialogSensitiveData2 *data);
static void gimp_procedure_dialog_sensitive_data_free (GimpProcedureDialogSensitiveData *data);
static void gimp_procedure_dialog_sensitive_cb_data_free (GimpProcedureDialogSensitiveData2 *data);
static void gimp_procedure_dialog_set_sensitive_if_in_cb (GObject *config,
GParamSpec *param_spec,
GimpProcedureDialogSensitiveData2 *data);
static void gimp_procedure_dialog_sensitive_data_free (GimpProcedureDialogSensitiveData *data);
static void gimp_procedure_dialog_sensitive_cb_data_free (GimpProcedureDialogSensitiveData2 *data);
G_DEFINE_TYPE_WITH_PRIVATE (GimpProcedureDialog, gimp_procedure_dialog,
@ -153,6 +161,8 @@ gimp_procedure_dialog_class_init (GimpProcedureDialogClass *klass)
object_class->get_property = gimp_procedure_dialog_get_property;
object_class->set_property = gimp_procedure_dialog_set_property;
klass->fill_start = gimp_procedure_dialog_real_fill_start;
klass->fill_end = gimp_procedure_dialog_real_fill_end;
klass->fill_list = gimp_procedure_dialog_real_fill_list;
props[PROP_PROCEDURE] =
@ -195,6 +205,8 @@ gimp_procedure_dialog_init (GimpProcedureDialog *dialog)
dialog->priv->label_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
dialog->priv->sensitive_data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gimp_procedure_dialog_sensitive_data_free);
dialog->priv->fill_started = FALSE;
dialog->priv->fill_ended = FALSE;
}
static GObject *
@ -485,6 +497,20 @@ gimp_procedure_dialog_get_property (GObject *object,
}
}
static void
gimp_procedure_dialog_real_fill_start (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config)
{
}
static void
gimp_procedure_dialog_real_fill_end (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config)
{
}
static void
gimp_procedure_dialog_real_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
@ -1634,6 +1660,15 @@ gimp_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
{
gboolean free_properties = FALSE;
if (! dialog->priv->fill_started &&
GIMP_PROCEDURE_DIALOG_GET_CLASS (dialog)->fill_start)
{
GIMP_PROCEDURE_DIALOG_GET_CLASS (dialog)->fill_start (dialog,
dialog->priv->procedure,
dialog->priv->config);
dialog->priv->fill_started = TRUE;
}
if (! properties)
{
GParamSpec **pspecs;
@ -2508,6 +2543,24 @@ gimp_procedure_dialog_run (GimpProcedureDialog *dialog)
{
g_return_val_if_fail (GIMP_IS_PROCEDURE_DIALOG (dialog), FALSE);
if (! dialog->priv->fill_started &&
GIMP_PROCEDURE_DIALOG_GET_CLASS (dialog)->fill_start)
{
GIMP_PROCEDURE_DIALOG_GET_CLASS (dialog)->fill_start (dialog,
dialog->priv->procedure,
dialog->priv->config);
dialog->priv->fill_started = TRUE;
}
if (! dialog->priv->fill_ended &&
GIMP_PROCEDURE_DIALOG_GET_CLASS (dialog)->fill_end)
{
GIMP_PROCEDURE_DIALOG_GET_CLASS (dialog)->fill_end (dialog,
dialog->priv->procedure,
dialog->priv->config);
dialog->priv->fill_ended = TRUE;
}
while (TRUE)
{
gint response = gimp_dialog_run (GIMP_DIALOG (dialog));

View File

@ -52,10 +52,16 @@ struct _GimpProcedureDialogClass
{
GimpDialogClass parent_class;
void (* fill_list) (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties);
void (* fill_start) (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config);
void (* fill_end) (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config);
void (* fill_list) (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties);
/* Padding for future expansion */
void (*_gimp_reserved1) (void);

View File

@ -37,15 +37,16 @@ struct _GimpVectorLoadProcedureDialogPrivate
{
/* TODO: add thumbnail support from the file. */
GFile *file;
gboolean filled_once;
};
static void gimp_vector_load_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties);
static void gimp_vector_load_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties);
static void gimp_vector_load_procedure_dialog_fill_start (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config);
G_DEFINE_TYPE_WITH_PRIVATE (GimpVectorLoadProcedureDialog, gimp_vector_load_procedure_dialog, GIMP_TYPE_PROCEDURE_DIALOG)
@ -59,7 +60,8 @@ gimp_vector_load_procedure_dialog_class_init (GimpVectorLoadProcedureDialogClass
proc_dialog_class = GIMP_PROCEDURE_DIALOG_CLASS (klass);
proc_dialog_class->fill_list = gimp_vector_load_procedure_dialog_fill_list;
proc_dialog_class->fill_start = gimp_vector_load_procedure_dialog_fill_start;
proc_dialog_class->fill_list = gimp_vector_load_procedure_dialog_fill_list;
}
static void
@ -68,7 +70,27 @@ gimp_vector_load_procedure_dialog_init (GimpVectorLoadProcedureDialog *dialog)
dialog->priv = gimp_vector_load_procedure_dialog_get_instance_private (dialog);
dialog->priv->file = NULL;
dialog->priv->filled_once = FALSE;
}
static void
gimp_vector_load_procedure_dialog_fill_start (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config)
{
GtkWidget *content_area;
GtkWidget *res_entry;
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
/* Resolution */
res_entry = gimp_prop_resolution_entry_new (G_OBJECT (config),
"width", "height", "pixel-density",
"physical-unit");
gtk_box_pack_start (GTK_BOX (content_area), res_entry, FALSE, FALSE, 0);
gtk_widget_show (res_entry);
GIMP_PROCEDURE_DIALOG_CLASS (parent_class)->fill_start (dialog, procedure, config);
}
static void
@ -77,29 +99,27 @@ gimp_vector_load_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
GimpProcedureConfig *config,
GList *properties)
{
GimpVectorLoadProcedureDialog *load_dialog;
GList *properties2 = NULL;
GList *iter;
load_dialog = GIMP_VECTOR_LOAD_PROCEDURE_DIALOG (dialog);
if (! load_dialog->priv->filled_once)
for (iter = properties; iter; iter = iter->next)
{
GtkWidget *content_area;
GtkWidget *res_entry;
gchar *propname = iter->data;
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
if (g_strcmp0 (propname, "width") == 0 ||
g_strcmp0 (propname, "height") == 0 ||
g_strcmp0 (propname, "keep-ratio") == 0 ||
g_strcmp0 (propname, "prefer-native-dimensions") == 0 ||
g_strcmp0 (propname, "pixel-density") == 0 ||
g_strcmp0 (propname, "physical-unit") == 0)
/* Ignoring the standards args which are being handled by fill_start(). */
continue;
/* Resolution */
res_entry = gimp_prop_resolution_entry_new (G_OBJECT (config),
"width", "height", "pixel-density",
"physical-unit");
gtk_box_pack_start (GTK_BOX (content_area), res_entry, FALSE, FALSE, 0);
gtk_widget_show (res_entry);
load_dialog->priv->filled_once = TRUE;
properties2 = g_list_prepend (properties2, propname);
}
GIMP_PROCEDURE_DIALOG_CLASS (parent_class)->fill_list (dialog, procedure, config, properties);
properties2 = g_list_reverse (properties2);
GIMP_PROCEDURE_DIALOG_CLASS (parent_class)->fill_list (dialog, procedure, config, properties2);
g_list_free (properties2);
}