Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix folder moving in file system dock #81725

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 49 additions & 24 deletions editor/filesystem_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1363,15 +1363,15 @@ void FileSystemDock::_get_all_items_in_dir(EditorFileSystemDirectory *p_efsd, Ve
}
}

void FileSystemDock::_find_remaps(EditorFileSystemDirectory *p_efsd, const Vector<String> &r_renames, Vector<String> &r_to_remaps) const {
void FileSystemDock::_find_file_owners(EditorFileSystemDirectory *p_efsd, const Vector<String> &p_renames, Vector<String> &r_file_owners) const {
for (int i = 0; i < p_efsd->get_subdir_count(); i++) {
_find_remaps(p_efsd->get_subdir(i), r_renames, r_to_remaps);
_find_file_owners(p_efsd->get_subdir(i), p_renames, r_file_owners);
}
for (int i = 0; i < p_efsd->get_file_count(); i++) {
Vector<String> deps = p_efsd->get_file_deps(i);
for (int j = 0; j < deps.size(); j++) {
if (r_renames.has(deps[j])) {
r_to_remaps.push_back(p_efsd->get_file_path(i));
if (p_renames.has(deps[j])) {
r_file_owners.push_back(p_efsd->get_file_path(i));
Rindbee marked this conversation as resolved.
Show resolved Hide resolved
break;
}
}
Expand Down Expand Up @@ -1562,22 +1562,22 @@ void FileSystemDock::_update_resource_paths_after_move(const HashMap<String, Str
}
}

void FileSystemDock::_update_dependencies_after_move(const HashMap<String, String> &p_renames, const Vector<String> &p_remaps) const {
void FileSystemDock::_update_dependencies_after_move(const HashMap<String, String> &p_renames, const Vector<String> &p_file_owners) const {
// 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.
List<String> scenes_to_reload;
for (int i = 0; i < p_remaps.size(); ++i) {
for (int i = 0; i < p_file_owners.size(); ++i) {
// Because we haven't called a rescan yet the found remap might still be an old path itself.
String file = p_renames.has(p_remaps[i]) ? p_renames[p_remaps[i]] : p_remaps[i];
const String file = p_renames.has(p_file_owners[i]) ? p_renames[p_file_owners[i]] : p_file_owners[i];
print_verbose("Remapping dependencies for: " + file);
Error err = ResourceLoader::rename_dependencies(file, p_renames);
const Error err = ResourceLoader::rename_dependencies(file, p_renames);
if (err == OK) {
if (ResourceLoader::get_resource_type(file) == "PackedScene") {
scenes_to_reload.push_back(file);
}
} else {
EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies:") + "\n" + p_remaps[i] + "\n");
EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies for:") + "\n" + p_file_owners[i] + "\n");
}
}

Expand Down Expand Up @@ -1773,18 +1773,17 @@ void FileSystemDock::_rename_operation_confirm() {
return;
}

Vector<String> old_paths;
HashMap<String, ResourceUID::ID> uids;
Vector<String> remaps;
_before_move(old_paths, uids, remaps);
Vector<String> file_owners; // The files that use these moved/renamed resource files.
_before_move(uids, file_owners);

HashMap<String, String> file_renames;
HashMap<String, String> folder_renames;
_try_move_item(to_rename, new_path, file_renames, folder_renames);

int current_tab = EditorSceneTabs::get_singleton()->get_current_tab();
_update_resource_paths_after_move(file_renames, uids);
_update_dependencies_after_move(file_renames, remaps);
_update_dependencies_after_move(file_renames, file_owners);
_update_project_settings_after_move(file_renames, folder_renames);
_update_favorites_list_after_move(file_renames, folder_renames);

Expand Down Expand Up @@ -1910,10 +1909,9 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_cop
}
}

Vector<String> old_paths;
HashMap<String, ResourceUID::ID> uids;
Vector<String> remaps;
_before_move(old_paths, uids, remaps);
Vector<String> file_owners; // The files that use these moved/renamed resource files.
_before_move(uids, file_owners);

bool is_moved = false;
HashMap<String, String> file_renames;
Expand All @@ -1936,7 +1934,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_cop
if (is_moved) {
int current_tab = EditorSceneTabs::get_singleton()->get_current_tab();
_update_resource_paths_after_move(file_renames, uids);
_update_dependencies_after_move(file_renames, remaps);
_update_dependencies_after_move(file_renames, file_owners);
_update_project_settings_after_move(file_renames, folder_renames);
_update_favorites_list_after_move(file_renames, folder_renames);

Expand All @@ -1951,20 +1949,43 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_cop
}
}

void FileSystemDock::_before_move(Vector<String> &r_old_paths, HashMap<String, ResourceUID::ID> &r_uids, Vector<String> &r_remaps) const {
void FileSystemDock::_before_move(HashMap<String, ResourceUID::ID> &r_uids, Vector<String> &r_file_owners) const {
Vector<String> renamed_files;
for (int i = 0; i < to_move.size(); i++) {
r_old_paths.push_back(to_move[i].path);
ResourceUID::ID uid = ResourceLoader::get_resource_uid(to_move[i].path);
if (uid != ResourceUID::INVALID_ID) {
r_uids[to_move[i].path] = uid;
if (to_move[i].is_file) {
renamed_files.push_back(to_move[i].path);
ResourceUID::ID uid = ResourceLoader::get_resource_uid(to_move[i].path);
if (uid != ResourceUID::INVALID_ID) {
r_uids[to_move[i].path] = uid;
}
} else {
EditorFileSystemDirectory *current_folder = EditorFileSystem::get_singleton()->get_filesystem_path(to_move[i].path);
List<EditorFileSystemDirectory *> folders;
folders.push_back(current_folder);
while (folders.front()) {
current_folder = folders.front()->get();
for (int j = 0; j < current_folder->get_file_count(); j++) {
const String file_path = current_folder->get_file_path(j);
renamed_files.push_back(file_path);
ResourceUID::ID uid = ResourceLoader::get_resource_uid(file_path);
if (uid != ResourceUID::INVALID_ID) {
r_uids[file_path] = uid;
}
}
for (int j = 0; j < current_folder->get_subdir_count(); j++) {
folders.push_back(current_folder->get_subdir(j));
}
folders.pop_front();
}
}
}

_find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), r_old_paths, r_remaps);
// Look for files that use these moved/renamed resource files.
_find_file_owners(EditorFileSystem::get_singleton()->get_filesystem(), renamed_files, r_file_owners);

// Open scenes with dependencies on the ones about to be moved will be reloaded,
// so save them first to prevent losing unsaved changes.
EditorNode::get_singleton()->save_scene_list(r_remaps);
EditorNode::get_singleton()->save_scene_list(r_file_owners);
}

Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) const {
Expand Down Expand Up @@ -2201,6 +2222,10 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
break;
}

// Rename has same logic as move for resource files.
to_move.clear();
to_move.push_back(to_rename);

if (tree->has_focus()) {
// Edit node in Tree.
tree->edit_selected(true);
Expand Down
6 changes: 3 additions & 3 deletions editor/filesystem_dock.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,11 @@ class FileSystemDock : public VBoxContainer {
void _update_import_dock();

void _get_all_items_in_dir(EditorFileSystemDirectory *p_efsd, Vector<String> &r_files, Vector<String> &r_folders) const;
void _find_remaps(EditorFileSystemDirectory *p_efsd, const Vector<String> &r_renames, Vector<String> &r_to_remaps) const;
void _find_file_owners(EditorFileSystemDirectory *p_efsd, const Vector<String> &p_renames, Vector<String> &r_file_owners) const;
void _try_move_item(const FileOrFolder &p_item, const String &p_new_path, HashMap<String, String> &p_file_renames, HashMap<String, String> &p_folder_renames);
void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const;
void _before_move(Vector<String> &r_old_paths, HashMap<String, ResourceUID::ID> &r_uids, Vector<String> &r_remaps) const;
void _update_dependencies_after_move(const HashMap<String, String> &p_renames, const Vector<String> &p_remaps) const;
void _before_move(HashMap<String, ResourceUID::ID> &r_uids, Vector<String> &r_file_owners) const;
void _update_dependencies_after_move(const HashMap<String, String> &p_renames, const Vector<String> &p_file_owners) const;
void _update_resource_paths_after_move(const HashMap<String, String> &p_renames, const HashMap<String, ResourceUID::ID> &p_uids) const;
void _update_favorites_list_after_move(const HashMap<String, String> &p_files_renames, const HashMap<String, String> &p_folders_renames) const;
void _update_project_settings_after_move(const HashMap<String, String> &p_renames, const HashMap<String, String> &p_folders_renames);
Expand Down