From 7cdf85693a8dd139f66088fb5dc137eec363b0c7 Mon Sep 17 00:00:00 2001 From: Jehan Date: Sat, 2 May 2020 01:42:04 +0200 Subject: [PATCH] app: multi-layer aware layers-mask-add and layers-mask-add-button. These actions raise a GimpViewableDialog. For this to work, I made this widget work with a list of GimpViewable, not a single viewable anymore (so maybe the widget class name should change?). When this list contains only a single GimpViewable, it will display exactly like before, with a viewable preview. With several viewables, the preview won't show. This allows to add masks to all selected layers at once, with the same basic options for all masks, as set in the dialog. --- app/actions/gradient-editor-commands.c | 4 +- app/actions/layers-commands.c | 75 +++++++++++++------- app/dialogs/color-profile-dialog.c | 10 +-- app/dialogs/color-profile-import-dialog.c | 2 +- app/dialogs/convert-indexed-dialog.c | 2 +- app/dialogs/convert-precision-dialog.c | 2 +- app/dialogs/fill-dialog.c | 2 +- app/dialogs/grid-dialog.c | 2 +- app/dialogs/image-merge-layers-dialog.c | 2 +- app/dialogs/image-properties-dialog.c | 2 +- app/dialogs/item-options-dialog.c | 2 +- app/dialogs/layer-add-mask-dialog.c | 32 ++++++--- app/dialogs/layer-add-mask-dialog.h | 4 +- app/dialogs/print-size-dialog.c | 2 +- app/dialogs/resize-dialog.c | 2 +- app/dialogs/scale-dialog.c | 2 +- app/dialogs/stroke-dialog.c | 2 +- app/dialogs/template-options-dialog.c | 2 +- app/display/gimpdisplayshell-filter-dialog.c | 2 +- app/display/gimpdisplayshell-rotate-dialog.c | 2 +- app/display/gimpdisplayshell-scale-dialog.c | 2 +- app/display/gimptoolgui.c | 4 +- app/tools/gimptexttool.c | 2 +- app/widgets/gimpcolordialog.c | 4 +- app/widgets/gimpcolormapeditor.c | 6 +- app/widgets/gimpcontrollereditor.c | 2 +- app/widgets/gimppaletteeditor.c | 6 +- app/widgets/gimpviewabledialog.c | 75 +++++++++++--------- app/widgets/gimpviewabledialog.h | 10 +-- 29 files changed, 159 insertions(+), 107 deletions(-) diff --git a/app/actions/gradient-editor-commands.c b/app/actions/gradient-editor-commands.c index f7d1ce30fc..01864061a8 100644 --- a/app/actions/gradient-editor-commands.c +++ b/app/actions/gradient-editor-commands.c @@ -397,7 +397,7 @@ gradient_editor_replicate_cmd_callback (GimpAction *action, desc = _("Replicate Gradient Selection"); } - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (gradient), + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, gradient), data_editor->context, title, "gimp-gradient-segment-replicate", @@ -508,7 +508,7 @@ gradient_editor_split_uniformly_cmd_callback (GimpAction *action, desc = _("Split Gradient Segments Uniformly"); } - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (gradient), + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, gradient), data_editor->context, title, "gimp-gradient-segment-split-uniformly", diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c index 2706640847..d841a7af1c 100644 --- a/app/actions/layers-commands.c +++ b/app/actions/layers-commands.c @@ -135,7 +135,7 @@ static void layers_edit_attributes_callback (GtkWidget *dialog, gboolean rename_text_layer, gpointer user_data); static void layers_add_mask_callback (GtkWidget *dialog, - GimpLayer *layer, + GList *layers, GimpAddMaskType add_mask_type, GimpChannel *channel, gboolean invert, @@ -1026,31 +1026,51 @@ layers_mask_add_cmd_callback (GimpAction *action, gpointer data) { GimpImage *image; - GimpLayer *layer; + GList *layers; + GList *iter; GtkWidget *widget; GtkWidget *dialog; - return_if_no_layer (image, layer, data); + GList *update_layers = NULL; + gint n_channels = 0; + return_if_no_layers (image, layers, data); return_if_no_widget (widget, data); - if (gimp_layer_get_mask (layer)) + for (iter = layers; iter; iter = iter->next) + { + g_return_if_fail (GIMP_IS_LAYER (iter->data)); + + if (! gimp_layer_get_mask (iter->data)) + { + update_layers = g_list_prepend (update_layers, iter->data); + n_channels++; + } + } + if (n_channels == 0) + /* No layers or they all have masks already. */ return; #define ADD_MASK_DIALOG_KEY "gimp-add-mask-dialog" - dialog = dialogs_get_dialog (G_OBJECT (layer), ADD_MASK_DIALOG_KEY); + for (iter = update_layers; iter; iter = iter->next) + { + dialog = dialogs_get_dialog (G_OBJECT (iter->data), ADD_MASK_DIALOG_KEY); + if (dialog) + break; + } if (! dialog) { GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config); - dialog = layer_add_mask_dialog_new (layer, action_data_get_context (data), + dialog = layer_add_mask_dialog_new (update_layers, action_data_get_context (data), widget, config->layer_add_mask_type, config->layer_add_mask_invert, layers_add_mask_callback, NULL); - dialogs_attach_dialog (G_OBJECT (layer), ADD_MASK_DIALOG_KEY, dialog); + for (iter = update_layers; iter; iter = iter->next) + dialogs_attach_dialog (G_OBJECT (iter->data), ADD_MASK_DIALOG_KEY, dialog); } gtk_window_present (GTK_WINDOW (dialog)); @@ -1865,15 +1885,16 @@ layers_edit_attributes_callback (GtkWidget *dialog, static void layers_add_mask_callback (GtkWidget *dialog, - GimpLayer *layer, + GList *layers, GimpAddMaskType add_mask_type, GimpChannel *channel, gboolean invert, gpointer user_data) { - GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); + GimpImage *image = gimp_item_get_image (GIMP_ITEM (layers->data)); GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config); GimpLayerMask *mask; + GList *iter; GError *error = NULL; g_object_set (config, @@ -1881,25 +1902,31 @@ layers_add_mask_callback (GtkWidget *dialog, "layer-add-mask-invert", invert, NULL); - mask = gimp_layer_create_mask (layer, - config->layer_add_mask_type, - channel); - - if (config->layer_add_mask_invert) - gimp_channel_invert (GIMP_CHANNEL (mask), FALSE); - - if (! gimp_layer_add_mask (layer, mask, TRUE, &error)) + gimp_image_undo_group_start (image, + GIMP_UNDO_GROUP_LAYER_ADD, + _("Add Layer Masks")); + for (iter = layers; iter; iter = iter->next) { - gimp_message_literal (image->gimp, - G_OBJECT (dialog), GIMP_MESSAGE_WARNING, - error->message); - g_object_unref (mask); - g_clear_error (&error); - return; + mask = gimp_layer_create_mask (iter->data, + config->layer_add_mask_type, + channel); + + if (config->layer_add_mask_invert) + gimp_channel_invert (GIMP_CHANNEL (mask), FALSE); + + if (! gimp_layer_add_mask (iter->data, mask, TRUE, &error)) + { + gimp_message_literal (image->gimp, + G_OBJECT (dialog), GIMP_MESSAGE_WARNING, + error->message); + g_object_unref (mask); + g_clear_error (&error); + return; + } } + gimp_image_undo_group_end (image); gimp_image_flush (image); - gtk_widget_destroy (dialog); } diff --git a/app/dialogs/color-profile-dialog.c b/app/dialogs/color-profile-dialog.c index 0fbee6d28a..698075f9af 100644 --- a/app/dialogs/color-profile-dialog.c +++ b/app/dialogs/color-profile-dialog.c @@ -124,7 +124,7 @@ color_profile_dialog_new (ColorProfileDialogType dialog_type, { case COLOR_PROFILE_DIALOG_ASSIGN_PROFILE: dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("Assign ICC Color Profile"), "gimp-image-color-profile-assign", NULL, @@ -142,7 +142,7 @@ color_profile_dialog_new (ColorProfileDialogType dialog_type, case COLOR_PROFILE_DIALOG_CONVERT_TO_PROFILE: dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("Convert to ICC Color Profile"), "gimp-image-color-profile-convert", NULL, @@ -160,7 +160,7 @@ color_profile_dialog_new (ColorProfileDialogType dialog_type, case COLOR_PROFILE_DIALOG_CONVERT_TO_RGB: dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("RGB Conversion"), "gimp-image-convert-rgb", GIMP_ICON_CONVERT_RGB, @@ -178,7 +178,7 @@ color_profile_dialog_new (ColorProfileDialogType dialog_type, case COLOR_PROFILE_DIALOG_CONVERT_TO_GRAY: dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("Grayscale Conversion"), "gimp-image-convert-gray", GIMP_ICON_CONVERT_GRAYSCALE, @@ -196,7 +196,7 @@ color_profile_dialog_new (ColorProfileDialogType dialog_type, case COLOR_PROFILE_DIALOG_SELECT_SOFTPROOF_PROFILE: dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("Soft-Proof Profile"), "gimp-select-softproof-profile", GIMP_ICON_DOCUMENT_PRINT, diff --git a/app/dialogs/color-profile-import-dialog.c b/app/dialogs/color-profile-import-dialog.c index bcba551d90..4b1a845df2 100644 --- a/app/dialogs/color-profile-import-dialog.c +++ b/app/dialogs/color-profile-import-dialog.c @@ -92,7 +92,7 @@ color_profile_import_dialog_run (GimpImage *image, } dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, title, "gimp-image-color-profile-import", NULL, diff --git a/app/dialogs/convert-indexed-dialog.c b/app/dialogs/convert-indexed-dialog.c index f59f4c82f3..5469999427 100644 --- a/app/dialogs/convert-indexed-dialog.c +++ b/app/dialogs/convert-indexed-dialog.c @@ -130,7 +130,7 @@ convert_indexed_dialog_new (GimpImage *image, private->user_data = user_data; private->dialog = dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("Indexed Color Conversion"), "gimp-image-convert-indexed", GIMP_ICON_CONVERT_INDEXED, diff --git a/app/dialogs/convert-precision-dialog.c b/app/dialogs/convert-precision-dialog.c index 39a9227e0b..aded700768 100644 --- a/app/dialogs/convert-precision-dialog.c +++ b/app/dialogs/convert-precision-dialog.c @@ -134,7 +134,7 @@ convert_precision_dialog_new (GimpImage *image, blurb = g_strdup_printf (_("Convert Image to %s"), enum_desc); - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("Encoding Conversion"), "gimp-image-convert-precision", GIMP_ICON_CONVERT_PRECISION, diff --git a/app/dialogs/fill-dialog.c b/app/dialogs/fill-dialog.c index cca4e23bc6..2a0d5551c0 100644 --- a/app/dialogs/fill-dialog.c +++ b/app/dialogs/fill-dialog.c @@ -103,7 +103,7 @@ fill_dialog_new (GimpItem *item, gimp_config_sync (G_OBJECT (options), G_OBJECT (private->options), 0); - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (item), context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, item), context, title, "gimp-fill-options", icon_name, _("Choose Fill Style"), diff --git a/app/dialogs/grid-dialog.c b/app/dialogs/grid-dialog.c index 3c8fcb6b7b..9eb2f758f4 100644 --- a/app/dialogs/grid-dialog.c +++ b/app/dialogs/grid-dialog.c @@ -91,7 +91,7 @@ grid_dialog_new (GimpImage *image, private->grid = gimp_image_get_grid (image); private->grid_backup = gimp_config_duplicate (GIMP_CONFIG (private->grid)); - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("Configure Grid"), "gimp-grid-configure", GIMP_ICON_GRID, _("Configure Image Grid"), parent, diff --git a/app/dialogs/image-merge-layers-dialog.c b/app/dialogs/image-merge-layers-dialog.c index f7a698d2f2..6ac115a44b 100644 --- a/app/dialogs/image-merge-layers-dialog.c +++ b/app/dialogs/image-merge-layers-dialog.c @@ -89,7 +89,7 @@ image_merge_layers_dialog_new (GimpImage *image, private->callback = callback; private->user_data = user_data; - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("Merge Layers"), "gimp-image-merge-layers", GIMP_ICON_LAYER_MERGE_DOWN, _("Layers Merge Options"), diff --git a/app/dialogs/image-properties-dialog.c b/app/dialogs/image-properties-dialog.c index 1d0cbc204a..fb1a104b03 100644 --- a/app/dialogs/image-properties-dialog.c +++ b/app/dialogs/image-properties-dialog.c @@ -56,7 +56,7 @@ image_properties_dialog_new (GimpImage *image, g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (parent == NULL || GTK_IS_WIDGET (parent), NULL); - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, _("Image Properties"), "gimp-image-properties", "dialog-information", diff --git a/app/dialogs/item-options-dialog.c b/app/dialogs/item-options-dialog.c index 3ecc346338..cc7e7389f7 100644 --- a/app/dialogs/item-options-dialog.c +++ b/app/dialogs/item-options-dialog.c @@ -137,7 +137,7 @@ item_options_dialog_new (GimpImage *image, else viewable = GIMP_VIEWABLE (image); - dialog = gimp_viewable_dialog_new (viewable, context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, viewable), context, title, role, icon_name, desc, parent, gimp_standard_help_func, help_id, diff --git a/app/dialogs/layer-add-mask-dialog.c b/app/dialogs/layer-add-mask-dialog.c index dac0163f2c..9c2ff78c50 100644 --- a/app/dialogs/layer-add-mask-dialog.c +++ b/app/dialogs/layer-add-mask-dialog.c @@ -46,7 +46,7 @@ typedef struct _LayerAddMaskDialog LayerAddMaskDialog; struct _LayerAddMaskDialog { - GimpLayer *layer; + GList *layers; GimpAddMaskType add_mask_type; GimpChannel *channel; gboolean invert; @@ -70,7 +70,7 @@ static gboolean layer_add_mask_dialog_channel_selected (GimpContainerView *vi /* public functions */ GtkWidget * -layer_add_mask_dialog_new (GimpLayer *layer, +layer_add_mask_dialog_new (GList *layers, GimpContext *context, GtkWidget *parent, GimpAddMaskType add_mask_type, @@ -86,23 +86,32 @@ layer_add_mask_dialog_new (GimpLayer *layer, GtkWidget *button; GimpImage *image; GimpChannel *channel; + gchar *title; + gchar *desc; + gint n_layers = g_list_length (layers); - g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL); + g_return_val_if_fail (layers, NULL); g_return_val_if_fail (GTK_IS_WIDGET (parent), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); private = g_slice_new0 (LayerAddMaskDialog); - private->layer = layer; + private->layers = layers; private->add_mask_type = add_mask_type; private->invert = invert; private->callback = callback; private->user_data = user_data; - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (layer), context, - _("Add Layer Mask"), "gimp-layer-add-mask", + title = ngettext ("Add Layer Mask", "Add Layer Masks", n_layers); + title = g_strdup_printf (title, n_layers); + desc = ngettext ("Add a Mask to the Layer", "Add Masks to %d Layers", n_layers); + desc = g_strdup_printf (desc, n_layers); + + dialog = gimp_viewable_dialog_new (layers, context, + title, + "gimp-layer-add-mask", GIMP_ICON_LAYER_MASK, - _("Add a Mask to the Layer"), + desc, parent, gimp_standard_help_func, GIMP_HELP_LAYER_MASK_ADD, @@ -112,6 +121,9 @@ layer_add_mask_dialog_new (GimpLayer *layer, NULL); + g_free (title); + g_free (desc); + gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, @@ -144,7 +156,7 @@ layer_add_mask_dialog_new (GimpLayer *layer, gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); gtk_widget_show (frame); - image = gimp_item_get_image (GIMP_ITEM (layer)); + image = gimp_item_get_image (GIMP_ITEM (layers->data)); combo = gimp_container_combo_box_new (gimp_image_get_channels (image), context, @@ -193,7 +205,7 @@ layer_add_mask_dialog_response (GtkWidget *dialog, { if (response_id == GTK_RESPONSE_OK) { - GimpImage *image = gimp_item_get_image (GIMP_ITEM (private->layer)); + GimpImage *image = gimp_item_get_image (GIMP_ITEM (private->layers->data)); if (private->add_mask_type == GIMP_ADD_MASK_CHANNEL && ! private->channel) @@ -205,7 +217,7 @@ layer_add_mask_dialog_response (GtkWidget *dialog, } private->callback (dialog, - private->layer, + private->layers, private->add_mask_type, private->channel, private->invert, diff --git a/app/dialogs/layer-add-mask-dialog.h b/app/dialogs/layer-add-mask-dialog.h index ecdd9d3ff2..c6d79767c2 100644 --- a/app/dialogs/layer-add-mask-dialog.h +++ b/app/dialogs/layer-add-mask-dialog.h @@ -20,14 +20,14 @@ typedef void (* GimpAddMaskCallback) (GtkWidget *dialog, - GimpLayer *layer, + GList *layers, GimpAddMaskType add_mask_type, GimpChannel *channel, gboolean invert, gpointer user_data); -GtkWidget * layer_add_mask_dialog_new (GimpLayer *layer, +GtkWidget * layer_add_mask_dialog_new (GList *layers, GimpContext *context, GtkWidget *parent, GimpAddMaskType add_mask_type, diff --git a/app/dialogs/print-size-dialog.c b/app/dialogs/print-size-dialog.c index f7d788f911..8d4417ae47 100644 --- a/app/dialogs/print-size-dialog.c +++ b/app/dialogs/print-size-dialog.c @@ -114,7 +114,7 @@ print_size_dialog_new (GimpImage *image, gimp_image_get_resolution (image, &private->xres, &private->yres); - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, image), context, title, role, GIMP_ICON_DOCUMENT_PRINT_RESOLUTION, title, parent, diff --git a/app/dialogs/resize-dialog.c b/app/dialogs/resize-dialog.c index f401f05f0c..fb452731b2 100644 --- a/app/dialogs/resize-dialog.c +++ b/app/dialogs/resize-dialog.c @@ -176,7 +176,7 @@ resize_dialog_new (GimpViewable *viewable, private->old_layer_set = private->layer_set; private->old_resize_text_layers = private->resize_text_layers; - dialog = gimp_viewable_dialog_new (viewable, context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, viewable), context, title, role, GIMP_ICON_OBJECT_RESIZE, title, parent, help_func, help_id, diff --git a/app/dialogs/scale-dialog.c b/app/dialogs/scale-dialog.c index 2bf2e285fd..c64acc9ef1 100644 --- a/app/dialogs/scale-dialog.c +++ b/app/dialogs/scale-dialog.c @@ -128,7 +128,7 @@ scale_dialog_new (GimpViewable *viewable, gimp_image_get_resolution (image, &xres, &yres); - dialog = gimp_viewable_dialog_new (viewable, context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, viewable), context, title, role, GIMP_ICON_OBJECT_SCALE, title, parent, help_func, help_id, diff --git a/app/dialogs/stroke-dialog.c b/app/dialogs/stroke-dialog.c index 797bb21d36..32012c0068 100644 --- a/app/dialogs/stroke-dialog.c +++ b/app/dialogs/stroke-dialog.c @@ -116,7 +116,7 @@ stroke_dialog_new (GimpItem *item, gimp_config_sync (G_OBJECT (options), G_OBJECT (private->options), 0); - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (item), context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, item), context, title, "gimp-stroke-options", icon_name, _("Choose Stroke Style"), diff --git a/app/dialogs/template-options-dialog.c b/app/dialogs/template-options-dialog.c index 5d7266f23f..16ee9f25ec 100644 --- a/app/dialogs/template-options-dialog.c +++ b/app/dialogs/template-options-dialog.c @@ -110,7 +110,7 @@ template_options_dialog_new (GimpTemplate *template, gimp_object_set_static_name (GIMP_OBJECT (template), _("Unnamed")); } - dialog = gimp_viewable_dialog_new (viewable, context, + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, viewable), context, title, role, icon_name, desc, parent, gimp_standard_help_func, help_id, diff --git a/app/display/gimpdisplayshell-filter-dialog.c b/app/display/gimpdisplayshell-filter-dialog.c index b942e5b4b4..7844ac9bc6 100644 --- a/app/display/gimpdisplayshell-filter-dialog.c +++ b/app/display/gimpdisplayshell-filter-dialog.c @@ -74,7 +74,7 @@ gimp_display_shell_filter_dialog_new (GimpDisplayShell *shell) cdd = g_slice_new0 (ColorDisplayDialog); cdd->shell = shell; - cdd->dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (image), + cdd->dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, image), gimp_get_user_context (shell->display->gimp), _("Color Display Filters"), "gimp-display-filters", diff --git a/app/display/gimpdisplayshell-rotate-dialog.c b/app/display/gimpdisplayshell-rotate-dialog.c index 13fd0f5cdd..876df8a6e0 100644 --- a/app/display/gimpdisplayshell-rotate-dialog.c +++ b/app/display/gimpdisplayshell-rotate-dialog.c @@ -109,7 +109,7 @@ gimp_display_shell_rotate_dialog (GimpDisplayShell *shell) data->old_angle = shell->rotate_angle; shell->rotate_dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (image), + gimp_viewable_dialog_new (g_list_prepend (NULL, image), gimp_get_user_context (shell->display->gimp), _("Rotate View"), "display-rotate", GIMP_ICON_OBJECT_ROTATE_180, diff --git a/app/display/gimpdisplayshell-scale-dialog.c b/app/display/gimpdisplayshell-scale-dialog.c index ddc04724f1..c80ad4bfa2 100644 --- a/app/display/gimpdisplayshell-scale-dialog.c +++ b/app/display/gimpdisplayshell-scale-dialog.c @@ -110,7 +110,7 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell) NULL); shell->scale_dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (image), + gimp_viewable_dialog_new (g_list_prepend (NULL, image), gimp_get_user_context (shell->display->gimp), _("Zoom Ratio"), "display_scale", "zoom-original", diff --git a/app/display/gimptoolgui.c b/app/display/gimptoolgui.c index 927a040810..81eda2bee8 100644 --- a/app/display/gimptoolgui.c +++ b/app/display/gimptoolgui.c @@ -940,8 +940,8 @@ gimp_tool_gui_update_viewable (GimpToolGui *gui) if (private->tool_info) context = GIMP_CONTEXT (private->tool_info->tool_options); - gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (private->dialog), - private->viewable, context); + gimp_viewable_dialog_set_viewables (GIMP_VIEWABLE_DIALOG (private->dialog), + g_list_prepend (NULL, private->viewable), context); } } diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c index 37d0d4ca7d..6570d8eb9e 100644 --- a/app/tools/gimptexttool.c +++ b/app/tools/gimptexttool.c @@ -1752,7 +1752,7 @@ gimp_text_tool_confirm_dialog (GimpTextTool *text_tool) return; } - dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (text_tool->layer), + dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, text_tool->layer), GIMP_CONTEXT (gimp_tool_get_options (tool)), _("Confirm Text Editing"), "gimp-text-tool-confirm", diff --git a/app/widgets/gimpcolordialog.c b/app/widgets/gimpcolordialog.c index 7aa9b1f8d1..155abeb495 100644 --- a/app/widgets/gimpcolordialog.c +++ b/app/widgets/gimpcolordialog.c @@ -470,8 +470,8 @@ gimp_color_dialog_new (GimpViewable *viewable, if (viewable) { - gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (dialog), - viewable, context); + gimp_viewable_dialog_set_viewables (GIMP_VIEWABLE_DIALOG (dialog), + g_list_prepend (NULL, viewable), context); } else { diff --git a/app/widgets/gimpcolormapeditor.c b/app/widgets/gimpcolormapeditor.c index d7480f5d21..8a2152822a 100644 --- a/app/widgets/gimpcolormapeditor.c +++ b/app/widgets/gimpcolormapeditor.c @@ -258,9 +258,9 @@ gimp_colormap_editor_edit_color (GimpColormapEditor *editor) } else { - gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (editor->color_dialog), - GIMP_VIEWABLE (image), - GIMP_IMAGE_EDITOR (editor)->context); + gimp_viewable_dialog_set_viewables (GIMP_VIEWABLE_DIALOG (editor->color_dialog), + g_list_prepend (NULL, image), + GIMP_IMAGE_EDITOR (editor)->context); g_object_set (editor->color_dialog, "description", desc, NULL); gimp_color_dialog_set_color (GIMP_COLOR_DIALOG (editor->color_dialog), &color); diff --git a/app/widgets/gimpcontrollereditor.c b/app/widgets/gimpcontrollereditor.c index 9df413a6f2..043529a679 100644 --- a/app/widgets/gimpcontrollereditor.c +++ b/app/widgets/gimpcontrollereditor.c @@ -649,7 +649,7 @@ gimp_controller_editor_edit_clicked (GtkWidget *button, event_blurb); editor->edit_dialog = - gimp_viewable_dialog_new (GIMP_VIEWABLE (editor->info), editor->context, + gimp_viewable_dialog_new (g_list_prepend (NULL, editor->info), editor->context, _("Select Controller Event Action"), "gimp-controller-action-dialog", GIMP_ICON_EDIT, diff --git a/app/widgets/gimppaletteeditor.c b/app/widgets/gimppaletteeditor.c index 8bf36675a3..a5b039566e 100644 --- a/app/widgets/gimppaletteeditor.c +++ b/app/widgets/gimppaletteeditor.c @@ -501,9 +501,9 @@ gimp_palette_editor_edit_color (GimpPaletteEditor *editor) } else { - gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (editor->color_dialog), - GIMP_VIEWABLE (palette), - data_editor->context); + gimp_viewable_dialog_set_viewables (GIMP_VIEWABLE_DIALOG (editor->color_dialog), + g_list_prepend (NULL, palette), + data_editor->context); gimp_color_dialog_set_color (GIMP_COLOR_DIALOG (editor->color_dialog), &editor->color->color); diff --git a/app/widgets/gimpviewabledialog.c b/app/widgets/gimpviewabledialog.c index c26a157154..1c4f98bfc5 100644 --- a/app/widgets/gimpviewabledialog.c +++ b/app/widgets/gimpviewabledialog.c @@ -40,7 +40,7 @@ enum { PROP_0, - PROP_VIEWABLE, + PROP_VIEWABLES, PROP_CONTEXT, PROP_ICON_NAME, PROP_DESC @@ -76,10 +76,9 @@ gimp_viewable_dialog_class_init (GimpViewableDialogClass *klass) object_class->get_property = gimp_viewable_dialog_get_property; object_class->set_property = gimp_viewable_dialog_set_property; - g_object_class_install_property (object_class, PROP_VIEWABLE, - g_param_spec_object ("viewable", NULL, NULL, - GIMP_TYPE_VIEWABLE, - GIMP_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_VIEWABLES, + g_param_spec_pointer ("viewables", NULL, NULL, + GIMP_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_CONTEXT, g_param_spec_object ("context", NULL, NULL, @@ -154,7 +153,10 @@ gimp_viewable_dialog_dispose (GObject *object) GimpViewableDialog *dialog = GIMP_VIEWABLE_DIALOG (object); if (dialog->view) - gimp_viewable_dialog_set_viewable (dialog, NULL, NULL); + gimp_viewable_dialog_set_viewables (dialog, NULL, NULL); + + g_list_free (dialog->viewables); + dialog->viewables = NULL; G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -169,18 +171,15 @@ gimp_viewable_dialog_set_property (GObject *object, switch (property_id) { - case PROP_VIEWABLE: - gimp_viewable_dialog_set_viewable (dialog, - g_value_get_object (value), - dialog->context); + case PROP_VIEWABLES: + gimp_viewable_dialog_set_viewables (dialog, + g_value_get_pointer (value), + dialog->context); break; case PROP_CONTEXT: - gimp_viewable_dialog_set_viewable (dialog, - dialog->view ? - GIMP_VIEW (dialog->view)->viewable : - NULL, - g_value_get_object (value)); + gimp_viewable_dialog_set_viewables (dialog, g_list_copy (dialog->viewables), + g_value_get_object (value)); break; case PROP_ICON_NAME: @@ -210,10 +209,8 @@ gimp_viewable_dialog_get_property (GObject *object, switch (property_id) { - case PROP_VIEWABLE: - g_value_set_object (value, - dialog->view ? - GIMP_VIEW (dialog->view)->viewable : NULL); + case PROP_VIEWABLES: + g_value_set_pointer (value, dialog->viewables); break; case PROP_CONTEXT: @@ -227,7 +224,7 @@ gimp_viewable_dialog_get_property (GObject *object, } GtkWidget * -gimp_viewable_dialog_new (GimpViewable *viewable, +gimp_viewable_dialog_new (GList *viewables, GimpContext *context, const gchar *title, const gchar *role, @@ -242,21 +239,20 @@ gimp_viewable_dialog_new (GimpViewable *viewable, va_list args; gboolean use_header_bar; - g_return_val_if_fail (viewable == NULL || GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (title != NULL, NULL); g_return_val_if_fail (role != NULL, NULL); g_return_val_if_fail (parent == NULL || GTK_IS_WIDGET (parent), NULL); - if (! viewable) - g_warning ("Use of GimpViewableDialog with a NULL viewable is deprecated!"); + if (! viewables) + g_warning ("Use of GimpViewableDialog with an empty viewable list is deprecated!"); g_object_get (gtk_settings_get_default (), "gtk-dialogs-use-header", &use_header_bar, NULL); dialog = g_object_new (GIMP_TYPE_VIEWABLE_DIALOG, - "viewable", viewable, + "viewables", viewables, "context", context, "title", title, "role", role, @@ -275,22 +271,35 @@ gimp_viewable_dialog_new (GimpViewable *viewable, return GTK_WIDGET (dialog); } +/* + * gimp_viewable_dialog_set_viewables: + * @dialog: + * @viewables: + * @context: + * + * Sets @dialog to display contents related to the list of #GimpViewable + * @viewables. If this list contains a single viewable, a small preview + * is also shown. + * @dialog takes ownership of @viewables and will free the list upon + * destruction. + */ void -gimp_viewable_dialog_set_viewable (GimpViewableDialog *dialog, - GimpViewable *viewable, - GimpContext *context) +gimp_viewable_dialog_set_viewables (GimpViewableDialog *dialog, + GList *viewables, + GimpContext *context) { g_return_if_fail (GIMP_IS_VIEWABLE_DIALOG (dialog)); - g_return_if_fail (viewable == NULL || GIMP_IS_VIEWABLE (viewable)); g_return_if_fail (context == NULL || GIMP_IS_CONTEXT (context)); - dialog->context = context; + dialog->context = context; + g_list_free (dialog->viewables); + dialog->viewables = viewables; if (dialog->view) { GimpViewable *old_viewable = GIMP_VIEW (dialog->view)->viewable; - if (viewable == old_viewable) + if (g_list_length (viewables) == 1 && viewables->data == old_viewable) { gimp_view_renderer_set_context (GIMP_VIEW (dialog->view)->renderer, context); @@ -311,10 +320,12 @@ gimp_viewable_dialog_set_viewable (GimpViewableDialog *dialog, } } - if (viewable) + if (g_list_length (viewables) == 1 && viewables->data) { - GtkWidget *box; + GimpViewable *viewable = viewables->data; + GtkWidget *box; + g_return_if_fail (GIMP_IS_VIEWABLE (viewable)); g_signal_connect_object (viewable, GIMP_VIEWABLE_GET_CLASS (viewable)->name_changed_signal, G_CALLBACK (gimp_viewable_dialog_name_changed), diff --git a/app/widgets/gimpviewabledialog.h b/app/widgets/gimpviewabledialog.h index f7b3dae4ec..c9d67025fe 100644 --- a/app/widgets/gimpviewabledialog.h +++ b/app/widgets/gimpviewabledialog.h @@ -40,6 +40,8 @@ struct _GimpViewableDialog GimpContext *context; + GList *viewables; + GtkWidget *icon; GtkWidget *view; GtkWidget *desc_label; @@ -54,7 +56,7 @@ struct _GimpViewableDialogClass GType gimp_viewable_dialog_get_type (void) G_GNUC_CONST; -GtkWidget * gimp_viewable_dialog_new (GimpViewable *viewable, +GtkWidget * gimp_viewable_dialog_new (GList *viewables, GimpContext *context, const gchar *title, const gchar *role, @@ -65,9 +67,9 @@ GtkWidget * gimp_viewable_dialog_new (GimpViewable *viewable, const gchar *help_id, ...) G_GNUC_NULL_TERMINATED; -void gimp_viewable_dialog_set_viewable (GimpViewableDialog *dialog, - GimpViewable *viewable, - GimpContext *context); +void gimp_viewable_dialog_set_viewables (GimpViewableDialog *dialog, + GList *viewables, + GimpContext *context); G_END_DECLS