diff options
Diffstat (limited to 'uui/source/iahndl.cxx')
-rwxr-xr-x | uui/source/iahndl.cxx | 1588 |
1 files changed, 1588 insertions, 0 deletions
diff --git a/uui/source/iahndl.cxx b/uui/source/iahndl.cxx new file mode 100755 index 000000000000..ee233f5ac9de --- /dev/null +++ b/uui/source/iahndl.cxx @@ -0,0 +1,1588 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <memory> + +#include "com/sun/star/awt/XWindow.hpp" +#include "com/sun/star/beans/PropertyValue.hpp" +#include "com/sun/star/configuration/backend/MergeRecoveryRequest.hpp" +#include "com/sun/star/configuration/backend/StratumCreationException.hpp" +#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/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/ErrorCodeIOException.hpp" +#include "com/sun/star/task/ErrorCodeRequest.hpp" +#include "com/sun/star/task/FutureDocumentVersionProductUpdateRequest.hpp" +#include "com/sun/star/task/XInteractionAbort.hpp" +#include "com/sun/star/task/XInteractionApprove.hpp" +#include "com/sun/star/task/XInteractionAskLater.hpp" +#include "com/sun/star/task/XInteractionDisapprove.hpp" +#include "com/sun/star/task/XInteractionHandler2.hpp" +#include "com/sun/star/task/XInteractionRequest.hpp" +#include "com/sun/star/task/XInteractionRetry.hpp" +#include "com/sun/star/ucb/InteractiveAppException.hpp" +#include "com/sun/star/ucb/InteractiveCHAOSException.hpp" +#include "com/sun/star/ucb/InteractiveLockingLockedException.hpp" +#include "com/sun/star/ucb/InteractiveLockingNotLockedException.hpp" +#include "com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp" +#include "com/sun/star/ucb/InteractiveNetworkConnectException.hpp" +#include "com/sun/star/ucb/InteractiveNetworkOffLineException.hpp" +#include "com/sun/star/ucb/InteractiveNetworkReadException.hpp" +#include "com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp" +#include "com/sun/star/ucb/InteractiveNetworkWriteException.hpp" +#include "com/sun/star/ucb/InteractiveWrongMediumException.hpp" +#include "com/sun/star/ucb/NameClashException.hpp" +#include "com/sun/star/ucb/NameClashResolveRequest.hpp" +#include "com/sun/star/ucb/UnsupportedNameClashException.hpp" +#include "com/sun/star/ucb/XInteractionReplaceExistingData.hpp" +#include "com/sun/star/ucb/XInteractionSupplyName.hpp" +#include "com/sun/star/xforms/InvalidDataOnSubmitException.hpp" + +#include "osl/conditn.hxx" +#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" + +#include "getcontinuations.hxx" +#include "secmacrowarnings.hxx" +#include "newerverwarn.hxx" + +#include "iahndl.hxx" +#include "nameclashdlg.hxx" + +/** === 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 { + +class HandleData : public osl::Condition +{ +public: + HandleData( + uno::Reference< task::XInteractionRequest > const & rRequest) + : osl::Condition(), + m_rRequest(rRequest), + bHandled( false ) + { + } + uno::Reference< task::XInteractionRequest > m_rRequest; + bool bHandled; + beans::Optional< rtl::OUString > m_aResult; +}; + +} /* namespace */ + +UUIInteractionHelper::UUIInteractionHelper( + uno::Reference< lang::XMultiServiceFactory > const & rServiceFactory, + uno::Sequence< uno::Any > const & rArguments) + SAL_THROW(()): + m_xServiceFactory(rServiceFactory), + m_aProperties(rArguments) +{ +} + +UUIInteractionHelper::UUIInteractionHelper( + uno::Reference< lang::XMultiServiceFactory > const & rServiceFactory) + SAL_THROW(()): + m_xServiceFactory(rServiceFactory) +{ +} + +UUIInteractionHelper::~UUIInteractionHelper() +{ +} + +long +UUIInteractionHelper::handlerequest( + void* pHandleData, void* pInteractionHelper) +{ + HandleData* pHND + = static_cast< HandleData * >(pHandleData); + UUIInteractionHelper* pUUI + = static_cast< UUIInteractionHelper * >(pInteractionHelper); + bool bDummy = false; + rtl::OUString aDummy; + pHND->bHandled + = pUUI->handleRequest_impl(pHND->m_rRequest, false, bDummy, aDummy); + pHND->set(); + return 0; +} + +bool +UUIInteractionHelper::handleRequest( + uno::Reference< task::XInteractionRequest > const & rRequest) + SAL_THROW((uno::RuntimeException)) +{ + Application* pApp = 0; + if( + // be aware,it is the same type + static_cast< oslThreadIdentifier >( + Application::GetMainThreadIdentifier()) + != osl_getThreadIdentifier(NULL) + && + (pApp = GetpApp()) + != 0 + ) { + // we are not in the main thread, let it handle that stuff + HandleData aHD(rRequest); + Link aLink(&aHD,handlerequest); + pApp->PostUserEvent(aLink,this); + ULONG locks = Application::ReleaseSolarMutex(); + aHD.wait(); + Application::AcquireSolarMutex(locks); + return aHD.bHandled; + } + else + { + bool bDummy = false; + rtl::OUString aDummy; + return handleRequest_impl(rRequest, false, bDummy, aDummy); + } +} + +long +UUIInteractionHelper::getstringfromrequest( + void* pHandleData,void* pInteractionHelper) +{ + HandleData* pHND = (HandleData*) pHandleData; + UUIInteractionHelper* pUUI = (UUIInteractionHelper*) pInteractionHelper; + pHND->m_aResult = pUUI->getStringFromRequest_impl(pHND->m_rRequest); + pHND->set(); + return 0; +} + +beans::Optional< rtl::OUString > +UUIInteractionHelper::getStringFromRequest_impl( + uno::Reference< task::XInteractionRequest > const & rRequest) + SAL_THROW((uno::RuntimeException)) +{ + bool bSuccess = false; + rtl::OUString aMessage; + handleRequest_impl(rRequest, true, bSuccess, aMessage); + + OSL_ENSURE(bSuccess || + !isInformationalErrorMessageRequest( + rRequest->getContinuations()), + "Interaction request is a candidate for a string representation." + "Please implement!"); + + return beans::Optional< rtl::OUString >(bSuccess, aMessage); +} + +beans::Optional< rtl::OUString > +UUIInteractionHelper::getStringFromRequest( + uno::Reference< task::XInteractionRequest > const & rRequest) + SAL_THROW((uno::RuntimeException)) +{ + Application* pApp = 0; + if( + // be aware,it is the same type + static_cast< oslThreadIdentifier >( + Application::GetMainThreadIdentifier()) + != osl_getThreadIdentifier(NULL) + && + (pApp = GetpApp()) + != 0 + ) { + // we are not in the main thread, let it handle that stuff + HandleData aHD(rRequest); + Link aLink(&aHD,getstringfromrequest); + pApp->PostUserEvent(aLink,this); + ULONG locks = Application::ReleaseSolarMutex(); + aHD.wait(); + Application::AcquireSolarMutex(locks); + return aHD.m_aResult; + } + else + return getStringFromRequest_impl(rRequest); +} + +::rtl::OUString +UUIInteractionHelper::replaceMessageWithArguments( + ::rtl::OUString aMessage, + std::vector< rtl::OUString > const & rArguments ) +{ + for (sal_Int32 i = 0;;) + { + i = aMessage. + indexOf(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("$(ARG")), i); + if (i == -1) + break; + if (aMessage.getLength() - i >= RTL_CONSTASCII_LENGTH("$(ARGx)") + && aMessage.getStr()[i + RTL_CONSTASCII_LENGTH("$(ARGx")] == ')') + { + sal_Unicode c + = aMessage.getStr()[i + RTL_CONSTASCII_LENGTH("$(ARG")]; + if (c >= '1' && c <= '2') + { + std::vector< rtl::OUString >::size_type nIndex + = static_cast< std::vector< rtl::OUString >::size_type >( + c - '1'); + if (nIndex < rArguments.size()) + { + aMessage + = aMessage.replaceAt(i, + RTL_CONSTASCII_LENGTH("$(ARGx)"), + rArguments[nIndex]); + i += rArguments[nIndex].getLength(); + continue; + } + } + } + ++i; + } + + return aMessage; +} + +bool +UUIInteractionHelper::isInformationalErrorMessageRequest( + uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & + rContinuations) +{ + // Only requests with a single continuation (user has no choice, request + // is just informational) + if (rContinuations.getLength() != 1 ) + return false; + + // user can only abort or approve, all other continuations are not + // considered to be informational. + uno::Reference< task::XInteractionApprove > xApprove( + rContinuations[0], uno::UNO_QUERY); + if (xApprove.is()) + return true; + + uno::Reference< task::XInteractionAbort > xAbort( + rContinuations[0], uno::UNO_QUERY); + if (xAbort.is()) + return true; + + return false; +} + +bool +UUIInteractionHelper::tryOtherInteractionHandler( + uno::Reference< task::XInteractionRequest > const & rRequest) + SAL_THROW((uno::RuntimeException)) +{ + InteractionHandlerDataList dataList; + getInteractionHandlerList(dataList); + + InteractionHandlerDataList::const_iterator aEnd(dataList.end()); + for (InteractionHandlerDataList::const_iterator aIt(dataList.begin()); + aIt != aEnd; + ++aIt) + { + if ( handleCustomRequest( rRequest, aIt->ServiceName ) ) + return true; + } + return false; +} + +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 ); + + const bool bExactMatch = ( i_rPropagation.compareToAscii( "named-only" ) == 0 ); + if ( bExactMatch ) + return i_rRequest.getValueType().equals( aType ); + + return i_rRequest.isExtractableTo( aType ); + } +} + +// --------------------------------------------------------------------------------------------------------------------- +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 ); + + Reference< XInitialization > xHandlerInit( xHandler, UNO_QUERY ); + if ( xHandlerInit.is() ) + { + ::comphelper::NamedValueCollection aInitArgs; + aInitArgs.put( "Parent", getParentXWindow() ); + xHandlerInit->initialize( aInitArgs.getWrappedPropertyValues() ); + } + + 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; +} + +bool +UUIInteractionHelper::handleRequest_impl( + uno::Reference< task::XInteractionRequest > const & rRequest, + bool bObtainErrorStringOnly, + bool & bHasErrorString, + rtl::OUString & rErrorString) + SAL_THROW((uno::RuntimeException)) +{ + try + { + if (!rRequest.is()) + return false; + + uno::Any aAnyRequest(rRequest->getRequest()); + + script::ModuleSizeExceededRequest aModSizeException; + if (aAnyRequest >>= aModSizeException ) + { + ErrCode nErrorCode = ERRCODE_UUI_IO_MODULESIZEEXCEEDED; + std::vector< rtl::OUString > aArguments; + uno::Sequence< rtl::OUString > sModules + = aModSizeException.Names; + if ( sModules.getLength() ) + { + rtl::OUString aName; + for ( sal_Int32 index=0; index< sModules.getLength(); ++index ) + { + if ( index ) + aName = aName + rtl::OUString( ',' ) + sModules[index]; + else + aName = sModules[index]; // 1st name + } + aArguments.push_back( aName ); + } + handleErrorHandlerRequest( task::InteractionClassification_WARNING, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + ucb::NameClashException aNCException; + if (aAnyRequest >>= aNCException) + { + ErrCode nErrorCode = ERRCODE_UUI_IO_TARGETALREADYEXISTS; + std::vector< rtl::OUString > aArguments; + + if( aNCException.Name.getLength() ) + { + nErrorCode = ERRCODE_UUI_IO_ALREADYEXISTS; + aArguments.push_back( aNCException.Name ); + } + + handleErrorHandlerRequest( aNCException.Classification, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + ucb::UnsupportedNameClashException aUORequest; + if (aAnyRequest >>= aUORequest) + { + ErrCode nErrorCode = ERRCODE_UUI_IO_UNSUPPORTEDOVERWRITE; + std::vector< rtl::OUString > aArguments; + + uno::Reference< task::XInteractionApprove > xApprove; + uno::Reference< task::XInteractionDisapprove > xDisapprove; + getContinuations( + rRequest->getContinuations(), &xApprove, &xDisapprove); + + if ( xApprove.is() && xDisapprove.is() ) + { + handleErrorHandlerRequest( task::InteractionClassification_QUERY, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + } + return true; + } + + if ( handleInteractiveIOException( rRequest, + bObtainErrorStringOnly, + bHasErrorString, + rErrorString ) ) + return true; + + ucb::InteractiveAppException aAppException; + if (aAnyRequest >>= aAppException) + { + std::vector< rtl::OUString > aArguments; + handleErrorHandlerRequest( aAppException.Classification, + aAppException.Code, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + ucb::InteractiveNetworkException aNetworkException; + if (aAnyRequest >>= aNetworkException) + { + ErrCode nErrorCode; + std::vector< rtl::OUString > aArguments; + ucb::InteractiveNetworkOffLineException aOffLineException; + ucb::InteractiveNetworkResolveNameException aResolveNameException; + ucb::InteractiveNetworkConnectException aConnectException; + ucb::InteractiveNetworkReadException aReadException; + ucb::InteractiveNetworkWriteException aWriteException; + if (aAnyRequest >>= aOffLineException) + nErrorCode = ERRCODE_INET_OFFLINE; + else if (aAnyRequest >>= aResolveNameException) + { + nErrorCode = ERRCODE_INET_NAME_RESOLVE; + aArguments.push_back(aResolveNameException.Server); + } + else if (aAnyRequest >>= aConnectException) + { + nErrorCode = ERRCODE_INET_CONNECT; + aArguments.push_back(aConnectException.Server); + } + else if (aAnyRequest >>= aReadException) + { + nErrorCode = ERRCODE_INET_READ; + aArguments.push_back(aReadException.Diagnostic); + } + else if (aAnyRequest >>= aWriteException) + { + nErrorCode = ERRCODE_INET_WRITE; + aArguments.push_back(aWriteException.Diagnostic); + } + else + nErrorCode = ERRCODE_INET_GENERAL; + + handleErrorHandlerRequest(aNetworkException.Classification, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + ucb::InteractiveCHAOSException aChaosException; + if (aAnyRequest >>= aChaosException) + { + std::vector< rtl::OUString > aArguments; + sal_Int32 nCount + = std::min< sal_Int32 >(aChaosException.Arguments.getLength(), + 2); + aArguments. + reserve(static_cast< std::vector< rtl::OUString >::size_type >( + nCount)); + for (sal_Int32 i = 0; i < nCount; ++i) + aArguments.push_back(aChaosException.Arguments[i]); + handleErrorHandlerRequest(aChaosException.Classification, + aChaosException.ID, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + ucb::InteractiveWrongMediumException aWrongMediumException; + if (aAnyRequest >>= aWrongMediumException) + { + sal_Int32 nMedium = 0; + aWrongMediumException.Medium >>= nMedium; + std::vector< rtl::OUString > aArguments; + aArguments.push_back(UniString::CreateFromInt32(nMedium + 1)); + handleErrorHandlerRequest(aWrongMediumException.Classification, + ERRCODE_UUI_WRONGMEDIUM, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + java::WrongJavaVersionException aWrongJavaVersionException; + if (aAnyRequest >>= aWrongJavaVersionException) + { + ErrCode nErrorCode; + std::vector< rtl::OUString > aArguments; + if (aWrongJavaVersionException.DetectedVersion.getLength() == 0) + if (aWrongJavaVersionException.LowestSupportedVersion. + getLength() + == 0) + nErrorCode = ERRCODE_UUI_WRONGJAVA; + else + { + nErrorCode = ERRCODE_UUI_WRONGJAVA_MIN; + aArguments.push_back(aWrongJavaVersionException. + LowestSupportedVersion); + } + else if (aWrongJavaVersionException.LowestSupportedVersion. + getLength() + == 0) + { + nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION; + aArguments.push_back(aWrongJavaVersionException. + DetectedVersion); + } + else + { + nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION_MIN; + aArguments.reserve(2); + aArguments.push_back(aWrongJavaVersionException. + DetectedVersion); + aArguments.push_back(aWrongJavaVersionException. + LowestSupportedVersion); + } + handleErrorHandlerRequest(task::InteractionClassification_ERROR, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + sync2::BadPartnershipException aBadPartnershipException; + if (aAnyRequest >>= aBadPartnershipException) + { + ErrCode nErrorCode; + std::vector< rtl::OUString > aArguments; + if (aBadPartnershipException.Partnership.getLength() == 0) + nErrorCode = ERRCODE_UUI_BADPARTNERSHIP; + else + { + nErrorCode = ERRCODE_UUI_BADPARTNERSHIP_NAME; + aArguments.push_back(aBadPartnershipException.Partnership); + } + handleErrorHandlerRequest(task::InteractionClassification_ERROR, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + configuration::backend::MergeRecoveryRequest aMergeRecoveryRequest; + if (aAnyRequest >>= aMergeRecoveryRequest) + { + ErrCode nErrorCode = aMergeRecoveryRequest.IsRemovalRequest + ? ERRCODE_UUI_CONFIGURATION_BROKENDATA_WITHREMOVE + : ERRCODE_UUI_CONFIGURATION_BROKENDATA_NOREMOVE; + + std::vector< rtl::OUString > aArguments; + aArguments.push_back(aMergeRecoveryRequest.ErrorLayerId); + + handleErrorHandlerRequest(task::InteractionClassification_ERROR, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + configuration::backend::StratumCreationException + aStratumCreationException; + + if (aAnyRequest >>= aStratumCreationException) + { + const ErrCode nErrorCode = ERRCODE_UUI_CONFIGURATION_BACKENDMISSING; + + rtl::OUString aStratum = aStratumCreationException.StratumData; + if (aStratum.getLength() == 0) + aStratum = aStratumCreationException.StratumService; + + std::vector< rtl::OUString > aArguments; + aArguments.push_back(aStratum); + + handleErrorHandlerRequest(task::InteractionClassification_ERROR, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + xforms::InvalidDataOnSubmitException aInvalidDataOnSubmitException; + if (aAnyRequest >>= aInvalidDataOnSubmitException) + { + const ErrCode nErrorCode = + ERRCODE_UUI_INVALID_XFORMS_SUBMISSION_DATA; + + std::vector< rtl::OUString > aArguments; + + handleErrorHandlerRequest(task::InteractionClassification_QUERY, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + ucb::InteractiveLockingLockedException aLLException; + if (aAnyRequest >>= aLLException) + { + ErrCode nErrorCode = aLLException.SelfOwned + ? ERRCODE_UUI_LOCKING_LOCKED_SELF : ERRCODE_UUI_LOCKING_LOCKED; + std::vector< rtl::OUString > aArguments; + aArguments.push_back( aLLException.Url ); + + handleErrorHandlerRequest( aLLException.Classification, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString ); + return true; + } + + ucb::InteractiveLockingNotLockedException aLNLException; + if (aAnyRequest >>= aLNLException) + { + ErrCode nErrorCode = ERRCODE_UUI_LOCKING_NOT_LOCKED; + std::vector< rtl::OUString > aArguments; + aArguments.push_back( aLNLException.Url ); + + handleErrorHandlerRequest( aLNLException.Classification, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString ); + return true; + } + + ucb::InteractiveLockingLockExpiredException aLLEException; + if (aAnyRequest >>= aLLEException) + { + ErrCode nErrorCode = ERRCODE_UUI_LOCKING_LOCK_EXPIRED; + std::vector< rtl::OUString > aArguments; + aArguments.push_back( aLLEException.Url ); + + handleErrorHandlerRequest( aLLEException.Classification, + nErrorCode, + aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString ); + return true; + } + + document::BrokenPackageRequest aBrokenPackageRequest; + if (aAnyRequest >>= aBrokenPackageRequest) + { + std::vector< rtl::OUString > aArguments; + + if( aBrokenPackageRequest.aName.getLength() ) + aArguments.push_back( aBrokenPackageRequest.aName ); + + handleBrokenPackageRequest( aArguments, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString ); + return true; + } + + task::ErrorCodeRequest aErrorCodeRequest; + if (aAnyRequest >>= aErrorCodeRequest) + { + handleGenericErrorRequest( aErrorCodeRequest.ErrCode, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + task::ErrorCodeIOException aErrorCodeIOException; + if (aAnyRequest >>= aErrorCodeIOException) + { + handleGenericErrorRequest( aErrorCodeIOException.ErrCode, + rRequest->getContinuations(), + bObtainErrorStringOnly, + bHasErrorString, + rErrorString); + return true; + } + + + /////////////////////////////////////////////////////////////////// + // Handle requests which do not have a plain string representation. + /////////////////////////////////////////////////////////////////// + if (!bObtainErrorStringOnly) + { + if ( handleAuthenticationRequest( rRequest ) ) + return true; + + if ( handleCertificateValidationRequest( rRequest ) ) + return true; + + ucb::NameClashResolveRequest aNameClashResolveRequest; + if (aAnyRequest >>= aNameClashResolveRequest) + { + handleNameClashResolveRequest(aNameClashResolveRequest, + rRequest->getContinuations()); + return true; + } + + if ( handleMasterPasswordRequest( rRequest ) ) + return true; + + if ( handlePasswordRequest( rRequest ) ) + return true; + + if ( handleCookiesRequest( rRequest ) ) + return true; + + if ( handleNoSuchFilterRequest( rRequest ) ) + return true; + + if ( handleAmbigousFilterRequest( rRequest ) ) + return true; + + if ( handleFilterOptionsRequest( rRequest ) ) + return true; + + if ( handleLockedDocumentRequest( rRequest ) ) + return true; + + if ( handleChangedByOthersRequest( rRequest ) ) + return true; + + if ( handleLockFileIgnoreRequest( rRequest ) ) + return true; + + task::DocumentMacroConfirmationRequest aMacroConfirmRequest; + if (aAnyRequest >>= aMacroConfirmRequest) + { + handleMacroConfirmRequest( + aMacroConfirmRequest.DocumentURL, + aMacroConfirmRequest.DocumentStorage, + aMacroConfirmRequest.DocumentVersion.getLength() ? aMacroConfirmRequest.DocumentVersion : ODFVER_012_TEXT, + aMacroConfirmRequest.DocumentSignatureInformation, + rRequest->getContinuations()); + return true; + } + + task::FutureDocumentVersionProductUpdateRequest + aProductUpdateRequest; + if (aAnyRequest >>= aProductUpdateRequest) + { + handleFutureDocumentVersionUpdateRequest( + aProductUpdateRequest, + rRequest->getContinuations()); + return true; + } + + /////////////////////////////////////////////////////////////// + // 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; + } + + // Not handled. + return false; + } + catch (std::bad_alloc const &) + { + throw uno::RuntimeException( + 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 +UUIInteractionHelper::getInteractionHandlerList( + InteractionHandlerDataList &rdataList) + SAL_THROW((uno::RuntimeException)) +{ + try + { + uno::Reference< lang::XMultiServiceFactory > xConfigProv( + m_xServiceFactory->createInstance( + rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationProvider" ) ), + uno::UNO_QUERY ); + + if ( !xConfigProv.is() ) + throw uno::RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "unable to instanciate config provider service")), + uno::Reference< uno::XInterface >()); + + rtl::OUStringBuffer aFullPath; + aFullPath.appendAscii( + "/org.openoffice.ucb.InteractionHandler/InteractionHandlers" ); + + uno::Sequence< uno::Any > aArguments( 1 ); + beans::PropertyValue aProperty; + aProperty.Name + = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); + aProperty.Value <<= aFullPath.makeStringAndClear(); + aArguments[ 0 ] <<= aProperty; + + uno::Reference< uno::XInterface > xInterface( + xConfigProv->createInstanceWithArguments( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationAccess" ) ), + aArguments ) ); + + if ( !xInterface.is() ) + throw uno::RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "unable to instanciate config access")), + uno::Reference< uno::XInterface >()); + + uno::Reference< container::XNameAccess > xNameAccess( + xInterface, uno::UNO_QUERY ); + if ( !xNameAccess.is() ) + throw uno::RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "config access does not implement XNameAccess")), + uno::Reference< uno::XInterface >()); + + uno::Sequence< rtl::OUString > aElems = xNameAccess->getElementNames(); + const rtl::OUString* pElems = aElems.getConstArray(); + sal_Int32 nCount = aElems.getLength(); + + if ( nCount > 0 ) + { + uno::Reference< container::XHierarchicalNameAccess > + xHierNameAccess( xInterface, uno::UNO_QUERY ); + + if ( !xHierNameAccess.is() ) + throw uno::RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "config access does not implement XHierarchicalNameAccess")), + uno::Reference< uno::XInterface >()); + + // Iterate over children. + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + rtl::OUStringBuffer aElemBuffer; + aElemBuffer.appendAscii( "['" ); + aElemBuffer.append( pElems[ n ] ); + + try + { + InteractionHandlerData aInfo; + + // Obtain service name. + rtl::OUStringBuffer aKeyBuffer = aElemBuffer; + aKeyBuffer.appendAscii( "']/ServiceName" ); + + rtl::OUString aValue; + if ( !( xHierNameAccess->getByHierarchicalName( + aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) + { + OSL_ENSURE( false, + "GetInteractionHandlerList - " + "Error getting item value!" ); + continue; + } + + aInfo.ServiceName = aValue; + + // Append info to list. + rdataList.push_back( aInfo ); + } + catch ( container::NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( false, + "GetInteractionHandlerList - " + "caught NoSuchElementException!" ); + } + } + } + } + catch ( uno::RuntimeException const & ) + { + throw; + } + catch ( uno::Exception const & ) + { + OSL_ENSURE( false, "GetInteractionHandlerList - Caught Exception!" ); + } +} + +Window * +UUIInteractionHelper::getParentProperty() + SAL_THROW(()) +{ + uno::Reference< awt::XWindow > xWindow = getParentXWindow(); + if ( xWindow.is() ) + return VCLUnoHelper::GetWindow(xWindow); + + return 0; +} + +uno::Reference< awt::XWindow> +UUIInteractionHelper::getParentXWindow() const + SAL_THROW(()) +{ + osl::MutexGuard aGuard(m_aPropertyMutex); + ::comphelper::NamedValueCollection aProperties( m_aProperties ); + if ( aProperties.has( "Parent" ) ) + { + uno::Reference< awt::XWindow > xWindow; + OSL_VERIFY( aProperties.get( "Parent" ) >>= xWindow ); + return xWindow; + } + return 0; +} + +rtl::OUString +UUIInteractionHelper::getContextProperty() + SAL_THROW(()) +{ + osl::MutexGuard aGuard(m_aPropertyMutex); + for (sal_Int32 i = 0; i < m_aProperties.getLength(); ++i) + { + beans::PropertyValue aProperty; + if ((m_aProperties[i] >>= aProperty) + && aProperty. + Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Context"))) + { + rtl::OUString aContext; + aProperty.Value >>= aContext; + return aContext; + } + } + return rtl::OUString(); +} + +uno::Reference< task::XInteractionHandler > +UUIInteractionHelper::getInteractionHandler() + SAL_THROW((uno::RuntimeException)) +{ + uno::Reference< task::XInteractionHandler > xIH; + try + { + xIH.set(m_xServiceFactory->createInstanceWithArguments( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.task.InteractionHandler")), + m_aProperties), + uno::UNO_QUERY); + } + catch (uno::Exception const &) + {} + + if (!xIH.is()) + throw uno::RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "unable to instanciate Interaction Handler service")), + uno::Reference< uno::XInterface >()); + return xIH; +} + +namespace { + +USHORT +executeMessageBox( + Window * pParent, + rtl::OUString const & rTitle, + rtl::OUString const & rMessage, + WinBits nButtonMask ) + SAL_THROW((uno::RuntimeException)) +{ + vos::OGuard aGuard(Application::GetSolarMutex()); + + MessBox xBox( pParent, nButtonMask, rTitle, rMessage ); + + USHORT aResult = xBox.Execute(); + switch( aResult ) + { + case BUTTONID_OK: + aResult = ERRCODE_BUTTON_OK; + break; + case BUTTONID_CANCEL: + aResult = ERRCODE_BUTTON_CANCEL; + break; + case BUTTONID_YES: + aResult = ERRCODE_BUTTON_YES; + break; + case BUTTONID_NO: + aResult = ERRCODE_BUTTON_NO; + break; + case BUTTONID_RETRY: + aResult = ERRCODE_BUTTON_RETRY; + break; + } + + return aResult; +} + +NameClashResolveDialogResult executeSimpleNameClashResolveDialog( Window *pParent, + rtl::OUString const & rTargetFolderURL, + rtl::OUString const & rClashingName, + rtl::OUString & rProposedNewName, + bool bAllowOverwrite ) +{ + std::auto_ptr< ResMgr > xManager( ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); + if ( !xManager.get() ) + return ABORT; + + NameClashDialog aDialog( pParent, xManager.get(), rTargetFolderURL, + rClashingName, rProposedNewName, bAllowOverwrite ); + + NameClashResolveDialogResult eResult = (NameClashResolveDialogResult) aDialog.Execute(); + rProposedNewName = aDialog.getNewName(); + return eResult; +} + +} // namespace + +void +UUIInteractionHelper::handleNameClashResolveRequest( + ucb::NameClashResolveRequest const & rRequest, + uno::Sequence< uno::Reference< + task::XInteractionContinuation > > const & rContinuations) + SAL_THROW((uno::RuntimeException)) +{ + OSL_ENSURE( + rRequest.TargetFolderURL.getLength() > 0, + "NameClashResolveRequest must not contain empty TargetFolderURL" ); + + OSL_ENSURE( + rRequest.ClashingName.getLength() > 0, + "NameClashResolveRequest must not contain empty ClashingName" ); + + uno::Reference< task::XInteractionAbort > xAbort; + uno::Reference< ucb::XInteractionSupplyName > xSupplyName; + uno::Reference< ucb::XInteractionReplaceExistingData > xReplaceExistingData; + getContinuations( + rContinuations, &xAbort, &xSupplyName, &xReplaceExistingData); + + OSL_ENSURE( xAbort.is(), + "NameClashResolveRequest must contain Abort continuation" ); + + OSL_ENSURE( xSupplyName.is(), + "NameClashResolveRequest must contain SupplyName continuation" ); + + NameClashResolveDialogResult eResult = ABORT; + rtl::OUString aProposedNewName( rRequest.ProposedNewName ); + + eResult = executeSimpleNameClashResolveDialog( getParentProperty(), + rRequest.TargetFolderURL, + rRequest.ClashingName, + aProposedNewName, + xReplaceExistingData.is() ); + + switch ( eResult ) + { + case ABORT: + xAbort->select(); + break; + + case RENAME: + xSupplyName->setName( aProposedNewName ); + xSupplyName->select(); + break; + + case OVERWRITE: + OSL_ENSURE( + xReplaceExistingData.is(), + "Invalid NameClashResolveDialogResult: OVERWRITE - " + "No ReplaceExistingData continuation available!" ); + xReplaceExistingData->select(); + break; + } +} + +void +UUIInteractionHelper::handleGenericErrorRequest( + sal_Int32 nErrorCode, + uno::Sequence< uno::Reference< + task::XInteractionContinuation > > const & rContinuations, + bool bObtainErrorStringOnly, + bool & bHasErrorString, + rtl::OUString & rErrorString) + SAL_THROW((uno::RuntimeException)) +{ + if (bObtainErrorStringOnly) + { + bHasErrorString = isInformationalErrorMessageRequest(rContinuations); + if (bHasErrorString) + { + String aErrorString; + ErrorHandler::GetErrorString(nErrorCode, aErrorString); + rErrorString = aErrorString; + } + } + else + { + uno::Reference< task::XInteractionAbort > xAbort; + uno::Reference< task::XInteractionApprove > xApprove; + getContinuations(rContinuations, &xApprove, &xAbort); + + // Note: It's important to convert the transported long to the + // required unsigned long value. Otherwhise using as flag field + // can fail ... + ErrCode nError = static_cast< ErrCode >(nErrorCode); + sal_Bool bWarning = !ERRCODE_TOERROR(nError); + + if ( nError == ERRCODE_SFX_BROKENSIGNATURE + || nError == ERRCODE_SFX_INCOMPLETE_ENCRYPTION ) + { + // the security warning box needs a special title + String aErrorString; + ErrorHandler::GetErrorString( nErrorCode, aErrorString ); + + std::auto_ptr< ResMgr > xManager( + ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); + ::rtl::OUString aTitle; + + try + { + uno::Any aProductNameAny = + ::utl::ConfigManager::GetConfigManager() + ->GetDirectConfigProperty( + ::utl::ConfigManager::PRODUCTNAME ); + aProductNameAny >>= aTitle; + } + catch( uno::Exception& ) + { + } + + ::rtl::OUString aErrTitle + = String( ResId( nError == ERRCODE_SFX_BROKENSIGNATURE + ? STR_WARNING_BROKENSIGNATURE_TITLE + : STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE, + *xManager.get() ) ); + + if ( aTitle.getLength() && aErrTitle.getLength() ) + aTitle += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " - " ) ); + aTitle += aErrTitle; + + executeMessageBox( + getParentProperty(), aTitle, aErrorString, WB_OK ); + } + else + ErrorHandler::HandleError(nErrorCode); + + if (xApprove.is() && bWarning) + xApprove->select(); + else if (xAbort.is()) + xAbort->select(); + } +} + +void +UUIInteractionHelper::handleMacroConfirmRequest( + const ::rtl::OUString& aDocumentURL, + const uno::Reference< embed::XStorage >& xZipStorage, + const ::rtl::OUString& aDocumentVersion, + const uno::Sequence< security::DocumentSignatureInformation > aSignInfo, + uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & + rContinuations ) + SAL_THROW((uno::RuntimeException)) +{ + uno::Reference< task::XInteractionAbort > xAbort; + uno::Reference< task::XInteractionApprove > xApprove; + getContinuations( rContinuations, &xApprove, &xAbort ); + + bool bApprove = false; + + std::auto_ptr< ResMgr > pResMgr( + ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); + if ( pResMgr.get() ) + { + bool bShowSignatures = aSignInfo.getLength() > 0; + MacroWarning aWarning( + getParentProperty(), bShowSignatures, *pResMgr.get() ); + + aWarning.SetDocumentURL( aDocumentURL ); + if ( aSignInfo.getLength() > 1 ) + { + aWarning.SetStorage( xZipStorage, aDocumentVersion, aSignInfo ); + } + else if ( aSignInfo.getLength() == 1 ) + { + aWarning.SetCertificate( aSignInfo[ 0 ].Signer ); + } + + bApprove = aWarning.Execute() == RET_OK; + } + + if ( bApprove && xApprove.is() ) + xApprove->select(); + else if ( xAbort.is() ) + xAbort->select(); +} + +void +UUIInteractionHelper::handleFutureDocumentVersionUpdateRequest( + const task::FutureDocumentVersionProductUpdateRequest& _rRequest, + uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & + rContinuations ) + SAL_THROW((uno::RuntimeException)) +{ + uno::Reference< task::XInteractionAbort > xAbort; + uno::Reference< task::XInteractionApprove > xApprove; + uno::Reference< task::XInteractionAskLater > xAskLater; + getContinuations( rContinuations, &xApprove, &xAbort, &xAskLater ); + + short nResult = RET_CANCEL; + + static bool s_bDeferredToNextSession = false; + // TODO: this static variable is somewhat hacky. Formerly (before the dialog was moved from SFX2 to the + // interaction handler implementation), this was stored in SFX_APP()'s impl structure, in member + // bODFVersionWarningLater. Of course, we do not have access to it here. + // + // A proper solution which I would envision would be: + // - There's a central implementation (this one here) of css.task.InteractionHandler + // - There's a configuration which maps UNO names to service names + // - If the handler is confronted with a request, it tries to find the name of the UNO structure describing + // the request in the said configuration. + // - If an entry is found, then + // - the respective service is instantiated + // - the component is queried for css.task.XInteractionHandler, and the request is delegated + // - if no entry is found, then the request is silenced (with calling the AbortContinuation, if possible) + // This way, the FutureDocumentVersionProductUpdateRequest could be handled in SFX (or any other + // suitable place), again, and we would only have one place where we remember the s_bDeferredToNextSession + // flag. + // + // 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 ) + { + std::auto_ptr< ResMgr > pResMgr( + ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); + if ( pResMgr.get() ) + { + ::uui::NewerVersionWarningDialog aDialog( + getParentProperty(), + _rRequest.DocumentODFVersion, + *pResMgr.get() ); + nResult = aDialog.Execute(); + } + } + + switch ( nResult ) + { + case RET_OK: + if ( xApprove.is() ) + xApprove->select(); + break; + case RET_CANCEL: + if ( xAbort.is() ) + xAbort->select(); + break; + case RET_ASK_LATER: + if ( xAskLater.is() ) + xAskLater->select(); + s_bDeferredToNextSession = true; + break; + default: + OSL_ENSURE( false, + "UUIInteractionHelper::handleFutureDocumentVersionUpdateRequest: " + "unexpected dialog return value!" ); + break; + } +} + +void +UUIInteractionHelper::handleBrokenPackageRequest( + std::vector< rtl::OUString > const & rArguments, + uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & + rContinuations, + bool bObtainErrorStringOnly, + bool & bHasErrorString, + rtl::OUString & rErrorString) + SAL_THROW((uno::RuntimeException)) +{ + if (bObtainErrorStringOnly) + { + bHasErrorString = isInformationalErrorMessageRequest(rContinuations); + if (!bHasErrorString) + return; + } + + uno::Reference< task::XInteractionApprove > xApprove; + uno::Reference< task::XInteractionDisapprove > xDisapprove; + uno::Reference< task::XInteractionAbort > xAbort; + getContinuations(rContinuations, &xApprove, &xDisapprove, &xAbort); + + ErrCode nErrorCode; + if( xApprove.is() && xDisapprove.is() ) + { + nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE; + } + else if ( xAbort.is() ) + { + nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE_CANTREPAIR; + } + else + return; + + ::rtl::OUString aMessage; + { + vos::OGuard aGuard(Application::GetSolarMutex()); + std::auto_ptr< ResMgr > xManager( + ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(uui))); + if (!xManager.get()) + return; + + ResId aResId( RID_UUI_ERRHDL, *xManager.get() ); + if ( !ErrorResource(aResId).getString(nErrorCode, &aMessage) ) + return; + } + + aMessage = replaceMessageWithArguments( aMessage, rArguments ); + + if (bObtainErrorStringOnly) + { + rErrorString = aMessage; + return; + } + + WinBits nButtonMask; + if( xApprove.is() && xDisapprove.is() ) + { + nButtonMask = WB_YES_NO | WB_DEF_YES; + } + else if ( xAbort.is() ) + { + nButtonMask = WB_OK; + } + else + return; + + uno::Any aProductNameAny = + ::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty( + ::utl::ConfigManager::PRODUCTNAME ); + uno::Any aProductVersionAny = + ::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty( + ::utl::ConfigManager::PRODUCTVERSION ); + ::rtl::OUString aProductName, aProductVersion; + if ( !( aProductNameAny >>= aProductName ) ) + aProductName + = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StarOffice") ); + + ::rtl::OUString aTitle( aProductName ); + if( aProductVersionAny >>= aProductVersion ) + { + aTitle += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" ") ); + aTitle += aProductVersion; + } + + switch ( executeMessageBox( getParentProperty(), + aTitle, + aMessage, + nButtonMask )) + { + case ERRCODE_BUTTON_OK: + OSL_ENSURE( xAbort.is(), "unexpected situation" ); + if (xAbort.is()) + xAbort->select(); + break; + + case ERRCODE_BUTTON_NO: + OSL_ENSURE(xDisapprove.is(), "unexpected situation"); + if (xDisapprove.is()) + xDisapprove->select(); + break; + + case ERRCODE_BUTTON_YES: + OSL_ENSURE(xApprove.is(), "unexpected situation"); + if (xApprove.is()) + xApprove->select(); + break; + } +} + +//========================================================================= +// ErrorResource Implementation +//========================================================================= + +bool +ErrorResource::getString(ErrCode nErrorCode, rtl::OUString * pString) + const SAL_THROW(()) +{ + OSL_ENSURE(pString, "specification violation"); + ResId aResId(static_cast< USHORT >(nErrorCode & ERRCODE_RES_MASK), + *m_pResMgr); + aResId.SetRT(RSC_STRING); + if (!IsAvailableRes(aResId)) + return false; + aResId.SetAutoRelease(false); + *pString = UniString(aResId); + m_pResMgr->PopContext(); + return true; +} |