diff --git a/libgimp/Makefile.gi b/libgimp/Makefile.gi index 2cf4510561..7e25a01dab 100644 --- a/libgimp/Makefile.gi +++ b/libgimp/Makefile.gi @@ -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 diff --git a/libgimp/gimp.def b/libgimp/gimp.def index 4a01a64880..32fa15e3bb 100644 --- a/libgimp/gimp.def +++ b/libgimp/gimp.def @@ -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 diff --git a/libgimp/gimpproceduredialog.c b/libgimp/gimpproceduredialog.c index c91f4a139e..47e292482c 100644 --- a/libgimp/gimpproceduredialog.c +++ b/libgimp/gimpproceduredialog.c @@ -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); diff --git a/libgimp/gimpproceduredialog.h b/libgimp/gimpproceduredialog.h index 95497faf9c..8825f93d7c 100644 --- a/libgimp/gimpproceduredialog.h +++ b/libgimp/gimpproceduredialog.h @@ -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); diff --git a/libgimp/gimpsaveprocedure.c b/libgimp/gimpsaveprocedure.c index c2032ab96b..8443949997 100644 --- a/libgimp/gimpsaveprocedure.c +++ b/libgimp/gimpsaveprocedure.c @@ -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; +} diff --git a/libgimp/gimpsaveprocedure.h b/libgimp/gimpsaveprocedure.h index c15c0b82cb..40d3a4cfbd 100644 --- a/libgimp/gimpsaveprocedure.h +++ b/libgimp/gimpsaveprocedure.h @@ -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 diff --git a/libgimp/gimpsaveproceduredialog.c b/libgimp/gimpsaveproceduredialog.c new file mode 100644 index 0000000000..efec13ef66 --- /dev/null +++ b/libgimp/gimpsaveproceduredialog.c @@ -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 . + */ + +#include "config.h" + +#include +#include + +#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)); +} diff --git a/libgimp/gimpsaveproceduredialog.h b/libgimp/gimpsaveproceduredialog.h new file mode 100644 index 0000000000..e97b4111f3 --- /dev/null +++ b/libgimp/gimpsaveproceduredialog.h @@ -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 . + */ + +#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION) +#error "Only 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__ */ diff --git a/libgimp/gimpui.def b/libgimp/gimpui.def index 8410deb48c..e61530fc74 100644 --- a/libgimp/gimpui.def +++ b/libgimp/gimpui.def @@ -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 diff --git a/libgimp/gimpui.h b/libgimp/gimpui.h index ab53ca5f26..83789509cb 100644 --- a/libgimp/gimpui.h +++ b/libgimp/gimpui.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include diff --git a/libgimp/gimpuitypes.h b/libgimp/gimpuitypes.h index aa168d760a..e361b6f7ee 100644 --- a/libgimp/gimpuitypes.h +++ b/libgimp/gimpuitypes.h @@ -29,6 +29,7 @@ G_BEGIN_DECLS typedef struct _GimpProcedureDialog GimpProcedureDialog; +typedef struct _GimpSaveProcedureDialog GimpSaveProcedureDialog; typedef struct _GimpAspectPreview GimpAspectPreview; typedef struct _GimpDrawablePreview GimpDrawablePreview; diff --git a/libgimp/meson.build b/libgimp/meson.build index 2126649c9b..9e7b4fbbe3 100644 --- a/libgimp/meson.build +++ b/libgimp/meson.build @@ -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', ]