Fixed 'Change Type' ignoring non-top-level nodes and editing foreign nodes/ being available when it is not.

This commit is contained in:
Edward Chan
2026-05-31 00:55:10 -04:00
parent c96e11965f
commit 8984aff92c
2 changed files with 28 additions and 30 deletions
+26 -28
View File
@@ -615,7 +615,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
if (editor_selection->get_selection().size() > 1) {
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
break;
}
rename_dialog->popup_centered();
@@ -627,7 +627,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
Tree *tree = scene_tree->get_scene_tree();
if (tree->is_anything_selected()) {
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
break;
}
tree->grab_focus(!tree->has_focus(true));
@@ -635,7 +635,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
} break;
case TOOL_REPARENT_TO_NEW_NODE:
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
break;
}
[[fallthrough]];
@@ -708,7 +708,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_CUT:
case TOOL_COPY: {
if (!edited_scene || (p_tool == TOOL_CUT && !_validate_no_foreign())) {
if (!edited_scene || (p_tool == TOOL_CUT && !_validate_no_foreign_selected(editor_selection->get_top_selected_node_list()))) {
break;
}
@@ -782,7 +782,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
break;
}
@@ -800,11 +800,13 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
if (!_validate_no_foreign()) {
List<Node *> full_selection = editor_selection->get_full_selected_node_list();
if (!_validate_no_foreign_selected(full_selection)) {
break;
}
if (!_validate_no_instance()) {
if (!_validate_no_instance_selected(full_selection)) {
break;
}
@@ -883,7 +885,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
break;
}
@@ -1055,7 +1057,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
break;
}
@@ -1164,7 +1166,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
return;
}
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
break;
}
@@ -1378,7 +1380,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
break;
}
@@ -1413,7 +1415,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
break;
}
@@ -2401,10 +2403,8 @@ void SceneTreeDock::_node_prerenamed(Node *p_node, const String &p_new_name) {
perform_node_renames(nullptr, &path_renames);
}
bool SceneTreeDock::_validate_no_foreign() {
const List<Node *> selection = editor_selection->get_top_selected_node_list();
for (Node *E : selection) {
bool SceneTreeDock::_validate_no_foreign_selected(const List<Node *> &p_selected) {
for (Node *E : p_selected) {
if (E != edited_scene && E->get_owner() != edited_scene) {
accept->set_text(TTR("Can't operate on nodes from a foreign scene!"));
accept->popup_centered();
@@ -2430,10 +2430,8 @@ bool SceneTreeDock::_validate_no_foreign() {
return true;
}
bool SceneTreeDock::_validate_no_instance() {
const List<Node *> selection = editor_selection->get_top_selected_node_list();
for (Node *E : selection) {
bool SceneTreeDock::_validate_no_instance_selected(const List<Node *> &p_selected) {
for (Node *E : p_selected) {
if (E != edited_scene && E->is_instance()) {
accept->set_text(TTR("This operation can't be done on instantiated scenes."));
accept->popup_centered();
@@ -3127,13 +3125,13 @@ void SceneTreeDock::_create() {
_do_create(parent);
} else if (current_option == TOOL_CHANGE_TYPE) {
const List<Node *> selection = editor_selection->get_top_selected_node_list();
ERR_FAIL_COND(selection.is_empty());
const List<Node *> full_selection = editor_selection->get_full_selected_node_list();
ERR_FAIL_COND(full_selection.is_empty());
EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
ur->create_action(TTR("Change type of node(s)"), UndoRedo::MERGE_DISABLE, selection.front()->get());
ur->create_action(TTR("Change type of node(s)"), UndoRedo::MERGE_DISABLE, full_selection.front()->get());
for (Node *n : selection) {
for (Node *n : full_selection) {
ERR_FAIL_NULL(n);
Variant c = create_dialog->instantiate_selected();
@@ -3793,7 +3791,7 @@ void SceneTreeDock::_script_dropped(const String &p_file, NodePath p_to) {
}
void SceneTreeDock::_nodes_dragged(const Array &p_nodes, NodePath p_to, int p_type) {
if (!_validate_no_foreign()) {
if (!_validate_no_foreign_selected(editor_selection->get_top_selected_node_list())) {
return;
}
@@ -3860,8 +3858,8 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
ERR_FAIL_COND(!EditorNode::get_singleton()->get_edited_scene());
menu->clear(false);
const List<Node *> selection = editor_selection->get_top_selected_node_list();
List<Node *> full_selection = editor_selection->get_full_selected_node_list(); // Above method only returns nodes with common parent.
const List<Node *> selection = editor_selection->get_top_selected_node_list(); // Only the top-level selected nodes.
List<Node *> full_selection = editor_selection->get_full_selected_node_list(); // All selected nodes.
scene_tree->get_scene_tree()->grab_focus(true);
@@ -3938,7 +3936,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
bool can_replace = true;
if (profile_allow_editing) {
for (Node *E : selection) {
for (Node *E : full_selection) {
if (E != edited_scene && (E->get_owner() != edited_scene || E->is_instance())) {
can_replace = false;
if (!E->is_instance()) {
+2 -2
View File
@@ -252,8 +252,8 @@ class SceneTreeDock : public EditorDock {
void _new_scene_from(const String &p_file);
void _set_node_owner_recursive(Node *p_node, Node *p_owner, const HashMap<const Node *, Node *> &p_inverse_duplimap);
bool _validate_no_foreign();
bool _validate_no_instance();
bool _validate_no_foreign_selected(const List<Node *> &p_selected);
bool _validate_no_instance_selected(const List<Node *> &p_selected);
void _selection_changed();
void _update_script_button();
void _queue_update_script_button();