libgimp: new metadata support concept in GimpSaveProcedure and new…

… class GimpSaveProcedureDialog.
The idea is that we have basically the same code in most file format
plug-ins to handle various generic metadata, yet usually with slight
differences here and there. Even behavior is sometimes a bit different
even though there is no reason for the logics to be different from one
format to another.

So I move the metadata support logics into GimpSaveProcedure (and
GimpProcedureConfig still keeps the main export logics). The GUI logics
is now in a new GimpSaveProcedureDialog. So export plug-ins will now get
the creation of generic metadata nearly for free. All they have to do is
to tell what kind of metadata the GimpSaveProcedure supports with the
gimp_save_procedure_set_support_*() functions.

Then consistency will apply:
- If a format supports a given metadata, they will always have an
  auxiliary argument with the same name across plug-ins.
- The label and tooltips will also be always the same in the GUI.
- Order of metadata widgets will also stay consistent.
- The widgets will work the same (no more "Comment" text view missing in
  one plug-in but present in another, or with an entry here, and a text
  view there, and so on).

Also adding gimp_save_procedure_dialog_add_metadata() to allow plug-ins
to "declare" one of their options as a metadata option, and therefore
have it packed within the "Metadata" block which is now created (for
instance for PNG/TIFF/JPEG specific metadata). This allows a nicer
organization of dialogs.
This commit is contained in:
Jehan 2020-11-21 01:15:15 +01:00
parent ae4daf9465
commit 3918a0a04c
12 changed files with 1100 additions and 89 deletions

View file

@ -190,6 +190,7 @@ libgimpui_introspectable_headers = \
../libgimp/gimpproceduredialog.h \
../libgimp/gimpprocview.h \
../libgimp/gimpprogressbar.h \
../libgimp/gimpsaveproceduredialog.h \
../libgimp/gimpselectbutton.h \
../libgimp/gimpzoompreview.h
@ -209,6 +210,7 @@ libgimpui_introspectable = \
../libgimp/gimpprocbrowserdialog.c \
../libgimp/gimpproceduredialog.c \
../libgimp/gimpprocview.c \
../libgimp/gimpsaveproceduredialog.c \
../libgimp/gimpprogressbar.c \
../libgimp/gimpselectbutton.c \
../libgimp/gimpzoompreview.c

View file

@ -759,8 +759,20 @@ EXPORTS
gimp_progress_uninstall
gimp_progress_update
gimp_quit
gimp_save_procedure_get_support_comment
gimp_save_procedure_get_support_exif
gimp_save_procedure_get_support_iptc
gimp_save_procedure_get_support_profile
gimp_save_procedure_get_support_thumbnail
gimp_save_procedure_get_support_xmp
gimp_save_procedure_get_type
gimp_save_procedure_new
gimp_save_procedure_set_support_comment
gimp_save_procedure_set_support_exif
gimp_save_procedure_set_support_iptc
gimp_save_procedure_set_support_profile
gimp_save_procedure_set_support_thumbnail
gimp_save_procedure_set_support_xmp
gimp_selection_all
gimp_selection_border
gimp_selection_bounds

View file

@ -60,6 +60,7 @@ struct _GimpProcedureDialogPrivate
};
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,
@ -70,6 +71,11 @@ static void gimp_procedure_dialog_get_property (GObject *object,
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_reset_initial (GtkWidget *button,
GimpProcedureDialog *dialog);
static void gimp_procedure_dialog_reset_factory (GtkWidget *button,
@ -102,16 +108,20 @@ gimp_procedure_dialog_class_init (GimpProcedureDialogClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gimp_procedure_dialog_constructed;
object_class->dispose = gimp_procedure_dialog_dispose;
object_class->get_property = gimp_procedure_dialog_get_property;
object_class->set_property = gimp_procedure_dialog_set_property;
klass->fill_list = gimp_procedure_dialog_real_fill_list;
props[PROP_PROCEDURE] =
g_param_spec_object ("procedure",
"Procedure",
"The GimpProcedure this dialog is used with",
GIMP_TYPE_PROCEDURE,
GIMP_PARAM_READWRITE);
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
props[PROP_CONFIG] =
g_param_spec_object ("config",
@ -135,6 +145,86 @@ gimp_procedure_dialog_init (GimpProcedureDialog *dialog)
dialog->priv->label_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
}
static void
gimp_procedure_dialog_constructed (GObject *object)
{
GimpProcedureDialog *dialog;
GimpProcedure *procedure;
const gchar *ok_label;
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *content_area;
gchar *role;
G_OBJECT_CLASS (parent_class)->constructed (object);
dialog = GIMP_PROCEDURE_DIALOG (object);
procedure = dialog->priv->procedure;
role = g_strdup_printf ("gimp-%s", gimp_procedure_get_name (procedure));
g_object_set (object,
"role", role,
NULL);
g_free (role);
if (GIMP_IS_LOAD_PROCEDURE (procedure))
ok_label = _("_Open");
else if (GIMP_IS_SAVE_PROCEDURE (procedure))
ok_label = _("_Export");
else
ok_label = _("_OK");
button = gimp_dialog_add_button (GIMP_DIALOG (dialog),
_("_Reset"), RESPONSE_RESET);
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "reset");
button = gimp_dialog_add_button (GIMP_DIALOG (dialog),
_("_Cancel"), GTK_RESPONSE_CANCEL);
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "cancel");
button = gimp_dialog_add_button (GIMP_DIALOG (dialog),
ok_label, GTK_RESPONSE_OK);
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "ok");
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
RESPONSE_RESET,
GTK_RESPONSE_CANCEL,
-1);
gimp_window_set_transient (GTK_WINDOW (dialog));
/* Main content area. */
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_container_set_border_width (GTK_CONTAINER (content_area), 12);
gtk_box_set_spacing (GTK_BOX (content_area), 3);
/* Bottom box buttons with small additional padding. */
hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
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 (content_area), hbox, FALSE, FALSE, 0);
gtk_container_child_set (GTK_CONTAINER (content_area), hbox,
"padding", 3, NULL);
gtk_widget_show (hbox);
button = gtk_button_new_with_mnemonic (_("_Load Defaults"));
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "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"));
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "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);
}
static void
gimp_procedure_dialog_dispose (GObject *object)
{
@ -207,19 +297,43 @@ gimp_procedure_dialog_get_property (GObject *object,
}
}
static void
gimp_procedure_dialog_real_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties)
{
GtkWidget *content_area;
GList *iter;
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
for (iter = properties; iter; iter = iter->next)
{
GtkWidget *widget;
widget = gimp_procedure_dialog_get_widget (dialog, iter->data, G_TYPE_NONE);
if (widget)
{
/* Reference the widget because the hash table will
* unreference it anyway when getting destroyed so we don't
* want to give the only reference to the parent widget.
*/
g_object_ref (widget);
gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0);
gtk_widget_show (widget);
}
}
}
GtkWidget *
gimp_procedure_dialog_new (GimpProcedure *procedure,
GimpProcedureConfig *config,
const gchar *title)
{
GtkWidget *dialog;
gchar *role;
const gchar *help_id;
const gchar *ok_label;
gboolean use_header_bar;
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *content_area;
g_return_val_if_fail (GIMP_IS_PROCEDURE (procedure), NULL);
g_return_val_if_fail (GIMP_IS_PROCEDURE_CONFIG (config), NULL);
@ -227,8 +341,6 @@ gimp_procedure_dialog_new (GimpProcedure *procedure,
procedure, NULL);
g_return_val_if_fail (title != NULL, NULL);
role = g_strdup_printf ("gimp-%s", gimp_procedure_get_name (procedure));
help_id = gimp_procedure_get_help_id (procedure);
g_object_get (gtk_settings_get_default (),
@ -239,71 +351,11 @@ gimp_procedure_dialog_new (GimpProcedure *procedure,
"procedure", procedure,
"config", config,
"title", title,
"role", role,
"help-func", gimp_standard_help_func,
"help-id", help_id,
"use-header-bar", use_header_bar,
NULL);
g_free (role);
if (GIMP_IS_LOAD_PROCEDURE (procedure))
ok_label = _("_Open");
else if (GIMP_IS_SAVE_PROCEDURE (procedure))
ok_label = _("_Export");
else
ok_label = _("_OK");
button = gimp_dialog_add_button (GIMP_DIALOG (dialog),
_("_Reset"), RESPONSE_RESET);
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "reset");
button = gimp_dialog_add_button (GIMP_DIALOG (dialog),
_("_Cancel"), GTK_RESPONSE_CANCEL);
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "cancel");
button = gimp_dialog_add_button (GIMP_DIALOG (dialog),
ok_label, GTK_RESPONSE_OK);
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "ok");
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
RESPONSE_RESET,
GTK_RESPONSE_CANCEL,
-1);
gimp_window_set_transient (GTK_WINDOW (dialog));
/* Main content area. */
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_container_set_border_width (GTK_CONTAINER (content_area), 12);
gtk_box_set_spacing (GTK_BOX (content_area), 3);
/* Bottom box buttons with small additional padding. */
hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
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 (content_area), hbox, FALSE, FALSE, 0);
gtk_container_child_set (GTK_CONTAINER (content_area), hbox,
"padding", 3, NULL);
gtk_widget_show (hbox);
button = gtk_button_new_with_mnemonic (_("_Load Defaults"));
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "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"));
gimp_procedure_dialog_check_mnemonic (GIMP_PROCEDURE_DIALOG (dialog), button, NULL, "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);
}
@ -664,11 +716,7 @@ void
gimp_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
GList *properties)
{
GtkWidget *content_area;
GList *iter;
gboolean free_properties = FALSE;
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gboolean free_properties = FALSE;
if (! properties)
{
@ -698,22 +746,10 @@ gimp_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
free_properties = TRUE;
}
for (iter = properties; iter; iter = iter->next)
{
GtkWidget *widget;
widget = gimp_procedure_dialog_get_widget (dialog, iter->data, G_TYPE_NONE);
if (widget)
{
/* Reference the widget because the hash table will
* unreference it anyway when getting destroyed so we don't
* want to give the only reference to the parent widget.
*/
g_object_ref (widget);
gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0);
gtk_widget_show (widget);
}
}
GIMP_PROCEDURE_DIALOG_GET_CLASS (dialog)->fill_list (dialog,
dialog->priv->procedure,
dialog->priv->config,
properties);
if (free_properties)
g_list_free (properties);

View file

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

View file

@ -26,16 +26,43 @@
#include "gimppdb_pdb.h"
enum
{
PROP_0,
PROP_SUPPORTS_EXIF,
PROP_SUPPORTS_IPTC,
PROP_SUPPORTS_XMP,
PROP_SUPPORTS_PROFILE,
PROP_SUPPORTS_THUMBNAIL,
PROP_SUPPORTS_COMMENT,
N_PROPS
};
struct _GimpSaveProcedurePrivate
{
GimpRunSaveFunc run_func;
gpointer run_data;
GDestroyNotify run_data_destroy;
gboolean supports_exif;
gboolean supports_iptc;
gboolean supports_xmp;
gboolean supports_profile;
gboolean supports_thumbnail;
gboolean supports_comment;
};
static void gimp_save_procedure_constructed (GObject *object);
static void gimp_save_procedure_finalize (GObject *object);
static void gimp_save_procedure_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_save_procedure_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_save_procedure_install (GimpProcedure *procedure);
static GimpValueArray *
@ -46,12 +73,15 @@ static GimpProcedureConfig *
GParamSpec **args,
gint n_args);
static void gimp_save_procedure_add_metadata (GimpSaveProcedure *save_procedure);
G_DEFINE_TYPE_WITH_PRIVATE (GimpSaveProcedure, gimp_save_procedure,
GIMP_TYPE_FILE_PROCEDURE)
#define parent_class gimp_save_procedure_parent_class
static GParamSpec *props[N_PROPS] = { NULL, };
static void
gimp_save_procedure_class_init (GimpSaveProcedureClass *klass)
@ -61,10 +91,93 @@ gimp_save_procedure_class_init (GimpSaveProcedureClass *klass)
object_class->constructed = gimp_save_procedure_constructed;
object_class->finalize = gimp_save_procedure_finalize;
object_class->get_property = gimp_save_procedure_get_property;
object_class->set_property = gimp_save_procedure_set_property;
procedure_class->install = gimp_save_procedure_install;
procedure_class->run = gimp_save_procedure_run;
procedure_class->create_config = gimp_save_procedure_create_config;
/**
* GimpSaveProcedure:exif:
*
* Whether the save procedure supports EXIF.
*
* Since: 3.0.0
*/
props[PROP_SUPPORTS_EXIF] = g_param_spec_boolean ("supports-exif",
"Supports EXIF metadata storage",
NULL,
FALSE,
G_PARAM_CONSTRUCT |
GIMP_PARAM_READWRITE);
/**
* GimpSaveProcedure:iptc:
*
* Whether the save procedure supports IPTC.
*
* Since: 3.0.0
*/
props[PROP_SUPPORTS_IPTC] = g_param_spec_boolean ("supports-iptc",
"Supports IPTC metadata storage",
NULL,
FALSE,
G_PARAM_CONSTRUCT |
GIMP_PARAM_READWRITE);
/**
* GimpSaveProcedure:xmpp:
*
* Whether the save procedure supports XMP.
*
* Since: 3.0.0
*/
props[PROP_SUPPORTS_XMP] = g_param_spec_boolean ("supports-xmp",
"Supports XMP metadata storage",
NULL,
FALSE,
G_PARAM_CONSTRUCT |
GIMP_PARAM_READWRITE);
/**
* GimpSaveProcedure:profile:
*
* Whether the save procedure supports ICC color profiles.
*
* Since: 3.0.0
*/
props[PROP_SUPPORTS_PROFILE] = g_param_spec_boolean ("supports-profile",
"Supports color profile storage",
NULL,
FALSE,
G_PARAM_CONSTRUCT |
GIMP_PARAM_READWRITE);
/**
* GimpSaveProcedure:thumbnail:
*
* Whether the save procedure supports storing a thumbnail.
*
* Since: 3.0.0
*/
props[PROP_SUPPORTS_THUMBNAIL] = g_param_spec_boolean ("supports-thumbnail",
"Supports thumbnail storage",
NULL,
FALSE,
G_PARAM_CONSTRUCT |
GIMP_PARAM_READWRITE);
/**
* GimpSaveProcedure:comment:
*
* Whether the save procedure supports storing a comment.
*
* Since: 3.0.0
*/
props[PROP_SUPPORTS_COMMENT] = g_param_spec_boolean ("supports-comment",
"Supports comment storage",
NULL,
FALSE,
G_PARAM_CONSTRUCT |
GIMP_PARAM_READWRITE);
g_object_class_install_properties (object_class, N_PROPS, props);
}
static void
@ -115,6 +228,76 @@ gimp_save_procedure_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_save_procedure_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpSaveProcedure *procedure = GIMP_SAVE_PROCEDURE (object);
switch (property_id)
{
case PROP_SUPPORTS_EXIF:
procedure->priv->supports_exif = g_value_get_boolean (value);
break;
case PROP_SUPPORTS_IPTC:
procedure->priv->supports_iptc = g_value_get_boolean (value);
break;
case PROP_SUPPORTS_XMP:
procedure->priv->supports_xmp = g_value_get_boolean (value);
break;
case PROP_SUPPORTS_PROFILE:
procedure->priv->supports_profile = g_value_get_boolean (value);
break;
case PROP_SUPPORTS_THUMBNAIL:
procedure->priv->supports_thumbnail = g_value_get_boolean (value);
break;
case PROP_SUPPORTS_COMMENT:
procedure->priv->supports_comment = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_save_procedure_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpSaveProcedure *procedure = GIMP_SAVE_PROCEDURE (object);
switch (property_id)
{
case PROP_SUPPORTS_EXIF:
g_value_set_boolean (value, procedure->priv->supports_exif);
break;
case PROP_SUPPORTS_IPTC:
g_value_set_boolean (value, procedure->priv->supports_iptc);
break;
case PROP_SUPPORTS_XMP:
g_value_set_boolean (value, procedure->priv->supports_xmp);
break;
case PROP_SUPPORTS_PROFILE:
g_value_set_boolean (value, procedure->priv->supports_profile);
break;
case PROP_SUPPORTS_THUMBNAIL:
g_value_set_boolean (value, procedure->priv->supports_thumbnail);
break;
case PROP_SUPPORTS_COMMENT:
g_value_set_boolean (value, procedure->priv->supports_comment);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_save_procedure_install (GimpProcedure *procedure)
{
@ -122,6 +305,7 @@ gimp_save_procedure_install (GimpProcedure *procedure)
const gchar *mime_types;
gint priority;
gimp_save_procedure_add_metadata (GIMP_SAVE_PROCEDURE (procedure));
GIMP_PROCEDURE_CLASS (parent_class)->install (procedure);
_gimp_pdb_set_file_proc_save_handler (gimp_procedure_get_name (procedure),
@ -191,6 +375,8 @@ gimp_save_procedure_create_config (GimpProcedure *procedure,
GParamSpec **args,
gint n_args)
{
gimp_save_procedure_add_metadata (GIMP_SAVE_PROCEDURE (procedure));
if (n_args > ARG_OFFSET)
{
args += ARG_OFFSET;
@ -207,6 +393,60 @@ gimp_save_procedure_create_config (GimpProcedure *procedure,
n_args);
}
static void
gimp_save_procedure_add_metadata (GimpSaveProcedure *save_procedure)
{
GimpProcedure *procedure = GIMP_PROCEDURE (save_procedure);
if (save_procedure->priv->supports_exif)
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-exif",
"Save Exif",
"Save Exif (Exchangeable image file format) metadata",
gimp_export_exif (),
G_PARAM_READWRITE);
if (save_procedure->priv->supports_iptc)
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-iptc",
"Save IPTC",
"Save IPTC (International Press Telecommunications Council) metadata",
gimp_export_iptc (),
G_PARAM_READWRITE);
if (save_procedure->priv->supports_xmp)
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-xmp",
"Save XMP",
"Save XMP (Extensible Metadata Platform) metadata",
gimp_export_xmp (),
G_PARAM_READWRITE);
if (save_procedure->priv->supports_profile)
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-color-profile",
"Save color profile",
"Save the ICC color profile as metadata",
gimp_export_color_profile (),
G_PARAM_READWRITE);
if (save_procedure->priv->supports_thumbnail)
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-thumbnail",
"Save thumbnail",
"Save a smaller representation of the image as metadata",
TRUE,
G_PARAM_READWRITE);
if (save_procedure->priv->supports_comment)
{
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-comment",
"Save comment",
"Save a comment as metadata",
gimp_export_comment (),
G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_STRING (procedure, "gimp-comment",
"Comment",
"Image comment",
gimp_get_default_comment (),
G_PARAM_READWRITE);
gimp_procedure_set_argument_sync (procedure, "gimp-comment",
GIMP_ARGUMENT_SYNC_PARASITE);
}
}
/* public functions */
@ -271,3 +511,317 @@ gimp_save_procedure_new (GimpPlugIn *plug_in,
return GIMP_PROCEDURE (procedure);
}
/**
* gimp_save_procedure_set_support_exif:
* @procedure: a #GimpProcedure.
* @supports: whether Exif metadata are supported.
*
* Determine whether @procedure supports saving Exif data. By default,
* it won't (so there is usually no reason to run this function with
* %FALSE).
* This will have several consequence:
* - Automatically adds a standard auxiliary argument "save-exif" in the
* end of the argument list of @procedure, with relevant blurb and
* description.
* - If used with other gimp_save_procedure_set_support_*() functions,
* they will always be ordered the same (the order of the calls don't
* matter), keeping all save procedures consistent.
* - Generated GimpSaveProcedureDialog will contain the metadata
* options, once again always in the same order and with consistent
* GUI style across plug-ins.
* - API from #GimpProcedureConfig will automatically process these
* properties to decide whether to save a given metadata or not.
*
* Note that since this is an auxiliary argument, it won't be part of
* the PDB arguments. By default, the value will be gimp_export_exif().
* Since: 3.0
**/
void
gimp_save_procedure_set_support_exif (GimpSaveProcedure *procedure,
gboolean supports)
{
g_return_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure));
g_object_set (procedure,
"supports-exif", supports,
NULL);
}
/**
* gimp_save_procedure_set_support_iptc:
* @procedure: a #GimpProcedure.
* @supports: whether IPTC metadata are supported.
*
* Determine whether @procedure supports saving IPTC data. By default,
* it won't (so there is usually no reason to run this function with
* %FALSE).
* This will have several consequence:
* - Automatically adds a standard auxiliary argument "save-iptc" in the
* end of the argument list of @procedure, with relevant blurb and
* description.
* - If used with other gimp_save_procedure_set_support_*() functions,
* they will always be ordered the same (the order of the calls don't
* matter), keeping all save procedures consistent.
* - Generated GimpSaveProcedureDialog will contain the metadata
* options, once again always in the same order and with consistent
* GUI style across plug-ins.
* - API from #GimpProcedureConfig will automatically process these
* properties to decide whether to save a given metadata or not.
*
* Note that since this is an auxiliary argument, it won't be part of
* the PDB arguments. By default, the value will be gimp_export_iptc().
* Since: 3.0
**/
void
gimp_save_procedure_set_support_iptc (GimpSaveProcedure *procedure,
gboolean supports)
{
g_return_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure));
g_object_set (procedure,
"supports-iptc", supports,
NULL);
}
/**
* gimp_save_procedure_set_support_xmp:
* @procedure: a #GimpProcedure.
* @supports: whether XMP metadata are supported.
*
* Determine whether @procedure supports saving XMP data. By default,
* it won't (so there is usually no reason to run this function with
* %FALSE).
* This will have several consequence:
* - Automatically adds a standard auxiliary argument "save-xmp" in the
* end of the argument list of @procedure, with relevant blurb and
* description.
* - If used with other gimp_save_procedure_set_support_*() functions,
* they will always be ordered the same (the order of the calls don't
* matter), keeping all save procedures consistent.
* - Generated GimpSaveProcedureDialog will contain the metadata
* options, once again always in the same order and with consistent
* GUI style across plug-ins.
* - API from #GimpProcedureConfig will automatically process these
* properties to decide whether to save a given metadata or not.
*
* Note that since this is an auxiliary argument, it won't be part of
* the PDB arguments. By default, the value will be gimp_export_xmp().
* Since: 3.0
**/
void
gimp_save_procedure_set_support_xmp (GimpSaveProcedure *procedure,
gboolean supports)
{
g_return_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure));
g_object_set (procedure,
"supports-xmp", supports,
NULL);
}
/**
* gimp_save_procedure_set_support_profile:
* @procedure: a #GimpProcedure.
* @supports: whether color profiles can be stored.
*
* Determine whether @procedure supports saving ICC color profiles. By
* default, it won't (so there is usually no reason to run this function
* with %FALSE).
* This will have several consequence:
* - Automatically adds a standard auxiliary argument
* "save-color-profile" in the end of the argument list of @procedure,
* with relevant blurb and description.
* - If used with other gimp_save_procedure_set_support_*() functions,
* they will always be ordered the same (the order of the calls don't
* matter), keeping all save procedures consistent.
* - Generated GimpSaveProcedureDialog will contain the metadata
* options, once again always in the same order and with consistent
* GUI style across plug-ins.
* - API from #GimpProcedureConfig will automatically process these
* properties to decide whether to save a given metadata or not.
*
* Note that since this is an auxiliary argument, it won't be part of
* the PDB arguments. By default, the value will be
* gimp_export_color_profile().
* Since: 3.0
**/
void
gimp_save_procedure_set_support_profile (GimpSaveProcedure *procedure,
gboolean supports)
{
g_return_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure));
g_object_set (procedure,
"supports-profile", supports,
NULL);
}
/**
* gimp_save_procedure_set_support_thumbnail:
* @procedure: a #GimpProcedure.
* @supports: whether a thumbnail can be stored.
*
* Determine whether @procedure supports saving a thumbnail. By default,
* it won't (so there is usually no reason to run this function with
* %FALSE).
* This will have several consequence:
* - Automatically adds a standard auxiliary argument "save-thumbnail"
* in the end of the argument list of @procedure, with relevant blurb
* and description.
* - If used with other gimp_save_procedure_set_support_*() functions,
* they will always be ordered the same (the order of the calls don't
* matter), keeping all save procedures consistent.
* - Generated GimpSaveProcedureDialog will contain the metadata
* options, once again always in the same order and with consistent
* GUI style across plug-ins.
* - API from #GimpProcedureConfig will automatically process these
* properties to decide whether to save a given metadata or not.
*
* Note that since this is an auxiliary argument, it won't be part of
* the PDB arguments. By default, the value will be %TRUE.
* Since: 3.0
**/
void
gimp_save_procedure_set_support_thumbnail (GimpSaveProcedure *procedure,
gboolean supports)
{
g_return_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure));
g_object_set (procedure,
"supports-thumbnail", supports,
NULL);
}
/**
* gimp_save_procedure_set_support_comment:
* @procedure: a #GimpProcedure.
* @supports: whether a comment can be stored.
*
* Determine whether @procedure supports saving a comment. By default,
* it won't (so there is usually no reason to run this function with
* %FALSE).
* This will have several consequence:
* - Automatically adds a standard auxiliary argument "save-comment"
* in the end of the argument list of @procedure, with relevant blurb
* and description.
* - If used with other gimp_save_procedure_set_support_*() functions,
* they will always be ordered the same (the order of the calls don't
* matter), keeping all save procedures consistent.
* - Generated GimpSaveProcedureDialog will contain the metadata
* options, once again always in the same order and with consistent
* GUI style across plug-ins.
* - API from #GimpProcedureConfig will automatically process these
* properties to decide whether to save a given metadata or not.
*
* Note that since this is an auxiliary argument, it won't be part of
* the PDB arguments. By default, the value will be
* gimp_export_comment().
* Since: 3.0
**/
void
gimp_save_procedure_set_support_comment (GimpSaveProcedure *procedure,
gboolean supports)
{
g_return_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure));
g_object_set (procedure,
"supports-comment", supports,
NULL);
}
/**
* gimp_save_procedure_get_support_exif:
* @procedure: a #GimpProcedure.
*
* Returns: %TRUE if @procedure supports Exif saving.
*
* Since: 3.0
**/
gboolean
gimp_save_procedure_get_support_exif (GimpSaveProcedure *procedure)
{
g_return_val_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure), FALSE);
return procedure->priv->supports_exif;
}
/**
* gimp_save_procedure_get_support_iptc:
* @procedure: a #GimpProcedure.
*
* Returns: %TRUE if @procedure supports IPTC saving.
*
* Since: 3.0
**/
gboolean
gimp_save_procedure_get_support_iptc (GimpSaveProcedure *procedure)
{
g_return_val_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure), FALSE);
return procedure->priv->supports_iptc;
}
/**
* gimp_save_procedure_get_support_xmp:
* @procedure: a #GimpProcedure.
*
* Returns: %TRUE if @procedure supports XMP saving.
*
* Since: 3.0
**/
gboolean
gimp_save_procedure_get_support_xmp (GimpSaveProcedure *procedure)
{
g_return_val_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure), FALSE);
return procedure->priv->supports_xmp;
}
/**
* gimp_save_procedure_get_support_profile:
* @procedure: a #GimpProcedure.
*
* Returns: %TRUE if @procedure supports ICC color profile saving.
*
* Since: 3.0
**/
gboolean
gimp_save_procedure_get_support_profile (GimpSaveProcedure *procedure)
{
g_return_val_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure), FALSE);
return procedure->priv->supports_profile;
}
/**
* gimp_save_procedure_get_support_thumbnail:
* @procedure: a #GimpProcedure.
*
* Returns: %TRUE if @procedure supports thumbnail saving.
*
* Since: 3.0
**/
gboolean
gimp_save_procedure_get_support_thumbnail (GimpSaveProcedure *procedure)
{
g_return_val_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure), FALSE);
return procedure->priv->supports_thumbnail;
}
/**
* gimp_save_procedure_get_support_comment:
* @procedure: a #GimpProcedure.
*
* Returns: %TRUE if @procedure supports comment saving.
*
* Since: 3.0
**/
gboolean
gimp_save_procedure_get_support_comment (GimpSaveProcedure *procedure)
{
g_return_val_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure), FALSE);
return procedure->priv->supports_comment;
}

View file

@ -91,6 +91,26 @@ GimpProcedure * gimp_save_procedure_new (GimpPlugIn *plug_in,
gpointer run_data,
GDestroyNotify run_data_destroy);
void gimp_save_procedure_set_support_exif (GimpSaveProcedure *procedure,
gboolean supports);
void gimp_save_procedure_set_support_iptc (GimpSaveProcedure *procedure,
gboolean supports);
void gimp_save_procedure_set_support_xmp (GimpSaveProcedure *procedure,
gboolean supports);
void gimp_save_procedure_set_support_profile (GimpSaveProcedure *procedure,
gboolean supports);
void gimp_save_procedure_set_support_thumbnail (GimpSaveProcedure *procedure,
gboolean supports);
void gimp_save_procedure_set_support_comment (GimpSaveProcedure *procedure,
gboolean supports);
gboolean gimp_save_procedure_get_support_exif (GimpSaveProcedure *procedure);
gboolean gimp_save_procedure_get_support_iptc (GimpSaveProcedure *procedure);
gboolean gimp_save_procedure_get_support_xmp (GimpSaveProcedure *procedure);
gboolean gimp_save_procedure_get_support_profile (GimpSaveProcedure *procedure);
gboolean gimp_save_procedure_get_support_thumbnail (GimpSaveProcedure *procedure);
gboolean gimp_save_procedure_get_support_comment (GimpSaveProcedure *procedure);
G_END_DECLS

View file

@ -0,0 +1,296 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpsaveproceduredialog.c
* Copyright (C) 2020 Jehan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "gimp.h"
#include "gimpui.h"
#include "libgimp-intl.h"
struct _GimpSaveProcedureDialogPrivate
{
GList *additional_metadata;
};
static void gimp_save_procedure_dialog_dispose (GObject *object);
static void gimp_save_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties);
G_DEFINE_TYPE_WITH_PRIVATE (GimpSaveProcedureDialog, gimp_save_procedure_dialog, GIMP_TYPE_PROCEDURE_DIALOG)
#define parent_class gimp_save_procedure_dialog_parent_class
static void
gimp_save_procedure_dialog_class_init (GimpSaveProcedureDialogClass *klass)
{
GObjectClass *object_class;
GimpProcedureDialogClass *proc_dialog_class;
object_class = G_OBJECT_CLASS (klass);
proc_dialog_class = GIMP_PROCEDURE_DIALOG_CLASS (klass);
object_class->dispose = gimp_save_procedure_dialog_dispose;
proc_dialog_class->fill_list = gimp_save_procedure_dialog_fill_list;
}
static void
gimp_save_procedure_dialog_init (GimpSaveProcedureDialog *dialog)
{
dialog->priv = gimp_save_procedure_dialog_get_instance_private (dialog);
dialog->priv->additional_metadata = NULL;
}
static void
gimp_save_procedure_dialog_dispose (GObject *object)
{
GimpSaveProcedureDialog *dialog = GIMP_SAVE_PROCEDURE_DIALOG (object);
g_list_free_full (dialog->priv->additional_metadata, g_free);
dialog->priv->additional_metadata = NULL;
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gimp_save_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GList *properties)
{
GimpSaveProcedureDialog *save_dialog;
GimpSaveProcedure *save_procedure;
GtkWidget *content_area;
GList *properties2 = NULL;
GList *iter;
gint n_checkboxes;
save_dialog = GIMP_SAVE_PROCEDURE_DIALOG (dialog);
save_procedure = GIMP_SAVE_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_save_procedure_get_support_exif (save_procedure) &&
g_strcmp0 (propname, "save-exif") == 0) ||
(gimp_save_procedure_get_support_iptc (save_procedure) &&
g_strcmp0 (propname, "save-iptc") == 0) ||
(gimp_save_procedure_get_support_xmp (save_procedure) &&
g_strcmp0 (propname, "save-xmp") == 0) ||
(gimp_save_procedure_get_support_profile (save_procedure) &&
g_strcmp0 (propname, "save-color-profile") == 0) ||
(gimp_save_procedure_get_support_thumbnail (save_procedure) &&
g_strcmp0 (propname, "save-thumbnail") == 0) ||
(gimp_save_procedure_get_support_comment (save_procedure) &&
(g_strcmp0 (propname, "save-comment") == 0 ||
g_strcmp0 (propname, "gimp-comment") == 0)) ||
g_list_find (save_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);
n_checkboxes = gimp_save_procedure_get_support_exif (save_procedure) +
gimp_save_procedure_get_support_iptc (save_procedure) +
gimp_save_procedure_get_support_xmp (save_procedure) +
gimp_save_procedure_get_support_profile (save_procedure) +
gimp_save_procedure_get_support_thumbnail (save_procedure);
if (n_checkboxes != 0 ||
g_list_length (save_dialog->priv->additional_metadata) > 0 ||
gimp_save_procedure_get_support_comment (save_procedure))
{
GtkWidget *frame;
GtkWidget *box;
GtkWidget *flowbox;
GtkWidget *widget;
frame = gimp_frame_new (_("Metadata"));
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
gtk_container_add (GTK_CONTAINER (frame), box);
gtk_widget_show (box);
flowbox = gtk_flow_box_new ();
if (n_checkboxes + g_list_length (save_dialog->priv->additional_metadata) > 3)
{
gtk_flow_box_set_min_children_per_line (GTK_FLOW_BOX (flowbox), 2);
gtk_flow_box_set_max_children_per_line (GTK_FLOW_BOX (flowbox), 2);
}
gtk_box_pack_start (GTK_BOX (box), flowbox, TRUE, TRUE, 0);
gtk_widget_show (flowbox);
if (gimp_save_procedure_get_support_exif (save_procedure))
{
widget = gimp_prop_check_button_new (G_OBJECT (config),
"save-exif", NULL);
gtk_container_add (GTK_CONTAINER (flowbox), widget);
gtk_widget_show (widget);
}
if (gimp_save_procedure_get_support_iptc (save_procedure))
{
widget = gimp_prop_check_button_new (G_OBJECT (config),
"save-iptc", NULL);
gtk_container_add (GTK_CONTAINER (flowbox), widget);
gtk_widget_show (widget);
}
if (gimp_save_procedure_get_support_xmp (save_procedure))
{
widget = gimp_prop_check_button_new (G_OBJECT (config),
"save-xmp", NULL);
gtk_container_add (GTK_CONTAINER (flowbox), widget);
gtk_widget_show (widget);
}
if (gimp_save_procedure_get_support_profile (save_procedure))
{
widget = gimp_prop_check_button_new (G_OBJECT (config),
"save-color-profile", NULL);
gtk_container_add (GTK_CONTAINER (flowbox), widget);
gtk_widget_show (widget);
}
if (gimp_save_procedure_get_support_thumbnail (save_procedure))
{
widget = gimp_prop_check_button_new (G_OBJECT (config),
"save-thumbnail", NULL);
gtk_container_add (GTK_CONTAINER (flowbox), widget);
gtk_widget_show (widget);
}
for (iter = save_dialog->priv->additional_metadata; iter; iter = iter->next)
{
widget = gimp_procedure_dialog_get_widget (dialog, iter->data, G_TYPE_NONE);
g_object_ref (widget);
gtk_container_add (GTK_CONTAINER (flowbox), widget);
gtk_widget_show (widget);
}
if (gimp_save_procedure_get_support_comment (save_procedure))
{
GtkTextBuffer *buffer;
const gchar *tooltip;
GtkWidget *frame2;
GtkWidget *title;
GParamSpec *pspec;
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
"gimp-comment");
frame2 = gimp_frame_new (NULL);
title = gimp_prop_check_button_new (G_OBJECT (config),
"save-comment", NULL);
gtk_frame_set_label_widget (GTK_FRAME (frame2), title);
gtk_widget_show (title);
buffer = gimp_prop_text_buffer_new (G_OBJECT (config),
"gimp-comment", -1);
widget = gtk_text_view_new_with_buffer (buffer);
gtk_text_view_set_top_margin (GTK_TEXT_VIEW (widget), 3);
gtk_text_view_set_bottom_margin (GTK_TEXT_VIEW (widget), 3);
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (widget), 3);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (widget), 3);
g_object_unref (buffer);
tooltip = g_param_spec_get_blurb (pspec);
if (tooltip)
gimp_help_set_help_data (widget, tooltip, NULL);
gtk_widget_set_hexpand (widget, TRUE);
gtk_widget_set_vexpand (widget, TRUE);
gtk_container_add (GTK_CONTAINER (frame2), widget);
gtk_widget_show (widget);
/* Why do I put the text view inside a flowbox? This is a
* bit ugly as this is only to allow the text view title
* checkbox to be aligned with other checkboxes while
* still taking double the width. Probably should have I
* gone with a GtkGrid on this one.
*/
flowbox = gtk_flow_box_new ();
gtk_flow_box_set_min_children_per_line (GTK_FLOW_BOX (flowbox), 1);
gtk_flow_box_set_max_children_per_line (GTK_FLOW_BOX (flowbox), 1);
gtk_box_pack_start (GTK_BOX (box), flowbox, TRUE, TRUE, 0);
gtk_widget_show (flowbox);
gtk_container_add (GTK_CONTAINER (flowbox), frame2);
gtk_widget_show (frame2);
}
gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
}
}
GtkWidget *
gimp_save_procedure_dialog_new (GimpSaveProcedure *procedure,
GimpProcedureConfig *config,
const gchar *title)
{
GtkWidget *dialog;
const gchar *help_id;
gboolean use_header_bar;
g_return_val_if_fail (GIMP_IS_SAVE_PROCEDURE (procedure), NULL);
g_return_val_if_fail (GIMP_IS_PROCEDURE_CONFIG (config), NULL);
g_return_val_if_fail (gimp_procedure_config_get_procedure (config) ==
GIMP_PROCEDURE (procedure), NULL);
g_return_val_if_fail (title != NULL, NULL);
help_id = gimp_procedure_get_help_id (GIMP_PROCEDURE (procedure));
g_object_get (gtk_settings_get_default (),
"gtk-dialogs-use-header", &use_header_bar,
NULL);
dialog = g_object_new (GIMP_TYPE_SAVE_PROCEDURE_DIALOG,
"procedure", procedure,
"config", config,
"title", title,
"help-func", gimp_standard_help_func,
"help-id", help_id,
"use-header-bar", use_header_bar,
NULL);
return dialog;
}
void
gimp_save_procedure_dialog_add_metadata (GimpSaveProcedureDialog *dialog,
const gchar *property)
{
if (! g_list_find (dialog->priv->additional_metadata, property))
dialog->priv->additional_metadata = g_list_append (dialog->priv->additional_metadata,
g_strdup (property));
}

View file

@ -0,0 +1,79 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpsaveproceduredialog.h
* Copyright (C) 2020 Jehan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimpui.h> can be included directly."
#endif
#ifndef __GIMP_SAVE_PROCEDURE_DIALOG_H__
#define __GIMP_SAVE_PROCEDURE_DIALOG_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
#define GIMP_TYPE_SAVE_PROCEDURE_DIALOG (gimp_save_procedure_dialog_get_type ())
#define GIMP_SAVE_PROCEDURE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SAVE_PROCEDURE_DIALOG, GimpSaveProcedureDialog))
#define GIMP_SAVE_PROCEDURE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SAVE_PROCEDURE_DIALOG, GimpSaveProcedureDialogClass))
#define GIMP_IS_SAVE_PROCEDURE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SAVE_PROCEDURE_DIALOG))
#define GIMP_IS_SAVE_PROCEDURE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SAVE_PROCEDURE_DIALOG))
#define GIMP_SAVE_PROCEDURE_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SAVE_PROCEDURE_DIALOG, GimpSaveProcedureDialogClass))
typedef struct _GimpSaveProcedureDialogClass GimpSaveProcedureDialogClass;
typedef struct _GimpSaveProcedureDialogPrivate GimpSaveProcedureDialogPrivate;
struct _GimpSaveProcedureDialog
{
GimpProcedureDialog parent_instance;
GimpSaveProcedureDialogPrivate *priv;
};
struct _GimpSaveProcedureDialogClass
{
GimpProcedureDialogClass parent_class;
/* Padding for future expansion */
void (*_gimp_reserved1) (void);
void (*_gimp_reserved2) (void);
void (*_gimp_reserved3) (void);
void (*_gimp_reserved4) (void);
void (*_gimp_reserved5) (void);
void (*_gimp_reserved6) (void);
void (*_gimp_reserved7) (void);
void (*_gimp_reserved8) (void);
};
GType gimp_save_procedure_dialog_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_save_procedure_dialog_new (GimpSaveProcedure *procedure,
GimpProcedureConfig *config,
const gchar *title);
void gimp_save_procedure_dialog_add_metadata (GimpSaveProcedureDialog *dialog,
const gchar *property);
G_END_DECLS
#endif /* __GIMP_SAVE_PROCEDURE_DIALOG_H__ */

View file

@ -52,6 +52,9 @@ EXPORTS
gimp_procedure_dialog_run
gimp_progress_bar_get_type
gimp_progress_bar_new
gimp_save_procedure_dialog_add_metadata
gimp_save_procedure_dialog_get_type
gimp_save_procedure_dialog_new
gimp_select_button_close_popup
gimp_select_button_get_type
gimp_ui_get_display_window

View file

@ -43,6 +43,7 @@
#include <libgimp/gimpproceduredialog.h>
#include <libgimp/gimpprocview.h>
#include <libgimp/gimpprogressbar.h>
#include <libgimp/gimpsaveproceduredialog.h>
#include <libgimp/gimpselectbutton.h>
#include <libgimp/gimpzoompreview.h>

View file

@ -29,6 +29,7 @@ G_BEGIN_DECLS
typedef struct _GimpProcedureDialog GimpProcedureDialog;
typedef struct _GimpSaveProcedureDialog GimpSaveProcedureDialog;
typedef struct _GimpAspectPreview GimpAspectPreview;
typedef struct _GimpDrawablePreview GimpDrawablePreview;

View file

@ -242,6 +242,7 @@ libgimpui_sources_introspectable = [
'gimpproceduredialog.c',
'gimpprocview.c',
'gimpprogressbar.c',
'gimpsaveproceduredialog.c',
'gimpselectbutton.c',
'gimpui.c',
'gimpzoompreview.c',
@ -272,6 +273,7 @@ libgimpui_headers_introspectable = [
'gimpproceduredialog.h',
'gimpprocview.h',
'gimpprogressbar.h',
'gimpsaveproceduredialog.h',
'gimpselectbutton.h',
'gimpzoompreview.h',
]