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

New commits:
commit d79a41a02cd46c50cab08ba1a5d5b213b6843251
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Wed Jun 5 14:04:24 2019 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Mon Dec 9 15:32:17 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 <glo...@fbihome.de>

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";
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to