[gimp] Bug 616416: hidden layer groups appear again after an image change



commit 359c9c22d9445699ea4a010038658efe74d8f4d7
Author: Massimo Valentini <mvalentini src gnome org>
Date:   Sun Sep 25 21:37:44 2011 +0200

    Bug 616416: hidden layer groups appear again after an image change

 app/core/gimpgrouplayer.c           |   24 ++++++++
 app/core/gimpviewable.c             |   23 ++++++++
 app/core/gimpviewable.h             |    7 ++
 app/widgets/gimpcontainertreeview.c |  104 +++++++++++++++++++++++++++++++---
 app/xcf/xcf-load.c                  |   17 +++++-
 app/xcf/xcf-private.h               |    3 +-
 app/xcf/xcf-save.c                  |   22 +++++++
 7 files changed, 186 insertions(+), 14 deletions(-)
---
diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c
index 3c726d2..3a31c6d 100644
--- a/app/core/gimpgrouplayer.c
+++ b/app/core/gimpgrouplayer.c
@@ -52,6 +52,7 @@ struct _GimpGroupLayerPrivate
   GeglNode       *graph;
   GeglNode       *offset_node;
   gint            suspend_resize;
+  gboolean        expanded;
 
   /*  hackish temp states to make the projection/tiles stuff work  */
   gboolean        reallocate_projection;
@@ -84,6 +85,9 @@ static gboolean        gimp_group_layer_get_size     (GimpViewable    *viewable,
                                                       gint            *width,
                                                       gint            *height);
 static GimpContainer * gimp_group_layer_get_children (GimpViewable    *viewable);
+static gboolean        gimp_group_layer_get_expanded (GimpViewable    *viewable);
+static void            gimp_group_layer_set_expanded (GimpViewable    *viewable,
+                                                      gboolean         expanded);
 
 static GimpItem      * gimp_group_layer_duplicate    (GimpItem        *item,
                                                       GType            new_type);
@@ -200,6 +204,8 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
   viewable_class->default_stock_id = "gtk-directory";
   viewable_class->get_size         = gimp_group_layer_get_size;
   viewable_class->get_children     = gimp_group_layer_get_children;
+  viewable_class->set_expanded     = gimp_group_layer_set_expanded;
+  viewable_class->get_expanded     = gimp_group_layer_get_expanded;
 
   item_class->duplicate            = gimp_group_layer_duplicate;
   item_class->convert              = gimp_group_layer_convert;
@@ -250,6 +256,7 @@ gimp_group_layer_init (GimpGroupLayer *group)
   GimpGroupLayerPrivate *private = GET_PRIVATE (group);
 
   private->children = gimp_drawable_stack_new (GIMP_TYPE_LAYER);
+  private->expanded = TRUE;
 
   g_signal_connect (private->children, "add",
                     G_CALLBACK (gimp_group_layer_child_add),
@@ -382,6 +389,23 @@ gimp_group_layer_get_children (GimpViewable *viewable)
   return GET_PRIVATE (viewable)->children;
 }
 
+static gboolean
+gimp_group_layer_get_expanded (GimpViewable *viewable)
+{
+  GimpGroupLayer *group = GIMP_GROUP_LAYER (viewable);
+
+  return GET_PRIVATE (group)->expanded;
+}
+
+static void
+gimp_group_layer_set_expanded (GimpViewable *viewable,
+                               gboolean      expanded)
+{
+  GimpGroupLayer *group = GIMP_GROUP_LAYER (viewable);
+
+  GET_PRIVATE (group)->expanded = expanded;
+}
+
 static GimpItem *
 gimp_group_layer_duplicate (GimpItem *item,
                             GType     new_type)
diff --git a/app/core/gimpviewable.c b/app/core/gimpviewable.c
index c8d9932..91d8376 100644
--- a/app/core/gimpviewable.c
+++ b/app/core/gimpviewable.c
@@ -169,6 +169,8 @@ gimp_viewable_class_init (GimpViewableClass *klass)
   klass->get_new_pixbuf          = gimp_viewable_real_get_new_pixbuf;
   klass->get_description         = gimp_viewable_real_get_description;
   klass->get_children            = gimp_viewable_real_get_children;
+  klass->set_expanded            = NULL;
+  klass->get_expanded            = NULL;
 
   GIMP_CONFIG_INSTALL_PROP_STRING (object_class, PROP_STOCK_ID, "stock-id",
                                    NULL, NULL,
@@ -1178,6 +1180,27 @@ gimp_viewable_get_children (GimpViewable *viewable)
 }
 
 gboolean
+gimp_viewable_get_expanded (GimpViewable *viewable)
+{
+  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), FALSE);
+
+  if (GIMP_VIEWABLE_GET_CLASS (viewable)->get_expanded)
+    return GIMP_VIEWABLE_GET_CLASS (viewable)->get_expanded (viewable);
+
+  return FALSE;
+}
+
+void
+gimp_viewable_set_expanded (GimpViewable *viewable,
+                            gboolean       expanded)
+{
+  g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
+
+  if (GIMP_VIEWABLE_GET_CLASS (viewable)->set_expanded)
+    GIMP_VIEWABLE_GET_CLASS (viewable)->set_expanded (viewable, expanded);
+}
+
+gboolean
 gimp_viewable_is_ancestor (GimpViewable *ancestor,
                            GimpViewable *descendant)
 {
diff --git a/app/core/gimpviewable.h b/app/core/gimpviewable.h
index 58db2ae..9b32a48 100644
--- a/app/core/gimpviewable.h
+++ b/app/core/gimpviewable.h
@@ -97,6 +97,10 @@ struct _GimpViewableClass
                                           gchar        **tooltip);
 
   GimpContainer * (* get_children)       (GimpViewable  *viewable);
+
+  void            (* set_expanded)       (GimpViewable  *viewable,
+                                          gboolean       expand);
+  gboolean        (* get_expanded)       (GimpViewable  *viewable);
 };
 
 
@@ -176,6 +180,9 @@ void            gimp_viewable_set_parent         (GimpViewable  *viewable,
                                                   GimpViewable  *parent);
 
 GimpContainer * gimp_viewable_get_children       (GimpViewable  *viewable);
+gboolean        gimp_viewable_get_expanded       (GimpViewable  *viewable);
+void            gimp_viewable_set_expanded       (GimpViewable  *viewable,
+                                                  gboolean       expanded);
 
 gboolean        gimp_viewable_is_ancestor        (GimpViewable  *ancestor,
                                                   GimpViewable  *descendant);
diff --git a/app/widgets/gimpcontainertreeview.c b/app/widgets/gimpcontainertreeview.c
index c745053..e0c801b 100644
--- a/app/widgets/gimpcontainertreeview.c
+++ b/app/widgets/gimpcontainertreeview.c
@@ -114,6 +114,13 @@ static gboolean      gimp_container_tree_view_get_selected_single (GimpContainer
                                                                    GtkTreeIter            *iter);
 static gint          gimp_container_tree_view_get_selected        (GimpContainerView    *view,
                                                                    GList               **items);
+static void          gimp_container_tree_view_row_expanded        (GtkTreeView               *tree_view,
+                                                                   GtkTreeIter               *iter,
+                                                                   GtkTreePath               *path,
+                                                                   GimpContainerTreeView     *view);
+static void          gimp_container_tree_view_expand_rows         (GtkTreeModel             *model,
+                                                                   GtkTreeView              *view,
+                                                                   GtkTreeIter              *parent);
 
 
 G_DEFINE_TYPE_WITH_CODE (GimpContainerTreeView, gimp_container_tree_view,
@@ -508,6 +515,9 @@ gimp_container_tree_view_set_container (GimpContainerView *view,
 
   if (old_container)
     {
+      g_signal_handlers_disconnect_by_func (tree_view->view,
+                                            gimp_container_tree_view_row_expanded,
+                                            tree_view);
       if (! container)
         {
           if (gimp_dnd_viewable_source_remove (GTK_WIDGET (tree_view->view),
@@ -552,6 +562,22 @@ gimp_container_tree_view_set_container (GimpContainerView *view,
 
   parent_view_iface->set_container (view, container);
 
+  if (container)
+    {
+      gimp_container_tree_view_expand_rows (tree_view->model,
+                                            tree_view->view,
+                                            NULL);
+
+      g_signal_connect (tree_view->view,
+                        "row-collapsed",
+                        G_CALLBACK (gimp_container_tree_view_row_expanded),
+                        tree_view);
+      g_signal_connect (tree_view->view,
+                        "row-expanded",
+                        G_CALLBACK (gimp_container_tree_view_row_expanded),
+                        tree_view);
+    }
+
   gtk_tree_view_columns_autosize (tree_view->view);
 }
 
@@ -592,16 +618,6 @@ gimp_container_tree_view_insert_item (GimpContainerView *view,
                                                 viewable,
                                                 parent_insert_data,
                                                 index);
-
-  if (parent_insert_data)
-    {
-      GtkTreePath *path = gtk_tree_model_get_path (tree_view->model, iter);
-
-      gtk_tree_view_expand_to_path (tree_view->view, path);
-
-      gtk_tree_path_free (path);
-    }
-
   return iter;
 }
 
@@ -1311,3 +1327,71 @@ gimp_container_tree_view_get_selected (GimpContainerView    *view,
 
   return selected_count;
 }
+
+static void
+gimp_container_tree_view_row_expanded (GtkTreeView           *tree_view,
+                                       GtkTreeIter           *iter,
+                                       GtkTreePath           *path,
+                                       GimpContainerTreeView *view)
+{
+  GimpViewRenderer *renderer;
+
+  gtk_tree_model_get (view->model, iter,
+                      GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
+                      -1);
+  if (renderer)
+    {
+      gboolean expanded = gtk_tree_view_row_expanded (tree_view, path);
+
+      gimp_viewable_set_expanded (renderer->viewable,
+                                  expanded);
+      if (expanded)
+        {
+          g_signal_handlers_block_by_func (tree_view,
+                                           gimp_container_tree_view_row_expanded,
+                                           view);
+
+          gimp_container_tree_view_expand_rows (view->model, tree_view, iter);
+
+          g_signal_handlers_unblock_by_func (tree_view,
+                                             gimp_container_tree_view_row_expanded,
+                                             view);
+        }
+
+      g_object_unref (renderer);
+    }
+}
+
+static void
+gimp_container_tree_view_expand_rows (GtkTreeModel *model,
+                                      GtkTreeView  *view,
+                                      GtkTreeIter  *parent)
+{
+  GtkTreeIter iter;
+
+  if (gtk_tree_model_iter_children (model, &iter, parent))
+    do
+      if (gtk_tree_model_iter_has_child (model, &iter))
+        {
+          GimpViewRenderer *renderer;
+
+          gtk_tree_model_get (model, &iter,
+                              GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
+                              -1);
+          if (renderer)
+            {
+              GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
+
+              if (gimp_viewable_get_expanded (renderer->viewable))
+                gtk_tree_view_expand_row (view, path, FALSE);
+              else
+                gtk_tree_view_collapse_row (view, path);
+
+              gtk_tree_path_free (path);
+              g_object_unref (renderer);
+            }
+
+          gimp_container_tree_view_expand_rows (model, view, &iter);
+        }
+    while (gtk_tree_model_iter_next (model, &iter));
+}
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index 6319b37..a5f21e5 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -83,7 +83,8 @@ static gboolean        xcf_load_layer_props   (XcfInfo      *info,
                                                gboolean     *apply_mask,
                                                gboolean     *edit_mask,
                                                gboolean     *show_mask,
-                                               guint32      *text_layer_flags);
+                                               guint32      *text_layer_flags,
+                                               guint32      *group_layer_flags);
 static gboolean        xcf_load_channel_props (XcfInfo      *info,
                                                GimpImage    *image,
                                                GimpChannel **channel);
@@ -693,7 +694,8 @@ xcf_load_layer_props (XcfInfo    *info,
                       gboolean   *apply_mask,
                       gboolean   *edit_mask,
                       gboolean   *show_mask,
-                      guint32    *text_layer_flags)
+                      guint32    *text_layer_flags,
+                      guint32    *group_layer_flags)
 {
   PropType prop_type;
   guint32  prop_size;
@@ -870,6 +872,10 @@ xcf_load_layer_props (XcfInfo    *info,
           }
           break;
 
+        case PROP_GROUP_ITEM_FLAGS:
+          info->cp += xcf_read_int32 (info->fp, group_layer_flags, 1);
+          break;
+
         default:
 #ifdef GIMP_UNSTABLE
           g_printerr ("unexpected/unknown layer property: %d (skipping)\n",
@@ -1061,6 +1067,7 @@ xcf_load_layer (XcfInfo    *info,
   gboolean       show_mask  = FALSE;
   gboolean       active;
   gboolean       floating;
+  guint32        group_layer_flags = 0;
   guint32        text_layer_flags = 0;
   gint           width;
   gint           height;
@@ -1089,7 +1096,7 @@ xcf_load_layer (XcfInfo    *info,
   /* read in the layer properties */
   if (! xcf_load_layer_props (info, image, &layer, item_path,
                               &apply_mask, &edit_mask, &show_mask,
-                              &text_layer_flags))
+                              &text_layer_flags, &group_layer_flags))
     goto error;
 
   xcf_progress_update (info);
@@ -1128,6 +1135,10 @@ xcf_load_layer (XcfInfo    *info,
 
       xcf_progress_update (info);
     }
+  else
+    {
+      gimp_viewable_set_expanded (GIMP_VIEWABLE (layer), group_layer_flags != 0);
+    }
 
   /* read in the layer mask */
   if (layer_mask_offset != 0)
diff --git a/app/xcf/xcf-private.h b/app/xcf/xcf-private.h
index b539d31..1873e20 100644
--- a/app/xcf/xcf-private.h
+++ b/app/xcf/xcf-private.h
@@ -51,7 +51,8 @@ typedef enum
   PROP_SAMPLE_POINTS      = 27,
   PROP_LOCK_CONTENT       = 28,
   PROP_GROUP_ITEM         = 29,
-  PROP_ITEM_PATH          = 30
+  PROP_ITEM_PATH          = 30,
+  PROP_GROUP_ITEM_FLAGS   = 31
 } PropType;
 
 typedef enum
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index 6d3e214..f02b357 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -537,6 +537,15 @@ xcf_save_layer_props (XcfInfo    *info,
                                         flags));
     }
 
+  if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
+    {
+      gint32 flags = gimp_viewable_get_expanded (GIMP_VIEWABLE (layer));
+
+      xcf_check_error (xcf_save_prop (info,
+                                      image, PROP_GROUP_ITEM_FLAGS, error,
+                                      flags));
+    }
+
   parasites = gimp_item_get_parasites (GIMP_ITEM (layer));
 
   if (gimp_parasite_list_length (parasites) > 0)
@@ -1113,6 +1122,19 @@ xcf_save_prop (XcfInfo    *info,
           }
       }
       break;
+
+    case PROP_GROUP_ITEM_FLAGS:
+      {
+        guint32 flags;
+
+        flags = 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, &flags, 1);
+      }
+      break;
     }
 
   va_end (args);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]