Ported: [Windows, 3.x] Add support for handling network share paths. - bruvzg

11a7997a67
This commit is contained in:
Relintai 2022-07-28 19:33:43 +02:00
parent 69976cd190
commit 152f9728b0
8 changed files with 66 additions and 12 deletions

View File

@ -148,14 +148,18 @@ Error DirAccess::make_dir_recursive(String p_dir) {
full_dir = full_dir.replace("\\", "/"); full_dir = full_dir.replace("\\", "/");
//int slices = full_dir.get_slice_count("/");
String base; String base;
if (full_dir.begins_with("res://")) { if (full_dir.begins_with("res://")) {
base = "res://"; base = "res://";
} else if (full_dir.begins_with("user://")) { } else if (full_dir.begins_with("user://")) {
base = "user://"; base = "user://";
} else if (full_dir.is_network_share_path()) {
int pos = full_dir.find("/", 2);
ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER);
pos = full_dir.find("/", pos + 1);
ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER);
base = full_dir.substr(0, pos + 1);
} else if (full_dir.begins_with("/")) { } else if (full_dir.begins_with("/")) {
base = "/"; base = "/";
} else if (full_dir.find(":/") != -1) { } else if (full_dir.find(":/") != -1) {

View File

@ -3416,6 +3416,10 @@ String String::rstrip(const String &p_chars) const {
return substr(0, end + 1); return substr(0, end + 1);
} }
bool String::is_network_share_path() const {
return begins_with("//") || begins_with("\\\\");
}
String String::simplify_path() const { String String::simplify_path() const {
String s = *this; String s = *this;
String drive; String drive;
@ -3428,6 +3432,9 @@ String String::simplify_path() const {
} else if (s.begins_with("user://")) { } else if (s.begins_with("user://")) {
drive = "user://"; drive = "user://";
s = s.substr(7, s.length()); s = s.substr(7, s.length());
} else if (is_network_share_path()) {
drive = s.substr(0, 2);
s = s.substr(2, s.length() - 2);
} else if (s.begins_with("/") || s.begins_with("\\")) { } else if (s.begins_with("/") || s.begins_with("\\")) {
drive = s.substr(0, 1); drive = s.substr(0, 1);
s = s.substr(1, s.length() - 1); s = s.substr(1, s.length() - 1);
@ -4372,6 +4379,23 @@ String String::get_base_dir() const {
} }
} }
// Windows UNC network share path.
if (end == 0) {
if (is_network_share_path()) {
basepos = find("/", 2);
if (basepos == -1) {
basepos = find("\\", 2);
}
int servpos = find("/", basepos + 1);
if (servpos == -1) {
servpos = find("\\", basepos + 1);
}
if (servpos != -1) {
end = servpos + 1;
}
}
}
// unix root directory base // unix root directory base
if (end == 0) { if (end == 0) {
if (begins_with("/")) { if (begins_with("/")) {

View File

@ -356,6 +356,7 @@ public:
String get_file() const; String get_file() const;
static String humanize_size(uint64_t p_size); static String humanize_size(uint64_t p_size);
String simplify_path() const; String simplify_path() const;
bool is_network_share_path() const;
String append_path(const char *p_path) const; String append_path(const char *p_path) const;
String append_path(const String &p_path) const; String append_path(const String &p_path) const;
String path_clean_end_slash() const; String path_clean_end_slash() const;

View File

@ -159,8 +159,11 @@ Error DirAccessWindows::make_dir(String p_dir) {
bool success; bool success;
int err; int err;
p_dir = "\\\\?\\" + p_dir; //done according to if (!p_dir.is_network_share_path()) {
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx p_dir = "\\\\?\\" + p_dir;
// Add "\\?\" to the path to extend max. path length past 248, if it's not a network share UNC path.
// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
}
success = CreateDirectoryW(p_dir.c_str(), NULL); success = CreateDirectoryW(p_dir.c_str(), NULL);
err = GetLastError(); err = GetLastError();
@ -344,6 +347,10 @@ uint64_t DirAccessWindows::get_space_left() {
String DirAccessWindows::get_filesystem_type() const { String DirAccessWindows::get_filesystem_type() const {
String path = fix_path(const_cast<DirAccessWindows *>(this)->get_current_dir()); String path = fix_path(const_cast<DirAccessWindows *>(this)->get_current_dir());
if (path.is_network_share_path()) {
return "Network Share";
}
int unit_end = path.find(":"); int unit_end = path.find(":");
ERR_FAIL_COND_V(unit_end == -1, String()); ERR_FAIL_COND_V(unit_end == -1, String());
String unit = path.substr(0, unit_end + 1) + "\\"; String unit = path.substr(0, unit_end + 1) + "\\";

View File

@ -229,7 +229,14 @@ Vector<String> EditorFileDialog::get_selected_files() const {
void EditorFileDialog::update_dir() { void EditorFileDialog::update_dir() {
if (drives->is_visible()) { if (drives->is_visible()) {
drives->select(dir_access->get_current_drive()); if (dir_access->get_current_dir().is_network_share_path()) {
_update_drives(false);
drives->add_item(RTR("Network"));
drives->set_item_disabled(drives->get_item_count() - 1, true);
drives->select(drives->get_item_count() - 1);
} else {
drives->select(dir_access->get_current_drive());
}
} }
dir->set_text(dir_access->get_current_dir_without_drive()); dir->set_text(dir_access->get_current_dir_without_drive());
@ -1151,7 +1158,7 @@ void EditorFileDialog::_select_drive(int p_idx) {
_push_history(); _push_history();
} }
void EditorFileDialog::_update_drives() { void EditorFileDialog::_update_drives(bool p_select) {
int dc = dir_access->get_drive_count(); int dc = dir_access->get_drive_count();
if (dc == 0 || access != ACCESS_FILESYSTEM) { if (dc == 0 || access != ACCESS_FILESYSTEM) {
drives->hide(); drives->hide();
@ -1170,7 +1177,9 @@ void EditorFileDialog::_update_drives() {
drives->add_item(dir_access->get_drive(i)); drives->add_item(dir_access->get_drive(i));
} }
drives->select(dir_access->get_current_drive()); if (p_select) {
drives->select(dir_access->get_current_drive());
}
} }
} }

View File

@ -193,7 +193,7 @@ private:
void _delete_items(); void _delete_items();
void _update_drives(); void _update_drives(bool p_select = true);
void _go_up(); void _go_up();
void _go_back(); void _go_back();

View File

@ -138,7 +138,14 @@ void FileDialog::update_dir() {
dir->set_text(dir_access->get_current_dir_without_drive()); dir->set_text(dir_access->get_current_dir_without_drive());
if (drives->is_visible()) { if (drives->is_visible()) {
drives->select(dir_access->get_current_drive()); if (dir_access->get_current_dir().is_network_share_path()) {
_update_drives(false);
drives->add_item(RTR("Network"));
drives->set_item_disabled(drives->get_item_count() - 1, true);
drives->select(drives->get_item_count() - 1);
} else {
drives->select(dir_access->get_current_drive());
}
} }
// Deselect any item, to make "Select Current Folder" button text by default. // Deselect any item, to make "Select Current Folder" button text by default.
@ -758,7 +765,7 @@ void FileDialog::_select_drive(int p_idx) {
update_dir(); update_dir();
} }
void FileDialog::_update_drives() { void FileDialog::_update_drives(bool p_select) {
int dc = dir_access->get_drive_count(); int dc = dir_access->get_drive_count();
if (dc == 0 || access != ACCESS_FILESYSTEM) { if (dc == 0 || access != ACCESS_FILESYSTEM) {
drives->hide(); drives->hide();
@ -776,7 +783,9 @@ void FileDialog::_update_drives() {
drives->add_item(dir_access->get_drive(i)); drives->add_item(dir_access->get_drive(i));
} }
drives->select(dir_access->get_current_drive()); if (p_select) {
drives->select(dir_access->get_current_drive());
}
} }
} }

View File

@ -123,7 +123,7 @@ private:
void _make_dir_confirm(); void _make_dir_confirm();
void _go_up(); void _go_up();
void _update_drives(); void _update_drives(bool p_select = true);
void _unhandled_input(const Ref<InputEvent> &p_event); void _unhandled_input(const Ref<InputEvent> &p_event);