Merge pull request #117010 from bruvzg/voll_name_win
[Windows] Show drive names in file dialog.
This commit is contained in:
7 files changed
+100
-36
No files matched your search
@@ -265,11 +265,16 @@ int DirAccess::_get_drive_count() {
|
||||
return d->get_drive_count();
|
||||
}
|
||||
|
||||
String DirAccess::get_drive_name(int p_idx) {
|
||||
String DirAccess::_get_drive_name(int p_idx) {
|
||||
Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
return d->get_drive(p_idx);
|
||||
}
|
||||
|
||||
String DirAccess::_get_drive_label(int p_idx) {
|
||||
Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
return d->get_drive_label(p_idx);
|
||||
}
|
||||
|
||||
Error DirAccess::make_dir_absolute(const String &p_dir) {
|
||||
Ref<DirAccess> d = DirAccess::create_for_path(p_dir);
|
||||
return d->make_dir(p_dir);
|
||||
@@ -646,7 +651,8 @@ void DirAccess::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_directories"), &DirAccess::get_directories);
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("get_directories_at", "path"), &DirAccess::get_directories_at);
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("get_drive_count"), &DirAccess::_get_drive_count);
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("get_drive_name", "idx"), &DirAccess::get_drive_name);
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("get_drive_name", "idx"), &DirAccess::_get_drive_name);
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("get_drive_label", "idx"), &DirAccess::_get_drive_label);
|
||||
ClassDB::bind_method(D_METHOD("get_current_drive"), &DirAccess::get_current_drive);
|
||||
ClassDB::bind_method(D_METHOD("change_dir", "to_dir"), &DirAccess::change_dir);
|
||||
ClassDB::bind_method(D_METHOD("get_current_dir", "include_drive"), &DirAccess::get_current_dir, DEFVAL(true));
|
||||
|
||||
@@ -91,6 +91,7 @@ public:
|
||||
|
||||
virtual int get_drive_count() = 0;
|
||||
virtual String get_drive(int p_drive) = 0;
|
||||
virtual String get_drive_label(int p_drive) { return String(); }
|
||||
virtual int get_current_drive();
|
||||
virtual bool drives_are_shortcuts();
|
||||
|
||||
@@ -145,7 +146,8 @@ public:
|
||||
static Ref<DirAccess> create_temp(const String &p_prefix = "", bool p_keep = false, Error *r_error = nullptr);
|
||||
|
||||
static int _get_drive_count();
|
||||
static String get_drive_name(int p_idx);
|
||||
static String _get_drive_name(int p_idx);
|
||||
static String _get_drive_label(int p_idx);
|
||||
|
||||
static Error make_dir_absolute(const String &p_dir);
|
||||
static Error make_dir_recursive_absolute(const String &p_dir);
|
||||
|
||||
@@ -186,6 +186,14 @@
|
||||
On other platforms, the method returns 0.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_drive_label" qualifiers="static">
|
||||
<return type="String" />
|
||||
<param index="0" name="idx" type="int" />
|
||||
<description>
|
||||
On Windows, returns the label of the drive (partition) passed as an argument.
|
||||
On other platforms, or if the requested drive does not exist, returns an empty String.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_drive_name" qualifiers="static">
|
||||
<return type="String" />
|
||||
<param index="0" name="idx" type="int" />
|
||||
@@ -194,7 +202,7 @@
|
||||
On macOS, returns the path to the mounted volume passed as an argument.
|
||||
On Linux, returns the path to the mounted volume or GTK 3 bookmark passed as an argument.
|
||||
On Android (API level 30+), returns the path to the mounted volume as an argument.
|
||||
On other platforms, or if the requested drive does not exist, the method returns an empty String.
|
||||
On other platforms, or if the requested drive does not exist, returns an empty String.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_files">
|
||||
|
||||
@@ -135,16 +135,38 @@ void DirAccessWindows::list_dir_end() {
|
||||
}
|
||||
}
|
||||
|
||||
void DirAccessWindows::_update_drives() {
|
||||
drives.clear();
|
||||
DWORD mask = GetLogicalDrives();
|
||||
for (int i = 0; i < MAX_DRIVES; i++) {
|
||||
if (mask & (1 << i)) {
|
||||
String path = String::chr('A' + i) + ":";
|
||||
String label;
|
||||
char16_t wlabel[4096];
|
||||
if (GetVolumeInformationW((LPCWSTR)(path).utf16().get_data(), (LPWSTR)wlabel, 4096, nullptr, nullptr, nullptr, nullptr, 0)) {
|
||||
label = String::utf16(wlabel);
|
||||
}
|
||||
drives.push_back(DriveInfo{ path, label });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int DirAccessWindows::get_drive_count() {
|
||||
return drive_count;
|
||||
return drives.size();
|
||||
}
|
||||
|
||||
String DirAccessWindows::get_drive_label(int p_drive) {
|
||||
if (p_drive < 0 || p_drive >= (int)drives.size()) {
|
||||
return String();
|
||||
}
|
||||
return drives[p_drive].label;
|
||||
}
|
||||
|
||||
String DirAccessWindows::get_drive(int p_drive) {
|
||||
if (p_drive < 0 || p_drive >= drive_count) {
|
||||
return "";
|
||||
if (p_drive < 0 || p_drive >= (int)drives.size()) {
|
||||
return String();
|
||||
}
|
||||
|
||||
return String::chr(drives[p_drive]) + ":";
|
||||
return drives[p_drive].path;
|
||||
}
|
||||
|
||||
Error DirAccessWindows::change_dir(String p_dir) {
|
||||
@@ -485,15 +507,7 @@ DirAccessWindows::DirAccessWindows() {
|
||||
GetCurrentDirectoryW(real_current_dir_name.size(), (LPWSTR)real_current_dir_name.ptrw());
|
||||
current_dir = String::utf16((const char16_t *)real_current_dir_name.get_data());
|
||||
|
||||
DWORD mask = GetLogicalDrives();
|
||||
|
||||
for (int i = 0; i < MAX_DRIVES; i++) {
|
||||
if (mask & (1 << i)) { //DRIVE EXISTS
|
||||
|
||||
drives[drive_count] = 'A' + i;
|
||||
drive_count++;
|
||||
}
|
||||
}
|
||||
_update_drives();
|
||||
|
||||
change_dir(".");
|
||||
}
|
||||
|
||||
@@ -45,8 +45,13 @@ class DirAccessWindows : public DirAccess {
|
||||
DirAccessWindowsPrivate *p = nullptr;
|
||||
/* Windows stuff */
|
||||
|
||||
char drives[MAX_DRIVES] = { 0 }; // a-z:
|
||||
int drive_count = 0;
|
||||
struct DriveInfo {
|
||||
String path;
|
||||
String label;
|
||||
};
|
||||
|
||||
LocalVector<DriveInfo> drives;
|
||||
void _update_drives();
|
||||
|
||||
String current_dir;
|
||||
|
||||
@@ -65,6 +70,7 @@ public:
|
||||
|
||||
virtual int get_drive_count() override;
|
||||
virtual String get_drive(int p_drive) override;
|
||||
virtual String get_drive_label(int p_drive) override;
|
||||
|
||||
virtual Error change_dir(String p_dir) override; ///< can be relative or absolute, return false on success
|
||||
virtual String get_current_dir(bool p_include_drive = true) const override; ///< return current dir location
|
||||
|
||||
+42
-15
@@ -370,14 +370,24 @@ void FileDialog::update_dir() {
|
||||
if (drives->is_visible()) {
|
||||
if (dir_access->get_current_dir().is_network_share_path()) {
|
||||
_update_drives(false);
|
||||
drives->add_item(ETR("Network"));
|
||||
drives->set_item_disabled(-1, true);
|
||||
drives->select(drives->get_item_count() - 1);
|
||||
PopupMenu *pm = drives->get_popup();
|
||||
pm->add_item(ETR("Network"));
|
||||
Dictionary meta;
|
||||
meta["index"] = -1;
|
||||
meta["path"] = String();
|
||||
meta["name"] = ETR("Network");
|
||||
pm->set_item_metadata(-1, meta);
|
||||
pm->set_item_disabled(-1, true);
|
||||
drives->set_text(meta["name"]);
|
||||
selected_drive = pm->get_item_count() - 1;
|
||||
} else {
|
||||
PopupMenu *pm = drives->get_popup();
|
||||
int cur = dir_access->get_current_drive();
|
||||
for (int i = 0; i < drives->get_item_count(); i++) {
|
||||
if (drives->get_item_metadata(i).operator int() == cur) {
|
||||
drives->select(i);
|
||||
for (int i = 0; i < pm->get_item_count(); i++) {
|
||||
const Dictionary &meta = pm->get_item_metadata(i);
|
||||
if (meta["index"].operator int() == cur) {
|
||||
drives->set_text(meta["name"]);
|
||||
selected_drive = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -393,7 +403,7 @@ void FileDialog::_dir_submitted(String p_dir) {
|
||||
#ifdef WINDOWS_ENABLED
|
||||
if (root_prefix.is_empty() && drives->is_visible() && !new_dir.is_network_share_path() && new_dir.is_absolute_path() && new_dir.find(":/") == -1 && new_dir.find(":\\") == -1) {
|
||||
// Non network path without X:/ prefix on Windows, add drive letter.
|
||||
new_dir = drives->get_item_text(drives->get_selected()).path_join(new_dir);
|
||||
new_dir = drives->get_popup()->get_item_metadata(selected_drive).operator Dictionary()["path"].operator String().path_join(new_dir);
|
||||
}
|
||||
#endif
|
||||
if (!root_prefix.is_empty()) {
|
||||
@@ -1615,8 +1625,11 @@ void FileDialog::_make_dir() {
|
||||
}
|
||||
|
||||
void FileDialog::_select_drive(int p_idx) {
|
||||
String d = drives->get_item_text(p_idx);
|
||||
_change_dir(d);
|
||||
const Dictionary &meta = drives->get_popup()->get_item_metadata(p_idx);
|
||||
drives->set_text(meta["name"]);
|
||||
selected_drive = p_idx;
|
||||
|
||||
_change_dir(meta["path"]);
|
||||
filename_edit->set_text("");
|
||||
_push_history();
|
||||
}
|
||||
@@ -1662,7 +1675,8 @@ void FileDialog::_update_drives(bool p_select) {
|
||||
if (drive_map.size() == 0) {
|
||||
drives->hide();
|
||||
} else {
|
||||
drives->clear();
|
||||
PopupMenu *pm = drives->get_popup();
|
||||
pm->clear();
|
||||
Node *dp = drives->get_parent();
|
||||
if (dp) {
|
||||
dp->remove_child(drives);
|
||||
@@ -1672,10 +1686,22 @@ void FileDialog::_update_drives(bool p_select) {
|
||||
drives->show();
|
||||
|
||||
for (const KeyValue<int, String> &drv : drive_map) {
|
||||
drives->add_item(drv.value);
|
||||
drives->set_item_metadata(-1, drv.key);
|
||||
String display_name = drv.value;
|
||||
String lbl = dir_access->get_drive_label(drv.key);
|
||||
if (!lbl.is_empty()) {
|
||||
display_name = drv.value + " (" + lbl + ")";
|
||||
}
|
||||
pm->add_item(display_name);
|
||||
pm->set_item_tooltip(-1, drv.value);
|
||||
|
||||
Dictionary meta;
|
||||
meta["index"] = drv.key;
|
||||
meta["path"] = drv.value;
|
||||
meta["name"] = drv.value;
|
||||
pm->set_item_metadata(-1, meta);
|
||||
if (p_select && drv.key == cur) {
|
||||
drives->select(drives->get_item_count() - 1);
|
||||
drives->set_text(drv.value);
|
||||
selected_drive = drv.key;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2367,8 +2393,9 @@ FileDialog::FileDialog() {
|
||||
drives_container = memnew(HBoxContainer);
|
||||
top_toolbar->add_child(drives_container);
|
||||
|
||||
drives = memnew(OptionButton);
|
||||
drives->connect(SceneStringName(item_selected), callable_mp(this, &FileDialog::_select_drive));
|
||||
drives = memnew(MenuButton);
|
||||
drives->set_flat(false);
|
||||
drives->get_popup()->connect("index_pressed", callable_mp(this, &FileDialog::_select_drive));
|
||||
drives->set_accessibility_name(ETR("Drive"));
|
||||
top_toolbar->add_child(drives);
|
||||
|
||||
|
||||
@@ -214,7 +214,8 @@ private:
|
||||
Button *dir_up = nullptr;
|
||||
|
||||
HBoxContainer *drives_container = nullptr;
|
||||
OptionButton *drives = nullptr;
|
||||
MenuButton *drives = nullptr;
|
||||
int selected_drive = 0;
|
||||
LineEdit *directory_edit = nullptr;
|
||||
HBoxContainer *shortcuts_container = nullptr;
|
||||
|
||||
|
||||
Reference in new issue
Block a user