From d4933b30526903624340ed98f97ed094b3a80b4d Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Fri, 9 Nov 2012 11:17:25 +0100 Subject: [PATCH] Bug 674160 - Redesign of "Lock panel" Apply and heavily modify patch from remyDev which adds "lock position" to GimpItem, similar to "lock content". Lock position disables all sorts of translation and transform, from the GUI and the PDB. Cleaned up some aspects of the lock content code as well because a second instance of similar code always shows what went wrong the first time. --- app/actions/drawable-actions.c | 66 +++++++----- app/actions/drawable-commands.c | 30 ++++++ app/actions/drawable-commands.h | 2 + app/actions/layers-actions.c | 22 ++-- app/actions/vectors-actions.c | 61 ++++++----- app/actions/vectors-commands.c | 27 +++++ app/actions/vectors-commands.h | 2 + app/core/core-enums.c | 4 + app/core/core-enums.h | 2 + app/core/gimpgrouplayer.c | 21 ++++ app/core/gimpimage-undo-push.c | 32 ++++++ app/core/gimpimage-undo-push.h | 6 ++ app/core/gimpitem-linked.c | 33 ++++++ app/core/gimpitem-linked.h | 48 +++++---- app/core/gimpitem.c | 133 ++++++++++++++++++++---- app/core/gimpitem.h | 17 ++- app/core/gimpitempropundo.c | 28 +++++ app/core/gimpitempropundo.h | 6 +- app/core/gimplayermask.c | 62 ++++++----- app/pdb/drawable-transform-cmds.c | 54 +++++++--- app/pdb/gimppdb-utils.c | 10 ++ app/pdb/internal-procs.c | 2 +- app/pdb/item-cmds.c | 114 ++++++++++++++++++++ app/pdb/item-transform-cmds.c | 27 +++-- app/pdb/layer-cmds.c | 62 +++++++---- app/pdb/pdb-types.h | 3 +- app/pdb/transform-tools-cmds.c | 18 ++-- app/pdb/vectors-cmds.c | 22 ++-- app/tools/gimpmovetool.c | 130 +++++++++++++++++------ app/tools/gimptransformtool.c | 53 +++++++--- app/tools/gimpvectortool.c | 3 +- app/widgets/gimpchanneltreeview.c | 24 +++-- app/widgets/gimpdrawabletreeview.c | 6 +- app/widgets/gimphelp-ids.h | 7 +- app/widgets/gimpitemtreeview.c | 121 ++++++++++++++++++++- app/widgets/gimpitemtreeview.h | 5 + app/widgets/gimplayertreeview.c | 29 +++--- app/widgets/gimpvectorstreeview.c | 31 +++--- app/xcf/xcf-load.c | 22 ++++ app/xcf/xcf-private.h | 3 +- app/xcf/xcf-save.c | 17 +++ libgimp/gimp.def | 2 + libgimp/gimpitem_pdb.c | 66 ++++++++++++ libgimp/gimpitem_pdb.h | 3 + tools/pdbgen/pdb/drawable_transform.pdb | 19 ++-- tools/pdbgen/pdb/item.pdb | 53 ++++++++++ tools/pdbgen/pdb/item_transform.pdb | 12 ++- tools/pdbgen/pdb/layer.pdb | 62 +++++++---- tools/pdbgen/pdb/transform_tools.pdb | 18 ++-- tools/pdbgen/pdb/vectors.pdb | 22 ++-- 50 files changed, 1290 insertions(+), 332 deletions(-) diff --git a/app/actions/drawable-actions.c b/app/actions/drawable-actions.c index 0871c1a891..4b63374849 100644 --- a/app/actions/drawable-actions.c +++ b/app/actions/drawable-actions.c @@ -95,7 +95,15 @@ static const GimpToggleActionEntry drawable_toggle_actions[] = "Keep the pixels on this drawable from being modified"), G_CALLBACK (drawable_lock_content_cmd_callback), FALSE, - NULL, /* GIMP_HELP_LAYER_LOCK_PIXELS */ } + GIMP_HELP_LAYER_LOCK_PIXELS }, + + { "drawable-lock-position", GIMP_STOCK_TOOL_MOVE, + NC_("drawable-action", "L_ock position of channel"), NULL, + NC_("drawable-action", + "Keep the position on this drawable from being modified"), + G_CALLBACK (drawable_lock_position_cmd_callback), + FALSE, + GIMP_HELP_LAYER_LOCK_POSITION }, }; static const GimpEnumActionEntry drawable_flip_actions[] = @@ -171,14 +179,17 @@ drawable_actions_update (GimpActionGroup *group, gpointer data) { GimpImage *image; - GimpDrawable *drawable = NULL; - gboolean is_rgb = FALSE; - gboolean visible = FALSE; - gboolean linked = FALSE; - gboolean locked = FALSE; - gboolean can_lock = FALSE; - gboolean writable = FALSE; - gboolean children = FALSE; + GimpDrawable *drawable = NULL; + gboolean is_rgb = FALSE; + gboolean visible = FALSE; + gboolean linked = FALSE; + gboolean locked = FALSE; + gboolean can_lock = FALSE; + gboolean locked_pos = FALSE; + gboolean can_lock_pos = FALSE; + gboolean writable = FALSE; + gboolean movable = FALSE; + gboolean children = FALSE; image = action_data_get_image (data); @@ -197,11 +208,14 @@ drawable_actions_update (GimpActionGroup *group, else item = GIMP_ITEM (drawable); - visible = gimp_item_get_visible (item); - linked = gimp_item_get_linked (item); - locked = gimp_item_get_lock_content (item); - can_lock = gimp_item_can_lock_content (item); - writable = ! gimp_item_is_content_locked (item); + visible = gimp_item_get_visible (item); + linked = gimp_item_get_linked (item); + locked = gimp_item_get_lock_content (item); + can_lock = gimp_item_can_lock_content (item); + writable = ! gimp_item_is_content_locked (item); + locked_pos = gimp_item_get_lock_position (item); + can_lock_pos = gimp_item_can_lock_position (item); + movable = ! gimp_item_is_position_locked (item); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) children = TRUE; @@ -219,20 +233,22 @@ drawable_actions_update (GimpActionGroup *group, SET_SENSITIVE ("drawable-levels-stretch", writable && !children && is_rgb); SET_SENSITIVE ("drawable-offset", writable && !children); - SET_SENSITIVE ("drawable-visible", drawable); - SET_SENSITIVE ("drawable-linked", drawable); - SET_SENSITIVE ("drawable-lock-content", can_lock); + SET_SENSITIVE ("drawable-visible", drawable); + SET_SENSITIVE ("drawable-linked", drawable); + SET_SENSITIVE ("drawable-lock-content", can_lock); + SET_SENSITIVE ("drawable-lock-position", can_lock_pos); - SET_ACTIVE ("drawable-visible", visible); - SET_ACTIVE ("drawable-linked", linked); - SET_ACTIVE ("drawable-lock-content", locked); + SET_ACTIVE ("drawable-visible", visible); + SET_ACTIVE ("drawable-linked", linked); + SET_ACTIVE ("drawable-lock-content", locked); + SET_ACTIVE ("drawable-lock-position", locked_pos); - SET_SENSITIVE ("drawable-flip-horizontal", writable); - SET_SENSITIVE ("drawable-flip-vertical", writable); + SET_SENSITIVE ("drawable-flip-horizontal", writable && movable); + SET_SENSITIVE ("drawable-flip-vertical", writable && movable); - SET_SENSITIVE ("drawable-rotate-90", writable); - SET_SENSITIVE ("drawable-rotate-180", writable); - SET_SENSITIVE ("drawable-rotate-270", writable); + SET_SENSITIVE ("drawable-rotate-90", writable && movable); + SET_SENSITIVE ("drawable-rotate-180", writable && movable); + SET_SENSITIVE ("drawable-rotate-270", writable && movable); #undef SET_SENSITIVE #undef SET_ACTIVE diff --git a/app/actions/drawable-commands.c b/app/actions/drawable-commands.c index 5ef5b9c6b5..e697a8678b 100644 --- a/app/actions/drawable-commands.c +++ b/app/actions/drawable-commands.c @@ -227,6 +227,36 @@ drawable_lock_content_cmd_callback (GtkAction *action, } } +void +drawable_lock_position_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpImage *image; + GimpDrawable *drawable; + gboolean locked; + return_if_no_drawable (image, drawable, data); + + locked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + + if (GIMP_IS_LAYER_MASK (drawable)) + drawable = + GIMP_DRAWABLE (gimp_layer_mask_get_layer (GIMP_LAYER_MASK (drawable))); + + if (locked != gimp_item_get_lock_position (GIMP_ITEM (drawable))) + { + GimpUndo *undo; + gboolean push_undo = TRUE; + + undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO, + GIMP_UNDO_ITEM_LOCK_POSITION); + + if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (drawable)) + push_undo = FALSE; + + gimp_item_set_lock_position (GIMP_ITEM (drawable), locked, push_undo); + gimp_image_flush (image); + } +} void drawable_flip_cmd_callback (GtkAction *action, diff --git a/app/actions/drawable-commands.h b/app/actions/drawable-commands.h index 188347e020..e206e0e96a 100644 --- a/app/actions/drawable-commands.h +++ b/app/actions/drawable-commands.h @@ -36,6 +36,8 @@ void drawable_visible_cmd_callback (GtkAction *action, gpointer data); void drawable_lock_content_cmd_callback (GtkAction *action, gpointer data); +void drawable_lock_position_cmd_callback (GtkAction *action, + gpointer data); void drawable_flip_cmd_callback (GtkAction *action, gint value, diff --git a/app/actions/layers-actions.c b/app/actions/layers-actions.c index e05a9f28bb..e68d3100d2 100644 --- a/app/actions/layers-actions.c +++ b/app/actions/layers-actions.c @@ -535,6 +535,7 @@ layers_actions_update (GimpActionGroup *group, gboolean can_lock_alpha = FALSE; gboolean text_layer = FALSE; gboolean writable = FALSE; + gboolean movable = FALSE; gboolean children = FALSE; GList *next = NULL; GList *next_visible = NULL; @@ -559,6 +560,7 @@ layers_actions_update (GimpActionGroup *group, can_lock_alpha = gimp_layer_can_lock_alpha (layer); alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)); writable = ! gimp_item_is_content_locked (GIMP_ITEM (layer)); + movable = ! gimp_item_is_position_locked (GIMP_ITEM (layer)); if (gimp_viewable_get_children (GIMP_VIEWABLE (layer))) children = TRUE; @@ -641,19 +643,19 @@ layers_actions_update (GimpActionGroup *group, SET_SENSITIVE ("layers-merge-layers", layer && !fs && !ac); SET_SENSITIVE ("layers-flatten-image", layer && !fs && !ac); - SET_VISIBLE ("layers-text-discard", text_layer && !ac); - SET_VISIBLE ("layers-text-to-vectors", text_layer && !ac); - SET_VISIBLE ("layers-text-along-vectors", text_layer && !ac); + SET_VISIBLE ("layers-text-discard", text_layer && !ac); + SET_VISIBLE ("layers-text-to-vectors", text_layer && !ac); + SET_VISIBLE ("layers-text-along-vectors", text_layer && !ac); - SET_SENSITIVE ("layers-resize", writable && !ac); - SET_SENSITIVE ("layers-resize-to-image", writable && !ac); - SET_SENSITIVE ("layers-scale", writable && !ac); + SET_SENSITIVE ("layers-resize", writable && movable && !ac); + SET_SENSITIVE ("layers-resize-to-image", writable && movable && !ac); + SET_SENSITIVE ("layers-scale", writable && movable && !ac); - SET_SENSITIVE ("layers-crop-to-selection", writable && sel); - SET_SENSITIVE ("layers-crop-to-content", writable); + SET_SENSITIVE ("layers-crop-to-selection", writable && movable && sel); + SET_SENSITIVE ("layers-crop-to-content", writable && movable); - SET_SENSITIVE ("layers-alpha-add", writable && !children && !fs && !alpha); - SET_SENSITIVE ("layers-alpha-remove", writable && !children && !fs && alpha); + SET_SENSITIVE ("layers-alpha-add", writable && !children && !fs && !alpha); + SET_SENSITIVE ("layers-alpha-remove", writable && !children && !fs && alpha); SET_SENSITIVE ("layers-lock-alpha", can_lock_alpha); SET_ACTIVE ("layers-lock-alpha", lock_alpha); diff --git a/app/actions/vectors-actions.c b/app/actions/vectors-actions.c index aad41ce9d8..04c2a80c09 100644 --- a/app/actions/vectors-actions.c +++ b/app/actions/vectors-actions.c @@ -159,7 +159,13 @@ static const GimpToggleActionEntry vectors_toggle_actions[] = NC_("vectors-action", "L_ock strokes"), NULL, NULL, G_CALLBACK (vectors_lock_content_cmd_callback), FALSE, - NULL /* GIMP_HELP_PATH_LOCK_STROKES */ } + GIMP_HELP_PATH_LOCK_STROKES }, + + { "vectors-lock-position", GIMP_STOCK_TOOL_MOVE, + NC_("vectors-action", "L_ock position"), NULL, NULL, + G_CALLBACK (vectors_lock_position_cmd_callback), + FALSE, + GIMP_HELP_PATH_LOCK_POSITION } }; static const GimpEnumActionEntry vectors_to_selection_actions[] = @@ -243,19 +249,21 @@ void vectors_actions_update (GimpActionGroup *group, gpointer data) { - GimpImage *image = action_data_get_image (data); - GimpVectors *vectors = NULL; - GimpDrawable *drawable = NULL; - gint n_vectors = 0; - gboolean mask_empty = TRUE; - gboolean visible = FALSE; - gboolean linked = FALSE; - gboolean locked = FALSE; - gboolean can_lock = FALSE; - gboolean dr_writable = FALSE; - gboolean dr_children = FALSE; - GList *next = NULL; - GList *prev = NULL; + GimpImage *image = action_data_get_image (data); + GimpVectors *vectors = NULL; + GimpDrawable *drawable = NULL; + gint n_vectors = 0; + gboolean mask_empty = TRUE; + gboolean visible = FALSE; + gboolean linked = FALSE; + gboolean locked = FALSE; + gboolean can_lock = FALSE; + gboolean locked_pos = FALSE; + gboolean can_lock_pos = FALSE; + gboolean dr_writable = FALSE; + gboolean dr_children = FALSE; + GList *next = NULL; + GList *prev = NULL; if (image) { @@ -270,11 +278,12 @@ vectors_actions_update (GimpActionGroup *group, GList *vectors_list; GList *list; - visible = gimp_item_get_visible (item); - linked = gimp_item_get_linked (item); - locked = gimp_item_get_lock_content (item); - can_lock = gimp_item_can_lock_content (item); - + visible = gimp_item_get_visible (item); + linked = gimp_item_get_linked (item); + locked = gimp_item_get_lock_content (item); + can_lock = gimp_item_can_lock_content (item); + locked_pos = gimp_item_get_lock_position (item); + can_lock_pos = gimp_item_can_lock_position (item); vectors_list = gimp_item_get_container_iter (item); list = g_list_find (vectors_list, vectors); @@ -323,13 +332,15 @@ vectors_actions_update (GimpActionGroup *group, SET_SENSITIVE ("vectors-export", vectors); SET_SENSITIVE ("vectors-import", image); - SET_SENSITIVE ("vectors-visible", vectors); - SET_SENSITIVE ("vectors-linked", vectors); - SET_SENSITIVE ("vectors-lock-content", can_lock); + SET_SENSITIVE ("vectors-visible", vectors); + SET_SENSITIVE ("vectors-linked", vectors); + SET_SENSITIVE ("vectors-lock-content", can_lock); + SET_SENSITIVE ("vectors-lock-position", can_lock_pos); - SET_ACTIVE ("vectors-visible", visible); - SET_ACTIVE ("vectors-linked", linked); - SET_ACTIVE ("vectors-lock-content", locked); + SET_ACTIVE ("vectors-visible", visible); + SET_ACTIVE ("vectors-linked", linked); + SET_ACTIVE ("vectors-lock-content", locked); + SET_ACTIVE ("vectors-lock-position", locked_pos); SET_SENSITIVE ("vectors-selection-to-vectors", image && !mask_empty); SET_SENSITIVE ("vectors-selection-to-vectors-short", image && !mask_empty); diff --git a/app/actions/vectors-commands.c b/app/actions/vectors-commands.c index 81a85ab8d5..1ffa2ec96f 100644 --- a/app/actions/vectors-commands.c +++ b/app/actions/vectors-commands.c @@ -641,6 +641,33 @@ vectors_lock_content_cmd_callback (GtkAction *action, } } +void +vectors_lock_position_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpImage *image; + GimpVectors *vectors; + gboolean locked; + return_if_no_vectors (image, vectors, data); + + locked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + + if (locked != gimp_item_get_lock_position (GIMP_ITEM (vectors))) + { + GimpUndo *undo; + gboolean push_undo = TRUE; + + undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO, + GIMP_UNDO_ITEM_LOCK_POSITION); + + if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (vectors)) + push_undo = FALSE; + + + gimp_item_set_lock_position (GIMP_ITEM (vectors), locked, push_undo); + gimp_image_flush (image); + } +} /* private functions */ diff --git a/app/actions/vectors-commands.h b/app/actions/vectors-commands.h index 40118c0e1b..af485c3978 100644 --- a/app/actions/vectors-commands.h +++ b/app/actions/vectors-commands.h @@ -69,6 +69,8 @@ void vectors_linked_cmd_callback (GtkAction *action, gpointer data); void vectors_lock_content_cmd_callback (GtkAction *action, gpointer data); +void vectors_lock_position_cmd_callback (GtkAction *action, + gpointer data); #endif /* __VECTORS_COMMANDS_H__ */ diff --git a/app/core/core-enums.c b/app/core/core-enums.c index 3dfbaac3af..fc0d650f71 100644 --- a/app/core/core-enums.c +++ b/app/core/core-enums.c @@ -1081,6 +1081,8 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_ITEM_DISPLACE, "GIMP_UNDO_ITEM_DISPLACE", "item-displace" }, { GIMP_UNDO_ITEM_VISIBILITY, "GIMP_UNDO_ITEM_VISIBILITY", "item-visibility" }, { GIMP_UNDO_ITEM_LINKED, "GIMP_UNDO_ITEM_LINKED", "item-linked" }, + { GIMP_UNDO_ITEM_LOCK_CONTENT, "GIMP_UNDO_ITEM_LOCK_CONTENT", "item-lock-content" }, + { GIMP_UNDO_ITEM_LOCK_POSITION, "GIMP_UNDO_ITEM_LOCK_POSITION", "item-lock-position" }, { GIMP_UNDO_LAYER_ADD, "GIMP_UNDO_LAYER_ADD", "layer-add" }, { GIMP_UNDO_LAYER_REMOVE, "GIMP_UNDO_LAYER_REMOVE", "layer-remove" }, { GIMP_UNDO_LAYER_MODE, "GIMP_UNDO_LAYER_MODE", "layer-mode" }, @@ -1168,6 +1170,8 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_ITEM_DISPLACE, NC_("undo-type", "Move item"), NULL }, { GIMP_UNDO_ITEM_VISIBILITY, NC_("undo-type", "Item visibility"), NULL }, { GIMP_UNDO_ITEM_LINKED, NC_("undo-type", "Link/Unlink item"), NULL }, + { GIMP_UNDO_ITEM_LOCK_CONTENT, NC_("undo-type", "Lock/Unlock content"), NULL }, + { GIMP_UNDO_ITEM_LOCK_POSITION, NC_("undo-type", "Lock/Unlock position"), NULL }, { GIMP_UNDO_LAYER_ADD, NC_("undo-type", "New layer"), NULL }, { GIMP_UNDO_LAYER_REMOVE, NC_("undo-type", "Delete layer"), NULL }, { GIMP_UNDO_LAYER_MODE, NC_("undo-type", "Set layer mode"), NULL }, diff --git a/app/core/core-enums.h b/app/core/core-enums.h index a7e6f6adbc..8bbba37837 100644 --- a/app/core/core-enums.h +++ b/app/core/core-enums.h @@ -522,6 +522,8 @@ typedef enum /*< pdb-skip >*/ GIMP_UNDO_ITEM_DISPLACE, /*< desc="Move item" >*/ GIMP_UNDO_ITEM_VISIBILITY, /*< desc="Item visibility" >*/ GIMP_UNDO_ITEM_LINKED, /*< desc="Link/Unlink item" >*/ + GIMP_UNDO_ITEM_LOCK_CONTENT, /*< desc="Lock/Unlock content" >*/ + GIMP_UNDO_ITEM_LOCK_POSITION, /*< desc="Lock/Unlock position" >*/ GIMP_UNDO_LAYER_ADD, /*< desc="New layer" >*/ GIMP_UNDO_LAYER_REMOVE, /*< desc="Delete layer" >*/ GIMP_UNDO_LAYER_MODE, /*< desc="Set layer mode" >*/ diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c index f9f25e79f9..303412f6cc 100644 --- a/app/core/gimpgrouplayer.c +++ b/app/core/gimpgrouplayer.c @@ -87,6 +87,7 @@ static gboolean gimp_group_layer_get_expanded (GimpViewable *viewable) static void gimp_group_layer_set_expanded (GimpViewable *viewable, gboolean expanded); +static gboolean gimp_group_layer_is_position_locked (const GimpItem *item); static GimpItem * gimp_group_layer_duplicate (GimpItem *item, GType new_type); static void gimp_group_layer_convert (GimpItem *item, @@ -208,6 +209,7 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass) viewable_class->set_expanded = gimp_group_layer_set_expanded; viewable_class->get_expanded = gimp_group_layer_get_expanded; + item_class->is_position_locked = gimp_group_layer_is_position_locked; item_class->duplicate = gimp_group_layer_duplicate; item_class->convert = gimp_group_layer_convert; item_class->translate = gimp_group_layer_translate; @@ -405,6 +407,25 @@ gimp_group_layer_set_expanded (GimpViewable *viewable, GET_PRIVATE (group)->expanded = expanded; } +static gboolean +gimp_group_layer_is_position_locked (const GimpItem *item) +{ + GimpGroupLayerPrivate *private = GET_PRIVATE (item); + GList *list; + + for (list = gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (private->children)); + list; + list = g_list_next (list)) + { + GimpItem *child = list->data; + + if (gimp_item_is_position_locked (child)) + return TRUE; + } + + return GIMP_ITEM_CLASS (parent_class)->is_position_locked (item); +} + static GimpItem * gimp_group_layer_duplicate (GimpItem *item, GType new_type) diff --git a/app/core/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c index b99046cc98..c226924429 100644 --- a/app/core/gimpimage-undo-push.c +++ b/app/core/gimpimage-undo-push.c @@ -392,6 +392,38 @@ gimp_image_undo_push_item_linked (GimpImage *image, NULL); } +GimpUndo * +gimp_image_undo_push_item_lock_content (GimpImage *image, + const gchar *undo_desc, + GimpItem *item) +{ + g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); + g_return_val_if_fail (GIMP_IS_ITEM (item), NULL); + g_return_val_if_fail (gimp_item_is_attached (item), NULL); + + return gimp_image_undo_push (image, GIMP_TYPE_ITEM_PROP_UNDO, + GIMP_UNDO_ITEM_LOCK_CONTENT, undo_desc, + GIMP_DIRTY_ITEM_META, + "item", item, + NULL); +} + +GimpUndo * +gimp_image_undo_push_item_lock_position (GimpImage *image, + const gchar *undo_desc, + GimpItem *item) +{ + g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); + g_return_val_if_fail (GIMP_IS_ITEM (item), NULL); + g_return_val_if_fail (gimp_item_is_attached (item), NULL); + + return gimp_image_undo_push (image, GIMP_TYPE_ITEM_PROP_UNDO, + GIMP_UNDO_ITEM_LOCK_POSITION, undo_desc, + GIMP_DIRTY_ITEM_META, + "item", item, + NULL); +} + GimpUndo * gimp_image_undo_push_item_parasite (GimpImage *image, const gchar *undo_desc, diff --git a/app/core/gimpimage-undo-push.h b/app/core/gimpimage-undo-push.h index d1c56cad87..eb97208b6f 100644 --- a/app/core/gimpimage-undo-push.h +++ b/app/core/gimpimage-undo-push.h @@ -97,6 +97,12 @@ GimpUndo * gimp_image_undo_push_item_visibility (GimpImage *image, GimpUndo * gimp_image_undo_push_item_linked (GimpImage *image, const gchar *undo_desc, GimpItem *item); +GimpUndo * gimp_image_undo_push_item_lock_content (GimpImage *image, + const gchar *undo_desc, + GimpItem *item); +GimpUndo * gimp_image_undo_push_item_lock_position (GimpImage *image, + const gchar *undo_desc, + GimpItem *item); GimpUndo * gimp_image_undo_push_item_parasite (GimpImage *image, const gchar *undo_desc, GimpItem *item, diff --git a/app/core/gimpitem-linked.c b/app/core/gimpitem-linked.c index aa41723045..fe86e403a8 100644 --- a/app/core/gimpitem-linked.c +++ b/app/core/gimpitem-linked.c @@ -32,6 +32,39 @@ /* public functions */ +gboolean +gimp_item_linked_is_locked (const GimpItem *item) +{ + GList *list; + GList *l; + gboolean locked = FALSE; + + g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE); + g_return_val_if_fail (gimp_item_get_linked (item) == TRUE, FALSE); + g_return_val_if_fail (gimp_item_is_attached (item), FALSE); + + list = gimp_image_item_list_get_list (gimp_item_get_image (item), item, + GIMP_ITEM_TYPE_ALL, + GIMP_ITEM_SET_LINKED); + + list = gimp_image_item_list_filter (item, list, TRUE, FALSE); + + for (l = list; l; l = g_list_next (l)) + { + GimpItem *item = l->data; + + if (gimp_item_is_position_locked (item)) + { + locked = TRUE; + break; + } + } + + g_list_free (list); + + return locked; +} + void gimp_item_linked_translate (GimpItem *item, gint offset_x, diff --git a/app/core/gimpitem-linked.h b/app/core/gimpitem-linked.h index 759361b905..974d0ad30c 100644 --- a/app/core/gimpitem-linked.h +++ b/app/core/gimpitem-linked.h @@ -19,29 +19,31 @@ #define __GIMP_ITEM_LINKED_H__ -void gimp_item_linked_translate (GimpItem *item, - gint offset_x, - gint offset_y, - gboolean push_undo); -void gimp_item_linked_flip (GimpItem *item, - GimpContext *context, - GimpOrientationType flip_type, - gdouble axis, - gboolean clip_result); -void gimp_item_linked_rotate (GimpItem *item, - GimpContext *context, - GimpRotationType rotate_type, - gdouble center_x, - gdouble center_y, - gboolean clip_result); -void gimp_item_linked_transform (GimpItem *item, - GimpContext *context, - const GimpMatrix3 *matrix, - GimpTransformDirection direction, - GimpInterpolationType interpolation_type, - gint recursion_level, - GimpTransformResize clip_result, - GimpProgress *progress); +gboolean gimp_item_linked_is_locked (const GimpItem *item); + +void gimp_item_linked_translate (GimpItem *item, + gint offset_x, + gint offset_y, + gboolean push_undo); +void gimp_item_linked_flip (GimpItem *item, + GimpContext *context, + GimpOrientationType flip_type, + gdouble axis, + gboolean clip_result); +void gimp_item_linked_rotate (GimpItem *item, + GimpContext *context, + GimpRotationType rotate_type, + gdouble center_x, + gdouble center_y, + gboolean clip_result); +void gimp_item_linked_transform (GimpItem *item, + GimpContext *context, + const GimpMatrix3 *matrix, + GimpTransformDirection direction, + GimpInterpolationType interpolation_type, + gint recursion_level, + GimpTransformResize clip_result, + GimpProgress *progress); #endif /* __GIMP_ITEM_LINKED_H__ */ diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c index 468e4e6e12..5f633dfec4 100644 --- a/app/core/gimpitem.c +++ b/app/core/gimpitem.c @@ -35,6 +35,7 @@ #include "gimpimage-undo.h" #include "gimpimage-undo-push.h" #include "gimpitem.h" +#include "gimpitem-linked.h" #include "gimpitem-preview.h" #include "gimpitemtree.h" #include "gimplist.h" @@ -52,6 +53,7 @@ enum VISIBILITY_CHANGED, LINKED_CHANGED, LOCK_CONTENT_CHANGED, + LOCK_POSITION_CHANGED, LAST_SIGNAL }; @@ -66,7 +68,8 @@ enum PROP_OFFSET_Y, PROP_VISIBLE, PROP_LINKED, - PROP_LOCK_CONTENT + PROP_LOCK_CONTENT, + PROP_LOCK_POSITION }; @@ -84,9 +87,10 @@ struct _GimpItemPrivate gint width, height; /* size in pixels */ gint offset_x, offset_y; /* pixel offset in image */ - guint visible : 1; /* control visibility */ - guint linked : 1; /* control linkage */ - guint lock_content : 1; /* content editability */ + guint visible : 1; /* control visibility */ + guint linked : 1; /* control linkage */ + guint lock_content : 1; /* content editability */ + guint lock_position : 1; /* content movability */ guint removed : 1; /* removed from the image? */ @@ -119,6 +123,7 @@ static gint64 gimp_item_get_memsize (GimpObject *object, static void gimp_item_real_visibility_changed (GimpItem *item); static gboolean gimp_item_real_is_content_locked (const GimpItem *item); +static gboolean gimp_item_real_is_position_locked (const GimpItem *item); static GimpItem * gimp_item_real_duplicate (GimpItem *item, GType new_type); static void gimp_item_real_convert (GimpItem *item, @@ -197,6 +202,15 @@ gimp_item_class_init (GimpItemClass *klass) gimp_marshal_VOID__VOID, G_TYPE_NONE, 0); + gimp_item_signals[LOCK_POSITION_CHANGED] = + g_signal_new ("lock-position-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GimpItemClass, lock_position_changed), + NULL, NULL, + gimp_marshal_VOID__VOID, + G_TYPE_NONE, 0); + object_class->constructed = gimp_item_constructed; object_class->finalize = gimp_item_finalize; object_class->set_property = gimp_item_set_property; @@ -211,10 +225,12 @@ gimp_item_class_init (GimpItemClass *klass) klass->visibility_changed = gimp_item_real_visibility_changed; klass->linked_changed = NULL; klass->lock_content_changed = NULL; + klass->lock_position_changed = NULL; klass->unset_removed = NULL; klass->is_attached = NULL; klass->is_content_locked = gimp_item_real_is_content_locked; + klass->is_position_locked = gimp_item_real_is_position_locked; klass->get_tree = NULL; klass->duplicate = gimp_item_real_duplicate; klass->convert = gimp_item_real_convert; @@ -286,6 +302,12 @@ gimp_item_class_init (GimpItemClass *klass) FALSE, GIMP_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_LOCK_POSITION, + g_param_spec_boolean ("lock-position", + NULL, NULL, + FALSE, + GIMP_PARAM_READABLE)); + g_type_class_add_private (klass, sizeof (GimpItemPrivate)); } @@ -296,18 +318,19 @@ gimp_item_init (GimpItem *item) g_object_force_floating (G_OBJECT (item)); - private->ID = 0; - private->tattoo = 0; - private->image = NULL; - private->parasites = gimp_parasite_list_new (); - private->width = 0; - private->height = 0; - private->offset_x = 0; - private->offset_y = 0; - private->visible = TRUE; - private->linked = FALSE; - private->lock_content = FALSE; - private->removed = FALSE; + private->ID = 0; + private->tattoo = 0; + private->image = NULL; + private->parasites = gimp_parasite_list_new (); + private->width = 0; + private->height = 0; + private->offset_x = 0; + private->offset_y = 0; + private->visible = TRUE; + private->linked = FALSE; + private->lock_content = FALSE; + private->lock_position = FALSE; + private->removed = FALSE; } static void @@ -412,6 +435,9 @@ gimp_item_get_property (GObject *object, case PROP_LOCK_CONTENT: g_value_set_boolean (value, private->lock_content); break; + case PROP_LOCK_POSITION: + g_value_set_boolean (value, private->lock_position); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -466,6 +492,16 @@ gimp_item_real_is_content_locked (const GimpItem *item) return GET_PRIVATE (item)->lock_content; } +static gboolean +gimp_item_real_is_position_locked (const GimpItem *item) +{ + if (gimp_item_get_linked (item)) + if (gimp_item_linked_is_locked (item)) + return TRUE; + + return GET_PRIVATE (item)->lock_position; +} + static GimpItem * gimp_item_real_duplicate (GimpItem *item, GType new_type) @@ -528,6 +564,10 @@ gimp_item_real_duplicate (GimpItem *item, gimp_item_set_lock_content (new_item, gimp_item_get_lock_content (item), FALSE); + if (gimp_item_can_lock_position (new_item)) + gimp_item_set_lock_position (new_item, gimp_item_get_lock_position (item), + FALSE); + return new_item; } @@ -1746,9 +1786,10 @@ gimp_item_replace_item (GimpItem *item, gimp_item_get_width (replace), gimp_item_get_height (replace)); - gimp_item_set_visible (item, gimp_item_get_visible (replace), FALSE); - gimp_item_set_linked (item, gimp_item_get_linked (replace), FALSE); - gimp_item_set_lock_content (item, gimp_item_get_lock_content (replace), FALSE); + gimp_item_set_visible (item, gimp_item_get_visible (replace), FALSE); + gimp_item_set_linked (item, gimp_item_get_linked (replace), FALSE); + gimp_item_set_lock_content (item, gimp_item_get_lock_content (replace), FALSE); + gimp_item_set_lock_position (item, gimp_item_get_lock_position (replace), FALSE); } /** @@ -2086,6 +2127,60 @@ gimp_item_is_content_locked (const GimpItem *item) return GIMP_ITEM_GET_CLASS (item)->is_content_locked (item); } +void +gimp_item_set_lock_position (GimpItem *item, + gboolean lock_position, + gboolean push_undo) +{ + g_return_if_fail (GIMP_IS_ITEM (item)); + g_return_if_fail (gimp_item_can_lock_position (item)); + + lock_position = lock_position ? TRUE : FALSE; + + if (gimp_item_get_lock_position (item) != lock_position) + { + if (push_undo && gimp_item_is_attached (item)) + { + GimpImage *image = gimp_item_get_image (item); + + gimp_image_undo_push_item_lock_position (image, NULL, item); + } + + GET_PRIVATE (item)->lock_position = lock_position; + + g_signal_emit (item, gimp_item_signals[LOCK_POSITION_CHANGED], 0); + + g_object_notify (G_OBJECT (item), "lock-position"); + } +} + +gboolean +gimp_item_get_lock_position (const GimpItem *item) +{ + g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE); + + return GET_PRIVATE (item)->lock_position; +} + +gboolean +gimp_item_can_lock_position (const GimpItem *item) +{ + g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE); + + if (gimp_viewable_get_children (GIMP_VIEWABLE (item))) + return FALSE; + + return TRUE; +} + +gboolean +gimp_item_is_position_locked (const GimpItem *item) +{ + g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE); + + return GIMP_ITEM_GET_CLASS (item)->is_position_locked (item); +} + gboolean gimp_item_mask_bounds (GimpItem *item, gint *x1, diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h index 22d854ee82..ca4f14c05b 100644 --- a/app/core/gimpitem.h +++ b/app/core/gimpitem.h @@ -42,15 +42,17 @@ struct _GimpItemClass GimpViewableClass parent_class; /* signals */ - void (* removed) (GimpItem *item); - void (* visibility_changed) (GimpItem *item); - void (* linked_changed) (GimpItem *item); - void (* lock_content_changed) (GimpItem *item); + void (* removed) (GimpItem *item); + void (* visibility_changed) (GimpItem *item); + void (* linked_changed) (GimpItem *item); + void (* lock_content_changed) (GimpItem *item); + void (* lock_position_changed) (GimpItem *item); /* virtual functions */ void (* unset_removed) (GimpItem *item); gboolean (* is_attached) (const GimpItem *item); gboolean (* is_content_locked) (const GimpItem *item); + gboolean (* is_position_locked) (const GimpItem *item); GimpItemTree * (* get_tree) (GimpItem *item); GimpItem * (* duplicate) (GimpItem *item, GType new_type); @@ -308,6 +310,13 @@ gboolean gimp_item_get_lock_content (const GimpItem *item); gboolean gimp_item_can_lock_content (const GimpItem *item); gboolean gimp_item_is_content_locked (const GimpItem *item); +void gimp_item_set_lock_position (GimpItem *item, + gboolean lock_position, + gboolean push_undo); +gboolean gimp_item_get_lock_position (const GimpItem *item); +gboolean gimp_item_can_lock_position (const GimpItem *item); +gboolean gimp_item_is_position_locked (const GimpItem *item); + gboolean gimp_item_mask_bounds (GimpItem *item, gint *x1, gint *y1, diff --git a/app/core/gimpitempropundo.c b/app/core/gimpitempropundo.c index 9413f3b5a2..359bbce62d 100644 --- a/app/core/gimpitempropundo.c +++ b/app/core/gimpitempropundo.c @@ -127,6 +127,14 @@ gimp_item_prop_undo_constructed (GObject *object) item_prop_undo->linked = gimp_item_get_linked (item); break; + case GIMP_UNDO_ITEM_LOCK_CONTENT: + item_prop_undo->lock_content = gimp_item_get_lock_content (item); + break; + + case GIMP_UNDO_ITEM_LOCK_POSITION: + item_prop_undo->lock_position = gimp_item_get_lock_position (item); + break; + case GIMP_UNDO_PARASITE_ATTACH: case GIMP_UNDO_PARASITE_REMOVE: g_assert (item_prop_undo->parasite_name != NULL); @@ -277,6 +285,26 @@ gimp_item_prop_undo_pop (GimpUndo *undo, } break; + case GIMP_UNDO_ITEM_LOCK_CONTENT: + { + gboolean lock_content; + + lock_content = gimp_item_get_lock_content (item); + gimp_item_set_lock_content (item, item_prop_undo->lock_content, FALSE); + item_prop_undo->lock_content = lock_content; + } + break; + + case GIMP_UNDO_ITEM_LOCK_POSITION: + { + gboolean lock_position; + + lock_position = gimp_item_get_lock_position (item); + gimp_item_set_lock_position (item, item_prop_undo->lock_position, FALSE); + item_prop_undo->lock_position = lock_position; + } + break; + case GIMP_UNDO_PARASITE_ATTACH: case GIMP_UNDO_PARASITE_REMOVE: { diff --git a/app/core/gimpitempropundo.h b/app/core/gimpitempropundo.h index e20eb13adc..c0c1c5f9c6 100644 --- a/app/core/gimpitempropundo.h +++ b/app/core/gimpitempropundo.h @@ -41,8 +41,10 @@ struct _GimpItemPropUndo gchar *name; gint offset_x; gint offset_y; - gboolean visible; - gboolean linked; + guint visible : 1; + guint linked : 1; + guint lock_content : 1; + guint lock_position : 1; gchar *parasite_name; GimpParasite *parasite; }; diff --git a/app/core/gimplayermask.c b/app/core/gimplayermask.c index 4ebf07fd15..d54d9fb88d 100644 --- a/app/core/gimplayermask.c +++ b/app/core/gimplayermask.c @@ -37,24 +37,25 @@ #include "gimp-intl.h" -static gboolean gimp_layer_mask_is_attached (const GimpItem *item); -static gboolean gimp_layer_mask_is_content_locked (const GimpItem *item); -static GimpItemTree * gimp_layer_mask_get_tree (GimpItem *item); -static GimpItem * gimp_layer_mask_duplicate (GimpItem *item, - GType new_type); -static gboolean gimp_layer_mask_rename (GimpItem *item, - const gchar *new_name, - const gchar *undo_desc, - GError **error); +static gboolean gimp_layer_mask_is_attached (const GimpItem *item); +static gboolean gimp_layer_mask_is_content_locked (const GimpItem *item); +static gboolean gimp_layer_mask_is_position_locked (const GimpItem *item); +static GimpItemTree * gimp_layer_mask_get_tree (GimpItem *item); +static GimpItem * gimp_layer_mask_duplicate (GimpItem *item, + GType new_type); +static gboolean gimp_layer_mask_rename (GimpItem *item, + const gchar *new_name, + const gchar *undo_desc, + GError **error); -static void gimp_layer_mask_convert_type (GimpDrawable *drawable, - GimpImage *dest_image, - const Babl *new_format, - GimpImageBaseType new_base_type, - GimpPrecision new_precision, - gint layer_dither_type, - gint mask_dither_type, - gboolean push_undo); +static void gimp_layer_mask_convert_type (GimpDrawable *drawable, + GimpImage *dest_image, + const Babl *new_format, + GimpImageBaseType new_base_type, + GimpPrecision new_precision, + gint layer_dither_type, + gint mask_dither_type, + gboolean push_undo); G_DEFINE_TYPE (GimpLayerMask, gimp_layer_mask, GIMP_TYPE_CHANNEL) @@ -71,13 +72,14 @@ gimp_layer_mask_class_init (GimpLayerMaskClass *klass) viewable_class->default_stock_id = "gimp-layer-mask"; - item_class->is_attached = gimp_layer_mask_is_attached; - item_class->is_content_locked = gimp_layer_mask_is_content_locked; - item_class->get_tree = gimp_layer_mask_get_tree; - item_class->duplicate = gimp_layer_mask_duplicate; - item_class->rename = gimp_layer_mask_rename; - item_class->translate_desc = C_("undo-type", "Move Layer Mask"); - item_class->to_selection_desc = C_("undo-type", "Layer Mask to Selection"); + item_class->is_attached = gimp_layer_mask_is_attached; + item_class->is_content_locked = gimp_layer_mask_is_content_locked; + item_class->is_position_locked = gimp_layer_mask_is_position_locked; + item_class->get_tree = gimp_layer_mask_get_tree; + item_class->duplicate = gimp_layer_mask_duplicate; + item_class->rename = gimp_layer_mask_rename; + item_class->translate_desc = C_("undo-type", "Move Layer Mask"); + item_class->to_selection_desc = C_("undo-type", "Layer Mask to Selection"); drawable_class->convert_type = gimp_layer_mask_convert_type; } @@ -100,6 +102,18 @@ gimp_layer_mask_is_content_locked (const GimpItem *item) return FALSE; } +static gboolean +gimp_layer_mask_is_position_locked (const GimpItem *item) +{ + GimpLayerMask *mask = GIMP_LAYER_MASK (item); + GimpLayer *layer = gimp_layer_mask_get_layer (mask); + + if (layer) + return gimp_item_is_position_locked (GIMP_ITEM (layer)); + + return FALSE; +} + static gboolean gimp_layer_mask_is_attached (const GimpItem *item) { diff --git a/app/pdb/drawable-transform-cmds.c b/app/pdb/drawable-transform-cmds.c index 0e66e9ae0b..50141ff753 100644 --- a/app/pdb/drawable-transform-cmds.c +++ b/app/pdb/drawable-transform-cmds.c @@ -74,7 +74,8 @@ drawable_transform_flip_simple_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -143,7 +144,9 @@ drawable_transform_flip_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -228,7 +231,8 @@ drawable_transform_flip_default_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -329,7 +333,9 @@ drawable_transform_perspective_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -424,7 +430,8 @@ drawable_transform_perspective_default_invoker (GimpProcedure *procedure gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -513,7 +520,8 @@ drawable_transform_rotate_simple_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -587,7 +595,9 @@ drawable_transform_rotate_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -676,7 +686,8 @@ drawable_transform_rotate_default_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -773,7 +784,8 @@ drawable_transform_scale_invoker (GimpProcedure *procedure, gint x, y, width, height; success = (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error) && x0 < x1 && y0 < y1); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error) && x0 < x1 && y0 < y1); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -859,7 +871,8 @@ drawable_transform_scale_default_invoker (GimpProcedure *procedure, gint x, y, width, height; success = (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error) && x0 < x1 && y0 < y1); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error) && x0 < x1 && y0 < y1); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -949,7 +962,9 @@ drawable_transform_shear_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -1031,7 +1046,8 @@ drawable_transform_shear_default_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -1131,7 +1147,9 @@ drawable_transform_2d_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -1224,7 +1242,8 @@ drawable_transform_2d_default_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -1329,7 +1348,9 @@ drawable_transform_matrix_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -1430,7 +1451,8 @@ drawable_transform_matrix_default_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) diff --git a/app/pdb/gimppdb-utils.c b/app/pdb/gimppdb-utils.c index f803b8222d..4c553f48a6 100644 --- a/app/pdb/gimppdb-utils.c +++ b/app/pdb/gimppdb-utils.c @@ -498,6 +498,16 @@ gimp_pdb_item_is_modifyable (GimpItem *item, return FALSE; } + if ((modify & GIMP_PDB_ITEM_POSITION) && gimp_item_is_position_locked (item)) + { + g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT, + _("Item '%s' (%d) cannot be modified because its " + "position and size are locked"), + gimp_object_get_name (item), + gimp_item_get_ID (item)); + return FALSE; + } + return TRUE; } diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c index 2d937ebe45..ff65aefc89 100644 --- a/app/pdb/internal-procs.c +++ b/app/pdb/internal-procs.c @@ -28,7 +28,7 @@ #include "internal-procs.h" -/* 678 procedures registered total */ +/* 680 procedures registered total */ void internal_procs_init (GimpPDB *pdb) diff --git a/app/pdb/item-cmds.c b/app/pdb/item-cmds.c index 20a53588fe..0addf698b1 100644 --- a/app/pdb/item-cmds.c +++ b/app/pdb/item-cmds.c @@ -659,6 +659,62 @@ item_set_lock_content_invoker (GimpProcedure *procedure, error ? *error : NULL); } +static GimpValueArray * +item_get_lock_position_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpValueArray *return_vals; + GimpItem *item; + gboolean lock_position = FALSE; + + item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp); + + if (success) + { + lock_position = gimp_item_get_lock_position (GIMP_ITEM (item)); + } + + return_vals = gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); + + if (success) + g_value_set_boolean (gimp_value_array_index (return_vals, 1), lock_position); + + return return_vals; +} + +static GimpValueArray * +item_set_lock_position_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpItem *item; + gboolean lock_position; + + item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp); + lock_position = g_value_get_boolean (gimp_value_array_index (args, 1)); + + if (success) + { + if (gimp_item_can_lock_position (GIMP_ITEM (item))) + gimp_item_set_lock_position (GIMP_ITEM (item), lock_position, TRUE); + else + success = FALSE; + } + + return gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); +} + static GimpValueArray * item_get_tattoo_invoker (GimpProcedure *procedure, Gimp *gimp, @@ -1442,6 +1498,64 @@ register_item_procs (GimpPDB *pdb) gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); + /* + * gimp-item-get-lock-position + */ + procedure = gimp_procedure_new (item_get_lock_position_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "gimp-item-get-lock-position"); + gimp_procedure_set_static_strings (procedure, + "gimp-item-get-lock-position", + "Get the 'lock position' state of the specified item.", + "This procedure returns the specified item's lock position state.", + "Michael Natterer ", + "Michael Natterer", + "2012", + NULL); + gimp_procedure_add_argument (procedure, + gimp_param_spec_item_id ("item", + "item", + "The item", + pdb->gimp, FALSE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_return_value (procedure, + g_param_spec_boolean ("lock-position", + "lock position", + "Whether the item's position is locked", + FALSE, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + + /* + * gimp-item-set-lock-position + */ + procedure = gimp_procedure_new (item_set_lock_position_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "gimp-item-set-lock-position"); + gimp_procedure_set_static_strings (procedure, + "gimp-item-set-lock-position", + "Set the 'lock position' state of the specified item.", + "This procedure sets the specified item's lock position state.", + "Michael Natterer ", + "Michael Natterer", + "2009", + NULL); + gimp_procedure_add_argument (procedure, + gimp_param_spec_item_id ("item", + "item", + "The item", + pdb->gimp, FALSE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + g_param_spec_boolean ("lock-position", + "lock position", + "The new item 'lock position' state", + FALSE, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + /* * gimp-item-get-tattoo */ diff --git a/app/pdb/item-transform-cmds.c b/app/pdb/item-transform-cmds.c index 98c43d9575..48f02a4d9a 100644 --- a/app/pdb/item-transform-cmds.c +++ b/app/pdb/item-transform-cmds.c @@ -72,7 +72,8 @@ item_transform_flip_simple_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) @@ -147,7 +148,8 @@ item_transform_flip_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) @@ -245,7 +247,8 @@ item_transform_perspective_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) @@ -338,7 +341,8 @@ item_transform_rotate_simple_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) @@ -416,7 +420,8 @@ item_transform_rotate_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) @@ -511,7 +516,8 @@ item_transform_scale_invoker (GimpProcedure *procedure, gint x, y, width, height; success = (gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error) && x0 < x1 && y0 < y1); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error) && x0 < x1 && y0 < y1); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) @@ -599,7 +605,8 @@ item_transform_shear_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) @@ -697,7 +704,8 @@ item_transform_2d_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) @@ -800,7 +808,8 @@ item_transform_matrix_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) diff --git a/app/pdb/layer-cmds.c b/app/pdb/layer-cmds.c index adeec46b6b..8031b9e2ef 100644 --- a/app/pdb/layer-cmds.c +++ b/app/pdb/layer-cmds.c @@ -377,7 +377,8 @@ layer_scale_invoker (GimpProcedure *procedure, if (success) { if (gimp_pdb_item_is_attached (GIMP_ITEM (layer), NULL, - GIMP_PDB_ITEM_CONTENT, error)) + GIMP_PDB_ITEM_CONTENT | GIMP_PDB_ITEM_POSITION, + error)) { GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context); @@ -425,7 +426,8 @@ layer_scale_full_invoker (GimpProcedure *procedure, if (success) { if (gimp_pdb_item_is_attached (GIMP_ITEM (layer), NULL, - GIMP_PDB_ITEM_CONTENT, error)) + GIMP_PDB_ITEM_CONTENT | GIMP_PDB_ITEM_POSITION, + error)) { if (progress) gimp_progress_start (progress, _("Scaling"), FALSE); @@ -471,7 +473,8 @@ layer_resize_invoker (GimpProcedure *procedure, if (success) { if (gimp_pdb_item_is_attached (GIMP_ITEM (layer), NULL, - GIMP_PDB_ITEM_CONTENT, error)) + GIMP_PDB_ITEM_CONTENT | GIMP_PDB_ITEM_POSITION, + error)) gimp_item_resize (GIMP_ITEM (layer), context, new_width, new_height, offx, offy); else @@ -498,7 +501,8 @@ layer_resize_to_image_size_invoker (GimpProcedure *procedure, if (success) { if (gimp_pdb_item_is_attached (GIMP_ITEM (layer), NULL, - GIMP_PDB_ITEM_CONTENT, error)) + GIMP_PDB_ITEM_CONTENT | GIMP_PDB_ITEM_POSITION, + error)) gimp_layer_resize_to_image (layer, context); else success = FALSE; @@ -527,17 +531,23 @@ layer_translate_invoker (GimpProcedure *procedure, if (success) { - GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); + if (gimp_pdb_item_is_modifyable (GIMP_ITEM (layer), + GIMP_PDB_ITEM_POSITION, error)) + { + GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); - gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, - _("Move Layer")); + gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, + _("Move Layer")); - gimp_item_translate (GIMP_ITEM (layer), offx, offy, TRUE); + gimp_item_translate (GIMP_ITEM (layer), offx, offy, TRUE); - if (gimp_item_get_linked (GIMP_ITEM (layer))) - gimp_item_linked_translate (GIMP_ITEM (layer), offx, offy, TRUE); + if (gimp_item_get_linked (GIMP_ITEM (layer))) + gimp_item_linked_translate (GIMP_ITEM (layer), offx, offy, TRUE); - gimp_image_undo_group_end (image); + gimp_image_undo_group_end (image); + } + else + success = FALSE; } return gimp_procedure_get_return_values (procedure, success, @@ -563,23 +573,29 @@ layer_set_offsets_invoker (GimpProcedure *procedure, if (success) { - GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); - gint offset_x; - gint offset_y; + if (gimp_pdb_item_is_modifyable (GIMP_ITEM (layer), + GIMP_PDB_ITEM_POSITION, error)) + { + GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); + gint offset_x; + gint offset_y; - gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, - _("Move Layer")); + gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, + _("Move Layer")); - gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y); - offx -= offset_x; - offy -= offset_y; + gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y); + offx -= offset_x; + offy -= offset_y; - gimp_item_translate (GIMP_ITEM (layer), offx, offy, TRUE); + gimp_item_translate (GIMP_ITEM (layer), offx, offy, TRUE); - if (gimp_item_get_linked (GIMP_ITEM (layer))) - gimp_item_linked_translate (GIMP_ITEM (layer), offx, offy, TRUE); + if (gimp_item_get_linked (GIMP_ITEM (layer))) + gimp_item_linked_translate (GIMP_ITEM (layer), offx, offy, TRUE); - gimp_image_undo_group_end (image); + gimp_image_undo_group_end (image); + } + else + success = FALSE; } return gimp_procedure_get_return_values (procedure, success, diff --git a/app/pdb/pdb-types.h b/app/pdb/pdb-types.h index e8d1271f50..e5a55290ab 100644 --- a/app/pdb/pdb-types.h +++ b/app/pdb/pdb-types.h @@ -38,7 +38,8 @@ typedef enum typedef enum { - GIMP_PDB_ITEM_CONTENT = 1 << 0 + GIMP_PDB_ITEM_CONTENT = 1 << 0, + GIMP_PDB_ITEM_POSITION = 1 << 1 } GimpPDBItemModify; diff --git a/app/pdb/transform-tools-cmds.c b/app/pdb/transform-tools-cmds.c index 806f203c76..eb575d85c7 100644 --- a/app/pdb/transform-tools-cmds.c +++ b/app/pdb/transform-tools-cmds.c @@ -68,7 +68,8 @@ flip_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -141,7 +142,8 @@ perspective_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -225,7 +227,8 @@ rotate_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -314,7 +317,8 @@ scale_invoker (GimpProcedure *procedure, gint x, y, width, height; success = (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error) && + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error) && x0 < x1 && y0 < y1); if (success && @@ -400,7 +404,8 @@ shear_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -495,7 +500,8 @@ transform_2d_invoker (GimpProcedure *procedure, gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) diff --git a/app/pdb/vectors-cmds.c b/app/pdb/vectors-cmds.c index 3a0dd01cc2..5adf50033a 100644 --- a/app/pdb/vectors-cmds.c +++ b/app/pdb/vectors-cmds.c @@ -101,7 +101,7 @@ vectors_new_from_text_layer_invoker (GimpProcedure *procedure, if (success) { - if (gimp_pdb_layer_is_text_layer (layer, FALSE, error)) + if (gimp_pdb_layer_is_text_layer (layer, 0, error)) { gint x, y; @@ -397,7 +397,9 @@ vectors_stroke_translate_invoker (GimpProcedure *procedure, if (success) { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) { @@ -438,7 +440,9 @@ vectors_stroke_scale_invoker (GimpProcedure *procedure, if (success) { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) { @@ -481,7 +485,9 @@ vectors_stroke_rotate_invoker (GimpProcedure *procedure, if (success) { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) { @@ -522,7 +528,9 @@ vectors_stroke_flip_invoker (GimpProcedure *procedure, if (success) { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) { @@ -567,7 +575,9 @@ vectors_stroke_flip_free_invoker (GimpProcedure *procedure, if (success) { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) { diff --git a/app/tools/gimpmovetool.c b/app/tools/gimpmovetool.c index 7ace03621c..e71daf0d0c 100644 --- a/app/tools/gimpmovetool.c +++ b/app/tools/gimpmovetool.c @@ -182,10 +182,13 @@ gimp_move_tool_button_press (GimpTool *tool, GimpButtonPressType press_type, GimpDisplay *display) { - GimpMoveTool *move = GIMP_MOVE_TOOL (tool); - GimpMoveOptions *options = GIMP_MOVE_TOOL_GET_OPTIONS (tool); - GimpDisplayShell *shell = gimp_display_get_shell (display); - GimpImage *image = gimp_display_get_image (display); + GimpMoveTool *move = GIMP_MOVE_TOOL (tool); + GimpMoveOptions *options = GIMP_MOVE_TOOL_GET_OPTIONS (tool); + GimpDisplayShell *shell = gimp_display_get_shell (display); + GimpImage *image = gimp_display_get_image (display); + GimpItem *active_item = NULL; + const gchar *null_message = NULL; + const gchar *locked_message = NULL; tool->display = display; @@ -289,48 +292,103 @@ gimp_move_tool_button_press (GimpTool *tool, switch (options->move_type) { case GIMP_TRANSFORM_TYPE_PATH: - if (gimp_image_get_active_vectors (image)) - { - gimp_tool_control_activate (tool->control); - gimp_edit_selection_tool_start (tool, display, coords, - GIMP_TRANSLATE_MODE_VECTORS, TRUE); - } + { + active_item = GIMP_ITEM (gimp_image_get_active_vectors (image)); + null_message = _("There is no path to move."); + locked_message = _("The active path's position is locked."); + + if (active_item && ! gimp_item_is_position_locked (active_item)) + { + gimp_tool_control_activate (tool->control); + gimp_edit_selection_tool_start (tool, display, coords, + GIMP_TRANSLATE_MODE_VECTORS, + TRUE); + return; + } + } break; case GIMP_TRANSFORM_TYPE_SELECTION: - if (! gimp_channel_is_empty (gimp_image_get_mask (image))) - { - gimp_tool_control_activate (tool->control); - gimp_edit_selection_tool_start (tool, display, coords, - GIMP_TRANSLATE_MODE_MASK, TRUE); - } + { + active_item = GIMP_ITEM (gimp_image_get_mask (image)); + /* cannot happen, so don't translate these messages */ + null_message = "There is no selection to move."; + locked_message = "The selection's position is locked."; + + if (active_item && ! gimp_item_is_position_locked (active_item)) + { + if (! gimp_channel_is_empty (gimp_image_get_mask (image))) + { + gimp_tool_control_activate (tool->control); + gimp_edit_selection_tool_start (tool, display, coords, + GIMP_TRANSLATE_MODE_MASK, + TRUE); + return; + } + else + locked_message = _("The selection is empty."); + } + } break; case GIMP_TRANSFORM_TYPE_LAYER: { - GimpDrawable *drawable = gimp_image_get_active_drawable (image); + active_item = GIMP_ITEM (gimp_image_get_active_drawable (image)); + null_message = _("There is no layer to move."); - if (GIMP_IS_LAYER_MASK (drawable)) + if (GIMP_IS_LAYER_MASK (active_item)) { - gimp_tool_control_activate (tool->control); - gimp_edit_selection_tool_start (tool, display, coords, - GIMP_TRANSLATE_MODE_LAYER_MASK, TRUE); + locked_message = _("The active layer's position is locked."); + + if (! gimp_item_is_position_locked (active_item)) + { + gimp_tool_control_activate (tool->control); + gimp_edit_selection_tool_start (tool, display, coords, + GIMP_TRANSLATE_MODE_LAYER_MASK, + TRUE); + return; + } } - else if (GIMP_IS_CHANNEL (drawable)) + else if (GIMP_IS_CHANNEL (active_item)) { - gimp_tool_control_activate (tool->control); - gimp_edit_selection_tool_start (tool, display, coords, - GIMP_TRANSLATE_MODE_CHANNEL, TRUE); + locked_message = _("The active channel's position is locked."); + + if (! gimp_item_is_position_locked (active_item)) + { + gimp_tool_control_activate (tool->control); + gimp_edit_selection_tool_start (tool, display, coords, + GIMP_TRANSLATE_MODE_CHANNEL, + TRUE); + return; + } } - else if (GIMP_IS_LAYER (drawable)) + else if (GIMP_IS_LAYER (active_item)) { - gimp_tool_control_activate (tool->control); - gimp_edit_selection_tool_start (tool, display, coords, - GIMP_TRANSLATE_MODE_LAYER, TRUE); + locked_message = _("The active layer's position is locked."); + + if (! gimp_item_is_position_locked (active_item)) + { + gimp_tool_control_activate (tool->control); + gimp_edit_selection_tool_start (tool, display, coords, + GIMP_TRANSLATE_MODE_LAYER, + TRUE); + return; + } } } break; } + + if (! active_item) + { + gimp_tool_message_literal (tool, display, null_message); + gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display); + } + else + { + gimp_tool_message_literal (tool, display, locked_message); + gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display); + } } static void @@ -693,7 +751,9 @@ gimp_move_tool_cursor_update (GimpTool *tool, if (options->move_current) { - if (! gimp_image_get_active_vectors (image)) + GimpItem *item = GIMP_ITEM (gimp_image_get_active_vectors (image)); + + if (! item || gimp_item_is_position_locked (item)) modifier = GIMP_CURSOR_MODIFIER_BAD; } else @@ -720,7 +780,9 @@ gimp_move_tool_cursor_update (GimpTool *tool, } else if (options->move_current) { - if (! gimp_image_get_active_drawable (image)) + GimpItem *item = GIMP_ITEM (gimp_image_get_active_drawable (image)); + + if (! item || gimp_item_is_position_locked (item)) modifier = GIMP_CURSOR_MODIFIER_BAD; } else @@ -746,10 +808,14 @@ gimp_move_tool_cursor_update (GimpTool *tool, tool_cursor = GIMP_TOOL_CURSOR_MOVE; modifier = GIMP_CURSOR_MODIFIER_ANCHOR; } + else if (gimp_item_is_position_locked (GIMP_ITEM (layer))) + { + modifier = GIMP_CURSOR_MODIFIER_BAD; + } else if (layer != gimp_image_get_active_layer (image)) { tool_cursor = GIMP_TOOL_CURSOR_HAND; - modifier = GIMP_CURSOR_MODIFIER_MOVE; + modifier = GIMP_CURSOR_MODIFIER_MOVE; } } else diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c index 3664086bfb..c6dad9600d 100644 --- a/app/tools/gimptransformtool.c +++ b/app/tools/gimptransformtool.c @@ -260,7 +260,14 @@ gimp_transform_tool_initialize (GimpTool *tool, 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.")); + _("The active layer's pixels are locked.")); + return FALSE; + } + + if (gimp_item_is_position_locked (GIMP_ITEM (drawable))) + { + g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, + _("The active layer's position and size are locked.")); return FALSE; } @@ -729,11 +736,13 @@ gimp_transform_tool_cursor_update (GimpTool *tool, switch (options->type) { - GimpDrawable *drawable; + GimpDrawable *drawable = NULL; + GimpVectors *vectors = NULL; case GIMP_TRANSFORM_TYPE_LAYER: drawable = gimp_image_get_active_drawable (image); - if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) + if (gimp_item_is_content_locked (GIMP_ITEM (drawable)) || + gimp_item_is_position_locked (GIMP_ITEM (drawable))) modifier = GIMP_CURSOR_MODIFIER_BAD; break; @@ -741,7 +750,10 @@ gimp_transform_tool_cursor_update (GimpTool *tool, break; case GIMP_TRANSFORM_TYPE_PATH: - if (! gimp_image_get_active_vectors (image)) + vectors = gimp_image_get_active_vectors (image); + if (! vectors || + gimp_item_is_content_locked (GIMP_ITEM (vectors)) || + gimp_item_is_position_locked (GIMP_ITEM (vectors))) modifier = GIMP_CURSOR_MODIFIER_BAD; break; } @@ -1218,22 +1230,34 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool, switch (options->type) { case GIMP_TRANSFORM_TYPE_LAYER: - active_item = GIMP_ITEM (gimp_image_get_active_drawable (image)); - null_message = _("There is no layer to transform."); - locked_message = _("The active layer's pixels are locked."); + active_item = GIMP_ITEM (gimp_image_get_active_drawable (image)); + null_message = _("There is no layer to transform."); + + if (gimp_item_is_content_locked (active_item)) + locked_message = _("The active layer's pixels are locked."); + else + locked_message = _("The active layer's position and size are locked."); break; case GIMP_TRANSFORM_TYPE_SELECTION: - active_item = GIMP_ITEM (gimp_image_get_mask (image)); + active_item = GIMP_ITEM (gimp_image_get_mask (image)); /* cannot happen, so don't translate these messages */ - null_message = "There is no selection to transform."; - locked_message = "The selection's pixels are locked."; + null_message = "There is no selection to transform."; + + if (gimp_item_is_content_locked (active_item)) + locked_message = "The selection's pixels are locked."; + else + locked_message = "The selection's position and size are locked."; break; case GIMP_TRANSFORM_TYPE_PATH: - active_item = GIMP_ITEM (gimp_image_get_active_vectors (image)); - null_message = _("There is no path to transform."); - locked_message = _("The active path's strokes are locked."); + active_item = GIMP_ITEM (gimp_image_get_active_vectors (image)); + null_message = _("There is no path to transform."); + + if (gimp_item_is_content_locked (active_item)) + locked_message = _("The active path's strokes are locked."); + else + locked_message = _("The active path's position are locked."); break; } @@ -1244,7 +1268,8 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool, return; } - if (gimp_item_is_content_locked (active_item)) + if (gimp_item_is_content_locked (active_item) || + gimp_item_is_position_locked (active_item)) { gimp_tool_message_literal (tool, display, locked_message); gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display); diff --git a/app/tools/gimpvectortool.c b/app/tools/gimpvectortool.c index e18d07f7ee..980b10e3b1 100644 --- a/app/tools/gimpvectortool.c +++ b/app/tools/gimpvectortool.c @@ -243,7 +243,8 @@ gimp_vector_tool_control (GimpTool *tool, static gboolean gimp_vector_tool_check_writable (GimpVectorTool *vector_tool) { - if (gimp_item_is_content_locked (GIMP_ITEM (vector_tool->vectors))) + if (gimp_item_is_content_locked (GIMP_ITEM (vector_tool->vectors)) || + gimp_item_is_position_locked (GIMP_ITEM (vector_tool->vectors))) { gimp_tool_message_literal (GIMP_TOOL (vector_tool), GIMP_TOOL (vector_tool)->display, diff --git a/app/widgets/gimpchanneltreeview.c b/app/widgets/gimpchanneltreeview.c index 458c749264..bc72dee8a8 100644 --- a/app/widgets/gimpchanneltreeview.c +++ b/app/widgets/gimpchanneltreeview.c @@ -113,17 +113,19 @@ gimp_channel_tree_view_class_init (GimpChannelTreeViewClass *klass) iv_class->remove_item = (GimpRemoveItemFunc) gimp_image_remove_channel; iv_class->new_item = gimp_channel_tree_view_item_new; - iv_class->action_group = "channels"; - iv_class->activate_action = "channels-edit-attributes"; - iv_class->edit_action = "channels-edit-attributes"; - iv_class->new_action = "channels-new"; - iv_class->new_default_action = "channels-new-last-values"; - iv_class->raise_action = "channels-raise"; - iv_class->raise_top_action = "channels-raise-to-top"; - iv_class->lower_action = "channels-lower"; - iv_class->lower_bottom_action = "channels-lower-to-bottom"; - iv_class->duplicate_action = "channels-duplicate"; - iv_class->delete_action = "channels-delete"; + iv_class->action_group = "channels"; + iv_class->activate_action = "channels-edit-attributes"; + iv_class->edit_action = "channels-edit-attributes"; + iv_class->new_action = "channels-new"; + iv_class->new_default_action = "channels-new-last-values"; + iv_class->raise_action = "channels-raise"; + iv_class->raise_top_action = "channels-raise-to-top"; + iv_class->lower_action = "channels-lower"; + iv_class->lower_bottom_action = "channels-lower-to-bottom"; + iv_class->duplicate_action = "channels-duplicate"; + iv_class->delete_action = "channels-delete"; + iv_class->lock_content_help_id = GIMP_HELP_CHANNEL_LOCK_PIXELS; + iv_class->lock_position_help_id = GIMP_HELP_CHANNEL_LOCK_POSITION; g_type_class_add_private (klass, sizeof (GimpChannelTreeViewPriv)); } diff --git a/app/widgets/gimpdrawabletreeview.c b/app/widgets/gimpdrawabletreeview.c index 2c1f60f5bd..ab8d4c6656 100644 --- a/app/widgets/gimpdrawabletreeview.c +++ b/app/widgets/gimpdrawabletreeview.c @@ -117,8 +117,10 @@ gimp_drawable_tree_view_class_init (GimpDrawableTreeViewClass *klass) item_view_class->set_image = gimp_drawable_tree_view_set_image; - item_view_class->lock_content_stock_id = GIMP_STOCK_TOOL_PAINTBRUSH; - item_view_class->lock_content_tooltip = _("Lock pixels"); + item_view_class->lock_content_stock_id = GIMP_STOCK_TOOL_PAINTBRUSH; + item_view_class->lock_content_tooltip = _("Lock pixels"); + item_view_class->lock_position_stock_id = GIMP_STOCK_TOOL_MOVE; + item_view_class->lock_position_tooltip = _("Lock position and size"); } static void diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h index 77d43b4618..981226a2a1 100644 --- a/app/widgets/gimphelp-ids.h +++ b/app/widgets/gimphelp-ids.h @@ -143,7 +143,6 @@ #define GIMP_HELP_LAYER_DIALOG "gimp-layer-dialog" #define GIMP_HELP_LAYER_DIALOG_PAINT_MODE_MENU "gimp-layer-dialog-paint-mode-menu" #define GIMP_HELP_LAYER_DIALOG_OPACITY_SCALE "gimp-layer-dialog-opacity-scale" -#define GIMP_HELP_LAYER_DIALOG_LOCK_ALPHA_BUTTON "gimp-layer-dialog-lock-alpha-button" #define GIMP_HELP_LAYER_NEW "gimp-layer-new" #define GIMP_HELP_LAYER_NEW_FROM_VISIBLE "gimp-layer-new-from-visible" @@ -171,6 +170,8 @@ #define GIMP_HELP_LAYER_OPACITY "gimp-layer-opacity" #define GIMP_HELP_LAYER_MODE "gimp-layer-mode" #define GIMP_HELP_LAYER_LOCK_ALPHA "gimp-layer-lock-alpha" +#define GIMP_HELP_LAYER_LOCK_PIXELS "gimp-layer-lock-pixels" +#define GIMP_HELP_LAYER_LOCK_POSITION "gimp-layer-lock-position" #define GIMP_HELP_LAYER_MASK_ADD "gimp-layer-mask-add" #define GIMP_HELP_LAYER_MASK_APPLY "gimp-layer-mask-apply" #define GIMP_HELP_LAYER_MASK_DELETE "gimp-layer-mask-delete" @@ -207,6 +208,8 @@ #define GIMP_HELP_CHANNEL_LOWER_TO_BOTTOM "gimp-channel-lower-to-bottom" #define GIMP_HELP_CHANNEL_DUPLICATE "gimp-channel-duplicate" #define GIMP_HELP_CHANNEL_DELETE "gimp-channel-delete" +#define GIMP_HELP_CHANNEL_LOCK_PIXELS "gimp-channel-lock-pixels" +#define GIMP_HELP_CHANNEL_LOCK_POSITION "gimp-channel-lock-position" #define GIMP_HELP_CHANNEL_SELECTION_REPLACE "gimp-channel-selection-replace" #define GIMP_HELP_CHANNEL_SELECTION_ADD "gimp-channel-selection-add" #define GIMP_HELP_CHANNEL_SELECTION_SUBTRACT "gimp-channel-selection-subtract" @@ -229,6 +232,8 @@ #define GIMP_HELP_PATH_MERGE_VISIBLE "gimp-path-merge-visible" #define GIMP_HELP_PATH_VISIBLE "gimp-path-visible" #define GIMP_HELP_PATH_LINKED "gimp-path-linked" +#define GIMP_HELP_PATH_LOCK_STROKES "gimp-path-lock-strokes" +#define GIMP_HELP_PATH_LOCK_POSITION "gimp-path-lock-position" #define GIMP_HELP_PATH_SELECTION_REPLACE "gimp-path-selection-replace" #define GIMP_HELP_PATH_SELECTION_ADD "gimp-path-selection-add" #define GIMP_HELP_PATH_SELECTION_SUBTRACT "gimp-path-selection-subtract" diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c index 4caa6c82c9..cd8d0bd1af 100644 --- a/app/widgets/gimpitemtreeview.c +++ b/app/widgets/gimpitemtreeview.c @@ -74,6 +74,7 @@ struct _GimpItemTreeViewPriv GtkWidget *lock_box; GtkWidget *lock_content_toggle; + GtkWidget *lock_position_toggle; GtkWidget *edit_button; GtkWidget *new_button; @@ -91,6 +92,7 @@ struct _GimpItemTreeViewPriv GimpTreeHandler *visible_changed_handler; GimpTreeHandler *linked_changed_handler; GimpTreeHandler *lock_content_changed_handler; + GimpTreeHandler *lock_position_changed_handler; gboolean inserting_item; /* EEK */ }; @@ -169,6 +171,8 @@ static void gimp_item_tree_view_linked_changed (GimpItem *item, GimpItemTreeView *view); static void gimp_item_tree_view_lock_content_changed (GimpItem *item, GimpItemTreeView *view); +static void gimp_item_tree_view_lock_position_changed(GimpItem *item, + GimpItemTreeView *view); static void gimp_item_tree_view_eye_clicked (GtkCellRendererToggle *toggle, gchar *path, @@ -181,7 +185,9 @@ static void gimp_item_tree_view_chain_clicked (GtkCellRendererToggle *togg static void gimp_item_tree_view_lock_content_toggled (GtkWidget *widget, GimpItemTreeView *view); - +static void gimp_item_tree_view_lock_position_toggled + (GtkWidget *widget, + GimpItemTreeView *view); static void gimp_item_tree_view_update_options (GimpItemTreeView *view, GimpItem *item); @@ -271,6 +277,10 @@ gimp_item_tree_view_class_init (GimpItemTreeViewClass *klass) klass->lock_content_tooltip = NULL; klass->lock_content_help_id = NULL; + klass->lock_position_stock_id = NULL; + klass->lock_position_tooltip = NULL; + klass->lock_position_help_id = NULL; + g_type_class_add_private (klass, sizeof (GimpItemTreeViewPriv)); } @@ -451,11 +461,9 @@ gimp_item_tree_view_constructed (GObject *object) GTK_BUTTON (item_view->priv->delete_button), item_view_class->item_type); - - /* Lock content toggle */ - hbox = gimp_item_tree_view_get_lock_box (item_view); + /* Lock content toggle */ item_view->priv->lock_content_toggle = gtk_toggle_button_new (); gtk_box_pack_start (GTK_BOX (hbox), item_view->priv->lock_content_toggle, FALSE, FALSE, 0); @@ -480,6 +488,28 @@ gimp_item_tree_view_constructed (GObject *object) gtk_container_add (GTK_CONTAINER (item_view->priv->lock_content_toggle), image); gtk_widget_show (image); + + /* Lock position toggle */ + item_view->priv->lock_position_toggle = gtk_toggle_button_new (); + gtk_box_pack_start (GTK_BOX (hbox), item_view->priv->lock_position_toggle, + FALSE, FALSE, 0); + gtk_box_reorder_child (GTK_BOX (hbox), + item_view->priv->lock_position_toggle, 1); + gtk_widget_show (item_view->priv->lock_position_toggle); + + g_signal_connect (item_view->priv->lock_position_toggle, "toggled", + G_CALLBACK (gimp_item_tree_view_lock_position_toggled), + item_view); + + gimp_help_set_help_data (item_view->priv->lock_position_toggle, + item_view_class->lock_position_tooltip, + item_view_class->lock_position_help_id); + + image = gtk_image_new_from_stock (item_view_class->lock_position_stock_id, + icon_size); + gtk_container_add (GTK_CONTAINER (item_view->priv->lock_position_toggle), + image); + gtk_widget_show (image); } static void @@ -862,6 +892,9 @@ gimp_item_tree_view_set_container (GimpContainerView *view, gimp_tree_handler_disconnect (item_view->priv->lock_content_changed_handler); item_view->priv->lock_content_changed_handler = NULL; + + gimp_tree_handler_disconnect (item_view->priv->lock_position_changed_handler); + item_view->priv->lock_position_changed_handler = NULL; } parent_view_iface->set_container (view, container); @@ -882,6 +915,11 @@ gimp_item_tree_view_set_container (GimpContainerView *view, gimp_tree_handler_connect (container, "lock-content-changed", G_CALLBACK (gimp_item_tree_view_lock_content_changed), view); + + item_view->priv->lock_position_changed_handler = + gimp_tree_handler_connect (container, "lock-position-changed", + G_CALLBACK (gimp_item_tree_view_lock_position_changed), + view); } } @@ -1393,6 +1431,61 @@ gimp_item_tree_view_lock_content_toggled (GtkWidget *widget, } } +static void +gimp_item_tree_view_lock_position_changed (GimpItem *item, + GimpItemTreeView *view) +{ + GimpImage *image = view->priv->image; + GimpItem *active_item; + + active_item = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->get_active_item (image); + + if (active_item == item) + gimp_item_tree_view_update_options (view, item); +} + +static void +gimp_item_tree_view_lock_position_toggled (GtkWidget *widget, + GimpItemTreeView *view) +{ + GimpImage *image = view->priv->image; + GimpItem *item; + + item = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->get_active_item (image); + + if (item) + { + gboolean lock_position; + + lock_position = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + + if (gimp_item_get_lock_position (item) != lock_position) + { + GimpUndo *undo; + gboolean push_undo = TRUE; + + /* compress lock position undos */ + undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO, + GIMP_UNDO_ITEM_LOCK_POSITION); + + if (undo && GIMP_ITEM_UNDO (undo)->item == item) + push_undo = FALSE; + + g_signal_handlers_block_by_func (item, + gimp_item_tree_view_lock_position_changed, + view); + + gimp_item_set_lock_position (item, lock_position, push_undo); + + g_signal_handlers_unblock_by_func (item, + gimp_item_tree_view_lock_position_changed, + view); + + gimp_image_flush (image); + } + } +} + static gboolean gimp_item_tree_view_item_pre_clicked (GimpCellRendererViewable *cell, const gchar *path_str, @@ -1407,7 +1500,7 @@ gimp_item_tree_view_item_pre_clicked (GimpCellRendererViewable *cell, path = gtk_tree_path_new_from_string (path_str); if (gtk_tree_model_get_iter (tree_view->model, &iter, path) && - state & GDK_MOD1_MASK) + (state & GDK_MOD1_MASK)) { GimpImage *image = gimp_item_tree_view_get_image (item_view); GimpViewRenderer *renderer = NULL; @@ -1456,8 +1549,26 @@ gimp_item_tree_view_update_options (GimpItemTreeView *view, view); } + if (gimp_item_get_lock_position (item) != + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->lock_position_toggle))) + { + g_signal_handlers_block_by_func (view->priv->lock_position_toggle, + gimp_item_tree_view_lock_position_toggled, + view); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->lock_position_toggle), + gimp_item_get_lock_position (item)); + + g_signal_handlers_unblock_by_func (view->priv->lock_position_toggle, + gimp_item_tree_view_lock_position_toggled, + view); + } + gtk_widget_set_sensitive (view->priv->lock_content_toggle, gimp_item_can_lock_content (item)); + + gtk_widget_set_sensitive (view->priv->lock_position_toggle, + gimp_item_can_lock_position (item)); } diff --git a/app/widgets/gimpitemtreeview.h b/app/widgets/gimpitemtreeview.h index f9ab1b1b41..75d8e23d4b 100644 --- a/app/widgets/gimpitemtreeview.h +++ b/app/widgets/gimpitemtreeview.h @@ -95,6 +95,11 @@ struct _GimpItemTreeViewClass const gchar *lock_content_stock_id; const gchar *lock_content_tooltip; const gchar *lock_content_help_id; + + /* lock position (translation and transformation) button appearance */ + const gchar *lock_position_stock_id; + const gchar *lock_position_tooltip; + const gchar *lock_position_help_id; }; diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c index 6946a3292f..d48108eec2 100644 --- a/app/widgets/gimplayertreeview.c +++ b/app/widgets/gimplayertreeview.c @@ -208,17 +208,19 @@ gimp_layer_tree_view_class_init (GimpLayerTreeViewClass *klass) item_view_class->remove_item = (GimpRemoveItemFunc) gimp_image_remove_layer; item_view_class->new_item = gimp_layer_tree_view_item_new; - item_view_class->action_group = "layers"; - item_view_class->activate_action = "layers-text-tool"; - item_view_class->edit_action = "layers-edit-attributes"; - item_view_class->new_action = "layers-new"; - item_view_class->new_default_action = "layers-new-last-values"; - item_view_class->raise_action = "layers-raise"; - item_view_class->raise_top_action = "layers-raise-to-top"; - item_view_class->lower_action = "layers-lower"; - item_view_class->lower_bottom_action = "layers-lower-to-bottom"; - item_view_class->duplicate_action = "layers-duplicate"; - item_view_class->delete_action = "layers-delete"; + item_view_class->action_group = "layers"; + item_view_class->activate_action = "layers-text-tool"; + item_view_class->edit_action = "layers-edit-attributes"; + item_view_class->new_action = "layers-new"; + item_view_class->new_default_action = "layers-new-last-values"; + item_view_class->raise_action = "layers-raise"; + item_view_class->raise_top_action = "layers-raise-to-top"; + item_view_class->lower_action = "layers-lower"; + item_view_class->lower_bottom_action = "layers-lower-to-bottom"; + item_view_class->duplicate_action = "layers-duplicate"; + item_view_class->delete_action = "layers-delete"; + item_view_class->lock_content_help_id = GIMP_HELP_LAYER_LOCK_PIXELS; + item_view_class->lock_position_help_id = GIMP_HELP_LAYER_LOCK_POSITION; g_type_class_add_private (klass, sizeof (GimpLayerTreeViewPriv)); } @@ -304,8 +306,9 @@ gimp_layer_tree_view_init (GimpLayerTreeView *view) G_CALLBACK (gimp_layer_tree_view_lock_alpha_button_toggled), view); - gimp_help_set_help_data (view->priv->lock_alpha_toggle, _("Lock alpha channel"), - GIMP_HELP_LAYER_DIALOG_LOCK_ALPHA_BUTTON); + gimp_help_set_help_data (view->priv->lock_alpha_toggle, + _("Lock alpha channel"), + GIMP_HELP_LAYER_LOCK_ALPHA); gtk_widget_style_get (GTK_WIDGET (view), "button-icon-size", &icon_size, diff --git a/app/widgets/gimpvectorstreeview.c b/app/widgets/gimpvectorstreeview.c index ae4da93fa9..eb8009350d 100644 --- a/app/widgets/gimpvectorstreeview.c +++ b/app/widgets/gimpvectorstreeview.c @@ -41,6 +41,7 @@ #include "gimpactiongroup.h" #include "gimpcontainerview.h" #include "gimpdnd.h" +#include "gimphelp-ids.h" #include "gimpuimanager.h" #include "gimpvectorstreeview.h" #include "gimpwidgets-utils.h" @@ -96,19 +97,23 @@ gimp_vectors_tree_view_class_init (GimpVectorsTreeViewClass *klass) iv_class->remove_item = (GimpRemoveItemFunc) gimp_image_remove_vectors; iv_class->new_item = gimp_vectors_tree_view_item_new; - iv_class->action_group = "vectors"; - iv_class->activate_action = "vectors-path-tool"; - iv_class->edit_action = "vectors-edit-attributes"; - iv_class->new_action = "vectors-new"; - iv_class->new_default_action = "vectors-new-last-values"; - iv_class->raise_action = "vectors-raise"; - iv_class->raise_top_action = "vectors-raise-to-top"; - iv_class->lower_action = "vectors-lower"; - iv_class->lower_bottom_action = "vectors-lower-to-bottom"; - iv_class->duplicate_action = "vectors-duplicate"; - iv_class->delete_action = "vectors-delete"; - iv_class->lock_content_stock_id = GIMP_STOCK_TOOL_PATH; - iv_class->lock_content_tooltip = _("Lock path strokes"); + iv_class->action_group = "vectors"; + iv_class->activate_action = "vectors-path-tool"; + iv_class->edit_action = "vectors-edit-attributes"; + iv_class->new_action = "vectors-new"; + iv_class->new_default_action = "vectors-new-last-values"; + iv_class->raise_action = "vectors-raise"; + iv_class->raise_top_action = "vectors-raise-to-top"; + iv_class->lower_action = "vectors-lower"; + iv_class->lower_bottom_action = "vectors-lower-to-bottom"; + iv_class->duplicate_action = "vectors-duplicate"; + iv_class->delete_action = "vectors-delete"; + iv_class->lock_content_stock_id = GIMP_STOCK_TOOL_PATH; + iv_class->lock_content_tooltip = _("Lock path strokes"); + iv_class->lock_content_help_id = GIMP_HELP_PATH_LOCK_STROKES; + iv_class->lock_position_stock_id = GIMP_STOCK_TOOL_MOVE; + iv_class->lock_position_tooltip = _("Lock path position"); + iv_class->lock_position_help_id = GIMP_HELP_PATH_LOCK_POSITION; } static void diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c index 5f12659084..3b8d923c40 100644 --- a/app/xcf/xcf-load.c +++ b/app/xcf/xcf-load.c @@ -805,6 +805,18 @@ xcf_load_layer_props (XcfInfo *info, } break; + case PROP_LOCK_POSITION: + { + gboolean lock_position; + + info->cp += xcf_read_int32 (info->fp, (guint32 *) &lock_position, 1); + + if (gimp_item_can_lock_position (GIMP_ITEM (*layer))) + gimp_item_set_lock_position (GIMP_ITEM (*layer), + lock_position, FALSE); + } + break; + case PROP_APPLY_MASK: info->cp += xcf_read_int32 (info->fp, (guint32 *) apply_mask, 1); break; @@ -1006,6 +1018,16 @@ xcf_load_channel_props (XcfInfo *info, } break; + case PROP_LOCK_POSITION: + { + gboolean lock_position; + + info->cp += xcf_read_int32 (info->fp, (guint32 *) &lock_position, 1); + gimp_item_set_lock_position (GIMP_ITEM (*channel), + lock_position ? TRUE : FALSE, FALSE); + } + break; + case PROP_SHOW_MASKED: { gboolean show_masked; diff --git a/app/xcf/xcf-private.h b/app/xcf/xcf-private.h index 05f1492878..eb05224df0 100644 --- a/app/xcf/xcf-private.h +++ b/app/xcf/xcf-private.h @@ -55,7 +55,8 @@ typedef enum PROP_LOCK_CONTENT = 28, PROP_GROUP_ITEM = 29, PROP_ITEM_PATH = 30, - PROP_GROUP_ITEM_FLAGS = 31 + PROP_GROUP_ITEM_FLAGS = 31, + PROP_LOCK_POSITION = 32 } PropType; typedef enum diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c index b707fe316e..266f2b81f1 100644 --- a/app/xcf/xcf-save.c +++ b/app/xcf/xcf-save.c @@ -506,6 +506,8 @@ xcf_save_layer_props (XcfInfo *info, gimp_item_get_lock_content (GIMP_ITEM (layer)))); xcf_check_error (xcf_save_prop (info, image, PROP_LOCK_ALPHA, error, gimp_layer_get_lock_alpha (layer))); + xcf_check_error (xcf_save_prop (info, image, PROP_LOCK_POSITION, error, + gimp_item_get_lock_position (GIMP_ITEM (layer)))); if (gimp_layer_get_mask (layer)) { @@ -596,6 +598,8 @@ xcf_save_channel_props (XcfInfo *info, gimp_item_get_linked (GIMP_ITEM (channel)))); xcf_check_error (xcf_save_prop (info, image, PROP_LOCK_CONTENT, error, gimp_item_get_lock_content (GIMP_ITEM (channel)))); + xcf_check_error (xcf_save_prop (info, image, PROP_LOCK_POSITION, error, + gimp_item_get_lock_position (GIMP_ITEM (channel)))); xcf_check_error (xcf_save_prop (info, image, PROP_SHOW_MASKED, error, gimp_channel_get_show_masked (channel))); @@ -763,6 +767,19 @@ xcf_save_prop (XcfInfo *info, } break; + case PROP_LOCK_POSITION: + { + guint32 lock_position; + + lock_position = va_arg (args, guint32); + size = 4; + + xcf_write_prop_type_check_error (info, prop_type); + xcf_write_int32_check_error (info, &size, 1); + xcf_write_int32_check_error (info, &lock_position, 1); + } + break; + case PROP_APPLY_MASK: { guint32 apply_mask; diff --git a/libgimp/gimp.def b/libgimp/gimp.def index 3bf5288a9e..710a8b2dfc 100644 --- a/libgimp/gimp.def +++ b/libgimp/gimp.def @@ -507,6 +507,7 @@ EXPORTS gimp_item_get_image gimp_item_get_linked gimp_item_get_lock_content + gimp_item_get_lock_position gimp_item_get_name gimp_item_get_parasite gimp_item_get_parasite_list @@ -524,6 +525,7 @@ EXPORTS gimp_item_is_vectors gimp_item_set_linked gimp_item_set_lock_content + gimp_item_set_lock_position gimp_item_set_name gimp_item_set_tattoo gimp_item_set_visible diff --git a/libgimp/gimpitem_pdb.c b/libgimp/gimpitem_pdb.c index 6f8b00a41d..4858263ddc 100644 --- a/libgimp/gimpitem_pdb.c +++ b/libgimp/gimpitem_pdb.c @@ -732,6 +732,72 @@ gimp_item_set_lock_content (gint32 item_ID, return success; } +/** + * gimp_item_get_lock_position: + * @item_ID: The item. + * + * Get the 'lock position' state of the specified item. + * + * This procedure returns the specified item's lock position state. + * + * Returns: Whether the item's position is locked. + * + * Since: GIMP 2.10 + **/ +gboolean +gimp_item_get_lock_position (gint32 item_ID) +{ + GimpParam *return_vals; + gint nreturn_vals; + gboolean lock_position = FALSE; + + return_vals = gimp_run_procedure ("gimp-item-get-lock-position", + &nreturn_vals, + GIMP_PDB_ITEM, item_ID, + GIMP_PDB_END); + + if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS) + lock_position = return_vals[1].data.d_int32; + + gimp_destroy_params (return_vals, nreturn_vals); + + return lock_position; +} + +/** + * gimp_item_set_lock_position: + * @item_ID: The item. + * @lock_position: The new item 'lock position' state. + * + * Set the 'lock position' state of the specified item. + * + * This procedure sets the specified item's lock position state. + * + * Returns: TRUE on success. + * + * Since: GIMP 2.10 + **/ +gboolean +gimp_item_set_lock_position (gint32 item_ID, + gboolean lock_position) +{ + GimpParam *return_vals; + gint nreturn_vals; + gboolean success = TRUE; + + return_vals = gimp_run_procedure ("gimp-item-set-lock-position", + &nreturn_vals, + GIMP_PDB_ITEM, item_ID, + GIMP_PDB_INT32, lock_position, + GIMP_PDB_END); + + success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS; + + gimp_destroy_params (return_vals, nreturn_vals); + + return success; +} + /** * gimp_item_get_tattoo: * @item_ID: The item. diff --git a/libgimp/gimpitem_pdb.h b/libgimp/gimpitem_pdb.h index 04788a47c6..c564f0f0f4 100644 --- a/libgimp/gimpitem_pdb.h +++ b/libgimp/gimpitem_pdb.h @@ -58,6 +58,9 @@ gboolean gimp_item_set_linked (gint32 item_ID, gboolean gimp_item_get_lock_content (gint32 item_ID); gboolean gimp_item_set_lock_content (gint32 item_ID, gboolean lock_content); +gboolean gimp_item_get_lock_position (gint32 item_ID); +gboolean gimp_item_set_lock_position (gint32 item_ID, + gboolean lock_position); gint gimp_item_get_tattoo (gint32 item_ID); gboolean gimp_item_set_tattoo (gint32 item_ID, gint tattoo); diff --git a/tools/pdbgen/pdb/drawable_transform.pdb b/tools/pdbgen/pdb/drawable_transform.pdb index 7cbf357da5..faf61440c5 100644 --- a/tools/pdbgen/pdb/drawable_transform.pdb +++ b/tools/pdbgen/pdb/drawable_transform.pdb @@ -25,11 +25,14 @@ sub transform_invoke { my ($progress_text, $assemble_matrix, $check) = @_; my $success_check = 'gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error);'; + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error);'; if ($check) { $success_check = "(gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error) && " . $check . ");"; + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error) && " . $check . ");"; } %invoke = ( @@ -86,11 +89,13 @@ CODE sub transform_default_invoke { my ($progress_text, $assemble_matrix, $check) = @_; my $success_check = 'gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error);'; + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error);'; if ($check) { $success_check = "(gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error) && " . $check . ");"; + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error) && " . $check . ");"; } %invoke = ( @@ -180,7 +185,8 @@ sub drawable_transform_flip_simple { gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -423,7 +429,8 @@ sub drawable_transform_rotate_simple { gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) diff --git a/tools/pdbgen/pdb/item.pdb b/tools/pdbgen/pdb/item.pdb index 2c7eb43a5a..de868acaff 100644 --- a/tools/pdbgen/pdb/item.pdb +++ b/tools/pdbgen/pdb/item.pdb @@ -623,6 +623,58 @@ CODE ); } +sub item_get_lock_position { + $blurb = "Get the 'lock position' state of the specified item."; + + $help = "This procedure returns the specified item's lock position state."; + + &mitch_pdb_misc('2012', '2.10'); + + @inargs = ( + { name => 'item', type => 'item', + desc => 'The item' } + ); + + @outargs = ( + { name => 'lock_position', type => 'boolean', + desc => "Whether the item's position is locked" } + ); + + %invoke = ( + code => <<'CODE' +{ + lock_position = gimp_item_get_lock_position (GIMP_ITEM (item)); +} +CODE + ); +} + +sub item_set_lock_position { + $blurb = "Set the 'lock position' state of the specified item."; + + $help = "This procedure sets the specified item's lock position state."; + + &mitch_pdb_misc('2009', '2.10'); + + @inargs = ( + { name => 'item', type => 'item', + desc => 'The item' }, + { name => 'lock_position', type => 'boolean', + desc => "The new item 'lock position' state" } + ); + + %invoke = ( + code => <<'CODE' +{ + if (gimp_item_can_lock_position (GIMP_ITEM (item))) + gimp_item_set_lock_position (GIMP_ITEM (item), lock_position, TRUE); + else + success = FALSE; +} +CODE + ); +} + sub item_get_tattoo { $blurb = "Get the tattoo of the specified item."; @@ -817,6 +869,7 @@ CODE item_get_visible item_set_visible item_get_linked item_set_linked item_get_lock_content item_set_lock_content + item_get_lock_position item_set_lock_position item_get_tattoo item_set_tattoo item_attach_parasite item_detach_parasite item_get_parasite diff --git a/tools/pdbgen/pdb/item_transform.pdb b/tools/pdbgen/pdb/item_transform.pdb index 1b6dd7dd87..cee4b52df3 100644 --- a/tools/pdbgen/pdb/item_transform.pdb +++ b/tools/pdbgen/pdb/item_transform.pdb @@ -23,11 +23,13 @@ sub transform_invoke { my ($progress_text, $assemble_matrix, $check) = @_; my $success_check = 'gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error);'; + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error);'; if ($check) { $success_check = "(gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error) && " . $check . ");"; + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error) && " . $check . ");"; } %invoke = ( @@ -138,7 +140,8 @@ HELP gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) @@ -346,7 +349,8 @@ HELP gint x, y, width, height; success = gimp_pdb_item_is_attached (item, NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (item, &x, &y, &width, &height)) diff --git a/tools/pdbgen/pdb/layer.pdb b/tools/pdbgen/pdb/layer.pdb index df12ec40e6..b381f30058 100644 --- a/tools/pdbgen/pdb/layer.pdb +++ b/tools/pdbgen/pdb/layer.pdb @@ -433,7 +433,8 @@ HELP code => <<'CODE' { if (gimp_pdb_item_is_attached (GIMP_ITEM (layer), NULL, - GIMP_PDB_ITEM_CONTENT, error)) + GIMP_PDB_ITEM_CONTENT | GIMP_PDB_ITEM_POSITION, + error)) { GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context); @@ -477,7 +478,8 @@ sub layer_scale_full { code => <<'CODE' { if (gimp_pdb_item_is_attached (GIMP_ITEM (layer), NULL, - GIMP_PDB_ITEM_CONTENT, error)) + GIMP_PDB_ITEM_CONTENT | GIMP_PDB_ITEM_POSITION, + error)) { if (progress) gimp_progress_start (progress, _("Scaling"), FALSE); @@ -529,7 +531,8 @@ HELP code => <<'CODE' { if (gimp_pdb_item_is_attached (GIMP_ITEM (layer), NULL, - GIMP_PDB_ITEM_CONTENT, error)) + GIMP_PDB_ITEM_CONTENT | GIMP_PDB_ITEM_POSITION, + error)) gimp_item_resize (GIMP_ITEM (layer), context, new_width, new_height, offx, offy); else @@ -558,7 +561,8 @@ HELP code => <<'CODE' { if (gimp_pdb_item_is_attached (GIMP_ITEM (layer), NULL, - GIMP_PDB_ITEM_CONTENT, error)) + GIMP_PDB_ITEM_CONTENT | GIMP_PDB_ITEM_POSITION, + error)) gimp_layer_resize_to_image (layer, context); else success = FALSE; @@ -592,17 +596,23 @@ HELP %invoke = ( code => <<'CODE' { - GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); + if (gimp_pdb_item_is_modifyable (GIMP_ITEM (layer), + GIMP_PDB_ITEM_POSITION, error)) + { + GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); - gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, - _("Move Layer")); + gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, + _("Move Layer")); - gimp_item_translate (GIMP_ITEM (layer), offx, offy, TRUE); + gimp_item_translate (GIMP_ITEM (layer), offx, offy, TRUE); - if (gimp_item_get_linked (GIMP_ITEM (layer))) - gimp_item_linked_translate (GIMP_ITEM (layer), offx, offy, TRUE); + if (gimp_item_get_linked (GIMP_ITEM (layer))) + gimp_item_linked_translate (GIMP_ITEM (layer), offx, offy, TRUE); - gimp_image_undo_group_end (image); + gimp_image_undo_group_end (image); + } + else + success = FALSE; } CODE ); @@ -698,23 +708,29 @@ HELP %invoke = ( code => <<'CODE' { - GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); - gint offset_x; - gint offset_y; + if (gimp_pdb_item_is_modifyable (GIMP_ITEM (layer), + GIMP_PDB_ITEM_POSITION, error)) + { + GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); + gint offset_x; + gint offset_y; - gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, - _("Move Layer")); + gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, + _("Move Layer")); - gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y); - offx -= offset_x; - offy -= offset_y; + gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y); + offx -= offset_x; + offy -= offset_y; - gimp_item_translate (GIMP_ITEM (layer), offx, offy, TRUE); + gimp_item_translate (GIMP_ITEM (layer), offx, offy, TRUE); - if (gimp_item_get_linked (GIMP_ITEM (layer))) - gimp_item_linked_translate (GIMP_ITEM (layer), offx, offy, TRUE); + if (gimp_item_get_linked (GIMP_ITEM (layer))) + gimp_item_linked_translate (GIMP_ITEM (layer), offx, offy, TRUE); - gimp_image_undo_group_end (image); + gimp_image_undo_group_end (image); + } + else + success = FALSE; } CODE ); diff --git a/tools/pdbgen/pdb/transform_tools.pdb b/tools/pdbgen/pdb/transform_tools.pdb index bea3e26df1..1912be5acf 100644 --- a/tools/pdbgen/pdb/transform_tools.pdb +++ b/tools/pdbgen/pdb/transform_tools.pdb @@ -38,7 +38,8 @@ sub flip { gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -113,7 +114,8 @@ sub perspective { gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -191,7 +193,8 @@ sub rotate { gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -278,7 +281,8 @@ sub scale { gint x, y, width, height; success = (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error) && + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error) && x0 < x1 && y0 < y1); if (success && @@ -359,7 +363,8 @@ sub shear { gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) @@ -448,7 +453,8 @@ sub transform_2d { gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) diff --git a/tools/pdbgen/pdb/vectors.pdb b/tools/pdbgen/pdb/vectors.pdb index 22087bd84c..e5cd964ccb 100644 --- a/tools/pdbgen/pdb/vectors.pdb +++ b/tools/pdbgen/pdb/vectors.pdb @@ -71,7 +71,7 @@ HELP %invoke = ( code => <<'CODE' { - if (gimp_pdb_layer_is_text_layer (layer, FALSE, error)) + if (gimp_pdb_layer_is_text_layer (layer, 0, error)) { gint x, y; @@ -359,7 +359,9 @@ HELP code => <<"CODE" { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) { @@ -401,7 +403,9 @@ HELP code => <<"CODE" { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) { @@ -444,7 +448,9 @@ HELP code => <<"CODE" { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) { @@ -486,7 +492,9 @@ HELP code => <<"CODE" { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) { @@ -533,7 +541,9 @@ HELP code => <<"CODE" { GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, - GIMP_PDB_ITEM_CONTENT, error); + GIMP_PDB_ITEM_CONTENT | + GIMP_PDB_ITEM_POSITION, + error); if (stroke) {