diff options
-rw-r--r-- | doc/classes/EditorUndoRedoManager.xml | 7 | ||||
-rw-r--r-- | editor/editor_inspector.cpp | 4 | ||||
-rw-r--r-- | editor/editor_node.cpp | 20 | ||||
-rw-r--r-- | editor/editor_node.h | 2 | ||||
-rw-r--r-- | editor/editor_properties_array_dict.cpp | 4 | ||||
-rw-r--r-- | editor/editor_undo_redo_manager.cpp | 16 | ||||
-rw-r--r-- | editor/editor_undo_redo_manager.h | 2 | ||||
-rw-r--r-- | editor/plugins/cast_2d_editor_plugin.cpp | 1 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 9 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.cpp | 4 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 6 | ||||
-rw-r--r-- | modules/gridmap/editor/grid_map_editor_plugin.cpp | 21 |
12 files changed, 63 insertions, 33 deletions
diff --git a/doc/classes/EditorUndoRedoManager.xml b/doc/classes/EditorUndoRedoManager.xml index 26580bbf06..5ac0d790a2 100644 --- a/doc/classes/EditorUndoRedoManager.xml +++ b/doc/classes/EditorUndoRedoManager.xml @@ -88,6 +88,13 @@ The way undo operation are ordered in actions is dictated by [param backward_undo_ops]. When [param backward_undo_ops] is [code]false[/code] undo option are ordered in the same order they were added. Which means the first operation to be added will be the first to be undone. </description> </method> + <method name="force_fixed_history"> + <return type="void" /> + <description> + Forces the next operation (e.g. [method add_do_method]) to use the action's history rather than guessing it from the object. This is sometimes needed when a history can't be correctly determined, like for a nested resource that doesn't have a path yet. + This method should only be used when absolutely necessary, otherwise it might cause invalid history state. For most of complex cases, the [code]custom_context[/code] parameter of [method create_action] is sufficient. + </description> + </method> <method name="get_history_undo_redo" qualifiers="const"> <return type="UndoRedo" /> <param index="0" name="id" type="int" /> diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 6c26231a4b..81d9510033 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2598,6 +2598,10 @@ int EditorInspector::inspector_plugin_count = 0; EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, const Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) { for (int i = inspector_plugin_count - 1; i >= 0; i--) { + if (!inspector_plugins[i]->can_handle(p_object)) { + continue; + } + inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide); if (inspector_plugins[i]->added_editors.size()) { for (List<EditorInspectorPlugin::AddedEditor>::Element *E = inspector_plugins[i]->added_editors.front()->next(); E; E = E->next()) { //only keep first one diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 55487f7896..ae7066fea9 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1737,7 +1737,7 @@ bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_nod return false; } -int EditorNode::_save_external_resources() { +int EditorNode::_save_external_resources(bool p_also_save_external_data) { // Save external resources and its subresources if any was modified. int flg = 0; @@ -1783,6 +1783,16 @@ int EditorNode::_save_external_resources() { saved++; } + if (p_also_save_external_data) { + for (int i = 0; i < editor_data.get_editor_plugin_count(); i++) { + EditorPlugin *plugin = editor_data.get_editor_plugin(i); + if (!plugin->get_unsaved_status().is_empty()) { + plugin->save_external_data(); + saved++; + } + } + } + EditorUndoRedoManager::get_singleton()->set_history_as_saved(EditorUndoRedoManager::GLOBAL_HISTORY); return saved; @@ -1812,9 +1822,7 @@ static void _reset_animation_mixers(Node *p_node, List<Pair<AnimationMixer *, Re } void EditorNode::_save_scene(String p_file, int idx) { - if (!saving_scene.is_empty() && saving_scene == p_file) { - return; - } + ERR_FAIL_COND_MSG(!saving_scene.is_empty() && saving_scene == p_file, "Scene saved while already being saved!"); Node *scene = editor_data.get_edited_scene_root(idx); @@ -2728,10 +2736,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { ScriptEditor::get_singleton()->save_current_script(); } - const int saved = _save_external_resources(); + const int saved = _save_external_resources(true); if (saved > 0) { show_accept( - vformat(TTR("The current scene has no root node, but %d modified external resource(s) were saved anyway."), saved), + vformat(TTR("The current scene has no root node, but %d modified external resource(s) and/or plugin data were saved anyway."), saved), TTR("OK")); } else if (p_option == FILE_SAVE_AS_SCENE) { // Don't show this dialog when pressing Ctrl + S to avoid interfering with script saving. diff --git a/editor/editor_node.h b/editor/editor_node.h index b7b4dff74e..49674dd1c1 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -573,7 +573,7 @@ private: void _update_undo_redo_allowed(); - int _save_external_resources(); + int _save_external_resources(bool p_also_save_external_data = false); void _set_current_scene(int p_idx); void _set_current_scene_nocheck(int p_idx); diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 127bca9bbf..633f6abad9 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -435,7 +435,7 @@ void EditorPropertyArray::update_property() { editor->setup("Object"); new_prop = editor; } else { - new_prop = EditorInspector::instantiate_property_editor(nullptr, value_type, "", subtype_hint, subtype_hint_string, PROPERTY_USAGE_NONE); + new_prop = EditorInspector::instantiate_property_editor(this, value_type, "", subtype_hint, subtype_hint_string, PROPERTY_USAGE_NONE); } new_prop->set_selectable(false); new_prop->set_use_folding(is_using_folding()); @@ -1064,7 +1064,7 @@ void EditorPropertyDictionary::update_property() { editor->setup("Object"); new_prop = editor; } else { - new_prop = EditorInspector::instantiate_property_editor(nullptr, value_type, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE); + new_prop = EditorInspector::instantiate_property_editor(this, value_type, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE); } new_prop->set_selectable(false); new_prop->set_use_folding(is_using_folding()); diff --git a/editor/editor_undo_redo_manager.cpp b/editor/editor_undo_redo_manager.cpp index 94f76dbc41..55bc198dfb 100644 --- a/editor/editor_undo_redo_manager.cpp +++ b/editor/editor_undo_redo_manager.cpp @@ -104,8 +104,13 @@ int EditorUndoRedoManager::get_history_id_for_object(Object *p_object) const { } EditorUndoRedoManager::History &EditorUndoRedoManager::get_history_for_object(Object *p_object) { - int history_id = get_history_id_for_object(p_object); - ERR_FAIL_COND_V_MSG(pending_action.history_id != INVALID_HISTORY && history_id != pending_action.history_id, get_or_create_history(pending_action.history_id), vformat("UndoRedo history mismatch: expected %d, got %d.", pending_action.history_id, history_id)); + int history_id; + if (!forced_history) { + history_id = get_history_id_for_object(p_object); + ERR_FAIL_COND_V_MSG(pending_action.history_id != INVALID_HISTORY && history_id != pending_action.history_id, get_or_create_history(pending_action.history_id), vformat("UndoRedo history mismatch: expected %d, got %d.", pending_action.history_id, history_id)); + } else { + history_id = pending_action.history_id; + } History &history = get_or_create_history(history_id); if (pending_action.history_id == INVALID_HISTORY) { @@ -116,6 +121,11 @@ EditorUndoRedoManager::History &EditorUndoRedoManager::get_history_for_object(Ob return history; } +void EditorUndoRedoManager::force_fixed_history() { + ERR_FAIL_COND_MSG(pending_action.history_id == INVALID_HISTORY, "The current action has no valid history assigned."); + forced_history = true; +} + void EditorUndoRedoManager::create_action_for_history(const String &p_name, int p_history_id, UndoRedo::MergeMode p_mode, bool p_backward_undo_ops) { if (pending_action.history_id != INVALID_HISTORY) { // Nested action. @@ -236,6 +246,7 @@ void EditorUndoRedoManager::commit_action(bool p_execute) { return; // Empty action, do nothing. } + forced_history = false; is_committing = true; History &history = get_or_create_history(pending_action.history_id); @@ -469,6 +480,7 @@ void EditorUndoRedoManager::_bind_methods() { ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode", "custom_context", "backward_undo_ops"), &EditorUndoRedoManager::create_action, DEFVAL(UndoRedo::MERGE_DISABLE), DEFVAL((Object *)nullptr), DEFVAL(false)); ClassDB::bind_method(D_METHOD("commit_action", "execute"), &EditorUndoRedoManager::commit_action, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_committing_action"), &EditorUndoRedoManager::is_committing_action); + ClassDB::bind_method(D_METHOD("force_fixed_history"), &EditorUndoRedoManager::force_fixed_history); { MethodInfo mi; diff --git a/editor/editor_undo_redo_manager.h b/editor/editor_undo_redo_manager.h index e8c782871c..219d5e0702 100644 --- a/editor/editor_undo_redo_manager.h +++ b/editor/editor_undo_redo_manager.h @@ -67,6 +67,7 @@ private: HashMap<int, History> history_map; Action pending_action; + bool forced_history = false; bool is_committing = false; History *_get_newest_undo(); @@ -79,6 +80,7 @@ public: UndoRedo *get_history_undo_redo(int p_idx) const; int get_history_id_for_object(Object *p_object) const; History &get_history_for_object(Object *p_object); + void force_fixed_history(); void create_action_for_history(const String &p_name, int p_history_id, UndoRedo::MergeMode p_mode = UndoRedo::MERGE_DISABLE, bool p_backward_undo_ops = false); void create_action(const String &p_name = "", UndoRedo::MergeMode p_mode = UndoRedo::MERGE_DISABLE, Object *p_custom_context = nullptr, bool p_backward_undo_ops = false); diff --git a/editor/plugins/cast_2d_editor_plugin.cpp b/editor/plugins/cast_2d_editor_plugin.cpp index c9d7ff8e08..3da7d4a7dc 100644 --- a/editor/plugins/cast_2d_editor_plugin.cpp +++ b/editor/plugins/cast_2d_editor_plugin.cpp @@ -102,7 +102,6 @@ bool Cast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { node->set("target_position", point); canvas_item_editor->update_viewport(); - node->notify_property_list_changed(); return true; } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 3d043909b2..9d5dbb4a4f 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1012,8 +1012,6 @@ void ScriptEditor::_resave_scripts(const String &p_str) { se->trim_final_newlines(); } - se->insert_final_newline(); - if (convert_indent_on_save) { se->convert_indent(); } @@ -1410,8 +1408,6 @@ void ScriptEditor::_menu_option(int p_option) { current->trim_final_newlines(); } - current->insert_final_newline(); - if (convert_indent_on_save) { current->convert_indent(); } @@ -2614,8 +2610,6 @@ void ScriptEditor::save_current_script() { current->trim_final_newlines(); } - current->insert_final_newline(); - if (convert_indent_on_save) { current->convert_indent(); } @@ -2662,8 +2656,6 @@ void ScriptEditor::save_all_scripts() { se->trim_final_newlines(); } - se->insert_final_newline(); - if (!se->is_unsaved()) { continue; } @@ -2713,6 +2705,7 @@ void ScriptEditor::apply_scripts() const { if (!se) { continue; } + se->insert_final_newline(); se->apply_code(); } } diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index b33250bcb5..27056a6cc4 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -1056,10 +1056,12 @@ void SpriteFramesEditor::_rename_node_animation(EditorUndoRedoManager *undo_redo for (Node *E : nodes) { String current_name = E->call("get_animation"); if (current_name == p_filter) { + undo_redo->force_fixed_history(); // Fixes corner-case when editing SpriteFrames stored as separate file. undo_redo->add_undo_method(E, "set_animation", p_new_animation); } String autoplay_name = E->call("get_autoplay"); if (autoplay_name == p_filter) { + undo_redo->force_fixed_history(); undo_redo->add_undo_method(E, "set_autoplay", p_new_autoplay); } } @@ -1067,10 +1069,12 @@ void SpriteFramesEditor::_rename_node_animation(EditorUndoRedoManager *undo_redo for (Node *E : nodes) { String current_name = E->call("get_animation"); if (current_name == p_filter) { + undo_redo->force_fixed_history(); undo_redo->add_do_method(E, "set_animation", p_new_animation); } String autoplay_name = E->call("get_autoplay"); if (autoplay_name == p_filter) { + undo_redo->force_fixed_history(); undo_redo->add_do_method(E, "set_autoplay", p_new_autoplay); } } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 3f6927c02a..607c446e1b 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -3649,12 +3649,15 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, cons if (output_port_type == VisualShaderNode::PORT_TYPE_SAMPLER) { if (is_texture2d) { + undo_redo->force_fixed_history(); // vsnode is freshly created and has no path, so history can't be correctly determined. undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeTexture::SOURCE_PORT); } if (is_texture3d || is_texture2d_array) { + undo_redo->force_fixed_history(); undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeSample3D::SOURCE_PORT); } if (is_cubemap) { + undo_redo->force_fixed_history(); undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeCubemap::SOURCE_PORT); } } @@ -3754,16 +3757,19 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, cons //post-initialization if (is_texture2d || is_texture3d || is_curve || is_curve_xyz) { + undo_redo->force_fixed_history(); undo_redo->add_do_method(vsnode.ptr(), "set_texture", ResourceLoader::load(p_resource_path)); return; } if (is_cubemap) { + undo_redo->force_fixed_history(); undo_redo->add_do_method(vsnode.ptr(), "set_cube_map", ResourceLoader::load(p_resource_path)); return; } if (is_texture2d_array) { + undo_redo->force_fixed_history(); undo_redo->add_do_method(vsnode.ptr(), "set_texture_array", ResourceLoader::load(p_resource_path)); } } diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index b93b7c1a8c..f402e2a583 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -59,10 +59,18 @@ void GridMapEditor::_menu_option(int p_option) { switch (p_option) { case MENU_OPTION_PREV_LEVEL: { floor->set_value(floor->get_value() - 1); + if (selection.active && input_action == INPUT_SELECT) { + selection.current[edit_axis]--; + _validate_selection(); + } } break; case MENU_OPTION_NEXT_LEVEL: { floor->set_value(floor->get_value() + 1); + if (selection.active && input_action == INPUT_SELECT) { + selection.current[edit_axis]++; + _validate_selection(); + } } break; case MENU_OPTION_X_AXIS: @@ -754,19 +762,6 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D } } } - - if (k->is_shift_pressed() && selection.active && input_action != INPUT_PASTE) { - if (k->get_keycode() == (Key)options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) { - selection.click[edit_axis]--; - _validate_selection(); - return EditorPlugin::AFTER_GUI_INPUT_STOP; - } - if (k->get_keycode() == (Key)options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_NEXT_LEVEL))) { - selection.click[edit_axis]++; - _validate_selection(); - return EditorPlugin::AFTER_GUI_INPUT_STOP; - } - } } } |