summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/qt5/Qt5FilePicker.hxx5
-rw-r--r--vcl/inc/qt5/Qt5Instance.hxx4
-rw-r--r--vcl/qt5/Qt5FilePicker.cxx27
-rw-r--r--vcl/qt5/Qt5Instance.cxx16
-rw-r--r--vcl/unx/kde5/KDE5FilePicker.hxx3
-rw-r--r--vcl/unx/kde5/KDE5FilePicker2.cxx5
-rw-r--r--vcl/unx/kde5/KDE5SalInstance.cxx10
-rw-r--r--vcl/unx/kde5/KDE5SalInstance.hxx3
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; }