static void
gb_project_tree_actions_refresh (GSimpleAction *action,
                                 GVariant      *variant,
                                 gpointer       user_data)
{
  GbProjectTree *self = user_data;
  GbTreeNode *selected;
  GObject *item = NULL;

  g_assert (GB_IS_PROJECT_TREE (self));

  if ((selected = gb_tree_get_selected (GB_TREE (self))))
    {
      item = gb_tree_node_get_item (selected);
      if (item != NULL)
        g_object_ref (item);
    }

  gb_tree_rebuild (GB_TREE (self));

  if (item != NULL)
    {
      selected = gb_tree_find_item (GB_TREE (self), item);
      if (selected != NULL)
        {
          gb_tree_node_expand (selected, TRUE);
          gb_tree_node_select (selected);
          gb_tree_scroll_to_node (GB_TREE (self), selected);
        }
      g_object_unref (item);
    }
}
static void
gb_project_tree_actions__trash_file_cb (GObject      *object,
                                        GAsyncResult *result,
                                        gpointer      user_data)
{
  IdeProject *project = (IdeProject *)object;
  g_autoptr(GbProjectTree) self = user_data;
  g_autoptr(GError) error = NULL;
  GbTreeNode *node;
  GObject *item = NULL;

  g_assert (IDE_IS_PROJECT (project));
  g_assert (GB_IS_PROJECT_TREE (self));

  if (!ide_project_trash_file_finish (project, result, &error))
    {
      /* todo: warning dialog */
      g_warning ("%s", error->message);
      return;
    }

  /* todo: this should be done with tree observer */
  if ((node = gb_tree_get_selected (GB_TREE (self))))
    {
      if ((node = gb_tree_node_get_parent (node)))
        item = gb_tree_node_get_item (node);
    }

  gb_tree_rebuild (GB_TREE (self));

  if ((node = gb_tree_find_item (GB_TREE (self), item)))
    gb_tree_node_expand (node, TRUE);
}
void
gb_project_tree_set_context (GbProjectTree *self,
                             IdeContext    *context)
{
  GtkTreeModel *model;
  GtkTreeIter iter;
  GbTreeNode *root;

  g_return_if_fail (GB_IS_PROJECT_TREE (self));
  g_return_if_fail (!context || IDE_IS_CONTEXT (context));

  model = gtk_tree_view_get_model (GTK_TREE_VIEW (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 toplevel item (underneath root), expand it.
   */
  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);
    }
}
static void
gb_project_tree_actions_open_containing_folder (GSimpleAction *action,
                                                GVariant      *variant,
                                                gpointer       user_data)
{
  GbEditorWorkspace *self = user_data;
  GbTreeNode *selected;
  GObject *item;
  GFile *file;

  g_assert (GB_IS_PROJECT_TREE (self));

  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)))
    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;
    }

  gb_file_manager_show (file, NULL);
}
static void
gb_project_tree_actions_open_with_editor (GSimpleAction *action,
                                          GVariant      *variant,
                                          gpointer       user_data)
{
  GbWorkbench *workbench;
  GbProjectTree *self = user_data;
  GFileInfo *file_info;
  GFile *file;
  GbTreeNode *selected;
  GObject *item;

  g_assert (GB_IS_PROJECT_TREE (self));

  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))) ||
      (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) ||
      !(file = ide_project_file_get_file (IDE_PROJECT_FILE (item))) ||
      !(workbench = gb_widget_get_workbench (GTK_WIDGET (self))))
    return;

  gb_workbench_open_with_editor (workbench, file);
}
static void
gb_project_tree_actions_move_to_trash (GSimpleAction *action,
                                       GVariant      *param,
                                       gpointer       user_data)
{
  GbProjectTree *self = user_data;
  GbWorkbench *workbench;
  IdeContext *context;
  IdeProject *project;
  GbTreeNode *node;
  GFile *file;
  GObject *item;

  g_assert (G_IS_SIMPLE_ACTION (action));
  g_assert (GB_IS_PROJECT_TREE (self));

  workbench = gb_widget_get_workbench (GTK_WIDGET (self));
  context = gb_workbench_get_context (workbench);
  project = ide_context_get_project (context);

  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))))
    return;

  ide_project_trash_file_async (project,
                                file,
                                NULL,
                                gb_project_tree_actions__trash_file_cb,
                                g_object_ref (self));
}
示例#7
0
static void
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);

  builder = gb_project_tree_builder_new ();
  gb_tree_add_builder (GB_TREE (self), builder);

  g_signal_connect (self,
                    "notify::selection",
                    G_CALLBACK (gb_project_tree_notify_selection),
                    NULL);

  gb_project_tree_actions_init (self);
}
static void
gb_project_tree_actions__create_cb (GObject      *object,
                                    GAsyncResult *result,
                                    gpointer      user_data)
{
  GFile *file = (GFile *)object;
  g_autoptr(IdeProjectFile) project_file = NULL;
  g_autoptr(GbTreeNode) node = user_data;
  g_autoptr(GError) error = NULL;
  GbProjectTree *self;
  GbWorkbench *workbench;
  IdeContext *context;
  IdeProject *project;
  GbTreeNode *created;

  g_assert (G_IS_FILE (file));
  g_assert (GB_IS_TREE_NODE (node));

  if (!g_file_create_finish (file, result, &error))
    {
      /* todo: show error messsage */
      return;
    }

  self = GB_PROJECT_TREE (gb_tree_node_get_tree (node));
  if (self == NULL)
    return;

  workbench = gb_widget_get_workbench (GTK_WIDGET (self));
  if (workbench == NULL)
    return;

  context = gb_workbench_get_context (workbench);
  if (context == NULL)
    return;

  project = ide_context_get_project (context);

  project_file = create_file (context, file, G_FILE_TYPE_REGULAR);
  ide_project_add_file (project, project_file);

  gb_workbench_open (workbench, file);

  gb_tree_node_rebuild (node);
  gb_tree_node_expand (node, FALSE);

  created = gb_tree_find_item (GB_TREE (self), G_OBJECT (project_file));

  if (created != NULL)
    gb_tree_node_select (created);
}
static void
gb_project_tree_actions__popover_closed_cb (GbProjectTree *self,
                                            GtkPopover    *popover)
{
  GbTreeNode *selected;

  g_assert (GB_IS_PROJECT_TREE (self));
  g_assert (GTK_IS_POPOVER (popover));

  if (!(selected = gb_tree_get_selected (GB_TREE (self))) || !self->expanded_in_new)
    return;

  gb_tree_node_collapse (selected);
}
static void
gb_project_tree_actions__project_rename_file_cb (GObject      *object,
                                                 GAsyncResult *result,
                                                 gpointer      user_data)
{
  IdeProject *project = (IdeProject *)object;
  g_autoptr(GbRenameFilePopover) popover = user_data;
  g_autoptr(GError) error = NULL;
  GbTreeNode *node;
  GFile *file;
  GbTree *tree;
  gboolean expanded = FALSE;

  g_assert (IDE_IS_PROJECT (project));
  g_assert (GB_IS_RENAME_FILE_POPOVER (popover));

  if (!ide_project_rename_file_finish (project, result, &error))
    {
      /* todo: display error */
      g_warning ("%s", error->message);
      return;
    }

  file = g_object_get_data (G_OBJECT (popover), "G_FILE");
  tree = GB_TREE (gtk_popover_get_relative_to (GTK_POPOVER (popover)));

  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);

  gb_tree_rebuild (tree);

  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);
    }

  gtk_widget_hide (GTK_WIDGET (popover));
  gtk_widget_destroy (GTK_WIDGET (popover));
}
示例#11
0
void
gb_project_tree_set_context (GbProjectTree *self,
                             IdeContext    *context)
{
  GbTreeNode *root;
  IdeProject *project = NULL;
  GtkTreeModel *model;

  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));

  gb_tree_rebuild (GB_TREE (self));

  /*
   * If we only have one item at the root of the tree, expand it.
   */
  if ((model = gtk_tree_view_get_model (GTK_TREE_VIEW (self))))
    {
      GtkTreeIter iter;

      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);
        }
    }
}
static void
gb_project_tree_actions_show_icons (GSimpleAction *action,
                                    GVariant      *variant,
                                    gpointer       user_data)
{
  GbProjectTree *self = user_data;
  gboolean show_icons;

  g_assert (GB_IS_PROJECT_TREE (self));
  g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN));

  show_icons = g_variant_get_boolean (variant);
  gb_tree_set_show_icons (GB_TREE (self), show_icons);
  g_simple_action_set_state (action, variant);
}
示例#13
0
IdeContext *
gb_project_tree_get_context (GbProjectTree *self)
{
  GbTreeNode *root;
  GObject *item;

  g_return_val_if_fail (GB_IS_PROJECT_TREE (self), NULL);

  if ((root = gb_tree_get_root (GB_TREE (self))) &&
      (item = gb_tree_node_get_item (root)) &&
      IDE_IS_OBJECT (item))
    return ide_object_get_context (IDE_OBJECT (item));

  return NULL;
}
void
gb_project_tree_set_show_ignored_files (GbProjectTree *self,
                                        gboolean       show_ignored_files)
{
  g_return_if_fail (GB_IS_PROJECT_TREE (self));

  show_ignored_files = !!show_ignored_files;

  if (show_ignored_files != self->show_ignored_files)
    {
      self->show_ignored_files = show_ignored_files;
      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SHOW_IGNORED_FILES]);
      gb_tree_rebuild (GB_TREE (self));
    }
}
static void
gb_project_tree_actions__popover_create_file_cb (GbProjectTree    *self,
                                                 GFile            *file,
                                                 GFileType         file_type,
                                                 GbNewFilePopover *popover)
{
  GbTreeNode *selected;

  g_assert (GB_IS_PROJECT_TREE (self));
  g_assert (G_IS_FILE (file));
  g_assert ((file_type == G_FILE_TYPE_DIRECTORY) ||
            (file_type == G_FILE_TYPE_REGULAR));
  g_assert (GB_IS_NEW_FILE_POPOVER (popover));

  selected = gb_tree_get_selected (GB_TREE (self));

  g_assert (selected != NULL);
  g_assert (GB_IS_TREE_NODE (selected));

  if (file_type == G_FILE_TYPE_DIRECTORY)
    {
      g_file_make_directory_async (file,
                                   G_PRIORITY_DEFAULT,
                                   NULL, /* cancellable */
                                   gb_project_tree_actions__make_directory_cb,
                                   g_object_ref (selected));
    }
  else if (file_type == G_FILE_TYPE_REGULAR)
    {
      g_file_create_async (file,
                           G_FILE_CREATE_NONE,
                           G_PRIORITY_DEFAULT,
                           NULL, /* cancellable */
                           gb_project_tree_actions__create_cb,
                           g_object_ref (selected));
    }
  else
    {
      g_assert_not_reached ();
    }

  self->expanded_in_new = FALSE;

  gtk_widget_hide (GTK_WIDGET (popover));
  gtk_widget_destroy (GTK_WIDGET (popover));
}
void
gb_project_tree_actions_update (GbProjectTree *self)
{
  GActionGroup *group;
  GbTreeNode *selection;
  GObject *item = NULL;

  IDE_ENTRY;

  g_assert (GB_IS_PROJECT_TREE (self));

  group = gtk_widget_get_action_group (GTK_WIDGET (self), "project-tree");
  g_assert (G_IS_SIMPLE_ACTION_GROUP (group));

  selection = gb_tree_get_selected (GB_TREE (self));
  if (selection != NULL)
    item = gb_tree_node_get_item (selection);

  action_set (group, "new-file",
              "enabled", (IDE_IS_PROJECT_FILE (item) || IDE_IS_PROJECT_FILES (item)),
              NULL);
  action_set (group, "new-directory",
              "enabled", (IDE_IS_PROJECT_FILE (item) || IDE_IS_PROJECT_FILES (item)),
              NULL);
  action_set (group, "open",
              "enabled", (IDE_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)),
              NULL);
  action_set (group, "open-containing-folder",
              "enabled", (IDE_IS_PROJECT_FILE (item) || IDE_IS_PROJECT_FILES (item)),
              NULL);
  action_set (group, "rename-file",
              "enabled", IDE_IS_PROJECT_FILE (item),
              NULL);
  action_set (group, "move-to-trash",
              "enabled", (IDE_IS_PROJECT_FILE (item) && !project_file_is_directory (item)),
              NULL);

  IDE_EXIT;
}
static void
gb_project_tree_actions_open_containing_folder (GSimpleAction *action,
                                                GVariant      *variant,
                                                gpointer       user_data)
{
  GbProjectTree *self = user_data;
  GbTreeNode *selected;
  GObject *item;
  GFile *file;

  g_assert (GB_IS_PROJECT_TREE (self));

  if (!(selected = gb_tree_get_selected (GB_TREE (self))) ||
      !(item = gb_tree_node_get_item (selected)) ||
      !GB_IS_PROJECT_FILE (item))
    return;

  file = gb_project_file_get_file (GB_PROJECT_FILE (item));

  gb_file_manager_show (file, NULL);
}
static void
gb_project_tree_actions_open_with (GSimpleAction *action,
                                   GVariant      *variant,
                                   gpointer       user_data)
{
  g_autoptr(GDesktopAppInfo) app_info = NULL;
  g_autoptr(GdkAppLaunchContext) launch_context = NULL;
  GbProjectTree *self = user_data;
  GbTreeNode *selected;
  GbWorkbench *workbench;
  GdkDisplay *display;
  GFileInfo *file_info;
  GFile *file;
  const gchar *app_id;
  GObject *item;
  GList *files;

  g_assert (GB_IS_PROJECT_TREE (self));
  g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING));

  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) ||
      !(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))) ||
      !(app_info = g_desktop_app_info_new (app_id)))
    return;

  display = gtk_widget_get_display (GTK_WIDGET (self));
  launch_context = gdk_display_get_app_launch_context (display);

  files = g_list_append (NULL, file);
  g_app_info_launch (G_APP_INFO (app_info), files, G_APP_LAUNCH_CONTEXT (launch_context), NULL);
  g_list_free (files);
}
static void
gb_project_tree_actions_rename_file (GSimpleAction *action,
                                     GVariant      *variant,
                                     gpointer       user_data)
{
  GbProjectTree *self = user_data;
  GbTreeNode *selected;
  GtkPopover *popover;
  GObject *item;
  GFile *file;
  GFileInfo *file_info;
  gboolean is_dir;

  g_assert (GB_IS_PROJECT_TREE (self));

  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))))
    return;

  is_dir = (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY);

  popover = g_object_new (GB_TYPE_RENAME_FILE_POPOVER,
                          "file", file,
                          "is-directory", is_dir,
                          "position", GTK_POS_RIGHT,
                          NULL);
  g_signal_connect_object (popover,
                           "rename-file",
                           G_CALLBACK (gb_project_tree_actions__rename_file_cb),
                           self,
                           G_CONNECT_SWAPPED);
  gb_tree_node_show_popover (selected, popover);
}
static void
gb_project_tree_actions_new (GbProjectTree *self,
                             GFileType      file_type)
{
  GbTreeNode *selected;
  GObject *item;
  GtkPopover *popover;
  IdeProjectFile *project_file;
  GFile *file = NULL;
  gboolean is_dir;

  g_assert (GB_IS_PROJECT_TREE (self));
  g_assert ((file_type == G_FILE_TYPE_DIRECTORY) ||
            (file_type == G_FILE_TYPE_REGULAR));

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)))
    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;

      context = ide_object_get_context (IDE_OBJECT (item));
      vcs = ide_context_get_vcs (context);
      file = ide_vcs_get_working_directory (vcs);
      is_dir = TRUE;
    }

  g_assert (G_IS_FILE (file));

  /*
   * If this item is an IdeProjectFile and not a directory, then we really
   * want to create a sibling.
   */
  if (!is_dir)
    {
      GtkTreePath *path;

      selected = gb_tree_node_get_parent (selected);
      gb_tree_node_select (selected);
      path = gb_tree_node_get_path (selected);
      gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (self), path, NULL, FALSE, 0, 0);
      gtk_tree_path_free (path);

      goto again;
    }

  if ((self->expanded_in_new = !gb_tree_node_get_expanded (selected)))
    gb_tree_node_expand (selected, FALSE);

  popover = g_object_new (GB_TYPE_NEW_FILE_POPOVER,
                          "directory", file,
                          "file-type", file_type,
                          "position", GTK_POS_RIGHT,
                          NULL);
  g_signal_connect_object (popover,
                           "create-file",
                           G_CALLBACK (gb_project_tree_actions__popover_create_file_cb),
                           self,
                           G_CONNECT_SWAPPED);
  g_signal_connect_object (popover,
                           "closed",
                           G_CALLBACK (gb_project_tree_actions__popover_closed_cb),
                           self,
                           G_CONNECT_SWAPPED);

  gb_tree_node_show_popover (selected, popover);
}