Browse Source

Merge pull request #28455 from DrNochi/bugfix/script-dialog-path-with-spaces

Handle spaces correctly for base / parent scripts in the "New Script" dialog
Rémi Verschelde 6 years ago
parent
commit
47338a8056
2 changed files with 77 additions and 93 deletions
  1. 76 93
      editor/script_create_dialog.cpp
  2. 1 0
      editor/script_create_dialog.h

+ 76 - 93
editor/script_create_dialog.cpp

@@ -105,8 +105,12 @@ bool ScriptCreateDialog::_validate(const String &p_string) {
 	if (p_string.length() == 0)
 		return false;
 
-	String path_chars = "\"res://";
-	bool is_val_path = ScriptServer::get_language(language_menu->get_selected())->can_inherit_from_file();
+	if (ScriptServer::get_language(language_menu->get_selected())->can_inherit_from_file() && p_string.is_quoted()) {
+		String p = p_string.substr(1, p_string.length() - 2);
+		if (_validate_path(p, true) == "")
+			return true;
+	}
+
 	for (int i = 0; i < p_string.length(); i++) {
 
 		if (i == 0) {
@@ -114,17 +118,7 @@ bool ScriptCreateDialog::_validate(const String &p_string) {
 				return false; // no start with number plz
 		}
 
-		if (i == p_string.length() - 1 && is_val_path)
-			return p_string[i] == '\"';
-
-		if (is_val_path && i < path_chars.length()) {
-			if (p_string[i] != path_chars[i])
-				is_val_path = false;
-			else
-				continue;
-		}
-
-		bool valid_char = (p_string[i] >= '0' && p_string[i] <= '9') || (p_string[i] >= 'a' && p_string[i] <= 'z') || (p_string[i] >= 'A' && p_string[i] <= 'Z') || p_string[i] == '_' || p_string[i] == '-' || (is_val_path && (p_string[i] == '/' || p_string[i] == '.'));
+		bool valid_char = (p_string[i] >= '0' && p_string[i] <= '9') || (p_string[i] >= 'a' && p_string[i] <= 'z') || (p_string[i] >= 'A' && p_string[i] <= 'Z') || p_string[i] == '_' || p_string[i] == '-';
 
 		if (!valid_char)
 			return false;
@@ -133,6 +127,70 @@ bool ScriptCreateDialog::_validate(const String &p_string) {
 	return true;
 }
 
+String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must_exist) {
+
+	String p = p_path.strip_edges();
+
+	if (p == "") return TTR("Path is empty.");
+	if (p.get_file().get_basename() == "") return TTR("Filename is empty.");
+
+	p = ProjectSettings::get_singleton()->localize_path(p);
+	if (!p.begins_with("res://")) return TTR("Path is not local.");
+
+	DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+	if (d->change_dir(p.get_base_dir()) != OK) {
+		memdelete(d);
+		return TTR("Invalid base path.");
+	}
+	memdelete(d);
+
+	/* Does file already exist */
+	DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+	if (f->dir_exists(p)) {
+		memdelete(f);
+		return TTR("A directory with the same name exists.");
+	} else if (p_file_must_exist && !f->file_exists(p)) {
+		memdelete(f);
+		return TTR("File does not exist.");
+	}
+	memdelete(f);
+
+	/* Check file extension */
+	String extension = p.get_extension();
+	List<String> extensions;
+
+	// get all possible extensions for script
+	for (int l = 0; l < language_menu->get_item_count(); l++) {
+		ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
+	}
+
+	bool found = false;
+	bool match = false;
+	int index = 0;
+	for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
+		if (E->get().nocasecmp_to(extension) == 0) {
+			//FIXME (?) - changing language this way doesn't update controls, needs rework
+			//language_menu->select(index); // change Language option by extension
+			found = true;
+			if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) {
+				match = true;
+			}
+			break;
+		}
+		index++;
+	}
+
+	if (!found) return TTR("Invalid extension.");
+	if (!match) return TTR("Wrong extension chosen.");
+
+	/* Let ScriptLanguage do custom validation */
+	String path_error = ScriptServer::get_language(language_menu->get_selected())->validate_path(p);
+	if (path_error != "") return path_error;
+
+	/* All checks passed */
+	return "";
+}
+
 void ScriptCreateDialog::_class_name_changed(const String &p_name) {
 
 	if (_validate(class_name->get_text())) {
@@ -400,97 +458,22 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
 
 	is_path_valid = false;
 	is_new_script_created = true;
-	String p = p_path.strip_edges();
 
-	if (p == "") {
-		_msg_path_valid(false, TTR("Path is empty."));
-		_update_dialog();
-		return;
-	}
-
-	if (p.get_file().get_basename() == "") {
-		_msg_path_valid(false, TTR("Filename is empty."));
-		_update_dialog();
-		return;
-	}
-
-	p = ProjectSettings::get_singleton()->localize_path(p);
-	if (!p.begins_with("res://")) {
-		_msg_path_valid(false, TTR("Path is not local."));
-		_update_dialog();
-		return;
-	}
-
-	DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-	if (d->change_dir(p.get_base_dir()) != OK) {
-		_msg_path_valid(false, TTR("Invalid base path."));
-		memdelete(d);
+	String path_error = _validate_path(p_path, false);
+	if (path_error != "") {
+		_msg_path_valid(false, path_error);
 		_update_dialog();
 		return;
 	}
-	memdelete(d);
 
 	/* Does file already exist */
-
 	DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-	if (f->dir_exists(p)) {
+	String p = ProjectSettings::get_singleton()->localize_path(p_path.strip_edges());
+	if (f->file_exists(p)) {
 		is_new_script_created = false;
-		is_path_valid = false;
-		_msg_path_valid(false, TTR("A directory with the same name exists."));
-	} else if (f->file_exists(p)) {
-		is_new_script_created = false;
-		is_path_valid = true;
 		_msg_path_valid(true, TTR("File exists, it will be reused."));
 	}
 	memdelete(f);
-	_update_dialog();
-
-	/* Check file extension */
-
-	String extension = p.get_extension();
-	List<String> extensions;
-
-	// get all possible extensions for script
-	for (int l = 0; l < language_menu->get_item_count(); l++) {
-		ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
-	}
-
-	bool found = false;
-	bool match = false;
-	int index = 0;
-	for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-		if (E->get().nocasecmp_to(extension) == 0) {
-			//FIXME (?) - changing language this way doesn't update controls, needs rework
-			//language_menu->select(index); // change Language option by extension
-			found = true;
-			if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) {
-				match = true;
-			}
-			break;
-		}
-		index++;
-	}
-
-	if (!found) {
-		_msg_path_valid(false, TTR("Invalid extension."));
-		_update_dialog();
-		return;
-	}
-
-	if (!match) {
-		_msg_path_valid(false, TTR("Wrong extension chosen."));
-		_update_dialog();
-		return;
-	}
-
-	String path_error = ScriptServer::get_language(language_menu->get_selected())->validate_path(p);
-	if (path_error != "") {
-		_msg_path_valid(false, path_error);
-		_update_dialog();
-		return;
-	}
-
-	/* All checks passed */
 
 	is_path_valid = true;
 	_update_dialog();

+ 1 - 0
editor/script_create_dialog.h

@@ -87,6 +87,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
 	void _lang_changed(int l = 0);
 	void _built_in_pressed();
 	bool _validate(const String &p_string);
+	String _validate_path(const String &p_path, bool p_file_must_exist);
 	void _class_name_changed(const String &p_name);
 	void _parent_name_changed(const String &p_parent);
 	void _template_changed(int p_template = 0);