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 <sal/log.hxx>
65 #include <osl/conditn.hxx>
66 #include <unotools/resmgr.hxx>
67 #include <vcl/errinf.hxx>
68 #include <vcl/svapp.hxx>
69 #include <vcl/weld.hxx>
70 #include <osl/thread.hxx>
71 #include <tools/diagnose_ex.h>
72 #include <comphelper/documentconstants.hxx>
73 #include <comphelper/propertysequence.hxx>
74 #include <svtools/sfxecode.hxx>
75 #include <unotools/configmgr.hxx>
76 #include <comphelper/namedvaluecollection.hxx>
77 #include <typelib/typedescription.hxx>
78 #include <unotools/confignode.hxx>
82 #include <strings.hrc>
84 #include "getcontinuations.hxx"
85 #include "secmacrowarnings.hxx"
88 #include "nameclashdlg.hxx"
90 using ::com::sun::star::uno::Sequence
;
91 using ::com::sun::star::uno::UNO_QUERY
;
92 using ::com::sun::star::uno::Reference
;
93 using ::com::sun::star::task::XInteractionContinuation
;
94 using ::com::sun::star::task::XInteractionAbort
;
95 using ::com::sun::star::task::XInteractionApprove
;
96 using ::com::sun::star::uno::XInterface
;
97 using ::com::sun::star::lang::XInitialization
;
98 using ::com::sun::star::uno::UNO_QUERY_THROW
;
99 using ::com::sun::star::task::InteractionHandler
;
100 using ::com::sun::star::task::XInteractionHandler2
;
101 using ::com::sun::star::uno::Exception
;
102 using ::com::sun::star::uno::Any
;
103 using ::com::sun::star::task::XInteractionRequest
;
104 using ::com::sun::star::lang::XMultiServiceFactory
;
106 using namespace ::com::sun::star
;
110 class HandleData
: public osl::Condition
114 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
116 m_rRequest(rRequest
),
120 uno::Reference
< task::XInteractionRequest
> m_rRequest
;
122 beans::Optional
< OUString
> m_aResult
;
127 UUIInteractionHelper::UUIInteractionHelper(
128 uno::Reference
< uno::XComponentContext
> const & rxContext
,
129 uno::Reference
< awt::XWindow
> const & rxWindowParam
,
130 const OUString
& rContextParam
)
131 : m_xContext(rxContext
),
132 m_xWindowParam(rxWindowParam
),
133 m_aContextParam(rContextParam
)
137 UUIInteractionHelper::UUIInteractionHelper(
138 uno::Reference
< uno::XComponentContext
> const & rxContext
)
139 : m_xContext(rxContext
)
143 UUIInteractionHelper::~UUIInteractionHelper()
147 void UUIInteractionHelper::handlerequest(
148 void* pHandleData
, void* pInteractionHelper
)
151 = static_cast< HandleData
* >(pHandleData
);
152 UUIInteractionHelper
* pUUI
153 = static_cast< UUIInteractionHelper
* >(pInteractionHelper
);
157 = pUUI
->handleRequest_impl(pHND
->m_rRequest
, false, bDummy
, aDummy
);
162 UUIInteractionHelper::handleRequest(
163 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
165 if(!Application::IsMainThread() && GetpApp())
167 // we are not in the main thread, let it handle that stuff
168 HandleData
aHD(rRequest
);
169 Link
<void*,void> aLink(&aHD
,handlerequest
);
170 Application::PostUserEvent(aLink
,this);
171 comphelper::SolarMutex
& rSolarMutex
= Application::GetSolarMutex();
172 sal_uInt32 nLockCount
= (rSolarMutex
.IsCurrentThread()) ? rSolarMutex
.release(true) : 0;
175 rSolarMutex
.acquire(nLockCount
);
182 return handleRequest_impl(rRequest
, false, bDummy
, aDummy
);
186 void UUIInteractionHelper::getstringfromrequest(
187 void* pHandleData
,void* pInteractionHelper
)
189 HandleData
* pHND
= static_cast<HandleData
*>(pHandleData
);
190 UUIInteractionHelper
* pUUI
= static_cast<UUIInteractionHelper
*>(pInteractionHelper
);
191 pHND
->m_aResult
= pUUI
->getStringFromRequest_impl(pHND
->m_rRequest
);
195 beans::Optional
< OUString
>
196 UUIInteractionHelper::getStringFromRequest_impl(
197 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
199 bool bSuccess
= false;
201 handleRequest_impl(rRequest
, true, bSuccess
, aMessage
);
203 OSL_ENSURE(bSuccess
||
204 !isInformationalErrorMessageRequest(
205 rRequest
->getContinuations()),
206 "Interaction request is a candidate for a string representation."
207 "Please implement!");
209 return beans::Optional
< OUString
>(bSuccess
, aMessage
);
212 beans::Optional
< OUString
>
213 UUIInteractionHelper::getStringFromRequest(
214 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
216 if(!Application::IsMainThread() && GetpApp())
218 // we are not in the main thread, let it handle that stuff
219 HandleData
aHD(rRequest
);
220 Link
<void*,void> aLink(&aHD
,getstringfromrequest
);
221 Application::PostUserEvent(aLink
,this);
222 comphelper::SolarMutex
& rSolarMutex
= Application::GetSolarMutex();
223 sal_uInt32 nLockCount
= (rSolarMutex
.IsCurrentThread()) ? rSolarMutex
.release(true) : 0;
226 rSolarMutex
.acquire(nLockCount
);
227 return aHD
.m_aResult
;
230 return getStringFromRequest_impl(rRequest
);
234 UUIInteractionHelper::replaceMessageWithArguments(
235 const OUString
& _aMessage
,
236 std::vector
< OUString
> const & rArguments
)
238 OUString aMessage
= _aMessage
;
240 SAL_WARN_IF(rArguments
.empty(), "uui", "replaceMessageWithArguments: No arguments passed!");
241 for (size_t i
= 0; i
< rArguments
.size(); ++i
)
243 const OUString sReplaceTemplate
= "$(ARG" + OUString::number(i
+1) + ")";
244 aMessage
= aMessage
.replaceAll(sReplaceTemplate
, rArguments
[i
]);
251 UUIInteractionHelper::isInformationalErrorMessageRequest(
252 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
255 // Only requests with a single continuation (user has no choice, request
256 // is just informational)
257 if (rContinuations
.getLength() != 1 )
260 // user can only abort or approve, all other continuations are not
261 // considered to be informational.
262 uno::Reference
< task::XInteractionApprove
> xApprove(
263 rContinuations
[0], uno::UNO_QUERY
);
267 uno::Reference
< task::XInteractionAbort
> xAbort(
268 rContinuations
[0], uno::UNO_QUERY
);
273 UUIInteractionHelper::tryOtherInteractionHandler(
274 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
276 InteractionHandlerDataList dataList
;
277 getInteractionHandlerList(dataList
);
279 return std::any_of(dataList
.cbegin(), dataList
.cend(),
280 [&](const InteractionHandlerData
& rData
) { return handleCustomRequest( rRequest
, rData
.ServiceName
); });
286 bool lcl_matchesRequest( const Any
& i_rRequest
, const OUString
& i_rTypeName
, const OUString
& i_rPropagation
)
288 const css::uno::TypeDescription
aTypeDesc( i_rTypeName
);
289 const typelib_TypeDescription
* pTypeDesc
= aTypeDesc
.get();
290 if ( !pTypeDesc
|| !pTypeDesc
->pWeakRef
)
292 SAL_WARN( "uui","no type found for '" << i_rTypeName
<< "'" );
295 const css::uno::Type
aType( pTypeDesc
->pWeakRef
);
297 const bool bExactMatch
= i_rPropagation
== "named-only";
299 return i_rRequest
.getValueType().equals( aType
);
301 return i_rRequest
.isExtractableTo( aType
);
306 bool UUIInteractionHelper::handleCustomRequest( const Reference
< XInteractionRequest
>& i_rRequest
, const OUString
& i_rServiceName
) const
310 Reference
< XInteractionHandler2
> xHandler( m_xContext
->getServiceManager()->createInstanceWithContext( i_rServiceName
, m_xContext
), UNO_QUERY_THROW
);
312 Reference
< XInitialization
> xHandlerInit( xHandler
, UNO_QUERY
);
313 if ( xHandlerInit
.is() )
315 ::comphelper::NamedValueCollection aInitArgs
;
316 aInitArgs
.put( "Parent", getParentXWindow() );
317 xHandlerInit
->initialize( aInitArgs
.getWrappedPropertyValues() );
320 if ( xHandler
->handleInteractionRequest( i_rRequest
) )
323 catch( const Exception
& )
325 DBG_UNHANDLED_EXCEPTION("uui");
331 bool UUIInteractionHelper::handleTypedHandlerImplementations( Reference
< XInteractionRequest
> const & rRequest
)
334 const Any
aRequest( rRequest
->getRequest() );
336 const StringHashMap::const_iterator aCacheHitTest
= m_aTypedCustomHandlers
.find( aRequest
.getValueTypeName() );
337 if ( aCacheHitTest
!= m_aTypedCustomHandlers
.end() )
338 return handleCustomRequest( rRequest
, aCacheHitTest
->second
);
340 // the base registration node for "typed" interaction handlers
341 const ::utl::OConfigurationTreeRoot
aConfigRoot( ::utl::OConfigurationTreeRoot::createWithComponentContext(
343 "/org.openoffice.Interaction/InteractionHandlers",
345 ::utl::OConfigurationTreeRoot::CM_READONLY
348 // loop through all registered implementations
349 const Sequence
< OUString
> aRegisteredHandlers( aConfigRoot
.getNodeNames() );
350 for ( auto const & handlerName
: aRegisteredHandlers
)
352 const ::utl::OConfigurationNode
aHandlerNode( aConfigRoot
.openNode( handlerName
) );
353 const ::utl::OConfigurationNode
aTypesNode( aHandlerNode
.openNode( "HandledRequestTypes" ) );
355 // loop through all the types which the current handler is registered for
356 const Sequence
< OUString
> aHandledTypes( aTypesNode
.getNodeNames() );
357 for ( auto const & type
: aHandledTypes
)
359 // the UNO type is the node name
360 ::utl::OConfigurationNode
aType( aTypesNode
.openNode( type
) );
361 // and there's a child denoting how the responsibility propagates
362 OUString sPropagation
;
363 OSL_VERIFY( aType
.getNodeValue( "Propagation" ) >>= sPropagation
);
364 if ( lcl_matchesRequest( aRequest
, type
, sPropagation
) )
366 // retrieve the service/implementation name of the handler
367 OUString sServiceName
;
368 OSL_VERIFY( aHandlerNode
.getNodeValue( "ServiceName" ) >>= sServiceName
);
369 // cache the information who feels responsible for requests of this type
370 m_aTypedCustomHandlers
[ aRequest
.getValueTypeName() ] = sServiceName
;
371 // actually handle the request
372 return handleCustomRequest( rRequest
, sServiceName
);
381 UUIInteractionHelper::handleRequest_impl(
382 uno::Reference
< task::XInteractionRequest
> const & rRequest
,
383 bool bObtainErrorStringOnly
,
384 bool & bHasErrorString
,
385 OUString
& rErrorString
)
392 uno::Any
aAnyRequest(rRequest
->getRequest());
394 script::ModuleSizeExceededRequest aModSizeException
;
395 if (aAnyRequest
>>= aModSizeException
)
397 std::vector
< OUString
> aArguments
;
398 uno::Sequence
< OUString
> sModules
399 = aModSizeException
.Names
;
400 if ( sModules
.hasElements() )
402 OUStringBuffer aName
;
403 for ( sal_Int32 index
=0; index
< sModules
.getLength(); ++index
)
407 aName
.append(sModules
[index
]);
409 aArguments
.push_back( aName
.makeStringAndClear() );
411 handleErrorHandlerRequest( task::InteractionClassification_WARNING
,
412 ERRCODE_UUI_IO_MODULESIZEEXCEEDED
,
414 rRequest
->getContinuations(),
415 bObtainErrorStringOnly
,
421 document::ExoticFileLoadException aExoticFileLoadException
;
422 if (aAnyRequest
>>= aExoticFileLoadException
)
424 std::vector
< OUString
> aArguments
;
426 if( !aExoticFileLoadException
.URL
.isEmpty() )
428 aArguments
.push_back( aExoticFileLoadException
.URL
);
430 if( !aExoticFileLoadException
.FilterUIName
.isEmpty() )
432 aArguments
.push_back( aExoticFileLoadException
.FilterUIName
);
435 handleErrorHandlerRequest( task::InteractionClassification_WARNING
,
436 ERRCODE_UUI_IO_EXOTICFILEFORMAT
,
438 rRequest
->getContinuations(),
439 bObtainErrorStringOnly
,
445 ucb::NameClashException aNCException
;
446 if (aAnyRequest
>>= aNCException
)
448 ErrCode nErrorCode
= ERRCODE_UUI_IO_TARGETALREADYEXISTS
;
449 std::vector
< OUString
> aArguments
;
451 if( !aNCException
.Name
.isEmpty() )
453 nErrorCode
= ERRCODE_UUI_IO_ALREADYEXISTS
;
454 aArguments
.push_back( aNCException
.Name
);
457 handleErrorHandlerRequest( aNCException
.Classification
,
460 rRequest
->getContinuations(),
461 bObtainErrorStringOnly
,
467 ucb::UnsupportedNameClashException aUORequest
;
468 if (aAnyRequest
>>= aUORequest
)
470 std::vector
< OUString
> aArguments
;
472 uno::Reference
< task::XInteractionApprove
> xApprove
;
473 uno::Reference
< task::XInteractionDisapprove
> xDisapprove
;
475 rRequest
->getContinuations(), &xApprove
, &xDisapprove
);
477 if ( xApprove
.is() && xDisapprove
.is() )
479 handleErrorHandlerRequest( task::InteractionClassification_QUERY
,
480 ERRCODE_UUI_IO_UNSUPPORTEDOVERWRITE
,
482 rRequest
->getContinuations(),
483 bObtainErrorStringOnly
,
490 if ( handleInteractiveIOException( rRequest
,
491 bObtainErrorStringOnly
,
496 ucb::InteractiveAppException aAppException
;
497 if (aAnyRequest
>>= aAppException
)
499 std::vector
< OUString
> aArguments
;
500 handleErrorHandlerRequest( aAppException
.Classification
,
501 ErrCode(aAppException
.Code
),
503 rRequest
->getContinuations(),
504 bObtainErrorStringOnly
,
510 ucb::InteractiveNetworkException aNetworkException
;
511 if (aAnyRequest
>>= aNetworkException
)
514 std::vector
< OUString
> aArguments
;
515 ucb::InteractiveNetworkOffLineException aOffLineException
;
516 ucb::InteractiveNetworkResolveNameException aResolveNameException
;
517 ucb::InteractiveNetworkConnectException aConnectException
;
518 ucb::InteractiveNetworkReadException aReadException
;
519 ucb::InteractiveNetworkWriteException aWriteException
;
520 if (aAnyRequest
>>= aOffLineException
)
521 nErrorCode
= ERRCODE_INET_OFFLINE
;
522 else if (aAnyRequest
>>= aResolveNameException
)
524 nErrorCode
= ERRCODE_INET_NAME_RESOLVE
;
525 aArguments
.push_back(aResolveNameException
.Server
);
527 else if (aAnyRequest
>>= aConnectException
)
529 nErrorCode
= ERRCODE_INET_CONNECT
;
530 aArguments
.push_back(aConnectException
.Server
);
532 else if (aAnyRequest
>>= aReadException
)
534 nErrorCode
= ERRCODE_INET_READ
;
535 aArguments
.push_back(aReadException
.Diagnostic
);
537 else if (aAnyRequest
>>= aWriteException
)
539 nErrorCode
= ERRCODE_INET_WRITE
;
540 aArguments
.push_back(aWriteException
.Diagnostic
);
543 nErrorCode
= ERRCODE_INET_GENERAL
;
545 handleErrorHandlerRequest(aNetworkException
.Classification
,
548 rRequest
->getContinuations(),
549 bObtainErrorStringOnly
,
555 ucb::InteractiveWrongMediumException aWrongMediumException
;
556 if (aAnyRequest
>>= aWrongMediumException
)
558 sal_Int32 nMedium
= 0;
559 aWrongMediumException
.Medium
>>= nMedium
;
560 std::vector
< OUString
> aArguments
;
561 aArguments
.push_back(OUString::number(nMedium
+ 1));
562 handleErrorHandlerRequest(aWrongMediumException
.Classification
,
563 ERRCODE_UUI_WRONGMEDIUM
,
565 rRequest
->getContinuations(),
566 bObtainErrorStringOnly
,
572 java::WrongJavaVersionException aWrongJavaVersionException
;
573 if (aAnyRequest
>>= aWrongJavaVersionException
)
576 std::vector
< OUString
> aArguments
;
577 if (aWrongJavaVersionException
.DetectedVersion
.isEmpty())
578 if (aWrongJavaVersionException
.LowestSupportedVersion
.isEmpty())
579 nErrorCode
= ERRCODE_UUI_WRONGJAVA
;
582 nErrorCode
= ERRCODE_UUI_WRONGJAVA_MIN
;
583 aArguments
.push_back(aWrongJavaVersionException
.LowestSupportedVersion
);
585 else if (aWrongJavaVersionException
.LowestSupportedVersion
.isEmpty())
587 nErrorCode
= ERRCODE_UUI_WRONGJAVA_VERSION
;
588 aArguments
.push_back(aWrongJavaVersionException
.DetectedVersion
);
592 nErrorCode
= ERRCODE_UUI_WRONGJAVA_VERSION_MIN
;
593 aArguments
.reserve(2);
594 aArguments
.push_back(aWrongJavaVersionException
.DetectedVersion
);
595 aArguments
.push_back(aWrongJavaVersionException
.LowestSupportedVersion
);
597 handleErrorHandlerRequest(task::InteractionClassification_ERROR
,
600 rRequest
->getContinuations(),
601 bObtainErrorStringOnly
,
607 configuration::backend::MergeRecoveryRequest aMergeRecoveryRequest
;
608 if (aAnyRequest
>>= aMergeRecoveryRequest
)
610 ErrCode nErrorCode
= aMergeRecoveryRequest
.IsRemovalRequest
611 ? ERRCODE_UUI_CONFIGURATION_BROKENDATA_WITHREMOVE
612 : ERRCODE_UUI_CONFIGURATION_BROKENDATA_NOREMOVE
;
614 std::vector
< OUString
> aArguments
;
615 aArguments
.push_back(aMergeRecoveryRequest
.ErrorLayerId
);
617 handleErrorHandlerRequest(task::InteractionClassification_ERROR
,
620 rRequest
->getContinuations(),
621 bObtainErrorStringOnly
,
627 configuration::backend::StratumCreationException
628 aStratumCreationException
;
630 if (aAnyRequest
>>= aStratumCreationException
)
632 const ErrCode nErrorCode
= ERRCODE_UUI_CONFIGURATION_BACKENDMISSING
;
634 OUString aStratum
= aStratumCreationException
.StratumData
;
635 if (aStratum
.isEmpty())
636 aStratum
= aStratumCreationException
.StratumService
;
638 std::vector
< OUString
> aArguments
;
639 aArguments
.push_back(aStratum
);
641 handleErrorHandlerRequest(task::InteractionClassification_ERROR
,
644 rRequest
->getContinuations(),
645 bObtainErrorStringOnly
,
651 xforms::InvalidDataOnSubmitException aInvalidDataOnSubmitException
;
652 if (aAnyRequest
>>= aInvalidDataOnSubmitException
)
654 const ErrCode nErrorCode
=
655 ERRCODE_UUI_INVALID_XFORMS_SUBMISSION_DATA
;
657 std::vector
< OUString
> aArguments
;
659 handleErrorHandlerRequest(task::InteractionClassification_QUERY
,
662 rRequest
->getContinuations(),
663 bObtainErrorStringOnly
,
669 ucb::InteractiveLockingLockedException aLLException
;
670 if (aAnyRequest
>>= aLLException
)
672 ErrCode nErrorCode
= aLLException
.SelfOwned
673 ? ERRCODE_UUI_LOCKING_LOCKED_SELF
: ERRCODE_UUI_LOCKING_LOCKED
;
674 std::vector
< OUString
> aArguments
;
675 aArguments
.push_back( aLLException
.Url
);
677 handleErrorHandlerRequest( aLLException
.Classification
,
680 rRequest
->getContinuations(),
681 bObtainErrorStringOnly
,
687 ucb::InteractiveLockingNotLockedException aLNLException
;
688 if (aAnyRequest
>>= aLNLException
)
690 std::vector
< OUString
> aArguments
;
691 aArguments
.push_back( aLNLException
.Url
);
693 handleErrorHandlerRequest( aLNLException
.Classification
,
694 ERRCODE_UUI_LOCKING_NOT_LOCKED
,
696 rRequest
->getContinuations(),
697 bObtainErrorStringOnly
,
703 ucb::InteractiveLockingLockExpiredException aLLEException
;
704 if (aAnyRequest
>>= aLLEException
)
706 std::vector
< OUString
> aArguments
;
707 aArguments
.push_back( aLLEException
.Url
);
709 handleErrorHandlerRequest( aLLEException
.Classification
,
710 ERRCODE_UUI_LOCKING_LOCK_EXPIRED
,
712 rRequest
->getContinuations(),
713 bObtainErrorStringOnly
,
719 document::BrokenPackageRequest aBrokenPackageRequest
;
720 if (aAnyRequest
>>= aBrokenPackageRequest
)
722 std::vector
< OUString
> aArguments
;
724 if( !aBrokenPackageRequest
.aName
.isEmpty() )
725 aArguments
.push_back( aBrokenPackageRequest
.aName
);
727 handleBrokenPackageRequest( aArguments
,
728 rRequest
->getContinuations(),
729 bObtainErrorStringOnly
,
735 task::ErrorCodeRequest aErrorCodeRequest
;
736 if (aAnyRequest
>>= aErrorCodeRequest
)
738 handleGenericErrorRequest( ErrCode(aErrorCodeRequest
.ErrCode
),
739 rRequest
->getContinuations(),
740 bObtainErrorStringOnly
,
746 task::ErrorCodeIOException aErrorCodeIOException
;
747 if (aAnyRequest
>>= aErrorCodeIOException
)
749 handleGenericErrorRequest( ErrCode(aErrorCodeIOException
.ErrCode
),
750 rRequest
->getContinuations(),
751 bObtainErrorStringOnly
,
757 loader::CannotActivateFactoryException aCannotActivateFactoryException
;
758 if (aAnyRequest
>>= aCannotActivateFactoryException
)
760 std::vector
< OUString
> aArguments
;
761 aArguments
.push_back( aCannotActivateFactoryException
.Message
);
763 handleErrorHandlerRequest( task::InteractionClassification_ERROR
,
764 ERRCODE_UUI_CANNOT_ACTIVATE_FACTORY
,
766 rRequest
->getContinuations(),
767 bObtainErrorStringOnly
,
774 // Handle requests which do not have a plain string representation.
776 if (!bObtainErrorStringOnly
)
778 ucb::AuthenticationFallbackRequest anAuthFallbackRequest
;
779 if ( aAnyRequest
>>= anAuthFallbackRequest
)
781 handleAuthFallbackRequest( anAuthFallbackRequest
.instructions
,
782 anAuthFallbackRequest
.url
, rRequest
->getContinuations() );
786 if ( handleAuthenticationRequest( rRequest
) )
789 if ( handleCertificateValidationRequest( rRequest
) )
792 ucb::NameClashResolveRequest aNameClashResolveRequest
;
793 if (aAnyRequest
>>= aNameClashResolveRequest
)
795 handleNameClashResolveRequest(aNameClashResolveRequest
,
796 rRequest
->getContinuations());
800 if ( handleMasterPasswordRequest( rRequest
) )
803 if ( handlePasswordRequest( rRequest
) )
806 if ( handleNoSuchFilterRequest( rRequest
) )
809 if ( handleFilterOptionsRequest( rRequest
) )
812 if ( handleLockedDocumentRequest( rRequest
) )
815 if ( handleChangedByOthersRequest( rRequest
) )
818 if ( handleLockFileProblemRequest( rRequest
) )
821 task::DocumentMacroConfirmationRequest aMacroConfirmRequest
;
822 if (aAnyRequest
>>= aMacroConfirmRequest
)
824 handleMacroConfirmRequest(
825 aMacroConfirmRequest
.DocumentURL
,
826 aMacroConfirmRequest
.DocumentStorage
,
827 !aMacroConfirmRequest
.DocumentVersion
.isEmpty() ? aMacroConfirmRequest
.DocumentVersion
: ODFVER_012_TEXT
,
828 aMacroConfirmRequest
.DocumentSignatureInformation
,
829 rRequest
->getContinuations());
833 // Last chance: interaction handlers registered in the configuration
836 // typed InteractionHandlers (ooo.Interactions)
837 if ( handleTypedHandlerImplementations( rRequest
) )
840 // legacy configuration (ooo.ucb.InteractionHandlers)
841 if (tryOtherInteractionHandler( rRequest
))
848 catch( const uno::RuntimeException
& )
850 throw; // allowed to leave here
852 catch( const uno::Exception
& )
854 DBG_UNHANDLED_EXCEPTION("uui");
860 UUIInteractionHelper::getInteractionHandlerList(
861 InteractionHandlerDataList
&rdataList
)
865 uno::Reference
< lang::XMultiServiceFactory
> xConfigProv
=
866 configuration::theDefaultProvider::get( m_xContext
);
868 OUStringBuffer aFullPath
;
870 "/org.openoffice.ucb.InteractionHandler/InteractionHandlers" );
872 uno::Sequence
<uno::Any
> aArguments(comphelper::InitAnyPropertySequence(
874 {"nodepath", uno::Any(aFullPath
.makeStringAndClear())}
877 uno::Reference
< uno::XInterface
> xInterface(
878 xConfigProv
->createInstanceWithArguments(
879 "com.sun.star.configuration.ConfigurationAccess" , aArguments
) );
881 if ( !xInterface
.is() )
882 throw uno::RuntimeException("unable to instantiate config access");
884 uno::Reference
< container::XNameAccess
> xNameAccess(
885 xInterface
, uno::UNO_QUERY_THROW
);
886 const uno::Sequence
< OUString
> aElems
= xNameAccess
->getElementNames();
888 if ( aElems
.hasElements() )
890 uno::Reference
< container::XHierarchicalNameAccess
>
891 xHierNameAccess( xInterface
, uno::UNO_QUERY_THROW
);
893 // Iterate over children.
894 for ( const auto& rElem
: aElems
)
896 OUStringBuffer aElemBuffer
;
897 aElemBuffer
.append( "['" );
898 aElemBuffer
.append( rElem
);
902 InteractionHandlerData aInfo
;
904 // Obtain service name.
905 OUStringBuffer aKeyBuffer
= aElemBuffer
;
906 aKeyBuffer
.append( "']/ServiceName" );
909 if ( !( xHierNameAccess
->getByHierarchicalName(
910 aKeyBuffer
.makeStringAndClear() ) >>= aValue
) )
912 OSL_FAIL( "GetInteractionHandlerList - "
913 "Error getting item value!" );
917 aInfo
.ServiceName
= aValue
;
919 // Append info to list.
920 rdataList
.push_back( aInfo
);
922 catch ( container::NoSuchElementException
& )
924 // getByHierarchicalName
926 OSL_FAIL( "GetInteractionHandlerList - "
927 "caught NoSuchElementException!" );
932 catch ( uno::RuntimeException
const & )
936 catch ( uno::Exception
const & )
938 OSL_FAIL( "GetInteractionHandlerList - Caught Exception!" );
942 const uno::Reference
< awt::XWindow
>&
943 UUIInteractionHelper::getParentXWindow() const
945 return m_xWindowParam
;
948 uno::Reference
< task::XInteractionHandler2
>
949 UUIInteractionHelper::getInteractionHandler()
951 return InteractionHandler::createWithParentAndContext(
952 m_xContext
, m_xWindowParam
,
960 weld::Window
* pParent
,
961 OUString
const & rTitle
,
962 OUString
const & rMessage
,
963 VclMessageType eMessageType
)
965 SolarMutexGuard aGuard
;
967 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(pParent
, eMessageType
,
968 eMessageType
== VclMessageType::Question
? VclButtonsType::YesNo
: VclButtonsType::Ok
, rMessage
));
969 xBox
->set_title(rTitle
);
971 short nMessResult
= xBox
->run();
972 DialogMask aResult
= DialogMask::NONE
;
976 aResult
= DialogMask::ButtonsOk
;
979 aResult
= DialogMask::ButtonsCancel
;
982 aResult
= DialogMask::ButtonsYes
;
985 aResult
= DialogMask::ButtonsNo
;
994 NameClashResolveDialogResult
executeSimpleNameClashResolveDialog(weld::Window
*pParent
,
995 OUString
const & rTargetFolderURL
,
996 OUString
const & rClashingName
,
997 OUString
& rProposedNewName
,
998 bool bAllowOverwrite
)
1000 std::locale aResLocale
= Translate::Create("uui");
1001 NameClashDialog
aDialog(pParent
, aResLocale
, rTargetFolderURL
,
1002 rClashingName
, rProposedNewName
, bAllowOverwrite
);
1004 NameClashResolveDialogResult eResult
= static_cast<NameClashResolveDialogResult
>(aDialog
.run());
1005 rProposedNewName
= aDialog
.getNewName();
1012 UUIInteractionHelper::handleNameClashResolveRequest(
1013 ucb::NameClashResolveRequest
const & rRequest
,
1014 uno::Sequence
< uno::Reference
<
1015 task::XInteractionContinuation
> > const & rContinuations
)
1017 OSL_ENSURE(!rRequest
.TargetFolderURL
.isEmpty(),
1018 "NameClashResolveRequest must not contain empty TargetFolderURL" );
1020 OSL_ENSURE(!rRequest
.ClashingName
.isEmpty(),
1021 "NameClashResolveRequest must not contain empty ClashingName" );
1023 uno::Reference
< task::XInteractionAbort
> xAbort
;
1024 uno::Reference
< ucb::XInteractionSupplyName
> xSupplyName
;
1025 uno::Reference
< ucb::XInteractionReplaceExistingData
> xReplaceExistingData
;
1027 rContinuations
, &xAbort
, &xSupplyName
, &xReplaceExistingData
);
1029 OSL_ENSURE( xAbort
.is(),
1030 "NameClashResolveRequest must contain Abort continuation" );
1032 OSL_ENSURE( xSupplyName
.is(),
1033 "NameClashResolveRequest must contain SupplyName continuation" );
1035 NameClashResolveDialogResult eResult
= ABORT
;
1036 OUString
aProposedNewName( rRequest
.ProposedNewName
);
1038 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1039 eResult
= executeSimpleNameClashResolveDialog(Application::GetFrameWeld(xParent
),
1040 rRequest
.TargetFolderURL
,
1041 rRequest
.ClashingName
,
1043 xReplaceExistingData
.is());
1052 xSupplyName
->setName( aProposedNewName
);
1053 xSupplyName
->select();
1058 xReplaceExistingData
.is(),
1059 "Invalid NameClashResolveDialogResult: OVERWRITE - "
1060 "No ReplaceExistingData continuation available!" );
1061 xReplaceExistingData
->select();
1067 UUIInteractionHelper::handleGenericErrorRequest(
1069 uno::Sequence
< uno::Reference
<
1070 task::XInteractionContinuation
> > const & rContinuations
,
1071 bool bObtainErrorStringOnly
,
1072 bool & bHasErrorString
,
1073 OUString
& rErrorString
)
1075 if (bObtainErrorStringOnly
)
1077 bHasErrorString
= isInformationalErrorMessageRequest(rContinuations
);
1078 if (bHasErrorString
)
1080 OUString aErrorString
;
1081 ErrorHandler::GetErrorString(nErrorCode
, aErrorString
);
1082 rErrorString
= aErrorString
;
1087 uno::Reference
< task::XInteractionAbort
> xAbort
;
1088 uno::Reference
< task::XInteractionApprove
> xApprove
;
1089 getContinuations(rContinuations
, &xApprove
, &xAbort
);
1091 // Note: It's important to convert the transported long to the
1092 // required unsigned long value. Otherwise using as flag field
1094 ErrCode
nError(nErrorCode
);
1095 bool bWarning
= !nError
.IgnoreWarning();
1097 if ( nError
== ERRCODE_SFX_INCOMPLETE_ENCRYPTION
)
1099 // the security warning box needs a special title
1100 OUString aErrorString
;
1101 ErrorHandler::GetErrorString( nErrorCode
, aErrorString
);
1103 std::locale aResLocale
= Translate::Create("uui");
1104 OUString
aTitle( utl::ConfigManager::getProductName() );
1106 OUString aErrTitle
= Translate::get(STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE
, aResLocale
);
1108 if ( !aTitle
.isEmpty() && !aErrTitle
.isEmpty() )
1110 aTitle
+= aErrTitle
;
1112 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1113 executeMessageBox(Application::GetFrameWeld(xParent
), aTitle
, aErrorString
, VclMessageType::Error
);
1117 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1118 ErrorHandler::HandleError(nErrorCode
, Application::GetFrameWeld(xParent
));
1121 if (xApprove
.is() && bWarning
)
1123 else if (xAbort
.is())
1129 UUIInteractionHelper::handleMacroConfirmRequest(
1130 const OUString
& aDocumentURL
,
1131 const uno::Reference
< embed::XStorage
>& xZipStorage
,
1132 const OUString
& aDocumentVersion
,
1133 const uno::Sequence
< security::DocumentSignatureInformation
>& aSignInfo
,
1134 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
1137 uno::Reference
< task::XInteractionAbort
> xAbort
;
1138 uno::Reference
< task::XInteractionApprove
> xApprove
;
1139 getContinuations( rContinuations
, &xApprove
, &xAbort
);
1141 bool bApprove
= false;
1143 bool bShowSignatures
= aSignInfo
.hasElements();
1144 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1145 MacroWarning
aWarning(Application::GetFrameWeld(xParent
), bShowSignatures
);
1147 aWarning
.SetDocumentURL(aDocumentURL
);
1148 if ( aSignInfo
.getLength() > 1 )
1150 aWarning
.SetStorage(xZipStorage
, aDocumentVersion
, aSignInfo
);
1152 else if ( aSignInfo
.getLength() == 1 )
1154 aWarning
.SetCertificate(aSignInfo
[0].Signer
);
1157 bApprove
= aWarning
.run() == RET_OK
;
1159 if ( bApprove
&& xApprove
.is() )
1161 else if ( xAbort
.is() )
1166 UUIInteractionHelper::handleBrokenPackageRequest(
1167 std::vector
< OUString
> const & rArguments
,
1168 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
1170 bool bObtainErrorStringOnly
,
1171 bool & bHasErrorString
,
1172 OUString
& rErrorString
)
1174 if (bObtainErrorStringOnly
)
1176 bHasErrorString
= isInformationalErrorMessageRequest(rContinuations
);
1177 if (!bHasErrorString
)
1181 uno::Reference
< task::XInteractionApprove
> xApprove
;
1182 uno::Reference
< task::XInteractionDisapprove
> xDisapprove
;
1183 uno::Reference
< task::XInteractionAbort
> xAbort
;
1184 getContinuations(rContinuations
, &xApprove
, &xDisapprove
, &xAbort
);
1187 if( xApprove
.is() && xDisapprove
.is() )
1189 nErrorCode
= ERRCODE_UUI_IO_BROKENPACKAGE
;
1191 else if ( xAbort
.is() )
1193 nErrorCode
= ERRCODE_UUI_IO_BROKENPACKAGE_CANTREPAIR
;
1200 std::locale aResLocale
= Translate::Create("uui");
1201 ErrorResource
aErrorResource(RID_UUI_ERRHDL
, aResLocale
);
1202 if (!aErrorResource
.getString(nErrorCode
, aMessage
))
1206 aMessage
= replaceMessageWithArguments( aMessage
, rArguments
);
1208 if (bObtainErrorStringOnly
)
1210 rErrorString
= aMessage
;
1214 VclMessageType eMessageType
;
1215 if( xApprove
.is() && xDisapprove
.is() )
1216 eMessageType
= VclMessageType::Question
;
1217 else if ( xAbort
.is() )
1218 eMessageType
= VclMessageType::Warning
;
1223 utl::ConfigManager::getProductName() +
1225 utl::ConfigManager::getProductVersion() );
1227 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
1228 switch (executeMessageBox(Application::GetFrameWeld(xParent
), title
, aMessage
, eMessageType
))
1230 case DialogMask::ButtonsOk
:
1231 OSL_ENSURE( xAbort
.is(), "unexpected situation" );
1236 case DialogMask::ButtonsNo
:
1237 OSL_ENSURE(xDisapprove
.is(), "unexpected situation");
1238 if (xDisapprove
.is())
1239 xDisapprove
->select();
1242 case DialogMask::ButtonsYes
:
1243 OSL_ENSURE(xApprove
.is(), "unexpected situation");
1252 // ErrorResource Implementation
1253 bool ErrorResource::getString(ErrCode nErrorCode
, OUString
&rString
) const
1255 for (const std::pair
<const char*, ErrCode
>* pStringArray
= m_pStringArray
; pStringArray
->first
!= nullptr; ++pStringArray
)
1257 if (nErrorCode
.StripWarningAndDynamic() == pStringArray
->second
.StripWarningAndDynamic())
1259 rString
= Translate::get(pStringArray
->first
, m_rResLocale
);
1266 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */