[Libreoffice-commits] core.git: filter/CppunitTest_filter_priority.mk filter/source framework/source sfx2/inc sfx2/source

Caolán McNamara caolanm at redhat.com
Fri Nov 24 08:55:46 UTC 2017


 filter/CppunitTest_filter_priority.mk            |    1 
 filter/source/config/cache/typedetection.cxx     |   12 ++++--
 filter/source/config/cache/typedetection.hxx     |   41 ++++++++++++++++++++++-
 framework/source/loadenv/loadenv.cxx             |   36 ++++++++++++++++----
 sfx2/inc/preventduplicateinteraction.hxx         |    4 +-
 sfx2/source/appl/preventduplicateinteraction.cxx |   17 ++++++++-
 6 files changed, 97 insertions(+), 14 deletions(-)

New commits:
commit 6f31670783b3445a8073bd49fe4c041b655e91b3
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Nov 23 14:05:26 2017 +0000

    set new document window as parent for dialogs during load
    
    and exit typedetection early and completely if application quits
    while detecting
    
    During typedetection, before loading proper, we have the hidden window as
    parent so warnings are not modal to existing windows and they are cancelled on
    exit.
    
    Once we do have a window, then reinit interaction handler to have that window
    as the parent for any further dialogs.
    
    Change-Id: I5c6711557266bf7d1eb9291f1c454cbfaf766886
    Reviewed-on: https://gerrit.libreoffice.org/45148
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/filter/CppunitTest_filter_priority.mk b/filter/CppunitTest_filter_priority.mk
index e9bc7de8f196..5f9042dd0859 100644
--- a/filter/CppunitTest_filter_priority.mk
+++ b/filter/CppunitTest_filter_priority.mk
@@ -11,6 +11,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,filter_priority))
 
 $(eval $(call gb_CppunitTest_use_sdk_api,filter_priority))
 $(eval $(call gb_CppunitTest_use_ure,filter_priority))
+$(eval $(call gb_CppunitTest_use_vcl,filter_priority))
 
 $(eval $(call gb_CppunitTest_use_configuration,filter_priority))
 
diff --git a/filter/source/config/cache/typedetection.cxx b/filter/source/config/cache/typedetection.cxx
index 3355618042c0..7b867177412c 100644
--- a/filter/source/config/cache/typedetection.cxx
+++ b/filter/source/config/cache/typedetection.cxx
@@ -21,6 +21,7 @@
 #include "constant.hxx"
 
 #include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/util/URLTransformer.hpp>
 #include <com/sun/star/util/XURLTransformer.hpp>
 
@@ -50,7 +51,10 @@ namespace filter{
 
 TypeDetection::TypeDetection(const css::uno::Reference< css::uno::XComponentContext >& rxContext)
    : m_xContext(rxContext)
+   , m_xTerminateListener(new TerminateDetection(this))
+   , m_bCancel(false)
 {
+    css::frame::Desktop::create(m_xContext)->addTerminateListener(m_xTerminateListener.get());
     BaseContainer::init(rxContext                                     ,
                         TypeDetection::impl_getImplementationName()   ,
                         TypeDetection::impl_getSupportedServiceNames(),
@@ -60,6 +64,7 @@ TypeDetection::TypeDetection(const css::uno::Reference< css::uno::XComponentCont
 
 TypeDetection::~TypeDetection()
 {
+    css::frame::Desktop::create(m_xContext)->removeTerminateListener(m_xTerminateListener.get());
 }
 
 
@@ -425,18 +430,17 @@ OUString SAL_CALL TypeDetection::queryTypeByDescriptor(css::uno::Sequence< css::
         if (lFlatTypes.size()>0)
             sType = impl_detectTypeFlatAndDeep(stlDescriptor, lFlatTypes, bAllowDeep, lUsedDetectors, sLastChance);
 
-
         // flat detection failed
         // pure deep detection failed
         // => ask might existing InteractionHandler
         // means: ask user for its decision
-        if (sType.isEmpty())
+        if (sType.isEmpty() && !m_bCancel)
             sType = impl_askUserForTypeAndFilterIfAllowed(stlDescriptor);
 
 
         // no real detected type - but a might valid one.
         // update descriptor and set last chance for return.
-        if (sType.isEmpty() && !sLastChance.isEmpty())
+        if (sType.isEmpty() && !sLastChance.isEmpty() && !m_bCancel)
         {
             OSL_FAIL("set first flat detected type without a registered deep detection service as \"last chance\" ... nevertheless some other deep detections said \"NO\". I TRY IT!");
             sType = sLastChance;
@@ -896,7 +900,7 @@ OUString TypeDetection::impl_detectTypeFlatAndDeep(      utl::MediaDescriptor& r
     //    obtained from the cache                 => ignore it, and continue with search
 
     for (FlatDetection::const_iterator pFlatIt  = lFlatTypes.begin();
-                                       pFlatIt != lFlatTypes.end()  ;
+                                       pFlatIt != lFlatTypes.end() && !m_bCancel;
                                      ++pFlatIt                      )
     {
         const FlatDetectionInfo& aFlatTypeInfo = *pFlatIt;
diff --git a/filter/source/config/cache/typedetection.hxx b/filter/source/config/cache/typedetection.hxx
index 18185134af5a..830badc54f63 100644
--- a/filter/source/config/cache/typedetection.hxx
+++ b/filter/source/config/cache/typedetection.hxx
@@ -21,14 +21,16 @@
 
 #include "basecontainer.hxx"
 #include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <unotools/mediadescriptor.hxx>
+#include <cppuhelper/compbase.hxx>
 #include <cppuhelper/implbase.hxx>
 
-
 namespace filter{ namespace config {
 
+class TerminateDetection;
 
 /** @short      implements the service <type scope="com.sun.star.document">TypeDetection</type>.
  */
@@ -39,6 +41,8 @@ class TypeDetection : public ::cppu::ImplInheritanceHelper< BaseContainer
 // native interface
 
     css::uno::Reference< css::uno::XComponentContext > m_xContext;
+    rtl::Reference<TerminateDetection> m_xTerminateListener;
+    bool m_bCancel;
 
 public:
 
@@ -53,6 +57,11 @@ public:
      */
     explicit TypeDetection(const css::uno::Reference< css::uno::XComponentContext >& rxContext);
 
+    void cancel()
+    {
+        m_bCancel = true;
+    }
+
 
     /** @short  standard dtor.
      */
@@ -362,6 +371,36 @@ public:
     static css::uno::Reference< css::uno::XInterface > impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
 };
 
+class TerminateDetection : public cppu::WeakComponentImplHelper<css::frame::XTerminateListener>
+{
+private:
+    osl::Mutex m_aLock;
+    TypeDetection* m_pTypeDetection;
+
+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
+    {
+        m_pTypeDetection->cancel();
+    }
+
+    virtual void SAL_CALL notifyTermination(const css::lang::EventObject&) override
+    {
+    }
+
+    TerminateDetection(TypeDetection* pTypeDetection)
+        : cppu::WeakComponentImplHelper<css::frame::XTerminateListener>(m_aLock)
+        , m_pTypeDetection(pTypeDetection)
+    {
+    }
+};
+
 }}
 
 #endif // INCLUDED_FILTER_SOURCE_CONFIG_CACHE_TYPEDETECTION_HXX
diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx
index 3bfd87e3244c..6ad9498f776f 100644
--- a/framework/source/loadenv/loadenv.cxx
+++ b/framework/source/loadenv/loadenv.cxx
@@ -28,6 +28,7 @@
 #include <services.h>
 #include <comphelper/interaction.hxx>
 #include <comphelper/lok.hxx>
+#include <comphelper/propertysequence.hxx>
 #include <framework/interaction.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/configuration.hxx>
@@ -55,6 +56,7 @@
 #include <com/sun/star/frame/FrameSearchFlag.hpp>
 #include <com/sun/star/frame/XDispatchProvider.hpp>
 #include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/lang/DisposedException.hpp>
 #include <com/sun/star/io/XInputStream.hpp>
@@ -1044,15 +1046,35 @@ bool LoadEnv::impl_loadContent()
     bool bPreview   = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW(), false);
     css::uno::Reference< css::task::XStatusIndicator > xProgress  = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference< css::task::XStatusIndicator >());
 
-    if (!bHidden && !bMinimized && !bPreview && !xProgress.is())
+    if (!bHidden && !bMinimized && !bPreview)
     {
-        // Note: it's an optional interface!
-        css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
-        if (xProgressFactory.is())
+        if (!xProgress.is())
         {
-            xProgress = xProgressFactory->createStatusIndicator();
-            if (xProgress.is())
-                m_lMediaDescriptor[utl::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xProgress;
+            // Note: it's an optional interface!
+            css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
+            if (xProgressFactory.is())
+            {
+                xProgress = xProgressFactory->createStatusIndicator();
+                if (xProgress.is())
+                    m_lMediaDescriptor[utl::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xProgress;
+            }
+        }
+
+        // Now that we have a target window into which we can load, reinit the interaction handler to have this
+        // window as its parent for modal dialogs and ensure the window is visible
+        css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault(
+                                                                                utl::MediaDescriptor::PROP_INTERACTIONHANDLER(),
+                                                                                css::uno::Reference< css::task::XInteractionHandler >());
+        css::uno::Reference<css::lang::XInitialization> xHandler(xInteraction, css::uno::UNO_QUERY);
+        if (xHandler.is())
+        {
+            css::uno::Reference<css::awt::XWindow> xWindow = xTargetFrame->getContainerWindow();
+            uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
+            {
+                {"Parent", uno::Any(xWindow)}
+            }));
+            xHandler->initialize(aArguments);
+            impl_makeFrameWindowVisible(xWindow, false);
         }
     }
 
diff --git a/sfx2/inc/preventduplicateinteraction.hxx b/sfx2/inc/preventduplicateinteraction.hxx
index 9e31a5bcc829..5e1db5043aec 100644
--- a/sfx2/inc/preventduplicateinteraction.hxx
+++ b/sfx2/inc/preventduplicateinteraction.hxx
@@ -25,6 +25,7 @@
 #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/lang/XInitialization.hpp>
 #include <com/sun/star/task/XInteractionHandler2.hpp>
 #include <com/sun/star/task/XInteractionRequest.hpp>
 
@@ -160,7 +161,7 @@ struct ThreadHelpBase2
 };
 
 class PreventDuplicateInteraction : private ThreadHelpBase2
-                                    ,public ::cppu::WeakImplHelper< css::task::XInteractionHandler2 >
+                                  , public ::cppu::WeakImplHelper<css::lang::XInitialization, css::task::XInteractionHandler2>
 {
 
     // structs, types etc.
@@ -220,6 +221,7 @@ class PreventDuplicateInteraction : private ThreadHelpBase2
     // uno interface
     public:
 
+        virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) override;
 
         /**
             @interface  XInteractionHandler
diff --git a/sfx2/source/appl/preventduplicateinteraction.cxx b/sfx2/source/appl/preventduplicateinteraction.cxx
index 009754cae517..ffe89813c0db 100644
--- a/sfx2/source/appl/preventduplicateinteraction.cxx
+++ b/sfx2/source/appl/preventduplicateinteraction.cxx
@@ -42,6 +42,7 @@ void PreventDuplicateInteraction::setHandler(const css::uno::Reference< css::tas
 {
     // SAFE ->
     ::osl::ResettableMutexGuard aLock(m_aLock);
+    m_xWarningDialogsParent.reset();
     m_xHandler = xHandler;
     aLock.clear();
     // <- SAFE
@@ -54,6 +55,8 @@ void PreventDuplicateInteraction::useDefaultUUIHandler()
     aLock.clear();
     // <- SAFE
 
+    //if we use the default handler, set the parent to a window belonging to this object so that the dialogs
+    //don't block unrelated windows.
     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);
@@ -74,7 +77,7 @@ css::uno::Any SAL_CALL PreventDuplicateInteraction::queryInterface( const css::u
         if ( !xHandler.is() )
             return css::uno::Any();
     }
-    return ::cppu::WeakImplHelper< css::task::XInteractionHandler2 >::queryInterface( aType );
+    return ::cppu::WeakImplHelper<css::lang::XInitialization, css::task::XInteractionHandler2>::queryInterface(aType);
 }
 
 void SAL_CALL PreventDuplicateInteraction::handle(const css::uno::Reference< css::task::XInteractionRequest >& xRequest)
@@ -230,6 +233,18 @@ bool PreventDuplicateInteraction::getInteractionInfo(const css::uno::Type&
     return false;
 }
 
+void SAL_CALL PreventDuplicateInteraction::initialize(const css::uno::Sequence<css::uno::Any>& rArguments)
+{
+    // If we're re-initialized to set a specific new window as a parent then drop our temporary
+    // dialog parent
+    css::uno::Reference<css::lang::XInitialization> xHandler(m_xHandler, css::uno::UNO_QUERY);
+    if (xHandler.is())
+    {
+        m_xWarningDialogsParent.reset();
+        xHandler->initialize(rArguments);
+    }
+}
+
 IMPL_STATIC_LINK_NOARG(WarningDialogsParent, TerminateDesktop, void*, void)
 {
     css::frame::Desktop::create(comphelper::getProcessComponentContext())->terminate();


More information about the Libreoffice-commits mailing list