[Libreoffice-commits] core.git: Branch 'libreoffice-6-3' - vcl/inc vcl/qt5 vcl/unx

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Sun Jul 14 18:44:31 UTC 2019


 vcl/inc/qt5/Qt5FilePicker.hxx    |    5 ++++-
 vcl/inc/qt5/Qt5Instance.hxx      |    4 +++-
 vcl/qt5/Qt5FilePicker.cxx        |   27 +++++++++++++++++++++++++--
 vcl/qt5/Qt5Instance.cxx          |   16 +++++++++-------
 vcl/unx/kde5/KDE5FilePicker.hxx  |    3 ++-
 vcl/unx/kde5/KDE5FilePicker2.cxx |    5 +++--
 vcl/unx/kde5/KDE5SalInstance.cxx |   10 ++++++----
 vcl/unx/kde5/KDE5SalInstance.hxx |    3 ++-
 8 files changed, 54 insertions(+), 19 deletions(-)

New commits:
commit 4cbcbb0a45b243971eb2e1da88b28bc03829a18e
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Wed Jun 19 15:03:04 2019 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sun Jul 14 20:43:48 2019 +0200

    tdf#125971: map file URLs from QFileDialog to LO internal format
    
    jmux' suggestion at
    <https://bugs.documentfoundation.org/show_bug.cgi?id=125971#c7> turns out to be
    the correct fix after all; explained in a lengthy comment why that seemingly
    wrong call of translateToInternal happens to do the right thing.
    
    (Much of this patch is about passing the XComponentContext down to where it is
    now needed in Qt5FilePicker::getSelectedFiles.)
    
    Change-Id: I235554f8494cd3094a011d5a903059326db499fc
    Reviewed-on: https://gerrit.libreoffice.org/74359
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>
    (cherry picked from commit e2589f4584efcf0306ab69f7223abdd7469e3604)
    Reviewed-on: https://gerrit.libreoffice.org/75587
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

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 904267d76c48..8eee8ad955d9 100644
--- a/vcl/qt5/Qt5Instance.cxx
+++ b/vcl/qt5/Qt5Instance.cxx
@@ -405,32 +405,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; }


More information about the Libreoffice-commits mailing list