diff options
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/qt5/Qt5FilePicker.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/qt5/Qt5Instance.hxx | 4 | ||||
-rw-r--r-- | vcl/qt5/Qt5FilePicker.cxx | 27 | ||||
-rw-r--r-- | vcl/qt5/Qt5Instance.cxx | 16 | ||||
-rw-r--r-- | vcl/unx/kde5/KDE5FilePicker.hxx | 3 | ||||
-rw-r--r-- | vcl/unx/kde5/KDE5FilePicker2.cxx | 5 | ||||
-rw-r--r-- | vcl/unx/kde5/KDE5SalInstance.cxx | 10 | ||||
-rw-r--r-- | vcl/unx/kde5/KDE5SalInstance.hxx | 3 |
8 files changed, 54 insertions, 19 deletions
diff --git a/vcl/inc/qt5/Qt5FilePicker.hxx b/vcl/inc/qt5/Qt5FilePicker.hxx index 74d082a83aa0..d4e74b92ba15 100644 --- a/vcl/inc/qt5/Qt5FilePicker.hxx +++ b/vcl/inc/qt5/Qt5FilePicker.hxx @@ -58,6 +58,8 @@ class VCLPLUG_QT5_PUBLIC Qt5FilePicker : public QObject, public Qt5FilePicker_Ba Q_OBJECT private: + css::uno::Reference<css::uno::XComponentContext> m_context; + // whether to show (i.e. not remove) the file extension in the filter title, // e.g. whether to use "ODF Text Document (*.odt)" or just // "ODF Text Document" as filter title @@ -88,7 +90,8 @@ protected: public: // use non-native file dialog by default; there's no easy way to add custom widgets // in a generic way in the native one - explicit Qt5FilePicker(QFileDialog::FileMode, bool bShowFileExtensionInFilterTitle = false, + explicit Qt5FilePicker(css::uno::Reference<css::uno::XComponentContext> const& context, + QFileDialog::FileMode, bool bShowFileExtensionInFilterTitle = false, bool bUseNativeDialog = false); virtual ~Qt5FilePicker() override; diff --git a/vcl/inc/qt5/Qt5Instance.hxx b/vcl/inc/qt5/Qt5Instance.hxx index 2411cdb7f52c..881ac17803d4 100644 --- a/vcl/inc/qt5/Qt5Instance.hxx +++ b/vcl/inc/qt5/Qt5Instance.hxx @@ -78,7 +78,9 @@ Q_SIGNALS: void deleteObjectLaterSignal(QObject* pObject); protected: - virtual Qt5FilePicker* createPicker(QFileDialog::FileMode); + virtual Qt5FilePicker* + createPicker(css::uno::Reference<css::uno::XComponentContext> const& context, + QFileDialog::FileMode); public: explicit Qt5Instance(std::unique_ptr<QApplication>& pQApp, bool bUseCairo = false); diff --git a/vcl/qt5/Qt5FilePicker.cxx b/vcl/qt5/Qt5FilePicker.cxx index 084aa7622a0a..63b3ff79a2bc 100644 --- a/vcl/qt5/Qt5FilePicker.cxx +++ b/vcl/qt5/Qt5FilePicker.cxx @@ -33,6 +33,7 @@ #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp> #include <cppuhelper/interfacecontainer.h> #include <cppuhelper/supportsservice.hxx> #include <sal/log.hxx> @@ -77,9 +78,11 @@ uno::Sequence<OUString> FilePicker_getSupportedServiceNames() } } -Qt5FilePicker::Qt5FilePicker(QFileDialog::FileMode eMode, bool bShowFileExtensionInFilterTitle, +Qt5FilePicker::Qt5FilePicker(css::uno::Reference<css::uno::XComponentContext> const& context, + QFileDialog::FileMode eMode, bool bShowFileExtensionInFilterTitle, bool bUseNativeDialog) : Qt5FilePicker_Base(m_aHelperMutex) + , m_context(context) , m_bShowFileExtensionInFilterTitle(bShowFileExtensionInFilterTitle) , m_pFileDialog(new QFileDialog(nullptr, {}, QDir::homePath())) , m_bIsFolderPicker(eMode == QFileDialog::Directory) @@ -254,9 +257,29 @@ uno::Sequence<OUString> SAL_CALL Qt5FilePicker::getSelectedFiles() uno::Sequence<OUString> seq(urls.size()); + auto const trans = css::uri::ExternalUriReferenceTranslator::create(m_context); size_t i = 0; for (const QUrl& aURL : urls) - seq[i++] = toOUString(aURL.toString()); + { + // Unlike LO, QFileDialog (<https://doc.qt.io/qt-5/qfiledialog.html>) apparently always + // treats file-system pathnames as UTF-8--encoded, regardless of LANG/LC_CTYPE locale + // setting. And pathnames containing byte sequences that are not valid UTF-8 are apparently + // filtered out and not even displayed by QFileDialog, so aURL will always have a "payload" + // that matches the pathname's byte sequence. So the pathname's byte sequence (which + // happens to also be aURL's payload) in the LANG/LC_CTYPE encoding needs to be converted + // into LO's internal UTF-8 file URL encoding via + // XExternalUriReferenceTranslator::translateToInternal (which looks somewhat paradoxical as + // aURL.toEncoded() nominally already has a UTF-8 payload): + auto const extUrl = toOUString(aURL.toEncoded()); + auto intUrl = trans->translateToInternal(extUrl); + if (intUrl.isEmpty()) + { + // If translation failed, fall back to original URL: + SAL_WARN("vcl.qt5", "cannot convert <" << extUrl << "> from locale encoding to UTF-8"); + intUrl = extUrl; + } + seq[i++] = intUrl; + } return seq; } diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx index dc3df6446a67..d657ab729801 100644 --- a/vcl/qt5/Qt5Instance.cxx +++ b/vcl/qt5/Qt5Instance.cxx @@ -403,32 +403,34 @@ void Qt5Instance::ProcessEvent(SalUserEvent aEvent) aEvent.m_pFrame->CallCallback(aEvent.m_nEvent, aEvent.m_pData); } -Qt5FilePicker* Qt5Instance::createPicker(QFileDialog::FileMode eMode) +Qt5FilePicker* +Qt5Instance::createPicker(css::uno::Reference<css::uno::XComponentContext> const& context, + QFileDialog::FileMode eMode) { if (!IsMainThread()) { SolarMutexGuard g; Qt5FilePicker* pPicker; - RunInMainThread(std::function([&, this]() { pPicker = createPicker(eMode); })); + RunInMainThread(std::function([&, this]() { pPicker = createPicker(context, eMode); })); assert(pPicker); return pPicker; } - return new Qt5FilePicker(eMode); + return new Qt5FilePicker(context, eMode); } css::uno::Reference<css::ui::dialogs::XFilePicker2> -Qt5Instance::createFilePicker(const css::uno::Reference<css::uno::XComponentContext>&) +Qt5Instance::createFilePicker(const css::uno::Reference<css::uno::XComponentContext>& context) { return css::uno::Reference<css::ui::dialogs::XFilePicker2>( - createPicker(QFileDialog::ExistingFile)); + createPicker(context, QFileDialog::ExistingFile)); } css::uno::Reference<css::ui::dialogs::XFolderPicker2> -Qt5Instance::createFolderPicker(const css::uno::Reference<css::uno::XComponentContext>&) +Qt5Instance::createFolderPicker(const css::uno::Reference<css::uno::XComponentContext>& context) { return css::uno::Reference<css::ui::dialogs::XFolderPicker2>( - createPicker(QFileDialog::Directory)); + createPicker(context, QFileDialog::Directory)); } css::uno::Reference<css::uno::XInterface> diff --git a/vcl/unx/kde5/KDE5FilePicker.hxx b/vcl/unx/kde5/KDE5FilePicker.hxx index 32cbd4c92e7d..786a99b00777 100644 --- a/vcl/unx/kde5/KDE5FilePicker.hxx +++ b/vcl/unx/kde5/KDE5FilePicker.hxx @@ -34,7 +34,8 @@ protected: bool allowRemoteUrls; public: - explicit KDE5FilePicker(QFileDialog::FileMode); + explicit KDE5FilePicker(css::uno::Reference<css::uno::XComponentContext> const& context, + QFileDialog::FileMode); // XExecutableDialog functions virtual sal_Int16 SAL_CALL execute() override; diff --git a/vcl/unx/kde5/KDE5FilePicker2.cxx b/vcl/unx/kde5/KDE5FilePicker2.cxx index ac99b5d21066..cb778e2fd0f7 100644 --- a/vcl/unx/kde5/KDE5FilePicker2.cxx +++ b/vcl/unx/kde5/KDE5FilePicker2.cxx @@ -49,9 +49,10 @@ uno::Sequence<OUString> FilePicker_getSupportedServiceNames() // KDE5FilePicker -KDE5FilePicker::KDE5FilePicker(QFileDialog::FileMode eMode) +KDE5FilePicker::KDE5FilePicker(css::uno::Reference<css::uno::XComponentContext> const& context, + QFileDialog::FileMode eMode) // Native kde5 filepicker does not add file extension automatically - : Qt5FilePicker(eMode, true, true) + : Qt5FilePicker(context, eMode, true, true) , _layout(new QGridLayout(m_pExtraControls)) , allowRemoteUrls(false) { diff --git a/vcl/unx/kde5/KDE5SalInstance.cxx b/vcl/unx/kde5/KDE5SalInstance.cxx index 3a227fc7b2b6..0143212249ed 100644 --- a/vcl/unx/kde5/KDE5SalInstance.cxx +++ b/vcl/unx/kde5/KDE5SalInstance.cxx @@ -50,13 +50,15 @@ SalFrame* KDE5SalInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags nSt return pRet; } -Qt5FilePicker* KDE5SalInstance::createPicker(QFileDialog::FileMode eMode) +Qt5FilePicker* +KDE5SalInstance::createPicker(css::uno::Reference<css::uno::XComponentContext> const& context, + QFileDialog::FileMode eMode) { if (!IsMainThread()) { SolarMutexGuard g; Qt5FilePicker* pPicker; - RunInMainThread(std::function([&, this]() { pPicker = createPicker(eMode); })); + RunInMainThread(std::function([&, this]() { pPicker = createPicker(context, eMode); })); assert(pPicker); return pPicker; } @@ -65,8 +67,8 @@ Qt5FilePicker* KDE5SalInstance::createPicker(QFileDialog::FileMode eMode) // being used in the native file picker, which is only the case for KDE Plasma. // Therefore, return the plain qt5 one in order to not lose custom controls. if (Application::GetDesktopEnvironment() == "KDE5") - return new KDE5FilePicker(eMode); - return Qt5Instance::createPicker(eMode); + return new KDE5FilePicker(context, eMode); + return Qt5Instance::createPicker(context, eMode); } extern "C" { diff --git a/vcl/unx/kde5/KDE5SalInstance.hxx b/vcl/unx/kde5/KDE5SalInstance.hxx index 53993a5ecc34..a7c633f150e1 100644 --- a/vcl/unx/kde5/KDE5SalInstance.hxx +++ b/vcl/unx/kde5/KDE5SalInstance.hxx @@ -23,7 +23,8 @@ class KDE5SalInstance final : public Qt5Instance { - Qt5FilePicker* createPicker(QFileDialog::FileMode) override; + Qt5FilePicker* createPicker(css::uno::Reference<css::uno::XComponentContext> const& context, + QFileDialog::FileMode) override; SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle) override; bool hasNativeFileSelection() const override { return true; } |