From b27c48f03538871f342c3839ee370ab26cc5bf7f Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 16 Apr 2022 18:19:27 +0200 Subject: [PATCH 1/2] Fix Zenity/Kdialog not opening in paths with single quotes --- src/openrct2-ui/UiContext.Linux.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/openrct2-ui/UiContext.Linux.cpp b/src/openrct2-ui/UiContext.Linux.cpp index dc5aea4315..4ea06f0b0f 100644 --- a/src/openrct2-ui/UiContext.Linux.cpp +++ b/src/openrct2-ui/UiContext.Linux.cpp @@ -133,6 +133,7 @@ namespace OpenRCT2::Ui { std::string result; std::string executablePath; + u8string directory = EscapePathForShell(desc.InitialDirectory + '/'); DIALOG_TYPE dtype = GetDialogApp(&executablePath); switch (dtype) { @@ -141,8 +142,8 @@ namespace OpenRCT2::Ui std::string action = (desc.Type == FileDialogType::Open) ? "--getopenfilename" : "--getsavefilename"; std::string filter = GetKDialogFilterString(desc.Filters); std::string cmd = String::StdFormat( - "%s --title '%s' %s '%s' '%s'", executablePath.c_str(), desc.Title.c_str(), action.c_str(), - desc.InitialDirectory.c_str(), filter.c_str()); + "%s --title '%s' %s %s '%s'", executablePath.c_str(), desc.Title.c_str(), action.c_str(), + directory.c_str(), filter.c_str()); std::string output; if (Platform::Execute(cmd, &output) == 0) { @@ -160,8 +161,8 @@ namespace OpenRCT2::Ui } std::string filters = GetZenityFilterString(desc.Filters); std::string cmd = String::StdFormat( - "%s %s --filename='%s/' %s --title='%s' / %s", executablePath.c_str(), action.c_str(), - desc.InitialDirectory.c_str(), flags.c_str(), desc.Title.c_str(), filters.c_str()); + "%s %s --filename=%s %s --title='%s' / %s", executablePath.c_str(), action.c_str(), directory.c_str(), + flags.c_str(), desc.Title.c_str(), filters.c_str()); std::string output; if (Platform::Execute(cmd, &output) == 0) { From 3890aa50b7b018b9d84be7f1abeb1b3a1af05725 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 16 Apr 2022 18:39:36 +0200 Subject: [PATCH 2/2] Fix filters KDialog They were case sensitive and did not display correctly. --- src/openrct2-ui/UiContext.Linux.cpp | 60 +++++++++++++---------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/openrct2-ui/UiContext.Linux.cpp b/src/openrct2-ui/UiContext.Linux.cpp index 4ea06f0b0f..212b4b21a7 100644 --- a/src/openrct2-ui/UiContext.Linux.cpp +++ b/src/openrct2-ui/UiContext.Linux.cpp @@ -357,57 +357,51 @@ namespace OpenRCT2::Ui bool first = true; for (const auto& filter : filters) { - // KDialog wants filters space-delimited and we don't expect ';' anywhere else - std::string pattern = filter.Pattern; - for (size_t i = 0; i < pattern.size(); i++) + if (!first) { - if (pattern[i] == ';') - { - pattern[i] = ' '; - } + filtersb << "\\n"; } + first = false; - if (first) - { - filtersb << String::StdFormat("%s | %s", pattern.c_str(), filter.Name.c_str()); - first = false; - } - else - { - filtersb << String::StdFormat("\\n%s | %s", pattern.c_str(), filter.Name.c_str()); - } + filtersb << filter.Name.c_str() << " ("; + AddFilterCaseInsensitive(filtersb, filter.Pattern); + filtersb << ")"; } return filtersb.str(); } static std::string GetZenityFilterString(const std::vector filters) { - // Zenity seems to be case sensitive, while KDialog isn't std::stringstream filtersb; for (const auto& filter : filters) { filtersb << " --file-filter='" << filter.Name << " | "; - for (char c : filter.Pattern) - { - if (c == ';') - { - filtersb << ' '; - } - else if (isalpha(static_cast(c))) - { - auto uc = static_cast(c); - filtersb << '[' << static_cast(tolower(uc)) << static_cast(toupper(uc)) << ']'; - } - else - { - filtersb << c; - } - } + AddFilterCaseInsensitive(filtersb, filter.Pattern); filtersb << "'"; } return filtersb.str(); } + static void AddFilterCaseInsensitive(std::stringstream& stream, u8string pattern) + { + for (char c : pattern) + { + if (c == ';') + { + stream << ' '; + } + else if (isalpha(static_cast(c))) + { + auto uc = static_cast(c); + stream << '[' << static_cast(tolower(uc)) << static_cast(toupper(uc)) << ']'; + } + else + { + stream << c; + } + } + } + static void ThrowMissingDialogApp() { auto uiContext = GetContext()->GetUiContext();