From ef6d414e6e25c190a30e2f58c5822cb56ae4fbd3 Mon Sep 17 00:00:00 2001 From: Hein-Pieter van Braam-Stewart Date: Tue, 4 Jun 2019 05:36:23 +0200 Subject: [PATCH] Fix moving and renaming files This commit fixes several issues related to moving scenes and resources in an open project. * Don't try to reload scenes while not all scenes are updated yet. * Don't use the UndoRedo system to update non-user initiated editor state. * Resave scenes after moving files and updating resource path(s). (cherry picked from commit 0ac7715a27abc9a679f9537cc16ebb7e3d3bfea4) --- editor/editor_data.cpp | 1 + editor/editor_node.cpp | 44 +++++++++++++++++++++++++++++--------- editor/editor_node.h | 11 ++++++++-- editor/filesystem_dock.cpp | 31 ++++++++++++++++++++++++++- editor/filesystem_dock.h | 1 + 5 files changed, 75 insertions(+), 13 deletions(-) diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index f61a8310159..38f30df1694 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -560,6 +560,7 @@ void EditorData::move_edited_scene_index(int p_idx, int p_to_idx) { ERR_FAIL_INDEX(p_to_idx, edited_scene.size()); SWAP(edited_scene.write[p_idx], edited_scene.write[p_to_idx]); } + void EditorData::remove_scene(int p_idx) { ERR_FAIL_INDEX(p_idx, edited_scene.size()); if (edited_scene[p_idx].root) { diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index edcd7d64781..47eeef55ac8 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -504,6 +504,7 @@ void EditorNode::_fs_changed() { void EditorNode::_resources_reimported(const Vector &p_resources) { List scenes; //will load later + int current_tab = scene_tabs->get_current_tab(); for (int i = 0; i < p_resources.size(); i++) { String file_type = ResourceLoader::get_resource_type(p_resources[i]); @@ -526,6 +527,8 @@ void EditorNode::_resources_reimported(const Vector &p_resources) { for (List::Element *E = scenes.front(); E; E = E->next()) { reload_scene(E->get()); } + + scene_tabs->set_current_tab(current_tab); } void EditorNode::_sources_changed(bool p_exist) { @@ -1189,6 +1192,17 @@ void EditorNode::save_all_scenes() { _save_all_scenes(); } +void EditorNode::save_scene_list(Vector p_scene_filenames) { + + for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { + Node *scene = editor_data.get_edited_scene_root(i); + + if (scene && (p_scene_filenames.find(scene->get_filename()) >= 0)) { + _save_scene(scene->get_filename(), i); + } + } +} + void EditorNode::restart_editor() { exiting = true; @@ -2744,7 +2758,7 @@ bool EditorNode::is_addon_plugin_enabled(const String &p_addon) const { return plugin_addons.has(p_addon); } -void EditorNode::_remove_edited_scene() { +void EditorNode::_remove_edited_scene(bool p_change_tab) { int new_index = editor_data.get_edited_scene(); int old_index = new_index; @@ -2760,18 +2774,19 @@ void EditorNode::_remove_edited_scene() { if (editor_data.get_scene_path(old_index) != String()) { ScriptEditor::get_singleton()->close_builtin_scripts_from_scene(editor_data.get_scene_path(old_index)); } - _scene_tab_changed(new_index); + + if (p_change_tab) _scene_tab_changed(new_index); editor_data.remove_scene(old_index); editor_data.get_undo_redo().clear_history(false); _update_title(); _update_scene_tabs(); } -void EditorNode::_remove_scene(int index) { +void EditorNode::_remove_scene(int index, bool p_change_tab) { if (editor_data.get_edited_scene() == index) { //Scene to remove is current scene - _remove_edited_scene(); + _remove_edited_scene(p_change_tab); } else { //Scene to remove is not active scene editor_data.remove_scene(index); @@ -4023,6 +4038,14 @@ bool EditorNode::has_scenes_in_session() { return !scenes.empty(); } +int EditorNode::get_current_tab() { + return scene_tabs->get_current_tab(); +} + +void EditorNode::set_current_tab(int p_tab) { + scene_tabs->set_current_tab(p_tab); +} + void EditorNode::_update_layouts_menu() { editor_layouts->clear(); @@ -4612,8 +4635,7 @@ void EditorNode::reload_scene(const String &p_path) { if (scene_idx == -1) { if (get_edited_scene()) { - //scene is not open, so at it might be instanced, just refresh, set tab to itself and it will reload - set_current_scene(current_tab); + //scene is not open, so at it might be instanced. We'll refresh the whole scene later. editor_data.get_undo_redo().clear_history(); } return; @@ -4623,17 +4645,19 @@ void EditorNode::reload_scene(const String &p_path) { editor_data.apply_changes_in_editors(); _set_scene_metadata(p_path); } - //remove scene - _remove_scene(scene_idx); - //reload scene + //remove scene + _remove_scene(scene_idx, false); + + //reload scene load_scene(p_path, true, false, true, true); + //adjust index so tab is back a the previous position editor_data.move_edited_scene_to_index(scene_idx); get_undo_redo()->clear_history(); + //recover the tab scene_tabs->set_current_tab(current_tab); - _scene_tab_changed(current_tab); } int EditorNode::plugin_init_callback_count = 0; diff --git a/editor/editor_node.h b/editor/editor_node.h index e853703cab2..85b036710b2 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -499,8 +499,8 @@ private: static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog); void _cleanup_scene(); - void _remove_edited_scene(); - void _remove_scene(int index); + void _remove_edited_scene(bool p_change_tab = true); + void _remove_scene(int index, bool p_change_tab = true); bool _find_and_save_resource(RES p_res, Map &processed, int32_t flags); bool _find_and_save_edited_subresources(Object *obj, Map &processed, int32_t flags); void _save_edited_subresources(Node *scene, Map &processed, int32_t flags); @@ -615,6 +615,12 @@ protected: void _notification(int p_what); static void _bind_methods(); +protected: + friend class FileSystemDock; + + int get_current_tab(); + void set_current_tab(int p_tab); + public: bool call_build(); @@ -786,6 +792,7 @@ public: void remove_tool_menu_item(const String &p_name); void save_all_scenes(); + void save_scene_list(Vector p_scene_filenames); void restart_editor(); void dim_editor(bool p_dimming); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index a22961d1ff6..26e33d76916 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1167,6 +1167,21 @@ void FileSystemDock::_update_favorites_list_after_move(const Map EditorSettings::get_singleton()->set_favorites(new_favorites); } +void FileSystemDock::_save_scenes_after_move(const Map &p_renames) const { + Vector remaps; + _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), p_renames, remaps); + Vector 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(); @@ -1241,14 +1256,21 @@ void FileSystemDock::_rename_operation_confirm() { Map file_renames; Map folder_renames; _try_move_item(to_rename, new_path, file_renames, folder_renames); + + int current_tab = editor->get_current_tab(); + _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() { @@ -1334,13 +1356,20 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw } if (is_moved) { + int current_tab = editor->get_current_tab(); + _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); } } diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index ab0dec6f5ec..35087940b07 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -201,6 +201,7 @@ private: void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const; void _update_dependencies_after_move(const Map &p_renames) const; void _update_resource_paths_after_move(const Map &p_renames) const; + void _save_scenes_after_move(const Map &p_renames) const; void _update_favorites_list_after_move(const Map &p_files_renames, const Map &p_folders_renames) const; void _update_project_settings_after_move(const Map &p_folders_renames) const;