| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  rename_dialog.cpp                                                    */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							|  |  |  | /*                      https://godotengine.org                          */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-01-01 20:13:46 +01:00
										 |  |  | /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "rename_dialog.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/string/print_string.h"
 | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | #include "editor_node.h"
 | 
					
						
							| 
									
										
										
										
											2019-12-25 10:12:05 +08:00
										 |  |  | #include "editor_scale.h"
 | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | #include "editor_settings.h"
 | 
					
						
							|  |  |  | #include "editor_themes.h"
 | 
					
						
							|  |  |  | #include "modules/regex/regex.h"
 | 
					
						
							|  |  |  | #include "plugins/script_editor_plugin.h"
 | 
					
						
							|  |  |  | #include "scene/gui/control.h"
 | 
					
						
							|  |  |  | #include "scene/gui/label.h"
 | 
					
						
							|  |  |  | #include "scene/gui/tab_container.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_undo_redo) { | 
					
						
							|  |  |  | 	scene_tree_editor = p_scene_tree_editor; | 
					
						
							|  |  |  | 	undo_redo = p_undo_redo; | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	preview_node = nullptr; | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	set_title(TTR("Batch Rename")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	VBoxContainer *vbc = memnew(VBoxContainer); | 
					
						
							|  |  |  | 	add_child(vbc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// -- Search/Replace Area
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GridContainer *grd_main = memnew(GridContainer); | 
					
						
							|  |  |  | 	grd_main->set_columns(2); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	grd_main->set_v_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	vbc->add_child(grd_main); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ---- 1st & 2nd row
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label *lbl_search = memnew(Label); | 
					
						
							| 
									
										
										
										
											2020-08-14 15:57:07 -03:00
										 |  |  | 	lbl_search->set_text(TTR("Search:")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lne_search = memnew(LineEdit); | 
					
						
							|  |  |  | 	lne_search->set_name("lne_search"); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	lne_search->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Label *lbl_replace = memnew(Label); | 
					
						
							| 
									
										
										
										
											2020-08-14 15:57:07 -03:00
										 |  |  | 	lbl_replace->set_text(TTR("Replace:")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lne_replace = memnew(LineEdit); | 
					
						
							|  |  |  | 	lne_replace->set_name("lne_replace"); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	lne_replace->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	grd_main->add_child(lbl_search); | 
					
						
							|  |  |  | 	grd_main->add_child(lbl_replace); | 
					
						
							|  |  |  | 	grd_main->add_child(lne_search); | 
					
						
							|  |  |  | 	grd_main->add_child(lne_replace); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ---- 3rd & 4th row
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label *lbl_prefix = memnew(Label); | 
					
						
							| 
									
										
										
										
											2020-08-14 15:57:07 -03:00
										 |  |  | 	lbl_prefix->set_text(TTR("Prefix:")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lne_prefix = memnew(LineEdit); | 
					
						
							|  |  |  | 	lne_prefix->set_name("lne_prefix"); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	lne_prefix->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Label *lbl_suffix = memnew(Label); | 
					
						
							| 
									
										
										
										
											2020-08-14 15:57:07 -03:00
										 |  |  | 	lbl_suffix->set_text(TTR("Suffix:")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lne_suffix = memnew(LineEdit); | 
					
						
							|  |  |  | 	lne_suffix->set_name("lne_suffix"); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	lne_suffix->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	grd_main->add_child(lbl_prefix); | 
					
						
							|  |  |  | 	grd_main->add_child(lbl_suffix); | 
					
						
							|  |  |  | 	grd_main->add_child(lne_prefix); | 
					
						
							|  |  |  | 	grd_main->add_child(lne_suffix); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// -- Feature Tabs
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-19 21:22:16 +01:00
										 |  |  | 	cbut_regex = memnew(CheckButton); | 
					
						
							|  |  |  | 	cbut_regex->set_text(TTR("Use Regular Expressions")); | 
					
						
							|  |  |  | 	vbc->add_child(cbut_regex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CheckButton *cbut_collapse_features = memnew(CheckButton); | 
					
						
							|  |  |  | 	cbut_collapse_features->set_text(TTR("Advanced Options")); | 
					
						
							|  |  |  | 	vbc->add_child(cbut_collapse_features); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	tabc_features = memnew(TabContainer); | 
					
						
							|  |  |  | 	tabc_features->set_tab_align(TabContainer::ALIGN_LEFT); | 
					
						
							| 
									
										
										
										
											2020-08-14 15:57:07 -03:00
										 |  |  | 	tabc_features->set_use_hidden_tabs_for_min_size(true); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	vbc->add_child(tabc_features); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ---- Tab Substitute
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	VBoxContainer *vbc_substitute = memnew(VBoxContainer); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	vbc_substitute->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	vbc_substitute->set_name(TTR("Substitute")); | 
					
						
							|  |  |  | 	tabc_features->add_child(vbc_substitute); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 17:30:44 +02:00
										 |  |  | 	cbut_substitute = memnew(CheckBox); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	cbut_substitute->set_text(TTR("Substitute")); | 
					
						
							|  |  |  | 	vbc_substitute->add_child(cbut_substitute); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GridContainer *grd_substitute = memnew(GridContainer); | 
					
						
							|  |  |  | 	grd_substitute->set_columns(3); | 
					
						
							|  |  |  | 	vbc_substitute->add_child(grd_substitute); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Name
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	but_insert_name = memnew(Button); | 
					
						
							|  |  |  | 	but_insert_name->set_text("NAME"); | 
					
						
							| 
									
										
										
										
											2020-04-21 15:02:36 -03:00
										 |  |  | 	but_insert_name->set_tooltip(String("${NAME}\n") + TTR("Node name.")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_name->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	but_insert_name->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${NAME}")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_name->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	grd_substitute->add_child(but_insert_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Parent
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	but_insert_parent = memnew(Button); | 
					
						
							|  |  |  | 	but_insert_parent->set_text("PARENT"); | 
					
						
							| 
									
										
										
										
											2020-04-21 15:02:36 -03:00
										 |  |  | 	but_insert_parent->set_tooltip(String("${PARENT}\n") + TTR("Node's parent name, if available.")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_parent->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	but_insert_parent->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${PARENT}")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_parent->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	grd_substitute->add_child(but_insert_parent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Type
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	but_insert_type = memnew(Button); | 
					
						
							|  |  |  | 	but_insert_type->set_text("TYPE"); | 
					
						
							| 
									
										
										
										
											2020-04-21 15:02:36 -03:00
										 |  |  | 	but_insert_type->set_tooltip(String("${TYPE}\n") + TTR("Node type.")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_type->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	but_insert_type->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${TYPE}")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_type->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	grd_substitute->add_child(but_insert_type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Scene
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	but_insert_scene = memnew(Button); | 
					
						
							|  |  |  | 	but_insert_scene->set_text("SCENE"); | 
					
						
							| 
									
										
										
										
											2020-04-21 15:02:36 -03:00
										 |  |  | 	but_insert_scene->set_tooltip(String("${SCENE}\n") + TTR("Current scene name.")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_scene->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	but_insert_scene->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${SCENE}")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_scene->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	grd_substitute->add_child(but_insert_scene); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Root
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	but_insert_root = memnew(Button); | 
					
						
							|  |  |  | 	but_insert_root->set_text("ROOT"); | 
					
						
							| 
									
										
										
										
											2020-04-21 15:02:36 -03:00
										 |  |  | 	but_insert_root->set_tooltip(String("${ROOT}\n") + TTR("Root node name.")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_root->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	but_insert_root->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${ROOT}")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_root->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	grd_substitute->add_child(but_insert_root); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Count
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	but_insert_count = memnew(Button); | 
					
						
							|  |  |  | 	but_insert_count->set_text("COUNTER"); | 
					
						
							|  |  |  | 	but_insert_count->set_tooltip(String("${COUNTER}\n") + TTR("Sequential integer counter.\nCompare counter options.")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_count->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	but_insert_count->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${COUNTER}")); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_count->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	grd_substitute->add_child(but_insert_count); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	chk_per_level_counter = memnew(CheckBox); | 
					
						
							| 
									
										
										
										
											2020-01-19 21:22:16 +01:00
										 |  |  | 	chk_per_level_counter->set_text(TTR("Per-level Counter")); | 
					
						
							| 
									
										
										
										
											2020-08-14 15:57:07 -03:00
										 |  |  | 	chk_per_level_counter->set_tooltip(TTR("If set, the counter restarts for each group of child nodes.")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	vbc_substitute->add_child(chk_per_level_counter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HBoxContainer *hbc_count_options = memnew(HBoxContainer); | 
					
						
							|  |  |  | 	vbc_substitute->add_child(hbc_count_options); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label *lbl_count_start = memnew(Label); | 
					
						
							|  |  |  | 	lbl_count_start->set_text(TTR("Start")); | 
					
						
							| 
									
										
										
										
											2020-04-21 15:02:36 -03:00
										 |  |  | 	lbl_count_start->set_tooltip(TTR("Initial value for the counter.")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	hbc_count_options->add_child(lbl_count_start); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spn_count_start = memnew(SpinBox); | 
					
						
							| 
									
										
										
										
											2020-04-21 15:02:36 -03:00
										 |  |  | 	spn_count_start->set_tooltip(TTR("Initial value for the counter.")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	spn_count_start->set_step(1); | 
					
						
							|  |  |  | 	spn_count_start->set_min(0); | 
					
						
							|  |  |  | 	hbc_count_options->add_child(spn_count_start); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label *lbl_count_step = memnew(Label); | 
					
						
							|  |  |  | 	lbl_count_step->set_text(TTR("Step")); | 
					
						
							| 
									
										
										
										
											2020-04-21 15:02:36 -03:00
										 |  |  | 	lbl_count_step->set_tooltip(TTR("Amount by which counter is incremented for each node.")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	hbc_count_options->add_child(lbl_count_step); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spn_count_step = memnew(SpinBox); | 
					
						
							| 
									
										
										
										
											2020-04-21 15:02:36 -03:00
										 |  |  | 	spn_count_step->set_tooltip(TTR("Amount by which counter is incremented for each node.")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	spn_count_step->set_step(1); | 
					
						
							|  |  |  | 	hbc_count_options->add_child(spn_count_step); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label *lbl_count_padding = memnew(Label); | 
					
						
							|  |  |  | 	lbl_count_padding->set_text(TTR("Padding")); | 
					
						
							| 
									
										
										
										
											2018-08-28 21:15:04 +03:00
										 |  |  | 	lbl_count_padding->set_tooltip(TTR("Minimum number of digits for the counter.\nMissing digits are padded with leading zeros.")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	hbc_count_options->add_child(lbl_count_padding); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spn_count_padding = memnew(SpinBox); | 
					
						
							| 
									
										
										
										
											2018-08-28 21:15:04 +03:00
										 |  |  | 	spn_count_padding->set_tooltip(TTR("Minimum number of digits for the counter.\nMissing digits are padded with leading zeros.")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	spn_count_padding->set_step(1); | 
					
						
							|  |  |  | 	hbc_count_options->add_child(spn_count_padding); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ---- Tab Process
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	VBoxContainer *vbc_process = memnew(VBoxContainer); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	vbc_process->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	vbc_process->set_name(TTR("Post-Process")); | 
					
						
							|  |  |  | 	tabc_features->add_child(vbc_process); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 17:30:44 +02:00
										 |  |  | 	cbut_process = memnew(CheckBox); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	cbut_process->set_text(TTR("Post-Process")); | 
					
						
							|  |  |  | 	vbc_process->add_child(cbut_process); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ------ Style
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HBoxContainer *hbc_style = memnew(HBoxContainer); | 
					
						
							|  |  |  | 	vbc_process->add_child(hbc_style); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label *lbl_style = memnew(Label); | 
					
						
							|  |  |  | 	lbl_style->set_text(TTR("Style")); | 
					
						
							|  |  |  | 	hbc_style->add_child(lbl_style); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	opt_style = memnew(OptionButton); | 
					
						
							|  |  |  | 	opt_style->add_item(TTR("Keep")); | 
					
						
							| 
									
										
										
										
											2020-01-19 21:22:16 +01:00
										 |  |  | 	opt_style->add_item(TTR("PascalCase to snake_case")); | 
					
						
							|  |  |  | 	opt_style->add_item(TTR("snake_case to PascalCase")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	hbc_style->add_child(opt_style); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ------ Case
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HBoxContainer *hbc_case = memnew(HBoxContainer); | 
					
						
							|  |  |  | 	vbc_process->add_child(hbc_case); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label *lbl_case = memnew(Label); | 
					
						
							|  |  |  | 	lbl_case->set_text(TTR("Case")); | 
					
						
							|  |  |  | 	hbc_case->add_child(lbl_case); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	opt_case = memnew(OptionButton); | 
					
						
							|  |  |  | 	opt_case->add_item(TTR("Keep")); | 
					
						
							|  |  |  | 	opt_case->add_item(TTR("To Lowercase")); | 
					
						
							|  |  |  | 	opt_case->add_item(TTR("To Uppercase")); | 
					
						
							|  |  |  | 	hbc_case->add_child(opt_case); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// -- Preview
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HSeparator *sep_preview = memnew(HSeparator); | 
					
						
							|  |  |  | 	sep_preview->set_custom_minimum_size(Size2(10, 20)); | 
					
						
							|  |  |  | 	vbc->add_child(sep_preview); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbl_preview_title = memnew(Label); | 
					
						
							|  |  |  | 	vbc->add_child(lbl_preview_title); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lbl_preview = memnew(Label); | 
					
						
							|  |  |  | 	vbc->add_child(lbl_preview); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ---- Dialog related
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	set_min_size(Size2(383, 0)); | 
					
						
							| 
									
										
										
										
											2020-12-14 18:37:30 +00:00
										 |  |  | 	get_ok_button()->set_text(TTR("Rename")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	Button *but_reset = add_button(TTR("Reset")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	eh.errfunc = _error_handler; | 
					
						
							|  |  |  | 	eh.userdata = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ---- Connections
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	cbut_collapse_features->connect("toggled", callable_mp(this, &RenameDialog::_features_toggled)); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 15:57:07 -03:00
										 |  |  | 	// Substitute Buttons
 | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	lne_search->connect("focus_entered", callable_mp(this, &RenameDialog::_update_substitute)); | 
					
						
							|  |  |  | 	lne_search->connect("focus_exited", callable_mp(this, &RenameDialog::_update_substitute)); | 
					
						
							|  |  |  | 	lne_replace->connect("focus_entered", callable_mp(this, &RenameDialog::_update_substitute)); | 
					
						
							|  |  |  | 	lne_replace->connect("focus_exited", callable_mp(this, &RenameDialog::_update_substitute)); | 
					
						
							|  |  |  | 	lne_prefix->connect("focus_entered", callable_mp(this, &RenameDialog::_update_substitute)); | 
					
						
							|  |  |  | 	lne_prefix->connect("focus_exited", callable_mp(this, &RenameDialog::_update_substitute)); | 
					
						
							|  |  |  | 	lne_suffix->connect("focus_entered", callable_mp(this, &RenameDialog::_update_substitute)); | 
					
						
							|  |  |  | 	lne_suffix->connect("focus_exited", callable_mp(this, &RenameDialog::_update_substitute)); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Preview
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	lne_prefix->connect("text_changed", callable_mp(this, &RenameDialog::_update_preview)); | 
					
						
							|  |  |  | 	lne_suffix->connect("text_changed", callable_mp(this, &RenameDialog::_update_preview)); | 
					
						
							|  |  |  | 	lne_search->connect("text_changed", callable_mp(this, &RenameDialog::_update_preview)); | 
					
						
							|  |  |  | 	lne_replace->connect("text_changed", callable_mp(this, &RenameDialog::_update_preview)); | 
					
						
							|  |  |  | 	spn_count_start->connect("value_changed", callable_mp(this, &RenameDialog::_update_preview_int)); | 
					
						
							|  |  |  | 	spn_count_step->connect("value_changed", callable_mp(this, &RenameDialog::_update_preview_int)); | 
					
						
							|  |  |  | 	spn_count_padding->connect("value_changed", callable_mp(this, &RenameDialog::_update_preview_int)); | 
					
						
							|  |  |  | 	opt_style->connect("item_selected", callable_mp(this, &RenameDialog::_update_preview_int)); | 
					
						
							|  |  |  | 	opt_case->connect("item_selected", callable_mp(this, &RenameDialog::_update_preview_int)); | 
					
						
							|  |  |  | 	cbut_substitute->connect("pressed", callable_mp(this, &RenameDialog::_update_preview), varray("")); | 
					
						
							|  |  |  | 	cbut_regex->connect("pressed", callable_mp(this, &RenameDialog::_update_preview), varray("")); | 
					
						
							|  |  |  | 	cbut_process->connect("pressed", callable_mp(this, &RenameDialog::_update_preview), varray("")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	but_reset->connect("pressed", callable_mp(this, &RenameDialog::reset)); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	reset(); | 
					
						
							|  |  |  | 	_features_toggled(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method("rename", &RenameDialog::rename); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::_update_substitute() { | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	LineEdit *focus_owner_line_edit = Object::cast_to<LineEdit>(scene_tree_editor->get_focus_owner()); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 	bool is_main_field = _is_main_field(focus_owner_line_edit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	but_insert_name->set_disabled(!is_main_field); | 
					
						
							|  |  |  | 	but_insert_parent->set_disabled(!is_main_field); | 
					
						
							|  |  |  | 	but_insert_type->set_disabled(!is_main_field); | 
					
						
							|  |  |  | 	but_insert_scene->set_disabled(!is_main_field); | 
					
						
							|  |  |  | 	but_insert_root->set_disabled(!is_main_field); | 
					
						
							|  |  |  | 	but_insert_count->set_disabled(!is_main_field); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// The focus mode seems to be reset when disabling/re-enabling
 | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	but_insert_name->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							|  |  |  | 	but_insert_parent->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							|  |  |  | 	but_insert_type->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							|  |  |  | 	but_insert_scene->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							|  |  |  | 	but_insert_root->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							|  |  |  | 	but_insert_count->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::_post_popup() { | 
					
						
							|  |  |  | 	EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection(); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	preview_node = nullptr; | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Array selected_node_list = editor_selection->get_selected_nodes(); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(selected_node_list.size() == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	preview_node = selected_node_list[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_update_preview(); | 
					
						
							|  |  |  | 	_update_substitute(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::_update_preview_int(int new_value) { | 
					
						
							|  |  |  | 	_update_preview(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::_update_preview(String new_text) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (lock_preview_update || preview_node == nullptr) { | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	has_errors = false; | 
					
						
							|  |  |  | 	add_error_handler(&eh); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String new_name = _apply_rename(preview_node, spn_count_start->get_value()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!has_errors) { | 
					
						
							| 
									
										
										
										
											2020-08-14 15:57:07 -03:00
										 |  |  | 		lbl_preview_title->set_text(TTR("Preview:")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		lbl_preview->set_text(new_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (new_name == preview_node->get_name()) { | 
					
						
							| 
									
										
										
										
											2020-01-19 21:22:16 +01:00
										 |  |  | 			// New name is identical to the old one. Don't color it as much to avoid distracting the user.
 | 
					
						
							| 
									
										
										
										
											2020-03-12 09:37:40 -03:00
										 |  |  | 			const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color("accent_color", "Editor"); | 
					
						
							|  |  |  | 			const Color text_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color("default_color", "RichTextLabel"); | 
					
						
							| 
									
										
										
										
											2020-03-16 05:07:33 -04:00
										 |  |  | 			lbl_preview->add_theme_color_override("font_color", accent_color.lerp(text_color, 0.5)); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2020-03-12 09:37:40 -03:00
										 |  |  | 			lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("success_color", "Editor")); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	remove_error_handler(&eh); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String RenameDialog::_apply_rename(const Node *node, int count) { | 
					
						
							|  |  |  | 	String search = lne_search->get_text(); | 
					
						
							|  |  |  | 	String replace = lne_replace->get_text(); | 
					
						
							|  |  |  | 	String prefix = lne_prefix->get_text(); | 
					
						
							|  |  |  | 	String suffix = lne_suffix->get_text(); | 
					
						
							|  |  |  | 	String new_name = node->get_name(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cbut_substitute->is_pressed()) { | 
					
						
							|  |  |  | 		search = _substitute(search, node, count); | 
					
						
							|  |  |  | 		replace = _substitute(replace, node, count); | 
					
						
							|  |  |  | 		prefix = _substitute(prefix, node, count); | 
					
						
							|  |  |  | 		suffix = _substitute(suffix, node, count); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cbut_regex->is_pressed()) { | 
					
						
							|  |  |  | 		new_name = _regex(search, new_name, replace); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		new_name = new_name.replace(search, replace); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	new_name = prefix + new_name + suffix; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cbut_process->is_pressed()) { | 
					
						
							|  |  |  | 		new_name = _postprocess(new_name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return new_name; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String RenameDialog::_substitute(const String &subject, const Node *node, int count) { | 
					
						
							|  |  |  | 	String result = subject.replace("${COUNTER}", vformat("%0" + itos(spn_count_padding->get_value()) + "d", count)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (node) { | 
					
						
							|  |  |  | 		result = result.replace("${NAME}", node->get_name()); | 
					
						
							|  |  |  | 		result = result.replace("${TYPE}", node->get_class()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int current = EditorNode::get_singleton()->get_editor_data().get_edited_scene(); | 
					
						
							| 
									
										
										
										
											2020-01-19 18:48:59 +01:00
										 |  |  | 	// Always request the scene title with the extension stripped.
 | 
					
						
							|  |  |  | 	// Otherwise, the result could vary depending on whether a scene with the same name
 | 
					
						
							|  |  |  | 	// (but different extension) is currently open.
 | 
					
						
							|  |  |  | 	result = result.replace("${SCENE}", EditorNode::get_singleton()->get_editor_data().get_scene_title(current, true)); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Node *root_node = SceneTree::get_singleton()->get_edited_scene_root(); | 
					
						
							|  |  |  | 	if (root_node) { | 
					
						
							|  |  |  | 		result = result.replace("${ROOT}", root_node->get_name()); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 	if (node) { | 
					
						
							|  |  |  | 		Node *parent_node = node->get_parent(); | 
					
						
							|  |  |  | 		if (parent_node) { | 
					
						
							|  |  |  | 			if (node == root_node) { | 
					
						
							|  |  |  | 				// Can not substitute parent of root.
 | 
					
						
							|  |  |  | 				result = result.replace("${PARENT}", ""); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				result = result.replace("${PARENT}", parent_node->get_name()); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type) { | 
					
						
							|  |  |  | 	RenameDialog *self = (RenameDialog *)p_self; | 
					
						
							|  |  |  | 	String source_file(p_file); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Only show first error that is related to "regex"
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (self->has_errors || source_file.find("regex") < 0) { | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	String err_str; | 
					
						
							|  |  |  | 	if (p_errorexp && p_errorexp[0]) { | 
					
						
							|  |  |  | 		err_str = p_errorexp; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		err_str = p_error; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	self->has_errors = true; | 
					
						
							| 
									
										
										
										
											2020-08-14 15:57:07 -03:00
										 |  |  | 	self->lbl_preview_title->set_text(TTR("Regular Expression Error:")); | 
					
						
							| 
									
										
										
										
											2020-03-12 09:37:40 -03:00
										 |  |  | 	self->lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("error_color", "Editor")); | 
					
						
							| 
									
										
										
										
											2020-01-19 21:22:16 +01:00
										 |  |  | 	self->lbl_preview->set_text(vformat(TTR("At character %s"), err_str)); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String RenameDialog::_regex(const String &pattern, const String &subject, const String &replacement) { | 
					
						
							|  |  |  | 	RegEx regex(pattern); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return regex.sub(subject, replacement, true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String RenameDialog::_postprocess(const String &subject) { | 
					
						
							|  |  |  | 	int style_id = opt_style->get_selected(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String result = subject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (style_id == 1) { | 
					
						
							| 
									
										
										
										
											2020-01-19 21:22:16 +01:00
										 |  |  | 		// PascalCase to snake_case
 | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		result = result.camelcase_to_underscore(true); | 
					
						
							|  |  |  | 		result = _regex("_+", result, "_"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (style_id == 2) { | 
					
						
							| 
									
										
										
										
											2020-01-19 21:22:16 +01:00
										 |  |  | 		// snake_case to PascalCase
 | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		RegEx pattern("_+(.?)"); | 
					
						
							|  |  |  | 		Array matches = pattern.search_all(result); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-19 21:22:16 +01:00
										 |  |  | 		// The name `_` would become empty; ignore it.
 | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		if (matches.size() && result != "_") { | 
					
						
							|  |  |  | 			String buffer; | 
					
						
							|  |  |  | 			int start = 0; | 
					
						
							|  |  |  | 			int end = 0; | 
					
						
							|  |  |  | 			for (int i = 0; i < matches.size(); ++i) { | 
					
						
							|  |  |  | 				start = ((Ref<RegExMatch>)matches[i])->get_start(1); | 
					
						
							|  |  |  | 				buffer += result.substr(end, start - end - 1); | 
					
						
							|  |  |  | 				buffer += result.substr(start, 1).to_upper(); | 
					
						
							|  |  |  | 				end = start + 1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			buffer += result.substr(end, result.size() - (end + 1)); | 
					
						
							|  |  |  | 			result = buffer.replace("_", "").capitalize(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int case_id = opt_case->get_selected(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (case_id == 1) { | 
					
						
							|  |  |  | 		// To Lowercase
 | 
					
						
							|  |  |  | 		result = result.to_lower(); | 
					
						
							|  |  |  | 	} else if (case_id == 2) { | 
					
						
							|  |  |  | 		// To Upercase
 | 
					
						
							|  |  |  | 		result = result.to_upper(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::_iterate_scene(const Node *node, const Array &selection, int *counter) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!node) { | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (selection.has(node)) { | 
					
						
							|  |  |  | 		String new_name = _apply_rename(node, *counter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (node->get_name() != new_name) { | 
					
						
							|  |  |  | 			Pair<NodePath, String> rename_item; | 
					
						
							|  |  |  | 			rename_item.first = node->get_path(); | 
					
						
							|  |  |  | 			rename_item.second = new_name; | 
					
						
							|  |  |  | 			to_rename.push_back(rename_item); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		*counter += spn_count_step->get_value(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int *cur_counter = counter; | 
					
						
							|  |  |  | 	int level_counter = spn_count_start->get_value(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (chk_per_level_counter->is_pressed()) { | 
					
						
							|  |  |  | 		cur_counter = &level_counter; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < node->get_child_count(); ++i) { | 
					
						
							|  |  |  | 		_iterate_scene(node->get_child(i), selection, cur_counter); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::rename() { | 
					
						
							|  |  |  | 	// Editor selection is not ordered via scene tree. Instead iterate
 | 
					
						
							|  |  |  | 	// over scene tree until all selected nodes are found in order.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection(); | 
					
						
							|  |  |  | 	Array selected_node_list = editor_selection->get_selected_nodes(); | 
					
						
							|  |  |  | 	Node *root_node = SceneTree::get_singleton()->get_edited_scene_root(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	global_count = spn_count_start->get_value(); | 
					
						
							|  |  |  | 	to_rename.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Forward recursive as opposed to the actual renaming.
 | 
					
						
							|  |  |  | 	_iterate_scene(root_node, selected_node_list, &global_count); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 	if (undo_redo && !to_rename.is_empty()) { | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		undo_redo->create_action(TTR("Batch Rename")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Make sure to iterate reversed so that child nodes will find parents.
 | 
					
						
							|  |  |  | 		for (int i = to_rename.size() - 1; i >= 0; --i) { | 
					
						
							|  |  |  | 			Node *n = root_node->get_node(to_rename[i].first); | 
					
						
							|  |  |  | 			const String &new_name = to_rename[i].second; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!n) { | 
					
						
							| 
									
										
										
										
											2019-11-06 17:03:04 +01:00
										 |  |  | 				ERR_PRINT("Skipping missing node: " + to_rename[i].first.get_concatenated_subnames()); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			scene_tree_editor->emit_signal("node_prerename", n, new_name); | 
					
						
							|  |  |  | 			undo_redo->add_do_method(scene_tree_editor, "_rename_node", n->get_instance_id(), new_name); | 
					
						
							|  |  |  | 			undo_redo->add_undo_method(scene_tree_editor, "_rename_node", n->get_instance_id(), n->get_name()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		undo_redo->commit_action(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::reset() { | 
					
						
							|  |  |  | 	lock_preview_update = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lne_prefix->clear(); | 
					
						
							|  |  |  | 	lne_suffix->clear(); | 
					
						
							|  |  |  | 	lne_search->clear(); | 
					
						
							|  |  |  | 	lne_replace->clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cbut_substitute->set_pressed(false); | 
					
						
							|  |  |  | 	cbut_regex->set_pressed(false); | 
					
						
							|  |  |  | 	cbut_process->set_pressed(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	chk_per_level_counter->set_pressed(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spn_count_start->set_value(1); | 
					
						
							|  |  |  | 	spn_count_step->set_value(1); | 
					
						
							|  |  |  | 	spn_count_padding->set_value(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	opt_style->select(0); | 
					
						
							|  |  |  | 	opt_case->select(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lock_preview_update = false; | 
					
						
							|  |  |  | 	_update_preview(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RenameDialog::_is_main_field(LineEdit *line_edit) { | 
					
						
							|  |  |  | 	return line_edit && | 
					
						
							|  |  |  | 		   (line_edit == lne_search || line_edit == lne_replace || line_edit == lne_prefix || line_edit == lne_suffix); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::_insert_text(String text) { | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  | 	LineEdit *focus_owner = Object::cast_to<LineEdit>(scene_tree_editor->get_focus_owner()); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (_is_main_field(focus_owner)) { | 
					
						
							|  |  |  | 		focus_owner->selection_delete(); | 
					
						
							| 
									
										
										
										
											2021-03-28 19:31:25 +01:00
										 |  |  | 		focus_owner->insert_text_at_caret(text); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:12:25 -05:00
										 |  |  | 		_update_preview(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RenameDialog::_features_toggled(bool pressed) { | 
					
						
							|  |  |  | 	if (pressed) { | 
					
						
							|  |  |  | 		tabc_features->show(); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		tabc_features->hide(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Adjust to minimum size in y
 | 
					
						
							|  |  |  | 	Size2i size = get_size(); | 
					
						
							|  |  |  | 	size.y = 0; | 
					
						
							|  |  |  | 	set_size(size); | 
					
						
							|  |  |  | } |