diff options
Diffstat (limited to 'editor/filesystem_dock.cpp')
-rw-r--r-- | editor/filesystem_dock.cpp | 719 |
1 files changed, 422 insertions, 297 deletions
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 58af5285b9..a729befe8e 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -39,6 +39,7 @@ #include "editor_node.h" #include "editor_settings.h" #include "scene/main/viewport.h" +#include "scene/resources/packed_scene.h" Ref<Texture> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx) { Ref<Texture> file_icon; @@ -51,11 +52,10 @@ Ref<Texture> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_di return file_icon; } -bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths) { - +bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites) { bool parent_should_expand = false; - // Create a tree item for the subdirectory + // Create a tree item for the subdirectory. TreeItem *subdirectory_item = tree->create_item(p_parent); String dname = p_dir->get_name(); if (dname == "") @@ -63,10 +63,11 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory subdirectory_item->set_text(0, dname); subdirectory_item->set_icon(0, get_icon("Folder", "EditorIcons")); + subdirectory_item->set_icon_modulate(0, get_color("folder_icon_modulate", "FileDialog")); subdirectory_item->set_selectable(0, true); String lpath = p_dir->get_path(); subdirectory_item->set_metadata(0, lpath); - if (path == lpath || ((display_mode_setting == DISPLAY_MODE_SETTING_SPLIT) && path.get_base_dir() == lpath)) { + if (!p_select_in_favorites && (path == lpath || ((display_mode == DISPLAY_MODE_SPLIT) && path.get_base_dir() == lpath))) { subdirectory_item->select(0); } @@ -79,21 +80,28 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory parent_should_expand = true; } - // Create items for all subdirectories + // Create items for all subdirectories. for (int i = 0; i < p_dir->get_subdir_count(); i++) - parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths) || parent_should_expand); + parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites) || parent_should_expand); - // Create all items for the files in the subdirectory - if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) { + // Create all items for the files in the subdirectory. + if (display_mode == DISPLAY_MODE_TREE_ONLY) { for (int i = 0; i < p_dir->get_file_count(); i++) { + + String file_type = p_dir->get_file_type(i); + + if (_is_file_type_disabled_by_feature_profile(file_type)) { + // If type is disabled, file won't be displayed. + continue; + } String file_name = p_dir->get_file(i); if (searched_string.length() > 0) { if (file_name.to_lower().find(searched_string) < 0) { - // The seached string is not in the file name, we skip it + // The searched string is not in the file name, we skip it. continue; } else { - // We expand all parents + // We expand all parents. parent_should_expand = true; } } @@ -103,7 +111,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory file_item->set_icon(0, _get_tree_item_icon(p_dir, i)); String file_metadata = lpath.plus_file(file_name); file_item->set_metadata(0, file_metadata); - if (path == file_metadata) { + if (!p_select_in_favorites && path == file_metadata) { file_item->select(0); file_item->set_as_cursor(0); } @@ -126,7 +134,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory } Vector<String> FileSystemDock::_compute_uncollapsed_paths() { - // Register currently collapsed paths + // Register currently collapsed paths. Vector<String> uncollapsed_paths; TreeItem *root = tree->get_root(); if (root) { @@ -156,15 +164,14 @@ Vector<String> FileSystemDock::_compute_uncollapsed_paths() { return uncollapsed_paths; } -void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool p_uncollapse_root) { - - // Recreate the tree +void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, bool p_uncollapse_root, bool p_select_in_favorites) { + // Recreate the tree. tree->clear(); tree_update_id++; updating_tree = true; TreeItem *root = tree->create_item(); - // Handles the favorites + // Handles the favorites. TreeItem *favorites = tree->create_item(root); favorites->set_icon(0, get_icon("Favorites", "EditorIcons")); favorites->set_text(0, TTR("Favorites:")); @@ -178,15 +185,19 @@ void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool continue; Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons"); + const Color folder_color = get_color("folder_icon_modulate", "FileDialog"); String text; Ref<Texture> icon; + Color color; if (fave == "res://") { text = "/"; icon = folder_icon; + color = folder_color; } else if (fave.ends_with("/")) { text = fave.substr(0, fave.length() - 1).get_file(); icon = folder_icon; + color = folder_color; } else { text = fave.get_file(); int index; @@ -196,15 +207,21 @@ void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool } else { icon = get_icon("File", "EditorIcons"); } + color = Color(1, 1, 1); } if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { TreeItem *ti = tree->create_item(favorites); ti->set_text(0, text); ti->set_icon(0, icon); + ti->set_icon_modulate(0, color); ti->set_tooltip(0, fave); ti->set_selectable(0, true); ti->set_metadata(0, fave); + if (p_select_in_favorites && fave == path) { + ti->select(0); + ti->set_as_cursor(0); + } if (!fave.ends_with("/")) { Array udata; udata.push_back(tree_update_id); @@ -219,25 +236,26 @@ void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool uncollapsed_paths.push_back("res://"); } - // Create the remaining of the tree - _create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths); + // Create the remaining of the tree. + _create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths, p_select_in_favorites); tree->ensure_cursor_is_visible(); updating_tree = false; } -void FileSystemDock::_update_display_mode(bool p_force) { - // Compute the new display mode - DisplayMode new_display_mode = (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) ? DISPLAY_MODE_TREE_ONLY : DISPLAY_MODE_SPLIT; +void FileSystemDock::set_display_mode(DisplayMode p_display_mode) { + display_mode = p_display_mode; + _update_display_mode(false); +} - if (p_force || new_display_mode != display_mode || old_display_mode_setting != display_mode_setting) { - display_mode = new_display_mode; - old_display_mode_setting = display_mode_setting; - button_toggle_display_mode->set_pressed(display_mode_setting == DISPLAY_MODE_SETTING_SPLIT ? true : false); +void FileSystemDock::_update_display_mode(bool p_force) { + // Compute the new display mode. + if (p_force || old_display_mode != display_mode) { + button_toggle_display_mode->set_pressed(display_mode == DISPLAY_MODE_SPLIT); switch (display_mode) { case DISPLAY_MODE_TREE_ONLY: tree->show(); tree->set_v_size_flags(SIZE_EXPAND_FILL); - if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) { + if (display_mode == DISPLAY_MODE_TREE_ONLY) { tree_search_box->show(); } else { tree_search_box->hide(); @@ -258,21 +276,17 @@ void FileSystemDock::_update_display_mode(bool p_force) { _update_file_list(true); break; } + old_display_mode = display_mode; } } void FileSystemDock::_notification(int p_what) { - switch (p_what) { - - case NOTIFICATION_RESIZED: { - _update_display_mode(); - } break; case NOTIFICATION_ENTER_TREE: { - if (initialized) return; initialized = true; + EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", this, "_feature_profile_changed"); EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed"); EditorResourcePreview::get_singleton()->connect("preview_invalidated", this, "_preview_invalidated"); @@ -280,8 +294,7 @@ void FileSystemDock::_notification(int p_what) { String ei = "EditorIcons"; button_reload->set_icon(get_icon("Reload", ei)); button_toggle_display_mode->set_icon(get_icon("Panels2", ei)); - _update_file_list_display_mode_button(); - button_file_list_display_mode->connect("pressed", this, "_change_file_display"); + button_file_list_display_mode->connect("pressed", this, "_toggle_file_display"); files->connect("item_activated", this, "_file_list_activate_file"); button_hist_next->connect("pressed", this, "_fw_history"); @@ -296,11 +309,12 @@ void FileSystemDock::_notification(int p_what) { file_list_popup->connect("id_pressed", this, "_file_list_rmb_option"); tree_popup->connect("id_pressed", this, "_tree_rmb_option"); - current_path->connect("text_entered", this, "navigate_to_path"); + current_path->connect("text_entered", this, "_navigate_to_path"); - display_mode_setting = DisplayModeSetting(int(EditorSettings::get_singleton()->get("docks/filesystem/display_mode"))); always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); + set_file_list_display_mode(FileSystemDock::FILE_LIST_DISPLAY_LIST); + _update_display_mode(); if (EditorFileSystem::get_singleton()->is_scanning()) { @@ -308,18 +322,15 @@ void FileSystemDock::_notification(int p_what) { } else { _update_tree(Vector<String>(), true); } - } break; + case NOTIFICATION_PROCESS: { if (EditorFileSystem::get_singleton()->is_scanning()) { scanning_progress->set_value(EditorFileSystem::get_singleton()->get_scanning_progress() * 100); } } break; - case NOTIFICATION_EXIT_TREE: { - } break; case NOTIFICATION_DRAG_BEGIN: { - Dictionary dd = get_viewport()->gui_get_drag_data(); if (tree->is_visible_in_tree() && dd.has("type")) { if ((String(dd["type"]) == "files") || (String(dd["type"]) == "files_and_dirs") || (String(dd["type"]) == "resource")) { @@ -328,26 +339,26 @@ void FileSystemDock::_notification(int p_what) { tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN); } } - } break; - case NOTIFICATION_DRAG_END: { + case NOTIFICATION_DRAG_END: { tree->set_drop_mode_flags(0); - } break; + case NOTIFICATION_THEME_CHANGED: { if (is_visible_in_tree()) { _update_display_mode(true); } } break; + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - // Update icons + // Update icons. String ei = "EditorIcons"; button_reload->set_icon(get_icon("Reload", ei)); button_toggle_display_mode->set_icon(get_icon("Panels2", ei)); button_hist_next->set_icon(get_icon("Forward", ei)); button_hist_prev->set_icon(get_icon("Back", ei)); - if (button_file_list_display_mode->is_pressed()) { + if (file_list_display_mode == FILE_LIST_DISPLAY_LIST) { button_file_list_display_mode->set_icon(get_icon("FileThumbnail", "EditorIcons")); } else { button_file_list_display_mode->set_icon(get_icon("FileList", "EditorIcons")); @@ -358,65 +369,47 @@ void FileSystemDock::_notification(int p_what) { file_list_search_box->set_right_icon(get_icon("Search", ei)); file_list_search_box->set_clear_button_enabled(true); - bool should_update_files = false; - - // Update file list display mode - int new_file_list_mode = int(EditorSettings::get_singleton()->get("docks/filesystem/files_display_mode")); - if (new_file_list_mode != file_list_display_mode) { - set_file_list_display_mode(new_file_list_mode); - _update_file_list_display_mode_button(); - should_update_files = true; - } - - // Update display of files in tree - display_mode_setting = DisplayModeSetting(int(EditorSettings::get_singleton()->get("docks/filesystem/display_mode"))); - - // Update allways showfolders + // Update always show folders. bool new_always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); if (new_always_show_folders != always_show_folders) { always_show_folders = new_always_show_folders; - should_update_files = true; - } - - if (should_update_files) { _update_file_list(true); } - // Change full tree mode + // Change full tree mode. _update_display_mode(); - } break; } } void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_selected) { - // Update the import dock + // Update the import dock. import_dock_needs_update = true; call_deferred("_update_import_dock"); - // Return if we don't select something new + // Return if we don't select something new. if (!p_selected) return; - // Tree item selected + // Tree item selected. TreeItem *selected = tree->get_selected(); if (!selected) return; TreeItem *favorites_item = tree->get_root()->get_children(); if (selected->get_parent() == favorites_item && !String(selected->get_metadata(0)).ends_with("/")) { - // Go to the favorites if we click in the favorites and the path has changed + // Go to the favorites if we click in the favorites and the path has changed. path = "Favorites"; } else { path = selected->get_metadata(0); - // Note: the "Favorites" item also leads to this path + // Note: the "Favorites" item also leads to this path. } - // Set the current path + // Set the current path. _set_current_path_text(path); _push_to_history(); - // Update the file list + // Update the file list. if (!updating_tree && display_mode == DISPLAY_MODE_SPLIT) { _update_file_list(false); } @@ -430,7 +423,6 @@ String FileSystemDock::get_selected_path() const { } String FileSystemDock::get_current_path() const { - return path; } @@ -442,8 +434,7 @@ void FileSystemDock::_set_current_path_text(const String &p_path) { } } -void FileSystemDock::navigate_to_path(const String &p_path) { - +void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_favorites) { if (p_path == "Favorites") { path = p_path; } else { @@ -458,17 +449,19 @@ void FileSystemDock::navigate_to_path(const String &p_path) { } else if (dirAccess->dir_exists(p_path)) { path = target_path + "/"; } else { - ERR_EXPLAIN(vformat(TTR("Cannot navigate to '%s' as it has not been found in the file system!"), p_path)); - ERR_FAIL(); + memdelete(dirAccess); + ERR_FAIL_MSG(vformat("Cannot navigate to '%s' as it has not been found in the file system!", p_path)); } + memdelete(dirAccess); } _set_current_path_text(path); _push_to_history(); - _update_tree(_compute_uncollapsed_paths()); + _update_tree(_compute_uncollapsed_paths(), false, p_select_in_favorites); if (display_mode == DISPLAY_MODE_SPLIT) { _update_file_list(false); + files->get_v_scroll()->set_value(0); } String file_name = p_path.get_file(); @@ -483,8 +476,11 @@ void FileSystemDock::navigate_to_path(const String &p_path) { } } -void FileSystemDock::_file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) { +void FileSystemDock::navigate_to_path(const String &p_path) { + _navigate_to_path(p_path); +} +void FileSystemDock::_file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) { if ((file_list_vb->is_visible_in_tree() || path == p_path.get_base_dir()) && p_preview.is_valid()) { Array uarr = p_udata; int idx = uarr[0]; @@ -512,9 +508,13 @@ void FileSystemDock::_tree_thumbnail_done(const String &p_path, const Ref<Textur } } -void FileSystemDock::_update_file_list_display_mode_button() { +void FileSystemDock::_toggle_file_display() { + _set_file_display(file_list_display_mode != FILE_LIST_DISPLAY_LIST); + emit_signal("display_mode_changed"); +} - if (button_file_list_display_mode->is_pressed()) { +void FileSystemDock::_set_file_display(bool p_active) { + if (p_active) { file_list_display_mode = FILE_LIST_DISPLAY_LIST; button_file_list_display_mode->set_icon(get_icon("FileThumbnail", "EditorIcons")); button_file_list_display_mode->set_tooltip(TTR("View items as a grid of thumbnails.")); @@ -523,19 +523,30 @@ void FileSystemDock::_update_file_list_display_mode_button() { button_file_list_display_mode->set_icon(get_icon("FileList", "EditorIcons")); button_file_list_display_mode->set_tooltip(TTR("View items as a list.")); } + + _update_file_list(true); } -void FileSystemDock::_change_file_display() { +bool FileSystemDock::_is_file_type_disabled_by_feature_profile(const StringName &p_class) { + Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile(); + if (profile.is_null()) { + return false; + } - _update_file_list_display_mode_button(); + StringName class_name = p_class; - EditorSettings::get_singleton()->set("docks/filesystem/files_display_mode", file_list_display_mode); + while (class_name != StringName()) { - _update_file_list(true); + if (profile->is_class_disabled(class_name)) { + return true; + } + class_name = ClassDB::get_parent_class(class_name); + } + + return false; } void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *matches, int p_max_items) { - if (matches->size() > p_max_items) return; @@ -553,7 +564,11 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> * fi.type = p_path->get_file_type(i); fi.path = p_path->get_file_path(i); fi.import_broken = !p_path->get_file_import_is_valid(i); - fi.import_status = 0; + + if (_is_file_type_disabled_by_feature_profile(fi.type)) { + // This type is disabled, will not appear here. + continue; + } matches->push_back(fi); if (matches->size() > p_max_items) @@ -563,8 +578,7 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> * } void FileSystemDock::_update_file_list(bool p_keep_selection) { - - // Register the previously selected items + // Register the previously selected items. Set<String> cselection; if (p_keep_selection) { for (int i = 0; i < files->get_item_count(); i++) { @@ -590,7 +604,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { bool use_thumbnails = (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS); if (use_thumbnails) { - // Thumbnails mode + // Thumbnails mode. files->set_max_columns(0); files->set_icon_mode(ItemList::ICON_MODE_TOP); files->set_fixed_column_width(thumbnail_size * 3 / 2); @@ -607,8 +621,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { file_thumbnail_broken = get_icon("FileDeadBigThumb", ei); } } else { - - // No thumbnails + // No thumbnails. files->set_icon_mode(ItemList::ICON_MODE_LEFT); files->set_max_columns(1); files->set_max_text_lines(1); @@ -617,11 +630,12 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } Ref<Texture> folder_icon = (use_thumbnails) ? folder_thumbnail : get_icon("folder", "FileDialog"); + const Color folder_color = get_color("folder_icon_modulate", "FileDialog"); - // Build the FileInfo list + // Build the FileInfo list. List<FileInfo> filelist; if (path == "Favorites") { - // Display the favorites + // Display the favorites. Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < favorites.size(); i++) { String favorite = favorites[i]; @@ -655,7 +669,6 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { fi.type = ""; fi.import_broken = true; } - fi.import_status = 0; if (searched_string.length() == 0 || fi.name.to_lower().find(searched_string) >= 0) { filelist.push_back(fi); @@ -663,8 +676,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } } } else { - - // Get infos on the directory + file + // Get infos on the directory + file. if (directory.ends_with("/") && directory != "res://") { directory = directory.substr(0, directory.length() - 1); } @@ -678,13 +690,11 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { return; if (searched_string.length() > 0) { - // Display the search results + // Display the search results. _search(EditorFileSystem::get_singleton()->get_filesystem(), &filelist, 128); } else { - if (display_mode == DISPLAY_MODE_TREE_ONLY || always_show_folders) { - // Display folders in the list - + // Display folders in the list. if (directory != "res://") { files->add_item("..", folder_icon, true); @@ -694,14 +704,15 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->set_item_metadata(files->get_item_count() - 1, bd); files->set_item_selectable(files->get_item_count() - 1, false); + files->set_item_icon_modulate(files->get_item_count() - 1, folder_color); } for (int i = 0; i < efd->get_subdir_count(); i++) { - String dname = efd->get_subdir(i)->get_name(); files->add_item(dname, folder_icon, true); files->set_item_metadata(files->get_item_count() - 1, directory.plus_file(dname) + "/"); + files->set_item_icon_modulate(files->get_item_count() - 1, folder_color); if (cselection.has(dname)) { files->select(files->get_item_count() - 1, false); @@ -709,15 +720,13 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } } - // Display the folder content + // Display the folder content. for (int i = 0; i < efd->get_file_count(); i++) { - FileInfo fi; fi.name = efd->get_file(i); fi.path = directory.plus_file(fi.name); fi.type = efd->get_file_type(i); fi.import_broken = !efd->get_file_import_is_valid(i); - fi.import_status = 0; filelist.push_back(fi); } @@ -725,7 +734,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { filelist.sort(); } - // Fills the ItemList control node from the FileInfos + // Fills the ItemList control node from the FileInfos. String oi = "Object"; for (List<FileInfo>::Element *E = filelist.front(); E; E = E->next()) { FileInfo *finfo = &(E->get()); @@ -736,9 +745,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { Ref<Texture> type_icon; Ref<Texture> big_icon; - String tooltip = fname; + String tooltip = fpath; - // Select the icons + // Select the icons. if (!finfo->import_broken) { type_icon = (has_icon(ftype, ei)) ? get_icon(ftype, ei) : get_icon(oi, ei); big_icon = file_thumbnail; @@ -748,7 +757,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { tooltip += "\n" + TTR("Status: Import of file failed. Please fix file and reimport manually."); } - // Add the item to the ItemList + // Add the item to the ItemList. int item_index; if (use_thumbnails) { files->add_item(fname, big_icon, true); @@ -762,7 +771,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->set_item_metadata(item_index, fpath); } - // Generate the preview + // Generate the preview. if (!finfo->import_broken) { Array udata; udata.resize(2); @@ -771,7 +780,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { EditorResourcePreview::get_singleton()->queue_resource_preview(fpath, this, "_file_list_thumbnail_done", udata); } - // Select the items + // Select the items. if (cselection.has(fname)) files->select(item_index, false); @@ -780,7 +789,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->ensure_current_is_visible(); } - // Tooltip + // Tooltip. if (finfo->sources.size()) { for (int j = 0; j < finfo->sources.size(); j++) { tooltip += "\nSource: " + finfo->sources[j]; @@ -790,7 +799,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } } -void FileSystemDock::_select_file(const String p_path) { +void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorites) { String fpath = p_path; if (fpath.ends_with("/")) { if (fpath != "res://") { @@ -803,17 +812,21 @@ void FileSystemDock::_select_file(const String p_path) { editor->load_resource(fpath); } } - navigate_to_path(fpath); + _navigate_to_path(fpath, p_select_in_favorites); } void FileSystemDock::_tree_activate_file() { TreeItem *selected = tree->get_selected(); if (selected) { - call_deferred("_select_file", selected->get_metadata(0)); + String path = selected->get_metadata(0); + TreeItem *parent = selected->get_parent(); + bool is_favorite = parent != NULL && parent->get_metadata(0) == "Favorites"; - if (path.ends_with("/") || path == "Favorites") { + if ((!is_favorite && path.ends_with("/")) || path == "Favorites") { bool collapsed = selected->is_collapsed(); selected->set_collapsed(!collapsed); + } else { + _select_file(path, is_favorite && !path.ends_with("/")); } } } @@ -823,13 +836,12 @@ void FileSystemDock::_file_list_activate_file(int p_idx) { } void FileSystemDock::_preview_invalidated(const String &p_path) { - if (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS && p_path.get_base_dir() == path && searched_string.length() == 0 && file_list_vb->is_visible_in_tree()) { for (int i = 0; i < files->get_item_count(); i++) { if (files->get_item_metadata(i) == p_path) { - //re-request preview + // Re-request preview. Array udata; udata.resize(2); udata[0] = i; @@ -842,7 +854,6 @@ void FileSystemDock::_preview_invalidated(const String &p_path) { } void FileSystemDock::_fs_changed() { - button_hist_prev->set_disabled(history_pos == 0); button_hist_next->set_disabled(history_pos == history.size() - 1); scanning_vb->hide(); @@ -860,7 +871,6 @@ void FileSystemDock::_fs_changed() { } void FileSystemDock::_set_scanning_mode() { - button_hist_prev->set_disabled(true); button_hist_next->set_disabled(true); split_box->hide(); @@ -874,7 +884,6 @@ void FileSystemDock::_set_scanning_mode() { } void FileSystemDock::_fw_history() { - if (history_pos < history.size() - 1) history_pos++; @@ -952,7 +961,7 @@ void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, const Map<Str void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_new_path, Map<String, String> &p_file_renames, Map<String, String> &p_folder_renames) { - //Ensure folder paths end with "/" + // Ensure folder paths end with "/". String old_path = (p_item.is_file || p_item.path.ends_with("/")) ? p_item.path : (p_item.path + "/"); String new_path = (p_item.is_file || p_new_path.ends_with("/")) ? p_new_path : (p_new_path + "/"); @@ -962,12 +971,12 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ EditorNode::get_singleton()->add_io_error(TTR("Cannot move/rename resources root.")); return; } else if (!p_item.is_file && new_path.begins_with(old_path)) { - //This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/" + // This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/". EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.") + "\n" + old_path + "\n"); return; } - //Build a list of files which will have new paths as a result of this operation + // Build a list of files which will have new paths as a result of this operation. Vector<String> file_changed_paths; Vector<String> folder_changed_paths; if (p_item.is_file) { @@ -981,8 +990,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ print_verbose("Moving " + old_path + " -> " + new_path); Error err = da->rename(old_path, new_path); if (err == OK) { - - //Move/Rename any corresponding import settings too + // Move/Rename any corresponding import settings too. if (p_item.is_file && FileAccess::exists(old_path + ".import")) { err = da->rename(old_path + ".import", new_path + ".import"); if (err != OK) { @@ -990,7 +998,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ } } - // update scene if it is open + // Update scene if it is open. for (int i = 0; i < file_changed_paths.size(); ++i) { String new_item_path = p_item.is_file ? new_path : file_changed_paths[i].replace_first(old_path, new_path); if (ResourceLoader::get_resource_type(new_item_path) == "PackedScene" && editor->is_scene_open(file_changed_paths[i])) { @@ -998,13 +1006,14 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ for (int j = 0; j < ed->get_edited_scene_count(); j++) { if (ed->get_scene_path(j) == file_changed_paths[i]) { ed->get_edited_scene_root(j)->set_filename(new_item_path); + editor->save_layout(); break; } } } } - //Only treat as a changed dependency if it was successfully moved + // Only treat as a changed dependency if it was successfully moved. for (int i = 0; i < file_changed_paths.size(); ++i) { p_file_renames[file_changed_paths[i]] = file_changed_paths[i].replace_first(old_path, new_path); print_verbose(" Remap: " + file_changed_paths[i] + " -> " + p_file_renames[file_changed_paths[i]]); @@ -1021,7 +1030,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ } void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const { - //Ensure folder paths end with "/" + // Ensure folder paths end with "/". String old_path = (p_item.is_file || p_item.path.ends_with("/")) ? p_item.path : (p_item.path + "/"); String new_path = (p_item.is_file || p_new_path.ends_with("/")) ? p_new_path : (p_new_path + "/"); @@ -1031,7 +1040,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin EditorNode::get_singleton()->add_io_error(TTR("Cannot move/rename resources root.")); return; } else if (!p_item.is_file && new_path.begins_with(old_path)) { - //This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/" + // This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/". EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.") + "\n" + old_path + "\n"); return; } @@ -1040,7 +1049,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin print_verbose("Duplicating " + old_path + " -> " + new_path); Error err = p_item.is_file ? da->copy(old_path, new_path) : da->copy_dir(old_path, new_path); if (err == OK) { - //Move/Rename any corresponding import settings too + // Move/Rename any corresponding import settings too. if (p_item.is_file && FileAccess::exists(old_path + ".import")) { err = da->copy(old_path + ".import", new_path + ".import"); if (err != OK) { @@ -1054,13 +1063,11 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin } void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> &p_renames) const { - - //Rename all resources loaded, be it subresources or actual resources + // Rename all resources loaded, be it subresources or actual resources. List<Ref<Resource> > cached; ResourceCache::get_cached_resources(&cached); for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { - Ref<Resource> r = E->get(); String base_path = r->get_path(); @@ -1079,7 +1086,6 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> } for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) { - String path; if (i == EditorNode::get_editor_data().get_edited_scene()) { if (!get_tree()->get_edited_scene_root()) @@ -1087,7 +1093,6 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> path = get_tree()->get_edited_scene_root()->get_filename(); } else { - path = EditorNode::get_editor_data().get_scene_path(i); } @@ -1096,23 +1101,21 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> } if (i == EditorNode::get_editor_data().get_edited_scene()) { - get_tree()->get_edited_scene_root()->set_filename(path); } else { - EditorNode::get_editor_data().set_scene_path(i, path); } } } void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &p_renames) const { - //The following code assumes that the following holds: + // The following code assumes that the following holds: // 1) EditorFileSystem contains the old paths/folder structure from before the rename/move. // 2) ResourceLoader can use the new paths without needing to call rescan. Vector<String> remaps; _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), p_renames, remaps); for (int i = 0; i < remaps.size(); ++i) { - //Because we haven't called a rescan yet the found remap might still be an old path itself. + // Because we haven't called a rescan yet the found remap might still be an old path itself. String file = p_renames.has(remaps[i]) ? p_renames[remaps[i]] : remaps[i]; print_verbose("Remapping dependencies for: " + file); Error err = ResourceLoader::rename_dependencies(file, p_renames); @@ -1126,8 +1129,7 @@ void FileSystemDock::_update_dependencies_after_move(const Map<String, String> & } void FileSystemDock::_update_project_settings_after_move(const Map<String, String> &p_renames) const { - - // Find all project settings of type FILE and replace them if needed + // Find all project settings of type FILE and replace them if needed. const Map<StringName, PropertyInfo> prop_info = ProjectSettings::get_singleton()->get_custom_property_info(); for (const Map<StringName, PropertyInfo>::Element *E = prop_info.front(); E; E = E->next()) { if (E->get().hint == PROPERTY_HINT_FILE) { @@ -1158,7 +1160,6 @@ void FileSystemDock::_update_project_settings_after_move(const Map<String, Strin } void FileSystemDock::_update_favorites_list_after_move(const Map<String, String> &p_files_renames, const Map<String, String> &p_folders_renames) const { - Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); Vector<String> new_favorites; @@ -1176,6 +1177,21 @@ void FileSystemDock::_update_favorites_list_after_move(const Map<String, String> EditorSettings::get_singleton()->set_favorites(new_favorites); } +void FileSystemDock::_save_scenes_after_move(const Map<String, String> &p_renames) const { + Vector<String> remaps; + _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), p_renames, remaps); + Vector<String> new_filenames; + + for (int i = 0; i < remaps.size(); ++i) { + String file = p_renames.has(remaps[i]) ? p_renames[remaps[i]] : remaps[i]; + if (ResourceLoader::get_resource_type(file) == "PackedScene") { + new_filenames.push_back(file); + } + } + + editor->save_scene_list(new_filenames); +} + void FileSystemDock::_make_dir_confirm() { String dir_name = make_dir_dialog_text->get_text().strip_edges(); @@ -1184,7 +1200,7 @@ void FileSystemDock::_make_dir_confirm() { return; } else if (dir_name.find("/") != -1 || dir_name.find("\\") != -1 || dir_name.find(":") != -1 || dir_name.find("*") != -1 || dir_name.find("|") != -1 || dir_name.find(">") != -1 || dir_name.ends_with(".") || dir_name.ends_with(" ")) { - EditorNode::get_singleton()->show_warning(TTR("Provided name contains invalid characters")); + EditorNode::get_singleton()->show_warning(TTR("Provided name contains invalid characters.")); return; } @@ -1208,6 +1224,48 @@ void FileSystemDock::_make_dir_confirm() { } } +void FileSystemDock::_make_scene_confirm() { + String scene_name = make_scene_dialog_text->get_text().strip_edges(); + + if (scene_name.length() == 0) { + EditorNode::get_singleton()->show_warning(TTR("No name provided.")); + return; + } + + String directory = path; + if (!directory.ends_with("/")) { + directory = directory.get_base_dir(); + } + + String extension = scene_name.get_extension(); + List<String> extensions; + Ref<PackedScene> sd = memnew(PackedScene); + ResourceSaver::get_recognized_extensions(sd, &extensions); + + bool extension_correct = false; + for (List<String>::Element *E = extensions.front(); E; E = E->next()) { + if (E->get() == extension) { + extension_correct = true; + break; + } + } + if (!extension_correct) + scene_name = scene_name.get_basename() + ".tscn"; + + scene_name = directory.plus_file(scene_name); + + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + if (da->file_exists(scene_name)) { + EditorNode::get_singleton()->show_warning(TTR("A file or folder with this name already exists.")); + memdelete(da); + return; + } + memdelete(da); + + int idx = editor->new_scene(); + editor->get_editor_data().set_scene_path(idx, scene_name); +} + void FileSystemDock::_file_deleted(String p_file) { emit_signal("file_deleted", p_file); } @@ -1217,7 +1275,6 @@ void FileSystemDock::_folder_deleted(String p_folder) { } void FileSystemDock::_rename_operation_confirm() { - String new_name = rename_dialog_text->get_text().strip_edges(); if (new_name.length() == 0) { EditorNode::get_singleton()->show_warning(TTR("No name provided.")); @@ -1233,10 +1290,14 @@ void FileSystemDock::_rename_operation_confirm() { return; } - //Present a more user friendly warning for name conflict + if (EditorFileSystem::get_singleton()->is_group_file(old_path)) { + EditorFileSystem::get_singleton()->move_group_file(old_path, new_path); + } + + // Present a more user friendly warning for name conflict. DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); #if defined(WINDOWS_ENABLED) || defined(UWP_ENABLED) - // Workaround case insensitivity on Windows + // Workaround case insensitivity on Windows. if ((da->file_exists(new_path) || da->dir_exists(new_path)) && new_path.to_lower() != old_path.to_lower()) { #else if (da->file_exists(new_path) || da->dir_exists(new_path)) { @@ -1250,18 +1311,24 @@ void FileSystemDock::_rename_operation_confirm() { Map<String, String> file_renames; Map<String, String> folder_renames; _try_move_item(to_rename, new_path, file_renames, folder_renames); + + int current_tab = editor->get_current_tab(); + _save_scenes_after_move(file_renames); // save scenes before updating _update_dependencies_after_move(file_renames); _update_resource_paths_after_move(file_renames); _update_project_settings_after_move(file_renames); _update_favorites_list_after_move(file_renames, folder_renames); - //Rescan everything + editor->set_current_tab(current_tab); + print_verbose("FileSystem: calling rescan."); _rescan(); + + print_verbose("FileSystem: saving moved scenes."); + _save_scenes_after_move(file_renames); } void FileSystemDock::_duplicate_operation_confirm() { - String new_name = duplicate_dialog_text->get_text().strip_edges(); if (new_name.length() == 0) { EditorNode::get_singleton()->show_warning(TTR("No name provided.")); @@ -1271,15 +1338,15 @@ void FileSystemDock::_duplicate_operation_confirm() { return; } - String new_path; String base_dir = to_duplicate.path.get_base_dir(); - if (to_duplicate.is_file) { - new_path = base_dir.plus_file(new_name); - } else { - new_path = base_dir.substr(0, base_dir.find_last("/")) + "/" + new_name; + // get_base_dir() returns "some/path" if the original path was "some/path/", so work it around. + if (to_duplicate.path.ends_with("/")) { + base_dir = base_dir.get_base_dir(); } - //Present a more user friendly warning for name conflict + String new_path = base_dir.plus_file(new_name); + + // Present a more user friendly warning for name conflict DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (da->file_exists(new_path) || da->dir_exists(new_path)) { EditorNode::get_singleton()->show_warning(TTR("A file or folder with this name already exists.")); @@ -1290,7 +1357,7 @@ void FileSystemDock::_duplicate_operation_confirm() { _try_duplicate_item(to_duplicate, new_path); - //Rescan everything + // Rescan everything. print_verbose("FileSystem: calling rescan."); _rescan(); } @@ -1323,13 +1390,23 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw to_move_path = p_to_path; bool can_move = _check_existing(); if (!can_move) { - //ask to do something + // Ask to do something. overwrite_dialog->popup_centered_minsize(); overwrite_dialog->grab_focus(); return; } } + // Check groups. + for (int i = 0; i < to_move.size(); i++) { + + print_line("is group: " + to_move[i].path + ": " + itos(EditorFileSystem::get_singleton()->is_group_file(to_move[i].path))); + if (to_move[i].is_file && EditorFileSystem::get_singleton()->is_group_file(to_move[i].path)) { + print_line("move to: " + p_to_path.plus_file(to_move[i].path.get_file())); + EditorFileSystem::get_singleton()->move_group_file(to_move[i].path, p_to_path.plus_file(to_move[i].path.get_file())); + } + } + Map<String, String> file_renames; Map<String, String> folder_renames; bool is_moved = false; @@ -1343,18 +1420,25 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw } if (is_moved) { + int current_tab = editor->get_current_tab(); + _save_scenes_after_move(file_renames); //save scenes before updating _update_dependencies_after_move(file_renames); _update_resource_paths_after_move(file_renames); _update_project_settings_after_move(file_renames); _update_favorites_list_after_move(file_renames, folder_renames); + editor->set_current_tab(current_tab); + print_verbose("FileSystem: calling rescan."); _rescan(); + + print_verbose("FileSystem: saving moved scenes."); + _save_scenes_after_move(file_renames); } } Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) { - // Build a list of selected items with the active one at the first position + // Build a list of selected items with the active one at the first position. Vector<String> selected_strings; TreeItem *favorites_item = tree->get_root()->get_children(); @@ -1372,8 +1456,15 @@ Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) { selected = tree->get_next_selected(selected); } - // Remove paths or files that are included into another - if (remove_self_inclusion && selected_strings.size() > 1) { + if (remove_self_inclusion) { + selected_strings = _remove_self_included_paths(selected_strings); + } + return selected_strings; +} + +Vector<String> FileSystemDock::_remove_self_included_paths(Vector<String> selected_strings) { + // Remove paths or files that are included into another. + if (selected_strings.size() > 1) { selected_strings.sort_custom<NaturalNoCaseComparator>(); String last_path = ""; for (int i = 0; i < selected_strings.size(); i++) { @@ -1390,10 +1481,9 @@ Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) { } void FileSystemDock::_tree_rmb_option(int p_option) { + Vector<String> selected_strings = _tree_get_selected(false); - Vector<String> selected_strings = _tree_get_selected(); - - // Execute the current option + // Execute the current option. switch (p_option) { case FOLDER_EXPAND_ALL: case FOLDER_COLLAPSE_ALL: { @@ -1432,13 +1522,17 @@ void FileSystemDock::_file_list_rmb_option(int p_option) { _file_option(p_option, selected); } -void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) { - // The first one should be the active item +void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected) { + // The first one should be the active item. switch (p_option) { case FILE_SHOW_IN_EXPLORER: { - // Show the file / folder in the OS explorer + // Show the file/folder in the OS explorer. String fpath = path; + if (path == "Favorites") { + fpath = p_selected[0]; + } + if (!fpath.ends_with("/")) { fpath = fpath.get_base_dir(); } @@ -1447,14 +1541,30 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_OPEN: { - // Open the file + // Open folders. + TreeItem *selected = tree->get_root(); + selected = tree->get_next_selected(selected); + while (selected) { + if (p_selected.find(selected->get_metadata(0)) >= 0) { + selected->set_collapsed(false); + } + selected = tree->get_next_selected(selected); + } + // Open the file. for (int i = 0; i < p_selected.size(); i++) { _select_file(p_selected[i]); } } break; + case FILE_INHERIT: { + // Create a new scene inherited from the selected one. + if (p_selected.size() == 1) { + emit_signal("inherit", p_selected[0]); + } + } break; + case FILE_INSTANCE: { - // Instance all selected scenes + // Instance all selected scenes. Vector<String> paths; for (int i = 0; i < p_selected.size(); i++) { String fpath = p_selected[i]; @@ -1468,7 +1578,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_ADD_FAVORITE: { - // Add the files from favorites + // Add the files from favorites. Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < p_selected.size(); i++) { if (favorites.find(p_selected[i]) == -1) { @@ -1480,7 +1590,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_REMOVE_FAVORITE: { - // Remove the files from favorites + // Remove the files from favorites. Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < p_selected.size(); i++) { favorites.erase(p_selected[i]); @@ -1492,7 +1602,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_DEPENDENCIES: { - // Checkout the file dependencies + // Checkout the file dependencies. if (!p_selected.empty()) { String fpath = p_selected[0]; deps_editor->edit(fpath); @@ -1500,7 +1610,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_OWNERS: { - // Checkout the file owners + // Checkout the file owners. if (!p_selected.empty()) { String fpath = p_selected[0]; owners_editor->show(fpath); @@ -1508,10 +1618,11 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_MOVE: { - // Move the files to a given location + // Move the files to a given location. to_move.clear(); - for (int i = 0; i < p_selected.size(); i++) { - String fpath = p_selected[i]; + Vector<String> collapsed_paths = _remove_self_included_paths(p_selected); + for (int i = collapsed_paths.size() - 1; i >= 0; i--) { + String fpath = collapsed_paths[i]; if (fpath != "res://") { to_move.push_back(FileOrFolder(fpath, !fpath.ends_with("/"))); } @@ -1522,7 +1633,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_RENAME: { - // Rename the active file + // Rename the active file. if (!p_selected.empty()) { to_rename.path = p_selected[0]; if (to_rename.path != "res://") { @@ -1545,12 +1656,13 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_REMOVE: { - // Remove the selected files + // Remove the selected files. Vector<String> remove_files; Vector<String> remove_folders; + Vector<String> collapsed_paths = _remove_self_included_paths(p_selected); - for (int i = 0; i < p_selected.size(); i++) { - String fpath = p_selected[i]; + for (int i = 0; i < collapsed_paths.size(); i++) { + String fpath = collapsed_paths[i]; if (fpath != "res://") { if (fpath.ends_with("/")) { remove_folders.push_back(fpath); @@ -1566,7 +1678,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_DUPLICATE: { - // Duplicate the selected files + // Duplicate the selected files. for (int i = 0; i < p_selected.size(); i++) { to_duplicate.path = p_selected[i]; to_duplicate.is_file = !to_duplicate.path.ends_with("/"); @@ -1591,7 +1703,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_REIMPORT: { - // Reimport all selected files + // Reimport all selected files. Vector<String> reimport; for (int i = 0; i < p_selected.size(); i++) { reimport.push_back(p_selected[i]); @@ -1601,15 +1713,20 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_NEW_FOLDER: { - // Create a new folder make_dir_dialog_text->set_text("new folder"); make_dir_dialog_text->select_all(); make_dir_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); make_dir_dialog_text->grab_focus(); } break; + case FILE_NEW_SCENE: { + make_scene_dialog_text->set_text("new scene"); + make_scene_dialog_text->select_all(); + make_scene_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); + make_scene_dialog_text->grab_focus(); + } break; + case FILE_NEW_SCRIPT: { - // Create a new script String fpath = path; if (!fpath.ends_with("/")) { fpath = fpath.get_base_dir(); @@ -1619,7 +1736,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_COPY_PATH: { - // Copy the file path if (!p_selected.empty()) { String fpath = p_selected[0]; OS::get_singleton()->set_clipboard(fpath); @@ -1627,7 +1743,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } break; case FILE_NEW_RESOURCE: { - // Create a new resource new_resource_dialog->popup_create(true); } break; } @@ -1655,7 +1770,7 @@ void FileSystemDock::_resource_created() const { void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) { if (searched_string.length() == 0 && p_text.length() > 0) { - // Register the uncollapsed paths before they change + // Register the uncollapsed paths before they change. uncollapsed_paths_before_search = _compute_uncollapsed_paths(); } @@ -1663,7 +1778,7 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from if (p_from == tree_search_box) file_list_search_box->set_text(searched_string); - else // file_list_search_box + else // File_list_search_box. tree_search_box->set_text(searched_string); switch (display_mode) { @@ -1678,15 +1793,13 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from } void FileSystemDock::_rescan() { - _set_scanning_mode(); EditorFileSystem::get_singleton()->scan(); } void FileSystemDock::_toggle_split_mode(bool p_active) { - display_mode_setting = p_active ? DISPLAY_MODE_SETTING_SPLIT : DISPLAY_MODE_SETTING_TREE_ONLY; - EditorSettings::get_singleton()->set("docks/filesystem/display_mode", int(display_mode_setting)); - _update_display_mode(); + set_display_mode(p_active ? DISPLAY_MODE_SPLIT : DISPLAY_MODE_TREE_ONLY); + emit_signal("display_mode_changed"); } void FileSystemDock::fix_dependencies(const String &p_for_file) { @@ -1694,17 +1807,14 @@ void FileSystemDock::fix_dependencies(const String &p_for_file) { } void FileSystemDock::focus_on_filter() { - file_list_search_box->grab_focus(); } -void FileSystemDock::set_file_list_display_mode(int p_mode) { - +void FileSystemDock::set_file_list_display_mode(FileListDisplayMode p_mode) { if (p_mode == file_list_display_mode) return; - button_file_list_display_mode->set_pressed(p_mode == FILE_LIST_DISPLAY_LIST); - _change_file_display(); + _toggle_file_display(); } Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) { @@ -1714,12 +1824,12 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) Vector<String> paths; if (p_from == tree) { - // Check if the first selected is in favorite + // Check if the first selected is in favorite. TreeItem *selected = tree->get_next_selected(tree->get_root()); while (selected) { TreeItem *favorites_item = tree->get_root()->get_children(); if (selected == favorites_item) { - // The "Favorites" item is not draggable + // The "Favorites" item is not draggable. return Variant(); } @@ -1757,12 +1867,11 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) } bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { - Dictionary drag_data = p_data; if (drag_data.has("type") && String(drag_data["type"]) == "favorite") { - // Moving favorite around + // Moving favorite around. TreeItem *ti = tree->get_item_at_position(p_point); if (!ti) return false; @@ -1773,20 +1882,20 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da TreeItem *resources_item = favorites_item->get_next(); if (ti == favorites_item) { - return (drop_section == 1); // The parent, first fav + return (drop_section == 1); // The parent, first fav. } if (ti->get_parent() && favorites_item == ti->get_parent()) { return true; // A favorite } if (ti == resources_item) { - return (drop_section == -1); // The tree, last fav + return (drop_section == -1); // The tree, last fav. } return false; } if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - // Move resources + // Move resources. String to_dir; bool favorite; _get_drag_target_folder(to_dir, favorite, p_point, p_from); @@ -1794,7 +1903,7 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da } if (drag_data.has("type") && (String(drag_data["type"]) == "files" || String(drag_data["type"]) == "files_and_dirs")) { - // Move files or dir + // Move files or dir. String to_dir; bool favorite; _get_drag_target_folder(to_dir, favorite, p_point, p_from); @@ -1805,8 +1914,8 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da if (to_dir.empty()) return false; - //Attempting to move a folder into itself will fail later - //Rather than bring up a message don't try to do it in the first place + // Attempting to move a folder into itself will fail later, + // rather than bring up a message don't try to do it in the first place to_dir = to_dir.ends_with("/") ? to_dir : (to_dir + "/"); Vector<String> fnames = drag_data["files"]; for (int i = 0; i < fnames.size(); ++i) { @@ -1821,7 +1930,6 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da } void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { - if (!can_drop_data_fw(p_point, p_data, p_from)) return; Dictionary drag_data = p_data; @@ -1829,7 +1937,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, Vector<String> dirs = EditorSettings::get_singleton()->get_favorites(); if (drag_data.has("type") && String(drag_data["type"]) == "favorite") { - // Moving favorite around + // Moving favorite around. TreeItem *ti = tree->get_item_at_position(p_point); if (!ti) return; @@ -1841,20 +1949,20 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, TreeItem *resources_item = favorites_item->get_next(); if (ti == favorites_item) { - // Drop on the favorite folder + // Drop on the favorite folder. drop_position = 0; } else if (ti == resources_item) { - // Drop on the resouce item + // Drop on the resource item. drop_position = dirs.size(); } else { - // Drop in the list + // Drop in the list. drop_position = dirs.find(ti->get_metadata(0)); if (drop_section == 1) { drop_position++; } } - // Remove dragged favorites + // Remove dragged favorites. Vector<int> to_remove; int offset = 0; for (int i = 0; i < files.size(); i++) { @@ -1870,7 +1978,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, dirs.remove(to_remove[i] - i); } - // Re-add them at the right position + // Re-add them at the right position. for (int i = 0; i < files.size(); i++) { dirs.insert(drop_position, files[i]); drop_position++; @@ -1885,7 +1993,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - // Moving resource + // Moving resource. Ref<Resource> res = drag_data["resource"]; String to_dir; bool favorite; @@ -1897,7 +2005,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } if (drag_data.has("type") && (String(drag_data["type"]) == "files" || String(drag_data["type"]) == "files_and_dirs")) { - // Move files or add to favorites + // Move files or add to favorites. String to_dir; bool favorite; _get_drag_target_folder(to_dir, favorite, p_point, p_from); @@ -1927,7 +2035,7 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori target = String(); target_favorites = false; - // In the file list + // In the file list. if (p_from == files) { int pos = files->get_item_at_position(p_point, true); if (pos == -1) { @@ -1939,12 +2047,12 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori return; } - // In the tree + // In the tree. if (p_from == tree) { TreeItem *ti = tree->get_item_at_position(p_point); int section = tree->get_drop_section_at_position(p_point); if (ti) { - // Check the favorites first + // Check the favorites first. if (ti == tree->get_root()->get_children() && section >= 0) { target_favorites = true; return; @@ -1955,13 +2063,13 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori String fpath = ti->get_metadata(0); if (section == 0) { if (fpath.ends_with("/")) { - // We drop on a folder + // We drop on a folder. target = fpath; return; } } else { if (ti->get_parent() != tree->get_root()->get_children()) { - // Not in the favorite section + // Not in the favorite section. if (fpath != "res://") { // We drop between two files if (fpath.ends_with("/")) { @@ -1975,13 +2083,11 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori } } } - - return; } void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<String> p_paths, bool p_display_path_dependent_options) { - // Add options for files and folders - ERR_FAIL_COND(p_paths.empty()) + // Add options for files and folders. + ERR_FAIL_COND(p_paths.empty()); Vector<String> filenames; Vector<String> foldernames; @@ -2004,7 +2110,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str all_files_scenes &= (EditorFileSystem::get_singleton()->get_file_type(fpath) == "PackedScene"); } - // Check if in favorites + // Check if in favorites. bool found = false; for (int j = 0; j < favorites.size(); j++) { if (favorites[j] == fpath) { @@ -2020,14 +2126,16 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str } if (all_files) { - - if (all_files_scenes && filenames.size() >= 1) { - p_popup->add_item(TTR("Open Scene(s)"), FILE_OPEN); + if (all_files_scenes) { + if (filenames.size() == 1) { + p_popup->add_item(TTR("Open Scene"), FILE_OPEN); + p_popup->add_item(TTR("New Inherited Scene"), FILE_INHERIT); + } else { + p_popup->add_item(TTR("Open Scenes"), FILE_OPEN); + } p_popup->add_item(TTR("Instance"), FILE_INSTANCE); p_popup->add_separator(); - } - - if (!all_files_scenes && filenames.size() == 1) { + } else if (filenames.size() == 1) { p_popup->add_item(TTR("Open"), FILE_OPEN); p_popup->add_separator(); } @@ -2035,10 +2143,10 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str if (p_paths.size() >= 1) { if (!all_favorites) { - p_popup->add_item(TTR("Add to favorites"), FILE_ADD_FAVORITE); + p_popup->add_item(TTR("Add to Favorites"), FILE_ADD_FAVORITE); } if (!all_not_favorites) { - p_popup->add_item(TTR("Remove from favorites"), FILE_REMOVE_FAVORITE); + p_popup->add_item(TTR("Remove from Favorites"), FILE_REMOVE_FAVORITE); } p_popup->add_separator(); } @@ -2057,19 +2165,25 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str if (p_paths.size() == 1) { p_popup->add_item(TTR("Copy Path"), FILE_COPY_PATH); - p_popup->add_item(TTR("Rename..."), FILE_RENAME); - p_popup->add_item(TTR("Duplicate..."), FILE_DUPLICATE); + if (p_paths[0] != "res://") { + p_popup->add_item(TTR("Rename..."), FILE_RENAME); + p_popup->add_item(TTR("Duplicate..."), FILE_DUPLICATE); + } } - p_popup->add_item(TTR("Move To..."), FILE_MOVE); - p_popup->add_item(TTR("Delete"), FILE_REMOVE); + if (p_paths.size() > 1 || p_paths[0] != "res://") { + p_popup->add_item(TTR("Move To..."), FILE_MOVE); + p_popup->add_item(TTR("Delete"), FILE_REMOVE); + } if (p_paths.size() == 1) { p_popup->add_separator(); if (p_display_path_dependent_options) { p_popup->add_item(TTR("New Folder..."), FILE_NEW_FOLDER); + p_popup->add_item(TTR("New Scene..."), FILE_NEW_SCENE); p_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT); p_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE); + p_popup->add_separator(); } String fpath = p_paths[0]; @@ -2079,8 +2193,8 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str } void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) { - // Right click is pressed in the tree - Vector<String> paths = _tree_get_selected(); + // Right click is pressed in the tree. + Vector<String> paths = _tree_get_selected(false); if (paths.size() == 1) { if (paths[0].ends_with("/")) { @@ -2090,7 +2204,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) { } } - // Popup + // Popup. if (!paths.empty()) { tree_popup->clear(); tree_popup->set_size(Size2(1, 1)); @@ -2100,8 +2214,25 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) { } } +void FileSystemDock::_tree_rmb_empty(const Vector2 &p_pos) { + // Right click is pressed in the empty space of the tree. + path = "res://"; + tree_popup->clear(); + tree_popup->set_size(Size2(1, 1)); + tree_popup->add_item(TTR("New Folder..."), FILE_NEW_FOLDER); + tree_popup->add_item(TTR("New Scene..."), FILE_NEW_SCENE); + tree_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT); + tree_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE); + tree_popup->set_position(tree->get_global_position() + p_pos); + tree_popup->popup(); +} + +void FileSystemDock::_tree_empty_selected() { + tree->deselect_all(); +} + void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) { - // Right click is pressed in the file list + // Right click is pressed in the file list. Vector<String> paths; for (int i = 0; i < files->get_item_count(); i++) { if (!files->is_selected(i)) @@ -2113,7 +2244,7 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) { paths.push_back(files->get_item_metadata(i)); } - // Popup + // Popup. if (!paths.empty()) { file_list_popup->clear(); file_list_popup->set_size(Size2(1, 1)); @@ -2124,7 +2255,7 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) { } void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) { - // Right click on empty space for file list + // Right click on empty space for file list. if (searched_string.length() > 0) return; @@ -2132,21 +2263,21 @@ void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) { file_list_popup->set_size(Size2(1, 1)); file_list_popup->add_item(TTR("New Folder..."), FILE_NEW_FOLDER); + file_list_popup->add_item(TTR("New Scene..."), FILE_NEW_SCENE); file_list_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT); file_list_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE); - file_list_popup->add_item(TTR("Show in File Manager"), FILE_SHOW_IN_EXPLORER); + file_list_popup->add_separator(); + file_list_popup->add_item(TTR("Open in File Manager"), FILE_SHOW_IN_EXPLORER); file_list_popup->set_position(files->get_global_position() + p_pos); file_list_popup->popup(); } void FileSystemDock::select_file(const String &p_file) { - - navigate_to_path(p_file); + _navigate_to_path(p_file); } void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) { - - // Set the path to the current focussed item + // Set the path to the current focused item. int current = files->get_current(); if (current == p_index) { String fpath = files->get_item_metadata(current); @@ -2158,15 +2289,14 @@ void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) { } } - // Update the import dock + // Update the import dock. import_dock_needs_update = true; call_deferred("_update_import_dock"); } void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { - if (get_viewport()->get_modal_stack_top()) - return; //ignore because of modal window + return; // Ignore because of modal window. Ref<InputEventKey> key = p_event; if (key.is_valid() && key->is_pressed() && !key->is_echo()) { @@ -2183,9 +2313,8 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { } void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) { - if (get_viewport()->get_modal_stack_top()) - return; //ignore because of modal window + return; // Ignore because of modal window. Ref<InputEventKey> key = p_event; if (key.is_valid() && key->is_pressed() && !key->is_echo()) { @@ -2202,18 +2331,17 @@ void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) { } void FileSystemDock::_update_import_dock() { - if (!import_dock_needs_update) return; - // List selected + // List selected. Vector<String> selected; - if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) { + if (display_mode == DISPLAY_MODE_TREE_ONLY) { // Use the tree selected = _tree_get_selected(); } else { - // Use the file list + // Use the file list. for (int i = 0; i < files->get_item_count(); i++) { if (!files->is_selected(i)) continue; @@ -2222,7 +2350,7 @@ void FileSystemDock::_update_import_dock() { } } - // Check import + // Check import. Vector<String> imports; String import_type; for (int i = 0; i < selected.size(); i++) { @@ -2249,7 +2377,7 @@ void FileSystemDock::_update_import_dock() { if (import_type == "") { import_type = type; } else if (import_type != type) { - //all should be the same type + // All should be the same type. imports.clear(); break; } @@ -2267,8 +2395,11 @@ void FileSystemDock::_update_import_dock() { import_dock_needs_update = false; } -void FileSystemDock::_bind_methods() { +void FileSystemDock::_feature_profile_changed() { + _update_display_mode(true); +} +void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_file_list_gui_input"), &FileSystemDock::_file_list_gui_input); ClassDB::bind_method(D_METHOD("_tree_gui_input"), &FileSystemDock::_tree_gui_input); @@ -2278,11 +2409,13 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_toggle_split_mode"), &FileSystemDock::_toggle_split_mode); ClassDB::bind_method(D_METHOD("_tree_rmb_option", "option"), &FileSystemDock::_tree_rmb_option); - ClassDB::bind_method(D_METHOD("_file_list_rmb_option", "option"), &FileSystemDock::_file_list_rmb_option); - ClassDB::bind_method(D_METHOD("_tree_rmb_select"), &FileSystemDock::_tree_rmb_select); + ClassDB::bind_method(D_METHOD("_tree_empty_selected"), &FileSystemDock::_tree_empty_selected); + + ClassDB::bind_method(D_METHOD("_file_list_rmb_option", "option"), &FileSystemDock::_file_list_rmb_option); ClassDB::bind_method(D_METHOD("_file_list_rmb_select"), &FileSystemDock::_file_list_rmb_select); ClassDB::bind_method(D_METHOD("_file_list_rmb_pressed"), &FileSystemDock::_file_list_rmb_pressed); + ClassDB::bind_method(D_METHOD("_tree_rmb_empty"), &FileSystemDock::_tree_rmb_empty); ClassDB::bind_method(D_METHOD("_file_deleted"), &FileSystemDock::_file_deleted); ClassDB::bind_method(D_METHOD("_folder_deleted"), &FileSystemDock::_folder_deleted); @@ -2292,13 +2425,14 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_file_list_activate_file"), &FileSystemDock::_file_list_activate_file); ClassDB::bind_method(D_METHOD("_tree_activate_file"), &FileSystemDock::_tree_activate_file); ClassDB::bind_method(D_METHOD("_select_file"), &FileSystemDock::_select_file); - ClassDB::bind_method(D_METHOD("navigate_to_path"), &FileSystemDock::navigate_to_path); - ClassDB::bind_method(D_METHOD("_change_file_display"), &FileSystemDock::_change_file_display); + ClassDB::bind_method(D_METHOD("_navigate_to_path"), &FileSystemDock::_navigate_to_path, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("_toggle_file_display"), &FileSystemDock::_toggle_file_display); ClassDB::bind_method(D_METHOD("_fw_history"), &FileSystemDock::_fw_history); ClassDB::bind_method(D_METHOD("_bw_history"), &FileSystemDock::_bw_history); ClassDB::bind_method(D_METHOD("_fs_changed"), &FileSystemDock::_fs_changed); ClassDB::bind_method(D_METHOD("_tree_multi_selected"), &FileSystemDock::_tree_multi_selected); ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileSystemDock::_make_dir_confirm); + ClassDB::bind_method(D_METHOD("_make_scene_confirm"), &FileSystemDock::_make_scene_confirm); ClassDB::bind_method(D_METHOD("_resource_created"), &FileSystemDock::_resource_created); ClassDB::bind_method(D_METHOD("_move_operation_confirm", "to_path", "overwrite"), &FileSystemDock::_move_operation_confirm, DEFVAL(false)); ClassDB::bind_method(D_METHOD("_move_with_overwrite"), &FileSystemDock::_move_with_overwrite); @@ -2310,22 +2444,26 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &FileSystemDock::get_drag_data_fw); ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &FileSystemDock::can_drop_data_fw); ClassDB::bind_method(D_METHOD("drop_data_fw"), &FileSystemDock::drop_data_fw); + ClassDB::bind_method(D_METHOD("navigate_to_path"), &FileSystemDock::navigate_to_path); ClassDB::bind_method(D_METHOD("_preview_invalidated"), &FileSystemDock::_preview_invalidated); ClassDB::bind_method(D_METHOD("_file_multi_selected"), &FileSystemDock::_file_multi_selected); ClassDB::bind_method(D_METHOD("_update_import_dock"), &FileSystemDock::_update_import_dock); + ClassDB::bind_method(D_METHOD("_feature_profile_changed"), &FileSystemDock::_feature_profile_changed); + + ADD_SIGNAL(MethodInfo("inherit", PropertyInfo(Variant::STRING, "file"))); ADD_SIGNAL(MethodInfo("instance", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"))); - ADD_SIGNAL(MethodInfo("open")); ADD_SIGNAL(MethodInfo("file_removed", PropertyInfo(Variant::STRING, "file"))); ADD_SIGNAL(MethodInfo("folder_removed", PropertyInfo(Variant::STRING, "folder"))); ADD_SIGNAL(MethodInfo("files_moved", PropertyInfo(Variant::STRING, "old_file"), PropertyInfo(Variant::STRING, "new_file"))); ADD_SIGNAL(MethodInfo("folder_moved", PropertyInfo(Variant::STRING, "old_folder"), PropertyInfo(Variant::STRING, "new_file"))); + + ADD_SIGNAL(MethodInfo("display_mode_changed")); } FileSystemDock::FileSystemDock(EditorNode *p_editor) { - set_name("FileSystem"); editor = p_editor; path = "res://"; @@ -2345,13 +2483,13 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { button_hist_prev = memnew(ToolButton); button_hist_prev->set_disabled(true); button_hist_prev->set_focus_mode(FOCUS_NONE); - button_hist_prev->set_tooltip(TTR("Previous Directory")); + button_hist_prev->set_tooltip(TTR("Previous Folder/File")); toolbar_hbc->add_child(button_hist_prev); button_hist_next = memnew(ToolButton); button_hist_next->set_disabled(true); button_hist_next->set_focus_mode(FOCUS_NONE); - button_hist_next->set_tooltip(TTR("Next Directory")); + button_hist_next->set_tooltip(TTR("Next Folder/File")); toolbar_hbc->add_child(button_hist_next); current_path = memnew(LineEdit); @@ -2372,7 +2510,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { button_toggle_display_mode->set_toggle_mode(true); button_toggle_display_mode->connect("toggled", this, "_toggle_split_mode"); button_toggle_display_mode->set_focus_mode(FOCUS_NONE); - button_toggle_display_mode->set_tooltip(TTR("Toggle split mode")); + button_toggle_display_mode->set_tooltip(TTR("Toggle Split Mode")); toolbar_hbc->add_child(button_toggle_display_mode); HBoxContainer *toolbar2_hbc = memnew(HBoxContainer); @@ -2385,29 +2523,6 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { tree_search_box->connect("text_changed", this, "_search_changed", varray(tree_search_box)); toolbar2_hbc->add_child(tree_search_box); - //toolbar_hbc->add_spacer(); - - //Control *spacer = memnew( Control); - - /* - button_open = memnew( Button ); - button_open->set_flat(true); - button_open->connect("pressed",this,"_tree_toggle_collapsed"); - toolbar_hbc->add_child(button_open); - button_open->hide(); - button_open->set_focus_mode(FOCUS_NONE); - button_open->set_tooltip("Open the selected file.\nOpen as scene if a scene, or as resource otherwise."); - - - button_instance = memnew( Button ); - button_instance->set_flat(true); - button_instance->connect("pressed",this,"_instance_pressed"); - toolbar_hbc->add_child(button_instance); - button_instance->hide(); - button_instance->set_focus_mode(FOCUS_NONE); - button_instance->set_tooltip(TTR("Instance the selected scene(s) as child of the selected node.")); - -*/ file_list_popup = memnew(PopupMenu); file_list_popup->set_hide_on_window_lose_focus(true); add_child(file_list_popup); @@ -2429,10 +2544,11 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { tree->set_custom_minimum_size(Size2(0, 15 * EDSCALE)); split_box->add_child(tree); - tree->connect("item_edited", this, "_favorite_toggled"); tree->connect("item_activated", this, "_tree_activate_file"); tree->connect("multi_selected", this, "_tree_multi_selected"); tree->connect("item_rmb_selected", this, "_tree_rmb_select"); + tree->connect("empty_rmb", this, "_tree_rmb_empty"); + tree->connect("nothing_selected", this, "_tree_empty_selected"); tree->connect("gui_input", this, "_tree_gui_input"); file_list_vb = memnew(VBoxContainer); @@ -2449,7 +2565,6 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { path_hb->add_child(file_list_search_box); button_file_list_display_mode = memnew(ToolButton); - button_file_list_display_mode->set_toggle_mode(true); path_hb->add_child(button_file_list_display_mode); files = memnew(ItemList); @@ -2531,6 +2646,17 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { make_dir_dialog->register_text_enter(make_dir_dialog_text); make_dir_dialog->connect("confirmed", this, "_make_dir_confirm"); + make_scene_dialog = memnew(ConfirmationDialog); + make_scene_dialog->set_title(TTR("Create Scene")); + VBoxContainer *make_scene_dialog_vb = memnew(VBoxContainer); + make_scene_dialog->add_child(make_scene_dialog_vb); + + make_scene_dialog_text = memnew(LineEdit); + make_scene_dialog_vb->add_margin_child(TTR("Name:"), make_scene_dialog_text); + add_child(make_scene_dialog); + make_scene_dialog->register_text_enter(make_scene_dialog_text); + make_scene_dialog->connect("confirmed", this, "_make_scene_confirm"); + make_script_dialog_text = memnew(ScriptCreateDialog); make_script_dialog_text->set_title(TTR("Create Script")); add_child(make_script_dialog_text); @@ -2552,11 +2678,10 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { history_max_size = 20; history.push_back("res://"); - display_mode = DISPLAY_MODE_SPLIT; + display_mode = DISPLAY_MODE_TREE_ONLY; + old_display_mode = DISPLAY_MODE_TREE_ONLY; file_list_display_mode = FILE_LIST_DISPLAY_THUMBNAILS; - display_mode_setting = DISPLAY_MODE_SETTING_TREE_ONLY; - old_display_mode_setting = DISPLAY_MODE_SETTING_TREE_ONLY; always_show_folders = false; } |