[gnome-builder/wip/large-project] project-tree: stop using IdeProjectFiles for display tree



commit 05eca369b99e5e35d9318bf96d19ca8f0c55bfe4
Author: Christian Hergert <christian hergert me>
Date:   Sun Jun 14 20:14:56 2015 -0700

    project-tree: stop using IdeProjectFiles for display tree
    
    This is a step forward in the process of not knowing about all the project
    files in memory. More of our process to support larger projects such
    as WebKit, Mozilla, Chromium, Blender, XBMC, and such.
    
    Still two major things to cleanup here.
    
     1) Fix the post-creation work of new files/directories
     2) Stop loading project files on context load.

 src/project-tree/gb-project-tree-actions.c |  210 +++++++---------------
 src/project-tree/gb-project-tree-builder.c |  272 ++++++++++++++--------------
 src/project-tree/gb-project-tree.c         |   35 ++---
 src/workbench/gb-workbench.c               |    7 +-
 4 files changed, 212 insertions(+), 312 deletions(-)
---
diff --git a/src/project-tree/gb-project-tree-actions.c b/src/project-tree/gb-project-tree-actions.c
index ebda763..411b1a5 100644
--- a/src/project-tree/gb-project-tree-actions.c
+++ b/src/project-tree/gb-project-tree-actions.c
@@ -24,6 +24,7 @@
 
 #include "gb-file-manager.h"
 #include "gb-new-file-popover.h"
+#include "gb-project-file.h"
 #include "gb-project-tree.h"
 #include "gb-project-tree-actions.h"
 #include "gb-project-tree-private.h"
@@ -57,8 +58,8 @@ project_file_is_directory (GObject *object)
 {
   g_assert (!object || G_IS_OBJECT (object));
 
-  return (IDE_IS_PROJECT_FILE (object) &&
-          ide_project_file_get_is_directory (IDE_PROJECT_FILE (object)));
+  return (GB_IS_PROJECT_FILE (object) &&
+          gb_project_file_get_is_directory (GB_PROJECT_FILE (object)));
 }
 
 static void
@@ -127,19 +128,19 @@ gb_project_tree_actions_open (GSimpleAction *action,
 
   item = gb_tree_node_get_item (selected);
 
-  if (IDE_IS_PROJECT_FILE (item))
+  if (GB_IS_PROJECT_FILE (item))
     {
       GFileInfo *file_info;
       GFile *file;
 
-      file_info = ide_project_file_get_file_info (IDE_PROJECT_FILE (item));
+      file_info = gb_project_file_get_file_info (GB_PROJECT_FILE (item));
       if (!file_info)
         return;
 
       if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
         return;
 
-      file = ide_project_file_get_file (IDE_PROJECT_FILE (item));
+      file = gb_project_file_get_file (GB_PROJECT_FILE (item));
       if (!file)
         return;
 
@@ -170,10 +171,10 @@ gb_project_tree_actions_open_with (GSimpleAction *action,
   if (!(workbench = gb_widget_get_workbench (GTK_WIDGET (self))) ||
       !(selected = gb_tree_get_selected (GB_TREE (self))) ||
       !(item = gb_tree_node_get_item (selected)) ||
-      !IDE_IS_PROJECT_FILE (item) ||
+      !GB_IS_PROJECT_FILE (item) ||
       !(app_id = g_variant_get_string (variant, NULL)) ||
-      !(file_info = ide_project_file_get_file_info (IDE_PROJECT_FILE (item))) ||
-      !(file = ide_project_file_get_file (IDE_PROJECT_FILE (item))) ||
+      !(file_info = gb_project_file_get_file_info (GB_PROJECT_FILE (item))) ||
+      !(file = gb_project_file_get_file (GB_PROJECT_FILE (item))) ||
       !(app_info = g_desktop_app_info_new (app_id)))
     return;
 
@@ -201,10 +202,10 @@ gb_project_tree_actions_open_with_editor (GSimpleAction *action,
 
   if (!(selected = gb_tree_get_selected (GB_TREE (self))) ||
       !(item = gb_tree_node_get_item (selected)) ||
-      !IDE_IS_PROJECT_FILE (item) ||
-      !(file_info = ide_project_file_get_file_info (IDE_PROJECT_FILE (item))) ||
+      !GB_IS_PROJECT_FILE (item) ||
+      !(file_info = gb_project_file_get_file_info (GB_PROJECT_FILE (item))) ||
       (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) ||
-      !(file = ide_project_file_get_file (IDE_PROJECT_FILE (item))) ||
+      !(file = gb_project_file_get_file (GB_PROJECT_FILE (item))) ||
       !(workbench = gb_widget_get_workbench (GTK_WIDGET (self))))
     return;
 
@@ -225,22 +226,10 @@ gb_project_tree_actions_open_containing_folder (GSimpleAction *action,
 
   if (!(selected = gb_tree_get_selected (GB_TREE (self))) ||
       !(item = gb_tree_node_get_item (selected)) ||
-      !(IDE_IS_PROJECT_FILE (item) || IDE_IS_PROJECT_FILES (item)))
+      !GB_IS_PROJECT_FILE (item))
     return;
 
-  if (IDE_IS_PROJECT_FILES (item))
-    {
-      IdeContext *context;
-      IdeVcs *vcs;
-
-      context = ide_object_get_context (IDE_OBJECT (item));
-      vcs = ide_context_get_vcs (context);
-      file = ide_vcs_get_working_directory (vcs);
-    }
-  else if (!(file = ide_project_file_get_file (IDE_PROJECT_FILE (item))))
-    {
-      return;
-    }
+  file = gb_project_file_get_file (GB_PROJECT_FILE (item));
 
   gb_file_manager_show (file, NULL);
 }
@@ -303,24 +292,12 @@ gb_project_tree_actions_open_in_terminal (GSimpleAction *action,
 
   if (!(selected = gb_tree_get_selected (GB_TREE (self))) ||
       !(item = gb_tree_node_get_item (selected)) ||
-      !(IDE_IS_PROJECT_FILE (item) || IDE_IS_PROJECT_FILES (item)))
+      !GB_IS_PROJECT_FILE (item))
     return;
 
-  if (IDE_IS_PROJECT_FILES (item))
-    {
-      IdeContext *context;
-      IdeVcs *vcs;
-
-      context = ide_object_get_context (IDE_OBJECT (item));
-      vcs = ide_context_get_vcs (context);
-      file = ide_vcs_get_working_directory (vcs);
-    }
-  else if (!(file = ide_project_file_get_file (IDE_PROJECT_FILE (item))))
-    {
-      return;
-    }
+  file = gb_project_file_get_file (GB_PROJECT_FILE (item));
 
-  if (g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL) != G_FILE_TYPE_DIRECTORY)
+  if (!gb_project_file_get_is_directory (GB_PROJECT_FILE (item)))
     {
       g_autoptr(GFile) parent;
 
@@ -379,45 +356,12 @@ gb_project_tree_actions_show_icons (GSimpleAction *action,
   g_simple_action_set_state (action, variant);
 }
 
-static IdeProjectFile *
-create_file (IdeContext *context,
-             GFile      *file,
-             GFileType   file_type)
-{
-  g_autofree gchar *path = NULL;
-  g_autofree gchar *name = NULL;
-  g_autoptr(GFileInfo) file_info = NULL;
-  IdeVcs *vcs;
-  GFile *workdir;
-
-  g_assert (IDE_IS_CONTEXT (context));
-  g_assert (G_IS_FILE (file));
-  g_assert ((file_type == G_FILE_TYPE_DIRECTORY) || (file_type == G_FILE_TYPE_REGULAR));
-
-  vcs = ide_context_get_vcs (context);
-  workdir = ide_vcs_get_working_directory (vcs);
-  path = g_file_get_relative_path (workdir, file);
-  name = g_file_get_basename (file);
-
-  file_info = g_file_info_new ();
-  g_file_info_set_file_type (file_info, file_type);
-  g_file_info_set_name (file_info, name);
-  g_file_info_set_display_name (file_info, name);
-
-  return g_object_new (IDE_TYPE_PROJECT_FILE,
-                       "context", context,
-                       "file", file,
-                       "file-info", file_info,
-                       "path", path,
-                       "parent", NULL,
-                       NULL);
-}
-
 static void
 gb_project_tree_actions__make_directory_cb (GObject      *object,
                                             GAsyncResult *result,
                                             gpointer      user_data)
 {
+#if 0
   GFile *file = (GFile *)object;
   g_autoptr(GbTreeNode) node = user_data;
   g_autoptr(GError) error = NULL;
@@ -461,6 +405,7 @@ gb_project_tree_actions__make_directory_cb (GObject      *object,
 
   if (created != NULL)
     gb_tree_node_select (created);
+#endif
 }
 
 static void
@@ -468,6 +413,7 @@ gb_project_tree_actions__create_cb (GObject      *object,
                                     GAsyncResult *result,
                                     gpointer      user_data)
 {
+#if 0
   GFile *file = (GFile *)object;
   g_autoptr(IdeProjectFile) project_file = NULL;
   g_autoptr(GbTreeNode) node = user_data;
@@ -513,6 +459,11 @@ gb_project_tree_actions__create_cb (GObject      *object,
 
   if (created != NULL)
     gb_tree_node_select (created);
+#endif
+
+  /*
+   * TODO: Invalidate parent.
+   */
 }
 
 static void
@@ -584,7 +535,7 @@ gb_project_tree_actions_new (GbProjectTree *self,
   GbTreeNode *selected;
   GObject *item;
   GtkPopover *popover;
-  IdeProjectFile *project_file;
+  GbProjectFile *project_file;
   GFile *file = NULL;
   gboolean is_dir = FALSE;
 
@@ -595,36 +546,19 @@ gb_project_tree_actions_new (GbProjectTree *self,
 again:
   if (!(selected = gb_tree_get_selected (GB_TREE (self))) ||
       !(item = gb_tree_node_get_item (selected)) ||
-      !(IDE_IS_PROJECT_FILES (item) || IDE_IS_PROJECT_FILE (item)))
+      !GB_IS_PROJECT_FILE (item))
     return;
 
-  if (IDE_IS_PROJECT_FILE (item))
-    {
-      if (!(project_file = IDE_PROJECT_FILE (item)) ||
-          !(file = ide_project_file_get_file (project_file)))
-        return;
-      is_dir = project_file_is_directory (item);
-    }
-  else if (IDE_IS_PROJECT_FILES (item))
-    {
-      IdeContext *context;
-      IdeVcs *vcs;
+  if (!(project_file = GB_PROJECT_FILE (item)) ||
+      !(file = gb_project_file_get_file (project_file)))
+    return;
 
-      context = ide_object_get_context (IDE_OBJECT (item));
-      vcs = ide_context_get_vcs (context);
-      file = ide_vcs_get_working_directory (vcs);
-      is_dir = TRUE;
-    }
-  else
-    {
-      g_assert_not_reached ();
-      return;
-    }
+  is_dir = project_file_is_directory (item);
 
   g_assert (G_IS_FILE (file));
 
   /*
-   * If this item is an IdeProjectFile and not a directory, then we really
+   * If this item is an GbProjectFile and not a directory, then we really
    * want to create a sibling.
    */
   if (!is_dir)
@@ -686,26 +620,6 @@ gb_project_tree_actions_new_file (GSimpleAction *action,
   gb_project_tree_actions_new (self, G_FILE_TYPE_REGULAR);
 }
 
-static gint
-project_item_equal_func (GFile   *key,
-                         GObject *item)
-{
-  g_assert (G_IS_FILE (key));
-  g_assert (IDE_IS_PROJECT_ITEM (item));
-
-  if (IDE_IS_PROJECT_FILE (item))
-    {
-      GFile *file;
-
-      file = ide_project_file_get_file (IDE_PROJECT_FILE (item));
-      g_assert (G_IS_FILE (file));
-
-      return g_file_equal (key, file);
-    }
-
-  return FALSE;
-}
-
 static void
 gb_project_tree_actions__project_rename_file_cb (GObject      *object,
                                                  GAsyncResult *result,
@@ -715,9 +629,9 @@ gb_project_tree_actions__project_rename_file_cb (GObject      *object,
   g_autoptr(GbRenameFilePopover) popover = user_data;
   g_autoptr(GError) error = NULL;
   GbTreeNode *node;
+  GbTreeNode *parent;
   GFile *file;
   GbTree *tree;
-  gboolean expanded = FALSE;
 
   g_assert (IDE_IS_PROJECT (project));
   g_assert (GB_IS_RENAME_FILE_POPOVER (popover));
@@ -735,23 +649,15 @@ gb_project_tree_actions__project_rename_file_cb (GObject      *object,
   g_assert (G_IS_FILE (file));
   g_assert (GB_IS_TREE (tree));
 
-  if ((node = gb_tree_get_selected (tree)))
-    expanded = gb_tree_node_get_expanded (node);
+  node = gb_tree_get_selected (tree);
+  parent = gb_tree_node_get_parent (node);
 
-  gb_tree_rebuild (tree);
+  gb_tree_node_invalidate (parent);
+  gb_tree_node_expand (parent, TRUE);
 
-  node = gb_tree_find_custom (tree,
-                              (GEqualFunc)project_item_equal_func,
-                              file);
-
-  if (node != NULL)
-    {
-      gb_tree_node_expand (node, TRUE);
-      if (!expanded)
-        gb_tree_node_collapse (node);
-      gb_tree_node_select (node);
-      gb_tree_scroll_to_node (tree, node);
-    }
+  /*
+   * TODO: Reselect child node.
+   */
 
   gtk_widget_hide (GTK_WIDGET (popover));
   gtk_widget_destroy (GTK_WIDGET (popover));
@@ -776,7 +682,7 @@ gb_project_tree_actions__rename_file_cb (GbProjectTree       *self,
   context = gb_workbench_get_context (workbench);
   project = ide_context_get_project (context);
 
-  /* todo: set busin spinner in popover */
+  /* todo: set busy spinner in popover */
 
   g_object_set_data_full (G_OBJECT (popover),
                           "G_FILE",
@@ -805,9 +711,9 @@ gb_project_tree_actions_rename_file (GSimpleAction *action,
 
   if (!(selected = gb_tree_get_selected (GB_TREE (self))) ||
       !(item = gb_tree_node_get_item (selected)) ||
-      !IDE_IS_PROJECT_FILE (item) ||
-      !(file = ide_project_file_get_file (IDE_PROJECT_FILE (item))) ||
-      !(file_info = ide_project_file_get_file_info (IDE_PROJECT_FILE (item))))
+      !GB_IS_PROJECT_FILE (item) ||
+      !(file = gb_project_file_get_file (GB_PROJECT_FILE (item))) ||
+      !(file_info = gb_project_file_get_file_info (GB_PROJECT_FILE (item))))
     return;
 
   is_dir = (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY);
@@ -923,7 +829,7 @@ gb_project_tree_actions_move_to_trash (GSimpleAction *action,
   if (!(node = gb_tree_get_selected (GB_TREE (self))) ||
       !(item = gb_tree_node_get_item (node)) ||
       !IDE_IS_PROJECT_FILE (item) ||
-      !(file = ide_project_file_get_file (IDE_PROJECT_FILE (item))))
+      !(file = gb_project_file_get_file (GB_PROJECT_FILE (item))))
     return;
 
   /*
@@ -965,6 +871,16 @@ gb_project_tree_actions_move_to_trash (GSimpleAction *action,
                                 g_object_ref (self));
 }
 
+static gboolean
+is_files_node (GbTreeNode *node)
+{
+  GObject *item = gb_tree_node_get_item (node);
+  GbTreeNode *parent = gb_tree_node_get_parent (node);
+  GObject *parent_item = gb_tree_node_get_item (parent);
+
+  return (GB_IS_PROJECT_FILE (item) && !GB_IS_PROJECT_FILE (parent_item));
+}
+
 static GActionEntry GbProjectTreeActions[] = {
   { "collapse-all-nodes",     gb_project_tree_actions_collapse_all_nodes },
   { "move-to-trash",          gb_project_tree_actions_move_to_trash },
@@ -1031,28 +947,28 @@ gb_project_tree_actions_update (GbProjectTree *self)
     item = gb_tree_node_get_item (selection);
 
   action_set (group, "new-file",
-              "enabled", (IDE_IS_PROJECT_FILE (item) || IDE_IS_PROJECT_FILES (item)),
+              "enabled", GB_IS_PROJECT_FILE (item),
               NULL);
   action_set (group, "new-directory",
-              "enabled", (IDE_IS_PROJECT_FILE (item) || IDE_IS_PROJECT_FILES (item)),
+              "enabled", GB_IS_PROJECT_FILE (item),
               NULL);
   action_set (group, "open",
-              "enabled", (IDE_IS_PROJECT_FILE (item) && !project_file_is_directory (item)),
+              "enabled", (GB_IS_PROJECT_FILE (item) && !project_file_is_directory (item)),
               NULL);
   action_set (group, "open-with-editor",
-              "enabled", (IDE_IS_PROJECT_FILE (item) && !project_file_is_directory (item)),
+              "enabled", (GB_IS_PROJECT_FILE (item) && !project_file_is_directory (item)),
               NULL);
   action_set (group, "open-containing-folder",
-              "enabled", (IDE_IS_PROJECT_FILE (item) || IDE_IS_PROJECT_FILES (item)),
+              "enabled", GB_IS_PROJECT_FILE (item),
               NULL);
   action_set (group, "open-in-terminal",
-              "enabled", IDE_IS_PROJECT_FILE (item),
+              "enabled", GB_IS_PROJECT_FILE (item),
               NULL);
   action_set (group, "rename-file",
-              "enabled", IDE_IS_PROJECT_FILE (item),
+              "enabled", (GB_IS_PROJECT_FILE (item) && !is_files_node (selection)),
               NULL);
   action_set (group, "move-to-trash",
-              "enabled", (IDE_IS_PROJECT_FILE (item) && !project_file_is_directory (item)),
+              "enabled", (GB_IS_PROJECT_FILE (item) && !is_files_node (selection)),
               NULL);
 
   IDE_EXIT;
diff --git a/src/project-tree/gb-project-tree-builder.c b/src/project-tree/gb-project-tree-builder.c
index 54fd7e3..c6c1430 100644
--- a/src/project-tree/gb-project-tree-builder.c
+++ b/src/project-tree/gb-project-tree-builder.c
@@ -19,6 +19,7 @@
 #include <glib/gi18n.h>
 
 #include "gb-project-tree-builder.h"
+#include "gb-project-file.h"
 #include "gb-tree.h"
 #include "gb-widget.h"
 #include "gb-workbench.h"
@@ -40,154 +41,142 @@ gb_project_tree_builder_new (void)
   return g_object_new (GB_TYPE_PROJECT_TREE_BUILDER, NULL);
 }
 
-static const gchar *
-get_icon_name (GFileInfo *file_info)
-{
-  GFileType file_type;
-
-  g_return_val_if_fail (G_IS_FILE_INFO (file_info), NULL);
-
-  file_type = g_file_info_get_file_type (file_info);
-
-  if (file_type == G_FILE_TYPE_DIRECTORY)
-    return "folder-symbolic";
-
-  return "text-x-generic-symbolic";
-}
-
 static void
-build_project (GbProjectTreeBuilder *self,
+build_context (GbProjectTreeBuilder *self,
                GbTreeNode           *node)
 {
-  IdeProjectItem *root;
-  GSequenceIter *iter;
-  IdeProject *project;
-  GSequence *children;
+  g_autoptr(GbProjectFile) item = NULL;
+  g_autoptr(GFileInfo) file_info = NULL;
+  g_autofree gchar *name = NULL;
+  GbTreeNode *child;
+  IdeContext *context;
+  IdeVcs *vcs;
+  GFile *workdir;
 
   g_return_if_fail (GB_IS_PROJECT_TREE_BUILDER (self));
   g_return_if_fail (GB_IS_TREE_NODE (node));
 
-  project = IDE_PROJECT (gb_tree_node_get_item (node));
+  context = IDE_CONTEXT (gb_tree_node_get_item (node));
+  vcs = ide_context_get_vcs (context);
+  workdir = ide_vcs_get_working_directory (vcs);
 
-  ide_project_reader_lock (project);
+  file_info = g_file_info_new ();
 
-  root = ide_project_get_root (project);
-  children = ide_project_item_get_children (root);
+  g_file_info_set_file_type (file_info, G_FILE_TYPE_DIRECTORY);
 
-  if (children)
-    {
-      for (iter = g_sequence_get_begin_iter (children);
-           !g_sequence_iter_is_end (iter);
-           iter = g_sequence_iter_next (iter))
-        {
-          IdeProjectItem *item = g_sequence_get (iter);
-
-          if (IDE_IS_PROJECT_FILES (item))
-            {
-              GbTreeNode *child;
-
-              child = g_object_new (GB_TYPE_TREE_NODE,
-                                    "icon-name", "folder-symbolic",
-                                    "item", item,
-                                    "text", _("Files"),
-                                    NULL);
-              gb_tree_node_append (node, child);
-              break;
-            }
-        }
-    }
+  name = g_file_get_basename (workdir);
+  g_file_info_set_name (file_info, name);
+  g_file_info_set_display_name (file_info, name);
 
-  ide_project_reader_unlock (project);
+  item = g_object_new (GB_TYPE_PROJECT_FILE,
+                       "file", workdir,
+                       "file-info", file_info,
+                       NULL);
+
+  child = g_object_new (GB_TYPE_TREE_NODE,
+                        "item", item,
+                        "text", _("Files"),
+                        "icon-name", "folder-symbolic",
+                        NULL);
+  gb_tree_node_append (node, child);
 }
 
-static gint
-sort_files (IdeProjectItem *item_a,
-            IdeProjectItem *item_b,
-            gpointer        directories_first)
+static IdeVcs *
+get_vcs (GbTreeNode *node)
 {
-  GFileInfo *file_info_a;
-  GFileInfo *file_info_b;
-  const gchar *display_name_a;
-  const gchar *display_name_b;
-  g_autofree gchar *casefold_a = NULL;
-  g_autofree gchar *casefold_b = NULL;
-
-  file_info_a = ide_project_file_get_file_info (IDE_PROJECT_FILE (item_a));
-  file_info_b = ide_project_file_get_file_info (IDE_PROJECT_FILE (item_b));
+  GbTree *tree;
+  GbTreeNode *root;
+  IdeContext *context;
 
-  if (directories_first)
-    {
-      GFileType file_type_a;
-      GFileType file_type_b;
-
-      file_type_a = g_file_info_get_file_type (file_info_a);
-      file_type_b = g_file_info_get_file_type (file_info_b);
-
-      if (file_type_a != file_type_b &&
-          (file_type_a == G_FILE_TYPE_DIRECTORY ||
-           file_type_b == G_FILE_TYPE_DIRECTORY))
-        {
-          return file_type_a == G_FILE_TYPE_DIRECTORY ? -1 : +1;
-        }
-    }
+  g_assert (GB_IS_TREE_NODE (node));
 
-  display_name_a = g_file_info_get_display_name (file_info_a);
-  display_name_b = g_file_info_get_display_name (file_info_b);
+  tree = gb_tree_node_get_tree (node);
+  root = gb_tree_get_root (tree);
+  context = IDE_CONTEXT (gb_tree_node_get_item (root));
 
-  casefold_a = g_utf8_collate_key_for_filename (display_name_a, -1);
-  casefold_b = g_utf8_collate_key_for_filename (display_name_b, -1);
+  return ide_context_get_vcs (context);
+}
 
-  return g_utf8_collate (casefold_a, casefold_b);
+static gint
+compare_nodes_func (GbTreeNode *a,
+                    GbTreeNode *b,
+                    gpointer    user_data)
+{
+  GbProjectFile *file_a = GB_PROJECT_FILE (gb_tree_node_get_item (a));
+  GbProjectFile *file_b = GB_PROJECT_FILE (gb_tree_node_get_item (b));
+  GbProjectTreeBuilder *self = user_data;
+
+  if (self->sort_directories_first)
+    return gb_project_file_compare_directories_first (file_a, file_b);
+  else
+    return gb_project_file_compare (file_a, file_b);
 }
 
 static void
-build_files (GbProjectTreeBuilder *self,
-             GbTreeNode           *node)
+build_file (GbProjectTreeBuilder *self,
+            GbTreeNode           *node)
 {
-  IdeProjectItem *files;
-  GSequenceIter *iter;
-  GSequence *children;
-  gboolean directories_first;
+  g_autoptr(GFileEnumerator) enumerator = NULL;
+  GbProjectFile *project_file;
+  gpointer file_info_ptr;
+  IdeVcs *vcs;
+  GFile *file;
 
   g_return_if_fail (GB_IS_PROJECT_TREE_BUILDER (self));
   g_return_if_fail (GB_IS_TREE_NODE (node));
 
-  files = IDE_PROJECT_ITEM (gb_tree_node_get_item (node));
-  children = ide_project_item_get_children (files);
+  project_file = GB_PROJECT_FILE (gb_tree_node_get_item (node));
 
-  if (children)
+  vcs = get_vcs (node);
+
+  /*
+   * TODO: Make this all async.
+   */
+
+  if (!gb_project_file_get_is_directory (project_file))
+    return;
+
+  file = gb_project_file_get_file (project_file);
+
+  enumerator = g_file_enumerate_children (file,
+                                          G_FILE_ATTRIBUTE_STANDARD_NAME","
+                                          G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","
+                                          G_FILE_ATTRIBUTE_STANDARD_TYPE,
+                                          G_FILE_QUERY_INFO_NONE,
+                                          NULL,
+                                          NULL);
+
+  if (enumerator == NULL)
+    return;
+
+  while ((file_info_ptr = g_file_enumerator_next_file (enumerator, NULL, NULL)))
     {
-      directories_first = g_settings_get_boolean (self->file_chooser_settings,
-                                                  "sort-directories-first");
-      g_sequence_sort (children,
-                       (GCompareDataFunc) sort_files,
-                       GINT_TO_POINTER (directories_first));
-
-      for (iter = g_sequence_get_begin_iter (children);
-           !g_sequence_iter_is_end (iter);
-           iter = g_sequence_iter_next (iter))
-        {
-          IdeProjectItem *item = g_sequence_get (iter);
-          const gchar *display_name;
-          const gchar *icon_name;
-          GbTreeNode *child;
-          GFileInfo *file_info;
-
-          if (!IDE_IS_PROJECT_FILE (item))
-            continue;
-
-          file_info = ide_project_file_get_file_info (IDE_PROJECT_FILE (item));
-
-          display_name = g_file_info_get_display_name (file_info);
-          icon_name = get_icon_name (file_info);
-
-          child = g_object_new (GB_TYPE_TREE_NODE,
-                                "text", display_name,
-                                "icon-name", icon_name,
-                                "item", item,
-                                NULL);
-          gb_tree_node_append (node, child);
-        }
+      g_autoptr(GFileInfo) item_file_info = file_info_ptr;
+      g_autoptr(GFile) item_file = NULL;
+      g_autoptr(GbProjectFile) item = NULL;
+      GbTreeNode *child;
+      const gchar *name;
+      const gchar *display_name;
+      const gchar *icon_name;
+
+      name = g_file_info_get_name (item_file_info);
+      item_file = g_file_get_child (file, name);
+
+      if (ide_vcs_is_ignored (vcs, item_file, NULL))
+        continue;
+
+      item = gb_project_file_new (item_file, item_file_info);
+
+      display_name = gb_project_file_get_display_name (item);
+      icon_name = gb_project_file_get_icon_name (item);
+
+      child = g_object_new (GB_TYPE_TREE_NODE,
+                            "icon-name", icon_name,
+                            "text", display_name,
+                            "item", item,
+                            NULL);
+
+      gb_tree_node_insert_sorted (node, child, compare_nodes_func, self);
     }
 }
 
@@ -202,10 +191,10 @@ gb_project_tree_builder_build_node (GbTreeBuilder *builder,
 
   item = gb_tree_node_get_item (node);
 
-  if (IDE_IS_PROJECT (item))
-    build_project (self, node);
-  else if (IDE_IS_PROJECT_FILES (item) || IDE_IS_PROJECT_FILE (item))
-    build_files (self, node);
+  if (IDE_IS_CONTEXT (item))
+    build_context (self, node);
+  else if (GB_IS_PROJECT_FILE (item))
+    build_file (self, node);
 }
 
 static gchar *
@@ -221,8 +210,8 @@ get_content_type (GFile *file)
 }
 
 static void
-populate_mime_handlers (GMenu          *menu,
-                        IdeProjectFile *project_file)
+populate_mime_handlers (GMenu         *menu,
+                        GbProjectFile *project_file)
 {
   g_autofree gchar *content_type = NULL;
   GList *list;
@@ -230,11 +219,11 @@ populate_mime_handlers (GMenu          *menu,
   GFile *file;
 
   g_assert (G_IS_MENU (menu));
-  g_assert (IDE_IS_PROJECT_FILE (project_file));
+  g_assert (GB_IS_PROJECT_FILE (project_file));
 
   g_menu_remove_all (menu);
 
-  file = ide_project_file_get_file (project_file);
+  file = gb_project_file_get_file (project_file);
   if (file == NULL)
     return;
 
@@ -272,6 +261,9 @@ gb_project_tree_builder_node_popup (GbTreeBuilder *builder,
   GtkApplication *app;
   GObject *item;
   GMenu *submenu;
+  IdeVcs *vcs;
+  GFile *workdir;
+  GFile *file;
 
   g_assert (GB_IS_PROJECT_TREE_BUILDER (builder));
   g_assert (GB_IS_TREE_NODE (node));
@@ -280,13 +272,18 @@ gb_project_tree_builder_node_popup (GbTreeBuilder *builder,
   app = GTK_APPLICATION (g_application_get_default ());
   item = gb_tree_node_get_item (node);
 
-  if (IDE_IS_PROJECT_ITEM (item) || IDE_IS_PROJECT (item))
+  if (GB_IS_PROJECT_FILE (item))
     {
       submenu = gtk_application_get_menu_by_id (app, "gb-project-tree-build");
       g_menu_prepend_section (menu, NULL, G_MENU_MODEL (submenu));
     }
 
-  if (IDE_IS_PROJECT_FILE (item))
+  vcs = get_vcs (node);
+  workdir = ide_vcs_get_working_directory (vcs);
+
+  if (GB_IS_PROJECT_FILE (item) &&
+      (file = gb_project_file_get_file (GB_PROJECT_FILE (item))) &&
+      !g_file_equal (file, workdir))
     {
       submenu = gtk_application_get_menu_by_id (app, "gb-project-tree-move-to-trash");
       g_menu_prepend_section (menu, NULL, G_MENU_MODEL (submenu));
@@ -301,12 +298,12 @@ gb_project_tree_builder_node_popup (GbTreeBuilder *builder,
       g_menu_prepend_section (menu, NULL, G_MENU_MODEL (submenu));
 
       submenu = gtk_application_get_menu_by_id (app, "gb-project-tree-open-by-mime-section");
-      populate_mime_handlers (submenu, IDE_PROJECT_FILE (item));
+      populate_mime_handlers (submenu, GB_PROJECT_FILE (item));
 
       submenu = gtk_application_get_menu_by_id (app, "gb-project-tree-new");
       g_menu_prepend_section (menu, NULL, G_MENU_MODEL (submenu));
     }
-  else if (IDE_IS_PROJECT_FILES (item))
+  else if (GB_IS_PROJECT_FILE (item))
     {
       submenu = gtk_application_get_menu_by_id (app, "gb-project-tree-open-containing");
       g_menu_prepend_section (menu, NULL, G_MENU_MODEL (submenu));
@@ -329,21 +326,16 @@ gb_project_tree_builder_node_activated (GbTreeBuilder *builder,
 
   item = gb_tree_node_get_item (node);
 
-  if (IDE_IS_PROJECT_FILE (item))
+  if (GB_IS_PROJECT_FILE (item))
     {
       GbWorkbench *workbench;
-      GFileInfo *file_info;
       GbTree *tree;
       GFile *file;
 
-      file_info = ide_project_file_get_file_info (IDE_PROJECT_FILE (item));
-      if (!file_info)
-        goto failure;
-
-      if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
+      if (gb_project_file_get_is_directory (GB_PROJECT_FILE (item)))
         goto failure;
 
-      file = ide_project_file_get_file (IDE_PROJECT_FILE (item));
+      file = gb_project_file_get_file (GB_PROJECT_FILE (item));
       if (!file)
         goto failure;
 
diff --git a/src/project-tree/gb-project-tree.c b/src/project-tree/gb-project-tree.c
index b82d062..84529a5 100644
--- a/src/project-tree/gb-project-tree.c
+++ b/src/project-tree/gb-project-tree.c
@@ -71,37 +71,30 @@ void
 gb_project_tree_set_context (GbProjectTree *self,
                              IdeContext    *context)
 {
-  GbTreeNode *root;
-  IdeProject *project = NULL;
   GtkTreeModel *model;
+  GtkTreeIter iter;
+  GbTreeNode *root;
 
   g_return_if_fail (GB_IS_PROJECT_TREE (self));
   g_return_if_fail (!context || IDE_IS_CONTEXT (context));
 
-  if (context != NULL)
-    project = ide_context_get_project (context);
-
-  root = gb_tree_get_root (GB_TREE (self));
-  gb_tree_node_set_item (root, G_OBJECT (project));
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
 
-  gb_tree_rebuild (GB_TREE (self));
+  root = gb_tree_node_new ();
+  gb_tree_node_set_item (root, G_OBJECT (context));
+  gb_tree_set_root (GB_TREE (self), root);
 
   /*
-   * If we only have one item at the root of the tree, expand it.
+   * If we only have one toplevel item (underneath root), expand it.
    */
-  if ((model = gtk_tree_view_get_model (GTK_TREE_VIEW (self))))
+  if ((gtk_tree_model_iter_n_children (model, NULL) == 1) &&
+      gtk_tree_model_get_iter_first (model, &iter))
     {
-      GtkTreeIter iter;
+      g_autoptr(GbTreeNode) node = NULL;
 
-      if ((gtk_tree_model_iter_n_children (model, NULL) == 1) &&
-          gtk_tree_model_get_iter_first (model, &iter))
-        {
-          g_autoptr(GbTreeNode) node = NULL;
-
-          gtk_tree_model_get (model, &iter, 0, &node, -1);
-          if (node != NULL)
-            gb_tree_node_expand (node, FALSE);
-        }
+      gtk_tree_model_get (model, &iter, 0, &node, -1);
+      if (node != NULL)
+        gb_tree_node_expand (node, FALSE);
     }
 }
 
@@ -137,8 +130,6 @@ gb_project_tree_init (GbProjectTree *self)
 {
   GbTreeBuilder *builder;
 
-  gb_tree_set_root (GB_TREE (self), gb_tree_node_new ());
-
   self->settings = g_settings_new ("org.gnome.builder.project-tree");
   g_settings_bind (self->settings, "show-icons", self, "show-icons",
                    G_SETTINGS_BIND_DEFAULT);
diff --git a/src/workbench/gb-workbench.c b/src/workbench/gb-workbench.c
index 243f3ec..6e75c8a 100644
--- a/src/workbench/gb-workbench.c
+++ b/src/workbench/gb-workbench.c
@@ -31,6 +31,7 @@
 #include "gb-workbench-addin.h"
 #include "gb-workspace.h"
 #include "gb-workspace-pane.h"
+#include "gb-project-file.h"
 #include "gb-project-tree.h"
 #include "gb-view-grid.h"
 
@@ -996,7 +997,7 @@ find_files_node (GbTree     *tree,
 
   item = gb_tree_node_get_item (child);
 
-  return IDE_IS_PROJECT_FILES (item);
+  return GB_IS_PROJECT_FILE (item);
 }
 
 static gboolean
@@ -1014,11 +1015,11 @@ find_child_node (GbTree     *tree,
 
   item = gb_tree_node_get_item (child);
 
-  if (IDE_IS_PROJECT_FILE (item))
+  if (GB_IS_PROJECT_FILE (item))
     {
       const gchar *item_name;
 
-      item_name = ide_project_file_get_name (IDE_PROJECT_FILE (item));
+      item_name = gb_project_file_get_display_name (GB_PROJECT_FILE (item));
       return ide_str_equal0 (item_name, name);
     }
 


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