diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index e353e8a22fd..112a76ffa75 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -680,6 +680,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ONESHOT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_GROUP_ENABLE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INPUT_NAME);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_FILE_PATH);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NONE);
diff --git a/core/object/object.h b/core/object/object.h
index 4d3d340ca1a..5e826be7c02 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -95,6 +95,7 @@ enum PropertyHint {
PROPERTY_HINT_NO_NODEPATH, /// < this property will not contain a NodePath, regardless of type (Array, Dictionary, List, etc.). Needed for SceneTreeDock.
PROPERTY_HINT_GROUP_ENABLE, ///< used to make the property's group checkable. Only use for boolean types. Optional "feature" hint string force hides anything inside when unchecked.
PROPERTY_HINT_INPUT_NAME,
+ PROPERTY_HINT_FILE_PATH,
PROPERTY_HINT_MAX,
};
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 22b59e56a03..1991d877587 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -2815,7 +2815,7 @@
Hints that an integer property is a bitmask using the optionally named avoidance layers.
- Hints that a [String] property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
+ Hints that a [String] property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code]. By default the file will be stored as UID whenever available. You can use [ResourceUID] methods to convert it back to path. For storing a raw path, use [constant PROPERTY_HINT_FILE_PATH].
Hints that a [String] property is a path to a directory. Editing it will show a file dialog for picking the path.
@@ -2964,7 +2964,10 @@
- If it contains [code]"show_builtin"[/code], built-in input actions are included in the selection.
- If it contains [code]"loose_mode"[/code], loose mode is enabled. This allows inserting any action name even if it's not present in the input map.
-
+
+ Like [constant PROPERTY_HINT_FILE], but the property is stored as a raw path, not UID. That means the reference will be broken if you move the file. Consider using [constant PROPERTY_HINT_FILE] when possible.
+
+
Represents the size of the [enum PropertyHint] enum.
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 3c17cf00ba3..1960101cbaa 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -568,7 +568,7 @@ void EditorPropertyPath::_set_read_only(bool p_read_only) {
void EditorPropertyPath::_path_selected(const String &p_path) {
String full_path = p_path;
- if (!global) {
+ if (enable_uid) {
const ResourceUID::ID id = ResourceLoader::get_resource_uid(full_path);
if (id != ResourceUID::INVALID_ID) {
full_path = ResourceUID::get_singleton()->id_to_text(id);
@@ -629,10 +629,11 @@ void EditorPropertyPath::update_property() {
path->set_tooltip_text(full_path);
}
-void EditorPropertyPath::setup(const Vector &p_extensions, bool p_folder, bool p_global) {
+void EditorPropertyPath::setup(const Vector &p_extensions, bool p_folder, bool p_global, bool p_enable_uid) {
extensions = p_extensions;
folder = p_folder;
global = p_global;
+ enable_uid = p_enable_uid;
}
void EditorPropertyPath::set_save_mode() {
@@ -3801,13 +3802,14 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
EditorPropertyLocale *editor = memnew(EditorPropertyLocale);
editor->setup(p_hint_text);
return editor;
- } else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) {
+ } else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE || p_hint == PROPERTY_HINT_FILE_PATH) {
Vector extensions = p_hint_text.split(",");
bool global = p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE;
bool folder = p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_GLOBAL_DIR;
bool save = p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE;
+ bool enable_uid = p_hint == PROPERTY_HINT_FILE;
EditorPropertyPath *editor = memnew(EditorPropertyPath);
- editor->setup(extensions, folder, global);
+ editor->setup(extensions, folder, global, enable_uid);
if (save) {
editor->set_save_mode();
}
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 08adb99e3b5..20e38dbc506 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -161,6 +161,7 @@ class EditorPropertyPath : public EditorProperty {
bool folder = false;
bool global = false;
bool save_mode = false;
+ bool enable_uid = false;
EditorFileDialog *dialog = nullptr;
LineEdit *path = nullptr;
Button *path_edit = nullptr;
@@ -178,7 +179,7 @@ protected:
void _notification(int p_what);
public:
- void setup(const Vector &p_extensions, bool p_folder, bool p_global);
+ void setup(const Vector &p_extensions, bool p_folder, bool p_global, bool p_enable_uid);
void set_save_mode();
virtual void update_property() override;
EditorPropertyPath();
diff --git a/editor/export/editor_export_platform_apple_embedded.cpp b/editor/export/editor_export_platform_apple_embedded.cpp
index eab922e00db..3cef0355be4 100644
--- a/editor/export/editor_export_platform_apple_embedded.cpp
+++ b/editor/export/editor_export_platform_apple_embedded.cpp
@@ -351,9 +351,9 @@ void EditorExportPlatformAppleEmbedded::get_export_options(List *r
}
}
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024", PROPERTY_HINT_FILE, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024_dark", PROPERTY_HINT_FILE, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024_tinted", PROPERTY_HINT_FILE, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024", PROPERTY_HINT_FILE_PATH, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024_dark", PROPERTY_HINT_FILE_PATH, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024_tinted", PROPERTY_HINT_FILE_PATH, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), ""));
HashSet used_names;
@@ -361,9 +361,9 @@ void EditorExportPlatformAppleEmbedded::get_export_options(List *r
for (int i = 0; i < icon_infos.size(); ++i) {
if (!used_names.has(icon_infos[i].preset_key)) {
used_names.insert(icon_infos[i].preset_key);
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key), PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key) + "_dark", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key) + "_tinted", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key), PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key) + "_dark", PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key) + "_tinted", PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), ""));
}
}
}
diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp
index 98240dc862d..57cd2939bc3 100644
--- a/editor/export/project_export.cpp
+++ b/editor/export/project_export.cpp
@@ -280,7 +280,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
extension_vector.push_back("*." + extension);
}
- export_path->setup(extension_vector, false, true);
+ export_path->setup(extension_vector, false, true, false);
export_path->update_property();
advanced_options->set_disabled(false);
advanced_options->set_pressed(current->are_advanced_options_enabled());
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index de7fff1e4bc..2df20f1a8ea 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1635,7 +1635,7 @@ void FileSystemDock::_update_project_settings_after_move(const HashMap prop_info = ProjectSettings::get_singleton()->get_custom_property_info();
for (const KeyValue &E : prop_info) {
- if (E.value.hint == PROPERTY_HINT_FILE) {
+ if (E.value.hint == PROPERTY_HINT_FILE_PATH) {
String old_path = GLOBAL_GET(E.key);
if (p_renames.has(old_path)) {
ProjectSettings::get_singleton()->set_setting(E.key, p_renames[old_path]);
diff --git a/editor/gui/editor_file_dialog.cpp b/editor/gui/editor_file_dialog.cpp
index 177f5cb8dd9..223c48a4373 100644
--- a/editor/gui/editor_file_dialog.cpp
+++ b/editor/gui/editor_file_dialog.cpp
@@ -2191,7 +2191,7 @@ void EditorFileDialog::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List"), "set_display_mode", "get_display_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "file_mode", PROPERTY_HINT_ENUM, "Open one,Open many,Open folder,Open any,Save"), "set_file_mode", "get_file_mode");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir", PROPERTY_HINT_DIR, "", PROPERTY_USAGE_NONE), "set_current_dir", "get_current_dir");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE, "*", PROPERTY_USAGE_NONE), "set_current_file", "get_current_file");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE_PATH, "*", PROPERTY_USAGE_NONE), "set_current_file", "get_current_file");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_current_path", "get_current_path");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "filters"), "set_filters", "get_filters");
ADD_ARRAY_COUNT("Options", "option_count", "set_option_count", "get_option_count", "option_");
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 54812d687a8..73cb4ebd167 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -435,6 +435,14 @@
@export_file("*.txt") var notes_path: String
@export_file var level_paths: Array[String]
[/codeblock]
+ [b]Note:[/b] The file will be stored and referenced as UID, if available. This ensures that the reference is valid even when the file is moved. You can use [ResourceUID] methods to convert it to path.
+
+
+
+
+
+
+ Same as [annotation @export_file], except the file will be stored as a raw path. This means that it may become invalid when the file is moved. If you are exporting a [Resource] path, consider using [annotation @export_file] instead.
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 1bdd1da42f2..6cc79abea0c 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -102,6 +102,7 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations);
register_annotation(MethodInfo("@export_enum", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations, varray(), true);
register_annotation(MethodInfo("@export_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations, varray(""), true);
+ register_annotation(MethodInfo("@export_file_path", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations, varray(""), true);
register_annotation(MethodInfo("@export_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations);
register_annotation(MethodInfo("@export_global_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations, varray(""), true);
register_annotation(MethodInfo("@export_global_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations);
diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp
index 01c8c296f9a..2ba36c56f56 100644
--- a/platform/ios/export/export_plugin.cpp
+++ b/platform/ios/export/export_plugin.cpp
@@ -47,8 +47,8 @@ void EditorExportPlatformIOS::get_export_options(List *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/min_ios_version"), get_minimum_deployment_target()));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "storyboard/image_scale_mode", PROPERTY_HINT_ENUM, "Same as Logo,Center,Scale to Fit,Scale to Fill,Scale"), 0));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@2x", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@3x", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@2x", PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@3x", PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_custom_bg_color"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::COLOR, "storyboard/custom_bg_color"), Color()));
}
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index c4b73733472..48c03d418d7 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -1945,7 +1945,7 @@ void FileDialog::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "layout_toggle_enabled"), "set_customization_flag_enabled", "is_customization_flag_enabled", CUSTOMIZATION_LAYOUT);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir", PROPERTY_HINT_DIR, "", PROPERTY_USAGE_NONE), "set_current_dir", "get_current_dir");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE, "*", PROPERTY_USAGE_NONE), "set_current_file", "get_current_file");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE_PATH, "*", PROPERTY_USAGE_NONE), "set_current_file", "get_current_file");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_current_path", "get_current_path");
ADD_SIGNAL(MethodInfo("file_selected", PropertyInfo(Variant::STRING, "path")));
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index ea8034efbaa..4c93fe0383b 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -635,7 +635,7 @@ void HTTPRequest::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_http_proxy", "host", "port"), &HTTPRequest::set_http_proxy);
ClassDB::bind_method(D_METHOD("set_https_proxy", "host", "port"), &HTTPRequest::set_https_proxy);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE), "set_download_file", "get_download_file");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE_PATH), "set_download_file", "get_download_file");
ADD_PROPERTY(PropertyInfo(Variant::INT, "download_chunk_size", PROPERTY_HINT_RANGE, "256,16777216,suffix:B"), "set_download_chunk_size", "get_download_chunk_size");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "accept_gzip"), "set_accept_gzip", "is_accepting_gzip");