Skip to content

Commit f4439ea

Browse files
committed
Allow to easily rename multiple nodes
1 parent dad6c77 commit f4439ea

File tree

3 files changed

+78
-15
lines changed

3 files changed

+78
-15
lines changed

editor/gui/scene_tree_editor.cpp

+73-11
Original file line numberDiff line numberDiff line change
@@ -1030,8 +1030,13 @@ void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) {
10301030
}
10311031
}
10321032

1033-
void SceneTreeEditor::_rename_node(Node *p_node, const String &p_name) {
1034-
TreeItem *item = _find(tree->get_root(), p_node->get_path());
1033+
void SceneTreeEditor::rename_node(Node *p_node, const String &p_name, TreeItem *p_item) {
1034+
TreeItem *item;
1035+
if (p_item) {
1036+
item = p_item; // During batch rename the paths may change, so using _find() is unreliable.
1037+
} else {
1038+
item = _find(tree->get_root(), p_node->get_path());
1039+
}
10351040
ERR_FAIL_NULL(item);
10361041
String new_name = p_name.validate_node_name();
10371042

@@ -1091,7 +1096,7 @@ void SceneTreeEditor::_rename_node(Node *p_node, const String &p_name) {
10911096
emit_signal(SNAME("node_renamed"));
10921097
} else {
10931098
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
1094-
undo_redo->create_action("Rename Node", UndoRedo::MERGE_DISABLE, p_node);
1099+
undo_redo->create_action(TTR("Rename Node"), UndoRedo::MERGE_DISABLE, p_node);
10951100

10961101
emit_signal(SNAME("node_prerename"), p_node, new_name);
10971102

@@ -1108,17 +1113,74 @@ void SceneTreeEditor::_rename_node(Node *p_node, const String &p_name) {
11081113
}
11091114
}
11101115

1111-
void SceneTreeEditor::_renamed() {
1116+
void SceneTreeEditor::_edited() {
11121117
TreeItem *which = tree->get_edited();
1113-
11141118
ERR_FAIL_NULL(which);
1115-
NodePath np = which->get_metadata(0);
1116-
Node *n = get_node(np);
1119+
1120+
if (is_scene_tree_dock && tree->get_next_selected(which)) {
1121+
List<Node *> nodes_to_rename;
1122+
for (TreeItem *item = which; item; item = tree->get_next_selected(item)) {
1123+
Node *n = get_node(item->get_metadata(0));
1124+
ERR_FAIL_NULL(n);
1125+
nodes_to_rename.push_back(n);
1126+
}
1127+
ERR_FAIL_COND(nodes_to_rename.is_empty());
1128+
1129+
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
1130+
undo_redo->create_action(TTR("Rename Nodes"), UndoRedo::MERGE_DISABLE, nodes_to_rename.front()->get(), true);
1131+
1132+
TreeItem *item = which;
1133+
for (Node *n : nodes_to_rename) {
1134+
_renamed(item, which, n);
1135+
item = tree->get_next_selected(item);
1136+
}
1137+
which->remove_meta("use_class");
1138+
undo_redo->commit_action();
1139+
} else {
1140+
_renamed(which, nullptr);
1141+
}
1142+
}
1143+
1144+
void SceneTreeEditor::_renamed(TreeItem *p_item, TreeItem *p_batch_item, Node *p_node) {
1145+
Node *n;
1146+
if (p_node) {
1147+
n = p_node; // During batch rename the paths may change, so using metadata is unreliable.
1148+
} else {
1149+
n = get_node(p_item->get_metadata(0));
1150+
}
11171151
ERR_FAIL_NULL(n);
11181152

1119-
String new_name = which->get_text(0);
1153+
String new_name;
1154+
if (p_batch_item) {
1155+
if (!p_batch_item->get_meta(SNAME("use_class"), false)) {
1156+
new_name = p_batch_item->get_text(0);
1157+
}
1158+
} else {
1159+
new_name = p_item->get_text(0);
1160+
}
1161+
1162+
if (new_name.strip_edges().is_empty()) {
1163+
// If name is empty, fallback to class name.
1164+
if (int(GLOBAL_GET("editor/naming/node_name_casing")) != NAME_CASING_PASCAL_CASE) {
1165+
new_name = Node::adjust_name_casing(n->get_class());
1166+
} else {
1167+
new_name = n->get_class();
1168+
}
1169+
1170+
// When doing batch rename, rename all nodes to their respective class.
1171+
if (p_batch_item == p_item) {
1172+
p_batch_item->set_meta("use_class", true);
1173+
}
1174+
}
1175+
1176+
if (n->is_unique_name_in_owner() && get_tree()->get_edited_scene_root()->get_node_or_null("%" + new_name) != nullptr) {
1177+
error->set_text(vformat(TTR("A node with the unique name %s already exists in this scene."), new_name));
1178+
error->popup_centered();
1179+
p_item->set_text(0, n->get_name());
1180+
return;
1181+
}
11201182

1121-
_rename_node(n, new_name);
1183+
rename_node(n, new_name, p_item);
11221184
}
11231185

11241186
Node *SceneTreeEditor::get_selected() {
@@ -1491,7 +1553,7 @@ void SceneTreeEditor::set_connecting_signal(bool p_enable) {
14911553

14921554
void SceneTreeEditor::_bind_methods() {
14931555
ClassDB::bind_method(D_METHOD("_update_tree"), &SceneTreeEditor::_update_tree, DEFVAL(false)); // Still used by UndoRedo.
1494-
ClassDB::bind_method("_rename_node", &SceneTreeEditor::_rename_node);
1556+
ClassDB::bind_method("_test_update_tree", &SceneTreeEditor::_test_update_tree);
14951557

14961558
ClassDB::bind_method(D_METHOD("update_tree"), &SceneTreeEditor::update_tree);
14971559

@@ -1543,7 +1605,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope
15431605
}
15441606

15451607
tree->connect("cell_selected", callable_mp(this, &SceneTreeEditor::_selected_changed));
1546-
tree->connect("item_edited", callable_mp(this, &SceneTreeEditor::_renamed));
1608+
tree->connect("item_edited", callable_mp(this, &SceneTreeEditor::_edited));
15471609
tree->connect("multi_selected", callable_mp(this, &SceneTreeEditor::_cell_multi_selected));
15481610
tree->connect("button_clicked", callable_mp(this, &SceneTreeEditor::_cell_button_pressed));
15491611
tree->connect("nothing_selected", callable_mp(this, &SceneTreeEditor::_deselect_items));

editor/gui/scene_tree_editor.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ class SceneTreeEditor : public Control {
8989
void _notification(int p_what);
9090
void _selected_changed();
9191
void _deselect_items();
92-
void _rename_node(Node *p_node, const String &p_name);
9392

9493
void _cell_collapsed(Object *p_obj);
9594

@@ -101,7 +100,8 @@ class SceneTreeEditor : public Control {
101100
bool show_enabled_subscene = false;
102101
bool is_scene_tree_dock = false;
103102

104-
void _renamed();
103+
void _edited();
104+
void _renamed(TreeItem *p_item, TreeItem *p_batch_item, Node *p_node = nullptr);
105105

106106
HashSet<Node *> marked;
107107
bool marked_selectable = false;
@@ -147,6 +147,8 @@ class SceneTreeEditor : public Control {
147147
// Public for use with callable_mp.
148148
void _update_tree(bool p_scroll_to_selected = false);
149149

150+
void rename_node(Node *p_node, const String &p_name, TreeItem *p_item = nullptr);
151+
150152
void set_filter(const String &p_filter);
151153
String get_filter() const;
152154
String get_filter_term_warning();

editor/rename_dialog.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,7 @@ void RenameDialog::rename() {
599599
ERR_PRINT("Skipping missing node: " + to_rename[i].first.get_concatenated_subnames());
600600
continue;
601601
}
602-
603-
scene_tree_editor->call("_rename_node", n, new_name);
602+
scene_tree_editor->rename_node(n, new_name);
604603
}
605604

606605
undo_redo->commit_action();

0 commit comments

Comments
 (0)