diff --git a/app/tools/gimpaligntool.c b/app/tools/gimpaligntool.c index fced3c55b0..6b13519d74 100644 --- a/app/tools/gimpaligntool.c +++ b/app/tools/gimpaligntool.c @@ -155,6 +155,7 @@ gimp_align_tool_class_init (GimpAlignToolClass *klass) tool_class->cursor_update = gimp_align_tool_cursor_update; tool_class->can_undo = gimp_align_tool_can_undo; tool_class->undo = gimp_align_tool_undo; + tool_class->is_destructive = FALSE; draw_tool_class->draw = gimp_align_tool_draw; } diff --git a/app/tools/gimpbucketfilltool.c b/app/tools/gimpbucketfilltool.c index 7248c8fc69..813908f065 100644 --- a/app/tools/gimpbucketfilltool.c +++ b/app/tools/gimpbucketfilltool.c @@ -582,7 +582,6 @@ 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); - GimpItem *locked_item = NULL; GList *drawables = gimp_image_get_selected_drawables (image); GimpDrawable *drawable; @@ -623,28 +622,6 @@ gimp_bucket_fill_tool_button_press (GimpTool *tool, return; } - if (gimp_item_is_link_layer (GIMP_ITEM (drawable))) - { - gimp_tool_message_literal (tool, display, - _("Link layers must be rasterized " - "before they can be painted on.")); - return; - } - else if (gimp_item_is_vector_layer (GIMP_ITEM (drawable))) - { - gimp_tool_message_literal (tool, display, - _("Vector layers must be rasterized " - "before they can be painted on.")); - return; - } - else if (gimp_item_is_content_locked (GIMP_ITEM (drawable), &locked_item)) - { - gimp_tool_message_literal (tool, display, - _("The selected layer's pixels are locked.")); - gimp_tools_blink_lock_box (display->gimp, locked_item); - return; - } - if (options->fill_area == GIMP_BUCKET_FILL_LINE_ART && ! gimp_line_art_get_input (bucket_tool->priv->line_art)) { diff --git a/app/tools/gimpcolorpickertool.c b/app/tools/gimpcolorpickertool.c index ccdd5dc578..40d4224f39 100644 --- a/app/tools/gimpcolorpickertool.c +++ b/app/tools/gimpcolorpickertool.c @@ -120,14 +120,15 @@ gimp_color_picker_tool_class_init (GimpColorPickerToolClass *klass) GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); GimpColorToolClass *color_tool_class = GIMP_COLOR_TOOL_CLASS (klass); - object_class->constructed = gimp_color_picker_tool_constructed; - object_class->dispose = gimp_color_picker_tool_dispose; + object_class->constructed = gimp_color_picker_tool_constructed; + object_class->dispose = gimp_color_picker_tool_dispose; - tool_class->control = gimp_color_picker_tool_control; - tool_class->modifier_key = gimp_color_picker_tool_modifier_key; - tool_class->oper_update = gimp_color_picker_tool_oper_update; + tool_class->control = gimp_color_picker_tool_control; + tool_class->modifier_key = gimp_color_picker_tool_modifier_key; + tool_class->oper_update = gimp_color_picker_tool_oper_update; + tool_class->is_destructive = FALSE; - color_tool_class->picked = gimp_color_picker_tool_picked; + color_tool_class->picked = gimp_color_picker_tool_picked; } static void diff --git a/app/tools/gimpfiltertool.c b/app/tools/gimpfiltertool.c index 8ce1f0061e..a574863ec8 100644 --- a/app/tools/gimpfiltertool.c +++ b/app/tools/gimpfiltertool.c @@ -231,6 +231,7 @@ gimp_filter_tool_class_init (GimpFilterToolClass *klass) tool_class->oper_update = gimp_filter_tool_oper_update; tool_class->cursor_update = gimp_filter_tool_cursor_update; tool_class->options_notify = gimp_filter_tool_options_notify; + tool_class->is_destructive = FALSE; color_tool_class->can_pick = gimp_filter_tool_can_pick_color; color_tool_class->pick = gimp_filter_tool_pick_color; diff --git a/app/tools/gimpmagnifytool.c b/app/tools/gimpmagnifytool.c index 8c5f5d3983..e0ddac6423 100644 --- a/app/tools/gimpmagnifytool.c +++ b/app/tools/gimpmagnifytool.c @@ -109,6 +109,7 @@ gimp_magnify_tool_class_init (GimpMagnifyToolClass *klass) tool_class->motion = gimp_magnify_tool_motion; tool_class->modifier_key = gimp_magnify_tool_modifier_key; tool_class->cursor_update = gimp_magnify_tool_cursor_update; + tool_class->is_destructive = FALSE; draw_tool_class->draw = gimp_magnify_tool_draw; } diff --git a/app/tools/gimpmeasuretool.c b/app/tools/gimpmeasuretool.c index 4ab820a2a9..f232f767ce 100644 --- a/app/tools/gimpmeasuretool.c +++ b/app/tools/gimpmeasuretool.c @@ -146,6 +146,7 @@ gimp_measure_tool_class_init (GimpMeasureToolClass *klass) tool_class->button_press = gimp_measure_tool_button_press; tool_class->button_release = gimp_measure_tool_button_release; tool_class->motion = gimp_measure_tool_motion; + tool_class->is_destructive = FALSE; tr_class->recalc_matrix = gimp_measure_tool_recalc_matrix; tr_class->get_undo_desc = gimp_measure_tool_get_undo_desc; diff --git a/app/tools/gimpmovetool.c b/app/tools/gimpmovetool.c index 70c315a0a0..9f8407d4e7 100644 --- a/app/tools/gimpmovetool.c +++ b/app/tools/gimpmovetool.c @@ -136,6 +136,7 @@ gimp_move_tool_class_init (GimpMoveToolClass *klass) tool_class->modifier_key = gimp_move_tool_modifier_key; tool_class->oper_update = gimp_move_tool_oper_update; tool_class->cursor_update = gimp_move_tool_cursor_update; + tool_class->is_destructive = FALSE; draw_tool_class->draw = gimp_move_tool_draw; } diff --git a/app/tools/gimppainttool.c b/app/tools/gimppainttool.c index 6faa9a9c91..6db16017e0 100644 --- a/app/tools/gimppainttool.c +++ b/app/tools/gimppainttool.c @@ -315,8 +315,7 @@ gimp_paint_tool_button_press (GimpTool *tool, for (iter = drawables; iter; iter = iter->next) { - GimpDrawable *drawable = iter->data; - GimpItem *locked_item = NULL; + GimpDrawable *drawable = iter->data; if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { @@ -327,41 +326,6 @@ gimp_paint_tool_button_press (GimpTool *tool, return; } - if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)) || - gimp_item_is_link_layer (GIMP_ITEM (drawable)) || - gimp_item_is_content_locked (GIMP_ITEM (drawable), &locked_item)) - { - gboolean constrain_only; - - /* Allow vector/link or pixel-locaked layers to be set as sources */ - constrain_only = (state & gimp_get_constrain_behavior_mask () && - ! (state & gimp_get_extend_selection_mask ())); - if (! (GIMP_IS_SOURCE_TOOL (tool) && constrain_only)) - { - if (gimp_item_is_link_layer (GIMP_ITEM (drawable))) - { - gimp_tool_message_literal (tool, display, - _("Link layers must be rasterized " - "before they can be painted on.")); - } - else if (gimp_item_is_vector_layer (GIMP_ITEM (drawable))) - { - gimp_tool_message_literal (tool, display, - _("Vector layers must be rasterized " - "before they can be painted on.")); - } - else - { - gimp_tool_message_literal (tool, display, - _("The selected item's pixels are locked.")); - gimp_tools_blink_lock_box (display->gimp, locked_item); - } - g_list_free (drawables); - - return; - } - } - if (! gimp_paint_tool_check_alpha (paint_tool, drawable, display, &error)) { GtkWidget *options_gui; diff --git a/app/tools/gimppathtool.c b/app/tools/gimppathtool.c index 9f4944be14..c78eeeec21 100644 --- a/app/tools/gimppathtool.c +++ b/app/tools/gimppathtool.c @@ -187,6 +187,7 @@ gimp_path_tool_class_init (GimpPathToolClass *klass) tool_class->motion = gimp_path_tool_motion; tool_class->modifier_key = gimp_path_tool_modifier_key; tool_class->cursor_update = gimp_path_tool_cursor_update; + tool_class->is_destructive = FALSE; } static void diff --git a/app/tools/gimpselectiontool.c b/app/tools/gimpselectiontool.c index 4f35bbfd9f..3c422f2e5b 100644 --- a/app/tools/gimpselectiontool.c +++ b/app/tools/gimpselectiontool.c @@ -89,13 +89,14 @@ gimp_selection_tool_class_init (GimpSelectionToolClass *klass) { GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); - tool_class->control = gimp_selection_tool_control; - tool_class->modifier_key = gimp_selection_tool_modifier_key; - tool_class->key_press = gimp_edit_selection_tool_key_press; - tool_class->oper_update = gimp_selection_tool_oper_update; - tool_class->cursor_update = gimp_selection_tool_cursor_update; + tool_class->control = gimp_selection_tool_control; + tool_class->modifier_key = gimp_selection_tool_modifier_key; + tool_class->key_press = gimp_edit_selection_tool_key_press; + tool_class->oper_update = gimp_selection_tool_oper_update; + tool_class->cursor_update = gimp_selection_tool_cursor_update; + tool_class->is_destructive = FALSE; - klass->have_selection = gimp_selection_tool_real_have_selection; + klass->have_selection = gimp_selection_tool_real_have_selection; } static void diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c index ac92aafcd5..c0f97b1108 100644 --- a/app/tools/gimptexttool.c +++ b/app/tools/gimptexttool.c @@ -242,6 +242,7 @@ gimp_text_tool_class_init (GimpTextToolClass *klass) tool_class->oper_update = gimp_text_tool_oper_update; tool_class->cursor_update = gimp_text_tool_cursor_update; tool_class->get_popup = gimp_text_tool_get_popup; + tool_class->is_destructive = FALSE; draw_tool_class->draw = gimp_text_tool_draw; } diff --git a/app/tools/gimptool.c b/app/tools/gimptool.c index 94b4843539..803e10a450 100644 --- a/app/tools/gimptool.c +++ b/app/tools/gimptool.c @@ -28,6 +28,7 @@ #include "core/gimp.h" #include "core/gimpcontainer.h" #include "core/gimpimage.h" +#include "core/gimplinklayer.h" #include "core/gimpprogress.h" #include "core/gimptoolinfo.h" @@ -36,9 +37,15 @@ #include "display/gimpdisplayshell-cursor.h" #include "display/gimpstatusbar.h" +#include "path/gimpvectorlayer.h" + +#include "widgets/gimpwidgets-utils.h" + +#include "gimpsourcetool.h" #include "gimptool.h" #include "gimptool-progress.h" #include "gimptoolcontrol.h" +#include "gimptools-utils.h" #include "gimp-log.h" #include "gimp-intl.h" @@ -188,6 +195,8 @@ gimp_tool_class_init (GimpToolClass *klass) GIMP_TYPE_TOOL_INFO, GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + klass->is_destructive = TRUE; } static void @@ -632,6 +641,54 @@ gimp_tool_initialize (GimpTool *tool, g_return_val_if_fail (GIMP_IS_TOOL (tool), FALSE); g_return_val_if_fail (GIMP_IS_DISPLAY (display), FALSE); + /* Source tools are special-cased as we want to allow vector/link or + * pixel-locked layers to be set as sources. So we still let these be + * initialized but will further verify the button state in + * gimp_tool_button_press(). + */ + if (GIMP_TOOL_GET_CLASS (tool)->is_destructive && ! + GIMP_IS_SOURCE_TOOL (tool)) + { + GimpImage *image; + GList *drawables; + + image = gimp_display_get_image (display); + drawables = gimp_image_get_selected_drawables (image); + for (GList *iter = drawables; iter; iter = iter->next) + { + GimpDrawable *drawable = iter->data; + GimpItem *locked_item = NULL; + + if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)) || + gimp_item_is_link_layer (GIMP_ITEM (drawable)) || + gimp_item_is_content_locked (GIMP_ITEM (drawable), &locked_item)) + { + if (gimp_item_is_link_layer (GIMP_ITEM (drawable))) + { + gimp_tool_message_literal (tool, display, + _("Link layers must be rasterized " + "before they can be painted on.")); + } + else if (gimp_item_is_vector_layer (GIMP_ITEM (drawable))) + { + gimp_tool_message_literal (tool, display, + _("Vector layers must be rasterized " + "before they can be painted on.")); + } + else + { + gimp_tool_message_literal (tool, display, + _("The selected item's pixels are locked.")); + gimp_tools_blink_lock_box (display->gimp, locked_item); + } + + g_list_free (drawables); + return FALSE; + } + } + g_list_free (drawables); + } + if (! GIMP_TOOL_GET_CLASS (tool)->initialize (tool, display, &error)) { if (error) @@ -719,6 +776,56 @@ gimp_tool_button_press (GimpTool *tool, g_return_if_fail (coords != NULL); g_return_if_fail (GIMP_IS_DISPLAY (display)); + if (GIMP_IS_SOURCE_TOOL (tool)) + { + GimpImage *image; + GList *drawables; + + image = gimp_display_get_image (display); + drawables = gimp_image_get_selected_drawables (image); + for (GList *iter = drawables; iter; iter = iter->next) + { + GimpDrawable *drawable = iter->data; + GimpItem *locked_item = NULL; + + if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)) || + gimp_item_is_link_layer (GIMP_ITEM (drawable)) || + gimp_item_is_content_locked (GIMP_ITEM (drawable), &locked_item)) + { + gboolean constrain_only; + + /* Allow vector/link or pixel-locked layers to be set as sources */ + constrain_only = (state & gimp_get_constrain_behavior_mask () && + ! (state & gimp_get_extend_selection_mask ())); + if (! constrain_only) + { + if (gimp_item_is_link_layer (GIMP_ITEM (drawable))) + { + gimp_tool_message_literal (tool, display, + _("Link layers must be rasterized " + "before they can be painted on.")); + } + else if (gimp_item_is_vector_layer (GIMP_ITEM (drawable))) + { + gimp_tool_message_literal (tool, display, + _("Vector layers must be rasterized " + "before they can be painted on.")); + } + else + { + gimp_tool_message_literal (tool, display, + _("The selected item's pixels are locked.")); + gimp_tools_blink_lock_box (display->gimp, locked_item); + } + + g_list_free (drawables); + return; + } + } + } + g_list_free (drawables); + } + GIMP_TOOL_GET_CLASS (tool)->button_press (tool, coords, time, state, press_type, display); diff --git a/app/tools/gimptool.h b/app/tools/gimptool.h index bfea9dd2d0..bde5f5e272 100644 --- a/app/tools/gimptool.h +++ b/app/tools/gimptool.h @@ -163,6 +163,8 @@ struct _GimpToolClass void (* options_notify) (GimpTool *tool, GimpToolOptions *options, const GParamSpec *pspec); + + gboolean is_destructive; }; diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c index 429c79642a..97b4c6dffa 100644 --- a/app/tools/gimptransformtool.c +++ b/app/tools/gimptransformtool.c @@ -98,7 +98,8 @@ gimp_transform_tool_class_init (GimpTransformToolClass *klass) { GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); - tool_class->control = gimp_transform_tool_control; + tool_class->control = gimp_transform_tool_control; + tool_class->is_destructive = FALSE; klass->recalc_matrix = NULL; klass->get_undo_desc = gimp_transform_tool_real_get_undo_desc;