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

Allow easily renaming multiple nodes #69087

Merged
merged 1 commit into from
Mar 4, 2024
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
52 changes: 38 additions & 14 deletions editor/gui/scene_tree_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1030,8 +1030,13 @@ void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) {
}
}

void SceneTreeEditor::_rename_node(Node *p_node, const String &p_name) {
TreeItem *item = _find(tree->get_root(), p_node->get_path());
void SceneTreeEditor::rename_node(Node *p_node, const String &p_name, TreeItem *p_item) {
TreeItem *item;
AThousandShips marked this conversation as resolved.
Show resolved Hide resolved
if (p_item) {
item = p_item; // During batch rename the paths may change, so using _find() is unreliable.
} else {
item = _find(tree->get_root(), p_node->get_path());
}
Comment on lines +1033 to +1039
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should just iterate through the node in reverse order so that every node still find it's item as this is what is done for batch rename currently. For this you can just replace push_back by push push_front at line 1029.

I know this is not great as nodes will be numbered from bottom to top and would need fixing but I think fixing this is another PR job. For now this PR should aim to keep consistency with what batch rename does.

ERR_FAIL_NULL(item);
String new_name = p_name.validate_node_name();

Expand Down Expand Up @@ -1069,7 +1074,7 @@ void SceneTreeEditor::_rename_node(Node *p_node, const String &p_name) {

// We previously made sure name is not the same as current name so that it won't complain about already used unique name when not changing name.
if (p_node->is_unique_name_in_owner() && get_tree()->get_edited_scene_root()->get_node_or_null("%" + new_name)) {
String text = TTR("Another node already uses this unique name in the scene.");
String text = vformat(TTR("A node with the unique name %s already exists in this scene."), new_name);
if (error->is_visible()) {
if (!error->get_meta("same_unique_name", false)) {
error->set_text(error->get_text() + "\n\n" + text);
Expand All @@ -1091,7 +1096,7 @@ void SceneTreeEditor::_rename_node(Node *p_node, const String &p_name) {
emit_signal(SNAME("node_renamed"));
} else {
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action("Rename Node", UndoRedo::MERGE_DISABLE, p_node);
undo_redo->create_action(TTR("Rename Node"), UndoRedo::MERGE_DISABLE, p_node);

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

Expand All @@ -1108,17 +1113,37 @@ void SceneTreeEditor::_rename_node(Node *p_node, const String &p_name) {
}
}

void SceneTreeEditor::_renamed() {
TreeItem *which = tree->get_edited();

void SceneTreeEditor::_edited() {
TreeItem *which = tree->get_next_selected(nullptr);
ERR_FAIL_NULL(which);
NodePath np = which->get_metadata(0);
Node *n = get_node(np);
ERR_FAIL_NULL(n);
TreeItem *edited = tree->get_edited();
ERR_FAIL_NULL(edited);

if (is_scene_tree_dock && tree->get_next_selected(which)) {
List<Node *> nodes_to_rename;
for (TreeItem *item = which; item; item = tree->get_next_selected(item)) {
Node *n = get_node(item->get_metadata(0));
ERR_FAIL_NULL(n);
nodes_to_rename.push_back(n);
}
ERR_FAIL_COND(nodes_to_rename.is_empty());

String new_name = which->get_text(0);
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Rename Nodes"), UndoRedo::MERGE_DISABLE, nodes_to_rename.front()->get(), true);

TreeItem *item = which;
String new_name = edited->get_text(0);
for (Node *n : nodes_to_rename) {
rename_node(n, new_name, item);
item = tree->get_next_selected(item);
}

_rename_node(n, new_name);
undo_redo->commit_action();
} else {
Node *n = get_node(which->get_metadata(0));
ERR_FAIL_NULL(n);
rename_node(n, which->get_text(0));
}
}

Node *SceneTreeEditor::get_selected() {
Expand Down Expand Up @@ -1491,7 +1516,6 @@ void SceneTreeEditor::set_connecting_signal(bool p_enable) {

void SceneTreeEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_tree"), &SceneTreeEditor::_update_tree, DEFVAL(false)); // Still used by UndoRedo.
ClassDB::bind_method("_rename_node", &SceneTreeEditor::_rename_node);

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

Expand Down Expand Up @@ -1543,7 +1567,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope
}

tree->connect("cell_selected", callable_mp(this, &SceneTreeEditor::_selected_changed));
tree->connect("item_edited", callable_mp(this, &SceneTreeEditor::_renamed));
tree->connect("item_edited", callable_mp(this, &SceneTreeEditor::_edited));
tree->connect("multi_selected", callable_mp(this, &SceneTreeEditor::_cell_multi_selected));
tree->connect("button_clicked", callable_mp(this, &SceneTreeEditor::_cell_button_pressed));
tree->connect("nothing_selected", callable_mp(this, &SceneTreeEditor::_deselect_items));
Expand Down
6 changes: 4 additions & 2 deletions editor/gui/scene_tree_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ class SceneTreeEditor : public Control {
void _notification(int p_what);
void _selected_changed();
void _deselect_items();
void _rename_node(Node *p_node, const String &p_name);

void _cell_collapsed(Object *p_obj);

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

void _renamed();
void _edited();
void _renamed(TreeItem *p_item, TreeItem *p_batch_item, Node *p_node = nullptr);

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

void rename_node(Node *p_node, const String &p_name, TreeItem *p_item = nullptr);

void set_filter(const String &p_filter);
String get_filter() const;
String get_filter_term_warning();
Expand Down
3 changes: 1 addition & 2 deletions editor/rename_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,8 +599,7 @@ void RenameDialog::rename() {
ERR_PRINT("Skipping missing node: " + to_rename[i].first.get_concatenated_subnames());
continue;
}

scene_tree_editor->call("_rename_node", n, new_name);
scene_tree_editor->rename_node(n, new_name);
}

undo_redo->commit_action();
Expand Down
12 changes: 2 additions & 10 deletions editor/scene_tree_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3370,12 +3370,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
}

if (profile_allow_editing) {
bool add_separator = false;

if (full_selection.size() == 1) {
add_separator = true;
menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Rename")), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);
}
menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Rename")), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);

bool can_replace = true;
for (Node *E : selection) {
Expand All @@ -3386,14 +3381,11 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
}

if (can_replace) {
add_separator = true;
menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Reload")), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
}

if (scene_tree->get_selected() != edited_scene) {
if (add_separator) {
menu->add_separator();
}
menu->add_separator();
menu->add_icon_shortcut(get_editor_theme_icon(SNAME("MoveUp")), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
menu->add_icon_shortcut(get_editor_theme_icon(SNAME("MoveDown")), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Duplicate")), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
Expand Down
Loading