Revert "Related tdf#158739: blacklist Nvidia RTX 4050 for Skia hardware"
[LibreOffice.git] / uui / source / iahndl.cxx
blob2a029de54296e6766d453c9e9b4c0585270d89f8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <memory>
22 #include <com/sun/star/awt/XWindow.hpp>
23 #include <com/sun/star/configuration/theDefaultProvider.hpp>
24 #include <com/sun/star/configuration/backend/MergeRecoveryRequest.hpp>
25 #include <com/sun/star/configuration/backend/StratumCreationException.hpp>
26 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
27 #include <com/sun/star/document/BrokenPackageRequest.hpp>
28 #include <com/sun/star/document/ExoticFileLoadException.hpp>
29 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
30 #include <com/sun/star/java/WrongJavaVersionException.hpp>
31 #include <com/sun/star/lang/XInitialization.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/script/ModuleSizeExceededRequest.hpp>
34 #include <com/sun/star/task/ErrorCodeIOException.hpp>
35 #include <com/sun/star/task/ErrorCodeRequest2.hpp>
36 #include <com/sun/star/task/InteractionHandler.hpp>
37 #include <com/sun/star/task/XInteractionAbort.hpp>
38 #include <com/sun/star/task/XInteractionApprove.hpp>
39 #include <com/sun/star/task/XInteractionDisapprove.hpp>
40 #include <com/sun/star/task/XInteractionHandler2.hpp>
41 #include <com/sun/star/task/XInteractionRequest.hpp>
42 #include <com/sun/star/ucb/AuthenticationFallbackRequest.hpp>
43 #include <com/sun/star/ucb/InteractiveAppException.hpp>
44 #include <com/sun/star/ucb/InteractiveLockingLockedException.hpp>
45 #include <com/sun/star/ucb/InteractiveLockingNotLockedException.hpp>
46 #include <com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp>
47 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
48 #include <com/sun/star/ucb/InteractiveNetworkOffLineException.hpp>
49 #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
50 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
51 #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
52 #include <com/sun/star/ucb/InteractiveWrongMediumException.hpp>
53 #include <com/sun/star/ucb/NameClashException.hpp>
54 #include <com/sun/star/ucb/NameClashResolveRequest.hpp>
55 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
56 #include <com/sun/star/ucb/XInteractionReplaceExistingData.hpp>
57 #include <com/sun/star/ucb/XInteractionSupplyName.hpp>
58 #include <com/sun/star/xforms/InvalidDataOnSubmitException.hpp>
59 #include <com/sun/star/loader/CannotActivateFactoryException.hpp>
61 #include <sal/log.hxx>
62 #include <rtl/ustrbuf.hxx>
63 #include <osl/conditn.hxx>
64 #include <unotools/resmgr.hxx>
65 #include <utility>
66 #include <vcl/errinf.hxx>
67 #include <vcl/svapp.hxx>
68 #include <vcl/weld.hxx>
69 #include <comphelper/diagnose_ex.hxx>
70 #include <comphelper/documentconstants.hxx>
71 #include <comphelper/propertysequence.hxx>
72 #include <svtools/sfxecode.hxx>
73 #include <unotools/configmgr.hxx>
74 #include <comphelper/namedvaluecollection.hxx>
75 #include <typelib/typedescription.hxx>
76 #include <unotools/confignode.hxx>
78 #include <ids.hxx>
79 #include <ids.hrc>
80 #include <strings.hrc>
82 #include "getcontinuations.hxx"
83 #include "secmacrowarnings.hxx"
85 #include "iahndl.hxx"
86 #include "nameclashdlg.hxx"
87 #include <comphelper/string.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;
107 namespace {
109 class HandleData : public osl::Condition
111 public:
112 explicit HandleData(
113 uno::Reference< task::XInteractionRequest > xRequest)
114 : m_rRequest(std::move(xRequest)),
115 bHandled( false )
118 uno::Reference< task::XInteractionRequest > m_rRequest;
119 bool bHandled;
120 beans::Optional< OUString > m_aResult;
123 } /* namespace */
125 UUIInteractionHelper::UUIInteractionHelper(
126 uno::Reference< uno::XComponentContext > xContext)
127 : m_xContext(std::move(xContext))
131 UUIInteractionHelper::~UUIInteractionHelper()
135 void UUIInteractionHelper::handlerequest(
136 void* pHandleData, void* pInteractionHelper)
138 HandleData* pHND
139 = static_cast< HandleData * >(pHandleData);
140 UUIInteractionHelper* pUUI
141 = static_cast< UUIInteractionHelper * >(pInteractionHelper);
142 bool bDummy = false;
143 OUString aDummy;
146 pHND->bHandled
147 = pUUI->handleRequest_impl(pHND->m_rRequest, false, bDummy, aDummy);
148 pHND->set();
150 catch (css::uno::Exception&)
152 TOOLS_WARN_EXCEPTION("uui", "");
156 bool
157 UUIInteractionHelper::handleRequest(
158 uno::Reference< task::XInteractionRequest > const & rRequest)
160 if(!Application::IsMainThread() && GetpApp())
162 // we are not in the main thread, let it handle that stuff
163 HandleData aHD(rRequest);
164 Link<void*,void> aLink(&aHD,handlerequest);
165 Application::PostUserEvent(aLink,this);
166 comphelper::SolarMutex& rSolarMutex = Application::GetSolarMutex();
167 sal_uInt32 nLockCount = (rSolarMutex.IsCurrentThread()) ? rSolarMutex.release(true) : 0;
168 aHD.wait();
169 if (nLockCount)
170 rSolarMutex.acquire(nLockCount);
171 return aHD.bHandled;
173 else
175 bool bDummy = false;
176 OUString aDummy;
177 return handleRequest_impl(rRequest, false, bDummy, aDummy);
181 void UUIInteractionHelper::getstringfromrequest(
182 void* pHandleData,void* pInteractionHelper)
184 HandleData* pHND = static_cast<HandleData*>(pHandleData);
185 UUIInteractionHelper* pUUI = static_cast<UUIInteractionHelper*>(pInteractionHelper);
186 pHND->m_aResult = pUUI->getStringFromRequest_impl(pHND->m_rRequest);
187 pHND->set();
190 beans::Optional< OUString >
191 UUIInteractionHelper::getStringFromRequest_impl(
192 uno::Reference< task::XInteractionRequest > const & rRequest)
194 bool bSuccess = false;
195 OUString aMessage;
196 handleRequest_impl(rRequest, true, bSuccess, aMessage);
198 OSL_ENSURE(bSuccess ||
199 !isInformationalErrorMessageRequest(
200 rRequest->getContinuations()),
201 "Interaction request is a candidate for a string representation."
202 "Please implement!");
204 return beans::Optional< OUString >(bSuccess, aMessage);
207 beans::Optional< OUString >
208 UUIInteractionHelper::getStringFromRequest(
209 uno::Reference< task::XInteractionRequest > const & rRequest)
211 if(!Application::IsMainThread() && GetpApp())
213 // we are not in the main thread, let it handle that stuff
214 HandleData aHD(rRequest);
215 Link<void*,void> aLink(&aHD,getstringfromrequest);
216 Application::PostUserEvent(aLink,this);
217 comphelper::SolarMutex& rSolarMutex = Application::GetSolarMutex();
218 sal_uInt32 nLockCount = (rSolarMutex.IsCurrentThread()) ? rSolarMutex.release(true) : 0;
219 aHD.wait();
220 if (nLockCount)
221 rSolarMutex.acquire(nLockCount);
222 return aHD.m_aResult;
224 else
225 return getStringFromRequest_impl(rRequest);
228 OUString
229 UUIInteractionHelper::replaceMessageWithArguments(
230 const OUString& _aMessage,
231 std::vector< OUString > const & rArguments )
233 OUString aMessage = _aMessage;
235 SAL_WARN_IF(rArguments.empty(), "uui", "replaceMessageWithArguments: No arguments passed!");
236 for (size_t i = 0; i < rArguments.size(); ++i)
238 const OUString sReplaceTemplate = "$(ARG" + OUString::number(i+1) + ")";
239 aMessage = aMessage.replaceAll(sReplaceTemplate, rArguments[i]);
242 return aMessage;
245 bool
246 UUIInteractionHelper::isInformationalErrorMessageRequest(
247 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
248 rContinuations)
250 // Only requests with a single continuation (user has no choice, request
251 // is just informational)
252 if (rContinuations.getLength() != 1 )
253 return false;
255 // user can only abort or approve, all other continuations are not
256 // considered to be informational.
257 uno::Reference< task::XInteractionApprove > xApprove(
258 rContinuations[0], uno::UNO_QUERY);
259 if (xApprove.is())
260 return true;
262 uno::Reference< task::XInteractionAbort > xAbort(
263 rContinuations[0], uno::UNO_QUERY);
264 return xAbort.is();
267 namespace
270 bool lcl_matchesRequest( const Any& i_rRequest, const OUString& i_rTypeName, std::u16string_view i_rPropagation )
272 const css::uno::TypeDescription aTypeDesc( i_rTypeName );
273 const typelib_TypeDescription* pTypeDesc = aTypeDesc.get();
274 if ( !pTypeDesc || !pTypeDesc->pWeakRef )
276 SAL_WARN( "uui","no type found for '" << i_rTypeName << "'" );
277 return false;
279 const css::uno::Type aType( pTypeDesc->pWeakRef );
281 const bool bExactMatch = i_rPropagation == u"named-only";
282 if ( bExactMatch )
283 return i_rRequest.getValueType().equals( aType );
285 return i_rRequest.isExtractableTo( aType );
290 bool UUIInteractionHelper::handleCustomRequest( const Reference< XInteractionRequest >& i_rRequest, const OUString& i_rServiceName ) const
294 Reference< XInteractionHandler2 > xHandler( m_xContext->getServiceManager()->createInstanceWithContext( i_rServiceName, m_xContext ), UNO_QUERY_THROW );
296 Reference< XInitialization > xHandlerInit( xHandler, UNO_QUERY );
297 if ( xHandlerInit.is() )
299 ::comphelper::NamedValueCollection aInitArgs;
300 aInitArgs.put( "Parent", getParentXWindow() );
301 xHandlerInit->initialize( aInitArgs.getWrappedPropertyValues() );
304 if ( xHandler->handleInteractionRequest( i_rRequest ) )
305 return true;
307 catch( const Exception& )
309 DBG_UNHANDLED_EXCEPTION("uui");
311 return false;
315 bool UUIInteractionHelper::handleTypedHandlerImplementations( Reference< XInteractionRequest > const & rRequest )
317 // the request
318 const Any aRequest( rRequest->getRequest() );
320 const StringHashMap::const_iterator aCacheHitTest = m_aTypedCustomHandlers.find( aRequest.getValueTypeName() );
321 if ( aCacheHitTest != m_aTypedCustomHandlers.end() )
322 return handleCustomRequest( rRequest, aCacheHitTest->second );
324 // the base registration node for "typed" interaction handlers
325 const ::utl::OConfigurationTreeRoot aConfigRoot( ::utl::OConfigurationTreeRoot::createWithComponentContext(
326 m_xContext,
327 "/org.openoffice.Interaction/InteractionHandlers",
329 ::utl::OConfigurationTreeRoot::CM_READONLY
330 ) );
332 // loop through all registered implementations
333 const Sequence< OUString > aRegisteredHandlers( aConfigRoot.getNodeNames() );
334 for ( auto const & handlerName : aRegisteredHandlers )
336 const ::utl::OConfigurationNode aHandlerNode( aConfigRoot.openNode( handlerName ) );
337 const ::utl::OConfigurationNode aTypesNode( aHandlerNode.openNode( "HandledRequestTypes" ) );
339 // loop through all the types which the current handler is registered for
340 const Sequence< OUString > aHandledTypes( aTypesNode.getNodeNames() );
341 for ( auto const & type : aHandledTypes )
343 // the UNO type is the node name
344 ::utl::OConfigurationNode aType( aTypesNode.openNode( type ) );
345 // and there's a child denoting how the responsibility propagates
346 OUString sPropagation;
347 OSL_VERIFY( aType.getNodeValue( "Propagation" ) >>= sPropagation );
348 if ( lcl_matchesRequest( aRequest, type, sPropagation ) )
350 // retrieve the service/implementation name of the handler
351 OUString sServiceName;
352 OSL_VERIFY( aHandlerNode.getNodeValue( "ServiceName" ) >>= sServiceName );
353 // cache the information who feels responsible for requests of this type
354 m_aTypedCustomHandlers[ aRequest.getValueTypeName() ] = sServiceName;
355 // actually handle the request
356 return handleCustomRequest( rRequest, sServiceName );
361 return false;
364 bool
365 UUIInteractionHelper::handleRequest_impl(
366 uno::Reference< task::XInteractionRequest > const & rRequest,
367 bool bObtainErrorStringOnly,
368 bool & bHasErrorString,
369 OUString & rErrorString)
373 if (!rRequest.is())
374 return false;
376 uno::Any aAnyRequest(rRequest->getRequest());
378 script::ModuleSizeExceededRequest aModSizeException;
379 if (aAnyRequest >>= aModSizeException )
381 std::vector< OUString > aArguments;
382 aArguments.push_back(
383 comphelper::string::convertCommaSeparated(aModSizeException.Names));
384 handleErrorHandlerRequest( task::InteractionClassification_WARNING,
385 ERRCODE_UUI_IO_MODULESIZEEXCEEDED,
386 aArguments,
387 rRequest->getContinuations(),
388 bObtainErrorStringOnly,
389 bHasErrorString,
390 rErrorString);
391 return true;
394 document::ExoticFileLoadException aExoticFileLoadException;
395 if (aAnyRequest >>= aExoticFileLoadException)
397 std::vector< OUString > aArguments;
399 if( !aExoticFileLoadException.URL.isEmpty() )
401 aArguments.push_back( aExoticFileLoadException.URL );
403 if( !aExoticFileLoadException.FilterUIName.isEmpty() )
405 aArguments.push_back( aExoticFileLoadException.FilterUIName );
408 handleErrorHandlerRequest( task::InteractionClassification_WARNING,
409 ERRCODE_UUI_IO_EXOTICFILEFORMAT,
410 aArguments,
411 rRequest->getContinuations(),
412 bObtainErrorStringOnly,
413 bHasErrorString,
414 rErrorString);
415 return true;
418 ucb::NameClashException aNCException;
419 if (aAnyRequest >>= aNCException)
421 ErrCode nErrorCode = ERRCODE_UUI_IO_TARGETALREADYEXISTS;
422 std::vector< OUString > aArguments;
424 if( !aNCException.Name.isEmpty() )
426 nErrorCode = ERRCODE_UUI_IO_ALREADYEXISTS;
427 aArguments.push_back( aNCException.Name );
430 handleErrorHandlerRequest( aNCException.Classification,
431 nErrorCode,
432 aArguments,
433 rRequest->getContinuations(),
434 bObtainErrorStringOnly,
435 bHasErrorString,
436 rErrorString);
437 return true;
440 ucb::UnsupportedNameClashException aUORequest;
441 if (aAnyRequest >>= aUORequest)
444 uno::Reference< task::XInteractionApprove > xApprove;
445 uno::Reference< task::XInteractionDisapprove > xDisapprove;
446 getContinuations(
447 rRequest->getContinuations(), &xApprove, &xDisapprove);
449 if ( xApprove.is() && xDisapprove.is() )
451 std::vector< OUString > aArguments;
452 handleErrorHandlerRequest( task::InteractionClassification_QUERY,
453 ERRCODE_UUI_IO_UNSUPPORTEDOVERWRITE,
454 aArguments,
455 rRequest->getContinuations(),
456 bObtainErrorStringOnly,
457 bHasErrorString,
458 rErrorString);
460 return true;
463 if ( handleInteractiveIOException( rRequest,
464 bObtainErrorStringOnly,
465 bHasErrorString,
466 rErrorString ) )
467 return true;
469 ucb::InteractiveAppException aAppException;
470 if (aAnyRequest >>= aAppException)
472 std::vector< OUString > aArguments;
473 handleErrorHandlerRequest( aAppException.Classification,
474 ErrCode(aAppException.Code),
475 aArguments,
476 rRequest->getContinuations(),
477 bObtainErrorStringOnly,
478 bHasErrorString,
479 rErrorString);
480 return true;
483 ucb::InteractiveNetworkException aNetworkException;
484 if (aAnyRequest >>= aNetworkException)
486 ErrCode nErrorCode;
487 std::vector< OUString > aArguments;
488 ucb::InteractiveNetworkOffLineException aOffLineException;
489 ucb::InteractiveNetworkResolveNameException aResolveNameException;
490 ucb::InteractiveNetworkConnectException aConnectException;
491 ucb::InteractiveNetworkReadException aReadException;
492 ucb::InteractiveNetworkWriteException aWriteException;
493 if (aAnyRequest >>= aOffLineException)
494 nErrorCode = ERRCODE_INET_OFFLINE;
495 else if (aAnyRequest >>= aResolveNameException)
497 nErrorCode = ERRCODE_INET_NAME_RESOLVE;
498 aArguments.push_back(aResolveNameException.Server);
500 else if (aAnyRequest >>= aConnectException)
502 nErrorCode = ERRCODE_INET_CONNECT;
503 aArguments.push_back(aConnectException.Server);
505 else if (aAnyRequest >>= aReadException)
507 nErrorCode = ERRCODE_INET_READ;
508 aArguments.push_back(aReadException.Diagnostic);
510 else if (aAnyRequest >>= aWriteException)
512 nErrorCode = ERRCODE_INET_WRITE;
513 aArguments.push_back(aWriteException.Diagnostic);
515 else
516 nErrorCode = ERRCODE_INET_GENERAL;
518 handleErrorHandlerRequest(aNetworkException.Classification,
519 nErrorCode,
520 aArguments,
521 rRequest->getContinuations(),
522 bObtainErrorStringOnly,
523 bHasErrorString,
524 rErrorString);
525 return true;
528 ucb::InteractiveWrongMediumException aWrongMediumException;
529 if (aAnyRequest >>= aWrongMediumException)
531 sal_Int32 nMedium = 0;
532 aWrongMediumException.Medium >>= nMedium;
533 std::vector< OUString > aArguments { OUString::number(nMedium + 1) };
534 handleErrorHandlerRequest(aWrongMediumException.Classification,
535 ERRCODE_UUI_WRONGMEDIUM,
536 aArguments,
537 rRequest->getContinuations(),
538 bObtainErrorStringOnly,
539 bHasErrorString,
540 rErrorString);
541 return true;
544 java::WrongJavaVersionException aWrongJavaVersionException;
545 if (aAnyRequest >>= aWrongJavaVersionException)
547 ErrCode nErrorCode;
548 std::vector< OUString > aArguments;
549 if (aWrongJavaVersionException.DetectedVersion.isEmpty())
550 if (aWrongJavaVersionException.LowestSupportedVersion.isEmpty())
551 nErrorCode = ERRCODE_UUI_WRONGJAVA;
552 else
554 nErrorCode = ERRCODE_UUI_WRONGJAVA_MIN;
555 aArguments.push_back(aWrongJavaVersionException.LowestSupportedVersion);
557 else if (aWrongJavaVersionException.LowestSupportedVersion.isEmpty())
559 nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION;
560 aArguments.push_back(aWrongJavaVersionException.DetectedVersion);
562 else
564 nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION_MIN;
565 aArguments.reserve(2);
566 aArguments.push_back(aWrongJavaVersionException.DetectedVersion);
567 aArguments.push_back(aWrongJavaVersionException.LowestSupportedVersion);
569 handleErrorHandlerRequest(task::InteractionClassification_ERROR,
570 nErrorCode,
571 aArguments,
572 rRequest->getContinuations(),
573 bObtainErrorStringOnly,
574 bHasErrorString,
575 rErrorString);
576 return true;
579 configuration::backend::MergeRecoveryRequest aMergeRecoveryRequest;
580 if (aAnyRequest >>= aMergeRecoveryRequest)
582 ErrCode nErrorCode = aMergeRecoveryRequest.IsRemovalRequest
583 ? ERRCODE_UUI_CONFIGURATION_BROKENDATA_WITHREMOVE
584 : ERRCODE_UUI_CONFIGURATION_BROKENDATA_NOREMOVE;
586 std::vector< OUString > aArguments { aMergeRecoveryRequest.ErrorLayerId };
588 handleErrorHandlerRequest(task::InteractionClassification_ERROR,
589 nErrorCode,
590 aArguments,
591 rRequest->getContinuations(),
592 bObtainErrorStringOnly,
593 bHasErrorString,
594 rErrorString);
595 return true;
598 configuration::backend::StratumCreationException
599 aStratumCreationException;
601 if (aAnyRequest >>= aStratumCreationException)
603 const ErrCode nErrorCode = ERRCODE_UUI_CONFIGURATION_BACKENDMISSING;
605 OUString aStratum = aStratumCreationException.StratumData;
606 if (aStratum.isEmpty())
607 aStratum = aStratumCreationException.StratumService;
609 std::vector< OUString > aArguments { aStratum };
611 handleErrorHandlerRequest(task::InteractionClassification_ERROR,
612 nErrorCode,
613 aArguments,
614 rRequest->getContinuations(),
615 bObtainErrorStringOnly,
616 bHasErrorString,
617 rErrorString);
618 return true;
621 xforms::InvalidDataOnSubmitException aInvalidDataOnSubmitException;
622 if (aAnyRequest >>= aInvalidDataOnSubmitException)
624 const ErrCode nErrorCode =
625 ERRCODE_UUI_INVALID_XFORMS_SUBMISSION_DATA;
627 std::vector< OUString > aArguments;
629 handleErrorHandlerRequest(task::InteractionClassification_QUERY,
630 nErrorCode,
631 aArguments,
632 rRequest->getContinuations(),
633 bObtainErrorStringOnly,
634 bHasErrorString,
635 rErrorString);
636 return true;
639 ucb::InteractiveLockingLockedException aLLException;
640 if (aAnyRequest >>= aLLException)
642 ErrCode nErrorCode = aLLException.SelfOwned
643 ? ERRCODE_UUI_LOCKING_LOCKED_SELF : ERRCODE_UUI_LOCKING_LOCKED;
644 std::vector< OUString > aArguments { aLLException.Url };
646 handleErrorHandlerRequest( aLLException.Classification,
647 nErrorCode,
648 aArguments,
649 rRequest->getContinuations(),
650 bObtainErrorStringOnly,
651 bHasErrorString,
652 rErrorString );
653 return true;
656 ucb::InteractiveLockingNotLockedException aLNLException;
657 if (aAnyRequest >>= aLNLException)
659 std::vector< OUString > aArguments { aLNLException.Url };
661 handleErrorHandlerRequest( aLNLException.Classification,
662 ERRCODE_UUI_LOCKING_NOT_LOCKED,
663 aArguments,
664 rRequest->getContinuations(),
665 bObtainErrorStringOnly,
666 bHasErrorString,
667 rErrorString );
668 return true;
671 ucb::InteractiveLockingLockExpiredException aLLEException;
672 if (aAnyRequest >>= aLLEException)
674 std::vector< OUString > aArguments { aLLEException.Url };
676 handleErrorHandlerRequest( aLLEException.Classification,
677 ERRCODE_UUI_LOCKING_LOCK_EXPIRED,
678 aArguments,
679 rRequest->getContinuations(),
680 bObtainErrorStringOnly,
681 bHasErrorString,
682 rErrorString );
683 return true;
686 document::BrokenPackageRequest aBrokenPackageRequest;
687 if (aAnyRequest >>= aBrokenPackageRequest)
689 std::vector< OUString > aArguments;
691 if( !aBrokenPackageRequest.aName.isEmpty() )
692 aArguments.push_back( aBrokenPackageRequest.aName );
694 handleBrokenPackageRequest( aArguments,
695 rRequest->getContinuations(),
696 bObtainErrorStringOnly,
697 bHasErrorString,
698 rErrorString );
699 return true;
702 task::ErrorCodeRequest2 aErrorCodeRequest2;
703 if (aAnyRequest >>= aErrorCodeRequest2)
705 handleGenericErrorRequest(
706 ErrCodeMsg(ErrCode(aErrorCodeRequest2.ErrCode), aErrorCodeRequest2.Arg1, aErrorCodeRequest2.Arg2, static_cast<DialogMask>(aErrorCodeRequest2.DialogMask)),
707 rRequest->getContinuations(),
708 bObtainErrorStringOnly,
709 bHasErrorString,
710 rErrorString);
711 return true;
713 task::ErrorCodeRequest aErrorCodeRequest;
714 if (aAnyRequest >>= aErrorCodeRequest)
716 handleGenericErrorRequest( ErrCode(aErrorCodeRequest.ErrCode),
717 rRequest->getContinuations(),
718 bObtainErrorStringOnly,
719 bHasErrorString,
720 rErrorString);
721 return true;
724 task::ErrorCodeIOException aErrorCodeIOException;
725 if (aAnyRequest >>= aErrorCodeIOException)
727 handleGenericErrorRequest( ErrCode(aErrorCodeIOException.ErrCode),
728 rRequest->getContinuations(),
729 bObtainErrorStringOnly,
730 bHasErrorString,
731 rErrorString);
732 return true;
735 loader::CannotActivateFactoryException aCannotActivateFactoryException;
736 if (aAnyRequest >>= aCannotActivateFactoryException)
738 std::vector< OUString > aArguments { aCannotActivateFactoryException.Message };
740 handleErrorHandlerRequest( task::InteractionClassification_ERROR,
741 ERRCODE_UUI_CANNOT_ACTIVATE_FACTORY,
742 aArguments,
743 rRequest->getContinuations(),
744 bObtainErrorStringOnly,
745 bHasErrorString,
746 rErrorString );
747 return true;
751 // Handle requests which do not have a plain string representation.
753 if (!bObtainErrorStringOnly)
755 ucb::AuthenticationFallbackRequest anAuthFallbackRequest;
756 if ( aAnyRequest >>= anAuthFallbackRequest )
758 handleAuthFallbackRequest( anAuthFallbackRequest.instructions,
759 anAuthFallbackRequest.url, rRequest->getContinuations() );
760 return true;
763 if ( handleAuthenticationRequest( rRequest ) )
764 return true;
766 if ( handleCertificateValidationRequest( rRequest ) )
767 return true;
769 ucb::NameClashResolveRequest aNameClashResolveRequest;
770 if (aAnyRequest >>= aNameClashResolveRequest)
772 handleNameClashResolveRequest(aNameClashResolveRequest,
773 rRequest->getContinuations());
774 return true;
777 if ( handleMasterPasswordRequest( rRequest ) )
778 return true;
780 if ( handlePasswordRequest( rRequest ) )
781 return true;
783 if ( handleNoSuchFilterRequest( rRequest ) )
784 return true;
786 if ( handleFilterOptionsRequest( rRequest ) )
787 return true;
789 if ( handleLockedDocumentRequest( rRequest ) )
790 return true;
792 if ( handleChangedByOthersRequest( rRequest ) )
793 return true;
795 if ( handleLockFileProblemRequest( rRequest ) )
796 return true;
798 if ( handleReloadEditableRequest( rRequest ) )
799 return true;
801 task::DocumentMacroConfirmationRequest aMacroConfirmRequest;
802 if (aAnyRequest >>= aMacroConfirmRequest)
804 handleMacroConfirmRequest(
805 aMacroConfirmRequest.DocumentURL,
806 aMacroConfirmRequest.DocumentStorage,
807 !aMacroConfirmRequest.DocumentVersion.isEmpty() ? aMacroConfirmRequest.DocumentVersion : ODFVER_013_TEXT,
808 aMacroConfirmRequest.DocumentSignatureInformation,
809 rRequest->getContinuations());
810 return true;
813 OUString aFileName;
814 beans::NamedValue aLoadReadOnlyRequest;
815 if ((aAnyRequest >>= aLoadReadOnlyRequest) &&
816 aLoadReadOnlyRequest.Name == "LoadReadOnlyRequest" &&
817 (aLoadReadOnlyRequest.Value >>= aFileName))
819 handleLoadReadOnlyRequest(aFileName,
820 rRequest->getContinuations());
821 return true;
824 // Last chance: interaction handlers registered in the configuration
827 // typed InteractionHandlers (ooo.Interactions)
828 if ( handleTypedHandlerImplementations( rRequest ) )
829 return true;
832 // Not handled.
833 return false;
835 catch( const uno::RuntimeException& )
837 throw; // allowed to leave here
839 catch( const uno::Exception& )
841 DBG_UNHANDLED_EXCEPTION("uui");
843 return false;
846 const uno::Reference< awt::XWindow>&
847 UUIInteractionHelper::getParentXWindow() const
849 return m_xWindowParam;
852 uno::Reference< task::XInteractionHandler2 >
853 UUIInteractionHelper::getInteractionHandler() const
855 return InteractionHandler::createWithParentAndContext(
856 m_xContext, m_xWindowParam,
857 m_aContextParam);
860 namespace {
862 DialogMask
863 executeMessageBox(
864 weld::Window * pParent,
865 OUString const & rTitle,
866 OUString const & rMessage,
867 VclMessageType eMessageType)
869 SolarMutexGuard aGuard;
871 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent, eMessageType,
872 eMessageType == VclMessageType::Question ? VclButtonsType::YesNo : VclButtonsType::Ok, rMessage, GetpApp()));
873 xBox->set_title(rTitle);
875 short nMessResult = xBox->run();
876 DialogMask aResult = DialogMask::NONE;
877 switch (nMessResult)
879 case RET_OK:
880 aResult = DialogMask::ButtonsOk;
881 break;
882 case RET_CANCEL:
883 aResult = DialogMask::ButtonsCancel;
884 break;
885 case RET_YES:
886 aResult = DialogMask::ButtonsYes;
887 break;
888 case RET_NO:
889 aResult = DialogMask::ButtonsNo;
890 break;
891 default:
892 assert(false);
895 return aResult;
898 NameClashResolveDialogResult executeSimpleNameClashResolveDialog(weld::Window *pParent,
899 OUString const & rTargetFolderURL,
900 OUString const & rClashingName,
901 OUString & rProposedNewName,
902 bool bAllowOverwrite)
904 std::locale aResLocale = Translate::Create("uui");
905 NameClashDialog aDialog(pParent, aResLocale, rTargetFolderURL,
906 rClashingName, rProposedNewName, bAllowOverwrite);
908 NameClashResolveDialogResult eResult = static_cast<NameClashResolveDialogResult>(aDialog.run());
909 rProposedNewName = aDialog.getNewName();
910 return eResult;
913 } // namespace
915 void
916 UUIInteractionHelper::handleNameClashResolveRequest(
917 ucb::NameClashResolveRequest const & rRequest,
918 uno::Sequence< uno::Reference<
919 task::XInteractionContinuation > > const & rContinuations)
921 OSL_ENSURE(!rRequest.TargetFolderURL.isEmpty(),
922 "NameClashResolveRequest must not contain empty TargetFolderURL" );
924 OSL_ENSURE(!rRequest.ClashingName.isEmpty(),
925 "NameClashResolveRequest must not contain empty ClashingName" );
927 uno::Reference< task::XInteractionAbort > xAbort;
928 uno::Reference< ucb::XInteractionSupplyName > xSupplyName;
929 uno::Reference< ucb::XInteractionReplaceExistingData > xReplaceExistingData;
930 getContinuations(
931 rContinuations, &xAbort, &xSupplyName, &xReplaceExistingData);
933 OSL_ENSURE( xAbort.is(),
934 "NameClashResolveRequest must contain Abort continuation" );
936 OSL_ENSURE( xSupplyName.is(),
937 "NameClashResolveRequest must contain SupplyName continuation" );
939 NameClashResolveDialogResult eResult = ABORT;
940 OUString aProposedNewName( rRequest.ProposedNewName );
942 uno::Reference<awt::XWindow> xParent = getParentXWindow();
943 eResult = executeSimpleNameClashResolveDialog(Application::GetFrameWeld(xParent),
944 rRequest.TargetFolderURL,
945 rRequest.ClashingName,
946 aProposedNewName,
947 xReplaceExistingData.is());
949 switch ( eResult )
951 case ABORT:
952 xAbort->select();
953 break;
955 case RENAME:
956 xSupplyName->setName( aProposedNewName );
957 xSupplyName->select();
958 break;
960 case OVERWRITE:
961 OSL_ENSURE(
962 xReplaceExistingData.is(),
963 "Invalid NameClashResolveDialogResult: OVERWRITE - "
964 "No ReplaceExistingData continuation available!" );
965 xReplaceExistingData->select();
966 break;
970 void
971 UUIInteractionHelper::handleGenericErrorRequest(
972 ErrCodeMsg nErrorCode,
973 uno::Sequence< uno::Reference<
974 task::XInteractionContinuation > > const & rContinuations,
975 bool bObtainErrorStringOnly,
976 bool & bHasErrorString,
977 OUString & rErrorString)
979 if (bObtainErrorStringOnly)
981 bHasErrorString = isInformationalErrorMessageRequest(rContinuations);
982 if (bHasErrorString)
984 OUString aErrorString;
985 ErrorHandler::GetErrorString(nErrorCode, aErrorString);
986 rErrorString = aErrorString;
989 else
991 uno::Reference< task::XInteractionAbort > xAbort;
992 uno::Reference< task::XInteractionApprove > xApprove;
993 getContinuations(rContinuations, &xApprove, &xAbort);
995 // Note: It's important to convert the transported long to the
996 // required unsigned long value. Otherwise using as flag field
997 // can fail ...
998 bool bWarning = !nErrorCode.IgnoreWarning();
1000 if ( nErrorCode == ERRCODE_SFX_INCOMPLETE_ENCRYPTION )
1002 // the security warning box needs a special title
1003 OUString aErrorString;
1004 ErrorHandler::GetErrorString( nErrorCode, aErrorString );
1006 std::locale aResLocale = Translate::Create("uui");
1007 OUString aTitle( utl::ConfigManager::getProductName() );
1009 OUString aErrTitle = Translate::get(STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE, aResLocale);
1011 if ( !aTitle.isEmpty() && !aErrTitle.isEmpty() )
1012 aTitle += " - " ;
1013 aTitle += aErrTitle;
1015 uno::Reference<awt::XWindow> xParent = getParentXWindow();
1016 executeMessageBox(Application::GetFrameWeld(xParent), aTitle, aErrorString, VclMessageType::Error);
1018 else
1020 uno::Reference<awt::XWindow> xParent = getParentXWindow();
1021 ErrorHandler::HandleError(nErrorCode, Application::GetFrameWeld(xParent));
1024 if (xApprove.is() && bWarning)
1025 xApprove->select();
1026 else if (xAbort.is())
1027 xAbort->select();
1031 void
1032 UUIInteractionHelper::handleMacroConfirmRequest(
1033 const OUString& aDocumentURL,
1034 const uno::Reference< embed::XStorage >& xZipStorage,
1035 const OUString& aDocumentVersion,
1036 const uno::Sequence< security::DocumentSignatureInformation >& aSignInfo,
1037 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
1038 rContinuations )
1040 uno::Reference< task::XInteractionAbort > xAbort;
1041 uno::Reference< task::XInteractionApprove > xApprove;
1042 getContinuations( rContinuations, &xApprove, &xAbort );
1044 bool bApprove = false;
1046 bool bShowSignatures = aSignInfo.hasElements();
1047 uno::Reference<awt::XWindow> xParent = getParentXWindow();
1048 MacroWarning aWarning(Application::GetFrameWeld(xParent), bShowSignatures);
1050 aWarning.SetDocumentURL(aDocumentURL);
1051 if ( aSignInfo.getLength() > 1 )
1053 aWarning.SetStorage(xZipStorage, aDocumentVersion, aSignInfo);
1055 else if ( aSignInfo.getLength() == 1 )
1057 aWarning.SetCertificate(aSignInfo[0].Signer);
1060 bApprove = aWarning.run() == RET_OK;
1062 if ( bApprove && xApprove.is() )
1063 xApprove->select();
1064 else if ( xAbort.is() )
1065 xAbort->select();
1068 void
1069 UUIInteractionHelper::handleBrokenPackageRequest(
1070 std::vector< OUString > const & rArguments,
1071 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
1072 rContinuations,
1073 bool bObtainErrorStringOnly,
1074 bool & bHasErrorString,
1075 OUString & rErrorString)
1077 if (bObtainErrorStringOnly)
1079 bHasErrorString = isInformationalErrorMessageRequest(rContinuations);
1080 if (!bHasErrorString)
1081 return;
1084 uno::Reference< task::XInteractionApprove > xApprove;
1085 uno::Reference< task::XInteractionDisapprove > xDisapprove;
1086 uno::Reference< task::XInteractionAbort > xAbort;
1087 getContinuations(rContinuations, &xApprove, &xDisapprove, &xAbort);
1089 ErrCode nErrorCode;
1090 if( xApprove.is() && xDisapprove.is() )
1092 nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE;
1094 else if ( xAbort.is() )
1096 nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE_CANTREPAIR;
1098 else
1099 return;
1101 OUString aMessage;
1103 std::locale aResLocale = Translate::Create("uui");
1104 ErrorResource aErrorResource(RID_UUI_ERRHDL, aResLocale);
1105 if (!aErrorResource.getString(nErrorCode, aMessage))
1106 return;
1109 aMessage = replaceMessageWithArguments( aMessage, rArguments );
1111 if (bObtainErrorStringOnly)
1113 rErrorString = aMessage;
1114 return;
1117 VclMessageType eMessageType;
1118 if( xApprove.is() && xDisapprove.is() )
1119 eMessageType = VclMessageType::Question;
1120 else if ( xAbort.is() )
1121 eMessageType = VclMessageType::Warning;
1122 else
1123 return;
1125 OUString title(
1126 utl::ConfigManager::getProductName() +
1127 " " +
1128 utl::ConfigManager::getProductVersion() );
1130 uno::Reference<awt::XWindow> xParent = getParentXWindow();
1131 switch (executeMessageBox(Application::GetFrameWeld(xParent), title, aMessage, eMessageType))
1133 case DialogMask::ButtonsOk:
1134 OSL_ENSURE( xAbort.is(), "unexpected situation" );
1135 if (xAbort.is())
1136 xAbort->select();
1137 break;
1139 case DialogMask::ButtonsNo:
1140 OSL_ENSURE(xDisapprove.is(), "unexpected situation");
1141 if (xDisapprove.is())
1142 xDisapprove->select();
1143 break;
1145 case DialogMask::ButtonsYes:
1146 OSL_ENSURE(xApprove.is(), "unexpected situation");
1147 if (xApprove.is())
1148 xApprove->select();
1149 break;
1151 default: break;
1155 // ErrorResource Implementation
1156 bool ErrorResource::getString(ErrCode nErrorCode, OUString &rString) const
1158 for (const std::pair<TranslateId, ErrCode>* pStringArray = m_pStringArray; pStringArray->first; ++pStringArray)
1160 if (nErrorCode.StripWarning() == pStringArray->second.StripWarning())
1162 rString = Translate::get(pStringArray->first, m_rResLocale);
1163 return true;
1166 return false;
1169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */