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