[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - framework/Library_fwe.mk framework/source include/framework include/vcl uui/source vcl/source

Caolán McNamara caolanm at redhat.com
Fri Dec 1 01:15:46 UTC 2017


 framework/Library_fwe.mk                                         |    1 
 framework/source/dispatch/closedispatcher.cxx                    |   10 
 framework/source/fwe/interaction/preventduplicateinteraction.cxx |   10 
 framework/source/loadenv/loadenv.cxx                             |    6 
 include/framework/preventduplicateinteraction.hxx                |  112 ++++++++++
 include/vcl/dialog.hxx                                           |   10 
 include/vcl/msgbox.hxx                                           |    3 
 include/vcl/svapp.hxx                                            |    6 
 uui/source/iahndl.cxx                                            |   33 --
 vcl/source/app/svapp.cxx                                         |   16 -
 vcl/source/window/dialog.cxx                                     |   12 -
 vcl/source/window/msgbox.cxx                                     |    8 
 12 files changed, 138 insertions(+), 89 deletions(-)

New commits:
commit 77359a2350cf121937d5d646c17621557ab832fe
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Nov 2 17:23:00 2017 +0000

    Resolves: tdf#113160 changing all warning dialogs to non-modal is unsafe
    
    existing code doesn't expect that so stuff crashes
    
    partial revert of...
    
    commit db6b703d391838c481fd090065f6d329edcd4efa
    Date:   Thu Aug 24 18:32:38 2017 +0200
    
        Allow non-modal Dialogs during FileImport/Load
    
    Change-Id: I152feb849186cf035664a700d3f94ee049cdf6d3
    Reviewed-on: https://gerrit.libreoffice.org/44227
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    
    Related: tdf#113160 set a temporary dialog parent during type detection
    
    to get warning dialogs that don't block the existing windows but whose
    lifecycle can be controlled to avoid crashes during exit
    
    Change-Id: I57965301c3d8a031acb33e83bf7715fe132385d0
    Reviewed-on: https://gerrit.libreoffice.org/45044
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    Reviewed-on: https://gerrit.libreoffice.org/45400
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/framework/Library_fwe.mk b/framework/Library_fwe.mk
index 0559236b2bad..d94cb100a975 100644
--- a/framework/Library_fwe.mk
+++ b/framework/Library_fwe.mk
@@ -46,6 +46,7 @@ $(eval $(call gb_Library_use_libraries,fwe,\
     svl \
     svt \
     tl \
+    tk \
     utl \
     vcl \
 	$(gb_UWINAPI) \
diff --git a/framework/source/dispatch/closedispatcher.cxx b/framework/source/dispatch/closedispatcher.cxx
index 9aa25190a544..96df4fe9d9e5 100644
--- a/framework/source/dispatch/closedispatcher.cxx
+++ b/framework/source/dispatch/closedispatcher.cxx
@@ -36,8 +36,6 @@
 #include <vcl/window.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/syswin.hxx>
-#include <osl/mutex.hxx>
-#include <vcl/dialog.hxx>
 #include <unotools/moduleoptions.hxx>
 #include <comphelper/processfactory.hxx>
 
@@ -363,14 +361,6 @@ IMPL_LINK_NOARG_TYPED(CloseDispatcher, impl_asyncCallback, LinkParamNone*, void)
         }
     }
 
-    // if we still have dialogs open, temporary suppress termination
-    if (bTerminateApp && Dialog::AreDialogsOpen())
-    {
-        Application::SetShutdownDelayed();
-        bCloseFrame = true;
-        bTerminateApp = false;
-    }
-
     // Do it now ...
     bool bSuccess = false;
     if (bCloseFrame)
diff --git a/framework/source/fwe/interaction/preventduplicateinteraction.cxx b/framework/source/fwe/interaction/preventduplicateinteraction.cxx
index 818fdfe2122a..9e43e1b1d44f 100644
--- a/framework/source/fwe/interaction/preventduplicateinteraction.cxx
+++ b/framework/source/fwe/interaction/preventduplicateinteraction.cxx
@@ -19,6 +19,7 @@
 
 #include <framework/preventduplicateinteraction.hxx>
 
+#include <comphelper/processfactory.hxx>
 #include <osl/diagnose.h>
 
 #include <com/sun/star/task/InteractionHandler.hpp>
@@ -53,7 +54,9 @@ void PreventDuplicateInteraction::useDefaultUUIHandler()
     aLock.clear();
     // <- SAFE
 
-    css::uno::Reference< css::task::XInteractionHandler > xHandler( css::task::InteractionHandler::createWithParent( m_xContext, nullptr ), css::uno::UNO_QUERY_THROW );
+    m_xWarningDialogsParent.reset(new WarningDialogsParentScope(m_xContext));
+    css::uno::Reference<css::task::XInteractionHandler> xHandler(css::task::InteractionHandler::createWithParent(
+        m_xContext, m_xWarningDialogsParent->GetDialogParent()), css::uno::UNO_QUERY_THROW);
 
     // SAFE ->
     aLock.reset();
@@ -236,6 +239,11 @@ bool PreventDuplicateInteraction::getInteractionInfo(const css::uno::Type&
     return false;
 }
 
+IMPL_STATIC_LINK_NOARG_TYPED(WarningDialogsParent, TerminateDesktop, void*, void)
+{
+    css::frame::Desktop::create(comphelper::getProcessComponentContext())->terminate();
+}
+
 } // namespace framework
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx
index c789f4d6e957..5e51c42bee83 100644
--- a/framework/source/loadenv/loadenv.cxx
+++ b/framework/source/loadenv/loadenv.cxx
@@ -378,10 +378,6 @@ void LoadEnv::startLoading()
     if (!bStarted)
         bStarted = impl_loadContent();
 
-    // This may have triggered Dialogs (error cases) that may have
-    // delayed the shutdown, so give delayed shutdown a chance
-    Application::TriggerShutdownDelayed();
-
     // not started => general error
     // We can't say - what was the reason for.
     if (!bStarted)
@@ -1077,7 +1073,7 @@ bool LoadEnv::impl_loadContent()
 
     if (!bHidden && !bMinimized && !bPreview && !xProgress.is())
     {
-        // Note: its an optional interface!
+        // Note: it's an optional interface!
         css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
         if (xProgressFactory.is())
         {
diff --git a/include/framework/preventduplicateinteraction.hxx b/include/framework/preventduplicateinteraction.hxx
index cf6ac0058eda..cd3d7438c785 100644
--- a/include/framework/preventduplicateinteraction.hxx
+++ b/include/framework/preventduplicateinteraction.hxx
@@ -24,17 +24,127 @@
 
 #include <vector>
 
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/TerminationVetoException.hpp>
+#include <com/sun/star/frame/XTerminateListener2.hpp>
 #include <com/sun/star/task/XInteractionHandler2.hpp>
 #include <com/sun/star/task/XInteractionRequest.hpp>
 
+#include <cppuhelper/compbase.hxx>
 #include <cppuhelper/implbase.hxx>
 
+#include <sfx2/app.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
 namespace com { namespace sun { namespace star { namespace uno {
     class XComponentContext;
 } } } }
 
 namespace framework{
 
+inline void closedialogs(SystemWindow& rTopLevel, bool bCloseRoot)
+{
+    for (vcl::Window *pChild = rTopLevel.GetWindow(GetWindowType::FirstTopWindowChild); pChild; pChild = rTopLevel.GetWindow(GetWindowType::NextTopWindowSibling))
+        closedialogs(dynamic_cast<SystemWindow&>(*pChild), true);
+    if (bCloseRoot)
+        rTopLevel.Close();
+}
+
+// This is intended to be the parent for any warning dialogs launched
+// during the load of a document so that those dialogs are modal to
+// this window and don't block any existing windows.
+//
+// If there are dialog children open on exit then veto termination,
+// close the topmost dialog and retry termination.
+class WarningDialogsParent :
+    public cppu::WeakComponentImplHelper<css::frame::XTerminateListener>
+{
+private:
+    osl::Mutex m_aLock;
+    VclPtr<WorkWindow> m_xWin;
+    css::uno::Reference<css::awt::XWindow> m_xInterface;
+
+private:
+
+    DECL_STATIC_LINK_TYPED(WarningDialogsParent, TerminateDesktop, void*, void);
+
+    void closewarningdialogs()
+    {
+        if (!m_xWin)
+            return;
+        SolarMutexGuard aSolarGuard;
+        closedialogs(dynamic_cast<SystemWindow&>(*m_xWin), false);
+    }
+
+public:
+
+    using cppu::WeakComponentImplHelperBase::disposing;
+    virtual void SAL_CALL disposing(const css::lang::EventObject&) override
+    {
+    }
+
+    // XTerminateListener
+    virtual void SAL_CALL queryTermination(const css::lang::EventObject&) override
+    {
+        closewarningdialogs();
+        Application::PostUserEvent(LINK(this, WarningDialogsParent, TerminateDesktop));
+        throw css::frame::TerminationVetoException();
+    }
+
+    virtual void SAL_CALL notifyTermination(const css::lang::EventObject&) override
+    {
+    }
+
+public:
+    WarningDialogsParent()
+        : cppu::WeakComponentImplHelper<css::frame::XTerminateListener>(m_aLock)
+    {
+        SolarMutexGuard aSolarGuard;
+        m_xWin = VclPtr<WorkWindow>::Create(nullptr, WB_STDWORK);
+        m_xWin->SetText("dialog parent for warning dialogs during load");
+        m_xInterface = VCLUnoHelper::GetInterface(m_xWin);
+    }
+
+    virtual ~WarningDialogsParent() override
+    {
+        closewarningdialogs();
+        m_xWin.disposeAndClear();
+    }
+
+    const css::uno::Reference<css::awt::XWindow>& GetDialogParent() const
+    {
+        return m_xInterface;
+    }
+};
+
+class WarningDialogsParentScope
+{
+private:
+    css::uno::Reference<css::frame::XDesktop> m_xDesktop;
+    rtl::Reference<WarningDialogsParent> m_xListener;
+
+public:
+    WarningDialogsParentScope(const css::uno::Reference<css::uno::XComponentContext>& rContext)
+        : m_xDesktop(css::frame::Desktop::create(rContext), css::uno::UNO_QUERY_THROW)
+        , m_xListener(new WarningDialogsParent)
+    {
+        m_xDesktop->addTerminateListener(m_xListener.get());
+    }
+
+    const css::uno::Reference<css::awt::XWindow>& GetDialogParent() const
+    {
+        return m_xListener->GetDialogParent();
+    }
+
+    ~WarningDialogsParentScope()
+    {
+        m_xDesktop->removeTerminateListener(m_xListener.get());
+    }
+};
+
 /**
     @short      Prevent us from showing the same interaction more than once during
                 the same transaction.
@@ -101,6 +211,8 @@ class FWE_DLLPUBLIC PreventDuplicateInteraction : private ThreadHelpBase2
             if it's not blocked. */
         css::uno::Reference< css::task::XInteractionHandler > m_xHandler;
 
+        std::unique_ptr<WarningDialogsParentScope> m_xWarningDialogsParent;
+
         /** This list describe which and how incoming interactions must be handled.
             Further it contains all collected information after this interaction
             object was used.*/
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index 87588d50c85d..34e03fc03a99 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -38,11 +38,8 @@ public:
         /** Use given parent or get a default one using GetDefaultParent(...) */
         Default,
 
-        /** Suppress Parent so that Parent is not blocked (kind of modal mode) */
-        NoParent,
-
-        /** Suppress Parent (no modal, see above) and additionally center on default parent */
-        NoParentCentered
+        /** No Parent */
+        NoParent
     };
 
 private:
@@ -124,8 +121,7 @@ public:
 
 
     void            EndDialog( long nResult = 0 );
-    static void     EndAllDialogs( vcl::Window* pParent=nullptr );
-    static bool     AreDialogsOpen();
+    static void     EndAllDialogs( vcl::Window const * pParent );
 
     void            GetDrawWindowBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
                                          sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const;
diff --git a/include/vcl/msgbox.hxx b/include/vcl/msgbox.hxx
index 0f526f618fe6..f3351664574c 100644
--- a/include/vcl/msgbox.hxx
+++ b/include/vcl/msgbox.hxx
@@ -47,8 +47,7 @@ protected:
 
 public:
                         MessBox( vcl::Window* pParent, WinBits nStyle,
-                                 const OUString& rTitle, const OUString& rMessage,
-                            Dialog::InitFlag eInitFlag = Dialog::InitFlag::NoParentCentered);
+                                 const OUString& rTitle, const OUString& rMessage);
     virtual             ~MessBox();
     virtual void        dispose() override;
 
diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx
index 2be63c268198..34b659fa7f33 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -1451,12 +1451,6 @@ public:
     // For vclbootstrapprotector:
     static void setDeInitHook(Link<LinkParamNone*,void> const & hook);
 
-    // for delayed shutdown: set using SetShutdownDelayed, then
-    // trigger using TriggerShutdownDelayed which may actually shutdown
-    // when SetShutdownDelayed is set
-    static void SetShutdownDelayed();
-    static void TriggerShutdownDelayed();
-
 private:
     DECL_STATIC_LINK_TYPED( Application, PostEventHandler, void*, void );
 };
diff --git a/uui/source/iahndl.cxx b/uui/source/iahndl.cxx
index b53f5b474323..e94947ecc233 100644
--- a/uui/source/iahndl.cxx
+++ b/uui/source/iahndl.cxx
@@ -998,33 +998,10 @@ executeMessageBox(
     vcl::Window * pParent,
     OUString const & rTitle,
     OUString const & rMessage,
-    WinBits nButtonMask,
-    Dialog::InitFlag eInitFlag)
+    WinBits nStyle)
 {
     SolarMutexGuard aGuard;
-    ScopedVclPtrInstance< MessBox > xBox(pParent, nButtonMask, rTitle, rMessage, eInitFlag);
-
-    if (Dialog::InitFlag::NoParentCentered == eInitFlag)
-    {
-        vcl::Window* pDefaultParent = Dialog::GetDefaultParent(nButtonMask);
-
-        if (pDefaultParent)
-        {
-            // need to 'Show' to have the following tasks do someting, does
-            // not work without and may even stumble on nullptrs/errors
-            xBox->Show();
-
-            // center on parent window
-            const Point aP(pDefaultParent->GetPosPixel());
-            const Size aS(pDefaultParent->GetSizePixel());
-            const Size aMySize(xBox->GetSizePixel());
-
-            xBox->SetPosPixel(
-                Point(
-                    aP.X() + ((aS.Width() - aMySize.Width()) >> 1),
-                    aP.Y() + ((aS.Height() - aMySize.Height()) >> 1)));
-        }
-    }
+    ScopedVclPtrInstance< MessBox > xBox(pParent, nStyle, rTitle, rMessage);
 
     sal_uInt16 aResult = xBox->Execute();
     switch( aResult )
@@ -1175,8 +1152,7 @@ UUIInteractionHelper::handleGenericErrorRequest(
                 aTitle += " - " ;
             aTitle += aErrTitle;
 
-            executeMessageBox(
-                getParentProperty(), aTitle, aErrorString, WB_OK, Dialog::InitFlag::NoParentCentered);
+            executeMessageBox(getParentProperty(), aTitle, aErrorString, WB_OK);
         }
         else
             ErrorHandler::HandleError(nErrorCode);
@@ -1299,8 +1275,7 @@ UUIInteractionHelper::handleBrokenPackageRequest(
         " " +
         utl::ConfigManager::getProductVersion() );
 
-    switch (
-        executeMessageBox( getParentProperty(), title, aMessage, nButtonMask, Dialog::InitFlag::NoParentCentered) )
+    switch (executeMessageBox(getParentProperty(), title, aMessage, nButtonMask))
     {
     case ERRCODE_BUTTON_OK:
         OSL_ENSURE( xAbort.is(), "unexpected situation" );
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index fc6fefc7d958..6af3c7c1c7cf 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -1816,20 +1816,4 @@ void Application::setDeInitHook(Link<LinkParamNone*,void> const & hook) {
     pSVData->maAppData.mbInAppMain = true;
 }
 
-void Application::SetShutdownDelayed()
-{
-    ImplSVData * pSVData = ImplGetSVData();
-    pSVData->maAppData.mbShutdownDelayed = true;
-}
-
-void Application::TriggerShutdownDelayed()
-{
-    ImplSVData * pSVData = ImplGetSVData();
-
-    if (pSVData->maAppData.mbShutdownDelayed && !Dialog::AreDialogsOpen())
-    {
-        Application::PostUserEvent(LINK(nullptr, ImplSVAppData, ImplPrepareExitMsg));
-    }
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 95fed10ab0a6..d0aa084e777e 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -406,7 +406,7 @@ void Dialog::ImplInit( vcl::Window* pParent, WinBits nStyle, InitFlag eFlag )
     // Now, all Dialogs are per default system windows !!!
     nStyle |= WB_SYSTEMWINDOW;
 
-    if (InitFlag::NoParent == eFlag || InitFlag::NoParentCentered == eFlag)
+    if (InitFlag::NoParent == eFlag)
     {
         pParent = nullptr;
     }
@@ -992,7 +992,7 @@ long Dialog::GetResult() const
     return mpDialogImpl->mnResult;
 }
 
-void Dialog::EndAllDialogs( vcl::Window* pParent )
+void Dialog::EndAllDialogs( vcl::Window const * pParent )
 {
     ImplSVData* pSVData = ImplGetSVData();
     Dialog* pTempModDialog;
@@ -1009,14 +1009,6 @@ void Dialog::EndAllDialogs( vcl::Window* pParent )
     }
 }
 
-bool Dialog::AreDialogsOpen()
-{
-    ImplSVData* pSVData = ImplGetSVData();
-    Dialog* pModDialog = pSVData->maWinData.mpLastExecuteDlg;
-
-    return (nullptr != pModDialog);
-}
-
 void Dialog::SetModalInputMode( bool bModal )
 {
     if ( bModal == mbModalMode )
diff --git a/vcl/source/window/msgbox.cxx b/vcl/source/window/msgbox.cxx
index f6fd26773624..172c9870889c 100644
--- a/vcl/source/window/msgbox.cxx
+++ b/vcl/source/window/msgbox.cxx
@@ -138,12 +138,14 @@ void MessBox::ImplInitButtons()
 }
 
 MessBox::MessBox( vcl::Window* pParent, WinBits nStyle,
-                  const OUString& rTitle, const OUString& rMessage, Dialog::InitFlag eInitFlag) :
+                  const OUString& rTitle, const OUString& rMessage) :
     ButtonDialog( WINDOW_MESSBOX ),
-    maMessText( rMessage )
+    maMessText( rMessage ),
+    mbHelpBtn( false ),
+    mbCheck( false )
 {
     ImplInitMessBoxData();
-    ImplInit( pParent, nStyle | WB_MOVEABLE | WB_HORZ | WB_CENTER, eInitFlag);
+    ImplInit( pParent, nStyle | WB_MOVEABLE | WB_HORZ | WB_CENTER);
     ImplInitButtons();
 
     if ( !rTitle.isEmpty() )


More information about the Libreoffice-commits mailing list