1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <memory> 29 30 #include "com/sun/star/awt/XWindow.hpp" 31 #include "com/sun/star/beans/PropertyValue.hpp" 32 #include "com/sun/star/configuration/backend/MergeRecoveryRequest.hpp" 33 #include "com/sun/star/configuration/backend/StratumCreationException.hpp" 34 #include "com/sun/star/container/XHierarchicalNameAccess.hpp" 35 #include "com/sun/star/document/BrokenPackageRequest.hpp" 36 #include "com/sun/star/task/DocumentMacroConfirmationRequest.hpp" 37 #include "com/sun/star/java/WrongJavaVersionException.hpp" 38 #include "com/sun/star/lang/XInitialization.hpp" 39 #include "com/sun/star/lang/XMultiServiceFactory.hpp" 40 #include "com/sun/star/script/ModuleSizeExceededRequest.hpp" 41 #include "com/sun/star/sync2/BadPartnershipException.hpp" 42 #include "com/sun/star/task/ErrorCodeIOException.hpp" 43 #include "com/sun/star/task/ErrorCodeRequest.hpp" 44 #include "com/sun/star/task/FutureDocumentVersionProductUpdateRequest.hpp" 45 #include "com/sun/star/task/XInteractionAbort.hpp" 46 #include "com/sun/star/task/XInteractionApprove.hpp" 47 #include "com/sun/star/task/XInteractionAskLater.hpp" 48 #include "com/sun/star/task/XInteractionDisapprove.hpp" 49 #include "com/sun/star/task/XInteractionHandler2.hpp" 50 #include "com/sun/star/task/XInteractionRequest.hpp" 51 #include "com/sun/star/task/XInteractionRetry.hpp" 52 #include "com/sun/star/ucb/InteractiveAppException.hpp" 53 #include "com/sun/star/ucb/InteractiveCHAOSException.hpp" 54 #include "com/sun/star/ucb/InteractiveLockingLockedException.hpp" 55 #include "com/sun/star/ucb/InteractiveLockingNotLockedException.hpp" 56 #include "com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp" 57 #include "com/sun/star/ucb/InteractiveNetworkConnectException.hpp" 58 #include "com/sun/star/ucb/InteractiveNetworkOffLineException.hpp" 59 #include "com/sun/star/ucb/InteractiveNetworkReadException.hpp" 60 #include "com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp" 61 #include "com/sun/star/ucb/InteractiveNetworkWriteException.hpp" 62 #include "com/sun/star/ucb/InteractiveWrongMediumException.hpp" 63 #include "com/sun/star/ucb/NameClashException.hpp" 64 #include "com/sun/star/ucb/NameClashResolveRequest.hpp" 65 #include "com/sun/star/ucb/UnsupportedNameClashException.hpp" 66 #include "com/sun/star/ucb/XInteractionReplaceExistingData.hpp" 67 #include "com/sun/star/ucb/XInteractionSupplyName.hpp" 68 #include "com/sun/star/xforms/InvalidDataOnSubmitException.hpp" 69 70 #include "osl/conditn.hxx" 71 #include "tools/rcid.h" // RSC_STRING 72 #include "tools/errinf.hxx" // ErrorHandler, ErrorContext, ... 73 #include "vos/mutex.hxx" 74 #include "tools/diagnose_ex.h" 75 #include "comphelper/documentconstants.hxx" // ODFVER_012_TEXT 76 #include "svtools/sfxecode.hxx" // ERRCODE_SFX_* 77 #include "vcl/msgbox.hxx" 78 #include "vcl/svapp.hxx" 79 #include "unotools/configmgr.hxx" 80 #include "toolkit/helper/vclunohelper.hxx" 81 #include "comphelper/namedvaluecollection.hxx" 82 #include "typelib/typedescription.hxx" 83 #include "unotools/confignode.hxx" 84 85 #include "ids.hrc" 86 87 #include "getcontinuations.hxx" 88 #include "secmacrowarnings.hxx" 89 #include "newerverwarn.hxx" 90 91 #include "iahndl.hxx" 92 #include "nameclashdlg.hxx" 93 94 /** === begin UNO using === **/ 95 using ::com::sun::star::uno::Sequence; 96 using ::com::sun::star::uno::UNO_QUERY; 97 using ::com::sun::star::uno::Reference; 98 using ::com::sun::star::task::XInteractionContinuation; 99 using ::com::sun::star::task::XInteractionAbort; 100 using ::com::sun::star::task::XInteractionApprove; 101 using ::com::sun::star::task::XInteractionAskLater; 102 using ::com::sun::star::task::FutureDocumentVersionProductUpdateRequest; 103 using ::com::sun::star::uno::XInterface; 104 using ::com::sun::star::lang::XInitialization; 105 using ::com::sun::star::uno::UNO_QUERY_THROW; 106 using ::com::sun::star::task::XInteractionHandler2; 107 using ::com::sun::star::uno::Exception; 108 using ::com::sun::star::uno::Any; 109 using ::com::sun::star::task::XInteractionRequest; 110 using ::com::sun::star::lang::XMultiServiceFactory; 111 /** === end UNO using === **/ 112 113 using namespace ::com::sun::star; 114 115 namespace { 116 117 class HandleData : public osl::Condition 118 { 119 public: 120 HandleData( 121 uno::Reference< task::XInteractionRequest > const & rRequest) 122 : osl::Condition(), 123 m_rRequest(rRequest), 124 bHandled( false ) 125 { 126 } 127 uno::Reference< task::XInteractionRequest > m_rRequest; 128 bool bHandled; 129 beans::Optional< rtl::OUString > m_aResult; 130 }; 131 132 } /* namespace */ 133 134 UUIInteractionHelper::UUIInteractionHelper( 135 uno::Reference< lang::XMultiServiceFactory > const & rServiceFactory, 136 uno::Sequence< uno::Any > const & rArguments) 137 SAL_THROW(()): 138 m_xServiceFactory(rServiceFactory), 139 m_aProperties(rArguments) 140 { 141 } 142 143 UUIInteractionHelper::UUIInteractionHelper( 144 uno::Reference< lang::XMultiServiceFactory > const & rServiceFactory) 145 SAL_THROW(()): 146 m_xServiceFactory(rServiceFactory) 147 { 148 } 149 150 UUIInteractionHelper::~UUIInteractionHelper() 151 { 152 } 153 154 long 155 UUIInteractionHelper::handlerequest( 156 void* pHandleData, void* pInteractionHelper) 157 { 158 HandleData* pHND 159 = static_cast< HandleData * >(pHandleData); 160 UUIInteractionHelper* pUUI 161 = static_cast< UUIInteractionHelper * >(pInteractionHelper); 162 bool bDummy = false; 163 rtl::OUString aDummy; 164 pHND->bHandled 165 = pUUI->handleRequest_impl(pHND->m_rRequest, false, bDummy, aDummy); 166 pHND->set(); 167 return 0; 168 } 169 170 bool 171 UUIInteractionHelper::handleRequest( 172 uno::Reference< task::XInteractionRequest > const & rRequest) 173 SAL_THROW((uno::RuntimeException)) 174 { 175 Application* pApp = 0; 176 if( 177 // be aware,it is the same type 178 static_cast< oslThreadIdentifier >( 179 Application::GetMainThreadIdentifier()) 180 != osl_getThreadIdentifier(NULL) 181 && 182 (pApp = GetpApp()) 183 != 0 184 ) { 185 // we are not in the main thread, let it handle that stuff 186 HandleData aHD(rRequest); 187 Link aLink(&aHD,handlerequest); 188 pApp->PostUserEvent(aLink,this); 189 sal_uLong locks = Application::ReleaseSolarMutex(); 190 aHD.wait(); 191 Application::AcquireSolarMutex(locks); 192 return aHD.bHandled; 193 } 194 else 195 { 196 bool bDummy = false; 197 rtl::OUString aDummy; 198 return handleRequest_impl(rRequest, false, bDummy, aDummy); 199 } 200 } 201 202 long 203 UUIInteractionHelper::getstringfromrequest( 204 void* pHandleData,void* pInteractionHelper) 205 { 206 HandleData* pHND = (HandleData*) pHandleData; 207 UUIInteractionHelper* pUUI = (UUIInteractionHelper*) pInteractionHelper; 208 pHND->m_aResult = pUUI->getStringFromRequest_impl(pHND->m_rRequest); 209 pHND->set(); 210 return 0; 211 } 212 213 beans::Optional< rtl::OUString > 214 UUIInteractionHelper::getStringFromRequest_impl( 215 uno::Reference< task::XInteractionRequest > const & rRequest) 216 SAL_THROW((uno::RuntimeException)) 217 { 218 bool bSuccess = false; 219 rtl::OUString aMessage; 220 handleRequest_impl(rRequest, true, bSuccess, aMessage); 221 222 OSL_ENSURE(bSuccess || 223 !isInformationalErrorMessageRequest( 224 rRequest->getContinuations()), 225 "Interaction request is a candidate for a string representation." 226 "Please implement!"); 227 228 return beans::Optional< rtl::OUString >(bSuccess, aMessage); 229 } 230 231 beans::Optional< rtl::OUString > 232 UUIInteractionHelper::getStringFromRequest( 233 uno::Reference< task::XInteractionRequest > const & rRequest) 234 SAL_THROW((uno::RuntimeException)) 235 { 236 Application* pApp = 0; 237 if( 238 // be aware,it is the same type 239 static_cast< oslThreadIdentifier >( 240 Application::GetMainThreadIdentifier()) 241 != osl_getThreadIdentifier(NULL) 242 && 243 (pApp = GetpApp()) 244 != 0 245 ) { 246 // we are not in the main thread, let it handle that stuff 247 HandleData aHD(rRequest); 248 Link aLink(&aHD,getstringfromrequest); 249 pApp->PostUserEvent(aLink,this); 250 sal_uLong locks = Application::ReleaseSolarMutex(); 251 aHD.wait(); 252 Application::AcquireSolarMutex(locks); 253 return aHD.m_aResult; 254 } 255 else 256 return getStringFromRequest_impl(rRequest); 257 } 258 259 ::rtl::OUString 260 UUIInteractionHelper::replaceMessageWithArguments( 261 ::rtl::OUString aMessage, 262 std::vector< rtl::OUString > const & rArguments ) 263 { 264 for (sal_Int32 i = 0;;) 265 { 266 i = aMessage. 267 indexOf(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("$(ARG")), i); 268 if (i == -1) 269 break; 270 if (aMessage.getLength() - i >= RTL_CONSTASCII_LENGTH("$(ARGx)") 271 && aMessage.getStr()[i + RTL_CONSTASCII_LENGTH("$(ARGx")] == ')') 272 { 273 sal_Unicode c 274 = aMessage.getStr()[i + RTL_CONSTASCII_LENGTH("$(ARG")]; 275 if (c >= '1' && c <= '2') 276 { 277 std::vector< rtl::OUString >::size_type nIndex 278 = static_cast< std::vector< rtl::OUString >::size_type >( 279 c - '1'); 280 if (nIndex < rArguments.size()) 281 { 282 aMessage 283 = aMessage.replaceAt(i, 284 RTL_CONSTASCII_LENGTH("$(ARGx)"), 285 rArguments[nIndex]); 286 i += rArguments[nIndex].getLength(); 287 continue; 288 } 289 } 290 } 291 ++i; 292 } 293 294 return aMessage; 295 } 296 297 bool 298 UUIInteractionHelper::isInformationalErrorMessageRequest( 299 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & 300 rContinuations) 301 { 302 // Only requests with a single continuation (user has no choice, request 303 // is just informational) 304 if (rContinuations.getLength() != 1 ) 305 return false; 306 307 // user can only abort or approve, all other continuations are not 308 // considered to be informational. 309 uno::Reference< task::XInteractionApprove > xApprove( 310 rContinuations[0], uno::UNO_QUERY); 311 if (xApprove.is()) 312 return true; 313 314 uno::Reference< task::XInteractionAbort > xAbort( 315 rContinuations[0], uno::UNO_QUERY); 316 if (xAbort.is()) 317 return true; 318 319 return false; 320 } 321 322 bool 323 UUIInteractionHelper::tryOtherInteractionHandler( 324 uno::Reference< task::XInteractionRequest > const & rRequest) 325 SAL_THROW((uno::RuntimeException)) 326 { 327 InteractionHandlerDataList dataList; 328 getInteractionHandlerList(dataList); 329 330 InteractionHandlerDataList::const_iterator aEnd(dataList.end()); 331 for (InteractionHandlerDataList::const_iterator aIt(dataList.begin()); 332 aIt != aEnd; 333 ++aIt) 334 { 335 if ( handleCustomRequest( rRequest, aIt->ServiceName ) ) 336 return true; 337 } 338 return false; 339 } 340 341 namespace 342 { 343 // ................................................................................................................. 344 static bool lcl_matchesRequest( const Any& i_rRequest, const ::rtl::OUString& i_rTypeName, const ::rtl::OUString& i_rPropagation ) 345 { 346 const ::com::sun::star::uno::TypeDescription aTypeDesc( i_rTypeName ); 347 const typelib_TypeDescription* pTypeDesc = aTypeDesc.get(); 348 if ( !pTypeDesc || !pTypeDesc->pWeakRef ) 349 { 350 #if OSL_DEBUG_LEVEL > 0 351 ::rtl::OStringBuffer aMessage; 352 aMessage.append( "no type found for '" ); 353 aMessage.append( ::rtl::OUStringToOString( i_rTypeName, RTL_TEXTENCODING_UTF8 ) ); 354 aMessage.append( "'" ); 355 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() ); 356 #endif 357 return false; 358 } 359 const ::com::sun::star::uno::Type aType( pTypeDesc->pWeakRef ); 360 361 const bool bExactMatch = ( i_rPropagation.compareToAscii( "named-only" ) == 0 ); 362 if ( bExactMatch ) 363 return i_rRequest.getValueType().equals( aType ); 364 365 return i_rRequest.isExtractableTo( aType ); 366 } 367 } 368 369 // --------------------------------------------------------------------------------------------------------------------- 370 bool UUIInteractionHelper::handleCustomRequest( const Reference< XInteractionRequest >& i_rRequest, const ::rtl::OUString& i_rServiceName ) const 371 { 372 try 373 { 374 Reference< XInteractionHandler2 > xHandler( m_xServiceFactory->createInstance( i_rServiceName ), UNO_QUERY_THROW ); 375 376 Reference< XInitialization > xHandlerInit( xHandler, UNO_QUERY ); 377 if ( xHandlerInit.is() ) 378 { 379 ::comphelper::NamedValueCollection aInitArgs; 380 aInitArgs.put( "Parent", getParentXWindow() ); 381 xHandlerInit->initialize( aInitArgs.getWrappedPropertyValues() ); 382 } 383 384 if ( xHandler->handleInteractionRequest( i_rRequest ) ) 385 return true; 386 } 387 catch( const Exception& ) 388 { 389 DBG_UNHANDLED_EXCEPTION(); 390 } 391 return false; 392 } 393 394 // --------------------------------------------------------------------------------------------------------------------- 395 bool UUIInteractionHelper::handleTypedHandlerImplementations( Reference< XInteractionRequest > const & rRequest ) 396 { 397 // the request 398 const Any aRequest( rRequest->getRequest() ); 399 400 const StringHashMap::const_iterator aCacheHitTest = m_aTypedCustomHandlers.find( aRequest.getValueTypeName() ); 401 if ( aCacheHitTest != m_aTypedCustomHandlers.end() ) 402 return handleCustomRequest( rRequest, aCacheHitTest->second ); 403 404 // the base registration node for "typed" interaction handlers 405 const ::utl::OConfigurationTreeRoot aConfigRoot( ::utl::OConfigurationTreeRoot::createWithServiceFactory( 406 m_xServiceFactory, 407 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Interaction/InteractionHandlers" ) ), 408 -1, 409 ::utl::OConfigurationTreeRoot::CM_READONLY 410 ) ); 411 412 // loop through all registered implementations 413 const Sequence< ::rtl::OUString > aRegisteredHandlers( aConfigRoot.getNodeNames() ); 414 const ::rtl::OUString* pHandlerName = aRegisteredHandlers.getConstArray(); 415 const ::rtl::OUString* pHandlersEnd = aRegisteredHandlers.getConstArray() + aRegisteredHandlers.getLength(); 416 for ( ; pHandlerName != pHandlersEnd; ++pHandlerName ) 417 { 418 const ::utl::OConfigurationNode aHandlerNode( aConfigRoot.openNode( *pHandlerName ) ); 419 const ::utl::OConfigurationNode aTypesNode( aHandlerNode.openNode( "HandledRequestTypes" ) ); 420 421 // loop through all the types which the current handler is registered for 422 const Sequence< ::rtl::OUString > aHandledTypes( aTypesNode.getNodeNames() ); 423 const ::rtl::OUString* pType = aHandledTypes.getConstArray(); 424 const ::rtl::OUString* pTypesEnd = aHandledTypes.getConstArray() + aHandledTypes.getLength(); 425 for ( ; pType != pTypesEnd; ++pType ) 426 { 427 // the UNO type is the node name 428 ::utl::OConfigurationNode aType( aTypesNode.openNode( *pType ) ); 429 // and there's a child denoting how the responsibility propagates 430 ::rtl::OUString sPropagation; 431 OSL_VERIFY( aType.getNodeValue( "Propagation" ) >>= sPropagation ); 432 if ( lcl_matchesRequest( aRequest, *pType, sPropagation ) ) 433 { 434 // retrieve the service/implementation name of the handler 435 ::rtl::OUString sServiceName; 436 OSL_VERIFY( aHandlerNode.getNodeValue( "ServiceName" ) >>= sServiceName ); 437 // cache the information who feels responsible for requests of this type 438 m_aTypedCustomHandlers[ aRequest.getValueTypeName() ] = sServiceName; 439 // actually handle the request 440 return handleCustomRequest( rRequest, sServiceName ); 441 } 442 } 443 } 444 445 return false; 446 } 447 448 bool 449 UUIInteractionHelper::handleRequest_impl( 450 uno::Reference< task::XInteractionRequest > const & rRequest, 451 bool bObtainErrorStringOnly, 452 bool & bHasErrorString, 453 rtl::OUString & rErrorString) 454 SAL_THROW((uno::RuntimeException)) 455 { 456 try 457 { 458 if (!rRequest.is()) 459 return false; 460 461 uno::Any aAnyRequest(rRequest->getRequest()); 462 463 script::ModuleSizeExceededRequest aModSizeException; 464 if (aAnyRequest >>= aModSizeException ) 465 { 466 ErrCode nErrorCode = ERRCODE_UUI_IO_MODULESIZEEXCEEDED; 467 std::vector< rtl::OUString > aArguments; 468 uno::Sequence< rtl::OUString > sModules 469 = aModSizeException.Names; 470 if ( sModules.getLength() ) 471 { 472 rtl::OUString aName; 473 for ( sal_Int32 index=0; index< sModules.getLength(); ++index ) 474 { 475 if ( index ) 476 aName = aName + rtl::OUString( ',' ) + sModules[index]; 477 else 478 aName = sModules[index]; // 1st name 479 } 480 aArguments.push_back( aName ); 481 } 482 handleErrorHandlerRequest( task::InteractionClassification_WARNING, 483 nErrorCode, 484 aArguments, 485 rRequest->getContinuations(), 486 bObtainErrorStringOnly, 487 bHasErrorString, 488 rErrorString); 489 return true; 490 } 491 492 ucb::NameClashException aNCException; 493 if (aAnyRequest >>= aNCException) 494 { 495 ErrCode nErrorCode = ERRCODE_UUI_IO_TARGETALREADYEXISTS; 496 std::vector< rtl::OUString > aArguments; 497 498 if( aNCException.Name.getLength() ) 499 { 500 nErrorCode = ERRCODE_UUI_IO_ALREADYEXISTS; 501 aArguments.push_back( aNCException.Name ); 502 } 503 504 handleErrorHandlerRequest( aNCException.Classification, 505 nErrorCode, 506 aArguments, 507 rRequest->getContinuations(), 508 bObtainErrorStringOnly, 509 bHasErrorString, 510 rErrorString); 511 return true; 512 } 513 514 ucb::UnsupportedNameClashException aUORequest; 515 if (aAnyRequest >>= aUORequest) 516 { 517 ErrCode nErrorCode = ERRCODE_UUI_IO_UNSUPPORTEDOVERWRITE; 518 std::vector< rtl::OUString > aArguments; 519 520 uno::Reference< task::XInteractionApprove > xApprove; 521 uno::Reference< task::XInteractionDisapprove > xDisapprove; 522 getContinuations( 523 rRequest->getContinuations(), &xApprove, &xDisapprove); 524 525 if ( xApprove.is() && xDisapprove.is() ) 526 { 527 handleErrorHandlerRequest( task::InteractionClassification_QUERY, 528 nErrorCode, 529 aArguments, 530 rRequest->getContinuations(), 531 bObtainErrorStringOnly, 532 bHasErrorString, 533 rErrorString); 534 } 535 return true; 536 } 537 538 if ( handleInteractiveIOException( rRequest, 539 bObtainErrorStringOnly, 540 bHasErrorString, 541 rErrorString ) ) 542 return true; 543 544 ucb::InteractiveAppException aAppException; 545 if (aAnyRequest >>= aAppException) 546 { 547 std::vector< rtl::OUString > aArguments; 548 handleErrorHandlerRequest( aAppException.Classification, 549 aAppException.Code, 550 aArguments, 551 rRequest->getContinuations(), 552 bObtainErrorStringOnly, 553 bHasErrorString, 554 rErrorString); 555 return true; 556 } 557 558 ucb::InteractiveNetworkException aNetworkException; 559 if (aAnyRequest >>= aNetworkException) 560 { 561 ErrCode nErrorCode; 562 std::vector< rtl::OUString > aArguments; 563 ucb::InteractiveNetworkOffLineException aOffLineException; 564 ucb::InteractiveNetworkResolveNameException aResolveNameException; 565 ucb::InteractiveNetworkConnectException aConnectException; 566 ucb::InteractiveNetworkReadException aReadException; 567 ucb::InteractiveNetworkWriteException aWriteException; 568 if (aAnyRequest >>= aOffLineException) 569 nErrorCode = ERRCODE_INET_OFFLINE; 570 else if (aAnyRequest >>= aResolveNameException) 571 { 572 nErrorCode = ERRCODE_INET_NAME_RESOLVE; 573 aArguments.push_back(aResolveNameException.Server); 574 } 575 else if (aAnyRequest >>= aConnectException) 576 { 577 nErrorCode = ERRCODE_INET_CONNECT; 578 aArguments.push_back(aConnectException.Server); 579 } 580 else if (aAnyRequest >>= aReadException) 581 { 582 nErrorCode = ERRCODE_INET_READ; 583 aArguments.push_back(aReadException.Diagnostic); 584 } 585 else if (aAnyRequest >>= aWriteException) 586 { 587 nErrorCode = ERRCODE_INET_WRITE; 588 aArguments.push_back(aWriteException.Diagnostic); 589 } 590 else 591 nErrorCode = ERRCODE_INET_GENERAL; 592 593 handleErrorHandlerRequest(aNetworkException.Classification, 594 nErrorCode, 595 aArguments, 596 rRequest->getContinuations(), 597 bObtainErrorStringOnly, 598 bHasErrorString, 599 rErrorString); 600 return true; 601 } 602 603 ucb::InteractiveCHAOSException aChaosException; 604 if (aAnyRequest >>= aChaosException) 605 { 606 std::vector< rtl::OUString > aArguments; 607 sal_Int32 nCount 608 = std::min< sal_Int32 >(aChaosException.Arguments.getLength(), 609 2); 610 aArguments. 611 reserve(static_cast< std::vector< rtl::OUString >::size_type >( 612 nCount)); 613 for (sal_Int32 i = 0; i < nCount; ++i) 614 aArguments.push_back(aChaosException.Arguments[i]); 615 handleErrorHandlerRequest(aChaosException.Classification, 616 aChaosException.ID, 617 aArguments, 618 rRequest->getContinuations(), 619 bObtainErrorStringOnly, 620 bHasErrorString, 621 rErrorString); 622 return true; 623 } 624 625 ucb::InteractiveWrongMediumException aWrongMediumException; 626 if (aAnyRequest >>= aWrongMediumException) 627 { 628 sal_Int32 nMedium = 0; 629 aWrongMediumException.Medium >>= nMedium; 630 std::vector< rtl::OUString > aArguments; 631 aArguments.push_back(UniString::CreateFromInt32(nMedium + 1)); 632 handleErrorHandlerRequest(aWrongMediumException.Classification, 633 ERRCODE_UUI_WRONGMEDIUM, 634 aArguments, 635 rRequest->getContinuations(), 636 bObtainErrorStringOnly, 637 bHasErrorString, 638 rErrorString); 639 return true; 640 } 641 642 java::WrongJavaVersionException aWrongJavaVersionException; 643 if (aAnyRequest >>= aWrongJavaVersionException) 644 { 645 ErrCode nErrorCode; 646 std::vector< rtl::OUString > aArguments; 647 if (aWrongJavaVersionException.DetectedVersion.getLength() == 0) 648 if (aWrongJavaVersionException.LowestSupportedVersion. 649 getLength() 650 == 0) 651 nErrorCode = ERRCODE_UUI_WRONGJAVA; 652 else 653 { 654 nErrorCode = ERRCODE_UUI_WRONGJAVA_MIN; 655 aArguments.push_back(aWrongJavaVersionException. 656 LowestSupportedVersion); 657 } 658 else if (aWrongJavaVersionException.LowestSupportedVersion. 659 getLength() 660 == 0) 661 { 662 nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION; 663 aArguments.push_back(aWrongJavaVersionException. 664 DetectedVersion); 665 } 666 else 667 { 668 nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION_MIN; 669 aArguments.reserve(2); 670 aArguments.push_back(aWrongJavaVersionException. 671 DetectedVersion); 672 aArguments.push_back(aWrongJavaVersionException. 673 LowestSupportedVersion); 674 } 675 handleErrorHandlerRequest(task::InteractionClassification_ERROR, 676 nErrorCode, 677 aArguments, 678 rRequest->getContinuations(), 679 bObtainErrorStringOnly, 680 bHasErrorString, 681 rErrorString); 682 return true; 683 } 684 685 sync2::BadPartnershipException aBadPartnershipException; 686 if (aAnyRequest >>= aBadPartnershipException) 687 { 688 ErrCode nErrorCode; 689 std::vector< rtl::OUString > aArguments; 690 if (aBadPartnershipException.Partnership.getLength() == 0) 691 nErrorCode = ERRCODE_UUI_BADPARTNERSHIP; 692 else 693 { 694 nErrorCode = ERRCODE_UUI_BADPARTNERSHIP_NAME; 695 aArguments.push_back(aBadPartnershipException.Partnership); 696 } 697 handleErrorHandlerRequest(task::InteractionClassification_ERROR, 698 nErrorCode, 699 aArguments, 700 rRequest->getContinuations(), 701 bObtainErrorStringOnly, 702 bHasErrorString, 703 rErrorString); 704 return true; 705 } 706 707 configuration::backend::MergeRecoveryRequest aMergeRecoveryRequest; 708 if (aAnyRequest >>= aMergeRecoveryRequest) 709 { 710 ErrCode nErrorCode = aMergeRecoveryRequest.IsRemovalRequest 711 ? ERRCODE_UUI_CONFIGURATION_BROKENDATA_WITHREMOVE 712 : ERRCODE_UUI_CONFIGURATION_BROKENDATA_NOREMOVE; 713 714 std::vector< rtl::OUString > aArguments; 715 aArguments.push_back(aMergeRecoveryRequest.ErrorLayerId); 716 717 handleErrorHandlerRequest(task::InteractionClassification_ERROR, 718 nErrorCode, 719 aArguments, 720 rRequest->getContinuations(), 721 bObtainErrorStringOnly, 722 bHasErrorString, 723 rErrorString); 724 return true; 725 } 726 727 configuration::backend::StratumCreationException 728 aStratumCreationException; 729 730 if (aAnyRequest >>= aStratumCreationException) 731 { 732 const ErrCode nErrorCode = ERRCODE_UUI_CONFIGURATION_BACKENDMISSING; 733 734 rtl::OUString aStratum = aStratumCreationException.StratumData; 735 if (aStratum.getLength() == 0) 736 aStratum = aStratumCreationException.StratumService; 737 738 std::vector< rtl::OUString > aArguments; 739 aArguments.push_back(aStratum); 740 741 handleErrorHandlerRequest(task::InteractionClassification_ERROR, 742 nErrorCode, 743 aArguments, 744 rRequest->getContinuations(), 745 bObtainErrorStringOnly, 746 bHasErrorString, 747 rErrorString); 748 return true; 749 } 750 751 xforms::InvalidDataOnSubmitException aInvalidDataOnSubmitException; 752 if (aAnyRequest >>= aInvalidDataOnSubmitException) 753 { 754 const ErrCode nErrorCode = 755 ERRCODE_UUI_INVALID_XFORMS_SUBMISSION_DATA; 756 757 std::vector< rtl::OUString > aArguments; 758 759 handleErrorHandlerRequest(task::InteractionClassification_QUERY, 760 nErrorCode, 761 aArguments, 762 rRequest->getContinuations(), 763 bObtainErrorStringOnly, 764 bHasErrorString, 765 rErrorString); 766 return true; 767 } 768 769 ucb::InteractiveLockingLockedException aLLException; 770 if (aAnyRequest >>= aLLException) 771 { 772 ErrCode nErrorCode = aLLException.SelfOwned 773 ? ERRCODE_UUI_LOCKING_LOCKED_SELF : ERRCODE_UUI_LOCKING_LOCKED; 774 std::vector< rtl::OUString > aArguments; 775 aArguments.push_back( aLLException.Url ); 776 777 handleErrorHandlerRequest( aLLException.Classification, 778 nErrorCode, 779 aArguments, 780 rRequest->getContinuations(), 781 bObtainErrorStringOnly, 782 bHasErrorString, 783 rErrorString ); 784 return true; 785 } 786 787 ucb::InteractiveLockingNotLockedException aLNLException; 788 if (aAnyRequest >>= aLNLException) 789 { 790 ErrCode nErrorCode = ERRCODE_UUI_LOCKING_NOT_LOCKED; 791 std::vector< rtl::OUString > aArguments; 792 aArguments.push_back( aLNLException.Url ); 793 794 handleErrorHandlerRequest( aLNLException.Classification, 795 nErrorCode, 796 aArguments, 797 rRequest->getContinuations(), 798 bObtainErrorStringOnly, 799 bHasErrorString, 800 rErrorString ); 801 return true; 802 } 803 804 ucb::InteractiveLockingLockExpiredException aLLEException; 805 if (aAnyRequest >>= aLLEException) 806 { 807 ErrCode nErrorCode = ERRCODE_UUI_LOCKING_LOCK_EXPIRED; 808 std::vector< rtl::OUString > aArguments; 809 aArguments.push_back( aLLEException.Url ); 810 811 handleErrorHandlerRequest( aLLEException.Classification, 812 nErrorCode, 813 aArguments, 814 rRequest->getContinuations(), 815 bObtainErrorStringOnly, 816 bHasErrorString, 817 rErrorString ); 818 return true; 819 } 820 821 document::BrokenPackageRequest aBrokenPackageRequest; 822 if (aAnyRequest >>= aBrokenPackageRequest) 823 { 824 std::vector< rtl::OUString > aArguments; 825 826 if( aBrokenPackageRequest.aName.getLength() ) 827 aArguments.push_back( aBrokenPackageRequest.aName ); 828 829 handleBrokenPackageRequest( aArguments, 830 rRequest->getContinuations(), 831 bObtainErrorStringOnly, 832 bHasErrorString, 833 rErrorString ); 834 return true; 835 } 836 837 task::ErrorCodeRequest aErrorCodeRequest; 838 if (aAnyRequest >>= aErrorCodeRequest) 839 { 840 handleGenericErrorRequest( aErrorCodeRequest.ErrCode, 841 rRequest->getContinuations(), 842 bObtainErrorStringOnly, 843 bHasErrorString, 844 rErrorString); 845 return true; 846 } 847 848 task::ErrorCodeIOException aErrorCodeIOException; 849 if (aAnyRequest >>= aErrorCodeIOException) 850 { 851 handleGenericErrorRequest( aErrorCodeIOException.ErrCode, 852 rRequest->getContinuations(), 853 bObtainErrorStringOnly, 854 bHasErrorString, 855 rErrorString); 856 return true; 857 } 858 859 860 /////////////////////////////////////////////////////////////////// 861 // Handle requests which do not have a plain string representation. 862 /////////////////////////////////////////////////////////////////// 863 if (!bObtainErrorStringOnly) 864 { 865 if ( handleAuthenticationRequest( rRequest ) ) 866 return true; 867 868 if ( handleCertificateValidationRequest( rRequest ) ) 869 return true; 870 871 ucb::NameClashResolveRequest aNameClashResolveRequest; 872 if (aAnyRequest >>= aNameClashResolveRequest) 873 { 874 handleNameClashResolveRequest(aNameClashResolveRequest, 875 rRequest->getContinuations()); 876 return true; 877 } 878 879 if ( handleMasterPasswordRequest( rRequest ) ) 880 return true; 881 882 if ( handlePasswordRequest( rRequest ) ) 883 return true; 884 885 if ( handleCookiesRequest( rRequest ) ) 886 return true; 887 888 if ( handleNoSuchFilterRequest( rRequest ) ) 889 return true; 890 891 if ( handleAmbigousFilterRequest( rRequest ) ) 892 return true; 893 894 if ( handleFilterOptionsRequest( rRequest ) ) 895 return true; 896 897 if ( handleLockedDocumentRequest( rRequest ) ) 898 return true; 899 900 if ( handleChangedByOthersRequest( rRequest ) ) 901 return true; 902 903 if ( handleLockFileIgnoreRequest( rRequest ) ) 904 return true; 905 906 task::DocumentMacroConfirmationRequest aMacroConfirmRequest; 907 if (aAnyRequest >>= aMacroConfirmRequest) 908 { 909 handleMacroConfirmRequest( 910 aMacroConfirmRequest.DocumentURL, 911 aMacroConfirmRequest.DocumentStorage, 912 aMacroConfirmRequest.DocumentVersion.getLength() ? aMacroConfirmRequest.DocumentVersion : ODFVER_012_TEXT, 913 aMacroConfirmRequest.DocumentSignatureInformation, 914 rRequest->getContinuations()); 915 return true; 916 } 917 918 task::FutureDocumentVersionProductUpdateRequest 919 aProductUpdateRequest; 920 if (aAnyRequest >>= aProductUpdateRequest) 921 { 922 handleFutureDocumentVersionUpdateRequest( 923 aProductUpdateRequest, 924 rRequest->getContinuations()); 925 return true; 926 } 927 928 /////////////////////////////////////////////////////////////// 929 // Last chance: interaction handlers registered in the configuration 930 /////////////////////////////////////////////////////////////// 931 932 // typed InteractionHandlers (ooo.Interactions) 933 if ( handleTypedHandlerImplementations( rRequest ) ) 934 return true; 935 936 // legacy configuration (ooo.ucb.InteractionHandlers) 937 if (tryOtherInteractionHandler( rRequest )) 938 return true; 939 } 940 941 // Not handled. 942 return false; 943 } 944 catch (std::bad_alloc const &) 945 { 946 throw uno::RuntimeException( 947 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("out of memory")), 948 uno::Reference< uno::XInterface >()); 949 } 950 catch( const uno::RuntimeException& ) 951 { 952 throw; // allowed to leave here 953 } 954 catch( const uno::Exception& ) 955 { 956 DBG_UNHANDLED_EXCEPTION(); 957 } 958 return false; 959 } 960 961 void 962 UUIInteractionHelper::getInteractionHandlerList( 963 InteractionHandlerDataList &rdataList) 964 SAL_THROW((uno::RuntimeException)) 965 { 966 try 967 { 968 uno::Reference< lang::XMultiServiceFactory > xConfigProv( 969 m_xServiceFactory->createInstance( 970 rtl::OUString::createFromAscii( 971 "com.sun.star.configuration.ConfigurationProvider" ) ), 972 uno::UNO_QUERY ); 973 974 if ( !xConfigProv.is() ) 975 throw uno::RuntimeException( 976 rtl::OUString( 977 RTL_CONSTASCII_USTRINGPARAM( 978 "unable to instanciate config provider service")), 979 uno::Reference< uno::XInterface >()); 980 981 rtl::OUStringBuffer aFullPath; 982 aFullPath.appendAscii( 983 "/org.openoffice.ucb.InteractionHandler/InteractionHandlers" ); 984 985 uno::Sequence< uno::Any > aArguments( 1 ); 986 beans::PropertyValue aProperty; 987 aProperty.Name 988 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); 989 aProperty.Value <<= aFullPath.makeStringAndClear(); 990 aArguments[ 0 ] <<= aProperty; 991 992 uno::Reference< uno::XInterface > xInterface( 993 xConfigProv->createInstanceWithArguments( 994 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 995 "com.sun.star.configuration.ConfigurationAccess" ) ), 996 aArguments ) ); 997 998 if ( !xInterface.is() ) 999 throw uno::RuntimeException( 1000 rtl::OUString( 1001 RTL_CONSTASCII_USTRINGPARAM( 1002 "unable to instanciate config access")), 1003 uno::Reference< uno::XInterface >()); 1004 1005 uno::Reference< container::XNameAccess > xNameAccess( 1006 xInterface, uno::UNO_QUERY ); 1007 if ( !xNameAccess.is() ) 1008 throw uno::RuntimeException( 1009 rtl::OUString( 1010 RTL_CONSTASCII_USTRINGPARAM( 1011 "config access does not implement XNameAccess")), 1012 uno::Reference< uno::XInterface >()); 1013 1014 uno::Sequence< rtl::OUString > aElems = xNameAccess->getElementNames(); 1015 const rtl::OUString* pElems = aElems.getConstArray(); 1016 sal_Int32 nCount = aElems.getLength(); 1017 1018 if ( nCount > 0 ) 1019 { 1020 uno::Reference< container::XHierarchicalNameAccess > 1021 xHierNameAccess( xInterface, uno::UNO_QUERY ); 1022 1023 if ( !xHierNameAccess.is() ) 1024 throw uno::RuntimeException( 1025 rtl::OUString( 1026 RTL_CONSTASCII_USTRINGPARAM( 1027 "config access does not implement XHierarchicalNameAccess")), 1028 uno::Reference< uno::XInterface >()); 1029 1030 // Iterate over children. 1031 for ( sal_Int32 n = 0; n < nCount; ++n ) 1032 { 1033 rtl::OUStringBuffer aElemBuffer; 1034 aElemBuffer.appendAscii( "['" ); 1035 aElemBuffer.append( pElems[ n ] ); 1036 1037 try 1038 { 1039 InteractionHandlerData aInfo; 1040 1041 // Obtain service name. 1042 rtl::OUStringBuffer aKeyBuffer = aElemBuffer; 1043 aKeyBuffer.appendAscii( "']/ServiceName" ); 1044 1045 rtl::OUString aValue; 1046 if ( !( xHierNameAccess->getByHierarchicalName( 1047 aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) 1048 { 1049 OSL_ENSURE( false, 1050 "GetInteractionHandlerList - " 1051 "Error getting item value!" ); 1052 continue; 1053 } 1054 1055 aInfo.ServiceName = aValue; 1056 1057 // Append info to list. 1058 rdataList.push_back( aInfo ); 1059 } 1060 catch ( container::NoSuchElementException& ) 1061 { 1062 // getByHierarchicalName 1063 1064 OSL_ENSURE( false, 1065 "GetInteractionHandlerList - " 1066 "caught NoSuchElementException!" ); 1067 } 1068 } 1069 } 1070 } 1071 catch ( uno::RuntimeException const & ) 1072 { 1073 throw; 1074 } 1075 catch ( uno::Exception const & ) 1076 { 1077 OSL_ENSURE( false, "GetInteractionHandlerList - Caught Exception!" ); 1078 } 1079 } 1080 1081 Window * 1082 UUIInteractionHelper::getParentProperty() 1083 SAL_THROW(()) 1084 { 1085 uno::Reference< awt::XWindow > xWindow = getParentXWindow(); 1086 if ( xWindow.is() ) 1087 return VCLUnoHelper::GetWindow(xWindow); 1088 1089 return 0; 1090 } 1091 1092 uno::Reference< awt::XWindow> 1093 UUIInteractionHelper::getParentXWindow() const 1094 SAL_THROW(()) 1095 { 1096 osl::MutexGuard aGuard(m_aPropertyMutex); 1097 ::comphelper::NamedValueCollection aProperties( m_aProperties ); 1098 if ( aProperties.has( "Parent" ) ) 1099 { 1100 uno::Reference< awt::XWindow > xWindow; 1101 OSL_VERIFY( aProperties.get( "Parent" ) >>= xWindow ); 1102 return xWindow; 1103 } 1104 return 0; 1105 } 1106 1107 rtl::OUString 1108 UUIInteractionHelper::getContextProperty() 1109 SAL_THROW(()) 1110 { 1111 osl::MutexGuard aGuard(m_aPropertyMutex); 1112 for (sal_Int32 i = 0; i < m_aProperties.getLength(); ++i) 1113 { 1114 beans::PropertyValue aProperty; 1115 if ((m_aProperties[i] >>= aProperty) 1116 && aProperty. 1117 Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Context"))) 1118 { 1119 rtl::OUString aContext; 1120 aProperty.Value >>= aContext; 1121 return aContext; 1122 } 1123 } 1124 return rtl::OUString(); 1125 } 1126 1127 uno::Reference< task::XInteractionHandler > 1128 UUIInteractionHelper::getInteractionHandler() 1129 SAL_THROW((uno::RuntimeException)) 1130 { 1131 uno::Reference< task::XInteractionHandler > xIH; 1132 try 1133 { 1134 xIH.set(m_xServiceFactory->createInstanceWithArguments( 1135 rtl::OUString( 1136 RTL_CONSTASCII_USTRINGPARAM( 1137 "com.sun.star.task.InteractionHandler")), 1138 m_aProperties), 1139 uno::UNO_QUERY); 1140 } 1141 catch (uno::Exception const &) 1142 {} 1143 1144 if (!xIH.is()) 1145 throw uno::RuntimeException( 1146 rtl::OUString( 1147 RTL_CONSTASCII_USTRINGPARAM( 1148 "unable to instanciate Interaction Handler service")), 1149 uno::Reference< uno::XInterface >()); 1150 return xIH; 1151 } 1152 1153 namespace { 1154 1155 sal_uInt16 1156 executeMessageBox( 1157 Window * pParent, 1158 rtl::OUString const & rTitle, 1159 rtl::OUString const & rMessage, 1160 WinBits nButtonMask ) 1161 SAL_THROW((uno::RuntimeException)) 1162 { 1163 vos::OGuard aGuard(Application::GetSolarMutex()); 1164 1165 MessBox xBox( pParent, nButtonMask, rTitle, rMessage ); 1166 1167 sal_uInt16 aResult = xBox.Execute(); 1168 switch( aResult ) 1169 { 1170 case BUTTONID_OK: 1171 aResult = ERRCODE_BUTTON_OK; 1172 break; 1173 case BUTTONID_CANCEL: 1174 aResult = ERRCODE_BUTTON_CANCEL; 1175 break; 1176 case BUTTONID_YES: 1177 aResult = ERRCODE_BUTTON_YES; 1178 break; 1179 case BUTTONID_NO: 1180 aResult = ERRCODE_BUTTON_NO; 1181 break; 1182 case BUTTONID_RETRY: 1183 aResult = ERRCODE_BUTTON_RETRY; 1184 break; 1185 } 1186 1187 return aResult; 1188 } 1189 1190 NameClashResolveDialogResult executeSimpleNameClashResolveDialog( Window *pParent, 1191 rtl::OUString const & rTargetFolderURL, 1192 rtl::OUString const & rClashingName, 1193 rtl::OUString & rProposedNewName, 1194 bool bAllowOverwrite ) 1195 { 1196 std::auto_ptr< ResMgr > xManager( ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); 1197 if ( !xManager.get() ) 1198 return ABORT; 1199 1200 NameClashDialog aDialog( pParent, xManager.get(), rTargetFolderURL, 1201 rClashingName, rProposedNewName, bAllowOverwrite ); 1202 1203 NameClashResolveDialogResult eResult = (NameClashResolveDialogResult) aDialog.Execute(); 1204 rProposedNewName = aDialog.getNewName(); 1205 return eResult; 1206 } 1207 1208 } // namespace 1209 1210 void 1211 UUIInteractionHelper::handleNameClashResolveRequest( 1212 ucb::NameClashResolveRequest const & rRequest, 1213 uno::Sequence< uno::Reference< 1214 task::XInteractionContinuation > > const & rContinuations) 1215 SAL_THROW((uno::RuntimeException)) 1216 { 1217 OSL_ENSURE( 1218 rRequest.TargetFolderURL.getLength() > 0, 1219 "NameClashResolveRequest must not contain empty TargetFolderURL" ); 1220 1221 OSL_ENSURE( 1222 rRequest.ClashingName.getLength() > 0, 1223 "NameClashResolveRequest must not contain empty ClashingName" ); 1224 1225 uno::Reference< task::XInteractionAbort > xAbort; 1226 uno::Reference< ucb::XInteractionSupplyName > xSupplyName; 1227 uno::Reference< ucb::XInteractionReplaceExistingData > xReplaceExistingData; 1228 getContinuations( 1229 rContinuations, &xAbort, &xSupplyName, &xReplaceExistingData); 1230 1231 OSL_ENSURE( xAbort.is(), 1232 "NameClashResolveRequest must contain Abort continuation" ); 1233 1234 OSL_ENSURE( xSupplyName.is(), 1235 "NameClashResolveRequest must contain SupplyName continuation" ); 1236 1237 NameClashResolveDialogResult eResult = ABORT; 1238 rtl::OUString aProposedNewName( rRequest.ProposedNewName ); 1239 1240 eResult = executeSimpleNameClashResolveDialog( getParentProperty(), 1241 rRequest.TargetFolderURL, 1242 rRequest.ClashingName, 1243 aProposedNewName, 1244 xReplaceExistingData.is() ); 1245 1246 switch ( eResult ) 1247 { 1248 case ABORT: 1249 xAbort->select(); 1250 break; 1251 1252 case RENAME: 1253 xSupplyName->setName( aProposedNewName ); 1254 xSupplyName->select(); 1255 break; 1256 1257 case OVERWRITE: 1258 OSL_ENSURE( 1259 xReplaceExistingData.is(), 1260 "Invalid NameClashResolveDialogResult: OVERWRITE - " 1261 "No ReplaceExistingData continuation available!" ); 1262 xReplaceExistingData->select(); 1263 break; 1264 } 1265 } 1266 1267 void 1268 UUIInteractionHelper::handleGenericErrorRequest( 1269 sal_Int32 nErrorCode, 1270 uno::Sequence< uno::Reference< 1271 task::XInteractionContinuation > > const & rContinuations, 1272 bool bObtainErrorStringOnly, 1273 bool & bHasErrorString, 1274 rtl::OUString & rErrorString) 1275 SAL_THROW((uno::RuntimeException)) 1276 { 1277 if (bObtainErrorStringOnly) 1278 { 1279 bHasErrorString = isInformationalErrorMessageRequest(rContinuations); 1280 if (bHasErrorString) 1281 { 1282 String aErrorString; 1283 ErrorHandler::GetErrorString(nErrorCode, aErrorString); 1284 rErrorString = aErrorString; 1285 } 1286 } 1287 else 1288 { 1289 uno::Reference< task::XInteractionAbort > xAbort; 1290 uno::Reference< task::XInteractionApprove > xApprove; 1291 getContinuations(rContinuations, &xApprove, &xAbort); 1292 1293 // Note: It's important to convert the transported long to the 1294 // required unsigned long value. Otherwhise using as flag field 1295 // can fail ... 1296 ErrCode nError = static_cast< ErrCode >(nErrorCode); 1297 sal_Bool bWarning = !ERRCODE_TOERROR(nError); 1298 1299 if ( nError == ERRCODE_SFX_BROKENSIGNATURE 1300 || nError == ERRCODE_SFX_INCOMPLETE_ENCRYPTION ) 1301 { 1302 // the security warning box needs a special title 1303 String aErrorString; 1304 ErrorHandler::GetErrorString( nErrorCode, aErrorString ); 1305 1306 std::auto_ptr< ResMgr > xManager( 1307 ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); 1308 ::rtl::OUString aTitle; 1309 1310 try 1311 { 1312 uno::Any aProductNameAny = 1313 ::utl::ConfigManager::GetConfigManager() 1314 ->GetDirectConfigProperty( 1315 ::utl::ConfigManager::PRODUCTNAME ); 1316 aProductNameAny >>= aTitle; 1317 } 1318 catch( uno::Exception& ) 1319 { 1320 } 1321 1322 ::rtl::OUString aErrTitle 1323 = String( ResId( nError == ERRCODE_SFX_BROKENSIGNATURE 1324 ? STR_WARNING_BROKENSIGNATURE_TITLE 1325 : STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE, 1326 *xManager.get() ) ); 1327 1328 if ( aTitle.getLength() && aErrTitle.getLength() ) 1329 aTitle += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " - " ) ); 1330 aTitle += aErrTitle; 1331 1332 executeMessageBox( 1333 getParentProperty(), aTitle, aErrorString, WB_OK ); 1334 } 1335 else 1336 ErrorHandler::HandleError(nErrorCode); 1337 1338 if (xApprove.is() && bWarning) 1339 xApprove->select(); 1340 else if (xAbort.is()) 1341 xAbort->select(); 1342 } 1343 } 1344 1345 void 1346 UUIInteractionHelper::handleMacroConfirmRequest( 1347 const ::rtl::OUString& aDocumentURL, 1348 const uno::Reference< embed::XStorage >& xZipStorage, 1349 const ::rtl::OUString& aDocumentVersion, 1350 const uno::Sequence< security::DocumentSignatureInformation > aSignInfo, 1351 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & 1352 rContinuations ) 1353 SAL_THROW((uno::RuntimeException)) 1354 { 1355 uno::Reference< task::XInteractionAbort > xAbort; 1356 uno::Reference< task::XInteractionApprove > xApprove; 1357 getContinuations( rContinuations, &xApprove, &xAbort ); 1358 1359 bool bApprove = false; 1360 1361 std::auto_ptr< ResMgr > pResMgr( 1362 ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); 1363 if ( pResMgr.get() ) 1364 { 1365 bool bShowSignatures = aSignInfo.getLength() > 0; 1366 MacroWarning aWarning( 1367 getParentProperty(), bShowSignatures, *pResMgr.get() ); 1368 1369 aWarning.SetDocumentURL( aDocumentURL ); 1370 if ( aSignInfo.getLength() > 1 ) 1371 { 1372 aWarning.SetStorage( xZipStorage, aDocumentVersion, aSignInfo ); 1373 } 1374 else if ( aSignInfo.getLength() == 1 ) 1375 { 1376 aWarning.SetCertificate( aSignInfo[ 0 ].Signer ); 1377 } 1378 1379 bApprove = aWarning.Execute() == RET_OK; 1380 } 1381 1382 if ( bApprove && xApprove.is() ) 1383 xApprove->select(); 1384 else if ( xAbort.is() ) 1385 xAbort->select(); 1386 } 1387 1388 void 1389 UUIInteractionHelper::handleFutureDocumentVersionUpdateRequest( 1390 const task::FutureDocumentVersionProductUpdateRequest& _rRequest, 1391 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & 1392 rContinuations ) 1393 SAL_THROW((uno::RuntimeException)) 1394 { 1395 uno::Reference< task::XInteractionAbort > xAbort; 1396 uno::Reference< task::XInteractionApprove > xApprove; 1397 uno::Reference< task::XInteractionAskLater > xAskLater; 1398 getContinuations( rContinuations, &xApprove, &xAbort, &xAskLater ); 1399 1400 short nResult = RET_CANCEL; 1401 1402 static bool s_bDeferredToNextSession = false; 1403 // TODO: this static variable is somewhat hacky. Formerly (before the dialog was moved from SFX2 to the 1404 // interaction handler implementation), this was stored in SFX_APP()'s impl structure, in member 1405 // bODFVersionWarningLater. Of course, we do not have access to it here. 1406 // 1407 // A proper solution which I would envision would be: 1408 // - There's a central implementation (this one here) of css.task.InteractionHandler 1409 // - There's a configuration which maps UNO names to service names 1410 // - If the handler is confronted with a request, it tries to find the name of the UNO structure describing 1411 // the request in the said configuration. 1412 // - If an entry is found, then 1413 // - the respective service is instantiated 1414 // - the component is queried for css.task.XInteractionHandler, and the request is delegated 1415 // - if no entry is found, then the request is silenced (with calling the AbortContinuation, if possible) 1416 // This way, the FutureDocumentVersionProductUpdateRequest could be handled in SFX (or any other 1417 // suitable place), again, and we would only have one place where we remember the s_bDeferredToNextSession 1418 // flag. 1419 // 1420 // Note: The above pattern has been implemented in CWS autorecovery. Now the remaining task is to move the 1421 // handling of this interaction to SFX, again. 1422 1423 if ( !s_bDeferredToNextSession ) 1424 { 1425 std::auto_ptr< ResMgr > pResMgr( 1426 ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); 1427 if ( pResMgr.get() ) 1428 { 1429 ::uui::NewerVersionWarningDialog aDialog( 1430 getParentProperty(), 1431 _rRequest.DocumentODFVersion, 1432 *pResMgr.get() ); 1433 nResult = aDialog.Execute(); 1434 } 1435 } 1436 1437 switch ( nResult ) 1438 { 1439 case RET_OK: 1440 if ( xApprove.is() ) 1441 xApprove->select(); 1442 break; 1443 case RET_CANCEL: 1444 if ( xAbort.is() ) 1445 xAbort->select(); 1446 break; 1447 case RET_ASK_LATER: 1448 if ( xAskLater.is() ) 1449 xAskLater->select(); 1450 s_bDeferredToNextSession = true; 1451 break; 1452 default: 1453 OSL_ENSURE( false, 1454 "UUIInteractionHelper::handleFutureDocumentVersionUpdateRequest: " 1455 "unexpected dialog return value!" ); 1456 break; 1457 } 1458 } 1459 1460 void 1461 UUIInteractionHelper::handleBrokenPackageRequest( 1462 std::vector< rtl::OUString > const & rArguments, 1463 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & 1464 rContinuations, 1465 bool bObtainErrorStringOnly, 1466 bool & bHasErrorString, 1467 rtl::OUString & rErrorString) 1468 SAL_THROW((uno::RuntimeException)) 1469 { 1470 if (bObtainErrorStringOnly) 1471 { 1472 bHasErrorString = isInformationalErrorMessageRequest(rContinuations); 1473 if (!bHasErrorString) 1474 return; 1475 } 1476 1477 uno::Reference< task::XInteractionApprove > xApprove; 1478 uno::Reference< task::XInteractionDisapprove > xDisapprove; 1479 uno::Reference< task::XInteractionAbort > xAbort; 1480 getContinuations(rContinuations, &xApprove, &xDisapprove, &xAbort); 1481 1482 ErrCode nErrorCode; 1483 if( xApprove.is() && xDisapprove.is() ) 1484 { 1485 nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE; 1486 } 1487 else if ( xAbort.is() ) 1488 { 1489 nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE_CANTREPAIR; 1490 } 1491 else 1492 return; 1493 1494 ::rtl::OUString aMessage; 1495 { 1496 vos::OGuard aGuard(Application::GetSolarMutex()); 1497 std::auto_ptr< ResMgr > xManager( 1498 ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(uui))); 1499 if (!xManager.get()) 1500 return; 1501 1502 ResId aResId( RID_UUI_ERRHDL, *xManager.get() ); 1503 if ( !ErrorResource(aResId).getString(nErrorCode, &aMessage) ) 1504 return; 1505 } 1506 1507 aMessage = replaceMessageWithArguments( aMessage, rArguments ); 1508 1509 if (bObtainErrorStringOnly) 1510 { 1511 rErrorString = aMessage; 1512 return; 1513 } 1514 1515 WinBits nButtonMask; 1516 if( xApprove.is() && xDisapprove.is() ) 1517 { 1518 nButtonMask = WB_YES_NO | WB_DEF_YES; 1519 } 1520 else if ( xAbort.is() ) 1521 { 1522 nButtonMask = WB_OK; 1523 } 1524 else 1525 return; 1526 1527 uno::Any aProductNameAny = 1528 ::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty( 1529 ::utl::ConfigManager::PRODUCTNAME ); 1530 uno::Any aProductVersionAny = 1531 ::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty( 1532 ::utl::ConfigManager::PRODUCTVERSION ); 1533 ::rtl::OUString aProductName, aProductVersion; 1534 if ( !( aProductNameAny >>= aProductName ) ) 1535 aProductName 1536 = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StarOffice") ); 1537 1538 ::rtl::OUString aTitle( aProductName ); 1539 if( aProductVersionAny >>= aProductVersion ) 1540 { 1541 aTitle += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" ") ); 1542 aTitle += aProductVersion; 1543 } 1544 1545 switch ( executeMessageBox( getParentProperty(), 1546 aTitle, 1547 aMessage, 1548 nButtonMask )) 1549 { 1550 case ERRCODE_BUTTON_OK: 1551 OSL_ENSURE( xAbort.is(), "unexpected situation" ); 1552 if (xAbort.is()) 1553 xAbort->select(); 1554 break; 1555 1556 case ERRCODE_BUTTON_NO: 1557 OSL_ENSURE(xDisapprove.is(), "unexpected situation"); 1558 if (xDisapprove.is()) 1559 xDisapprove->select(); 1560 break; 1561 1562 case ERRCODE_BUTTON_YES: 1563 OSL_ENSURE(xApprove.is(), "unexpected situation"); 1564 if (xApprove.is()) 1565 xApprove->select(); 1566 break; 1567 } 1568 } 1569 1570 //========================================================================= 1571 // ErrorResource Implementation 1572 //========================================================================= 1573 1574 bool 1575 ErrorResource::getString(ErrCode nErrorCode, rtl::OUString * pString) 1576 const SAL_THROW(()) 1577 { 1578 OSL_ENSURE(pString, "specification violation"); 1579 ResId aResId(static_cast< sal_uInt16 >(nErrorCode & ERRCODE_RES_MASK), 1580 *m_pResMgr); 1581 aResId.SetRT(RSC_STRING); 1582 if (!IsAvailableRes(aResId)) 1583 return false; 1584 aResId.SetAutoRelease(false); 1585 *pString = UniString(aResId); 1586 m_pResMgr->PopContext(); 1587 return true; 1588 } 1589