Explorar o código

Merge pull request #55611 from KoBeWi/yet_another_nice_backport

[3.x] Improve save handling for built-in scripts
Rémi Verschelde %!s(int64=3) %!d(string=hai) anos
pai
achega
8cedf916bc

+ 4 - 1
editor/editor_node.cpp

@@ -1548,8 +1548,10 @@ void EditorNode::_save_scene(String p_file, int idx) {
 
 
 	err = ResourceSaver::save(p_file, sdata, flg);
 	err = ResourceSaver::save(p_file, sdata, flg);
 
 
-	_save_external_resources();
+	// This needs to be emitted before saving external resources.
+	emit_signal("scene_saved", p_file);
 
 
+	_save_external_resources();
 	editor_data.save_editor_external_data();
 	editor_data.save_editor_external_data();
 
 
 	for (List<Ref<AnimatedValuesBackup>>::Element *E = anim_backups.front(); E; E = E->next()) {
 	for (List<Ref<AnimatedValuesBackup>>::Element *E = anim_backups.front(); E; E = E->next()) {
@@ -5668,6 +5670,7 @@ void EditorNode::_bind_methods() {
 	ADD_SIGNAL(MethodInfo("request_help_search"));
 	ADD_SIGNAL(MethodInfo("request_help_search"));
 	ADD_SIGNAL(MethodInfo("script_add_function_request", PropertyInfo(Variant::OBJECT, "obj"), PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::POOL_STRING_ARRAY, "args")));
 	ADD_SIGNAL(MethodInfo("script_add_function_request", PropertyInfo(Variant::OBJECT, "obj"), PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::POOL_STRING_ARRAY, "args")));
 	ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj")));
 	ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj")));
+	ADD_SIGNAL(MethodInfo("scene_saved", PropertyInfo(Variant::STRING, "path")));
 }
 }
 
 
 static Node *_resource_get_edited_scene() {
 static Node *_resource_get_edited_scene() {

+ 47 - 20
editor/plugins/script_editor_plugin.cpp

@@ -770,10 +770,6 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) {
 
 
 		RES script = se->get_edited_resource();
 		RES script = se->get_edited_resource();
 
 
-		if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
-			continue; //internal script, who cares
-		}
-
 		if (script == p_res) {
 		if (script == p_res) {
 			se->tag_saved_version();
 			se->tag_saved_version();
 		}
 		}
@@ -783,6 +779,26 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) {
 	_trigger_live_script_reload();
 	_trigger_live_script_reload();
 }
 }
 
 
+void ScriptEditor::_scene_saved_callback(const String &p_path) {
+	// If scene was saved, mark all built-in scripts from that scene as saved.
+	for (int i = 0; i < tab_container->get_child_count(); i++) {
+		ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+		if (!se) {
+			continue;
+		}
+
+		RES edited_res = se->get_edited_resource();
+
+		if (!edited_res->get_path().empty() && edited_res->get_path().find("::") == -1) {
+			continue; // External script, who cares.
+		}
+
+		if (edited_res->get_path().get_slice("::", 0) == p_path) {
+			se->tag_saved_version();
+		}
+	}
+}
+
 void ScriptEditor::_trigger_live_script_reload() {
 void ScriptEditor::_trigger_live_script_reload() {
 	if (!pending_auto_reload && auto_reload_running_scripts) {
 	if (!pending_auto_reload && auto_reload_running_scripts) {
 		call_deferred("_live_auto_reload_running_scripts");
 		call_deferred("_live_auto_reload_running_scripts");
@@ -1349,6 +1365,7 @@ void ScriptEditor::_notification(int p_what) {
 			editor->connect("stop_pressed", this, "_editor_stop");
 			editor->connect("stop_pressed", this, "_editor_stop");
 			editor->connect("script_add_function_request", this, "_add_callback");
 			editor->connect("script_add_function_request", this, "_add_callback");
 			editor->connect("resource_saved", this, "_res_saved_callback");
 			editor->connect("resource_saved", this, "_res_saved_callback");
+			editor->connect("scene_saved", this, "_scene_saved_callback");
 			script_list->connect("item_selected", this, "_script_selected");
 			script_list->connect("item_selected", this, "_script_selected");
 
 
 			members_overview->connect("item_selected", this, "_members_overview_selected");
 			members_overview->connect("item_selected", this, "_members_overview_selected");
@@ -1431,7 +1448,7 @@ void ScriptEditor::close_builtin_scripts_from_scene(const String &p_scene) {
 			}
 			}
 
 
 			if (script->get_path().find("::") != -1 && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed
 			if (script->get_path().find("::") != -1 && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed
-				_close_tab(i);
+				_close_tab(i, false);
 				i--;
 				i--;
 			}
 			}
 		}
 		}
@@ -1732,20 +1749,7 @@ void ScriptEditor::_update_script_names() {
 		if (se) {
 		if (se) {
 			Ref<Texture> icon = se->get_icon();
 			Ref<Texture> icon = se->get_icon();
 			String path = se->get_edited_resource()->get_path();
 			String path = se->get_edited_resource()->get_path();
-			bool built_in = !path.is_resource_file();
-			String name;
-
-			if (built_in) {
-				name = path.get_file();
-				const String &resource_name = se->get_edited_resource()->get_name();
-				if (resource_name != "") {
-					// If the built-in script has a custom resource name defined,
-					// display the built-in script name as follows: `ResourceName (scene_file.tscn)`
-					name = vformat("%s (%s)", resource_name, name.substr(0, name.find("::", 0)));
-				}
-			} else {
-				name = se->get_name();
-			}
+			String name = se->get_name();
 
 
 			_ScriptEditorItemData sd;
 			_ScriptEditorItemData sd;
 			sd.icon = icon;
 			sd.icon = icon;
@@ -2184,10 +2188,22 @@ void ScriptEditor::save_current_script() {
 		return;
 		return;
 	}
 	}
 
 
-	editor->save_resource(resource);
+	if (resource->get_path().empty() || resource->get_path().find("::") != -1) {
+		// If built-in script, save the scene instead.
+		const String scene_path = resource->get_path().get_slice("::", 0);
+		if (!scene_path.empty()) {
+			Vector<String> scene_to_save;
+			scene_to_save.push_back(scene_path);
+			editor->save_scene_list(scene_to_save);
+		}
+	} else {
+		editor->save_resource(resource);
+	}
 }
 }
 
 
 void ScriptEditor::save_all_scripts() {
 void ScriptEditor::save_all_scripts() {
+	Vector<String> scenes_to_save;
+
 	for (int i = 0; i < tab_container->get_child_count(); i++) {
 	for (int i = 0; i < tab_container->get_child_count(); i++) {
 		ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
 		ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
 		if (!se) {
 		if (!se) {
@@ -2224,9 +2240,19 @@ void ScriptEditor::save_all_scripts() {
 				continue;
 				continue;
 			}
 			}
 			editor->save_resource(edited_res); //external script, save it
 			editor->save_resource(edited_res); //external script, save it
+		} else {
+			// For built-in scripts, save their scenes instead.
+			const String scene_path = edited_res->get_path().get_slice("::", 0);
+			if (scenes_to_save.find(scene_path) > -1) {
+				scenes_to_save.push_back(scene_path);
+			}
 		}
 		}
 	}
 	}
 
 
+	if (!scenes_to_save.empty()) {
+		editor->save_scene_list(scenes_to_save);
+	}
+
 	_update_script_names();
 	_update_script_names();
 	EditorFileSystem::get_singleton()->update_script_classes();
 	EditorFileSystem::get_singleton()->update_script_classes();
 }
 }
@@ -3097,6 +3123,7 @@ void ScriptEditor::_bind_methods() {
 	ClassDB::bind_method("_reload_scripts", &ScriptEditor::_reload_scripts);
 	ClassDB::bind_method("_reload_scripts", &ScriptEditor::_reload_scripts);
 	ClassDB::bind_method("_resave_scripts", &ScriptEditor::_resave_scripts);
 	ClassDB::bind_method("_resave_scripts", &ScriptEditor::_resave_scripts);
 	ClassDB::bind_method("_res_saved_callback", &ScriptEditor::_res_saved_callback);
 	ClassDB::bind_method("_res_saved_callback", &ScriptEditor::_res_saved_callback);
+	ClassDB::bind_method("_scene_saved_callback", &ScriptEditor::_scene_saved_callback);
 	ClassDB::bind_method("_goto_script_line", &ScriptEditor::_goto_script_line);
 	ClassDB::bind_method("_goto_script_line", &ScriptEditor::_goto_script_line);
 	ClassDB::bind_method("_goto_script_line2", &ScriptEditor::_goto_script_line2);
 	ClassDB::bind_method("_goto_script_line2", &ScriptEditor::_goto_script_line2);
 	ClassDB::bind_method("_set_execution", &ScriptEditor::_set_execution);
 	ClassDB::bind_method("_set_execution", &ScriptEditor::_set_execution);

+ 1 - 0
editor/plugins/script_editor_plugin.h

@@ -321,6 +321,7 @@ class ScriptEditor : public PanelContainer {
 
 
 	void _add_callback(Object *p_obj, const String &p_function, const PoolStringArray &p_args);
 	void _add_callback(Object *p_obj, const String &p_function, const PoolStringArray &p_args);
 	void _res_saved_callback(const Ref<Resource> &p_res);
 	void _res_saved_callback(const Ref<Resource> &p_res);
+	void _scene_saved_callback(const String &p_path);
 
 
 	bool trim_trailing_whitespace_on_save;
 	bool trim_trailing_whitespace_on_save;
 	bool use_space_indentation;
 	bool use_space_indentation;

+ 14 - 8
editor/plugins/script_text_editor.cpp

@@ -524,15 +524,21 @@ void ScriptTextEditor::ensure_focus() {
 String ScriptTextEditor::get_name() {
 String ScriptTextEditor::get_name() {
 	String name;
 	String name;
 
 
-	if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
-		name = script->get_path().get_file();
-		if (is_unsaved()) {
-			name += "(*)";
+	name = script->get_path().get_file();
+	if (name.empty()) {
+		// This appears for newly created built-in scripts before saving the scene.
+		name = TTR("[unsaved]");
+	} else if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
+		const String &script_name = script->get_name();
+		if (script_name != "") {
+			// If the built-in script has a custom resource name defined,
+			// display the built-in script name as follows: `ResourceName (scene_file.tscn)`
+			name = vformat("%s (%s)", script_name, name.get_slice("::", 0));
 		}
 		}
-	} else if (script->get_name() != "") {
-		name = script->get_name();
-	} else {
-		name = script->get_class() + "(" + itos(script->get_instance_id()) + ")";
+	}
+
+	if (is_unsaved()) {
+		name += "(*)";
 	}
 	}
 
 
 	return name;
 	return name;

+ 14 - 8
editor/plugins/text_editor.cpp

@@ -150,15 +150,21 @@ void TextEditor::_load_theme_settings() {
 String TextEditor::get_name() {
 String TextEditor::get_name() {
 	String name;
 	String name;
 
 
-	if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) {
-		name = text_file->get_path().get_file();
-		if (is_unsaved()) {
-			name += "(*)";
+	name = text_file->get_path().get_file();
+	if (name.empty()) {
+		// This appears for newly created built-in text_files before saving the scene.
+		name = TTR("[unsaved]");
+	} else if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) {
+		const String &text_file_name = text_file->get_name();
+		if (text_file_name != "") {
+			// If the built-in text_file has a custom resource name defined,
+			// display the built-in text_file name as follows: `ResourceName (scene_file.tscn)`
+			name = vformat("%s (%s)", text_file_name, name.get_slice("::", 0));
 		}
 		}
-	} else if (text_file->get_name() != "") {
-		name = text_file->get_name();
-	} else {
-		name = text_file->get_class() + "(" + itos(text_file->get_instance_id()) + ")";
+	}
+
+	if (is_unsaved()) {
+		name += "(*)";
 	}
 	}
 
 
 	return name;
 	return name;

+ 14 - 8
modules/visual_script/visual_script_editor.cpp

@@ -2481,15 +2481,21 @@ void VisualScriptEditor::reload_text() {
 String VisualScriptEditor::get_name() {
 String VisualScriptEditor::get_name() {
 	String name;
 	String name;
 
 
-	if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
-		name = script->get_path().get_file();
-		if (is_unsaved()) {
-			name += "(*)";
+	name = script->get_path().get_file();
+	if (name.empty()) {
+		// This appears for newly created built-in scripts before saving the scene.
+		name = TTR("[unsaved]");
+	} else if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
+		const String &script_name = script->get_name();
+		if (script_name != "") {
+			// If the built-in script has a custom resource name defined,
+			// display the built-in script name as follows: `ResourceName (scene_file.tscn)`
+			name = vformat("%s (%s)", script_name, name.get_slice("::", 0));
 		}
 		}
-	} else if (script->get_name() != "") {
-		name = script->get_name();
-	} else {
-		name = script->get_class() + "(" + itos(script->get_instance_id()) + ")";
+	}
+
+	if (is_unsaved()) {
+		name += "(*)";
 	}
 	}
 
 
 	return name;
 	return name;