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