diff options
Diffstat (limited to 'editor/filesystem_dock.cpp')
| -rw-r--r-- | editor/filesystem_dock.cpp | 296 |
1 files changed, 231 insertions, 65 deletions
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 3625c14740..41356c1d56 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -42,12 +42,13 @@ #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/import_dock.h" #include "editor/scene_tree_dock.h" -#include "import_dock.h" +#include "editor/shader_create_dialog.h" +#include "scene/gui/label.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" #include "servers/display_server.h" -#include "shader_create_dialog.h" FileSystemDock *FileSystemDock::singleton = nullptr; @@ -72,7 +73,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory } subdirectory_item->set_text(0, dname); - subdirectory_item->set_structured_text_bidi_override(0, STRUCTURED_TEXT_FILE); + subdirectory_item->set_structured_text_bidi_override(0, TextServer::STRUCTURED_TEXT_FILE); subdirectory_item->set_icon(0, get_theme_icon(SNAME("Folder"), SNAME("EditorIcons"))); subdirectory_item->set_icon_modulate(0, get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog"))); subdirectory_item->set_selectable(0, true); @@ -142,7 +143,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory for (const FileInfo &fi : file_list) { TreeItem *file_item = tree->create_item(subdirectory_item); file_item->set_text(0, fi.name); - file_item->set_structured_text_bidi_override(0, STRUCTURED_TEXT_FILE); + file_item->set_structured_text_bidi_override(0, TextServer::STRUCTURED_TEXT_FILE); file_item->set_icon(0, _get_tree_item_icon(!fi.import_broken, fi.type)); String file_metadata = lpath.plus_file(fi.name); file_item->set_metadata(0, file_metadata); @@ -223,6 +224,20 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo favorites->set_collapsed(p_uncollapsed_paths.find("Favorites") < 0); Vector<String> favorite_paths = EditorSettings::get_singleton()->get_favorites(); + + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + bool fav_changed = false; + for (int i = favorite_paths.size() - 1; i >= 0; i--) { + if (da->dir_exists(favorite_paths[i]) || da->file_exists(favorite_paths[i])) { + continue; + } + favorite_paths.remove_at(i); + fav_changed = true; + } + if (fav_changed) { + EditorSettings::get_singleton()->set_favorites(favorite_paths); + } + for (int i = 0; i < favorite_paths.size(); i++) { String fave = favorite_paths[i]; if (!fave.begins_with("res://")) { @@ -395,12 +410,25 @@ void FileSystemDock::_notification(int p_what) { } } else if ((String(dd["type"]) == "files") || (String(dd["type"]) == "files_and_dirs") || (String(dd["type"]) == "resource")) { tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM | Tree::DROP_MODE_INBETWEEN); + } else if ((String(dd["type"]) == "nodes")) { + holding_branch = true; + TreeItem *item = tree->get_next_selected(tree->get_root()); + while (item) { + tree_items_selected_on_drag_begin.push_back(item); + item = tree->get_next_selected(item); + } + list_items_selected_on_drag_begin = files->get_selected_items(); } } } break; case NOTIFICATION_DRAG_END: { tree->set_drop_mode_flags(0); + + if (holding_branch) { + holding_branch = false; + _reselect_items_selected_on_drag_begin(true); + } } break; case NOTIFICATION_THEME_CHANGED: { @@ -511,16 +539,14 @@ void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_fa if (target_path.ends_with("/")) { target_path = target_path.substr(0, target_path.length() - 1); } - DirAccess *dirAccess = DirAccess::open("res://"); - if (dirAccess->file_exists(p_path)) { + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + if (da->file_exists(p_path)) { path = target_path; - } else if (dirAccess->dir_exists(p_path)) { + } else if (da->dir_exists(p_path)) { path = target_path + "/"; } else { - 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); @@ -767,14 +793,14 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { icon = folder_icon; if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { files->add_item(text, icon, true); - files->set_item_metadata(files->get_item_count() - 1, favorite); + files->set_item_metadata(-1, favorite); } } else if (favorite.ends_with("/")) { text = favorite.substr(0, favorite.length() - 1).get_file(); icon = folder_icon; if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { files->add_item(text, icon, true); - files->set_item_metadata(files->get_item_count() - 1, favorite); + files->set_item_metadata(-1, favorite); } } else { int index; @@ -828,9 +854,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { bd += "/"; } - 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); + files->set_item_metadata(-1, bd); + files->set_item_selectable(-1, false); + files->set_item_icon_modulate(-1, folder_color); } bool reversed = file_sort == FILE_SORT_NAME_REVERSE; @@ -840,8 +866,8 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { 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); + files->set_item_metadata(-1, directory.plus_file(dname) + "/"); + files->set_item_icon_modulate(-1, folder_color); if (cselection.has(dname)) { files->select(files->get_item_count() - 1, false); @@ -963,7 +989,7 @@ void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorit { List<String> importer_exts; - ResourceImporterScene::get_singleton()->get_recognized_extensions(&importer_exts); + ResourceImporterScene::get_scene_singleton()->get_recognized_extensions(&importer_exts); String extension = fpath.get_extension(); for (const String &E : importer_exts) { if (extension.nocasecmp_to(E) == 0) { @@ -974,12 +1000,32 @@ void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorit } if (is_imported) { - ResourceImporterScene::get_singleton()->show_advanced_options(fpath); + ResourceImporterScene::get_scene_singleton()->show_advanced_options(fpath); } else { - editor->open_request(fpath); + EditorNode::get_singleton()->open_request(fpath); + } + } else if (ResourceLoader::get_resource_type(fpath) == "AnimationLibrary") { + bool is_imported = false; + + { + List<String> importer_exts; + ResourceImporterScene::get_animation_singleton()->get_recognized_extensions(&importer_exts); + String extension = fpath.get_extension(); + for (const String &E : importer_exts) { + if (extension.nocasecmp_to(E) == 0) { + is_imported = true; + break; + } + } + } + + if (is_imported) { + ResourceImporterScene::get_animation_singleton()->show_advanced_options(fpath); + } else { + EditorNode::get_singleton()->open_request(fpath); } } else { - editor->load_resource(fpath); + EditorNode::get_singleton()->load_resource(fpath); } } _navigate_to_path(fpath, p_select_in_favorites); @@ -1157,7 +1203,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ _get_all_items_in_dir(EditorFileSystem::get_singleton()->get_filesystem_path(old_path), file_changed_paths, folder_changed_paths); } - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); print_verbose("Moving " + old_path + " -> " + new_path); Error err = da->rename(old_path, new_path); if (err == OK) { @@ -1172,12 +1218,12 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ // 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])) { - EditorData *ed = &editor->get_editor_data(); + if (ResourceLoader::get_resource_type(new_item_path) == "PackedScene" && EditorNode::get_singleton()->is_scene_open(file_changed_paths[i])) { + EditorData *ed = &EditorNode::get_singleton()->get_editor_data(); 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_scene_file_path(new_item_path); - editor->save_layout(); + EditorNode::get_singleton()->save_layout(); break; } } @@ -1197,7 +1243,6 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ } else { EditorNode::get_singleton()->add_io_error(TTR("Error moving:") + "\n" + old_path + "\n"); } - memdelete(da); } void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const { @@ -1216,7 +1261,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin return; } - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); 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) { @@ -1235,7 +1280,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin cfg->save(new_path + ".import"); } else if (p_item.is_file && (old_path.get_extension() == "tscn" || old_path.get_extension() == "tres")) { // FIXME: Quick hack to fix text resources. This should be fixed properly. - FileAccessRef file = FileAccess::open(old_path, FileAccess::READ, &err); + Ref<FileAccess> file = FileAccess::open(old_path, FileAccess::READ, &err); if (err == OK) { PackedStringArray lines = file->get_as_utf8_string().split("\n"); String line = lines[0]; @@ -1244,7 +1289,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin line = line.substr(0, line.find(" uid")) + "]"; lines.write[0] = line; - FileAccessRef file2 = FileAccess::open(new_path, FileAccess::WRITE, &err); + Ref<FileAccess> file2 = FileAccess::open(new_path, FileAccess::WRITE, &err); if (err == OK) { file2->store_string(String("\n").join(lines)); } @@ -1254,7 +1299,6 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin } else { EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + "\n"); } - memdelete(da); } void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> &p_renames) const { @@ -1315,7 +1359,7 @@ void FileSystemDock::_update_dependencies_after_move(const Map<String, String> & Error err = ResourceLoader::rename_dependencies(file, p_renames); if (err == OK) { if (ResourceLoader::get_resource_type(file) == "PackedScene") { - editor->reload_scene(file); + EditorNode::get_singleton()->reload_scene(file); } } else { EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies:") + "\n" + remaps[i] + "\n"); @@ -1384,7 +1428,7 @@ void FileSystemDock::_save_scenes_after_move(const Map<String, String> &p_rename } } - editor->save_scene_list(new_filenames); + EditorNode::get_singleton()->save_scene_list(new_filenames); } void FileSystemDock::_make_dir_confirm() { @@ -1403,13 +1447,18 @@ void FileSystemDock::_make_dir_confirm() { if (!directory.ends_with("/")) { directory = directory.get_base_dir(); } + print_verbose("Making folder " + dir_name + " in " + directory); - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); Error err = da->change_dir(directory); - if (err == OK) { - err = da->make_dir(dir_name); + ERR_FAIL_COND_MSG(err != OK, "Cannot open directory '" + directory + "'."); + + if (da->dir_exists(dir_name)) { + EditorNode::get_singleton()->show_warning(TTR("Could not create folder. File with that name already exists.")); + return; } - memdelete(da); + + err = da->make_dir(dir_name); if (err == OK) { print_verbose("FileSystem: calling rescan."); @@ -1450,16 +1499,14 @@ void FileSystemDock::_make_scene_confirm() { scene_name = directory.plus_file(scene_name); - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Ref<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); + int idx = EditorNode::get_singleton()->new_scene(); + EditorNode::get_singleton()->get_editor_data().set_scene_path(idx, scene_name); } void FileSystemDock::_file_removed(String p_file) { @@ -1467,7 +1514,7 @@ void FileSystemDock::_file_removed(String p_file) { // Find the closest parent directory available, in case multiple items were deleted along the same path. path = p_file.get_base_dir(); - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); while (!da->dir_exists(path)) { path = path.get_base_dir(); } @@ -1480,7 +1527,7 @@ void FileSystemDock::_folder_removed(String p_folder) { // Find the closest parent directory available, in case multiple items were deleted along the same path. path = p_folder.get_base_dir(); - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); while (!da->dir_exists(path)) { path = path.get_base_dir(); } @@ -1519,7 +1566,7 @@ void FileSystemDock::_rename_operation_confirm() { } // Present a more user friendly warning for name conflict. - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); #if defined(WINDOWS_ENABLED) || defined(UWP_ENABLED) // Workaround case insensitivity on Windows. if ((da->file_exists(new_path) || da->dir_exists(new_path)) && new_path.to_lower() != old_path.to_lower()) { @@ -1527,23 +1574,21 @@ void FileSystemDock::_rename_operation_confirm() { if (da->file_exists(new_path) || da->dir_exists(new_path)) { #endif EditorNode::get_singleton()->show_warning(TTR("A file or folder with this name already exists.")); - memdelete(da); return; } - memdelete(da); 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(); + int current_tab = EditorNode::get_singleton()->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); + EditorNode::get_singleton()->set_current_tab(current_tab); print_verbose("FileSystem: calling rescan."); _rescan(); @@ -1574,13 +1619,11 @@ void FileSystemDock::_duplicate_operation_confirm() { 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); + Ref<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.")); - memdelete(da); return; } - memdelete(da); _try_duplicate_item(to_duplicate, new_path); @@ -1647,14 +1690,14 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_ove } if (is_moved) { - int current_tab = editor->get_current_tab(); + int current_tab = EditorNode::get_singleton()->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); + EditorNode::get_singleton()->set_current_tab(current_tab); print_verbose("FileSystem: calling rescan."); _rescan(); @@ -1982,6 +2025,16 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } } break; + case FILE_COPY_UID: { + if (!p_selected.is_empty()) { + ResourceUID::ID uid = ResourceLoader::get_resource_uid(p_selected[0]); + if (uid != ResourceUID::INVALID_ID) { + String uid_string = ResourceUID::get_singleton()->id_to_text(uid); + DisplayServer::get_singleton()->clipboard_set(uid_string); + } + } + } break; + case FILE_NEW_RESOURCE: { new_resource_dialog->popup_create(true); } break; @@ -2026,8 +2079,8 @@ void FileSystemDock::_resource_created() { memdelete(node); } - editor->push_item(r); - editor->save_resource_as(RES(r), fpath); + EditorNode::get_singleton()->push_item(r); + EditorNode::get_singleton()->save_resource_as(Ref<Resource>(r), fpath); } void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) { @@ -2084,6 +2137,10 @@ void FileSystemDock::focus_on_filter() { } } +ScriptCreateDialog *FileSystemDock::get_script_create_dialog() const { + return make_script_dialog; +} + void FileSystemDock::set_file_list_display_mode(FileListDisplayMode p_mode) { if (p_mode == file_list_display_mode) { return; @@ -2327,7 +2384,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } int exist_counter = 1; - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); while (da->file_exists(new_path) || da->dir_exists(new_path)) { exist_counter++; new_path = vformat(new_path_base, exist_counter); @@ -2503,6 +2560,9 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str if (p_paths.size() == 1) { p_popup->add_icon_shortcut(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/copy_path"), FILE_COPY_PATH); + if (ResourceLoader::get_resource_uid(p_paths[0]) != ResourceUID::INVALID_ID) { + p_popup->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/copy_uid"), FILE_COPY_UID); + } if (p_paths[0] != "res://") { p_popup->add_icon_shortcut(get_theme_icon(SNAME("Rename"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/rename"), FILE_RENAME); p_popup->add_icon_shortcut(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/duplicate"), FILE_DUPLICATE); @@ -2646,13 +2706,86 @@ void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) { call_deferred(SNAME("_update_import_dock")); } +void FileSystemDock::_tree_mouse_exited() { + if (holding_branch) { + _reselect_items_selected_on_drag_begin(); + } +} + +void FileSystemDock::_reselect_items_selected_on_drag_begin(bool reset) { + TreeItem *selected_item = tree->get_next_selected(tree->get_root()); + if (selected_item) { + selected_item->deselect(0); + } + if (!tree_items_selected_on_drag_begin.is_empty()) { + bool reselected = false; + for (TreeItem *item : tree_items_selected_on_drag_begin) { + if (item->get_tree()) { + item->select(0); + reselected = true; + } + } + + if (reset) { + tree_items_selected_on_drag_begin.clear(); + } + + if (!reselected) { + // If couldn't reselect the items selected on drag begin, select the "res://" item. + tree->get_root()->get_child(1)->select(0); + } + } + + files->deselect_all(); + if (!list_items_selected_on_drag_begin.is_empty()) { + for (const int idx : list_items_selected_on_drag_begin) { + files->select(idx, false); + } + + if (reset) { + list_items_selected_on_drag_begin.clear(); + } + } +} + void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { Ref<InputEventKey> key = p_event; + + Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid()) { + TreeItem *item = tree->get_item_at_position(mm->get_position()); + if (item && holding_branch) { + String fpath = item->get_metadata(0); + while (!fpath.ends_with("/") && fpath != "res://" && item->get_parent()) { // Find the parent folder tree item. + item = item->get_parent(); + fpath = item->get_metadata(0); + } + + TreeItem *deselect_item = tree->get_next_selected(tree->get_root()); + while (deselect_item) { + deselect_item->deselect(0); + deselect_item = tree->get_next_selected(deselect_item); + } + item->select(0); + + if (display_mode == DisplayMode::DISPLAY_MODE_SPLIT) { + files->deselect_all(); + // Try to select the corresponding file list item. + const int files_item_idx = files->find_metadata(fpath); + if (files_item_idx != -1) { + files->select(files_item_idx); + } + } + } + } + if (key.is_valid() && key->is_pressed() && !key->is_echo()) { if (ED_IS_SHORTCUT("filesystem_dock/duplicate", p_event)) { _tree_rmb_option(FILE_DUPLICATE); } else if (ED_IS_SHORTCUT("filesystem_dock/copy_path", p_event)) { _tree_rmb_option(FILE_COPY_PATH); + } else if (ED_IS_SHORTCUT("filesystem_dock/copy_uid", p_event)) { + _tree_rmb_option(FILE_COPY_UID); } else if (ED_IS_SHORTCUT("filesystem_dock/delete", p_event)) { _tree_rmb_option(FILE_REMOVE); } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { @@ -2668,6 +2801,43 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { } void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) { + Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid() && holding_branch) { + const int item_idx = files->get_item_at_position(mm->get_position()); + if (item_idx != -1) { + files->deselect_all(); + String fpath = files->get_item_metadata(item_idx); + if (fpath.ends_with("/") || fpath == "res://") { + files->select(item_idx); + } + + TreeItem *deselect_item = tree->get_next_selected(tree->get_root()); + while (deselect_item) { + deselect_item->deselect(0); + deselect_item = tree->get_next_selected(deselect_item); + } + + // Try to select the corresponding tree item. + TreeItem *tree_item = tree->get_item_with_text(files->get_item_text(item_idx)); + if (tree_item) { + tree_item->select(0); + } else { + // Find parent folder. + fpath = fpath.substr(0, fpath.rfind("/") + 1); + if (fpath.size() > String("res://").size()) { + fpath = fpath.left(fpath.size() - 2); // Remove last '/'. + const int slash_idx = fpath.rfind("/"); + fpath = fpath.substr(slash_idx + 1, fpath.size() - slash_idx - 1); + } + + tree_item = tree->get_item_with_text(fpath); + if (tree_item) { + tree_item->select(0); + } + } + } + } + Ref<InputEventKey> key = p_event; if (key.is_valid() && key->is_pressed() && !key->is_echo()) { if (ED_IS_SHORTCUT("filesystem_dock/duplicate", p_event)) { @@ -2696,7 +2866,7 @@ void FileSystemDock::_get_imported_files(const String &p_path, Vector<String> &f return; } - DirAccess *da = DirAccess::open(p_path); + Ref<DirAccess> da = DirAccess::open(p_path); da->list_dir_begin(); String n = da->get_next(); while (!n.is_empty()) { @@ -2837,14 +3007,14 @@ void FileSystemDock::_bind_methods() { ADD_SIGNAL(MethodInfo("display_mode_changed")); } -FileSystemDock::FileSystemDock(EditorNode *p_editor) { +FileSystemDock::FileSystemDock() { singleton = this; set_name("FileSystem"); - editor = p_editor; path = "res://"; // `KeyModifierMask::CMD | Key::C` conflicts with other editor shortcuts. ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::C); + ED_SHORTCUT("filesystem_dock/copy_uid", TTR("Copy UID")); ED_SHORTCUT("filesystem_dock/duplicate", TTR("Duplicate..."), KeyModifierMask::CMD | Key::D); ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), Key::KEY_DELETE); ED_SHORTCUT("filesystem_dock/rename", TTR("Rename..."), Key::F2); @@ -2872,7 +3042,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { toolbar_hbc->add_child(button_hist_next); current_path = memnew(LineEdit); - current_path->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE); + current_path->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE); current_path->set_h_size_flags(SIZE_EXPAND_FILL); _set_current_path_text(path); toolbar_hbc->add_child(current_path); @@ -2932,6 +3102,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { tree->connect("empty_rmb", callable_mp(this, &FileSystemDock::_tree_rmb_empty)); tree->connect("nothing_selected", callable_mp(this, &FileSystemDock::_tree_empty_selected)); tree->connect("gui_input", callable_mp(this, &FileSystemDock::_tree_gui_input)); + tree->connect("mouse_exited", callable_mp(this, &FileSystemDock::_tree_mouse_exited)); file_list_vb = memnew(VBoxContainer); file_list_vb->set_v_size_flags(SIZE_EXPAND_FILL); @@ -2980,7 +3151,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { deps_editor = memnew(DependencyEditor); add_child(deps_editor); - owners_editor = memnew(DependencyEditorOwners(editor)); + owners_editor = memnew(DependencyEditorOwners()); add_child(owners_editor); remove_dialog = memnew(DependencyRemoveDialog); @@ -3057,10 +3228,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { searched_string = String(); uncollapsed_paths_before_search = Vector<String>(); - updating_tree = false; tree_update_id = 0; - initialized = false; - import_dock_needs_update = false; history_pos = 0; history_max_size = 20; @@ -3069,8 +3237,6 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { display_mode = DISPLAY_MODE_TREE_ONLY; old_display_mode = DISPLAY_MODE_TREE_ONLY; file_list_display_mode = FILE_LIST_DISPLAY_THUMBNAILS; - - always_show_folders = false; } FileSystemDock::~FileSystemDock() { |