Repository: godotengine/godot (language: cpp)

Issue:
Invalid script extension is also invalid path
**Godot version:**
3.2.1

**Issue description:**
![vB4BVUbTtM](https://user-images.githubusercontent.com/2223172/79026379-ed95af00-7b88-11ea-9d3d-3708c9fec5fb.gif)
Shouldn't it be only the latter? Both paths are technically valid.


Discussion / hints:
In `script_create_dialog.cpp`, before the path is validated, the variable `is_path_valid` is set to `false`, which is correct.

However, the path validation that happens in the `_validate_path` method also checks for a valid extension. When it can't find one, it returns an error ("Invalid extension") and lets the `_update_dialog` method change the state of the dialog. But this method looks at the `is_path_valid` flag to determine if the "Invalid path" message should be displayed.

IMHO the user should be warned that the extension is invalid, but the "Invalid path" message should not be displayed, and the "Create" button should not be disabled.
> IMHO the user should be warned that the extension is invalid, but the "Invalid path" message should not be displayed, and the "Create" button should not be disabled.

Godot depends on the extension to identify the file type and if it's not correct some things may not work. So the button should be disabled if the extension is invalid. I agree the "invalid path" message should not happen in this case.

Fix patch:
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 5001e5189de2..2b0f8214710e 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -216,7 +216,7 @@ bool ScriptCreateDialog::_validate_parent(const String &p_string) {
 
 	if (can_inherit_from_file && p_string.is_quoted()) {
 		String p = p_string.substr(1, p_string.length() - 2);
-		if (_validate_path(p, true) == "") {
+		if (_validate_path(p, true).is_empty()) {
 			return true;
 		}
 	}
@@ -224,8 +224,11 @@ bool ScriptCreateDialog::_validate_parent(const String &p_string) {
 	return EditorNode::get_editor_data().is_type_recognized(p_string);
 }
 
-String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must_exist) {
+String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must_exist, bool *r_path_valid) {
 	String p = p_path.strip_edges();
+	if (r_path_valid) {
+		*r_path_valid = false;
+	}
 
 	if (p.is_empty()) {
 		return TTR("Path is empty.");
@@ -263,6 +266,10 @@ String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must
 		}
 	}
 
+	if (r_path_valid) {
+		*r_path_valid = true;
+	}
+
 	// Check file extension.
 	String extension = p.get_extension();
 	List<String> extensions;
@@ -491,10 +498,9 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
 		return;
 	}
 
-	is_path_valid = false;
 	is_new_script_created = true;
 
-	path_error = _validate_path(p_path, false);
+	path_error = _validate_path(p_path, false, &is_path_valid);
 	if (!path_error.is_empty()) {
 		validation_panel->update();
 		return;
@@ -506,8 +512,6 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
 	if (da->file_exists(p)) {
 		is_new_script_created = false;
 	}
-
-	is_path_valid = true;
 	validation_panel->update();
 }
 
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index c8f043b42013..728029b9b3d0 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -99,7 +99,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
 	void _built_in_pressed();
 	void _use_template_pressed();
 	bool _validate_parent(const String &p_string);
-	String _validate_path(const String &p_path, bool p_file_must_exist);
+	String _validate_path(const String &p_path, bool p_file_must_exist, bool *r_path_valid = nullptr);
 	void _parent_name_changed(const String &p_parent);
 	void _template_changed(int p_template = 0);
 	void _browse_path(bool browse_parent, bool p_save);


Test patch: