diff --git a/Source/Engine/Platform/Linux/LinuxFileSystem.cpp b/Source/Engine/Platform/Linux/LinuxFileSystem.cpp index f8ad0d476..8efcba2a4 100644 --- a/Source/Engine/Platform/Linux/LinuxFileSystem.cpp +++ b/Source/Engine/Platform/Linux/LinuxFileSystem.cpp @@ -30,7 +30,6 @@ bool LinuxFileSystem::ShowOpenFileDialog(Window* parentWindow, const StringView& const StringAsANSI<> initialDirectoryAnsi(*initialDirectory, initialDirectory.Length()); const StringAsANSI<> titleAnsi(*title, title.Length()); const char* initDir = initialDirectory.HasChars() ? initialDirectoryAnsi.Get() : "."; - char cmd[2048]; String xdgCurrentDesktop; StringBuilder fileFilter; Array fileFilterEntries; @@ -39,6 +38,7 @@ bool LinuxFileSystem::ShowOpenFileDialog(Window* parentWindow, const StringView& const bool zenitySupported = FileSystem::FileExists(TEXT("/usr/bin/zenity")); const bool kdialogSupported = FileSystem::FileExists(TEXT("/usr/bin/kdialog")); + char cmd[2048]; if (zenitySupported && (xdgCurrentDesktop != TEXT("KDE") || !kdialogSupported)) // Prefer kdialog when running on KDE { for (int32 i = 1; i < fileFilterEntries.Count(); i += 2) @@ -87,6 +87,51 @@ bool LinuxFileSystem::ShowOpenFileDialog(Window* parentWindow, const StringView& return false; } +bool LinuxFileSystem::ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path) +{ + const StringAsANSI<> titleAnsi(*title, title.Length()); + String xdgCurrentDesktop; + Platform::GetEnvironmentVariable(TEXT("XDG_CURRENT_DESKTOP"), xdgCurrentDesktop); + + // TODO: support initialDirectory + + const bool zenitySupported = FileSystem::FileExists(TEXT("/usr/bin/zenity")); + const bool kdialogSupported = FileSystem::FileExists(TEXT("/usr/bin/kdialog")); + char cmd[2048]; + if (zenitySupported && (xdgCurrentDesktop != TEXT("KDE") || !kdialogSupported)) // Prefer kdialog when running on KDE + { + sprintf(cmd, "/usr/bin/zenity --modal --file-selection --directory --title=\"%s\" ", titleAnsi.Get()); + } + else if (kdialogSupported) + { + sprintf(cmd, "/usr/bin/kdialog --getexistingdirectory --title \"%s\" ", titleAnsi.Get()); + } + else + { + LOG(Error, "Missing file picker (install zenity or kdialog)."); + return true; + } + FILE* f = popen(cmd, "r"); + char buf[2048]; + fgets(buf, ARRAY_COUNT(buf), f); + int result = pclose(f); + if (result != 0) + return true; + + const char* c = buf; + while (*c) + { + const char* start = c; + while (*c != '\n') + c++; + path = String(start, (int32)(c - start)); + if (path.HasChars()) + break; + c++; + } + return false; +} + bool LinuxFileSystem::ShowFileExplorer(const StringView& path) { const StringAsANSI<> pathAnsi(*path, path.Length()); diff --git a/Source/Engine/Platform/Linux/LinuxFileSystem.h b/Source/Engine/Platform/Linux/LinuxFileSystem.h index cce89bcb8..6184d6720 100644 --- a/Source/Engine/Platform/Linux/LinuxFileSystem.h +++ b/Source/Engine/Platform/Linux/LinuxFileSystem.h @@ -15,6 +15,7 @@ public: // [FileSystemBase] static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array& filenames); + static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path); static bool ShowFileExplorer(const StringView& path); static bool CreateDirectory(const StringView& path); static bool DeleteDirectory(const String& path, bool deleteContents = true);