diff --git a/app/display/gimpdisplayshell-tool-events.c b/app/display/gimpdisplayshell-tool-events.c index 756a3bdf69..6fd2a75195 100644 --- a/app/display/gimpdisplayshell-tool-events.c +++ b/app/display/gimpdisplayshell-tool-events.c @@ -1911,13 +1911,12 @@ gimp_display_shell_initialize_tool (GimpDisplayShell *shell, (! gimp_image_is_empty (image) || gimp_tool_control_get_handle_empty_image (active_tool->control))) { - /* initialize the current tool if it has no drawable */ - if (! active_tool->drawable) + /* initialize the current tool if it has no drawables */ + if (! active_tool->drawables) { initialized = tool_manager_initialize_active (gimp, display); } - else if ((active_tool->drawable != - gimp_image_get_active_drawable (image)) && + else if (! gimp_image_equal_selected_drawables (image, active_tool->drawables) && (! gimp_tool_control_get_preserve (active_tool->control) && (gimp_tool_control_get_dirty_mask (active_tool->control) & GIMP_DIRTY_ACTIVE_DRAWABLE))) @@ -1925,7 +1924,7 @@ gimp_display_shell_initialize_tool (GimpDisplayShell *shell, GimpProcedure *procedure = g_object_get_data (G_OBJECT (active_tool), "gimp-gegl-procedure"); - if (image == gimp_item_get_image (GIMP_ITEM (active_tool->drawable))) + if (image == gimp_item_get_image (GIMP_ITEM (active_tool->drawables->data))) { /* When changing between drawables if the *same* image, * stop the tool using its dirty action, so it doesn't diff --git a/app/tools/gimpbrushtool.c b/app/tools/gimpbrushtool.c index 08c8ed964f..8fb3e49b07 100644 --- a/app/tools/gimpbrushtool.c +++ b/app/tools/gimpbrushtool.c @@ -156,14 +156,20 @@ gimp_brush_tool_oper_update (GimpTool *tool, GimpDisplay *display) { GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (tool); - GimpDrawable *drawable; + GimpDrawable *drawable = NULL; + GList *drawables; gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity, display); - drawable = gimp_image_get_active_drawable (gimp_display_get_image (display)); + drawables = gimp_image_get_selected_drawables (gimp_display_get_image (display)); + + if (drawables) + drawable = drawables->data; + + g_list_free (drawables); if (! gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool)) && drawable && proximity) diff --git a/app/tools/gimpbucketfilltool.c b/app/tools/gimpbucketfilltool.c index 3c988f6af0..1c323fef44 100644 --- a/app/tools/gimpbucketfilltool.c +++ b/app/tools/gimpbucketfilltool.c @@ -327,21 +327,23 @@ gimp_bucket_fill_tool_start (GimpBucketFillTool *tool, const GimpCoords *coords, GimpDisplay *display) { - GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool); - GimpContext *context = GIMP_CONTEXT (options); - GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool); + GimpContext *context = GIMP_CONTEXT (options); + GimpImage *image = gimp_display_get_image (display); + GList *drawables = gimp_image_get_selected_drawables (image); g_return_if_fail (! tool->priv->filter); + g_return_if_fail (g_list_length (drawables) == 1); gimp_line_art_freeze (tool->priv->line_art); GIMP_TOOL (tool)->display = display; - GIMP_TOOL (tool)->drawable = drawable; + g_list_free (GIMP_TOOL (tool)->drawables); + GIMP_TOOL (tool)->drawables = drawables; gimp_bucket_fill_tool_create_graph (tool); - tool->priv->filter = gimp_drawable_filter_new (drawable, _("Bucket fill"), + tool->priv->filter = gimp_drawable_filter_new (drawables->data, _("Bucket fill"), tool->priv->graph, GIMP_ICON_TOOL_BUCKET_FILL); @@ -370,10 +372,16 @@ gimp_bucket_fill_tool_preview (GimpBucketFillTool *tool, GimpDisplay *display, GimpFillOptions *fill_options) { - GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool); - GimpDisplayShell *shell = gimp_display_get_shell (display); - GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool); + GimpDisplayShell *shell = gimp_display_get_shell (display); + GimpImage *image = gimp_display_get_image (display); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; + + g_return_if_fail (g_list_length (drawables) == 1); + + drawable = drawables->data; + g_list_free (drawables); if (tool->priv->filter) { @@ -486,8 +494,9 @@ gimp_bucket_fill_tool_halt (GimpBucketFillTool *tool) if (gimp_line_art_is_frozen (tool->priv->line_art)) gimp_line_art_thaw (tool->priv->line_art); - GIMP_TOOL (tool)->display = NULL; - GIMP_TOOL (tool)->drawable = NULL; + GIMP_TOOL (tool)->display = NULL; + g_list_free (GIMP_TOOL (tool)->drawables); + GIMP_TOOL (tool)->drawables = NULL; } static void @@ -539,7 +548,8 @@ gimp_bucket_fill_tool_button_press (GimpTool *tool, GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool); GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; if (gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool))) { @@ -548,6 +558,21 @@ gimp_bucket_fill_tool_button_press (GimpTool *tool, return; } + if (g_list_length (drawables) != 1) + { + if (g_list_length (drawables) > 1) + gimp_tool_message_literal (tool, display, + _("Cannot fill multiple layers. Select only one layer.")); + else + gimp_tool_message_literal (tool, display, _("No selected drawables.")); + + g_list_free (drawables); + return; + } + + drawable = drawables->data; + g_list_free (drawables); + if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { gimp_tool_message_literal (tool, display, @@ -827,9 +852,14 @@ gimp_bucket_fill_tool_cursor_update (GimpTool *tool, if (gimp_bucket_fill_tool_coords_in_active_pickable (bucket_tool, display, coords)) { - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable = NULL; - if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) && + if (g_list_length (drawables) == 1) + drawable = drawables->data; + + if (drawable && + ! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) && ! gimp_item_is_content_locked (GIMP_ITEM (drawable)) && (gimp_item_is_visible (GIMP_ITEM (drawable)) || config->edit_non_visible)) @@ -999,7 +1029,12 @@ gimp_bucket_fill_tool_reset_line_art (GimpBucketFillTool *tool) if (image) { - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; + + g_return_if_fail (g_list_length (drawables) == 1); + drawable = drawables->data; + g_list_free (drawables); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) drawable = NULL; diff --git a/app/tools/gimpcagetool.c b/app/tools/gimpcagetool.c index 37bb4c2e58..44a24f4521 100644 --- a/app/tools/gimpcagetool.c +++ b/app/tools/gimpcagetool.c @@ -214,12 +214,25 @@ gimp_cage_tool_initialize (GimpTool *tool, GimpDisplay *display, GError **error) { - GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config); - GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config); + GimpImage *image = gimp_display_get_image (display); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; - if (! drawable) - return FALSE; + if (g_list_length (drawables) != 1) + { + if (g_list_length (drawables) > 1) + g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, + _("Cannot modify multiple layers. Select only one layer.")); + else + g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("No selected drawables.")); + + g_list_free (drawables); + return FALSE; + } + + drawable = drawables->data; + g_list_free (drawables); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { @@ -693,10 +706,16 @@ gimp_cage_tool_cursor_update (GimpTool *tool, } else { - GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpImage *image = gimp_display_get_image (display); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable = NULL; - if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) || + if (g_list_length (drawables) == 1) + drawable = drawables->data; + g_list_free (drawables); + + if (! drawable || + gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) || gimp_item_is_content_locked (GIMP_ITEM (drawable)) || ! (gimp_item_is_visible (GIMP_ITEM (drawable)) || config->edit_non_visible)) @@ -927,10 +946,13 @@ gimp_cage_tool_start (GimpCageTool *ct, { GimpTool *tool = GIMP_TOOL (ct); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables = gimp_image_get_selected_drawables (image); - tool->display = display; - tool->drawable = drawable; + g_return_if_fail (g_list_length (drawables) == 1); + + tool->display = display; + g_list_free (tool->drawables); + tool->drawables = drawables; g_clear_object (&ct->config); @@ -958,7 +980,7 @@ gimp_cage_tool_start (GimpCageTool *ct, /* Setting up cage offset to convert the cage point coords to * drawable coords */ - gimp_item_get_offset (GIMP_ITEM (tool->drawable), + gimp_item_get_offset (GIMP_ITEM (tool->drawables->data), &ct->offset_x, &ct->offset_y); gimp_draw_tool_start (GIMP_DRAW_TOOL (ct), display); @@ -987,9 +1009,10 @@ gimp_cage_tool_halt (GimpCageTool *ct) gimp_image_flush (gimp_display_get_image (tool->display)); } - tool->display = NULL; - tool->drawable = NULL; - ct->tool_state = CAGE_STATE_INIT; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; + ct->tool_state = CAGE_STATE_INIT; g_object_set (gimp_tool_get_options (tool), "cage-mode", GIMP_CAGE_MODE_CAGE_CHANGE, @@ -1274,7 +1297,7 @@ gimp_cage_tool_create_filter (GimpCageTool *ct) if (! ct->render_node) gimp_cage_tool_create_render_node (ct); - ct->filter = gimp_drawable_filter_new (GIMP_TOOL (ct)->drawable, + ct->filter = gimp_drawable_filter_new (GIMP_TOOL (ct)->drawables->data, _("Cage transform"), ct->render_node, GIMP_ICON_TOOL_CAGE); diff --git a/app/tools/gimpcroptool.c b/app/tools/gimpcroptool.c index fa9080da4e..897a7c73b9 100644 --- a/app/tools/gimpcroptool.c +++ b/app/tools/gimpcroptool.c @@ -532,8 +532,9 @@ gimp_crop_tool_halt (GimpCropTool *crop_tool) gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tool), NULL); g_clear_object (&crop_tool->widget); - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; gimp_crop_tool_update_option_defaults (crop_tool, TRUE); } diff --git a/app/tools/gimpcurvestool.c b/app/tools/gimpcurvestool.c index 9112308efa..8d21d8b082 100644 --- a/app/tools/gimpcurvestool.c +++ b/app/tools/gimpcurvestool.c @@ -199,7 +199,8 @@ gimp_curves_tool_initialize (GimpTool *tool, GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (tool); GimpCurvesTool *c_tool = GIMP_CURVES_TOOL (tool); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables; + GimpDrawable *drawable; GimpCurvesConfig *config; GimpHistogram *histogram; GimpHistogramChannel channel; @@ -209,6 +210,21 @@ gimp_curves_tool_initialize (GimpTool *tool, return FALSE; } + drawables = gimp_image_get_selected_drawables (image); + if (g_list_length (drawables) != 1) + { + if (g_list_length (drawables) > 1) + gimp_tool_message_literal (tool, display, + _("Cannot modify multiple drawables. Select only one.")); + else + gimp_tool_message_literal (tool, display, _("No selected drawables.")); + + g_list_free (drawables); + return FALSE; + } + drawable = drawables->data; + g_list_free (drawables); + config = GIMP_CURVES_CONFIG (filter_tool->config); histogram = gimp_histogram_new (config->trc); @@ -713,7 +729,7 @@ gimp_curves_tool_config_notify (GimpFilterTool *filter_tool, histogram = gimp_histogram_new (curves_config->trc); g_object_unref (gimp_drawable_calculate_histogram_async - (GIMP_TOOL (filter_tool)->drawable, histogram, FALSE)); + (GIMP_TOOL (filter_tool)->drawables->data, histogram, FALSE)); gimp_histogram_view_set_background (GIMP_HISTOGRAM_VIEW (curves_tool->graph), histogram); g_object_unref (histogram); @@ -782,7 +798,7 @@ gimp_curves_tool_color_picked (GimpFilterTool *filter_tool, { GimpCurvesTool *tool = GIMP_CURVES_TOOL (filter_tool); GimpCurvesConfig *config = GIMP_CURVES_CONFIG (filter_tool->config); - GimpDrawable *drawable = GIMP_TOOL (tool)->drawable; + GimpDrawable *drawable = GIMP_TOOL (tool)->drawables->data; GimpRGB rgb = *color; if (config->trc == GIMP_TRC_LINEAR) @@ -1015,7 +1031,7 @@ static gboolean curves_menu_sensitivity (gint value, gpointer data) { - GimpDrawable *drawable = GIMP_TOOL (data)->drawable; + GimpDrawable *drawable = GIMP_TOOL (data)->drawables->data; GimpHistogramChannel channel = value; if (!drawable) diff --git a/app/tools/gimpfiltertool-widgets.c b/app/tools/gimpfiltertool-widgets.c index d5cf6fe4b4..b8acd6cb4b 100644 --- a/app/tools/gimpfiltertool-widgets.c +++ b/app/tools/gimpfiltertool-widgets.c @@ -409,7 +409,7 @@ gimp_filter_tool_set_line (Controller *controller, return; tool = GIMP_TOOL (controller->filter_tool); - drawable = tool->drawable; + drawable = tool->drawables->data; if (drawable) { @@ -486,7 +486,7 @@ gimp_filter_tool_set_slider_line (Controller *controller, return; tool = GIMP_TOOL (controller->filter_tool); - drawable = tool->drawable; + drawable = tool->drawables->data; if (drawable) { @@ -572,7 +572,7 @@ gimp_filter_tool_set_transform_grid (Controller *controller, return; tool = GIMP_TOOL (controller->filter_tool); - drawable = tool->drawable; + drawable = tool->drawables->data; if (drawable) { @@ -662,7 +662,7 @@ gimp_filter_tool_set_transform_grids (Controller *controller, tool = GIMP_TOOL (controller->filter_tool); shell = gimp_display_get_shell (tool->display); - drawable = tool->drawable; + drawable = tool->drawables->data; g_signal_handlers_block_by_func (controller->widget, gimp_filter_tool_transform_grids_changed, @@ -885,7 +885,7 @@ gimp_filter_tool_set_focus (Controller *controller, return; tool = GIMP_TOOL (controller->filter_tool); - drawable = tool->drawable; + drawable = tool->drawables->data; if (drawable) { diff --git a/app/tools/gimpfiltertool.c b/app/tools/gimpfiltertool.c index c0da2bb0d6..db877673b1 100644 --- a/app/tools/gimpfiltertool.c +++ b/app/tools/gimpfiltertool.c @@ -283,25 +283,40 @@ gimp_filter_tool_initialize (GimpTool *tool, GimpToolInfo *tool_info = tool->tool_info; GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpDisplayShell *shell = gimp_display_get_shell (display); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; - if (! drawable) - return FALSE; + if (g_list_length (drawables) != 1) + { + if (g_list_length (drawables) > 1) + g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, + _("Cannot modify multiple drawables. Select only one.")); + else + g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("No selected drawables.")); + + g_list_free (drawables); + return FALSE; + } + drawable = drawables->data; if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Cannot modify the pixels of layer groups.")); + + g_list_free (drawables); return FALSE; } if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, - _("The active layer's pixels are locked.")); + _("A selected layer's pixels are locked.")); if (error) gimp_tools_blink_lock_box (display->gimp, GIMP_ITEM (drawable)); + + g_list_free (drawables); return FALSE; } @@ -309,7 +324,9 @@ gimp_filter_tool_initialize (GimpTool *tool, ! config->edit_non_visible) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, - _("The active layer is not visible.")); + _("A selected layer is not visible.")); + + g_list_free (drawables); return FALSE; } @@ -317,8 +334,9 @@ gimp_filter_tool_initialize (GimpTool *tool, gimp_filter_tool_disable_color_picking (filter_tool); - tool->display = display; - tool->drawable = drawable; + tool->display = display; + g_list_free (tool->drawables); + tool->drawables = drawables; if (filter_tool->config) gimp_config_reset (GIMP_CONFIG (filter_tool->config)); @@ -486,7 +504,7 @@ gimp_filter_tool_button_press (GimpTool *tool, } else if (state & gimp_get_toggle_behavior_mask ()) { - GimpItem *item = GIMP_ITEM (tool->drawable); + GimpItem *item = GIMP_ITEM (tool->drawables->data); gdouble pos_x; gdouble pos_y; @@ -702,7 +720,7 @@ gimp_filter_tool_options_notify (GimpTool *tool, if (filter_options->preview_split) { GimpDisplayShell *shell = gimp_display_get_shell (tool->display); - GimpItem *item = GIMP_ITEM (tool->drawable); + GimpItem *item = GIMP_ITEM (tool->drawables->data); gint x, y, width, height; gimp_display_shell_untransform_viewport (shell, TRUE, @@ -723,6 +741,8 @@ gimp_filter_tool_options_notify (GimpTool *tool, position = ((gdouble) ((x + width / 2) - gimp_item_get_offset_x (item)) / (gdouble) gimp_item_get_width (item)); + + } else { @@ -770,7 +790,7 @@ gimp_filter_tool_can_pick_color (GimpColorTool *color_tool, GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (color_tool); GimpImage *image = gimp_display_get_image (display); - if (gimp_image_get_active_drawable (image) != tool->drawable) + if (! gimp_image_equal_selected_drawables (image, tool->drawables)) return FALSE; return filter_tool->pick_abyss || @@ -791,11 +811,13 @@ gimp_filter_tool_pick_color (GimpColorTool *color_tool, gint off_x, off_y; gboolean picked; - gimp_item_get_offset (GIMP_ITEM (tool->drawable), &off_x, &off_y); + g_return_val_if_fail (g_list_length (tool->drawables) == 1, FALSE); - *sample_format = gimp_drawable_get_format (tool->drawable); + gimp_item_get_offset (GIMP_ITEM (tool->drawables->data), &off_x, &off_y); - picked = gimp_pickable_pick_color (GIMP_PICKABLE (tool->drawable), + *sample_format = gimp_drawable_get_format (tool->drawables->data); + + picked = gimp_pickable_pick_color (GIMP_PICKABLE (tool->drawables->data), coords->x - off_x, coords->y - off_y, color_tool->options->sample_average, @@ -946,10 +968,12 @@ gimp_filter_tool_halt (GimpFilterTool *filter_tool) if (tool->display) { GimpImage *image = gimp_display_get_image (tool->display); + GList *iter; - g_signal_handlers_disconnect_by_func (tool->drawable, - gimp_filter_tool_lock_position_changed, - filter_tool); + for (iter = tool->drawables; iter; iter = iter->next) + g_signal_handlers_disconnect_by_func (iter->data, + gimp_filter_tool_lock_position_changed, + filter_tool); g_signal_handlers_disconnect_by_func (image, gimp_filter_tool_mask_changed, @@ -980,7 +1004,6 @@ gimp_filter_tool_halt (GimpFilterTool *filter_tool) { gimp_drawable_filter_abort (filter_tool->filter); g_clear_object (&filter_tool->filter); - gimp_filter_tool_remove_guide (filter_tool); } @@ -1005,8 +1028,9 @@ gimp_filter_tool_halt (GimpFilterTool *filter_tool) gimp_filter_tool_set_widget (filter_tool, NULL); - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; } static void @@ -1194,8 +1218,9 @@ gimp_filter_tool_create_filter (GimpFilterTool *filter_tool) } gimp_assert (filter_tool->operation); + g_return_if_fail (g_list_length (tool->drawables) == 1); - filter_tool->filter = gimp_drawable_filter_new (tool->drawable, + filter_tool->filter = gimp_drawable_filter_new (tool->drawables->data, gimp_tool_get_undo_desc (tool), filter_tool->operation, gimp_tool_get_icon_name (tool)); @@ -1225,16 +1250,18 @@ gimp_filter_tool_update_dialog (GimpFilterTool *filter_tool) GimpChannel *mask = gimp_image_get_mask (image); const Babl *format; + g_return_if_fail (g_list_length (tool->drawables) == 1); + if (filter_tool->filter) format = gimp_drawable_filter_get_format (filter_tool->filter); else - format = gimp_drawable_get_format (tool->drawable); + format = gimp_drawable_get_format (tool->drawables->data); if (gimp_channel_is_empty (mask)) { gtk_widget_set_visible ( filter_tool->clip_combo, - gimp_item_get_clip (GIMP_ITEM (tool->drawable), FALSE) == FALSE && + gimp_item_get_clip (GIMP_ITEM (tool->drawables->data), FALSE) == FALSE && ! gimp_gegl_node_is_point_operation (filter_tool->operation) && babl_format_has_alpha (format)); @@ -1326,10 +1353,12 @@ gimp_filter_tool_add_guide (GimpFilterTool *filter_tool) GimpOrientationType orientation; gint position; + g_return_if_fail (g_list_length (tool->drawables) == 1); + if (filter_tool->preview_guide) return; - item = GIMP_ITEM (tool->drawable); + item = GIMP_ITEM (tool->drawables->data); image = gimp_item_get_image (item); if (options->preview_split_alignment == GIMP_ALIGN_LEFT || @@ -1374,7 +1403,7 @@ gimp_filter_tool_remove_guide (GimpFilterTool *filter_tool) if (! filter_tool->preview_guide) return; - image = gimp_item_get_image (GIMP_ITEM (tool->drawable)); + image = gimp_item_get_image (GIMP_ITEM (tool->drawables->data)); gimp_image_remove_guide (image, filter_tool->preview_guide, FALSE); } @@ -1388,10 +1417,12 @@ gimp_filter_tool_move_guide (GimpFilterTool *filter_tool) GimpOrientationType orientation; gint position; + g_return_if_fail (g_list_length (tool->drawables) == 1); + if (! filter_tool->preview_guide) return; - item = GIMP_ITEM (tool->drawable); + item = GIMP_ITEM (tool->drawables->data); if (options->preview_split_alignment == GIMP_ALIGN_LEFT || options->preview_split_alignment == GIMP_ALIGN_RIGHT) @@ -1447,9 +1478,13 @@ gimp_filter_tool_guide_moved (GimpGuide *guide, { GimpTool *tool = GIMP_TOOL (filter_tool); GimpFilterOptions *options = GIMP_FILTER_TOOL_GET_OPTIONS (filter_tool); - GimpItem *item = GIMP_ITEM (tool->drawable); + GimpItem *item; gdouble position; + g_return_if_fail (g_list_length (tool->drawables) == 1); + + item = GIMP_ITEM (tool->drawables->data); + if (options->preview_split_alignment == GIMP_ALIGN_LEFT || options->preview_split_alignment == GIMP_ALIGN_RIGHT) { @@ -1680,7 +1715,7 @@ gimp_filter_tool_get_operation (GimpFilterTool *filter_tool) G_CALLBACK (gimp_filter_tool_config_notify), G_OBJECT (filter_tool), 0); - if (tool->drawable) + if (tool->drawables) gimp_filter_tool_create_filter (filter_tool); } @@ -1991,6 +2026,8 @@ gimp_filter_tool_get_drawable_area (GimpFilterTool *filter_tool, tool = GIMP_TOOL (filter_tool); settings = GIMP_OPERATION_SETTINGS (filter_tool->config); + g_return_val_if_fail (g_list_length (tool->drawables) == 1, FALSE); + *drawable_offset_x = 0; *drawable_offset_y = 0; @@ -1999,7 +2036,7 @@ gimp_filter_tool_get_drawable_area (GimpFilterTool *filter_tool, drawable_area->width = 1; drawable_area->height = 1; - drawable = tool->drawable; + drawable = tool->drawables->data; if (drawable && settings) { diff --git a/app/tools/gimpforegroundselecttool.c b/app/tools/gimpforegroundselecttool.c index bc72235feb..852a6e1c90 100644 --- a/app/tools/gimpforegroundselecttool.c +++ b/app/tools/gimpforegroundselecttool.c @@ -282,11 +282,23 @@ gimp_foreground_select_tool_initialize (GimpTool *tool, GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool); GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpDisplayShell *shell = gimp_display_get_shell (display); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; - if (! drawable) - return FALSE; + if (g_list_length (drawables) != 1) + { + if (g_list_length (drawables) > 1) + g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, + _("Cannot select from multiple layers.")); + else + g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("No selected drawables.")); + + g_list_free (drawables); + return FALSE; + } + drawable = drawables->data; + g_list_free (drawables); if (! gimp_item_is_visible (GIMP_ITEM (drawable)) && ! config->edit_non_visible) @@ -910,8 +922,15 @@ gimp_foreground_select_tool_confirm (GimpPolygonSelectTool *poly_sel, { GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (poly_sel); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); - GimpItem *item = GIMP_ITEM (drawable); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; + GimpItem *item; + + g_return_if_fail (g_list_length (drawables) == 1); + + drawable = drawables->data; + item = GIMP_ITEM (drawable); + g_list_free (drawables); if (drawable && fg_select->state == MATTING_STATE_FREE_SELECT) { @@ -995,8 +1014,9 @@ gimp_foreground_select_tool_halt (GimpForegroundSelectTool *fg_select) if (tool->display) gimp_image_flush (gimp_display_get_image (tool->display)); - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; if (fg_select->gui) gimp_tool_gui_hide (fg_select->gui); @@ -1131,10 +1151,16 @@ gimp_foreground_select_tool_set_preview (GimpForegroundSelectTool *fg_select) static void gimp_foreground_select_tool_preview (GimpForegroundSelectTool *fg_select) { - GimpTool *tool = GIMP_TOOL (fg_select); + GimpTool *tool = GIMP_TOOL (fg_select); GimpForegroundSelectOptions *options; - GimpImage *image = gimp_display_get_image (tool->display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpImage *image = gimp_display_get_image (tool->display); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; + + g_return_if_fail (g_list_length (drawables) == 1); + + drawable = drawables->data; + g_list_free (drawables); options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool); diff --git a/app/tools/gimpgradienttool.c b/app/tools/gimpgradienttool.c index ddae75a8b3..421ee40ca3 100644 --- a/app/tools/gimpgradienttool.c +++ b/app/tools/gimpgradienttool.c @@ -239,9 +239,9 @@ gimp_gradient_tool_initialize (GimpTool *tool, GError **error) { GimpImage *image = gimp_display_get_image (display); - GList *drawables = gimp_image_get_selected_drawables (image); GimpGradientOptions *options = GIMP_GRADIENT_TOOL_GET_OPTIONS (tool); GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config); + GList *drawables; GimpDrawable *drawable; if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error)) @@ -249,6 +249,7 @@ gimp_gradient_tool_initialize (GimpTool *tool, return FALSE; } + drawables = gimp_image_get_selected_drawables (image); if (g_list_length (drawables) != 1) { if (g_list_length (drawables) > 1) @@ -482,8 +483,10 @@ gimp_gradient_tool_cursor_update (GimpTool *tool, gimp_tool_control_get_cursor (tool->control), gimp_tool_control_get_tool_cursor (tool->control), GIMP_CURSOR_MODIFIER_BAD); + g_list_free (drawables); return; } + g_list_free (drawables); GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display); } @@ -634,9 +637,9 @@ gimp_gradient_tool_start (GimpGradientTool *gradient_tool, if (options->instant_toggle) gtk_widget_set_sensitive (options->instant_toggle, FALSE); - tool->display = display; - tool->drawable = drawables->data; - g_list_free (drawables); + tool->display = display; + g_list_free (tool->drawables); + tool->drawables = drawables; gradient_tool->start_x = coords->x; gradient_tool->start_y = coords->y; @@ -669,7 +672,7 @@ gimp_gradient_tool_start (GimpGradientTool *gradient_tool, G_CALLBACK (gimp_gradient_tool_fg_bg_changed), gradient_tool); - gimp_gradient_tool_create_filter (gradient_tool, tool->drawable); + gimp_gradient_tool_create_filter (gradient_tool, tool->drawables->data); /* Initially sync all of the properties */ gimp_operation_config_sync_node (G_OBJECT (options), @@ -742,8 +745,9 @@ gimp_gradient_tool_halt (GimpGradientTool *gradient_tool) gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tool), NULL); g_clear_object (&gradient_tool->widget); - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; if (options->instant_toggle) gtk_widget_set_sensitive (options->instant_toggle, TRUE); @@ -840,15 +844,17 @@ gimp_gradient_tool_precalc_shapeburst (GimpGradientTool *gradient_tool) GimpTool *tool = GIMP_TOOL (gradient_tool); gint x, y, width, height; - if (gradient_tool->dist_buffer || ! tool->drawable) + if (gradient_tool->dist_buffer || ! tool->drawables) return; - if (! gimp_item_mask_intersect (GIMP_ITEM (tool->drawable), + g_return_if_fail (g_list_length (tool->drawables) == 1); + + if (! gimp_item_mask_intersect (GIMP_ITEM (tool->drawables->data), &x, &y, &width, &height)) return; gradient_tool->dist_buffer = - gimp_drawable_gradient_shapeburst_distmap (tool->drawable, + gimp_drawable_gradient_shapeburst_distmap (tool->drawables->data, options->distance_metric, GEGL_RECTANGLE (x, y, width, height), GIMP_PROGRESS (gradient_tool)); @@ -924,7 +930,7 @@ gimp_gradient_tool_update_graph (GimpGradientTool *gradient_tool) GimpGradientOptions *options = GIMP_GRADIENT_TOOL_GET_OPTIONS (gradient_tool); gint off_x, off_y; - gimp_item_get_offset (GIMP_ITEM (tool->drawable), &off_x, &off_y); + gimp_item_get_offset (GIMP_ITEM (tool->drawables->data), &off_x, &off_y); #if 0 if (gimp_gradient_tool_is_shapeburst (gradient_tool)) @@ -962,7 +968,7 @@ gimp_gradient_tool_update_graph (GimpGradientTool *gradient_tool) gdouble start_x, start_y; gdouble end_x, end_y; - gimp_item_mask_intersect (GIMP_ITEM (tool->drawable), + gimp_item_mask_intersect (GIMP_ITEM (tool->drawables->data), &roi.x, &roi.y, &roi.width, &roi.height); start_x = gradient_tool->start_x - off_x; @@ -970,7 +976,7 @@ gimp_gradient_tool_update_graph (GimpGradientTool *gradient_tool) end_x = gradient_tool->end_x - off_x; end_y = gradient_tool->end_y - off_y; - gimp_drawable_gradient_adjust_coords (tool->drawable, + gimp_drawable_gradient_adjust_coords (tool->drawables->data, options->gradient_type, &roi, &start_x, &start_y, &end_x, &end_y); diff --git a/app/tools/gimplevelstool.c b/app/tools/gimplevelstool.c index 2620cf37a6..dd29d74726 100644 --- a/app/tools/gimplevelstool.c +++ b/app/tools/gimplevelstool.c @@ -187,7 +187,8 @@ gimp_levels_tool_initialize (GimpTool *tool, GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (tool); GimpLevelsTool *l_tool = GIMP_LEVELS_TOOL (tool); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables; + GimpDrawable *drawable; GimpLevelsConfig *config; gdouble scale_factor; gdouble step_increment; @@ -199,6 +200,22 @@ gimp_levels_tool_initialize (GimpTool *tool, return FALSE; } + drawables = gimp_image_get_selected_drawables (image); + if (g_list_length (drawables) != 1) + { + if (g_list_length (drawables) > 1) + gimp_tool_message_literal (tool, display, + _("Cannot modify multiple drawables. Select only one.")); + else + gimp_tool_message_literal (tool, display, _("No selected drawables.")); + + g_list_free (drawables); + return FALSE; + } + + drawable = drawables->data; + g_list_free (drawables); + config = GIMP_LEVELS_CONFIG (filter_tool->config); g_clear_object (&l_tool->histogram); @@ -679,7 +696,7 @@ gimp_levels_tool_config_notify (GimpFilterTool *filter_tool, levels_tool->histogram = gimp_histogram_new (levels_config->trc); levels_tool->histogram_async = gimp_drawable_calculate_histogram_async - (GIMP_TOOL (filter_tool)->drawable, levels_tool->histogram, FALSE); + (GIMP_TOOL (filter_tool)->drawables->data, levels_tool->histogram, FALSE); gimp_histogram_view_set_histogram (GIMP_HISTOGRAM_VIEW (levels_tool->histogram_view), levels_tool->histogram); } @@ -949,12 +966,14 @@ static gboolean levels_menu_sensitivity (gint value, gpointer data) { - GimpDrawable *drawable = GIMP_TOOL (data)->drawable; + GimpDrawable *drawable; GimpHistogramChannel channel = value; - if (!drawable) + if (! GIMP_TOOL (data)->drawables) return FALSE; + drawable = GIMP_TOOL (data)->drawables->data; + switch (channel) { case GIMP_HISTOGRAM_VALUE: @@ -998,7 +1017,7 @@ levels_stretch_callback (GtkWidget *widget, { gimp_levels_config_stretch (GIMP_LEVELS_CONFIG (filter_tool->config), levels_tool->histogram, - gimp_drawable_is_rgb (tool->drawable)); + gimp_drawable_is_rgb (tool->drawables->data)); } } diff --git a/app/tools/gimpnpointdeformationtool.c b/app/tools/gimpnpointdeformationtool.c index 0b653dee34..e44f4bad80 100644 --- a/app/tools/gimpnpointdeformationtool.c +++ b/app/tools/gimpnpointdeformationtool.c @@ -246,13 +246,16 @@ gimp_n_point_deformation_tool_start (GimpNPointDeformationTool *npd_tool, image = gimp_display_get_image (display); - tool->display = display; - tool->drawable = gimp_image_get_active_drawable (image); + tool->display = display; + g_list_free (tool->drawables); + tool->drawables = gimp_image_get_selected_drawables (image); npd_tool->active = TRUE; + g_return_if_fail (g_list_length (tool->drawables) == 1); + /* create GEGL graph */ - source_buffer = gimp_drawable_get_buffer (tool->drawable); + source_buffer = gimp_drawable_get_buffer (tool->drawables->data); preview_buffer = gegl_buffer_new (gegl_buffer_get_extent (source_buffer), babl_format ("cairo-ARGB32")); @@ -293,7 +296,7 @@ gimp_n_point_deformation_tool_start (GimpNPointDeformationTool *npd_tool, npd_tool->lattice_points = g_new (GimpVector2, 5 * model->hidden_model->num_of_bones); - gimp_item_get_offset (GIMP_ITEM (tool->drawable), + gimp_item_get_offset (GIMP_ITEM (tool->drawables->data), &npd_tool->offset_x, &npd_tool->offset_y); gimp_npd_debug (("offset: %f %f\n", npd_tool->offset_x, npd_tool->offset_y)); @@ -302,7 +305,7 @@ gimp_n_point_deformation_tool_start (GimpNPointDeformationTool *npd_tool, gimp_n_point_deformation_tool_perform_deformation (npd_tool); /* hide original image */ - gimp_item_set_visible (GIMP_ITEM (tool->drawable), FALSE, FALSE); + gimp_item_set_visible (GIMP_ITEM (tool->drawables->data), FALSE, FALSE); gimp_image_flush (image); /* create and start a deformation thread */ @@ -334,7 +337,7 @@ gimp_n_point_deformation_tool_commit (GimpNPointDeformationTool *npd_tool) gimp_tool_control_pop_preserve (tool->control); /* show original/deformed image */ - gimp_item_set_visible (GIMP_ITEM (tool->drawable), TRUE, FALSE); + gimp_item_set_visible (GIMP_ITEM (tool->drawables->data), TRUE, FALSE); gimp_image_flush (gimp_display_get_image (tool->display)); npd_tool->active = FALSE; @@ -355,7 +358,7 @@ gimp_n_point_deformation_tool_halt (GimpNPointDeformationTool *npd_tool) gimp_n_point_deformation_tool_halt_threads (npd_tool); /* show original/deformed image */ - gimp_item_set_visible (GIMP_ITEM (tool->drawable), TRUE, FALSE); + gimp_item_set_visible (GIMP_ITEM (tool->drawables->data), TRUE, FALSE); gimp_image_flush (gimp_display_get_image (tool->display)); /* disable some options */ @@ -377,8 +380,9 @@ gimp_n_point_deformation_tool_halt (GimpNPointDeformationTool *npd_tool) g_clear_object (&npd_tool->preview_buffer); g_clear_pointer (&npd_tool->lattice_points, g_free); - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; } static void @@ -890,7 +894,7 @@ gimp_n_point_deformation_tool_motion (GimpTool *tool, static gboolean gimp_n_point_deformation_tool_canvas_update_timeout (GimpNPointDeformationTool *npd_tool) { - if (! GIMP_TOOL (npd_tool)->drawable) + if (! GIMP_TOOL (npd_tool)->drawables->data) return FALSE; gimp_npd_debug (("canvas update thread\n")); @@ -989,7 +993,7 @@ gimp_n_point_deformation_tool_apply_deformation (GimpNPointDeformationTool *npd_ npd_options = GIMP_N_POINT_DEFORMATION_TOOL_GET_OPTIONS (npd_tool); image = gimp_display_get_image (tool->display); - buffer = gimp_drawable_get_buffer (tool->drawable); + buffer = gimp_drawable_get_buffer (tool->drawables->data); width = gegl_buffer_get_width (buffer); height = gegl_buffer_get_height (buffer); @@ -999,16 +1003,16 @@ gimp_n_point_deformation_tool_apply_deformation (GimpNPointDeformationTool *npd_ gimp_n_point_deformation_tool_set_options (npd_tool, npd_options); npd_options->rigidity = prev; - gimp_drawable_push_undo (tool->drawable, _("N-Point Deformation"), NULL, + gimp_drawable_push_undo (tool->drawables->data, _("N-Point Deformation"), NULL, 0, 0, width, height); gimp_gegl_apply_operation (NULL, NULL, _("N-Point Deformation"), npd_tool->npd_node, - gimp_drawable_get_buffer (tool->drawable), + gimp_drawable_get_buffer (tool->drawables->data), NULL, FALSE); - gimp_drawable_update (tool->drawable, + gimp_drawable_update (tool->drawables->data, 0, 0, width, height); gimp_projection_flush (gimp_image_get_projection (image)); diff --git a/app/tools/gimpoffsettool.c b/app/tools/gimpoffsettool.c index 7b9536a102..ce7f00309a 100644 --- a/app/tools/gimpoffsettool.c +++ b/app/tools/gimpoffsettool.c @@ -173,13 +173,27 @@ gimp_offset_tool_initialize (GimpTool *tool, GimpOffsetTool *offset_tool = GIMP_OFFSET_TOOL (tool); GimpContext *context = GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (tool)); GimpImage *image; + GimpDrawable *drawable; gdouble xres; gdouble yres; if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error)) return FALSE; - image = gimp_item_get_image (GIMP_ITEM (tool->drawable)); + if (g_list_length (tool->drawables) != 1) + { + if (g_list_length (tool->drawables) > 1) + gimp_tool_message_literal (tool, display, + _("Cannot modify multiple drawables. Select only one.")); + else + gimp_tool_message_literal (tool, display, _("No selected drawables.")); + + return FALSE; + } + + drawable = tool->drawables->data; + + image = gimp_item_get_image (GIMP_ITEM (drawable)); gimp_image_get_resolution (image, &xres, &yres); @@ -194,17 +208,17 @@ gimp_offset_tool_initialize (GimpTool *tool, GIMP_SIZE_ENTRY (offset_tool->offset_se), 1, yres, FALSE); - if (GIMP_IS_LAYER (tool->drawable)) + if (GIMP_IS_LAYER (drawable)) gimp_tool_gui_set_description (filter_tool->gui, _("Offset Layer")); - else if (GIMP_IS_LAYER_MASK (tool->drawable)) + else if (GIMP_IS_LAYER_MASK (drawable)) gimp_tool_gui_set_description (filter_tool->gui, _("Offset Layer Mask")); - else if (GIMP_IS_CHANNEL (tool->drawable)) + else if (GIMP_IS_CHANNEL (drawable)) gimp_tool_gui_set_description (filter_tool->gui, _("Offset Channel")); else g_warning ("%s: unexpected drawable type", G_STRFUNC); gtk_widget_set_sensitive (offset_tool->transparent_radio, - gimp_drawable_has_alpha (tool->drawable)); + gimp_drawable_has_alpha (drawable)); g_signal_handlers_unblock_by_func (offset_tool->offset_se, gimp_offset_tool_offset_changed, @@ -403,7 +417,7 @@ gimp_offset_tool_oper_update (GimpTool *tool, gboolean proximity, GimpDisplay *display) { - if (! tool->drawable || + if (! tool->drawables || gimp_filter_tool_on_guide (GIMP_FILTER_TOOL (tool), coords, display)) { @@ -425,7 +439,7 @@ gimp_offset_tool_cursor_update (GimpTool *tool, GdkModifierType state, GimpDisplay *display) { - if (! tool->drawable || + if (! tool->drawables || gimp_filter_tool_on_guide (GIMP_FILTER_TOOL (tool), coords, display)) { @@ -708,8 +722,8 @@ gimp_offset_tool_update (GimpOffsetTool *offset_tool) type = orig_type; - if (tool->drawable && - ! gimp_drawable_has_alpha (tool->drawable) && + if (tool->drawables && + ! gimp_drawable_has_alpha (tool->drawables->data) && type == GIMP_OFFSET_TRANSPARENT) { type = GIMP_OFFSET_BACKGROUND; diff --git a/app/tools/gimpoperationtool.c b/app/tools/gimpoperationtool.c index d5894dc19f..ba7fd7c49b 100644 --- a/app/tools/gimpoperationtool.c +++ b/app/tools/gimpoperationtool.c @@ -292,7 +292,7 @@ gimp_operation_tool_reset (GimpFilterTool *filter_tool) GIMP_FILTER_TOOL_CLASS (parent_class)->reset (filter_tool); - if (filter_tool->config && GIMP_TOOL (op_tool)->drawable) + if (filter_tool->config && GIMP_TOOL (op_tool)->drawables) gimp_operation_tool_sync_op (op_tool, TRUE); gimp_operation_tool_relink_chains (op_tool); @@ -308,7 +308,7 @@ gimp_operation_tool_set_config (GimpFilterTool *filter_tool, GIMP_FILTER_TOOL_CLASS (parent_class)->set_config (filter_tool, config); - if (filter_tool->config && GIMP_TOOL (op_tool)->drawable) + if (filter_tool->config && GIMP_TOOL (op_tool)->drawables) gimp_operation_tool_sync_op (op_tool, FALSE); gimp_operation_tool_relink_chains (op_tool); @@ -857,7 +857,7 @@ gimp_operation_tool_set_operation (GimpOperationTool *op_tool, gimp_filter_tool_get_operation (filter_tool); - if (tool->drawable) + if (tool->drawables) gimp_operation_tool_sync_op (op_tool, TRUE); if (filter_tool->config && tool->display) diff --git a/app/tools/gimppainttool.c b/app/tools/gimppainttool.c index 011457604a..0aa2edc968 100644 --- a/app/tools/gimppainttool.c +++ b/app/tools/gimppainttool.c @@ -276,7 +276,8 @@ gimp_paint_tool_button_press (GimpTool *tool, GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config); GimpDisplayShell *shell = gimp_display_get_shell (display); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables; + GimpDrawable *drawable; gboolean constrain; GError *error = NULL; @@ -287,20 +288,28 @@ gimp_paint_tool_button_press (GimpTool *tool, return; } - if (! drawable) + drawables = gimp_image_get_selected_drawables (image); + if (g_list_length (drawables) != 1) { - if (g_list_length (gimp_image_get_selected_layers (image)) > 1) + if (g_list_length (drawables) > 1) gimp_tool_message_literal (tool, display, - _("Cannot paint on multiple layer. Select only one layer.")); + _("Cannot paint on multiple layers. Select only one layer.")); else gimp_tool_message_literal (tool, display, - _("No active drawable.")); + _("No selected drawables.")); + + g_list_free (drawables); return; } - else if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) + + drawable = drawables->data; + + if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { gimp_tool_message_literal (tool, display, _("Cannot paint on layer groups.")); + g_list_free (drawables); + return; } @@ -309,6 +318,8 @@ gimp_paint_tool_button_press (GimpTool *tool, gimp_tool_message_literal (tool, display, _("The active layer's pixels are locked.")); gimp_tools_blink_lock_box (display->gimp, GIMP_ITEM (drawable)); + g_list_free (drawables); + return; } @@ -327,6 +338,7 @@ gimp_paint_tool_button_press (GimpTool *tool, gimp_widget_blink (mode_box); g_clear_error (&error); + g_list_free (drawables); return; } @@ -336,6 +348,8 @@ gimp_paint_tool_button_press (GimpTool *tool, { gimp_tool_message_literal (tool, display, _("The active layer is not visible.")); + g_list_free (drawables); + return; } @@ -366,8 +380,8 @@ gimp_paint_tool_button_press (GimpTool *tool, return; } - tool->display = display; - tool->drawable = drawable; + tool->display = display; + tool->drawables = drawables; /* pause the current selection */ gimp_display_shell_selection_pause (shell); @@ -517,13 +531,20 @@ gimp_paint_tool_cursor_update (GimpTool *tool, if (! gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool))) { - GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpImage *image = gimp_display_get_image (display); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable = NULL; - if (! drawable) + if (! drawables) return; - if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) || + if (g_list_length (drawables) == 1) + drawable = drawables->data; + + g_list_free (drawables); + + if (! drawable || + gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) || gimp_item_is_content_locked (GIMP_ITEM (drawable)) || ! gimp_paint_tool_check_alpha (paint_tool, drawable, display, NULL) || ! (gimp_item_is_visible (GIMP_ITEM (drawable)) || @@ -574,7 +595,7 @@ gimp_paint_tool_oper_update (GimpTool *tool, GimpPaintCore *core = paint_tool->core; GimpDisplayShell *shell = gimp_display_get_shell (display); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables; if (gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool))) { @@ -604,7 +625,8 @@ gimp_paint_tool_oper_update (GimpTool *tool, tool->display = display; } - if (drawable && proximity) + drawables = gimp_image_get_selected_drawables (image); + if (g_list_length (drawables) == 1 && proximity) { gchar *status; gboolean constrain_mask = gimp_get_constrain_behavior_mask (); @@ -612,7 +634,7 @@ gimp_paint_tool_oper_update (GimpTool *tool, core->cur_coords = *coords; - gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); + gimp_item_get_offset (GIMP_ITEM (drawables->data), &off_x, &off_y); core->cur_coords.x -= off_x; core->cur_coords.y -= off_y; @@ -691,6 +713,7 @@ gimp_paint_tool_oper_update (GimpTool *tool, display); gimp_draw_tool_resume (draw_tool); + g_list_free (drawables); } static void @@ -698,17 +721,22 @@ gimp_paint_tool_draw (GimpDrawTool *draw_tool) { GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (draw_tool); - if (paint_tool->active && ! gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (draw_tool))) { GimpPaintCore *core = paint_tool->core; GimpImage *image = gimp_display_get_image (draw_tool->display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpCanvasItem *outline = NULL; gboolean line_drawn = FALSE; gdouble cur_x, cur_y; gint off_x, off_y; + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; + + g_return_if_fail (g_list_length (drawables) == 1); + + drawable = drawables->data; + g_list_free (drawables); gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); diff --git a/app/tools/gimpperspectiveclonetool.c b/app/tools/gimpperspectiveclonetool.c index 6630028060..b59d3a9869 100644 --- a/app/tools/gimpperspectiveclonetool.c +++ b/app/tools/gimpperspectiveclonetool.c @@ -209,20 +209,35 @@ gimp_perspective_clone_tool_initialize (GimpTool *tool, GError **error) { GimpPerspectiveCloneTool *clone_tool = GIMP_PERSPECTIVE_CLONE_TOOL (tool); + GimpImage *image = gimp_display_get_image (display); + GList *drawables; if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error)) { return FALSE; } + drawables = gimp_image_get_selected_drawables (image); + if (g_list_length (drawables) != 1) + { + if (g_list_length (drawables) > 1) + gimp_tool_message_literal (tool, display, + _("Cannot paint on multiple layers. Select only one layer.")); + else + gimp_tool_message_literal (tool, display, _("No selected drawables.")); + + g_list_free (drawables); + + return FALSE; + } + if (display != tool->display) { GimpDisplayShell *shell = gimp_display_get_shell (display); - GimpImage *image = gimp_display_get_image (display); gint i; - tool->display = display; - tool->drawable = gimp_image_get_active_drawable (image); + tool->display = display; + tool->drawables = drawables; /* Find the transform bounds initializing */ gimp_perspective_clone_tool_bounds (clone_tool, display); @@ -269,6 +284,10 @@ gimp_perspective_clone_tool_initialize (GimpTool *tool, for (i = 0; i < TRANS_INFO_SIZE; i++) clone_tool->old_trans_info[i] = clone_tool->trans_info[i]; } + else + { + g_list_free (drawables); + } return TRUE; } @@ -777,8 +796,9 @@ gimp_perspective_clone_tool_halt (GimpPerspectiveCloneTool *clone_tool) g_clear_object (&clone_tool->widget); - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; } static void diff --git a/app/tools/gimpseamlessclonetool.c b/app/tools/gimpseamlessclonetool.c index 79a97806d3..69beee0865 100644 --- a/app/tools/gimpseamlessclonetool.c +++ b/app/tools/gimpseamlessclonetool.c @@ -279,9 +279,15 @@ static void gimp_seamless_clone_tool_start (GimpSeamlessCloneTool *sc, GimpDisplay *display) { - GimpTool *tool = GIMP_TOOL (sc); - GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpTool *tool = GIMP_TOOL (sc); + GimpImage *image = gimp_display_get_image (display); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; + + g_return_if_fail (g_list_length (drawables) == 1); + + drawable = drawables->data; + g_list_free (drawables); /* First handle the paste - we need to make sure we have one in order * to do anything else. @@ -718,7 +724,7 @@ gimp_seamless_clone_tool_render_node_update (GimpSeamlessCloneTool *sc) static gint rendered_yoff = G_MAXINT; GimpSeamlessCloneOptions *options = GIMP_SEAMLESS_CLONE_TOOL_GET_OPTIONS (sc); - GimpDrawable *bg = GIMP_TOOL (sc)->drawable; + GimpDrawable *bg = GIMP_TOOL (sc)->drawables->data; gint off_x, off_y; /* All properties stay the same. No need to update. */ @@ -775,7 +781,7 @@ gimp_seamless_clone_tool_filter_update (GimpSeamlessCloneTool *sc) { GimpTool *tool = GIMP_TOOL (sc); GimpDisplayShell *shell = gimp_display_get_shell (tool->display); - GimpItem *item = GIMP_ITEM (tool->drawable); + GimpItem *item = GIMP_ITEM (tool->drawables->data); gint x, y; gint w, h; gint off_x, off_y; diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c index 5398ab7d47..9fa6f5dd2c 100644 --- a/app/tools/gimptexttool.c +++ b/app/tools/gimptexttool.c @@ -1102,8 +1102,9 @@ gimp_text_tool_halt (GimpTextTool *text_tool) gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tool), NULL); g_clear_object (&text_tool->widget); - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; } static void @@ -2223,7 +2224,8 @@ gimp_text_tool_set_layer (GimpTextTool *text_tool, return FALSE; } - tool->drawable = GIMP_DRAWABLE (layer); + g_list_free (tool->drawables); + tool->drawables = g_list_prepend (NULL, GIMP_DRAWABLE (layer)); } } diff --git a/app/tools/gimpthresholdtool.c b/app/tools/gimpthresholdtool.c index 826045d551..cdececd7b1 100644 --- a/app/tools/gimpthresholdtool.c +++ b/app/tools/gimpthresholdtool.c @@ -139,7 +139,8 @@ gimp_threshold_tool_initialize (GimpTool *tool, GimpThresholdTool *t_tool = GIMP_THRESHOLD_TOOL (tool); GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (tool); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables; + GimpDrawable *drawable; gdouble low; gdouble high; gint n_bins; @@ -149,6 +150,22 @@ gimp_threshold_tool_initialize (GimpTool *tool, return FALSE; } + drawables = gimp_image_get_selected_drawables (image); + if (g_list_length (drawables) != 1) + { + if (g_list_length (drawables) > 1) + gimp_tool_message_literal (tool, display, + _("Cannot modify multiple drawables. Select only one.")); + else + gimp_tool_message_literal (tool, display, _("No selected drawables.")); + + g_list_free (drawables); + return FALSE; + } + + drawable = drawables->data; + g_list_free (drawables); + g_clear_object (&t_tool->histogram_async); g_object_get (filter_tool->config, @@ -338,12 +355,16 @@ static gboolean gimp_threshold_tool_channel_sensitive (gint value, gpointer data) { - GimpDrawable *drawable = GIMP_TOOL (data)->drawable; - GimpHistogramChannel channel = value; + GList *drawables = GIMP_TOOL (data)->drawables; + GimpDrawable *drawable; + GimpHistogramChannel channel = value; - if (!drawable) + if (!drawables) return FALSE; + g_return_val_if_fail (g_list_length (drawables) == 1, FALSE); + drawable = drawables->data; + switch (channel) { case GIMP_HISTOGRAM_VALUE: diff --git a/app/tools/gimptool.c b/app/tools/gimptool.c index 99842ce542..0ad73e1ee1 100644 --- a/app/tools/gimptool.c +++ b/app/tools/gimptool.c @@ -197,7 +197,7 @@ gimp_tool_init (GimpTool *tool) tool->ID = global_tool_ID++; tool->control = g_object_new (GIMP_TYPE_TOOL_CONTROL, NULL); tool->display = NULL; - tool->drawable = NULL; + tool->drawables = NULL; tool->focus_display = NULL; tool->modifier_state = 0; tool->active_modifier_state = 0; @@ -331,8 +331,9 @@ gimp_tool_real_control (GimpTool *tool, break; case GIMP_TOOL_ACTION_HALT: - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; break; case GIMP_TOOL_ACTION_COMMIT: @@ -352,8 +353,9 @@ gimp_tool_real_button_press (GimpTool *tool, { GimpImage *image = gimp_display_get_image (display); - tool->display = display; - tool->drawable = gimp_image_get_active_drawable (image); + tool->display = display; + g_list_free (tool->drawables); + tool->drawables = gimp_image_get_selected_drawables (image); gimp_tool_control_activate (tool->control); } diff --git a/app/tools/gimptool.h b/app/tools/gimptool.h index 171636338d..aeaef5163a 100644 --- a/app/tools/gimptool.h +++ b/app/tools/gimptool.h @@ -50,7 +50,7 @@ struct _GimpTool GimpToolControl *control; GimpDisplay *display; /* pointer to currently active display */ - GimpDrawable *drawable; /* pointer to the tool's current drawable */ + GList *drawables; /* list of the tool's current drawables */ /* private state of gimp_tool_set_focus_display() and * gimp_tool_set_[active_]modifier_state() diff --git a/app/tools/gimptransformgridtool.c b/app/tools/gimptransformgridtool.c index 8802850bb0..191c56dc4f 100644 --- a/app/tools/gimptransformgridtool.c +++ b/app/tools/gimptransformgridtool.c @@ -339,7 +339,7 @@ gimp_transform_grid_tool_initialize (GimpTool *tool, GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); GimpTransformGridOptions *tg_options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tool); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GList *drawables; GimpObject *object; UndoInfo *undo_info; @@ -348,8 +348,21 @@ gimp_transform_grid_tool_initialize (GimpTool *tool, if (! object) return FALSE; + drawables = gimp_image_get_selected_drawables (image); + if (g_list_length (drawables) != 1) + { + if (g_list_length (drawables) > 1) + gimp_tool_message_literal (tool, display, + _("Cannot modify multiple drawables. Select only one.")); + else + gimp_tool_message_literal (tool, display, _("No active drawables.")); + + g_list_free (drawables); + return FALSE; + } + tool->display = display; - tool->drawable = drawable; + tool->drawables = drawables; tr_tool->object = object; @@ -762,7 +775,9 @@ gimp_transform_grid_tool_draw (GimpDrawTool *draw_tool) } else { - pickable = GIMP_PICKABLE (tool->drawable); + g_return_if_fail (g_list_length (tool->drawables) == 1); + + pickable = GIMP_PICKABLE (tool->drawables->data); } tg_tool->preview = @@ -1209,7 +1224,8 @@ gimp_transform_grid_tool_halt (GimpTransformGridTool *tg_tool) } tool->display = NULL; - tool->drawable = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; if (tr_tool->object) { @@ -1720,7 +1736,7 @@ gimp_transform_grid_tool_update_preview (GimpTransformGridTool *tg_tool) g_object_set ( tg_tool->preview, "transform", &tr_tool->transform, - "clip", gimp_item_get_clip (GIMP_ITEM (tool->drawable), + "clip", gimp_item_get_clip (GIMP_ITEM (tool->drawables->data), tr_options->clip), "opacity", tg_options->preview_opacity, NULL); @@ -1781,8 +1797,10 @@ gimp_transform_grid_tool_update_filters (GimpTransformGridTool *tg_tool) if (! tg_tool->filters) return; + g_return_if_fail (g_list_length (tool->drawables) == 1); + if (options->preview_linked && - gimp_item_get_linked (GIMP_ITEM (tool->drawable))) + gimp_item_get_linked (GIMP_ITEM (tool->drawables->data))) { GimpImage *image = gimp_display_get_image (tool->display); @@ -1795,7 +1813,7 @@ gimp_transform_grid_tool_update_filters (GimpTransformGridTool *tg_tool) } else { - drawables = g_list_prepend (NULL, tool->drawable); + drawables = g_list_copy (tool->drawables); } new_drawables = g_hash_table_new (g_direct_hash, g_direct_equal); diff --git a/app/tools/gimpwarptool.c b/app/tools/gimpwarptool.c index 1ab17b95b0..de60c2debc 100644 --- a/app/tools/gimpwarptool.c +++ b/app/tools/gimpwarptool.c @@ -311,6 +311,8 @@ gimp_warp_tool_button_press (GimpTool *tool, if (! gimp_warp_tool_can_stroke (wt, display, TRUE)) return; + g_return_if_fail (g_list_length (tool->drawables) == 1); + wt->current_stroke = gegl_path_new (); wt->last_pos.x = coords->x; @@ -334,7 +336,7 @@ gimp_warp_tool_button_press (GimpTool *tool, gimp_warp_tool_add_op (wt, new_op); g_object_unref (new_op); - gimp_item_get_offset (GIMP_ITEM (tool->drawable), &off_x, &off_y); + gimp_item_get_offset (GIMP_ITEM (tool->drawables->data), &off_x, &off_y); gimp_warp_tool_stroke_append (wt, 'M', wt->last_pos.x - off_x, @@ -447,7 +449,7 @@ gimp_warp_tool_motion (GimpTool *tool, gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); } - gimp_item_get_offset (GIMP_ITEM (tool->drawable), &off_x, &off_y); + gimp_item_get_offset (GIMP_ITEM (tool->drawables->data), &off_x, &off_y); gimp_warp_tool_stroke_append (wt, 'L', wt->last_pos.x - off_x, @@ -755,27 +757,34 @@ gimp_warp_tool_can_stroke (GimpWarpTool *wt, GimpDisplay *display, gboolean show_message) { - GimpTool *tool = GIMP_TOOL (wt); - GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt); - GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config); - GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpTool *tool = GIMP_TOOL (wt); + GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt); + GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config); + GimpImage *image = gimp_display_get_image (display); + GList *drawables = gimp_image_get_selected_drawables (image); + GimpDrawable *drawable; - if (! drawable) + if (g_list_length (drawables) != 1) { if (show_message) { - if (g_list_length (gimp_image_get_selected_layers (image)) > 1) + if (g_list_length (drawables) > 1) gimp_tool_message_literal (tool, display, _("Cannot warp multiple layers. Select only one layer.")); else gimp_tool_message_literal (tool, display, - _("No active drawable.")); + _("No active drawables.")); } + g_list_free (drawables); + return FALSE; } - else if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) + + drawable = drawables->data; + g_list_free (drawables); + + if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { if (show_message) { @@ -870,15 +879,18 @@ gimp_warp_tool_start (GimpWarpTool *wt, GimpTool *tool = GIMP_TOOL (wt); GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt); GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpDrawable *drawable; const Babl *format; GeglRectangle bbox; if (! gimp_warp_tool_can_stroke (wt, display, TRUE)) return FALSE; - tool->display = display; - tool->drawable = drawable; + tool->display = display; + g_list_free (tool->drawables); + tool->drawables = gimp_image_get_selected_drawables (image); + + drawable = tool->drawables->data; /* Create the coords buffer, with the size of the selection */ format = babl_format_n (babl_type ("float"), 2); @@ -935,8 +947,9 @@ gimp_warp_tool_halt (GimpWarpTool *wt) wt->redo_stack = NULL; } - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + g_list_free (tool->drawables); + tool->drawables = NULL; if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (wt))) gimp_draw_tool_stop (GIMP_DRAW_TOOL (wt)); @@ -1009,7 +1022,9 @@ gimp_warp_tool_stroke_timer (GimpWarpTool *wt) GimpTool *tool = GIMP_TOOL (wt); gint off_x, off_y; - gimp_item_get_offset (GIMP_ITEM (tool->drawable), &off_x, &off_y); + g_return_val_if_fail (g_list_length (tool->drawables) == 1, FALSE); + + gimp_item_get_offset (GIMP_ITEM (tool->drawables->data), &off_x, &off_y); gimp_warp_tool_stroke_append (wt, 'L', wt->last_pos.x - off_x, @@ -1401,6 +1416,8 @@ gimp_warp_tool_animate (GimpWarpTool *wt) GtkWidget *widget; gint i; + g_return_if_fail (g_list_length (tool->drawables) == 1); + if (! gimp_warp_tool_can_undo (tool, tool->display)) { gimp_tool_message_literal (tool, tool->display, @@ -1420,17 +1437,17 @@ gimp_warp_tool_animate (GimpWarpTool *wt) gimp_progress_start (GIMP_PROGRESS (tool), FALSE, _("Rendering Frame %d"), 1); - orig_image = gimp_item_get_image (GIMP_ITEM (tool->drawable)); + orig_image = gimp_item_get_image (GIMP_ITEM (tool->drawables->data)); image = gimp_create_image (orig_image->gimp, - gimp_item_get_width (GIMP_ITEM (tool->drawable)), - gimp_item_get_height (GIMP_ITEM (tool->drawable)), - gimp_drawable_get_base_type (tool->drawable), - gimp_drawable_get_precision (tool->drawable), + gimp_item_get_width (GIMP_ITEM (tool->drawables->data)), + gimp_item_get_height (GIMP_ITEM (tool->drawables->data)), + gimp_drawable_get_base_type (tool->drawables->data), + gimp_drawable_get_precision (tool->drawables->data), TRUE); /* the first frame is always the unwarped image */ - layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (tool->drawable), image, + layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (tool->drawables->data), image, GIMP_TYPE_LAYER)); gimp_object_take_name (GIMP_OBJECT (layer), g_strdup_printf (_("Frame %d"), 1)); @@ -1487,7 +1504,7 @@ gimp_warp_tool_animate (GimpWarpTool *wt) gimp_progress_end (GIMP_PROGRESS (tool)); /* recreate the image map */ - gimp_warp_tool_create_filter (wt, tool->drawable); + gimp_warp_tool_create_filter (wt, tool->drawables->data); gimp_warp_tool_update_stroke (wt, NULL); widget = GTK_WIDGET (gimp_display_get_shell (tool->display)); diff --git a/app/tools/tool_manager.c b/app/tools/tool_manager.c index 296606a70e..5a9b815b90 100644 --- a/app/tools/tool_manager.c +++ b/app/tools/tool_manager.c @@ -266,7 +266,8 @@ tool_manager_initialize_active (Gimp *gimp, { GimpImage *image = gimp_display_get_image (display); - tool->drawable = gimp_image_get_active_drawable (image); + g_list_free (tool->drawables); + tool->drawables = gimp_image_get_selected_drawables (image); return TRUE; }