summaryrefslogtreecommitdiff
path: root/uui/source/iahndl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'uui/source/iahndl.cxx')
-rw-r--r--uui/source/iahndl.cxx211
1 files changed, 148 insertions, 63 deletions
diff --git a/uui/source/iahndl.cxx b/uui/source/iahndl.cxx
index b6c1eb613f5f..e883bd60848d 100644
--- a/uui/source/iahndl.cxx
+++ b/uui/source/iahndl.cxx
@@ -34,13 +34,11 @@
#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
#include "com/sun/star/document/BrokenPackageRequest.hpp"
#include "com/sun/star/task/DocumentMacroConfirmationRequest.hpp"
-#include "com/sun/star/task/DocumentMacroConfirmationRequest2.hpp"
#include "com/sun/star/java/WrongJavaVersionException.hpp"
#include "com/sun/star/lang/XInitialization.hpp"
#include "com/sun/star/lang/XMultiServiceFactory.hpp"
#include "com/sun/star/script/ModuleSizeExceededRequest.hpp"
#include "com/sun/star/sync2/BadPartnershipException.hpp"
-#include "com/sun/star/task/DocumentMacroConfirmationRequest2.hpp"
#include "com/sun/star/task/ErrorCodeIOException.hpp"
#include "com/sun/star/task/ErrorCodeRequest.hpp"
#include "com/sun/star/task/FutureDocumentVersionProductUpdateRequest.hpp"
@@ -73,12 +71,16 @@
#include "tools/rcid.h" // RSC_STRING
#include "tools/errinf.hxx" // ErrorHandler, ErrorContext, ...
#include "vos/mutex.hxx"
+#include "tools/diagnose_ex.h"
#include "comphelper/documentconstants.hxx" // ODFVER_012_TEXT
#include "svtools/sfxecode.hxx" // ERRCODE_SFX_*
#include "vcl/msgbox.hxx"
#include "vcl/svapp.hxx"
#include "unotools/configmgr.hxx"
#include "toolkit/helper/vclunohelper.hxx"
+#include "comphelper/namedvaluecollection.hxx"
+#include "typelib/typedescription.hxx"
+#include "unotools/confignode.hxx"
#include "ids.hrc"
@@ -88,7 +90,26 @@
#include "iahndl.hxx"
-using namespace com::sun::star;
+/** === begin UNO using === **/
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::task::XInteractionContinuation;
+using ::com::sun::star::task::XInteractionAbort;
+using ::com::sun::star::task::XInteractionApprove;
+using ::com::sun::star::task::XInteractionAskLater;
+using ::com::sun::star::task::FutureDocumentVersionProductUpdateRequest;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::lang::XInitialization;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::task::XInteractionHandler2;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::task::XInteractionRequest;
+using ::com::sun::star::lang::XMultiServiceFactory;
+/** === end UNO using === **/
+
+using namespace ::com::sun::star;
namespace {
@@ -310,47 +331,116 @@ UUIInteractionHelper::tryOtherInteractionHandler(
aIt != aEnd;
++aIt)
{
- uno::Reference< uno::XInterface > xIfc;
+ if ( handleCustomRequest( rRequest, aIt->ServiceName ) )
+ return true;
+ }
+ return false;
+}
- try
- {
- xIfc = m_xServiceFactory->createInstance(aIt->ServiceName);
- }
- catch ( uno::RuntimeException const & )
- {
- throw;
- }
- catch ( uno::Exception const & )
+namespace
+{
+ // .................................................................................................................
+ static bool lcl_matchesRequest( const Any& i_rRequest, const ::rtl::OUString& i_rTypeName, const ::rtl::OUString& i_rPropagation )
+ {
+ const ::com::sun::star::uno::TypeDescription aTypeDesc( i_rTypeName );
+ const typelib_TypeDescription* pTypeDesc = aTypeDesc.get();
+ if ( !pTypeDesc || !pTypeDesc->pWeakRef )
{
+#if OSL_DEBUG_LEVEL > 0
+ ::rtl::OStringBuffer aMessage;
+ aMessage.append( "no type found for '" );
+ aMessage.append( ::rtl::OUStringToOString( i_rTypeName, RTL_TEXTENCODING_UTF8 ) );
+ aMessage.append( "'" );
+ OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
+#endif
+ return false;
}
+ const ::com::sun::star::uno::Type aType( pTypeDesc->pWeakRef );
- uno::Reference< lang::XInitialization >
- xInitialization( xIfc, uno::UNO_QUERY );
+ const bool bExactMatch = ( i_rPropagation.compareToAscii( "named-only" ) == 0 );
+ if ( bExactMatch )
+ return i_rRequest.getValueType().equals( aType );
- OSL_ENSURE( xInitialization.is(),
- "Custom Interactionhandler does not "
- "implement mandatory interface XInitialization!" );
- if (xInitialization.is())
- {
- uno::Sequence< uno::Any > propertyValues(1);
- beans::PropertyValue aProperty;
+ return i_rRequest.isExtractableTo( aType );
+ }
+}
- aProperty.Name = rtl::OUString::createFromAscii( "Parent" );
- aProperty.Value <<= getParentXWindow();
- propertyValues[ 0 ] <<= aProperty;
+// ---------------------------------------------------------------------------------------------------------------------
+bool UUIInteractionHelper::handleCustomRequest( const Reference< XInteractionRequest >& i_rRequest, const ::rtl::OUString& i_rServiceName ) const
+{
+ try
+ {
+ Reference< XInteractionHandler2 > xHandler( m_xServiceFactory->createInstance( i_rServiceName ), UNO_QUERY_THROW );
- xInitialization->initialize(propertyValues);
+ Reference< XInitialization > xHandlerInit( xHandler, UNO_QUERY );
+ if ( xHandlerInit.is() )
+ {
+ ::comphelper::NamedValueCollection aInitArgs;
+ aInitArgs.put( "Parent", getParentXWindow() );
+ xHandlerInit->initialize( aInitArgs.getWrappedPropertyValues() );
}
- uno::Reference< task::XInteractionHandler2 >
- xIH( xIfc, uno::UNO_QUERY );
-
- OSL_ENSURE( xIH.is(),
- "Custom Interactionhandler does not "
- "implement mandatory interface XInteractionHandler2!" );
- if (xIH.is() && xIH->handleInteractionRequest(rRequest))
+ if ( xHandler->handleInteractionRequest( i_rRequest ) )
return true;
}
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return false;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+bool UUIInteractionHelper::handleTypedHandlerImplementations( Reference< XInteractionRequest > const & rRequest )
+{
+ // the request
+ const Any aRequest( rRequest->getRequest() );
+
+ const StringHashMap::const_iterator aCacheHitTest = m_aTypedCustomHandlers.find( aRequest.getValueTypeName() );
+ if ( aCacheHitTest != m_aTypedCustomHandlers.end() )
+ return handleCustomRequest( rRequest, aCacheHitTest->second );
+
+ // the base registration node for "typed" interaction handlers
+ const ::utl::OConfigurationTreeRoot aConfigRoot( ::utl::OConfigurationTreeRoot::createWithServiceFactory(
+ m_xServiceFactory,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Interaction/InteractionHandlers" ) ),
+ -1,
+ ::utl::OConfigurationTreeRoot::CM_READONLY
+ ) );
+
+ // loop through all registered implementations
+ const Sequence< ::rtl::OUString > aRegisteredHandlers( aConfigRoot.getNodeNames() );
+ const ::rtl::OUString* pHandlerName = aRegisteredHandlers.getConstArray();
+ const ::rtl::OUString* pHandlersEnd = aRegisteredHandlers.getConstArray() + aRegisteredHandlers.getLength();
+ for ( ; pHandlerName != pHandlersEnd; ++pHandlerName )
+ {
+ const ::utl::OConfigurationNode aHandlerNode( aConfigRoot.openNode( *pHandlerName ) );
+ const ::utl::OConfigurationNode aTypesNode( aHandlerNode.openNode( "HandledRequestTypes" ) );
+
+ // loop through all the types which the current handler is registered for
+ const Sequence< ::rtl::OUString > aHandledTypes( aTypesNode.getNodeNames() );
+ const ::rtl::OUString* pType = aHandledTypes.getConstArray();
+ const ::rtl::OUString* pTypesEnd = aHandledTypes.getConstArray() + aHandledTypes.getLength();
+ for ( ; pType != pTypesEnd; ++pType )
+ {
+ // the UNO type is the node name
+ ::utl::OConfigurationNode aType( aTypesNode.openNode( *pType ) );
+ // and there's a child denoting how the responsibility propagates
+ ::rtl::OUString sPropagation;
+ OSL_VERIFY( aType.getNodeValue( "Propagation" ) >>= sPropagation );
+ if ( lcl_matchesRequest( aRequest, *pType, sPropagation ) )
+ {
+ // retrieve the service/implementation name of the handler
+ ::rtl::OUString sServiceName;
+ OSL_VERIFY( aHandlerNode.getNodeValue( "ServiceName" ) >>= sServiceName );
+ // cache the information who feels responsible for requests of this type
+ m_aTypedCustomHandlers[ aRequest.getValueTypeName() ] = sServiceName;
+ // actually handle the request
+ return handleCustomRequest( rRequest, sServiceName );
+ }
+ }
+ }
+
return false;
}
@@ -819,24 +909,12 @@ UUIInteractionHelper::handleRequest_impl(
handleMacroConfirmRequest(
aMacroConfirmRequest.DocumentURL,
aMacroConfirmRequest.DocumentStorage,
- ODFVER_012_TEXT,
+ aMacroConfirmRequest.DocumentVersion.getLength() ? aMacroConfirmRequest.DocumentVersion : ODFVER_012_TEXT,
aMacroConfirmRequest.DocumentSignatureInformation,
rRequest->getContinuations());
return true;
}
- task::DocumentMacroConfirmationRequest2 aMacroConfirmRequest2;
- if (aAnyRequest >>= aMacroConfirmRequest2)
- {
- handleMacroConfirmRequest(
- aMacroConfirmRequest2.DocumentURL,
- aMacroConfirmRequest2.DocumentZipStorage,
- aMacroConfirmRequest2.DocumentVersion,
- aMacroConfirmRequest2.DocumentSignatureInformation,
- rRequest->getContinuations());
- return true;
- }
-
task::FutureDocumentVersionProductUpdateRequest
aProductUpdateRequest;
if (aAnyRequest >>= aProductUpdateRequest)
@@ -848,8 +926,14 @@ UUIInteractionHelper::handleRequest_impl(
}
///////////////////////////////////////////////////////////////
- // Last chance: try to find and use another IH for the request.
+ // Last chance: interaction handlers registered in the configuration
///////////////////////////////////////////////////////////////
+
+ // typed InteractionHandlers (ooo.Interactions)
+ if ( handleTypedHandlerImplementations( rRequest ) )
+ return true;
+
+ // legacy configuration (ooo.ucb.InteractionHandlers)
if (tryOtherInteractionHandler( rRequest ))
return true;
}
@@ -863,6 +947,15 @@ UUIInteractionHelper::handleRequest_impl(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("out of memory")),
uno::Reference< uno::XInterface >());
}
+ catch( const uno::RuntimeException& )
+ {
+ throw; // allowed to leave here
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return false;
}
void
@@ -997,21 +1090,16 @@ UUIInteractionHelper::getParentProperty()
}
uno::Reference< awt::XWindow>
-UUIInteractionHelper::getParentXWindow()
+UUIInteractionHelper::getParentXWindow() const
SAL_THROW(())
{
osl::MutexGuard aGuard(m_aPropertyMutex);
- for (sal_Int32 i = 0; i < m_aProperties.getLength(); ++i)
+ ::comphelper::NamedValueCollection aProperties( m_aProperties );
+ if ( aProperties.has( "Parent" ) )
{
- beans::PropertyValue aProperty;
- if ((m_aProperties[i] >>= aProperty)
- && aProperty.
- Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Parent")))
- {
- uno::Reference< awt::XWindow > xWindow;
- aProperty.Value >>= xWindow;
- return xWindow;
- }
+ uno::Reference< awt::XWindow > xWindow;
+ OSL_VERIFY( aProperties.get( "Parent" ) >>= xWindow );
+ return xWindow;
}
return 0;
}
@@ -1350,11 +1438,8 @@ UUIInteractionHelper::handleFutureDocumentVersionUpdateRequest(
// suitable place), again, and we would only have one place where we remember the s_bDeferredToNextSession
// flag.
//
- // The side effect (well, actually the more important effect) would be that we do not need to burden
- // this central implementation with all interactions which are possible. Instead, separate parts of OOo
- // can define/implement different requests. (for instance, everything which today is done in the
- // css.sdb.InteractionHandler can then be routed through a "normal" interaction handler, where today we
- // always need to tell people to instantiate the SDB-version of the handler, not the normal one.)
+ // Note: The above pattern has been implemented in CWS autorecovery. Now the remaining task is to move the
+ // handling of this interaction to SFX, again.
if ( !s_bDeferredToNextSession )
{