[gnome-builder] project-tree: Expand tree properly after a refresh



commit 5b92c1efb529c0fa294c71fcce57f6521cfc5b4d
Author: Matthew Leeds <mleeds redhat com>
Date:   Wed Nov 23 02:20:35 2016 -0600

    project-tree: Expand tree properly after a refresh
    
    After refreshing the project tree (which checks for new files in the
    filesystem), the tree will have newly created IdeTreeNode instances, so
    the code we were using to find the node that was selected before the
    rebuild wasn't working, meaning that the tree was always collapsed after
    a rebuild. This commit changes gb_project_tree_actions_refresh to use
    gb_project_tree_reveal, and changes that function to allow expansions of
    matching folders, and to behave reasonably for deleted files and for the
    the top level folder. It also changes the places where that reveal
    function is called to make them work.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=774822

 plugins/project-tree/gb-project-tree-actions.c     |   27 ++++--
 .../project-tree/gb-project-tree-editor-addin.c    |    2 +-
 plugins/project-tree/gb-project-tree.c             |   89 +++++++++++++-------
 plugins/project-tree/gb-project-tree.h             |    3 +-
 4 files changed, 79 insertions(+), 42 deletions(-)
---
diff --git a/plugins/project-tree/gb-project-tree-actions.c b/plugins/project-tree/gb-project-tree-actions.c
index 66b11cd..7b55e49 100644
--- a/plugins/project-tree/gb-project-tree-actions.c
+++ b/plugins/project-tree/gb-project-tree-actions.c
@@ -70,28 +70,37 @@ gb_project_tree_actions_refresh (GSimpleAction *action,
   GbProjectTree *self = user_data;
   IdeTreeNode *selected;
   GObject *item = NULL;
+  g_autoptr(GFile) expand_to = NULL;
+  gboolean expanded = FALSE;
 
   g_assert (GB_IS_PROJECT_TREE (self));
 
   if ((selected = ide_tree_get_selected (IDE_TREE (self))))
     {
+      expanded = ide_tree_node_get_expanded (selected);
       item = ide_tree_node_get_item (selected);
-      if (item != NULL)
-        g_object_ref (item);
+      if (GB_IS_PROJECT_FILE (item))
+        expand_to = g_object_ref (gb_project_file_get_file (GB_PROJECT_FILE (item)));
     }
 
   ide_tree_rebuild (IDE_TREE (self));
 
-  if (item != NULL)
+  if (expand_to != NULL)
     {
-      selected = ide_tree_find_item (IDE_TREE (self), item);
-      if (selected != NULL)
+      gb_project_tree_reveal (self, expand_to, FALSE, expanded);
+    }
+  else
+    {
+      /* Even if nothing was selected, we want the top level expanded */
+      IdeContext *context;
+      context = gb_project_tree_get_context (self);
+      if (context != NULL)
         {
-          ide_tree_node_expand (selected, TRUE);
-          ide_tree_node_select (selected);
-          ide_tree_scroll_to_node (IDE_TREE (self), selected);
+          GFile *project_file;
+          project_file = ide_context_get_project_file (context);
+          if (project_file != NULL)
+            gb_project_tree_reveal (self, project_file, FALSE, FALSE);
         }
-      g_object_unref (item);
     }
 }
 
diff --git a/plugins/project-tree/gb-project-tree-editor-addin.c 
b/plugins/project-tree/gb-project-tree-editor-addin.c
index c38bca8..ce6960b 100644
--- a/plugins/project-tree/gb-project-tree-editor-addin.c
+++ b/plugins/project-tree/gb-project-tree-editor-addin.c
@@ -73,7 +73,7 @@ gb_project_tree_editor_addin_reveal (GSimpleAction *action,
   g_assert (!file || G_IS_FILE (file));
 
   if (G_IS_FILE (file))
-    gb_project_tree_reveal (tree, file, TRUE);
+    gb_project_tree_reveal (tree, file, TRUE, FALSE);
 }
 
 static void
diff --git a/plugins/project-tree/gb-project-tree.c b/plugins/project-tree/gb-project-tree.c
index f67a94e..119092e 100644
--- a/plugins/project-tree/gb-project-tree.c
+++ b/plugins/project-tree/gb-project-tree.c
@@ -73,7 +73,7 @@ gb_project_tree_project_file_renamed (GbProjectTree *self,
   g_assert (IDE_IS_PROJECT (project));
 
   ide_tree_rebuild (IDE_TREE (self));
-  gb_project_tree_reveal (self, dst_file, FALSE);
+  gb_project_tree_reveal (self, dst_file, FALSE, FALSE);
 
   IDE_EXIT;
 }
@@ -131,25 +131,14 @@ static void
 gb_project_tree_vcs_changed (GbProjectTree *self,
                              IdeVcs        *vcs)
 {
-  g_autoptr(GFile) file = NULL;
-  IdeTreeNode *node;
-  GObject *item;
+  GActionGroup *group;
 
   g_assert (GB_IS_PROJECT_TREE (self));
   g_assert (IDE_IS_VCS (vcs));
 
-  if (NULL != (node = ide_tree_get_selected (IDE_TREE (self))) &&
-      NULL != (item = ide_tree_node_get_item (node)) &&
-      GB_IS_PROJECT_FILE (item))
-    {
-      if (NULL != (file = gb_project_file_get_file (GB_PROJECT_FILE (item))))
-        g_object_ref (file);
-    }
-
-  ide_tree_rebuild (IDE_TREE (self));
-
-  if (file != NULL)
-    gb_project_tree_reveal (self, file, FALSE);
+  group = gtk_widget_get_action_group (GTK_WIDGET (self), "project-tree");
+  if (group != NULL)
+    g_action_group_activate_action (group, "refresh", NULL);
 }
 
 static void
@@ -179,7 +168,7 @@ gb_project_tree_buffer_saved_cb (GbProjectTree    *self,
       if (NULL == (node = ide_tree_find_custom (IDE_TREE (self), compare_to_file, gfile)))
         ide_tree_rebuild (IDE_TREE (self));
 
-      gb_project_tree_reveal (self, gfile, FALSE);
+      gb_project_tree_reveal (self, gfile, FALSE, FALSE);
     }
 }
 
@@ -423,18 +412,31 @@ find_files_node (IdeTree     *tree,
   return GB_IS_PROJECT_FILE (item);
 }
 
+/**
+ * gb_project_tree_reveal:
+ * @self: a #GbProjectTree
+ * @file: the #GFile to reveal
+ * @focus_tree_view: whether to focus the tree
+ * @expand_folder: whether the given file should be expanded (if it's a folder)
+ *
+ * Expand the tree so the node for the specified file is visible and selected.
+ * In the case that the file has been deleted, expand the tree as far as possible.
+ */
 void
 gb_project_tree_reveal (GbProjectTree *self,
                         GFile         *file,
-                        gboolean       focus_tree_view)
+                        gboolean       focus_tree_view,
+                        gboolean       expand_folder)
 {
   g_autofree gchar *relpath = NULL;
   g_auto(GStrv) parts = NULL;
   IdeContext *context;
-  IdeTreeNode *node;
+  IdeTreeNode *node = NULL;
+  IdeTreeNode *last_node = NULL;
   IdeVcs *vcs;
   GFile *workdir;
   guint i;
+  gboolean reveal_parent = FALSE;
 
   g_return_if_fail (GB_IS_PROJECT_TREE (self));
   g_return_if_fail (G_IS_FILE (file));
@@ -445,27 +447,52 @@ gb_project_tree_reveal (GbProjectTree *self,
   if (context == NULL)
     return;
 
-  vcs = ide_context_get_vcs (context);
-  workdir = ide_vcs_get_working_directory (vcs);
-  relpath = g_file_get_relative_path (workdir, file);
-
-  if (relpath == NULL)
-    return;
-
   node = ide_tree_find_child_node (IDE_TREE (self), NULL, find_files_node, NULL);
   if (node == NULL)
     return;
 
-  parts = g_strsplit (relpath, G_DIR_SEPARATOR_S, 0);
+  vcs = ide_context_get_vcs (context);
+  workdir = ide_vcs_get_working_directory (vcs);
 
-  for (i = 0; parts [i]; i++)
+  if (!g_file_equal (workdir, file))
     {
-      node = ide_tree_find_child_node (IDE_TREE (self), node, find_child_node, parts [i]);
-      if (node == NULL)
+      relpath = g_file_get_relative_path (workdir, file);
+
+      if (relpath == NULL)
         return;
+
+      parts = g_strsplit (relpath, G_DIR_SEPARATOR_S, 0);
+
+      last_node = node;
+      for (i = 0; parts [i]; i++)
+        {
+          node = ide_tree_find_child_node (IDE_TREE (self), node, find_child_node, parts [i]);
+          if (node == NULL)
+            {
+              if (last_node != NULL)
+                {
+                  node = last_node;
+                  reveal_parent = TRUE;
+                  break;
+                }
+              else
+                {
+                  return;
+                }
+            }
+          else
+            {
+              last_node = node;
+            }
+        }
     }
 
-  ide_tree_expand_to_node (IDE_TREE (self), node);
+  /* If the specified node wasn't found, still expand its ancestor */
+  if (expand_folder || reveal_parent)
+    ide_tree_node_expand (node, TRUE);
+  else
+    ide_tree_expand_to_node (IDE_TREE (self), node);
+
   ide_tree_scroll_to_node (IDE_TREE (self), node);
   ide_tree_node_select (node);
 
diff --git a/plugins/project-tree/gb-project-tree.h b/plugins/project-tree/gb-project-tree.h
index ae17520..a3979b9 100644
--- a/plugins/project-tree/gb-project-tree.h
+++ b/plugins/project-tree/gb-project-tree.h
@@ -36,7 +36,8 @@ void        gb_project_tree_set_show_ignored_files (GbProjectTree *self,
                                                     gboolean       show_ignored_files);
 void        gb_project_tree_reveal                 (GbProjectTree *self,
                                                     GFile         *file,
-                                                    gboolean       focus_tree_view);
+                                                    gboolean       focus_tree_view,
+                                                    gboolean       expand_folder);
 
 G_END_DECLS
 


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