diff options
-rw-r--r-- | filter/CppunitTest_filter_priority.mk | 1 | ||||
-rw-r--r-- | filter/source/config/cache/typedetection.cxx | 12 | ||||
-rw-r--r-- | filter/source/config/cache/typedetection.hxx | 41 | ||||
-rw-r--r-- | framework/source/loadenv/loadenv.cxx | 36 | ||||
-rw-r--r-- | sfx2/inc/preventduplicateinteraction.hxx | 4 | ||||
-rw-r--r-- | sfx2/source/appl/preventduplicateinteraction.cxx | 17 |
6 files changed, 97 insertions, 14 deletions
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(); |