1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <com/sun/star/awt/XWindow.hpp>
23 #include <com/sun/star/beans/PropertyValue.hpp>
24 #include <com/sun/star/configuration/theDefaultProvider.hpp>
25 #include <com/sun/star/configuration/backend/MergeRecoveryRequest.hpp>
26 #include <com/sun/star/configuration/backend/StratumCreationException.hpp>
27 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
28 #include <com/sun/star/document/BrokenPackageRequest.hpp>
29 #include <com/sun/star/document/ExoticFileLoadException.hpp>
30 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
31 #include <com/sun/star/java/WrongJavaVersionException.hpp>
32 #include <com/sun/star/lang/XInitialization.hpp>
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/script/ModuleSizeExceededRequest.hpp>
35 #include <com/sun/star/task/ErrorCodeIOException.hpp>
36 #include <com/sun/star/task/ErrorCodeRequest.hpp>
37 #include <com/sun/star/task/InteractionHandler.hpp>
38 #include <com/sun/star/task/XInteractionAbort.hpp>
39 #include <com/sun/star/task/XInteractionApprove.hpp>
40 #include <com/sun/star/task/XInteractionDisapprove.hpp>
41 #include <com/sun/star/task/XInteractionHandler2.hpp>
42 #include <com/sun/star/task/XInteractionRequest.hpp>
43 #include <com/sun/star/task/XInteractionRetry.hpp>
44 #include <com/sun/star/ucb/AuthenticationFallbackRequest.hpp>
45 #include <com/sun/star/ucb/InteractiveAppException.hpp>
46 #include <com/sun/star/ucb/InteractiveLockingLockedException.hpp>
47 #include <com/sun/star/ucb/InteractiveLockingNotLockedException.hpp>
48 #include <com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp>
49 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
50 #include <com/sun/star/ucb/InteractiveNetworkOffLineException.hpp>
51 #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
52 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
53 #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
54 #include <com/sun/star/ucb/InteractiveWrongMediumException.hpp>
55 #include <com/sun/star/ucb/NameClashException.hpp>
56 #include <com/sun/star/ucb/NameClashResolveRequest.hpp>
57 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
58 #include <com/sun/star/ucb/XInteractionReplaceExistingData.hpp>
59 #include <com/sun/star/ucb/XInteractionSupplyName.hpp>
60 #include <com/sun/star/xforms/InvalidDataOnSubmitException.hpp>
61 #include <com/sun/star/loader/CannotActivateFactoryException.hpp>
63 #include <rtl/strbuf.hxx>
64 #include <osl/conditn.hxx>
65 #include <unotools/resmgr.hxx>
66 #include <vcl/errinf.hxx>
67 #include <vcl/svapp.hxx>
68 #include <vcl/weld.hxx>
69 #include <osl/thread.hxx>
70 #include <tools/diagnose_ex.h>
71 #include <comphelper/documentconstants.hxx>
72 #include <comphelper/propertysequence.hxx>
73 #include <svtools/sfxecode.hxx>
74 #include <unotools/configmgr.hxx>
75 #include <comphelper/namedvaluecollection.hxx>
76 #include <typelib/typedescription.hxx>
77 #include <unotools/confignode.hxx>
81 #include <strings.hrc>
83 #include "getcontinuations.hxx"
84 #include "secmacrowarnings.hxx"
87 #include "nameclashdlg.hxx"
89 using ::com::sun::star::uno::Sequence
;
90 using ::com::sun::star::uno::UNO_QUERY
;
91 using ::com::sun::star::uno::Reference
;
92 using ::com::sun::star::task::XInteractionContinuation
;
93 using ::com::sun::star::task::XInteractionAbort
;
94 using ::com::sun::star::task::XInteractionApprove
;
95 using ::com::sun::star::uno::XInterface
;
96 using ::com::sun::star::lang::XInitialization
;
97 using ::com::sun::star::uno::UNO_QUERY_THROW
;
98 using ::com::sun::star::task::InteractionHandler
;
99 using ::com::sun::star::task::XInteractionHandler2
;
100 using ::com::sun::star::uno::Exception
;
101 using ::com::sun::star::uno::Any
;
102 using ::com::sun::star::task::XInteractionRequest
;
103 using ::com::sun::star::lang::XMultiServiceFactory
;
105 using namespace ::com::sun::star
;
109 class HandleData
: public osl::Condition
113 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
115 m_rRequest(rRequest
),
119 uno::Reference
< task::XInteractionRequest
> m_rRequest
;
121 beans::Optional
< OUString
> m_aResult
;
126 UUIInteractionHelper::UUIInteractionHelper(
127 uno::Reference
< uno::XComponentContext
> const & rxContext
,
128 uno::Reference
< awt::XWindow
> const & rxWindowParam
,
129 const OUString
& rContextParam
)
130 : m_xContext(rxContext
),
131 m_xWindowParam(rxWindowParam
),
132 m_aContextParam(rContextParam
)
136 UUIInteractionHelper::UUIInteractionHelper(
137 uno::Reference
< uno::XComponentContext
> const & rxContext
)
138 : m_xContext(rxContext
)
142 UUIInteractionHelper::~UUIInteractionHelper()
146 void UUIInteractionHelper::handlerequest(
147 void* pHandleData
, void* pInteractionHelper
)
150 = static_cast< HandleData
* >(pHandleData
);
151 UUIInteractionHelper
* pUUI
152 = static_cast< UUIInteractionHelper
* >(pInteractionHelper
);
156 = pUUI
->handleRequest_impl(pHND
->m_rRequest
, false, bDummy
, aDummy
);
161 UUIInteractionHelper::handleRequest(
162 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
165 Application::GetMainThreadIdentifier()
166 != osl::Thread::getCurrentIdentifier()
170 // we are not in the main thread, let it handle that stuff
171 HandleData
aHD(rRequest
);
172 Link
<void*,void> aLink(&aHD
,handlerequest
);
173 Application::PostUserEvent(aLink
,this);
174 comphelper::SolarMutex
& rSolarMutex
= Application::GetSolarMutex();
175 sal_uInt32 nLockCount
= (rSolarMutex
.IsCurrentThread()) ? rSolarMutex
.release(true) : 0;
178 rSolarMutex
.acquire(nLockCount
);
185 return handleRequest_impl(rRequest
, false, bDummy
, aDummy
);
189 void UUIInteractionHelper::getstringfromrequest(
190 void* pHandleData
,void* pInteractionHelper
)
192 HandleData
* pHND
= static_cast<HandleData
*>(pHandleData
);
193 UUIInteractionHelper
* pUUI
= static_cast<UUIInteractionHelper
*>(pInteractionHelper
);
194 pHND
->m_aResult
= pUUI
->getStringFromRequest_impl(pHND
->m_rRequest
);
198 beans::Optional
< OUString
>
199 UUIInteractionHelper::getStringFromRequest_impl(
200 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
202 bool bSuccess
= false;
204 handleRequest_impl(rRequest
, true, bSuccess
, aMessage
);
206 OSL_ENSURE(bSuccess
||
207 !isInformationalErrorMessageRequest(
208 rRequest
->getContinuations()),
209 "Interaction request is a candidate for a string representation."
210 "Please implement!");
212 return beans::Optional
< OUString
>(bSuccess
, aMessage
);
215 beans::Optional
< OUString
>
216 UUIInteractionHelper::getStringFromRequest(
217 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
220 Application::GetMainThreadIdentifier()
221 != osl::Thread::getCurrentIdentifier()
225 // we are not in the main thread, let it handle that stuff
226 HandleData
aHD(rRequest
);
227 Link
<void*,void> aLink(&aHD
,getstringfromrequest
);
228 Application::PostUserEvent(aLink
,this);
229 comphelper::SolarMutex
& rSolarMutex
= Application::GetSolarMutex();
230 sal_uInt32 nLockCount
= (rSolarMutex
.IsCurrentThread()) ? rSolarMutex
.release(true) : 0;
233 rSolarMutex
.acquire(nLockCount
);
234 return aHD
.m_aResult
;
237 return getStringFromRequest_impl(rRequest
);
241 UUIInteractionHelper::replaceMessageWithArguments(
242 const OUString
& _aMessage
,
243 std::vector
< OUString
> const & rArguments
)
245 OUString aMessage
= _aMessage
;
247 SAL_WARN_IF(rArguments
.size() == 0, "uui", "replaceMessageWithArguments: No arguments passed!");
248 for (size_t i
= 0; i
< rArguments
.size(); ++i
)
250 const OUString sReplaceTemplate
= "$(ARG" + OUString::number(i
+1) + ")";
251 aMessage
= aMessage
.replaceAll(sReplaceTemplate
, rArguments
[i
]);
258 UUIInteractionHelper::isInformationalErrorMessageRequest(
259 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
262 // Only requests with a single continuation (user has no choice, request
263 // is just informational)
264 if (rContinuations
.getLength() != 1 )
267 // user can only abort or approve, all other continuations are not
268 // considered to be informational.
269 uno::Reference
< task::XInteractionApprove
> xApprove(
270 rContinuations
[0], uno::UNO_QUERY
);
274 uno::Reference
< task::XInteractionAbort
> xAbort(
275 rContinuations
[0], uno::UNO_QUERY
);
280 UUIInteractionHelper::tryOtherInteractionHandler(
281 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
283 InteractionHandlerDataList dataList
;
284 getInteractionHandlerList(dataList
);
286 InteractionHandlerDataList::const_iterator
aEnd(dataList
.end());
287 for (InteractionHandlerDataList::const_iterator
aIt(dataList
.begin());
291 if ( handleCustomRequest( rRequest
, aIt
->ServiceName
) )
300 bool lcl_matchesRequest( const Any
& i_rRequest
, const OUString
& i_rTypeName
, const OUString
& i_rPropagation
)
302 const css::uno::TypeDescription
aTypeDesc( i_rTypeName
);
303 const typelib_TypeDescription
* pTypeDesc
= aTypeDesc
.get();
304 if ( !pTypeDesc
|| !pTypeDesc
->pWeakRef
)
306 SAL_WARN( "uui","no type found for '" << i_rTypeName
<< "'" );
309 const css::uno::Type
aType( pTypeDesc
->pWeakRef
);
311 const bool bExactMatch
= i_rPropagation
== "named-only";
313 return i_rRequest
.getValueType().equals( aType
);
315 return i_rRequest
.isExtractableTo( aType
);
320 bool UUIInteractionHelper::handleCustomRequest( const Reference
< XInteractionRequest
>& i_rRequest
, const OUString
& i_rServiceName
) const
324 Reference
< XInteractionHandler2
> xHandler( m_xContext
->getServiceManager()->createInstanceWithContext( i_rServiceName
, m_xContext
), UNO_QUERY_THROW
);
326 Reference
< XInitialization
> xHandlerInit( xHandler
, UNO_QUERY
);
327 if ( xHandlerInit
.is() )
329 ::comphelper::NamedValueCollection aInitArgs
;
330 aInitArgs
.put( "Parent", getParentXWindow() );
331 xHandlerInit
->initialize( aInitArgs
.getWrappedPropertyValues() );
334 if ( xHandler
->handleInteractionRequest( i_rRequest
) )
337 catch( const Exception
& )
339 DBG_UNHANDLED_EXCEPTION("uui");
345 bool UUIInteractionHelper::handleTypedHandlerImplementations( Reference
< XInteractionRequest
> const & rRequest
)
348 const Any
aRequest( rRequest
->getRequest() );
350 const StringHashMap::const_iterator aCacheHitTest
= m_aTypedCustomHandlers
.find( aRequest
.getValueTypeName() );
351 if ( aCacheHitTest
!= m_aTypedCustomHandlers
.end() )
352 return handleCustomRequest( rRequest
, aCacheHitTest
->second
);
354 // the base registration node for "typed" interaction handlers
355 const ::utl::OConfigurationTreeRoot
aConfigRoot( ::utl::OConfigurationTreeRoot::createWithComponentContext(
357 "/org.openoffice.Interaction/InteractionHandlers",
359 ::utl::OConfigurationTreeRoot::CM_READONLY
362 // loop through all registered implementations
363 const Sequence
< OUString
> aRegisteredHandlers( aConfigRoot
.getNodeNames() );
364 for ( auto const & handlerName
: aRegisteredHandlers
)
366 const ::utl::OConfigurationNode
aHandlerNode( aConfigRoot
.openNode( handlerName
) );
367 const ::utl::OConfigurationNode
aTypesNode( aHandlerNode
.openNode( "HandledRequestTypes" ) );
369 // loop through all the types which the current handler is registered for
370 const Sequence
< OUString
> aHandledTypes( aTypesNode
.getNodeNames() );
371 for ( auto const & type
: aHandledTypes
)
373 // the UNO type is the node name
374 ::utl::OConfigurationNode
aType( aTypesNode
.openNode( type
) );
375 // and there's a child denoting how the responsibility propagates
376 OUString sPropagation
;
377 OSL_VERIFY( aType
.getNodeValue( "Propagation" ) >>= sPropagation
);
378 if ( lcl_matchesRequest( aRequest
, type
, sPropagation
) )
380 // retrieve the service/implementation name of the handler
381 OUString sServiceName
;
382 OSL_VERIFY( aHandlerNode
.getNodeValue( "ServiceName" ) >>= sServiceName
);
383 // cache the information who feels responsible for requests of this type
384 m_aTypedCustomHandlers
[ aRequest
.getValueTypeName() ] = sServiceName
;
385 // actually handle the request
386 return handleCustomRequest( rRequest
, sServiceName
);
395 UUIInteractionHelper::handleRequest_impl(
396 uno::Reference
< task::XInteractionRequest
> const & rRequest
,
397 bool bObtainErrorStringOnly
,
398 bool & bHasErrorString
,
399 OUString
& rErrorString
)
406 uno::Any
aAnyRequest(rRequest
->getRequest());
408 script::ModuleSizeExceededRequest aModSizeException
;
409 if (aAnyRequest
>>= aModSizeException
)
411 std::vector
< OUString
> aArguments
;
412 uno::Sequence
< OUString
> sModules
413 = aModSizeException
.Names
;
414 if ( sModules
.getLength() )
417 for ( sal_Int32 index
=0; index
< sModules
.getLength(); ++index
)
420 aName
+= "," + sModules
[index
];
422 aName
= sModules
[index
]; // 1st name
424 aArguments
.push_back( aName
);
426 handleErrorHandlerRequest( task::InteractionClassification_WARNING
,
427 ERRCODE_UUI_IO_MODULESIZEEXCEEDED
,
429 rRequest
->getContinuations(),
430 bObtainErrorStringOnly
,
436 document::ExoticFileLoadException aExoticFileLoadException
;
437 if (aAnyRequest
>>= aExoticFileLoadException
)
439 std::vector
< OUString
> aArguments
;
441 if( !aExoticFileLoadException
.URL
.isEmpty() )
443 aArguments
.push_back( aExoticFileLoadException
.URL
);
445 if( !aExoticFileLoadException
.FilterUIName
.isEmpty() )
447 aArguments
.push_back( aExoticFileLoadException
.FilterUIName
);
450 handleErrorHandlerRequest( task::InteractionClassification_WARNING
,
451 ERRCODE_UUI_IO_EXOTICFILEFORMAT
,
453 rRequest
->getContinuations(),
454 bObtainErrorStringOnly
,
460 ucb::NameClashException aNCException
;
461 if (aAnyRequest
>>= aNCException
)
463 ErrCode nErrorCode
= ERRCODE_UUI_IO_TARGETALREADYEXISTS
;
464 std::vector
< OUString
> aArguments
;
466 if( !aNCException
.Name
.isEmpty() )
468 nErrorCode
= ERRCODE_UUI_IO_ALREADYEXISTS
;
469 aArguments
.push_back( aNCException
.Name
);
472 handleErrorHandlerRequest( aNCException
.Classification
,
475 rRequest
->getContinuations(),
476 bObtainErrorStringOnly
,
482 ucb::UnsupportedNameClashException aUORequest
;
483 if (aAnyRequest
>>= aUORequest
)
485 std::vector
< OUString
> aArguments
;
487 uno::Reference
< task::XInteractionApprove
> xApprove
;
488 uno::Reference
< task::XInteractionDisapprove
> xDisapprove
;
490 rRequest
->getContinuations(), &xApprove
, &xDisapprove
);
492 if ( xApprove
.is() && xDisapprove
.is() )
494 handleErrorHandlerRequest( task::InteractionClassification_QUERY
,
495 ERRCODE_UUI_IO_UNSUPPORTEDOVERWRITE
,
497 rRequest
->getContinuations(),
498 bObtainErrorStringOnly
,
505 if ( handleInteractiveIOException( rRequest
,
506 bObtainErrorStringOnly
,
511 ucb::InteractiveAppException aAppException
;
512 if (aAnyRequest
>>= aAppException
)
514 std::vector
< OUString
> aArguments
;
515 handleErrorHandlerRequest( aAppException
.Classification
,
516 ErrCode(aAppException
.Code
),
518 rRequest
->getContinuations(),
519 bObtainErrorStringOnly
,
525 ucb::InteractiveNetworkException aNetworkException
;
526 if (aAnyRequest
>>= aNetworkException
)
529 std::vector
< OUString
> aArguments
;
530 ucb::InteractiveNetworkOffLineException aOffLineException
;
531 ucb::InteractiveNetworkResolveNameException aResolveNameException
;
532 ucb::InteractiveNetworkConnectException aConnectException
;
533 ucb::InteractiveNetworkReadException aReadException
;
534 ucb::InteractiveNetworkWriteException aWriteException
;
535 if (aAnyRequest
>>= aOffLineException
)
536 nErrorCode
= ERRCODE_INET_OFFLINE
;
537 else if (aAnyRequest
>>= aResolveNameException
)
539 nErrorCode
= ERRCODE_INET_NAME_RESOLVE
;
540 aArguments
.push_back(aResolveNameException
.Server
);
542 else if (aAnyRequest
>>= aConnectException
)
544 nErrorCode
= ERRCODE_INET_CONNECT
;
545 aArguments
.push_back(aConnectException
.Server
);
547 else if (aAnyRequest
>>= aReadException
)
549 nErrorCode
= ERRCODE_INET_READ
;
550 aArguments
.push_back(aReadException
.Diagnostic
);
552 else if (aAnyRequest
>>= aWriteException
)
554 nErrorCode
= ERRCODE_INET_WRITE
;
555 aArguments
.push_back(aWriteException
.Diagnostic
);
558 nErrorCode
= ERRCODE_INET_GENERAL
;
560 handleErrorHandlerRequest(aNetworkException
.Classification
,
563 rRequest
->getContinuations(),
564 bObtainErrorStringOnly
,
570 ucb::InteractiveWrongMediumException aWrongMediumException
;
571 if (aAnyRequest
>>= aWrongMediumException
)
573 sal_Int32 nMedium
= 0;
574 aWrongMediumException
.Medium
>>= nMedium
;
575 std::vector
< OUString
> aArguments
;
576 aArguments
.push_back(OUString::number(nMedium
+ 1));
577 handleErrorHandlerRequest(aWrongMediumException
.Classification
,
578 ERRCODE_UUI_WRONGMEDIUM
,
580 rRequest
->getContinuations(),
581 bObtainErrorStringOnly
,
587 java::WrongJavaVersionException aWrongJavaVersionException
;
588 if (aAnyRequest
>>= aWrongJavaVersionException
)
591 std::vector
< OUString
> aArguments
;
592 if (aWrongJavaVersionException
.DetectedVersion
.isEmpty())
593 if (aWrongJavaVersionException
.LowestSupportedVersion
.isEmpty())
594 nErrorCode
= ERRCODE_UUI_WRONGJAVA
;
597 nErrorCode
= ERRCODE_UUI_WRONGJAVA_MIN
;
598 aArguments
.push_back(aWrongJavaVersionException
.LowestSupportedVersion
);
600 else if (aWrongJavaVersionException
.LowestSupportedVersion
.isEmpty())
602 nErrorCode
= ERRCODE_UUI_WRONGJAVA_VERSION
;
603 aArguments
.push_back(aWrongJavaVersionException
.DetectedVersion
);
607 nErrorCode
= ERRCODE_UUI_WRONGJAVA_VERSION_MIN
;
608 aArguments
.reserve(2);
609 aArguments
.push_back(aWrongJavaVersionException
.DetectedVersion
);
610 aArguments
.push_back(aWrongJavaVersionException
.LowestSupportedVersion
);
612 handleErrorHandlerRequest(task::InteractionClassification_ERROR
,
615 rRequest
->getContinuations(),
616 bObtainErrorStringOnly
,
622 configuration::backend::MergeRecoveryRequest aMergeRecoveryRequest
;
623 if (aAnyRequest
>>= aMergeRecoveryRequest
)
625 ErrCode nErrorCode
= aMergeRecoveryRequest
.IsRemovalRequest
626 ? ERRCODE_UUI_CONFIGURATION_BROKENDATA_WITHREMOVE
627 : ERRCODE_UUI_CONFIGURATION_BROKENDATA_NOREMOVE
;
629 std::vector
< OUString
> aArguments
;
630 aArguments
.push_back(aMergeRecoveryRequest
.ErrorLayerId
);
632 handleErrorHandlerRequest(task::InteractionClassification_ERROR
,
635 rRequest
->getContinuations(),
636 bObtainErrorStringOnly
,
642 configuration::backend::StratumCreationException
643 aStratumCreationException
;
645 if (aAnyRequest
>>= aStratumCreationException
)
647 const ErrCode nErrorCode
= ERRCODE_UUI_CONFIGURATION_BACKENDMISSING
;
649 OUString aStratum
= aStratumCreationException
.StratumData
;
650 if (aStratum
.isEmpty())
651 aStratum
= aStratumCreationException
.StratumService
;
653 std::vector
< OUString
> aArguments
;
654 aArguments
.push_back(aStratum
);
656 handleErrorHandlerRequest(task::InteractionClassification_ERROR
,
659 rRequest
->getContinuations(),
660 bObtainErrorStringOnly
,
666 xforms::InvalidDataOnSubmitException aInvalidDataOnSubmitException
;
667 if (aAnyRequest
>>= aInvalidDataOnSubmitException
)
669 const ErrCode nErrorCode
=
670 ERRCODE_UUI_INVALID_XFORMS_SUBMISSION_DATA
;
672 std::vector
< OUString
> aArguments
;
674 handleErrorHandlerRequest(task::InteractionClassification_QUERY
,
677 rRequest
->getContinuations(),
678 bObtainErrorStringOnly
,
684 ucb::InteractiveLockingLockedException aLLException
;
685 if (aAnyRequest
>>= aLLException
)
687 ErrCode nErrorCode
= aLLException
.SelfOwned
688 ? ERRCODE_UUI_LOCKING_LOCKED_SELF
: ERRCODE_UUI_LOCKING_LOCKED
;
689 std::vector
< OUString
> aArguments
;
690 aArguments
.push_back( aLLException
.Url
);
692 handleErrorHandlerRequest( aLLException
.Classification
,
695 rRequest
->getContinuations(),
696 bObtainErrorStringOnly
,
702 ucb::InteractiveLockingNotLockedException aLNLException
;
703 if (aAnyRequest
>>= aLNLException
)
705 std::vector
< OUString
> aArguments
;
706 aArguments
.push_back( aLNLException
.Url
);
708 handleErrorHandlerRequest( aLNLException
.Classification
,
709 ERRCODE_UUI_LOCKING_NOT_LOCKED
,
711 rRequest
->getContinuations(),
712 bObtainErrorStringOnly
,
718 ucb::InteractiveLockingLockExpiredException aLLEException
;
719 if (aAnyRequest
>>= aLLEException
)
721 std::vector
< OUString
> aArguments
;
722 aArguments
.push_back( aLLEException
.Url
);
724 handleErrorHandlerRequest( aLLEException
.Classification
,
725 ERRCODE_UUI_LOCKING_LOCK_EXPIRED
,
727 rRequest
->getContinuations(),
728 bObtainErrorStringOnly
,
734 document::BrokenPackageRequest aBrokenPackageRequest
;
735 if (aAnyRequest
>>= aBrokenPackageRequest
)
737 std::vector
< OUString
> aArguments
;
739 if( !aBrokenPackageRequest
.aName
.isEmpty() )
740 aArguments
.push_back( aBrokenPackageRequest
.aName
);
742 handleBrokenPackageRequest( aArguments
,
743 rRequest
->getContinuations(),
744 bObtainErrorStringOnly
,
750 task::ErrorCodeRequest aErrorCodeRequest
;
751 if (aAnyRequest
>>= aErrorCodeRequest
)
753 handleGenericErrorRequest( ErrCode(aErrorCodeRequest
.ErrCode
),
754 rRequest
->getContinuations(),
755 bObtainErrorStringOnly
,
761 task::ErrorCodeIOException aErrorCodeIOException
;
762 if (aAnyRequest
>>= aErrorCodeIOException
)
764 handleGenericErrorRequest( ErrCode(aErrorCodeIOException
.ErrCode
),
765 rRequest
->getContinuations(),
766 bObtainErrorStringOnly
,
772 loader::CannotActivateFactoryException aCannotActivateFactoryException
;
773 if (aAnyRequest
>>= aCannotActivateFactoryException
)
775 std::vector
< OUString
> aArguments
;
776 aArguments
.push_back( aCannotActivateFactoryException
.Message
);
778 handleErrorHandlerRequest( task::InteractionClassification_ERROR
,
779 ERRCODE_UUI_CANNOT_ACTIVATE_FACTORY
,
781 rRequest
->getContinuations(),
782 bObtainErrorStringOnly
,
789 // Handle requests which do not have a plain string representation.
791 if (!bObtainErrorStringOnly
)
793 ucb::AuthenticationFallbackRequest anAuthFallbackRequest
;
794 if ( aAnyRequest
>>= anAuthFallbackRequest
)
796 handleAuthFallbackRequest( anAuthFallbackRequest
.instructions
,
797 anAuthFallbackRequest
.url
, rRequest
->getContinuations() );
801 if ( handleAuthenticationRequest( rRequest
) )
804 if ( handleCertificateValidationRequest( rRequest
) )
807 ucb::NameClashResolveRequest aNameClashResolveRequest
;
808 if (aAnyRequest
>>= aNameClashResolveRequest
)
810 handleNameClashResolveRequest(aNameClashResolveRequest
,
811 rRequest
->getContinuations());
815 if ( handleMasterPasswordRequest( rRequest
) )
818 if ( handlePasswordRequest( rRequest
) )
821 if ( handleNoSuchFilterRequest( rRequest
) )
824 if ( handleFilterOptionsRequest( rRequest
) )
827 if ( handleLockedDocumentRequest( rRequest
) )
830 if ( handleChangedByOthersRequest( rRequest
) )
833 if ( handleLockFileProblemRequest( rRequest
) )
836 task::DocumentMacroConfirmationRequest aMacroConfirmRequest
;
837 if (aAnyRequest
>>= aMacroConfirmRequest
)
839 handleMacroConfirmRequest(
840 aMacroConfirmRequest
.DocumentURL
,
841 aMacroConfirmRequest
.DocumentStorage
,
842 !aMacroConfirmRequest
.DocumentVersion
.isEmpty() ? aMacroConfirmRequest
.DocumentVersion
: ODFVER_012_TEXT
,
843 aMacroConfirmRequest
.DocumentSignatureInformation
,
844 rRequest
->getContinuations());
848 // Last chance: interaction handlers registered in the configuration
851 // typed InteractionHandlers (ooo.Interactions)
852 if ( handleTypedHandlerImplementations( rRequest
) )
855 // legacy configuration (ooo.ucb.InteractionHandlers)
856 if (tryOtherInteractionHandler( rRequest
))
863 catch( const uno::RuntimeException
& )
865 throw; // allowed to leave here
867 catch( const uno::Exception
& )
869 DBG_UNHANDLED_EXCEPTION("uui");
875 UUIInteractionHelper::getInteractionHandlerList(
876 InteractionHandlerDataList
&rdataList
)
880 uno::Reference
< lang::XMultiServiceFactory
> xConfigProv
=
881 configuration::theDefaultProvider::get( m_xContext
);
883 OUStringBuffer aFullPath
;
885 "/org.openoffice.ucb.InteractionHandler/InteractionHandlers" );
887 uno::Sequence
<uno::Any
> aArguments(comphelper::InitAnyPropertySequence(
889 {"nodepath", uno::Any(aFullPath
.makeStringAndClear())}
892 uno::Reference
< uno::XInterface
> xInterface(
893 xConfigProv
->createInstanceWithArguments(
894 "com.sun.star.configuration.ConfigurationAccess" , aArguments
) );
896 if ( !xInterface
.is() )
897 throw uno::RuntimeException("unable to instantiate config access");
899 uno::Reference
< container::XNameAccess
> xNameAccess(
900 xInterface
, uno::UNO_QUERY_THROW
);
901 uno::Sequence
< OUString
> aElems
= xNameAccess
->getElementNames();
902 const OUString
* pElems
= aElems
.getConstArray();
903 sal_Int32 nCount
= aElems
.getLength();
907 uno::Reference
< container::XHierarchicalNameAccess
>
908 xHierNameAccess( xInterface
, uno::UNO_QUERY_THROW
);
910 // Iterate over children.
911 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
913 OUStringBuffer aElemBuffer
;
914 aElemBuffer
.append( "['" );
915 aElemBuffer
.append( pElems
[ n
] );
919 InteractionHandlerData aInfo
;
921 // Obtain service name.
922 OUStringBuffer aKeyBuffer
= aElemBuffer
;
923 aKeyBuffer
.append( "']/ServiceName" );
926 if ( !( xHierNameAccess
->getByHierarchicalName(
927 aKeyBuffer
.makeStringAndClear() ) >>= aValue
) )
929 OSL_FAIL( "GetInteractionHandlerList - "
930 "Error getting item value!" );
934 aInfo
.ServiceName
= aValue
;
936 // Append info to list.
937 rdataList
.push_back( aInfo
);
939 catch ( container::NoSuchElementException
& )
941 // getByHierarchicalName
943 OSL_FAIL( "GetInteractionHandlerList - "
944 "caught NoSuchElementException!" );
949 catch ( uno::RuntimeException
const & )
953 catch ( uno::Exception
const & )
955 OSL_FAIL( "GetInteractionHandlerList - Caught Exception!" );
959 const uno::Reference
< awt::XWindow
>&
960 UUIInteractionHelper::getParentXWindow() const
962 return m_xWindowParam
;
965 uno::Reference
< task::XInteractionHandler2
>
966 UUIInteractionHelper::getInteractionHandler()
968 return InteractionHandler::createWithParentAndContext(
969 m_xContext
, m_xWindowParam
,
977 weld::Window
* pParent
,
978 OUString
const & rTitle
,
979 OUString
const & rMessage
,
980 VclMessageType eMessageType
)
982 SolarMutexGuard aGuard
;
984 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(pParent
, eMessageType
,
985 eMessageType
== VclMessageType::Question
? VclButtonsType::YesNo
: VclButtonsType::Ok
, rMessage
));
986 xBox
->set_title(rTitle
);
988 short nMessResult
= xBox
->run();
989 DialogMask aResult
= DialogMask::NONE
;
993 aResult
= DialogMask::ButtonsOk
;
996 aResult
= DialogMask::ButtonsCancel
;
999 aResult
= DialogMask::ButtonsYes
;
1002 aResult
= DialogMask::ButtonsNo
;
1011 NameClashResolveDialogResult
executeSimpleNameClashResolveDialog(weld::Window
*pParent
,
1012 OUString
const & rTargetFolderURL
,
1013 OUString
const & rClashingName
,
1014 OUString
& rProposedNewName
,
1015 bool bAllowOverwrite
)
1017 std::locale aResLocale
= Translate::Create("uui");
1018 NameClashDialog
aDialog(pParent
, aResLocale
, rTargetFolderURL
,
1019 rClashingName
, rProposedNewName
, bAllowOverwrite
);
1021 NameClashResolveDialogResult eResult
= static_cast<NameClashResolveDialogResult
>(aDialog
.run());
1022 rProposedNewName
= aDialog
.getNewName();
1029 UUIInteractionHelper::handleNameClashResolveRequest(
1030 ucb::NameClashResolveRequest
const & rRequest
,
1031 uno::Sequence
< uno::Reference
<
1032 task::XInteractionContinuation
> > const & rContinuations
)
1034 OSL_ENSURE(!rRequest
.TargetFolderURL
.isEmpty(),
1035 "NameClashResolveRequest must not contain empty TargetFolderURL" );
1037 OSL_ENSURE(!rRequest
.ClashingName
.isEmpty(),
1038 "NameClashResolveRequest must not contain empty ClashingName" );
1040 uno::Reference
< task::XInteractionAbort
> xAbort
;
1041 uno::Reference
< ucb::XInteractionSupplyName
> xSupplyName
;
1042 uno::Reference
< ucb::XInteractionReplaceExistingData
> xReplaceExistingData
;
1044 rContinuations
, &xAbort
, &xSupplyName
, &xReplaceExistingData
);
1046 OSL_ENSURE( xAbort
.is(),
1047 "NameClashResolveRequest must contain Abort continuation" );
1049 OSL_ENSURE( xSupplyName
.is(),
1050 "NameClashResolveRequest must contain SupplyName continuation" );
1052 NameClashResolveDialogResult eResult
= ABORT
;
1053 OUString
aProposedNewName( rRequest
.ProposedNewName
);
1055 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1056 eResult
= executeSimpleNameClashResolveDialog(Application::GetFrameWeld(xParent
),
1057 rRequest
.TargetFolderURL
,
1058 rRequest
.ClashingName
,
1060 xReplaceExistingData
.is());
1069 xSupplyName
->setName( aProposedNewName
);
1070 xSupplyName
->select();
1075 xReplaceExistingData
.is(),
1076 "Invalid NameClashResolveDialogResult: OVERWRITE - "
1077 "No ReplaceExistingData continuation available!" );
1078 xReplaceExistingData
->select();
1084 UUIInteractionHelper::handleGenericErrorRequest(
1086 uno::Sequence
< uno::Reference
<
1087 task::XInteractionContinuation
> > const & rContinuations
,
1088 bool bObtainErrorStringOnly
,
1089 bool & bHasErrorString
,
1090 OUString
& rErrorString
)
1092 if (bObtainErrorStringOnly
)
1094 bHasErrorString
= isInformationalErrorMessageRequest(rContinuations
);
1095 if (bHasErrorString
)
1097 OUString aErrorString
;
1098 ErrorHandler::GetErrorString(nErrorCode
, aErrorString
);
1099 rErrorString
= aErrorString
;
1104 uno::Reference
< task::XInteractionAbort
> xAbort
;
1105 uno::Reference
< task::XInteractionApprove
> xApprove
;
1106 getContinuations(rContinuations
, &xApprove
, &xAbort
);
1108 // Note: It's important to convert the transported long to the
1109 // required unsigned long value. Otherwise using as flag field
1111 ErrCode
nError(nErrorCode
);
1112 bool bWarning
= !nError
.IgnoreWarning();
1114 if ( nError
== ERRCODE_SFX_INCOMPLETE_ENCRYPTION
)
1116 // the security warning box needs a special title
1117 OUString aErrorString
;
1118 ErrorHandler::GetErrorString( nErrorCode
, aErrorString
);
1120 std::locale aResLocale
= Translate::Create("uui");
1121 OUString
aTitle( utl::ConfigManager::getProductName() );
1123 OUString aErrTitle
= Translate::get(STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE
, aResLocale
);
1125 if ( !aTitle
.isEmpty() && !aErrTitle
.isEmpty() )
1127 aTitle
+= aErrTitle
;
1129 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1130 executeMessageBox(Application::GetFrameWeld(xParent
), aTitle
, aErrorString
, VclMessageType::Error
);
1134 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1135 ErrorHandler::HandleError(nErrorCode
, Application::GetFrameWeld(xParent
));
1138 if (xApprove
.is() && bWarning
)
1140 else if (xAbort
.is())
1146 UUIInteractionHelper::handleMacroConfirmRequest(
1147 const OUString
& aDocumentURL
,
1148 const uno::Reference
< embed::XStorage
>& xZipStorage
,
1149 const OUString
& aDocumentVersion
,
1150 const uno::Sequence
< security::DocumentSignatureInformation
>& aSignInfo
,
1151 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
1154 uno::Reference
< task::XInteractionAbort
> xAbort
;
1155 uno::Reference
< task::XInteractionApprove
> xApprove
;
1156 getContinuations( rContinuations
, &xApprove
, &xAbort
);
1158 bool bApprove
= false;
1160 bool bShowSignatures
= aSignInfo
.getLength() > 0;
1161 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1162 MacroWarning
aWarning(Application::GetFrameWeld(xParent
), bShowSignatures
);
1164 aWarning
.SetDocumentURL(aDocumentURL
);
1165 if ( aSignInfo
.getLength() > 1 )
1167 aWarning
.SetStorage(xZipStorage
, aDocumentVersion
, aSignInfo
);
1169 else if ( aSignInfo
.getLength() == 1 )
1171 aWarning
.SetCertificate(aSignInfo
[0].Signer
);
1174 bApprove
= aWarning
.run() == RET_OK
;
1176 if ( bApprove
&& xApprove
.is() )
1178 else if ( xAbort
.is() )
1183 UUIInteractionHelper::handleBrokenPackageRequest(
1184 std::vector
< OUString
> const & rArguments
,
1185 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
1187 bool bObtainErrorStringOnly
,
1188 bool & bHasErrorString
,
1189 OUString
& rErrorString
)
1191 if (bObtainErrorStringOnly
)
1193 bHasErrorString
= isInformationalErrorMessageRequest(rContinuations
);
1194 if (!bHasErrorString
)
1198 uno::Reference
< task::XInteractionApprove
> xApprove
;
1199 uno::Reference
< task::XInteractionDisapprove
> xDisapprove
;
1200 uno::Reference
< task::XInteractionAbort
> xAbort
;
1201 getContinuations(rContinuations
, &xApprove
, &xDisapprove
, &xAbort
);
1204 if( xApprove
.is() && xDisapprove
.is() )
1206 nErrorCode
= ERRCODE_UUI_IO_BROKENPACKAGE
;
1208 else if ( xAbort
.is() )
1210 nErrorCode
= ERRCODE_UUI_IO_BROKENPACKAGE_CANTREPAIR
;
1217 std::locale aResLocale
= Translate::Create("uui");
1218 ErrorResource
aErrorResource(RID_UUI_ERRHDL
, aResLocale
);
1219 if (!aErrorResource
.getString(nErrorCode
, aMessage
))
1223 aMessage
= replaceMessageWithArguments( aMessage
, rArguments
);
1225 if (bObtainErrorStringOnly
)
1227 rErrorString
= aMessage
;
1231 VclMessageType eMessageType
;
1232 if( xApprove
.is() && xDisapprove
.is() )
1233 eMessageType
= VclMessageType::Question
;
1234 else if ( xAbort
.is() )
1235 eMessageType
= VclMessageType::Warning
;
1240 utl::ConfigManager::getProductName() +
1242 utl::ConfigManager::getProductVersion() );
1244 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1245 switch (executeMessageBox(Application::GetFrameWeld(xParent
), title
, aMessage
, eMessageType
))
1247 case DialogMask::ButtonsOk
:
1248 OSL_ENSURE( xAbort
.is(), "unexpected situation" );
1253 case DialogMask::ButtonsNo
:
1254 OSL_ENSURE(xDisapprove
.is(), "unexpected situation");
1255 if (xDisapprove
.is())
1256 xDisapprove
->select();
1259 case DialogMask::ButtonsYes
:
1260 OSL_ENSURE(xApprove
.is(), "unexpected situation");
1269 // ErrorResource Implementation
1270 bool ErrorResource::getString(ErrCode nErrorCode
, OUString
&rString
) const
1272 for (const std::pair
<const char*, ErrCode
>* pStringArray
= m_pStringArray
; pStringArray
->first
!= nullptr; ++pStringArray
)
1274 if (nErrorCode
.StripWarningAndDynamic() == pStringArray
->second
.StripWarningAndDynamic())
1276 rString
= Translate::get(pStringArray
->first
, m_rResLocale
);
1283 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */