libgimp, plug-ins: add an "(edit)" link next to "Metadata" frame in…
… GimpSaveProcedureDialog. See issue #6092 and the discussion with Jacob. Basically we are trying to improve the metadata situation with more edit abilities and awareness, while in the same time having the export dialogs less of a mess (the "Comment" input in particular will most likely move to the metadata editor itself; I left it for now, until the move is done). The "(edit)" link will basically just run "plug-in-metadata-editor". Also as a side note: I realized that gimp_pdb_run_procedure() runs procedures synchronously and wait for a result, which is fine for quick non-interactive plug-ins, but freezes the calling process otherwise. Actually even when we want synchronous result, we should allow for GUI events to be processed (otherwise the OS just thinks the calling export plug-in is a zombie and proposes to kill it). This API should probably be improved (and an alternative async version added as well).
This commit is contained in:
parent
c0972eebb5
commit
c1c2b8e304
5 changed files with 105 additions and 13 deletions
|
|
@ -33,7 +33,11 @@
|
|||
|
||||
struct _GimpSaveProcedureDialogPrivate
|
||||
{
|
||||
GList *additional_metadata;
|
||||
GList *additional_metadata;
|
||||
GimpImage *image;
|
||||
|
||||
GThread *metadata_thread;
|
||||
GMutex metadata_thread_mutex;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -44,6 +48,11 @@ static void gimp_save_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
|
|||
GimpProcedureConfig *config,
|
||||
GList *properties);
|
||||
|
||||
static gpointer gimp_save_procedure_dialog_edit_metadata_thread (gpointer data);
|
||||
static gboolean gimp_save_procedure_dialog_activate_edit_metadata (GtkLinkButton *link,
|
||||
GimpSaveProcedureDialog *dialog);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GimpSaveProcedureDialog, gimp_save_procedure_dialog, GIMP_TYPE_PROCEDURE_DIALOG)
|
||||
|
||||
#define parent_class gimp_save_procedure_dialog_parent_class
|
||||
|
|
@ -67,6 +76,9 @@ gimp_save_procedure_dialog_init (GimpSaveProcedureDialog *dialog)
|
|||
dialog->priv = gimp_save_procedure_dialog_get_instance_private (dialog);
|
||||
|
||||
dialog->priv->additional_metadata = NULL;
|
||||
dialog->priv->image = NULL;
|
||||
dialog->priv->metadata_thread = NULL;
|
||||
g_mutex_init (&dialog->priv->metadata_thread_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -76,6 +88,8 @@ gimp_save_procedure_dialog_dispose (GObject *object)
|
|||
|
||||
g_list_free_full (dialog->priv->additional_metadata, g_free);
|
||||
dialog->priv->additional_metadata = NULL;
|
||||
g_clear_pointer (&dialog->priv->metadata_thread, g_thread_unref);
|
||||
g_mutex_clear (&dialog->priv->metadata_thread_mutex);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
|
@ -132,16 +146,45 @@ gimp_save_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
|
|||
g_list_length (save_dialog->priv->additional_metadata) > 0 ||
|
||||
gimp_save_procedure_get_support_comment (save_procedure))
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *widget;
|
||||
gint n_metadata;
|
||||
gint left = 0;
|
||||
gint top = 0;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *frame_title;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *label;
|
||||
GtkWidget *link;
|
||||
PangoAttrList *attrs;
|
||||
PangoAttribute *attr;
|
||||
gint n_metadata;
|
||||
gint left = 0;
|
||||
gint top = 0;
|
||||
|
||||
frame = gimp_frame_new (_("Metadata"));
|
||||
frame = gimp_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
||||
|
||||
/* Metadata frame title: a label and an edit link. */
|
||||
frame_title = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
|
||||
|
||||
label = gtk_label_new (_("Metadata"));
|
||||
attrs = pango_attr_list_new ();
|
||||
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
gtk_box_pack_start (GTK_BOX (frame_title), label, FALSE, FALSE, 0);
|
||||
gtk_widget_show (label);
|
||||
|
||||
link = gtk_link_button_new_with_label (_("Edit Metadata"), _("(edit)"));
|
||||
gtk_link_button_set_visited (GTK_LINK_BUTTON (link), FALSE);
|
||||
g_signal_connect (link, "activate-link",
|
||||
G_CALLBACK (gimp_save_procedure_dialog_activate_edit_metadata),
|
||||
dialog);
|
||||
gtk_box_pack_start (GTK_BOX (frame_title), link, FALSE, FALSE, 0);
|
||||
gtk_widget_show (link);
|
||||
|
||||
gtk_frame_set_label_widget (GTK_FRAME (frame), frame_title);
|
||||
gtk_widget_show (frame_title);
|
||||
|
||||
/* Metadata frame contents in a grid.. */
|
||||
grid = gtk_grid_new ();
|
||||
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
|
|
@ -276,9 +319,52 @@ gimp_save_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
|
|||
}
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gimp_save_procedure_dialog_edit_metadata_thread (gpointer data)
|
||||
{
|
||||
GimpSaveProcedureDialog *dialog = data;
|
||||
|
||||
gimp_pdb_run_procedure (gimp_get_pdb (), "plug-in-metadata-editor",
|
||||
GIMP_TYPE_RUN_MODE, GIMP_RUN_INTERACTIVE,
|
||||
GIMP_TYPE_IMAGE, dialog->priv->image,
|
||||
G_TYPE_NONE);
|
||||
|
||||
g_mutex_lock (&dialog->priv->metadata_thread_mutex);
|
||||
g_thread_unref (dialog->priv->metadata_thread);
|
||||
dialog->priv->metadata_thread = NULL;
|
||||
g_mutex_unlock (&dialog->priv->metadata_thread_mutex);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_save_procedure_dialog_activate_edit_metadata (GtkLinkButton *link,
|
||||
GimpSaveProcedureDialog *dialog)
|
||||
{
|
||||
gtk_link_button_set_visited (link, TRUE);
|
||||
|
||||
g_mutex_lock (&dialog->priv->metadata_thread_mutex);
|
||||
|
||||
if (! dialog->priv->metadata_thread)
|
||||
/* Only run if not already running. */
|
||||
dialog->priv->metadata_thread = g_thread_try_new ("Edit Metadata",
|
||||
gimp_save_procedure_dialog_edit_metadata_thread,
|
||||
dialog, NULL);
|
||||
|
||||
g_mutex_unlock (&dialog->priv->metadata_thread_mutex);
|
||||
|
||||
/* Stop propagation as the URI is bogus. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Public Functions */
|
||||
|
||||
|
||||
GtkWidget *
|
||||
gimp_save_procedure_dialog_new (GimpSaveProcedure *procedure,
|
||||
GimpProcedureConfig *config)
|
||||
GimpProcedureConfig *config,
|
||||
GimpImage *image)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
gchar *title;
|
||||
|
|
@ -290,6 +376,7 @@ gimp_save_procedure_dialog_new (GimpSaveProcedure *procedure,
|
|||
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 (GIMP_IS_IMAGE (image), NULL);
|
||||
|
||||
format_name = gimp_file_procedure_get_format_name (GIMP_FILE_PROCEDURE (procedure));
|
||||
if (! format_name)
|
||||
|
|
@ -317,6 +404,7 @@ gimp_save_procedure_dialog_new (GimpSaveProcedure *procedure,
|
|||
"help-id", help_id,
|
||||
"use-header-bar", use_header_bar,
|
||||
NULL);
|
||||
GIMP_SAVE_PROCEDURE_DIALOG (dialog)->priv->image = image;
|
||||
g_free (title);
|
||||
|
||||
return dialog;
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ struct _GimpSaveProcedureDialogClass
|
|||
GType gimp_save_procedure_dialog_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget * gimp_save_procedure_dialog_new (GimpSaveProcedure *procedure,
|
||||
GimpProcedureConfig *config);
|
||||
GimpProcedureConfig *config,
|
||||
GimpImage *image);
|
||||
|
||||
void gimp_save_procedure_dialog_add_metadata (GimpSaveProcedureDialog *dialog,
|
||||
const gchar *property);
|
||||
|
|
|
|||
|
|
@ -2167,7 +2167,8 @@ save_dialog (GimpImage *image,
|
|||
gboolean run;
|
||||
|
||||
dialog = gimp_save_procedure_dialog_new (GIMP_SAVE_PROCEDURE (procedure),
|
||||
GIMP_PROCEDURE_CONFIG (config));
|
||||
GIMP_PROCEDURE_CONFIG (config),
|
||||
image);
|
||||
|
||||
gimp_procedure_dialog_get_widget (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"compression", GIMP_TYPE_SCALE_ENTRY);
|
||||
|
|
|
|||
|
|
@ -796,7 +796,8 @@ save_dialog (GimpProcedure *procedure,
|
|||
NULL);
|
||||
|
||||
dialog = gimp_save_procedure_dialog_new (GIMP_SAVE_PROCEDURE (procedure),
|
||||
GIMP_PROCEDURE_CONFIG (config));
|
||||
GIMP_PROCEDURE_CONFIG (config),
|
||||
gimp_item_get_image (GIMP_ITEM (drawable)));
|
||||
|
||||
/* custom quantization tables - now used also for original quality */
|
||||
widget = gimp_procedure_dialog_get_widget (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
|
|
|
|||
|
|
@ -1283,7 +1283,8 @@ save_dialog (GimpImage *image,
|
|||
gboolean run;
|
||||
|
||||
dialog = gimp_save_procedure_dialog_new (GIMP_SAVE_PROCEDURE (procedure),
|
||||
GIMP_PROCEDURE_CONFIG (config));
|
||||
GIMP_PROCEDURE_CONFIG (config),
|
||||
image);
|
||||
|
||||
store =
|
||||
gimp_int_store_new (_("None"), GIMP_COMPRESSION_NONE,
|
||||
|
|
|
|||
Loading…
Reference in a new issue