diff --git a/app/core/core-enums.c b/app/core/core-enums.c index 9b459c9320..1c55ae0f23 100644 --- a/app/core/core-enums.c +++ b/app/core/core-enums.c @@ -1224,6 +1224,7 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_ITEM_COLOR_TAG, "GIMP_UNDO_ITEM_COLOR_TAG", "item-color-tag" }, { 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_ITEM_LOCK_VISIBILITY, "GIMP_UNDO_ITEM_LOCK_VISIBILITY", "item-lock-visibility" }, { 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" }, @@ -1331,6 +1332,7 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_ITEM_COLOR_TAG, NC_("undo-type", "Item color tag"), 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_ITEM_LOCK_VISIBILITY, NC_("undo-type", "Lock/Unlock visibility"), 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 ead4a09fc8..e55729acd9 100644 --- a/app/core/core-enums.h +++ b/app/core/core-enums.h @@ -596,6 +596,7 @@ typedef enum /*< pdb-skip >*/ GIMP_UNDO_ITEM_COLOR_TAG, /*< desc="Item color tag" >*/ GIMP_UNDO_ITEM_LOCK_CONTENT, /*< desc="Lock/Unlock content" >*/ GIMP_UNDO_ITEM_LOCK_POSITION, /*< desc="Lock/Unlock position" >*/ + GIMP_UNDO_ITEM_LOCK_VISIBILITY, /*< desc="Lock/Unlock visibility" >*/ 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/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c index aeb293c380..c2f9190114 100644 --- a/app/core/gimpimage-undo-push.c +++ b/app/core/gimpimage-undo-push.c @@ -482,6 +482,22 @@ gimp_image_undo_push_item_lock_position (GimpImage *image, NULL); } +GimpUndo * +gimp_image_undo_push_item_lock_visibility (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_VISIBILITY, 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 3aea6e4a1f..57a3ec9fc0 100644 --- a/app/core/gimpimage-undo-push.h +++ b/app/core/gimpimage-undo-push.h @@ -113,6 +113,9 @@ GimpUndo * gimp_image_undo_push_item_lock_content (GimpImage *image, GimpUndo * gimp_image_undo_push_item_lock_position (GimpImage *image, const gchar *undo_desc, GimpItem *item); +GimpUndo * gimp_image_undo_push_item_lock_visibility (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-exclusive.c b/app/core/gimpitem-exclusive.c index 5cdb45f32f..6b07c268f3 100644 --- a/app/core/gimpitem-exclusive.c +++ b/app/core/gimpitem-exclusive.c @@ -253,22 +253,21 @@ gimp_item_exclusive_get_lists (GimpItem *item, { GimpItem *other = list->data; - if (other != item) + if (other != item && + /* Don't include item with visibility locks. */ + ! gimp_item_is_visibility_locked (other) && + /* We are only interested in same level items. */ + gimp_viewable_get_parent (GIMP_VIEWABLE (other)) == + gimp_viewable_get_parent (GIMP_VIEWABLE (item))) { - /* we are only interested in same level items. - */ - if (gimp_viewable_get_parent (GIMP_VIEWABLE (other)) == - gimp_viewable_get_parent (GIMP_VIEWABLE (item))) - { - gboolean value; + gboolean value; - g_object_get (other, property, &value, NULL); + g_object_get (other, property, &value, NULL); - if (value) - *on = g_list_prepend (*on, other); - else - *off = g_list_prepend (*off, other); - } + if (value) + *on = g_list_prepend (*on, other); + else + *off = g_list_prepend (*off, other); } } diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c index 387242863a..a922b9a8b0 100644 --- a/app/core/gimpitem.c +++ b/app/core/gimpitem.c @@ -58,6 +58,7 @@ enum COLOR_TAG_CHANGED, LOCK_CONTENT_CHANGED, LOCK_POSITION_CHANGED, + LOCK_VISIBILITY_CHANGED, LAST_SIGNAL }; @@ -75,6 +76,7 @@ enum PROP_COLOR_TAG, PROP_LOCK_CONTENT, PROP_LOCK_POSITION, + PROP_LOCK_VISIBILITY, N_PROPS }; @@ -99,6 +101,7 @@ struct _GimpItemPrivate guint linked : 1; /* control linkage */ guint lock_content : 1; /* content editability */ guint lock_position : 1; /* content movability */ + guint lock_visibility : 1; /* automatic visibility change */ guint removed : 1; /* removed from the image? */ @@ -128,6 +131,7 @@ static gint64 gimp_item_get_memsize (GimpObject *object, static gboolean gimp_item_real_is_content_locked (GimpItem *item); static gboolean gimp_item_real_is_position_locked (GimpItem *item); +static gboolean gimp_item_real_is_visibility_locked (GimpItem *item); static gboolean gimp_item_real_bounds (GimpItem *item, gdouble *x, gdouble *y, @@ -233,6 +237,14 @@ gimp_item_class_init (GimpItemClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 0); + gimp_item_signals[LOCK_VISIBILITY_CHANGED] = + g_signal_new ("lock-visibility-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GimpItemClass, lock_visibility_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + object_class->constructed = gimp_item_constructed; object_class->finalize = gimp_item_finalize; object_class->set_property = gimp_item_set_property; @@ -250,11 +262,13 @@ gimp_item_class_init (GimpItemClass *klass) klass->color_tag_changed = NULL; klass->lock_content_changed = NULL; klass->lock_position_changed = NULL; + klass->lock_visibility_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->is_visibility_locked = gimp_item_real_is_visibility_locked; klass->get_tree = NULL; klass->bounds = gimp_item_real_bounds; klass->duplicate = gimp_item_real_duplicate; @@ -335,6 +349,11 @@ gimp_item_class_init (GimpItemClass *klass) FALSE, GIMP_PARAM_READABLE); + gimp_item_props[PROP_LOCK_VISIBILITY] = g_param_spec_boolean ("lock-visibility", + NULL, NULL, + FALSE, + GIMP_PARAM_READABLE); + g_object_class_install_properties (object_class, N_PROPS, gimp_item_props); } @@ -447,6 +466,9 @@ gimp_item_get_property (GObject *object, case PROP_LOCK_POSITION: g_value_set_boolean (value, private->lock_position); break; + case PROP_LOCK_VISIBILITY: + g_value_set_boolean (value, private->lock_visibility); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -489,6 +511,18 @@ gimp_item_real_is_position_locked (GimpItem *item) return GET_PRIVATE (item)->lock_position; } +static gboolean +gimp_item_real_is_visibility_locked (GimpItem *item) +{ + GimpItem *parent = gimp_item_get_parent (item); + + /* Locking visibility of a group item locks all child items. */ + if (parent && gimp_item_is_visibility_locked (parent)) + return TRUE; + + return GET_PRIVATE (item)->lock_visibility; +} + static gboolean gimp_item_real_bounds (GimpItem *item, gdouble *x, @@ -571,6 +605,10 @@ gimp_item_real_duplicate (GimpItem *item, gimp_item_set_lock_position (new_item, gimp_item_get_lock_position (item), FALSE); + if (gimp_item_can_lock_visibility (new_item)) + gimp_item_set_lock_visibility (new_item, gimp_item_get_lock_visibility (item), + FALSE); + return new_item; } @@ -2068,6 +2106,7 @@ gimp_item_replace_item (GimpItem *item, gimp_item_set_color_tag (item, gimp_item_get_color_tag (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); + gimp_item_set_lock_visibility (item, gimp_item_get_lock_visibility (replace), FALSE); } /** @@ -2280,7 +2319,8 @@ gimp_item_set_visible (GimpItem *item, visible = visible ? TRUE : FALSE; - if (gimp_item_get_visible (item) != visible) + if (gimp_item_get_visible (item) != visible && + ! gimp_item_is_visibility_locked (item)) { if (push_undo && gimp_item_is_attached (item)) { @@ -2539,6 +2579,57 @@ gimp_item_is_position_locked (GimpItem *item) return GIMP_ITEM_GET_CLASS (item)->is_position_locked (item); } +void +gimp_item_set_lock_visibility (GimpItem *item, + gboolean lock_visibility, + gboolean push_undo) +{ + g_return_if_fail (GIMP_IS_ITEM (item)); + g_return_if_fail (gimp_item_can_lock_visibility (item)); + + lock_visibility = lock_visibility ? TRUE : FALSE; + + if (gimp_item_get_lock_visibility (item) != lock_visibility) + { + if (push_undo && gimp_item_is_attached (item)) + { + GimpImage *image = gimp_item_get_image (item); + + gimp_image_undo_push_item_lock_visibility (image, NULL, item); + } + + GET_PRIVATE (item)->lock_visibility = lock_visibility; + + g_signal_emit (item, gimp_item_signals[LOCK_VISIBILITY_CHANGED], 0); + + g_object_notify (G_OBJECT (item), "lock-visibility"); + } +} + +gboolean +gimp_item_get_lock_visibility (GimpItem *item) +{ + g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE); + + return GET_PRIVATE (item)->lock_visibility; +} + +gboolean +gimp_item_can_lock_visibility (GimpItem *item) +{ + g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE); + + return TRUE; +} + +gboolean +gimp_item_is_visibility_locked (GimpItem *item) +{ + g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE); + + return GIMP_ITEM_GET_CLASS (item)->is_visibility_locked (item); +} + gboolean gimp_item_mask_bounds (GimpItem *item, gint *x1, diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h index f71e32b017..2c9794c9ed 100644 --- a/app/core/gimpitem.h +++ b/app/core/gimpitem.h @@ -48,12 +48,14 @@ struct _GimpItemClass void (* color_tag_changed) (GimpItem *item); void (* lock_content_changed) (GimpItem *item); void (* lock_position_changed) (GimpItem *item); + void (* lock_visibility_changed) (GimpItem *item); /* virtual functions */ void (* unset_removed) (GimpItem *item); gboolean (* is_attached) (GimpItem *item); gboolean (* is_content_locked) (GimpItem *item); gboolean (* is_position_locked) (GimpItem *item); + gboolean (* is_visibility_locked) (GimpItem *item); GimpItemTree * (* get_tree) (GimpItem *item); gboolean (* bounds) (GimpItem *item, gdouble *x, @@ -387,6 +389,13 @@ gboolean gimp_item_get_lock_position (GimpItem *item); gboolean gimp_item_can_lock_position (GimpItem *item); gboolean gimp_item_is_position_locked (GimpItem *item); +void gimp_item_set_lock_visibility (GimpItem *item, + gboolean lock_visibility, + gboolean push_undo); +gboolean gimp_item_get_lock_visibility (GimpItem *item); +gboolean gimp_item_can_lock_visibility (GimpItem *item); +gboolean gimp_item_is_visibility_locked (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 241b8aa73f..4c96c203e5 100644 --- a/app/core/gimpitempropundo.c +++ b/app/core/gimpitempropundo.c @@ -139,6 +139,10 @@ gimp_item_prop_undo_constructed (GObject *object) item_prop_undo->lock_position = gimp_item_get_lock_position (item); break; + case GIMP_UNDO_ITEM_LOCK_VISIBILITY: + item_prop_undo->lock_visibility = gimp_item_get_lock_visibility (item); + break; + case GIMP_UNDO_PARASITE_ATTACH: case GIMP_UNDO_PARASITE_REMOVE: gimp_assert (item_prop_undo->parasite_name != NULL); @@ -319,6 +323,16 @@ gimp_item_prop_undo_pop (GimpUndo *undo, } break; + case GIMP_UNDO_ITEM_LOCK_VISIBILITY: + { + gboolean lock_visibility; + + lock_visibility = gimp_item_get_lock_visibility (item); + gimp_item_set_lock_visibility (item, item_prop_undo->lock_visibility, FALSE); + item_prop_undo->lock_visibility = lock_visibility; + } + break; + case GIMP_UNDO_PARASITE_ATTACH: case GIMP_UNDO_PARASITE_REMOVE: { diff --git a/app/core/gimpitempropundo.h b/app/core/gimpitempropundo.h index 8f96e46519..8f5a8c79f5 100644 --- a/app/core/gimpitempropundo.h +++ b/app/core/gimpitempropundo.h @@ -42,10 +42,11 @@ struct _GimpItemPropUndo gchar *name; gint offset_x; gint offset_y; - guint visible : 1; - guint linked : 1; - guint lock_content : 1; - guint lock_position : 1; + guint visible : 1; + guint linked : 1; + guint lock_content : 1; + guint lock_position : 1; + guint lock_visibility : 1; GimpColorTag color_tag; gchar *parasite_name; GimpParasite *parasite; diff --git a/app/widgets/gimpdrawabletreeview.c b/app/widgets/gimpdrawabletreeview.c index b3465fa5c9..ad3ae0b7d9 100644 --- a/app/widgets/gimpdrawabletreeview.c +++ b/app/widgets/gimpdrawabletreeview.c @@ -118,10 +118,12 @@ gimp_drawable_tree_view_class_init (GimpDrawableTreeViewClass *klass) item_view_class->set_image = gimp_drawable_tree_view_set_image; - item_view_class->lock_content_icon_name = GIMP_ICON_TOOL_PAINTBRUSH; - item_view_class->lock_content_tooltip = _("Lock pixels"); - item_view_class->lock_position_icon_name = GIMP_ICON_TOOL_MOVE; - item_view_class->lock_position_tooltip = _("Lock position and size"); + item_view_class->lock_content_icon_name = GIMP_ICON_TOOL_PAINTBRUSH; + item_view_class->lock_content_tooltip = _("Lock pixels"); + item_view_class->lock_position_icon_name = GIMP_ICON_TOOL_MOVE; + item_view_class->lock_position_tooltip = _("Lock position and size"); + item_view_class->lock_visibility_icon_name = GIMP_ICON_VISIBLE; + item_view_class->lock_visibility_tooltip = _("Lock visibility"); } static void diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h index 96b8c1fe0c..60ebd9ecc0 100644 --- a/app/widgets/gimphelp-ids.h +++ b/app/widgets/gimphelp-ids.h @@ -201,6 +201,7 @@ #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_LOCK_VISIBILITY "gimp-layer-lock-visibility" #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" @@ -245,6 +246,7 @@ #define GIMP_HELP_CHANNEL_COLOR_TAG "gimp-channel-color-tag" #define GIMP_HELP_CHANNEL_LOCK_PIXELS "gimp-channel-lock-pixels" #define GIMP_HELP_CHANNEL_LOCK_POSITION "gimp-channel-lock-position" +#define GIMP_HELP_CHANNEL_LOCK_VISIBILITY "gimp-channel-lock-visibility" #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" diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c index 8850fe380a..cdf6b91ce8 100644 --- a/app/widgets/gimpitemtreeview.c +++ b/app/widgets/gimpitemtreeview.c @@ -76,6 +76,7 @@ struct _GimpItemTreeViewPrivate GtkWidget *multi_selection_label; GtkWidget *lock_content_toggle; GtkWidget *lock_position_toggle; + GtkWidget *lock_visibility_toggle; GtkWidget *new_button; GtkWidget *raise_button; @@ -95,6 +96,7 @@ struct _GimpItemTreeViewPrivate GimpTreeHandler *color_tag_changed_handler; GimpTreeHandler *lock_content_changed_handler; GimpTreeHandler *lock_position_changed_handler; + GimpTreeHandler *lock_visibility_changed_handler; gboolean inserting_item; /* EEK */ }; @@ -169,16 +171,18 @@ static void gimp_item_tree_view_name_edited (GtkCellRendererText *cell, const gchar *new_name, GimpItemTreeView *view); -static void gimp_item_tree_view_visible_changed (GimpItem *item, - GimpItemTreeView *view); -static void gimp_item_tree_view_linked_changed (GimpItem *item, - GimpItemTreeView *view); -static void gimp_item_tree_view_color_tag_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_visible_changed (GimpItem *item, + GimpItemTreeView *view); +static void gimp_item_tree_view_linked_changed (GimpItem *item, + GimpItemTreeView *view); +static void gimp_item_tree_view_color_tag_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_lock_visibility_changed (GimpItem *item, + GimpItemTreeView *view); static void gimp_item_tree_view_eye_clicked (GtkCellRendererToggle *toggle, gchar *path, @@ -194,6 +198,9 @@ static void gimp_item_tree_view_lock_content_toggled static void gimp_item_tree_view_lock_position_toggled (GtkWidget *widget, GimpItemTreeView *view); +static void gimp_item_tree_view_lock_visibility_toggled + (GtkWidget *widget, + GimpItemTreeView *view); static void gimp_item_tree_view_update_options (GimpItemTreeView *view, GList *items); @@ -290,6 +297,10 @@ gimp_item_tree_view_class_init (GimpItemTreeViewClass *klass) klass->lock_position_icon_name = NULL; klass->lock_position_tooltip = NULL; klass->lock_position_help_id = NULL; + + klass->lock_visibility_icon_name = NULL; + klass->lock_visibility_tooltip = NULL; + klass->lock_visibility_help_id = NULL; } static void @@ -533,6 +544,28 @@ gimp_item_tree_view_constructed (GObject *object) gtk_container_add (GTK_CONTAINER (item_view->priv->lock_position_toggle), image); gtk_widget_show (image); + + /* Lock visibility toggle */ + item_view->priv->lock_visibility_toggle = gtk_toggle_button_new (); + gtk_box_pack_start (GTK_BOX (hbox), item_view->priv->lock_visibility_toggle, + FALSE, FALSE, 0); + gtk_box_reorder_child (GTK_BOX (hbox), + item_view->priv->lock_visibility_toggle, 2); + gtk_widget_show (item_view->priv->lock_visibility_toggle); + + g_signal_connect (item_view->priv->lock_visibility_toggle, "toggled", + G_CALLBACK (gimp_item_tree_view_lock_visibility_toggled), + item_view); + + gimp_help_set_help_data (item_view->priv->lock_visibility_toggle, + item_view_class->lock_visibility_tooltip, + item_view_class->lock_visibility_help_id); + + image = gtk_image_new_from_icon_name (item_view_class->lock_visibility_icon_name, + icon_size); + gtk_container_add (GTK_CONTAINER (item_view->priv->lock_visibility_toggle), + image); + gtk_widget_show (image); } static void @@ -931,6 +964,9 @@ gimp_item_tree_view_set_container (GimpContainerView *view, gimp_tree_handler_disconnect (item_view->priv->lock_position_changed_handler); item_view->priv->lock_position_changed_handler = NULL; + + gimp_tree_handler_disconnect (item_view->priv->lock_visibility_changed_handler); + item_view->priv->lock_visibility_changed_handler = NULL; } parent_view_iface->set_container (view, container); @@ -961,6 +997,11 @@ gimp_item_tree_view_set_container (GimpContainerView *view, gimp_tree_handler_connect (container, "lock-position-changed", G_CALLBACK (gimp_item_tree_view_lock_position_changed), view); + + item_view->priv->lock_visibility_changed_handler = + gimp_tree_handler_connect (container, "lock-visibility-changed", + G_CALLBACK (gimp_item_tree_view_lock_visibility_changed), + view); } } @@ -1772,6 +1813,60 @@ gimp_item_tree_view_lock_position_toggled (GtkWidget *widget, gimp_image_undo_group_end (image); } +static void +gimp_item_tree_view_lock_visibility_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_visibility_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_visibility; + + lock_visibility = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + + if (gimp_item_get_lock_visibility (item) != lock_visibility) + { + GimpUndo *undo; + gboolean push_undo = TRUE; + + /* compress lock visibilities undos */ + undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO, + GIMP_UNDO_ITEM_LOCK_VISIBILITY); + + if (undo && GIMP_ITEM_UNDO (undo)->item == item) + push_undo = FALSE; + + g_signal_handlers_block_by_func (item, + gimp_item_tree_view_lock_visibility_changed, + view); + + gimp_item_set_lock_visibility (item, lock_visibility, push_undo); + + g_signal_handlers_unblock_by_func (item, + gimp_item_tree_view_lock_visibility_changed, + view); + gimp_image_flush (image); + } + } +} + static gboolean gimp_item_tree_view_item_pre_clicked (GimpCellRendererViewable *cell, const gchar *path_str, @@ -1842,8 +1937,11 @@ gimp_item_tree_view_update_options (GimpItemTreeView *view, gboolean some_can_lock_content = FALSE; gboolean all_have_lock_position = TRUE; gboolean some_can_lock_position = FALSE; + gboolean all_have_lock_visibility = TRUE; + gboolean some_can_lock_visibility = FALSE; gboolean inconsistent_lock_content = FALSE; gboolean inconsistent_lock_position = FALSE; + gboolean inconsistent_lock_visibility = FALSE; for (iter = items; iter; iter = iter->next) { @@ -1862,9 +1960,18 @@ gimp_item_tree_view_update_options (GimpItemTreeView *view, if (gimp_item_can_lock_position (iter->data)) some_can_lock_position = TRUE; + + if (! gimp_item_get_lock_visibility (iter->data)) + all_have_lock_visibility = FALSE; + else + inconsistent_lock_visibility = TRUE; + + if (gimp_item_can_lock_visibility (iter->data)) + some_can_lock_visibility = TRUE; } inconsistent_lock_content = (! all_have_lock_content && inconsistent_lock_content); inconsistent_lock_position = (! all_have_lock_position && inconsistent_lock_position); + inconsistent_lock_visibility = (! all_have_lock_visibility && inconsistent_lock_visibility); if (all_have_lock_content != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->lock_content_toggle))) @@ -1900,8 +2007,26 @@ gimp_item_tree_view_update_options (GimpItemTreeView *view, gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (view->priv->lock_position_toggle), inconsistent_lock_position); + if (all_have_lock_visibility != + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->lock_visibility_toggle))) + { + g_signal_handlers_block_by_func (view->priv->lock_visibility_toggle, + gimp_item_tree_view_lock_visibility_toggled, + view); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->lock_visibility_toggle), + all_have_lock_visibility); + + g_signal_handlers_unblock_by_func (view->priv->lock_visibility_toggle, + gimp_item_tree_view_lock_visibility_toggled, + view); + } + gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (view->priv->lock_visibility_toggle), + inconsistent_lock_visibility); + gtk_widget_set_sensitive (view->priv->lock_content_toggle, some_can_lock_content); gtk_widget_set_sensitive (view->priv->lock_position_toggle, some_can_lock_position); + gtk_widget_set_sensitive (view->priv->lock_position_toggle, some_can_lock_visibility); } diff --git a/app/widgets/gimpitemtreeview.h b/app/widgets/gimpitemtreeview.h index 5c7ab29165..951d6b4b8f 100644 --- a/app/widgets/gimpitemtreeview.h +++ b/app/widgets/gimpitemtreeview.h @@ -104,6 +104,11 @@ struct _GimpItemTreeViewClass const gchar *lock_position_icon_name; const gchar *lock_position_tooltip; const gchar *lock_position_help_id; + + /* lock visibility button appearance */ + const gchar *lock_visibility_icon_name; + const gchar *lock_visibility_tooltip; + const gchar *lock_visibility_help_id; };