Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / uui / source / iahndl.cxx
blob8850d920639fe13a64af1be4afa3fb1dabb52901
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/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/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/ErrorCodeRequest.hpp"
36 #include "com/sun/star/task/FutureDocumentVersionProductUpdateRequest.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/XInteractionAskLater.hpp"
41 #include "com/sun/star/task/XInteractionDisapprove.hpp"
42 #include "com/sun/star/task/XInteractionHandler2.hpp"
43 #include "com/sun/star/task/XInteractionRequest.hpp"
44 #include "com/sun/star/task/XInteractionRetry.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 "tools/rcid.h"
66 #include "tools/errinf.hxx"
67 #include "osl/mutex.hxx"
68 #include "osl/thread.hxx"
69 #include "tools/diagnose_ex.h"
70 #include "comphelper/documentconstants.hxx"
71 #include "svtools/sfxecode.hxx"
72 #include "vcl/msgbox.hxx"
73 #include "vcl/svapp.hxx"
74 #include "unotools/configmgr.hxx"
75 #include "toolkit/helper/vclunohelper.hxx"
76 #include "comphelper/processfactory.hxx"
77 #include "comphelper/namedvaluecollection.hxx"
78 #include "typelib/typedescription.hxx"
79 #include "unotools/confignode.hxx"
81 #include "ids.hrc"
83 #include "getcontinuations.hxx"
84 #include "secmacrowarnings.hxx"
85 #include "newerverwarn.hxx"
87 #include "iahndl.hxx"
88 #include "nameclashdlg.hxx"
90 #include <boost/scoped_ptr.hpp>
92 using ::com::sun::star::uno::Sequence;
93 using ::com::sun::star::uno::UNO_QUERY;
94 using ::com::sun::star::uno::Reference;
95 using ::com::sun::star::task::XInteractionContinuation;
96 using ::com::sun::star::task::XInteractionAbort;
97 using ::com::sun::star::task::XInteractionApprove;
98 using ::com::sun::star::task::XInteractionAskLater;
99 using ::com::sun::star::task::FutureDocumentVersionProductUpdateRequest;
100 using ::com::sun::star::uno::XInterface;
101 using ::com::sun::star::lang::XInitialization;
102 using ::com::sun::star::uno::UNO_QUERY_THROW;
103 using ::com::sun::star::task::InteractionHandler;
104 using ::com::sun::star::task::XInteractionHandler2;
105 using ::com::sun::star::uno::Exception;
106 using ::com::sun::star::uno::Any;
107 using ::com::sun::star::task::XInteractionRequest;
108 using ::com::sun::star::lang::XMultiServiceFactory;
110 using namespace ::com::sun::star;
112 namespace {
114 class HandleData : public osl::Condition
116 public:
117 HandleData(
118 uno::Reference< task::XInteractionRequest > const & rRequest)
119 : osl::Condition(),
120 m_rRequest(rRequest),
121 bHandled( false )
124 uno::Reference< task::XInteractionRequest > m_rRequest;
125 bool bHandled;
126 beans::Optional< OUString > m_aResult;
129 } /* namespace */
131 UUIInteractionHelper::UUIInteractionHelper(
132 uno::Reference< uno::XComponentContext > const & rxContext,
133 uno::Reference< awt::XWindow > const & rxWindowParam,
134 const OUString & rContextParam)
135 SAL_THROW(()):
136 m_xContext(rxContext),
137 m_xWindowParam(rxWindowParam),
138 m_aContextParam(rContextParam)
142 UUIInteractionHelper::UUIInteractionHelper(
143 uno::Reference< uno::XComponentContext > const & rxContext)
144 SAL_THROW(()):
145 m_xContext(rxContext)
149 UUIInteractionHelper::~UUIInteractionHelper()
153 long
154 UUIInteractionHelper::handlerequest(
155 void* pHandleData, void* pInteractionHelper)
157 HandleData* pHND
158 = static_cast< HandleData * >(pHandleData);
159 UUIInteractionHelper* pUUI
160 = static_cast< UUIInteractionHelper * >(pInteractionHelper);
161 bool bDummy = false;
162 OUString aDummy;
163 pHND->bHandled
164 = pUUI->handleRequest_impl(pHND->m_rRequest, false, bDummy, aDummy);
165 pHND->set();
166 return 0;
169 bool
170 UUIInteractionHelper::handleRequest(
171 uno::Reference< task::XInteractionRequest > const & rRequest)
172 SAL_THROW((uno::RuntimeException))
174 Application* pApp = 0;
176 // be aware,it is the same type
177 static_cast< oslThreadIdentifier >(
178 Application::GetMainThreadIdentifier())
179 != osl::Thread::getCurrentIdentifier()
181 (pApp = GetpApp())
182 != 0
184 // we are not in the main thread, let it handle that stuff
185 HandleData aHD(rRequest);
186 Link aLink(&aHD,handlerequest);
187 pApp->PostUserEvent(aLink,this);
188 sal_uLong locks = Application::ReleaseSolarMutex();
189 aHD.wait();
190 Application::AcquireSolarMutex(locks);
191 return aHD.bHandled;
193 else
195 bool bDummy = false;
196 OUString aDummy;
197 return handleRequest_impl(rRequest, false, bDummy, aDummy);
201 long
202 UUIInteractionHelper::getstringfromrequest(
203 void* pHandleData,void* pInteractionHelper)
205 HandleData* pHND = (HandleData*) pHandleData;
206 UUIInteractionHelper* pUUI = (UUIInteractionHelper*) pInteractionHelper;
207 pHND->m_aResult = pUUI->getStringFromRequest_impl(pHND->m_rRequest);
208 pHND->set();
209 return 0;
212 beans::Optional< OUString >
213 UUIInteractionHelper::getStringFromRequest_impl(
214 uno::Reference< task::XInteractionRequest > const & rRequest)
215 SAL_THROW((uno::RuntimeException))
217 bool bSuccess = false;
218 OUString aMessage;
219 handleRequest_impl(rRequest, true, bSuccess, aMessage);
221 OSL_ENSURE(bSuccess ||
222 !isInformationalErrorMessageRequest(
223 rRequest->getContinuations()),
224 "Interaction request is a candidate for a string representation."
225 "Please implement!");
227 return beans::Optional< OUString >(bSuccess, aMessage);
230 beans::Optional< OUString >
231 UUIInteractionHelper::getStringFromRequest(
232 uno::Reference< task::XInteractionRequest > const & rRequest)
233 SAL_THROW((uno::RuntimeException))
235 Application* pApp = 0;
237 // be aware,it is the same type
238 static_cast< oslThreadIdentifier >(
239 Application::GetMainThreadIdentifier())
240 != osl::Thread::getCurrentIdentifier()
242 (pApp = GetpApp())
243 != 0
245 // we are not in the main thread, let it handle that stuff
246 HandleData aHD(rRequest);
247 Link aLink(&aHD,getstringfromrequest);
248 pApp->PostUserEvent(aLink,this);
249 sal_uLong locks = Application::ReleaseSolarMutex();
250 aHD.wait();
251 Application::AcquireSolarMutex(locks);
252 return aHD.m_aResult;
254 else
255 return getStringFromRequest_impl(rRequest);
258 OUString
259 UUIInteractionHelper::replaceMessageWithArguments(
260 OUString aMessage,
261 std::vector< OUString > const & rArguments )
263 for (sal_Int32 i = 0;;)
265 i = aMessage.indexOf("$(ARG", i);
266 if (i == -1)
267 break;
268 if (aMessage.getLength() - i >= RTL_CONSTASCII_LENGTH("$(ARGx)")
269 && aMessage[i + RTL_CONSTASCII_LENGTH("$(ARGx")] == ')')
271 sal_Unicode c = aMessage[i + RTL_CONSTASCII_LENGTH("$(ARG")];
272 if (c >= '1' && c <= '2')
274 std::vector< OUString >::size_type nIndex
275 = static_cast< std::vector< OUString >::size_type >(
276 c - '1');
277 if (nIndex < rArguments.size())
279 aMessage
280 = aMessage.replaceAt(i,
281 RTL_CONSTASCII_LENGTH("$(ARGx)"),
282 rArguments[nIndex]);
283 i += rArguments[nIndex].getLength();
284 continue;
288 ++i;
291 return aMessage;
294 bool
295 UUIInteractionHelper::isInformationalErrorMessageRequest(
296 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
297 rContinuations)
299 // Only requests with a single continuation (user has no choice, request
300 // is just informational)
301 if (rContinuations.getLength() != 1 )
302 return false;
304 // user can only abort or approve, all other continuations are not
305 // considered to be informational.
306 uno::Reference< task::XInteractionApprove > xApprove(
307 rContinuations[0], uno::UNO_QUERY);
308 if (xApprove.is())
309 return true;
311 uno::Reference< task::XInteractionAbort > xAbort(
312 rContinuations[0], uno::UNO_QUERY);
313 if (xAbort.is())
314 return true;
316 return false;
319 bool
320 UUIInteractionHelper::tryOtherInteractionHandler(
321 uno::Reference< task::XInteractionRequest > const & rRequest)
322 SAL_THROW((uno::RuntimeException))
324 InteractionHandlerDataList dataList;
325 getInteractionHandlerList(dataList);
327 InteractionHandlerDataList::const_iterator aEnd(dataList.end());
328 for (InteractionHandlerDataList::const_iterator aIt(dataList.begin());
329 aIt != aEnd;
330 ++aIt)
332 if ( handleCustomRequest( rRequest, aIt->ServiceName ) )
333 return true;
335 return false;
338 namespace
340 // .................................................................................................................
341 static bool lcl_matchesRequest( const Any& i_rRequest, const OUString& i_rTypeName, const OUString& i_rPropagation )
343 const ::com::sun::star::uno::TypeDescription aTypeDesc( i_rTypeName );
344 const typelib_TypeDescription* pTypeDesc = aTypeDesc.get();
345 if ( !pTypeDesc || !pTypeDesc->pWeakRef )
347 #if OSL_DEBUG_LEVEL > 0
348 OStringBuffer aMessage;
349 aMessage.append( "no type found for '" );
350 aMessage.append( OUStringToOString( i_rTypeName, RTL_TEXTENCODING_UTF8 ) );
351 aMessage.append( "'" );
352 OSL_FAIL( aMessage.makeStringAndClear().getStr() );
353 #endif
354 return false;
356 const ::com::sun::star::uno::Type aType( pTypeDesc->pWeakRef );
358 const bool bExactMatch = i_rPropagation.equalsAscii( "named-only" );
359 if ( bExactMatch )
360 return i_rRequest.getValueType().equals( aType );
362 return i_rRequest.isExtractableTo( aType );
366 // ---------------------------------------------------------------------------------------------------------------------
367 bool UUIInteractionHelper::handleCustomRequest( const Reference< XInteractionRequest >& i_rRequest, const OUString& i_rServiceName ) const
371 Reference< XInteractionHandler2 > xHandler( m_xContext->getServiceManager()->createInstanceWithContext( i_rServiceName, m_xContext ), UNO_QUERY_THROW );
373 Reference< XInitialization > xHandlerInit( xHandler, UNO_QUERY );
374 if ( xHandlerInit.is() )
376 ::comphelper::NamedValueCollection aInitArgs;
377 aInitArgs.put( "Parent", getParentXWindow() );
378 xHandlerInit->initialize( aInitArgs.getWrappedPropertyValues() );
381 if ( xHandler->handleInteractionRequest( i_rRequest ) )
382 return true;
384 catch( const Exception& )
386 DBG_UNHANDLED_EXCEPTION();
388 return false;
391 // ---------------------------------------------------------------------------------------------------------------------
392 bool UUIInteractionHelper::handleTypedHandlerImplementations( Reference< XInteractionRequest > const & rRequest )
394 // the request
395 const Any aRequest( rRequest->getRequest() );
397 const StringHashMap::const_iterator aCacheHitTest = m_aTypedCustomHandlers.find( aRequest.getValueTypeName() );
398 if ( aCacheHitTest != m_aTypedCustomHandlers.end() )
399 return handleCustomRequest( rRequest, aCacheHitTest->second );
401 // the base registration node for "typed" interaction handlers
402 const ::utl::OConfigurationTreeRoot aConfigRoot( ::utl::OConfigurationTreeRoot::createWithComponentContext(
403 m_xContext,
404 OUString( "/org.openoffice.Interaction/InteractionHandlers" ),
406 ::utl::OConfigurationTreeRoot::CM_READONLY
407 ) );
409 // loop through all registered implementations
410 const Sequence< OUString > aRegisteredHandlers( aConfigRoot.getNodeNames() );
411 const OUString* pHandlerName = aRegisteredHandlers.getConstArray();
412 const OUString* pHandlersEnd = aRegisteredHandlers.getConstArray() + aRegisteredHandlers.getLength();
413 for ( ; pHandlerName != pHandlersEnd; ++pHandlerName )
415 const ::utl::OConfigurationNode aHandlerNode( aConfigRoot.openNode( *pHandlerName ) );
416 const ::utl::OConfigurationNode aTypesNode( aHandlerNode.openNode( "HandledRequestTypes" ) );
418 // loop through all the types which the current handler is registered for
419 const Sequence< OUString > aHandledTypes( aTypesNode.getNodeNames() );
420 const OUString* pType = aHandledTypes.getConstArray();
421 const OUString* pTypesEnd = aHandledTypes.getConstArray() + aHandledTypes.getLength();
422 for ( ; pType != pTypesEnd; ++pType )
424 // the UNO type is the node name
425 ::utl::OConfigurationNode aType( aTypesNode.openNode( *pType ) );
426 // and there's a child denoting how the responsibility propagates
427 OUString sPropagation;
428 OSL_VERIFY( aType.getNodeValue( "Propagation" ) >>= sPropagation );
429 if ( lcl_matchesRequest( aRequest, *pType, sPropagation ) )
431 // retrieve the service/implementation name of the handler
432 OUString sServiceName;
433 OSL_VERIFY( aHandlerNode.getNodeValue( "ServiceName" ) >>= sServiceName );
434 // cache the information who feels responsible for requests of this type
435 m_aTypedCustomHandlers[ aRequest.getValueTypeName() ] = sServiceName;
436 // actually handle the request
437 return handleCustomRequest( rRequest, sServiceName );
442 return false;
445 bool
446 UUIInteractionHelper::handleRequest_impl(
447 uno::Reference< task::XInteractionRequest > const & rRequest,
448 bool bObtainErrorStringOnly,
449 bool & bHasErrorString,
450 OUString & rErrorString)
451 SAL_THROW((uno::RuntimeException))
455 if (!rRequest.is())
456 return false;
458 uno::Any aAnyRequest(rRequest->getRequest());
460 script::ModuleSizeExceededRequest aModSizeException;
461 if (aAnyRequest >>= aModSizeException )
463 ErrCode nErrorCode = ERRCODE_UUI_IO_MODULESIZEEXCEEDED;
464 std::vector< OUString > aArguments;
465 uno::Sequence< OUString > sModules
466 = aModSizeException.Names;
467 if ( sModules.getLength() )
469 OUString aName;
470 for ( sal_Int32 index=0; index< sModules.getLength(); ++index )
472 if ( index )
473 aName = aName + OUString( ',' ) + sModules[index];
474 else
475 aName = sModules[index]; // 1st name
477 aArguments.push_back( aName );
479 handleErrorHandlerRequest( task::InteractionClassification_WARNING,
480 nErrorCode,
481 aArguments,
482 rRequest->getContinuations(),
483 bObtainErrorStringOnly,
484 bHasErrorString,
485 rErrorString);
486 return true;
489 ucb::NameClashException aNCException;
490 if (aAnyRequest >>= aNCException)
492 ErrCode nErrorCode = ERRCODE_UUI_IO_TARGETALREADYEXISTS;
493 std::vector< OUString > aArguments;
495 if( !aNCException.Name.isEmpty() )
497 nErrorCode = ERRCODE_UUI_IO_ALREADYEXISTS;
498 aArguments.push_back( aNCException.Name );
501 handleErrorHandlerRequest( aNCException.Classification,
502 nErrorCode,
503 aArguments,
504 rRequest->getContinuations(),
505 bObtainErrorStringOnly,
506 bHasErrorString,
507 rErrorString);
508 return true;
511 ucb::UnsupportedNameClashException aUORequest;
512 if (aAnyRequest >>= aUORequest)
514 ErrCode nErrorCode = ERRCODE_UUI_IO_UNSUPPORTEDOVERWRITE;
515 std::vector< OUString > aArguments;
517 uno::Reference< task::XInteractionApprove > xApprove;
518 uno::Reference< task::XInteractionDisapprove > xDisapprove;
519 getContinuations(
520 rRequest->getContinuations(), &xApprove, &xDisapprove);
522 if ( xApprove.is() && xDisapprove.is() )
524 handleErrorHandlerRequest( task::InteractionClassification_QUERY,
525 nErrorCode,
526 aArguments,
527 rRequest->getContinuations(),
528 bObtainErrorStringOnly,
529 bHasErrorString,
530 rErrorString);
532 return true;
535 if ( handleInteractiveIOException( rRequest,
536 bObtainErrorStringOnly,
537 bHasErrorString,
538 rErrorString ) )
539 return true;
541 ucb::InteractiveAppException aAppException;
542 if (aAnyRequest >>= aAppException)
544 std::vector< OUString > aArguments;
545 handleErrorHandlerRequest( aAppException.Classification,
546 aAppException.Code,
547 aArguments,
548 rRequest->getContinuations(),
549 bObtainErrorStringOnly,
550 bHasErrorString,
551 rErrorString);
552 return true;
555 ucb::InteractiveNetworkException aNetworkException;
556 if (aAnyRequest >>= aNetworkException)
558 ErrCode nErrorCode;
559 std::vector< OUString > aArguments;
560 ucb::InteractiveNetworkOffLineException aOffLineException;
561 ucb::InteractiveNetworkResolveNameException aResolveNameException;
562 ucb::InteractiveNetworkConnectException aConnectException;
563 ucb::InteractiveNetworkReadException aReadException;
564 ucb::InteractiveNetworkWriteException aWriteException;
565 if (aAnyRequest >>= aOffLineException)
566 nErrorCode = ERRCODE_INET_OFFLINE;
567 else if (aAnyRequest >>= aResolveNameException)
569 nErrorCode = ERRCODE_INET_NAME_RESOLVE;
570 aArguments.push_back(aResolveNameException.Server);
572 else if (aAnyRequest >>= aConnectException)
574 nErrorCode = ERRCODE_INET_CONNECT;
575 aArguments.push_back(aConnectException.Server);
577 else if (aAnyRequest >>= aReadException)
579 nErrorCode = ERRCODE_INET_READ;
580 aArguments.push_back(aReadException.Diagnostic);
582 else if (aAnyRequest >>= aWriteException)
584 nErrorCode = ERRCODE_INET_WRITE;
585 aArguments.push_back(aWriteException.Diagnostic);
587 else
588 nErrorCode = ERRCODE_INET_GENERAL;
590 handleErrorHandlerRequest(aNetworkException.Classification,
591 nErrorCode,
592 aArguments,
593 rRequest->getContinuations(),
594 bObtainErrorStringOnly,
595 bHasErrorString,
596 rErrorString);
597 return true;
600 ucb::InteractiveWrongMediumException aWrongMediumException;
601 if (aAnyRequest >>= aWrongMediumException)
603 sal_Int32 nMedium = 0;
604 aWrongMediumException.Medium >>= nMedium;
605 std::vector< OUString > aArguments;
606 aArguments.push_back(OUString::number(nMedium + 1));
607 handleErrorHandlerRequest(aWrongMediumException.Classification,
608 ERRCODE_UUI_WRONGMEDIUM,
609 aArguments,
610 rRequest->getContinuations(),
611 bObtainErrorStringOnly,
612 bHasErrorString,
613 rErrorString);
614 return true;
617 java::WrongJavaVersionException aWrongJavaVersionException;
618 if (aAnyRequest >>= aWrongJavaVersionException)
620 ErrCode nErrorCode;
621 std::vector< OUString > aArguments;
622 if (aWrongJavaVersionException.DetectedVersion.isEmpty())
623 if (aWrongJavaVersionException.LowestSupportedVersion.isEmpty())
624 nErrorCode = ERRCODE_UUI_WRONGJAVA;
625 else
627 nErrorCode = ERRCODE_UUI_WRONGJAVA_MIN;
628 aArguments.push_back(aWrongJavaVersionException.LowestSupportedVersion);
630 else if (aWrongJavaVersionException.LowestSupportedVersion.isEmpty())
632 nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION;
633 aArguments.push_back(aWrongJavaVersionException.DetectedVersion);
635 else
637 nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION_MIN;
638 aArguments.reserve(2);
639 aArguments.push_back(aWrongJavaVersionException.DetectedVersion);
640 aArguments.push_back(aWrongJavaVersionException.LowestSupportedVersion);
642 handleErrorHandlerRequest(task::InteractionClassification_ERROR,
643 nErrorCode,
644 aArguments,
645 rRequest->getContinuations(),
646 bObtainErrorStringOnly,
647 bHasErrorString,
648 rErrorString);
649 return true;
652 configuration::backend::MergeRecoveryRequest aMergeRecoveryRequest;
653 if (aAnyRequest >>= aMergeRecoveryRequest)
655 ErrCode nErrorCode = aMergeRecoveryRequest.IsRemovalRequest
656 ? ERRCODE_UUI_CONFIGURATION_BROKENDATA_WITHREMOVE
657 : ERRCODE_UUI_CONFIGURATION_BROKENDATA_NOREMOVE;
659 std::vector< OUString > aArguments;
660 aArguments.push_back(aMergeRecoveryRequest.ErrorLayerId);
662 handleErrorHandlerRequest(task::InteractionClassification_ERROR,
663 nErrorCode,
664 aArguments,
665 rRequest->getContinuations(),
666 bObtainErrorStringOnly,
667 bHasErrorString,
668 rErrorString);
669 return true;
672 configuration::backend::StratumCreationException
673 aStratumCreationException;
675 if (aAnyRequest >>= aStratumCreationException)
677 const ErrCode nErrorCode = ERRCODE_UUI_CONFIGURATION_BACKENDMISSING;
679 OUString aStratum = aStratumCreationException.StratumData;
680 if (aStratum.isEmpty())
681 aStratum = aStratumCreationException.StratumService;
683 std::vector< OUString > aArguments;
684 aArguments.push_back(aStratum);
686 handleErrorHandlerRequest(task::InteractionClassification_ERROR,
687 nErrorCode,
688 aArguments,
689 rRequest->getContinuations(),
690 bObtainErrorStringOnly,
691 bHasErrorString,
692 rErrorString);
693 return true;
696 xforms::InvalidDataOnSubmitException aInvalidDataOnSubmitException;
697 if (aAnyRequest >>= aInvalidDataOnSubmitException)
699 const ErrCode nErrorCode =
700 ERRCODE_UUI_INVALID_XFORMS_SUBMISSION_DATA;
702 std::vector< OUString > aArguments;
704 handleErrorHandlerRequest(task::InteractionClassification_QUERY,
705 nErrorCode,
706 aArguments,
707 rRequest->getContinuations(),
708 bObtainErrorStringOnly,
709 bHasErrorString,
710 rErrorString);
711 return true;
714 ucb::InteractiveLockingLockedException aLLException;
715 if (aAnyRequest >>= aLLException)
717 ErrCode nErrorCode = aLLException.SelfOwned
718 ? ERRCODE_UUI_LOCKING_LOCKED_SELF : ERRCODE_UUI_LOCKING_LOCKED;
719 std::vector< OUString > aArguments;
720 aArguments.push_back( aLLException.Url );
722 handleErrorHandlerRequest( aLLException.Classification,
723 nErrorCode,
724 aArguments,
725 rRequest->getContinuations(),
726 bObtainErrorStringOnly,
727 bHasErrorString,
728 rErrorString );
729 return true;
732 ucb::InteractiveLockingNotLockedException aLNLException;
733 if (aAnyRequest >>= aLNLException)
735 ErrCode nErrorCode = ERRCODE_UUI_LOCKING_NOT_LOCKED;
736 std::vector< OUString > aArguments;
737 aArguments.push_back( aLNLException.Url );
739 handleErrorHandlerRequest( aLNLException.Classification,
740 nErrorCode,
741 aArguments,
742 rRequest->getContinuations(),
743 bObtainErrorStringOnly,
744 bHasErrorString,
745 rErrorString );
746 return true;
749 ucb::InteractiveLockingLockExpiredException aLLEException;
750 if (aAnyRequest >>= aLLEException)
752 ErrCode nErrorCode = ERRCODE_UUI_LOCKING_LOCK_EXPIRED;
753 std::vector< OUString > aArguments;
754 aArguments.push_back( aLLEException.Url );
756 handleErrorHandlerRequest( aLLEException.Classification,
757 nErrorCode,
758 aArguments,
759 rRequest->getContinuations(),
760 bObtainErrorStringOnly,
761 bHasErrorString,
762 rErrorString );
763 return true;
766 document::BrokenPackageRequest aBrokenPackageRequest;
767 if (aAnyRequest >>= aBrokenPackageRequest)
769 std::vector< OUString > aArguments;
771 if( !aBrokenPackageRequest.aName.isEmpty() )
772 aArguments.push_back( aBrokenPackageRequest.aName );
774 handleBrokenPackageRequest( aArguments,
775 rRequest->getContinuations(),
776 bObtainErrorStringOnly,
777 bHasErrorString,
778 rErrorString );
779 return true;
782 task::ErrorCodeRequest aErrorCodeRequest;
783 if (aAnyRequest >>= aErrorCodeRequest)
785 // Sucky special handling for xlsx macro filter warning
786 if ( (sal_uInt32)ERRCODE_SFX_VBASIC_CANTSAVE_STORAGE == (sal_uInt32)aErrorCodeRequest.ErrCode)
788 std::vector< OUString > aArguments;
789 handleErrorHandlerRequest( task::InteractionClassification_WARNING,
790 ERRCODE_UUI_IO_WARN_CANTSAVE_MACROS,
791 aArguments,
792 rRequest->getContinuations(),
793 bObtainErrorStringOnly,
794 bHasErrorString,
795 rErrorString);
797 else
799 handleGenericErrorRequest( aErrorCodeRequest.ErrCode,
800 rRequest->getContinuations(),
801 bObtainErrorStringOnly,
802 bHasErrorString,
803 rErrorString);
805 return true;
808 task::ErrorCodeIOException aErrorCodeIOException;
809 if (aAnyRequest >>= aErrorCodeIOException)
811 handleGenericErrorRequest( aErrorCodeIOException.ErrCode,
812 rRequest->getContinuations(),
813 bObtainErrorStringOnly,
814 bHasErrorString,
815 rErrorString);
816 return true;
819 loader::CannotActivateFactoryException aCannotActivateFactoryException;
820 if (aAnyRequest >>= aCannotActivateFactoryException)
822 ErrCode nErrorCode = ERRCODE_UUI_CANNOT_ACTIVATE_FACTORY;
823 std::vector< OUString > aArguments;
824 aArguments.push_back( aCannotActivateFactoryException.Message );
826 handleErrorHandlerRequest( task::InteractionClassification_ERROR,
827 nErrorCode,
828 aArguments,
829 rRequest->getContinuations(),
830 bObtainErrorStringOnly,
831 bHasErrorString,
832 rErrorString );
833 return true;
837 ///////////////////////////////////////////////////////////////////
838 // Handle requests which do not have a plain string representation.
839 ///////////////////////////////////////////////////////////////////
840 if (!bObtainErrorStringOnly)
842 if ( handleAuthenticationRequest( rRequest ) )
843 return true;
845 if ( handleCertificateValidationRequest( rRequest ) )
846 return true;
848 ucb::NameClashResolveRequest aNameClashResolveRequest;
849 if (aAnyRequest >>= aNameClashResolveRequest)
851 handleNameClashResolveRequest(aNameClashResolveRequest,
852 rRequest->getContinuations());
853 return true;
856 if ( handleMasterPasswordRequest( rRequest ) )
857 return true;
859 if ( handlePasswordRequest( rRequest ) )
860 return true;
862 if ( handleNoSuchFilterRequest( rRequest ) )
863 return true;
865 if ( handleAmbigousFilterRequest( rRequest ) )
866 return true;
868 if ( handleFilterOptionsRequest( rRequest ) )
869 return true;
871 if ( handleLockedDocumentRequest( rRequest ) )
872 return true;
874 if ( handleChangedByOthersRequest( rRequest ) )
875 return true;
877 if ( handleLockFileIgnoreRequest( rRequest ) )
878 return true;
880 task::DocumentMacroConfirmationRequest aMacroConfirmRequest;
881 if (aAnyRequest >>= aMacroConfirmRequest)
883 handleMacroConfirmRequest(
884 aMacroConfirmRequest.DocumentURL,
885 aMacroConfirmRequest.DocumentStorage,
886 !aMacroConfirmRequest.DocumentVersion.isEmpty() ? aMacroConfirmRequest.DocumentVersion : ODFVER_012_TEXT,
887 aMacroConfirmRequest.DocumentSignatureInformation,
888 rRequest->getContinuations());
889 return true;
892 task::FutureDocumentVersionProductUpdateRequest
893 aProductUpdateRequest;
894 if (aAnyRequest >>= aProductUpdateRequest)
896 handleFutureDocumentVersionUpdateRequest(
897 aProductUpdateRequest,
898 rRequest->getContinuations());
899 return true;
902 ///////////////////////////////////////////////////////////////
903 // Last chance: interaction handlers registered in the configuration
904 ///////////////////////////////////////////////////////////////
906 // typed InteractionHandlers (ooo.Interactions)
907 if ( handleTypedHandlerImplementations( rRequest ) )
908 return true;
910 // legacy configuration (ooo.ucb.InteractionHandlers)
911 if (tryOtherInteractionHandler( rRequest ))
912 return true;
915 // Not handled.
916 return false;
918 catch (std::bad_alloc const &)
920 throw uno::RuntimeException("out of memory",
921 uno::Reference< uno::XInterface >());
923 catch( const uno::RuntimeException& )
925 throw; // allowed to leave here
927 catch( const uno::Exception& )
929 DBG_UNHANDLED_EXCEPTION();
931 return false;
934 void
935 UUIInteractionHelper::getInteractionHandlerList(
936 InteractionHandlerDataList &rdataList)
937 SAL_THROW((uno::RuntimeException))
941 uno::Reference< lang::XMultiServiceFactory > xConfigProv =
942 configuration::theDefaultProvider::get( m_xContext );
944 OUStringBuffer aFullPath;
945 aFullPath.appendAscii(
946 "/org.openoffice.ucb.InteractionHandler/InteractionHandlers" );
948 uno::Sequence< uno::Any > aArguments( 1 );
949 beans::PropertyValue aProperty;
950 aProperty.Name = "nodepath";
951 aProperty.Value <<= aFullPath.makeStringAndClear();
952 aArguments[ 0 ] <<= aProperty;
954 uno::Reference< uno::XInterface > xInterface(
955 xConfigProv->createInstanceWithArguments(
956 "com.sun.star.configuration.ConfigurationAccess" , aArguments ) );
958 if ( !xInterface.is() )
959 throw uno::RuntimeException("unable to instanciate config access",
960 uno::Reference< uno::XInterface >());
962 uno::Reference< container::XNameAccess > xNameAccess(
963 xInterface, uno::UNO_QUERY );
964 if ( !xNameAccess.is() )
965 throw uno::RuntimeException(OUString(
966 "config access does not implement XNameAccess"),
967 uno::Reference< uno::XInterface >());
969 uno::Sequence< OUString > aElems = xNameAccess->getElementNames();
970 const OUString* pElems = aElems.getConstArray();
971 sal_Int32 nCount = aElems.getLength();
973 if ( nCount > 0 )
975 uno::Reference< container::XHierarchicalNameAccess >
976 xHierNameAccess( xInterface, uno::UNO_QUERY );
978 if ( !xHierNameAccess.is() )
979 throw uno::RuntimeException(OUString(
980 "config access does not implement XHierarchicalNameAccess"),
981 uno::Reference< uno::XInterface >());
983 // Iterate over children.
984 for ( sal_Int32 n = 0; n < nCount; ++n )
986 OUStringBuffer aElemBuffer;
987 aElemBuffer.appendAscii( "['" );
988 aElemBuffer.append( pElems[ n ] );
992 InteractionHandlerData aInfo;
994 // Obtain service name.
995 OUStringBuffer aKeyBuffer = aElemBuffer;
996 aKeyBuffer.appendAscii( "']/ServiceName" );
998 OUString aValue;
999 if ( !( xHierNameAccess->getByHierarchicalName(
1000 aKeyBuffer.makeStringAndClear() ) >>= aValue ) )
1002 OSL_FAIL( "GetInteractionHandlerList - "
1003 "Error getting item value!" );
1004 continue;
1007 aInfo.ServiceName = aValue;
1009 // Append info to list.
1010 rdataList.push_back( aInfo );
1012 catch ( container::NoSuchElementException& )
1014 // getByHierarchicalName
1016 OSL_FAIL( "GetInteractionHandlerList - "
1017 "caught NoSuchElementException!" );
1022 catch ( uno::RuntimeException const & )
1024 throw;
1026 catch ( uno::Exception const & )
1028 OSL_FAIL( "GetInteractionHandlerList - Caught Exception!" );
1032 Window *
1033 UUIInteractionHelper::getParentProperty()
1034 SAL_THROW(())
1036 uno::Reference< awt::XWindow > xWindow = getParentXWindow();
1037 if ( xWindow.is() )
1038 return VCLUnoHelper::GetWindow(xWindow);
1040 return 0;
1043 uno::Reference< awt::XWindow>
1044 UUIInteractionHelper::getParentXWindow() const
1045 SAL_THROW(())
1047 return m_xWindowParam;
1050 OUString
1051 UUIInteractionHelper::getContextProperty()
1052 SAL_THROW(())
1054 return m_aContextParam;
1057 uno::Reference< task::XInteractionHandler2 >
1058 UUIInteractionHelper::getInteractionHandler()
1059 SAL_THROW((uno::RuntimeException))
1061 return InteractionHandler::createWithParentAndContext(
1062 m_xContext, m_xWindowParam,
1063 m_aContextParam);
1066 namespace {
1068 sal_uInt16
1069 executeMessageBox(
1070 Window * pParent,
1071 OUString const & rTitle,
1072 OUString const & rMessage,
1073 WinBits nButtonMask )
1074 SAL_THROW((uno::RuntimeException))
1076 SolarMutexGuard aGuard;
1078 MessBox xBox( pParent, nButtonMask, rTitle, rMessage );
1080 sal_uInt16 aResult = xBox.Execute();
1081 switch( aResult )
1083 case RET_OK:
1084 aResult = ERRCODE_BUTTON_OK;
1085 break;
1086 case RET_CANCEL:
1087 aResult = ERRCODE_BUTTON_CANCEL;
1088 break;
1089 case RET_YES:
1090 aResult = ERRCODE_BUTTON_YES;
1091 break;
1092 case RET_NO:
1093 aResult = ERRCODE_BUTTON_NO;
1094 break;
1095 case RET_RETRY:
1096 aResult = ERRCODE_BUTTON_RETRY;
1097 break;
1100 return aResult;
1103 NameClashResolveDialogResult executeSimpleNameClashResolveDialog( Window *pParent,
1104 OUString const & rTargetFolderURL,
1105 OUString const & rClashingName,
1106 OUString & rProposedNewName,
1107 bool bAllowOverwrite )
1109 boost::scoped_ptr< ResMgr > xManager( ResMgr::CreateResMgr( "uui" ) );
1110 if ( !xManager.get() )
1111 return ABORT;
1113 NameClashDialog aDialog( pParent, xManager.get(), rTargetFolderURL,
1114 rClashingName, rProposedNewName, bAllowOverwrite );
1116 NameClashResolveDialogResult eResult = (NameClashResolveDialogResult) aDialog.Execute();
1117 rProposedNewName = aDialog.getNewName();
1118 return eResult;
1121 } // namespace
1123 void
1124 UUIInteractionHelper::handleNameClashResolveRequest(
1125 ucb::NameClashResolveRequest const & rRequest,
1126 uno::Sequence< uno::Reference<
1127 task::XInteractionContinuation > > const & rContinuations)
1128 SAL_THROW((uno::RuntimeException))
1130 OSL_ENSURE(!rRequest.TargetFolderURL.isEmpty(),
1131 "NameClashResolveRequest must not contain empty TargetFolderURL" );
1133 OSL_ENSURE(!rRequest.ClashingName.isEmpty(),
1134 "NameClashResolveRequest must not contain empty ClashingName" );
1136 uno::Reference< task::XInteractionAbort > xAbort;
1137 uno::Reference< ucb::XInteractionSupplyName > xSupplyName;
1138 uno::Reference< ucb::XInteractionReplaceExistingData > xReplaceExistingData;
1139 getContinuations(
1140 rContinuations, &xAbort, &xSupplyName, &xReplaceExistingData);
1142 OSL_ENSURE( xAbort.is(),
1143 "NameClashResolveRequest must contain Abort continuation" );
1145 OSL_ENSURE( xSupplyName.is(),
1146 "NameClashResolveRequest must contain SupplyName continuation" );
1148 NameClashResolveDialogResult eResult = ABORT;
1149 OUString aProposedNewName( rRequest.ProposedNewName );
1151 eResult = executeSimpleNameClashResolveDialog( getParentProperty(),
1152 rRequest.TargetFolderURL,
1153 rRequest.ClashingName,
1154 aProposedNewName,
1155 xReplaceExistingData.is() );
1157 switch ( eResult )
1159 case ABORT:
1160 xAbort->select();
1161 break;
1163 case RENAME:
1164 xSupplyName->setName( aProposedNewName );
1165 xSupplyName->select();
1166 break;
1168 case OVERWRITE:
1169 OSL_ENSURE(
1170 xReplaceExistingData.is(),
1171 "Invalid NameClashResolveDialogResult: OVERWRITE - "
1172 "No ReplaceExistingData continuation available!" );
1173 xReplaceExistingData->select();
1174 break;
1178 void
1179 UUIInteractionHelper::handleGenericErrorRequest(
1180 sal_Int32 nErrorCode,
1181 uno::Sequence< uno::Reference<
1182 task::XInteractionContinuation > > const & rContinuations,
1183 bool bObtainErrorStringOnly,
1184 bool & bHasErrorString,
1185 OUString & rErrorString)
1186 SAL_THROW((uno::RuntimeException))
1188 if (bObtainErrorStringOnly)
1190 bHasErrorString = isInformationalErrorMessageRequest(rContinuations);
1191 if (bHasErrorString)
1193 OUString aErrorString;
1194 ErrorHandler::GetErrorString(nErrorCode, aErrorString);
1195 rErrorString = aErrorString;
1198 else
1200 uno::Reference< task::XInteractionAbort > xAbort;
1201 uno::Reference< task::XInteractionApprove > xApprove;
1202 getContinuations(rContinuations, &xApprove, &xAbort);
1204 // Note: It's important to convert the transported long to the
1205 // required unsigned long value. Otherwhise using as flag field
1206 // can fail ...
1207 ErrCode nError = static_cast< ErrCode >(nErrorCode);
1208 sal_Bool bWarning = !ERRCODE_TOERROR(nError);
1210 if ( nError == ERRCODE_SFX_BROKENSIGNATURE
1211 || nError == ERRCODE_SFX_INCOMPLETE_ENCRYPTION )
1213 // the security warning box needs a special title
1214 OUString aErrorString;
1215 ErrorHandler::GetErrorString( nErrorCode, aErrorString );
1217 boost::scoped_ptr< ResMgr > xManager(
1218 ResMgr::CreateResMgr( "uui" ) );
1219 OUString aTitle( utl::ConfigManager::getProductName() );
1221 OUString aErrTitle
1222 = ResId( nError == ERRCODE_SFX_BROKENSIGNATURE
1223 ? STR_WARNING_BROKENSIGNATURE_TITLE
1224 : STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE,
1225 *xManager.get() ).toString();
1227 if ( !aTitle.isEmpty() && !aErrTitle.isEmpty() )
1228 aTitle += " - " ;
1229 aTitle += aErrTitle;
1231 executeMessageBox(
1232 getParentProperty(), aTitle, aErrorString, WB_OK );
1234 else
1235 ErrorHandler::HandleError(nErrorCode);
1237 if (xApprove.is() && bWarning)
1238 xApprove->select();
1239 else if (xAbort.is())
1240 xAbort->select();
1244 void
1245 UUIInteractionHelper::handleMacroConfirmRequest(
1246 const OUString& aDocumentURL,
1247 const uno::Reference< embed::XStorage >& xZipStorage,
1248 const OUString& aDocumentVersion,
1249 const uno::Sequence< security::DocumentSignatureInformation > aSignInfo,
1250 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
1251 rContinuations )
1252 SAL_THROW((uno::RuntimeException))
1254 uno::Reference< task::XInteractionAbort > xAbort;
1255 uno::Reference< task::XInteractionApprove > xApprove;
1256 getContinuations( rContinuations, &xApprove, &xAbort );
1258 bool bApprove = false;
1260 boost::scoped_ptr< ResMgr > pResMgr( ResMgr::CreateResMgr( "uui" ) );
1261 if ( pResMgr.get() )
1263 bool bShowSignatures = aSignInfo.getLength() > 0;
1264 MacroWarning aWarning(
1265 getParentProperty(), bShowSignatures, *pResMgr.get() );
1267 aWarning.SetDocumentURL( aDocumentURL );
1268 if ( aSignInfo.getLength() > 1 )
1270 aWarning.SetStorage( xZipStorage, aDocumentVersion, aSignInfo );
1272 else if ( aSignInfo.getLength() == 1 )
1274 aWarning.SetCertificate( aSignInfo[ 0 ].Signer );
1277 bApprove = aWarning.Execute() == RET_OK;
1280 if ( bApprove && xApprove.is() )
1281 xApprove->select();
1282 else if ( xAbort.is() )
1283 xAbort->select();
1286 void
1287 UUIInteractionHelper::handleFutureDocumentVersionUpdateRequest(
1288 const task::FutureDocumentVersionProductUpdateRequest& _rRequest,
1289 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
1290 rContinuations )
1291 SAL_THROW((uno::RuntimeException))
1293 uno::Reference< task::XInteractionAbort > xAbort;
1294 uno::Reference< task::XInteractionApprove > xApprove;
1295 uno::Reference< task::XInteractionAskLater > xAskLater;
1296 getContinuations( rContinuations, &xApprove, &xAbort, &xAskLater );
1298 short nResult = RET_CANCEL;
1300 static bool s_bDeferredToNextSession = false;
1301 // TODO: this static variable is somewhat hacky. Formerly (before the dialog was moved from SFX2 to the
1302 // interaction handler implementation), this was stored in SFX_APP()'s impl structure, in member
1303 // bODFVersionWarningLater. Of course, we do not have access to it here.
1305 // A proper solution which I would envision would be:
1306 // - There's a central implementation (this one here) of css.task.InteractionHandler
1307 // - There's a configuration which maps UNO names to service names
1308 // - If the handler is confronted with a request, it tries to find the name of the UNO structure describing
1309 // the request in the said configuration.
1310 // - If an entry is found, then
1311 // - the respective service is instantiated
1312 // - the component is queried for css.task.XInteractionHandler, and the request is delegated
1313 // - if no entry is found, then the request is silenced (with calling the AbortContinuation, if possible)
1314 // This way, the FutureDocumentVersionProductUpdateRequest could be handled in SFX (or any other
1315 // suitable place), again, and we would only have one place where we remember the s_bDeferredToNextSession
1316 // flag.
1318 // Note: The above pattern has been implemented in CWS autorecovery. Now the remaining task is to move the
1319 // handling of this interaction to SFX, again.
1321 if ( !s_bDeferredToNextSession )
1323 boost::scoped_ptr< ResMgr > pResMgr( ResMgr::CreateResMgr( "uui" ) );
1324 if ( pResMgr.get() )
1326 ::uui::NewerVersionWarningDialog aDialog(
1327 getParentProperty(),
1328 _rRequest.DocumentODFVersion,
1329 *pResMgr.get() );
1330 nResult = aDialog.Execute();
1334 switch ( nResult )
1336 case RET_OK:
1337 if ( xApprove.is() )
1338 xApprove->select();
1339 break;
1340 case RET_CANCEL:
1341 if ( xAbort.is() )
1342 xAbort->select();
1343 break;
1344 case RET_ASK_LATER:
1345 if ( xAskLater.is() )
1346 xAskLater->select();
1347 s_bDeferredToNextSession = true;
1348 break;
1349 default:
1350 OSL_FAIL( "UUIInteractionHelper::handleFutureDocumentVersionUpdateRequest: "
1351 "unexpected dialog return value!" );
1352 break;
1356 void
1357 UUIInteractionHelper::handleBrokenPackageRequest(
1358 std::vector< OUString > const & rArguments,
1359 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
1360 rContinuations,
1361 bool bObtainErrorStringOnly,
1362 bool & bHasErrorString,
1363 OUString & rErrorString)
1364 SAL_THROW((uno::RuntimeException))
1366 if (bObtainErrorStringOnly)
1368 bHasErrorString = isInformationalErrorMessageRequest(rContinuations);
1369 if (!bHasErrorString)
1370 return;
1373 uno::Reference< task::XInteractionApprove > xApprove;
1374 uno::Reference< task::XInteractionDisapprove > xDisapprove;
1375 uno::Reference< task::XInteractionAbort > xAbort;
1376 getContinuations(rContinuations, &xApprove, &xDisapprove, &xAbort);
1378 ErrCode nErrorCode;
1379 if( xApprove.is() && xDisapprove.is() )
1381 nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE;
1383 else if ( xAbort.is() )
1385 nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE_CANTREPAIR;
1387 else
1388 return;
1390 OUString aMessage;
1392 SolarMutexGuard aGuard;
1393 boost::scoped_ptr< ResMgr > xManager(ResMgr::CreateResMgr("uui"));
1394 if (!xManager.get())
1395 return;
1397 ResId aResId( RID_UUI_ERRHDL, *xManager.get() );
1398 if ( !ErrorResource(aResId).getString(nErrorCode, aMessage) )
1399 return;
1402 aMessage = replaceMessageWithArguments( aMessage, rArguments );
1404 if (bObtainErrorStringOnly)
1406 rErrorString = aMessage;
1407 return;
1410 WinBits nButtonMask;
1411 if( xApprove.is() && xDisapprove.is() )
1413 nButtonMask = WB_YES_NO | WB_DEF_YES;
1415 else if ( xAbort.is() )
1417 nButtonMask = WB_OK;
1419 else
1420 return;
1422 OUString title(
1423 utl::ConfigManager::getProductName() +
1424 OUString( " " ) +
1425 utl::ConfigManager::getProductVersion() );
1427 switch (
1428 executeMessageBox( getParentProperty(), title, aMessage, nButtonMask ) )
1430 case ERRCODE_BUTTON_OK:
1431 OSL_ENSURE( xAbort.is(), "unexpected situation" );
1432 if (xAbort.is())
1433 xAbort->select();
1434 break;
1436 case ERRCODE_BUTTON_NO:
1437 OSL_ENSURE(xDisapprove.is(), "unexpected situation");
1438 if (xDisapprove.is())
1439 xDisapprove->select();
1440 break;
1442 case ERRCODE_BUTTON_YES:
1443 OSL_ENSURE(xApprove.is(), "unexpected situation");
1444 if (xApprove.is())
1445 xApprove->select();
1446 break;
1450 //=========================================================================
1451 // ErrorResource Implementation
1452 //=========================================================================
1454 bool
1455 ErrorResource::getString(ErrCode nErrorCode, OUString &rString)
1456 const SAL_THROW(())
1458 ResId aResId(static_cast< sal_uInt16 >(nErrorCode & ERRCODE_RES_MASK),
1459 *m_pResMgr);
1460 aResId.SetRT(RSC_STRING);
1461 if (!IsAvailableRes(aResId))
1462 return false;
1463 aResId.SetAutoRelease(false);
1464 rString = aResId.toString();
1465 m_pResMgr->PopContext();
1466 return true;
1469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */