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

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Mon Dec 9 16:18:43 UTC 2019


 vcl/inc/qt5/Qt5FilePicker.hxx |   21 ++++++---
 vcl/qt5/Qt5FilePicker.cxx     |   89 ++++++++++++++++++++++++++++++++----------
 2 files changed, 82 insertions(+), 28 deletions(-)

New commits:
commit e756a570cc18427a4ad61af15c42e3d8d54beb13
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Wed Jun 5 14:04:24 2019 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Mon Dec 9 17:17:56 2019 +0100

    tdf#129071 Qt5 set file picker parent widget
    
    If the XInitialization::initialize has a parent option, use that
    system window ID to find the parent Qt5Frame and set this as the
    parent of the file picker. This way the file picker doesn't show
    up as a separate window in the KDE task bar and get the proper
    icon. Just setting it transient to the parent is not enough.
    
    This also includes the terminate listener handling, so an open
    file picker won't prevent LO to shut down gracefully (which is
    handled independent from the document modified state).
    
    Change-Id: I62aef532e739e7fea9fe8a4b4e6c0e205faae1d9
    Reviewed-on: https://gerrit.libreoffice.org/74544
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
    (cherry picked from commit d79a41a02cd46c50cab08ba1a5d5b213b6843251)
    Reviewed-on: https://gerrit.libreoffice.org/84756

diff --git a/vcl/inc/qt5/Qt5FilePicker.hxx b/vcl/inc/qt5/Qt5FilePicker.hxx
index f88395c6acce..5fef2aaeae43 100644
--- a/vcl/inc/qt5/Qt5FilePicker.hxx
+++ b/vcl/inc/qt5/Qt5FilePicker.hxx
@@ -23,8 +23,9 @@
 
 #include <cppuhelper/compbase.hxx>
 
-#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
 #include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
 #include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
@@ -33,8 +34,6 @@
 #include <osl/conditn.hxx>
 #include <osl/mutex.hxx>
 
-#include <rtl/ustrbuf.hxx>
-
 #include <QtCore/QObject>
 #include <QtCore/QString>
 #include <QtCore/QStringList>
@@ -48,9 +47,10 @@ class QGridLayout;
 class QLabel;
 class QWidget;
 
-typedef ::cppu::WeakComponentImplHelper<
-    css::ui::dialogs::XFilePicker3, css::ui::dialogs::XFilePickerControlAccess,
-    css::ui::dialogs::XFolderPicker2, css::lang::XInitialization, css::lang::XServiceInfo>
+typedef ::cppu::WeakComponentImplHelper<css::frame::XTerminateListener, css::lang::XInitialization,
+                                        css::lang::XServiceInfo, css::ui::dialogs::XFilePicker3,
+                                        css::ui::dialogs::XFilePickerControlAccess,
+                                        css::ui::dialogs::XFolderPicker2>
     Qt5FilePicker_Base;
 
 class VCLPLUG_QT5_PUBLIC Qt5FilePicker : public QObject, public Qt5FilePicker_Base
@@ -75,6 +75,8 @@ private:
 
     const bool m_bIsFolderPicker;
 
+    QWidget* m_pParentWidget;
+
 protected:
     std::unique_ptr<QFileDialog> m_pFileDialog; ///< the file picker dialog
     QWidget* m_pExtraControls; ///< widget to contain extra custom controls
@@ -132,8 +134,7 @@ public:
     virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) override;
 
     // XEventListener
-    /// @throws css::uno::RuntimeException
-    virtual void disposing(const css::lang::EventObject& rEvent);
+    void SAL_CALL disposing(const css::lang::EventObject& rEvent) override;
     using cppu::WeakComponentImplHelperBase::disposing;
 
     // XServiceInfo
@@ -145,6 +146,10 @@ public:
     virtual OUString SAL_CALL getDirectory() override;
     virtual void SAL_CALL setDescription(const OUString& rDescription) override;
 
+    // XTerminateListener
+    void SAL_CALL queryTermination(const css::lang::EventObject& aEvent) override;
+    void SAL_CALL notifyTermination(const css::lang::EventObject& aEvent) override;
+
 protected:
     virtual void addCustomControl(sal_Int16 controlId);
     void setCustomControlWidgetLayout(QGridLayout* pLayout) { m_pLayout = pLayout; }
diff --git a/vcl/qt5/Qt5FilePicker.cxx b/vcl/qt5/Qt5FilePicker.cxx
index 10c25052fd8a..d37c28b33c11 100644
--- a/vcl/qt5/Qt5FilePicker.cxx
+++ b/vcl/qt5/Qt5FilePicker.cxx
@@ -25,8 +25,15 @@
 #include <Qt5Widget.hxx>
 #include <Qt5Instance.hxx>
 
+#include <com/sun/star/awt/SystemDependentXWindow.hpp>
+#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/TerminationVetoException.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
 #include <com/sun/star/lang/DisposedException.hpp>
 #include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/SystemDependent.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
@@ -36,6 +43,7 @@
 #include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp>
 #include <cppuhelper/interfacecontainer.h>
 #include <cppuhelper/supportsservice.hxx>
+#include <rtl/process.h>
 #include <sal/log.hxx>
 
 #include <QtCore/QDebug>
@@ -80,6 +88,7 @@ Qt5FilePicker::Qt5FilePicker(css::uno::Reference<css::uno::XComponentContext> co
     : Qt5FilePicker_Base(m_aHelperMutex)
     , m_context(context)
     , m_bIsFolderPicker(eMode == QFileDialog::Directory)
+    , m_pParentWidget(nullptr)
     , m_pFileDialog(new QFileDialog(nullptr, {}, QDir::homePath()))
     , m_pExtraControls(new QWidget())
 {
@@ -155,17 +164,16 @@ sal_Int16 SAL_CALL Qt5FilePicker::execute()
         return ret;
     }
 
-    vcl::Window* pWindow = ::Application::GetActiveTopWindow();
-    QWidget* pTransientParent = nullptr;
-    QWindow* pTransientWindow = nullptr;
-    if (pWindow)
+    QWidget* pTransientParent = m_pParentWidget;
+    if (!pTransientParent)
     {
-        Qt5Frame* pFrame = dynamic_cast<Qt5Frame*>(pWindow->ImplGetFrame());
-        assert(pFrame);
-        if (pFrame)
+        vcl::Window* pWindow = ::Application::GetActiveTopWindow();
+        if (pWindow)
         {
-            pTransientParent = pFrame->GetQWidget();
-            pTransientWindow = pTransientParent->window()->windowHandle();
+            Qt5Frame* pFrame = dynamic_cast<Qt5Frame*>(pWindow->ImplGetFrame());
+            assert(pFrame);
+            if (pFrame)
+                pTransientParent = pFrame->asChild();
         }
     }
 
@@ -174,16 +182,19 @@ sal_Int16 SAL_CALL Qt5FilePicker::execute()
     if (!m_aCurrentFilter.isEmpty())
         m_pFileDialog->selectNameFilter(m_aCurrentFilter);
 
-    if (pTransientParent)
-    {
-        m_pFileDialog->show();
-        m_pFileDialog->window()->windowHandle()->setTransientParent(pTransientWindow);
-        m_pFileDialog->setFocusProxy(pTransientParent);
-    }
-
     updateAutomaticFileExtension();
 
+    uno::Reference<css::frame::XDesktop> xDesktop(css::frame::Desktop::create(m_context),
+                                                  UNO_QUERY_THROW);
+
+    // will hide the window, so do before show
+    m_pFileDialog->setParent(pTransientParent, m_pFileDialog->windowFlags());
+    m_pFileDialog->show();
+    xDesktop->addTerminateListener(this);
     int result = m_pFileDialog->exec();
+    xDesktop->removeTerminateListener(this);
+    m_pFileDialog->setParent(nullptr, m_pFileDialog->windowFlags());
+
     if (QFileDialog::Rejected == result)
         return ExecutableDialogResults::CANCEL;
     return ExecutableDialogResults::OK;
@@ -679,9 +690,7 @@ void SAL_CALL Qt5FilePicker::initialize(const uno::Sequence<uno::Any>& args)
     // parameter checking
     uno::Any arg;
     if (args.getLength() == 0)
-    {
         throw lang::IllegalArgumentException("no arguments", static_cast<XFilePicker2*>(this), 1);
-    }
 
     arg = args[0];
 
@@ -805,11 +814,40 @@ void SAL_CALL Qt5FilePicker::initialize(const uno::Sequence<uno::Any>& args)
 
     m_pFileDialog->setAcceptMode(acceptMode);
     m_pFileDialog->setWindowTitle(getResString(resId));
+
+    css::uno::Reference<css::awt::XWindow> xParentWindow;
+    if (args.getLength() > 1)
+        args[1] >>= xParentWindow;
+    if (xParentWindow.is())
+    {
+        css::uno::Reference<css::awt::XSystemDependentWindowPeer> xSysWinPeer(xParentWindow,
+                                                                              css::uno::UNO_QUERY);
+        if (xSysWinPeer.is())
+        {
+            // the sal_*Int8 handling is strange, but it's public API - no way around
+            css::uno::Sequence<sal_Int8> aProcessIdent(16);
+            rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8*>(aProcessIdent.getArray()));
+            uno::Any aAny = xSysWinPeer->getWindowHandle(
+                aProcessIdent, css::lang::SystemDependent::SYSTEM_XWINDOW);
+            css::awt::SystemDependentXWindow xSysWin;
+            aAny >>= xSysWin;
+
+            const auto& pFrames = pSalInst->getFrames();
+            const long aWindowHandle = xSysWin.WindowHandle;
+            const auto it = std::find_if(pFrames.begin(), pFrames.end(),
+                                         [&aWindowHandle](auto pFrame) -> bool {
+                                             const SystemEnvData* pData = pFrame->GetSystemData();
+                                             return pData && long(pData->aWindow) == aWindowHandle;
+                                         });
+            if (it != pFrames.end())
+                m_pParentWidget = static_cast<Qt5Frame*>(*it)->asChild();
+        }
+    }
 }
 
-void SAL_CALL Qt5FilePicker::cancel() {}
+void SAL_CALL Qt5FilePicker::cancel() { m_pFileDialog->reject(); }
 
-void Qt5FilePicker::disposing(const lang::EventObject& rEvent)
+void SAL_CALL Qt5FilePicker::disposing(const lang::EventObject& rEvent)
 {
     uno::Reference<XFilePickerListener> xFilePickerListener(rEvent.Source, uno::UNO_QUERY);
 
@@ -819,6 +857,17 @@ void Qt5FilePicker::disposing(const lang::EventObject& rEvent)
     }
 }
 
+void SAL_CALL Qt5FilePicker::queryTermination(const css::lang::EventObject&)
+{
+    throw css::frame::TerminationVetoException();
+}
+
+void SAL_CALL Qt5FilePicker::notifyTermination(const css::lang::EventObject&)
+{
+    SolarMutexGuard aGuard;
+    m_pFileDialog->reject();
+}
+
 OUString SAL_CALL Qt5FilePicker::getImplementationName()
 {
     return "com.sun.star.ui.dialogs.Qt5FilePicker";


More information about the Libreoffice-commits mailing list