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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sfx2.hxx" 26 #include <com/sun/star/uno/Reference.h> 27 #include <com/sun/star/beans/PropertyValue.hpp> 28 #include <com/sun/star/frame/FrameSearchFlag.hpp> 29 #include <com/sun/star/frame/XComponentLoader.hpp> 30 #include <com/sun/star/frame/XNotifyingDispatch.hpp> 31 #include <com/sun/star/frame/XDispatchProvider.hpp> 32 #include <com/sun/star/util/XCloseable.hpp> 33 #include <com/sun/star/frame/XFrame.hpp> 34 #include <com/sun/star/frame/XDesktop.hpp> 35 #include <com/sun/star/frame/DispatchResultState.hpp> 36 #include <com/sun/star/frame/XDispatchResultListener.hpp> 37 #include <com/sun/star/util/URL.hpp> 38 #include <com/sun/star/util/XURLTransformer.hpp> 39 #include <com/sun/star/system/SystemShellExecute.hpp> 40 #include <com/sun/star/document/XTypeDetection.hpp> 41 #include <com/sun/star/system/SystemShellExecuteFlags.hpp> 42 #include <com/sun/star/document/MacroExecMode.hpp> 43 #include <com/sun/star/document/UpdateDocMode.hpp> 44 #include <com/sun/star/task/ErrorCodeRequest.hpp> 45 #include <com/sun/star/beans/XPropertySet.hpp> 46 #include <com/sun/star/embed/ElementModes.hpp> 47 #include <com/sun/star/container/XNameAccess.hpp> 48 #include <com/sun/star/uno/Sequence.h> 49 #include <comphelper/processfactory.hxx> 50 #include <cppuhelper/implbase1.hxx> 51 #include <rtl/ustring.hxx> 52 53 54 #include <comphelper/storagehelper.hxx> 55 #include <comphelper/synchronousdispatch.hxx> 56 #include <comphelper/configurationhelper.hxx> 57 #include <comphelper/sequenceasvector.hxx> 58 59 #include <vcl/wrkwin.hxx> 60 #include <svl/intitem.hxx> 61 #include <vcl/msgbox.hxx> 62 #include <svl/stritem.hxx> 63 #include <svl/eitem.hxx> 64 #include <sfx2/doctempl.hxx> 65 #include <svtools/sfxecode.hxx> 66 #include <framework/preventduplicateinteraction.hxx> 67 #include <svtools/ehdl.hxx> 68 #include <basic/sbxobj.hxx> 69 #include <svl/urihelper.hxx> 70 #include <unotools/localfilehelper.hxx> 71 #include <unotools/pathoptions.hxx> 72 #include <unotools/moduleoptions.hxx> 73 #include <svtools/templdlg.hxx> 74 #include <osl/file.hxx> 75 #include <unotools/extendedsecurityoptions.hxx> 76 #include <comphelper/docpasswordhelper.hxx> 77 #include <vcl/svapp.hxx> 78 79 #include <vos/mutex.hxx> 80 81 #include <rtl/logfile.hxx> 82 83 #include <sfx2/app.hxx> 84 #include <sfx2/bindings.hxx> 85 #include <sfx2/dispatch.hxx> 86 #include <sfx2/docfile.hxx> 87 #include <sfx2/fcontnr.hxx> 88 #include <sfx2/new.hxx> 89 #include <sfx2/objitem.hxx> 90 #include <sfx2/objsh.hxx> 91 #include <svl/slstitm.hxx> 92 #include "objshimp.hxx" 93 #include "openflag.hxx" 94 #include <sfx2/passwd.hxx> 95 #include "referers.hxx" 96 #include <sfx2/request.hxx> 97 #include "sfx2/sfxresid.hxx" 98 #include <sfx2/viewsh.hxx> 99 #include "app.hrc" 100 #include <sfx2/viewfrm.hxx> 101 #include <sfx2/sfxuno.hxx> 102 #include <sfx2/objface.hxx> 103 #include <sfx2/filedlghelper.hxx> 104 #include <sfx2/docfac.hxx> 105 #include <sfx2/event.hxx> 106 107 #define _SVSTDARR_STRINGSDTOR 108 #include <svl/svstdarr.hxx> 109 110 using namespace ::com::sun::star; 111 using namespace ::com::sun::star::beans; 112 using namespace ::com::sun::star::frame; 113 using namespace ::com::sun::star::lang; 114 using namespace ::com::sun::star::uno; 115 using namespace ::com::sun::star::util; 116 using namespace ::com::sun::star::system; 117 using namespace ::com::sun::star::task; 118 using namespace ::com::sun::star::container; 119 using namespace ::cppu; 120 using namespace ::sfx2; 121 122 namespace css = ::com::sun::star; 123 124 //========================================================================= 125 126 class SfxOpenDocStatusListener_Impl : public WeakImplHelper1< XDispatchResultListener > 127 { 128 public: 129 sal_Bool bFinished; 130 sal_Bool bSuccess; 131 virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& Event ) throw(RuntimeException); 132 virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException); 133 SfxOpenDocStatusListener_Impl() 134 : bFinished( sal_False ) 135 , bSuccess( sal_False ) 136 {} 137 }; 138 139 void SAL_CALL SfxOpenDocStatusListener_Impl::dispatchFinished( const DispatchResultEvent& aEvent ) throw(RuntimeException) 140 { 141 bSuccess = ( aEvent.State == DispatchResultState::SUCCESS ); 142 bFinished = sal_True; 143 } 144 145 void SAL_CALL SfxOpenDocStatusListener_Impl::disposing( const EventObject& ) throw(RuntimeException) 146 { 147 } 148 149 SfxObjectShellRef SfxApplication::DocAlreadyLoaded 150 ( 151 const String& rName, // Name of the Document including path 152 sal_Bool bSilent, // sal_True: do not ask for new view 153 sal_Bool bActivate, // should current view be activated 154 sal_Bool bForbidVisible, 155 const String* pPostStr 156 ) 157 158 /* [description] 159 assert if Document with the name 'rname' has been loaded and delivers the 160 pointer. Otherwise a zeropointer will be returned 161 */ 162 163 { 164 // create URL from searchable name 165 INetURLObject aUrlToFind( rName ); 166 DBG_ASSERT( aUrlToFind.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL" ); 167 String aPostString; 168 if ( pPostStr ) 169 aPostString = *pPostStr; 170 171 // still open? 172 SfxObjectShellRef xDoc; 173 174 if ( !aUrlToFind.HasError() ) 175 { 176 // check at normal opened documents 177 if ( !xDoc.Is() ) 178 { 179 xDoc = SfxObjectShell::GetFirst( 0, sal_False ); // include hidden files 180 while( xDoc.Is() ) 181 { 182 if ( xDoc->GetMedium() && 183 xDoc->GetCreateMode() == SFX_CREATE_MODE_STANDARD && 184 !xDoc->IsAbortingImport() && !xDoc->IsLoading() ) 185 { 186 // compare by URLs 187 INetURLObject aUrl( xDoc->GetMedium()->GetName() ); 188 if ( !aUrl.HasError() && aUrl == aUrlToFind && 189 (!bForbidVisible || !SfxViewFrame::GetFirst( xDoc, sal_True )) && 190 !xDoc->IsLoading()) 191 { 192 break; 193 } 194 } 195 xDoc = SfxObjectShell::GetNext( *xDoc, 0, sal_False ); 196 } 197 } 198 } 199 200 // found? 201 if ( xDoc.Is() && bActivate ) 202 { 203 DBG_ASSERT( 204 !bForbidVisible, "Invisible files cannot be activated" ); 205 206 SfxViewFrame* pFrame; 207 for( pFrame = SfxViewFrame::GetFirst( xDoc ); 208 pFrame && !pFrame->IsVisible(); 209 pFrame = SfxViewFrame::GetNext( *pFrame, xDoc ) ) ; 210 if ( pFrame ) 211 { 212 SfxViewFrame *pCur = SfxViewFrame::Current(); 213 if ( !bSilent && pFrame == pCur ) 214 InfoBox( 0, SfxResId(RID_DOCALREADYLOADED_DLG)).Execute(); 215 if ( bActivate ) 216 { 217 pFrame->MakeActive_Impl( sal_True ); 218 } 219 } 220 } 221 return xDoc; 222 } 223 224 //==================================================================== 225 226 void SetTemplate_Impl( const String &rFileName, 227 const String &rLongName, 228 SfxObjectShell *pDoc) 229 { 230 // write TemplateName to DocumentInfo of document 231 // TemplateDate stays as default (=current date) 232 pDoc->ResetFromTemplate( rLongName, rFileName ); 233 } 234 235 //==================================================================== 236 class SfxDocPasswordVerifier : public ::comphelper::IDocPasswordVerifier 237 { 238 public: 239 inline explicit SfxDocPasswordVerifier( const Reference< embed::XStorage >& rxStorage ) : 240 mxStorage( rxStorage ) {} 241 242 virtual ::comphelper::DocPasswordVerifierResult 243 verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData ); 244 virtual ::comphelper::DocPasswordVerifierResult 245 verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData ); 246 247 248 private: 249 Reference< embed::XStorage > mxStorage; 250 }; 251 252 //-------------------------------------------------------------------- 253 ::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData ) 254 { 255 o_rEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( rPassword ); 256 return verifyEncryptionData( o_rEncryptionData ); 257 } 258 259 260 //-------------------------------------------------------------------- 261 ::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData ) 262 { 263 ::comphelper::DocPasswordVerifierResult eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; 264 try 265 { 266 // check the encryption data 267 // if the data correct is the stream will be opened successfully 268 // and immediately closed 269 ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( mxStorage, rEncryptionData ); 270 271 mxStorage->openStreamElement( 272 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) ), 273 embed::ElementModes::READ | embed::ElementModes::NOCREATE ); 274 275 // no exception -> success 276 eResult = ::comphelper::DocPasswordVerifierResult_OK; 277 } 278 catch( const packages::WrongPasswordException& ) 279 { 280 eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; 281 } 282 catch( const uno::Exception& ) 283 { 284 // unknown error, report it as wrong password 285 // TODO/LATER: we need an additional way to report unknown problems in this case 286 eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; 287 } 288 return eResult; 289 } 290 291 //==================================================================== 292 293 //-------------------------------------------------------------------- 294 295 sal_uInt32 CheckPasswd_Impl 296 ( 297 //Window *pWin, // Parent of dialog 298 SfxObjectShell* pDoc, 299 SfxItemPool& /*rPool*/, // Pool, if we need to create a set 300 SfxMedium* pFile // Medium that needs a password (if necessary) 301 ) 302 303 /* [description] 304 To query a passwort on a medium works only if the medium is a storage. 305 If in documentinfo the password-flag is set, a dialog will query the user 306 for the password. The password will be saved in a set. If the set does not 307 exist, a set will be created. 308 */ 309 { 310 sal_uIntPtr nRet = ERRCODE_NONE; 311 312 if( ( !pFile->GetFilter() || pFile->IsStorage() ) ) 313 { 314 uno::Reference< embed::XStorage > xStorage = pFile->GetStorage( sal_True ); 315 if( xStorage.is() ) 316 { 317 uno::Reference< beans::XPropertySet > xStorageProps( xStorage, uno::UNO_QUERY ); 318 if ( xStorageProps.is() ) 319 { 320 sal_Bool bIsEncrypted = sal_False; 321 try { 322 xStorageProps->getPropertyValue( ::rtl::OUString::createFromAscii("HasEncryptedEntries") ) 323 >>= bIsEncrypted; 324 } catch( uno::Exception& ) 325 { 326 // TODO/LATER: 327 // the storage either has no encrypted elements or it's just 328 // does not allow to detect it, probably it should be implemented laiter 329 /* 330 bIsEncrypted = ( aInfo.Load( xStorage ) && aInfo.IsPasswd() ); 331 */ 332 } 333 334 if ( bIsEncrypted ) 335 { 336 Window* pWin = pDoc ? pDoc->GetDialogParent( pFile ) : NULL; 337 if ( pWin ) 338 pWin->Show(); 339 340 nRet = ERRCODE_SFX_CANTGETPASSWD; 341 342 SfxItemSet *pSet = pFile->GetItemSet(); 343 if( pSet ) 344 { 345 Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = pFile->GetInteractionHandler(); 346 if( xInteractionHandler.is() ) 347 { 348 // use the comphelper password helper to request a password 349 ::rtl::OUString aPassword; 350 SFX_ITEMSET_ARG( pSet, pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False); 351 if ( pPasswordItem ) 352 aPassword = pPasswordItem->GetValue(); 353 354 uno::Sequence< beans::NamedValue > aEncryptionData; 355 SFX_ITEMSET_ARG( pSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False); 356 if ( pEncryptionDataItem ) 357 pEncryptionDataItem->GetValue() >>= aEncryptionData; 358 359 ::rtl::OUString aDocumentName = INetURLObject( pFile->GetOrigURL() ).GetMainURL( INetURLObject::DECODE_WITH_CHARSET ); 360 361 SfxDocPasswordVerifier aVerifier( xStorage ); 362 aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( 363 aVerifier, aEncryptionData, aPassword, xInteractionHandler, aDocumentName, comphelper::DocPasswordRequestType_STANDARD ); 364 365 pSet->ClearItem( SID_PASSWORD ); 366 pSet->ClearItem( SID_ENCRYPTIONDATA ); 367 368 if ( aEncryptionData.getLength() > 0 ) 369 { 370 pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) ); 371 372 try 373 { 374 // update the version list of the medium using the new password 375 pFile->GetVersionList(); 376 } 377 catch( uno::Exception& ) 378 { 379 // TODO/LATER: set the error code 380 } 381 382 nRet = ERRCODE_NONE; 383 } 384 else 385 nRet = ERRCODE_IO_ABORT; 386 } 387 } 388 } 389 } 390 else 391 { 392 OSL_ENSURE( sal_False, "A storage must implement XPropertySet interface!" ); 393 nRet = ERRCODE_SFX_CANTGETPASSWD; 394 } 395 } 396 } 397 398 return nRet; 399 } 400 401 //-------------------------------------------------------------------- 402 403 404 sal_uIntPtr SfxApplication::LoadTemplate( SfxObjectShellLock& xDoc, const String &rFileName, sal_Bool bCopy, SfxItemSet* pSet ) 405 { 406 const SfxFilter* pFilter = NULL; 407 SfxMedium aMedium( rFileName, ( STREAM_READ | STREAM_SHARE_DENYNONE ), sal_False ); 408 409 if ( !aMedium.GetStorage( sal_True ).is() ) 410 aMedium.GetInStream(); 411 412 if ( aMedium.GetError() ) 413 { 414 delete pSet; 415 return aMedium.GetErrorCode(); 416 } 417 418 aMedium.UseInteractionHandler( sal_True ); 419 sal_uIntPtr nErr = GetFilterMatcher().GuessFilter( aMedium,&pFilter,SFX_FILTER_TEMPLATE, 0 ); 420 if ( 0 != nErr) 421 { 422 delete pSet; 423 return ERRCODE_SFX_NOTATEMPLATE; 424 } 425 426 if( !pFilter || !pFilter->IsAllowedAsTemplate() ) 427 { 428 delete pSet; 429 return ERRCODE_SFX_NOTATEMPLATE; 430 } 431 432 if ( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) 433 { 434 DBG_ASSERT( !xDoc.Is(), "Sorry, not implemented!" ); 435 delete pSet; 436 SfxStringItem aName( SID_FILE_NAME, rFileName ); 437 SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii("private:user") ); 438 SfxStringItem aFlags( SID_OPTIONS, String::CreateFromAscii("T") ); 439 SfxBoolItem aHidden( SID_HIDDEN, sal_True ); 440 const SfxPoolItem *pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, &aName, &aHidden, &aReferer, &aFlags, 0L ); 441 const SfxObjectItem *pObj = PTR_CAST( SfxObjectItem, pRet ); 442 if ( pObj ) 443 xDoc = PTR_CAST( SfxObjectShell, pObj->GetShell() ); 444 else 445 { 446 const SfxViewFrameItem *pView = PTR_CAST( SfxViewFrameItem, pRet ); 447 if ( pView ) 448 { 449 SfxViewFrame *pFrame = pView->GetFrame(); 450 if ( pFrame ) 451 xDoc = pFrame->GetObjectShell(); 452 } 453 } 454 455 if ( !xDoc.Is() ) 456 return ERRCODE_SFX_DOLOADFAILED; 457 } 458 else 459 { 460 if ( !xDoc.Is() ) 461 xDoc = SfxObjectShell::CreateObject( pFilter->GetServiceName() ); 462 463 SfxMedium *pMedium = new SfxMedium( rFileName, STREAM_STD_READ, sal_False, pFilter, pSet ); 464 if(!xDoc->DoLoad(pMedium)) 465 { 466 ErrCode nErrCode = xDoc->GetErrorCode(); 467 xDoc->DoClose(); 468 xDoc.Clear(); 469 return nErrCode; 470 } 471 } 472 473 if( bCopy ) 474 { 475 try 476 { 477 // TODO: introduce error handling 478 479 uno::Reference< embed::XStorage > xTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); 480 if( !xTempStorage.is() ) 481 throw uno::RuntimeException(); 482 483 xDoc->GetStorage()->copyToStorage( xTempStorage ); 484 485 //REMOVE // the following operations should be done in one step 486 //REMOVE xDoc->DoHandsOff(); 487 if ( !xDoc->DoSaveCompleted( new SfxMedium( xTempStorage, String() ) ) ) 488 throw uno::RuntimeException(); 489 } 490 catch( uno::Exception& ) 491 { 492 xDoc->DoClose(); 493 xDoc.Clear(); 494 495 // TODO: transfer correct error outside 496 return ERRCODE_SFX_GENERAL; 497 } 498 499 SetTemplate_Impl( rFileName, String(), xDoc ); 500 } 501 else 502 SetTemplate_Impl( rFileName, String(), xDoc ); 503 504 xDoc->SetNoName(); 505 xDoc->InvalidateName(); 506 xDoc->SetModified(sal_False); 507 xDoc->ResetError(); 508 509 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel ( xDoc->GetModel(), ::com::sun::star::uno::UNO_QUERY ); 510 if ( xModel.is() ) 511 { 512 SfxItemSet* pNew = xDoc->GetMedium()->GetItemSet()->Clone(); 513 pNew->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL ); 514 pNew->ClearItem( SID_FILTER_NAME ); 515 //pNew->Put( SfxStringItem( SID_FILTER_NAME, xDoc->GetFactory().GetFilter(0)->GetFilterName() ) ); 516 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs; 517 TransformItems( SID_OPENDOC, *pNew, aArgs ); 518 sal_Int32 nLength = aArgs.getLength(); 519 aArgs.realloc( nLength + 1 ); 520 aArgs[nLength].Name = DEFINE_CONST_UNICODE("Title"); 521 aArgs[nLength].Value <<= ::rtl::OUString( xDoc->GetTitle( SFX_TITLE_DETECT ) ); 522 xModel->attachResource( ::rtl::OUString(), aArgs ); 523 delete pNew; 524 } 525 526 return xDoc->GetErrorCode(); 527 } 528 529 //-------------------------------------------------------------------- 530 531 void SfxApplication::NewDocDirectExec_Impl( SfxRequest& rReq ) 532 { 533 DBG_MEMTEST(); 534 535 SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, sal_False); 536 String aFactName; 537 if ( pFactoryItem ) 538 aFactName = pFactoryItem->GetValue(); 539 else 540 aFactName = SvtModuleOptions().GetDefaultModuleName(); 541 542 543 SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, GetPool() ); 544 String aFact = String::CreateFromAscii("private:factory/"); 545 aFact += aFactName; 546 aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) ); 547 aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, GetFrame() ) ); 548 aReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii( "_default" ) ) ); 549 550 // TODO/LATER: Should the other arguments be transferred as well? 551 SFX_REQUEST_ARG( rReq, pDefaultPathItem, SfxStringItem, SID_DEFAULTFILEPATH, sal_False); 552 if ( pDefaultPathItem ) 553 aReq.AppendItem( *pDefaultPathItem ); 554 SFX_REQUEST_ARG( rReq, pDefaultNameItem, SfxStringItem, SID_DEFAULTFILENAME, sal_False); 555 if ( pDefaultNameItem ) 556 aReq.AppendItem( *pDefaultNameItem ); 557 558 SFX_APP()->ExecuteSlot( aReq ); 559 const SfxViewFrameItem* pItem = PTR_CAST( SfxViewFrameItem, aReq.GetReturnValue() ); 560 if ( pItem ) 561 rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) ); 562 } 563 564 //-------------------------------------------------------------------- 565 566 void SfxApplication::NewDocExec_Impl( SfxRequest& rReq ) 567 { 568 DBG_MEMTEST(); 569 570 // No Parameters given and only factory given by BASIC ? 571 SFX_REQUEST_ARG(rReq, pTemplNameItem, SfxStringItem, SID_TEMPLATE_NAME, sal_False); 572 SFX_REQUEST_ARG(rReq, pTemplFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False); 573 SFX_REQUEST_ARG(rReq, pTemplRegionNameItem, SfxStringItem, SID_TEMPLATE_REGIONNAME, sal_False); 574 575 SfxObjectShellLock xDoc; 576 577 String aTemplateRegion, aTemplateName, aTemplateFileName; 578 sal_Bool bDirect = sal_False; // use filename instead of region/template 579 SfxErrorContext aEc(ERRCTX_SFX_NEWDOC); 580 if ( !pTemplNameItem && !pTemplFileNameItem ) 581 { 582 Window* pTopWin = GetTopWindow(); 583 SvtDocumentTemplateDialog* pDocTemplDlg = new SvtDocumentTemplateDialog( NULL ); 584 int nRet = pDocTemplDlg->Execute(); 585 sal_Bool bNewWin = sal_False; 586 if ( nRet == RET_OK ) 587 { 588 rReq.Done(); 589 if ( pTopWin != GetTopWindow() ) 590 { 591 // the dialogue opens a document -> a new TopWindow appears 592 pTopWin = GetTopWindow(); 593 bNewWin = sal_True; 594 } 595 } 596 597 delete pDocTemplDlg; 598 if ( bNewWin && pTopWin ) 599 // after the destruction of the dialogue its parent comes to top, 600 // but we want that the new document is on top 601 pTopWin->ToTop(); 602 603 return; 604 } 605 else 606 { 607 // Template-Name 608 if ( pTemplNameItem ) 609 aTemplateName = pTemplNameItem->GetValue(); 610 611 // Template-Region 612 if ( pTemplRegionNameItem ) 613 aTemplateRegion = pTemplRegionNameItem->GetValue(); 614 615 // Template-File-Name 616 if ( pTemplFileNameItem ) 617 { 618 aTemplateFileName = pTemplFileNameItem->GetValue(); 619 bDirect = sal_True; 620 } 621 } 622 623 sal_uIntPtr lErr = 0; 624 SfxItemSet* pSet = new SfxAllItemSet( GetPool() ); 625 pSet->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) ); 626 if ( !bDirect ) 627 { 628 SfxDocumentTemplates aTmpFac; 629 if( !aTemplateFileName.Len() ) 630 aTmpFac.GetFull( aTemplateRegion, aTemplateName, aTemplateFileName ); 631 632 if( !aTemplateFileName.Len() ) 633 lErr = ERRCODE_SFX_TEMPLATENOTFOUND; 634 } 635 636 INetURLObject aObj( aTemplateFileName ); 637 SfxErrorContext aEC( ERRCTX_SFX_LOADTEMPLATE, aObj.PathToFileName() ); 638 639 if ( lErr != ERRCODE_NONE ) 640 { 641 sal_uIntPtr lFatalErr = ERRCODE_TOERROR(lErr); 642 if ( lFatalErr ) 643 ErrorHandler::HandleError(lErr); 644 } 645 else 646 { 647 SfxCallMode eMode = SFX_CALLMODE_SYNCHRON; 648 649 const SfxPoolItem *pRet=0; 650 SfxStringItem aReferer( SID_REFERER, DEFINE_CONST_UNICODE("private:user") ); 651 SfxStringItem aTarget( SID_TARGETNAME, DEFINE_CONST_UNICODE("_default") ); 652 if ( aTemplateFileName.Len() ) 653 { 654 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" ); 655 656 SfxStringItem aName( SID_FILE_NAME, aObj.GetMainURL( INetURLObject::NO_DECODE ) ); 657 SfxStringItem aTemplName( SID_TEMPLATE_NAME, aTemplateName ); 658 SfxStringItem aTemplRegionName( SID_TEMPLATE_REGIONNAME, aTemplateRegion ); 659 pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, &aTemplName, &aTemplRegionName, 0L ); 660 } 661 else 662 { 663 SfxStringItem aName( SID_FILE_NAME, DEFINE_CONST_UNICODE("private:factory") ); 664 pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, 0L ); 665 } 666 667 if ( pRet ) 668 rReq.SetReturnValue( *pRet ); 669 } 670 } 671 672 //--------------------------------------------------------------------------- 673 674 void SfxApplication::OpenDocExec_Impl( SfxRequest& rReq ) 675 { 676 DBG_MEMTEST(); 677 678 sal_uInt16 nSID = rReq.GetSlot(); 679 SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False ); 680 if ( pFileNameItem ) 681 { 682 String aCommand( pFileNameItem->GetValue() ); 683 const SfxSlot* pSlot = GetInterface()->GetSlot( aCommand ); 684 if ( pSlot ) 685 { 686 pFileNameItem = NULL; 687 } 688 else 689 { 690 sal_Int32 nIndex = aCommand.SearchAscii("slot:"); 691 if ( !nIndex ) 692 { 693 sal_uInt16 nSlotId = (sal_uInt16) String( aCommand, 5, aCommand.Len()-5 ).ToInt32(); 694 if ( nSlotId == SID_OPENDOC ) 695 pFileNameItem = NULL; 696 } 697 } 698 } 699 700 if ( !pFileNameItem ) 701 { 702 // get FileName from dialog 703 SvStringsDtor* pURLList = NULL; 704 String aFilter; 705 SfxItemSet* pSet = NULL; 706 String aPath; 707 SFX_REQUEST_ARG( rReq, pFolderNameItem, SfxStringItem, SID_PATH, sal_False ); 708 if ( pFolderNameItem ) 709 aPath = pFolderNameItem->GetValue(); 710 else if ( nSID == SID_OPENTEMPLATE ) 711 { 712 aPath = SvtPathOptions().GetTemplatePath(); 713 sal_Int32 nTokenCount = aPath.GetTokenCount( ';' ); 714 aPath = aPath.GetToken( 715 sal::static_int_cast< xub_StrLen >( 716 nTokenCount ? ( nTokenCount - 1 ) : 0 ), 717 ';' ); 718 } 719 720 sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG; 721 SFX_REQUEST_ARG( rReq, pSystemDialogItem, SfxBoolItem, SID_FILE_DIALOG, sal_False ); 722 if ( pSystemDialogItem ) 723 nDialog = pSystemDialogItem->GetValue() ? SFX2_IMPL_DIALOG_SYSTEM : SFX2_IMPL_DIALOG_OOO; 724 725 String sStandardDir; 726 727 SFX_REQUEST_ARG( rReq, pStandardDirItem, SfxStringItem, SID_STANDARD_DIR, sal_False ); 728 if ( pStandardDirItem ) 729 sStandardDir = pStandardDirItem->GetValue(); 730 731 ::com::sun::star::uno::Sequence< ::rtl::OUString > aBlackList; 732 733 SFX_REQUEST_ARG( rReq, pBlackListItem, SfxStringListItem, SID_BLACK_LIST, sal_False ); 734 if ( pBlackListItem ) 735 pBlackListItem->GetStringList( aBlackList ); 736 737 738 sal_uIntPtr nErr = sfx2::FileOpenDialog_Impl( 739 WB_OPEN | SFXWB_MULTISELECTION | SFXWB_SHOWVERSIONS, String(), pURLList, aFilter, pSet, &aPath, nDialog, sStandardDir, aBlackList ); 740 741 if ( nErr == ERRCODE_ABORT ) 742 { 743 delete pURLList; 744 return; 745 } 746 747 rReq.SetArgs( *(SfxAllItemSet*)pSet ); 748 if (aFilter.Len() >0 ) 749 rReq.AppendItem( SfxStringItem( SID_FILTER_NAME, aFilter ) ); 750 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); 751 rReq.AppendItem( SfxStringItem( SID_REFERER, String::CreateFromAscii(SFX_REFERER_USER) ) ); 752 delete pSet; 753 754 if ( pURLList->Count() ) 755 { 756 if ( nSID == SID_OPENTEMPLATE ) 757 rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_False ) ); 758 759 // This helper wraps an existing (or may new created InteractionHandler) 760 // intercept all incoming interactions and provide useful informations 761 // later if the following transaction was finished. 762 763 ::framework::PreventDuplicateInteraction* pHandler = new ::framework::PreventDuplicateInteraction(::comphelper::getProcessServiceFactory()); 764 css::uno::Reference< css::task::XInteractionHandler > xHandler (static_cast< css::task::XInteractionHandler* >(pHandler), css::uno::UNO_QUERY); 765 css::uno::Reference< css::task::XInteractionHandler > xWrappedHandler; 766 767 // wrap existing handler or create new UUI handler 768 SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False); 769 if (pInteractionItem) 770 { 771 pInteractionItem->GetValue() >>= xWrappedHandler; 772 rReq.RemoveItem( SID_INTERACTIONHANDLER ); 773 } 774 if (xWrappedHandler.is()) 775 pHandler->setHandler(xWrappedHandler); 776 else 777 pHandler->useDefaultUUIHandler(); 778 rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHandler)) ); 779 780 // define rules for this handler 781 css::uno::Type aInteraction = ::getCppuType(static_cast< css::task::ErrorCodeRequest* >(0)); 782 ::framework::PreventDuplicateInteraction::InteractionInfo aRule (aInteraction, 1); 783 pHandler->addInteractionRule(aRule); 784 785 for ( sal_uInt16 i = 0; i < pURLList->Count(); ++i ) 786 { 787 String aURL = *(pURLList->GetObject(i)); 788 rReq.RemoveItem( SID_FILE_NAME ); 789 rReq.AppendItem( SfxStringItem( SID_FILE_NAME, aURL ) ); 790 791 // execute synchronous, to avoid next document load at reschedule 792 // TODO/LATER: use URLList argument and always remove one document after another, each step in asychronous execution, until finished 793 // but only if reschedule is a problem 794 GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, *rReq.GetArgs() ); 795 796 // check for special interaction "NO MORE DOCUMENTS ALLOWED" and 797 // break loop then. Otherwise we risk showing the same interaction more then once. 798 if ( pHandler->getInteractionInfo(aInteraction, &aRule) ) 799 { 800 if (aRule.m_nCallCount > 0) 801 { 802 if (aRule.m_xRequest.is()) 803 { 804 css::task::ErrorCodeRequest aRequest; 805 if (aRule.m_xRequest->getRequest() >>= aRequest) 806 { 807 if (aRequest.ErrCode == 808 sal::static_int_cast< sal_Int32 >( 809 ERRCODE_SFX_NOMOREDOCUMENTSALLOWED)) 810 break; 811 } 812 } 813 } 814 } 815 } 816 817 delete pURLList; 818 return; 819 } 820 delete pURLList; 821 } 822 823 if ( !rReq.IsSynchronCall() ) 824 { 825 // now check whether a stream is already there 826 // if not: download it in a thread and restart the call 827 // return; 828 } 829 830 sal_Bool bHyperlinkUsed = sal_False; 831 832 if ( SID_OPENURL == nSID ) 833 { 834 // SID_OPENURL does the same as SID_OPENDOC! 835 rReq.SetSlot( SID_OPENDOC ); 836 nSID = SID_OPENDOC; 837 } 838 else if ( nSID == SID_OPENTEMPLATE ) 839 { 840 rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_False ) ); 841 } 842 // pass URL to OS by using ShellExecuter or open it internal 843 // if it seems to be an own format. 844 /* Attention! 845 There exist two possibilities to open hyperlinks: 846 a) using SID_OPENHYPERLINK (new) 847 b) using SID_BROWSE (old) 848 */ 849 else if ( nSID == SID_OPENHYPERLINK ) 850 { 851 rReq.SetSlot( SID_OPENDOC ); 852 nSID = SID_OPENDOC; 853 bHyperlinkUsed = sal_True; 854 } 855 856 // no else here! It's optional ... 857 if (!bHyperlinkUsed) 858 { 859 SFX_REQUEST_ARG(rReq, pHyperLinkUsedItem, SfxBoolItem, SID_BROWSE, sal_False); 860 if ( pHyperLinkUsedItem ) 861 bHyperlinkUsed = pHyperLinkUsedItem->GetValue(); 862 // no "official" item, so remove it from ItemSet before using UNO-API 863 rReq.RemoveItem( SID_BROWSE ); 864 } 865 866 SFX_REQUEST_ARG( rReq, pFileName, SfxStringItem, SID_FILE_NAME, sal_False ); 867 String aFileName = pFileName->GetValue(); 868 869 String aReferer; 870 SFX_REQUEST_ARG( rReq, pRefererItem, SfxStringItem, SID_REFERER, sal_False ); 871 if ( pRefererItem ) 872 aReferer = pRefererItem->GetValue(); 873 874 SFX_REQUEST_ARG( rReq, pFileFlagsItem, SfxStringItem, SID_OPTIONS, sal_False); 875 if ( pFileFlagsItem ) 876 { 877 String aFileFlags = pFileFlagsItem->GetValue(); 878 aFileFlags.ToUpperAscii(); 879 if ( STRING_NOTFOUND != aFileFlags.Search( 0x0054 ) ) // T = 54h 880 { 881 rReq.RemoveItem( SID_TEMPLATE ); 882 rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_True ) ); 883 } 884 885 if ( STRING_NOTFOUND != aFileFlags.Search( 0x0048 ) ) // H = 48h 886 { 887 rReq.RemoveItem( SID_HIDDEN ); 888 rReq.AppendItem( SfxBoolItem( SID_HIDDEN, sal_True ) ); 889 } 890 891 if ( STRING_NOTFOUND != aFileFlags.Search( 0x0052 ) ) // R = 52h 892 { 893 rReq.RemoveItem( SID_DOC_READONLY ); 894 rReq.AppendItem( SfxBoolItem( SID_DOC_READONLY, sal_True ) ); 895 } 896 897 if ( STRING_NOTFOUND != aFileFlags.Search( 0x0042 ) ) // B = 42h 898 { 899 rReq.RemoveItem( SID_PREVIEW ); 900 rReq.AppendItem( SfxBoolItem( SID_PREVIEW, sal_True ) ); 901 } 902 903 if ( STRING_NOTFOUND != aFileFlags.Search( 0x0053 ) ) // S = 53h 904 { 905 // not supported anymore 906 //rReq.RemoveItem( SID_SILENT ); 907 //rReq.AppendItem( SfxBoolItem( SID_SILENT, sal_True ) ); 908 } 909 910 rReq.RemoveItem( SID_OPTIONS ); 911 } 912 913 // Mark without URL cannot be handled by hyperlink code 914 if ( bHyperlinkUsed && aFileName.Len() && aFileName.GetChar(0) != '#' ) 915 { 916 Reference< ::com::sun::star::document::XTypeDetection > xTypeDetection( 917 ::comphelper::getProcessServiceFactory()->createInstance( 918 ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" )), 919 UNO_QUERY ); 920 if ( xTypeDetection.is() ) 921 { 922 URL aURL; 923 ::rtl::OUString aTypeName; 924 925 aURL.Complete = aFileName; 926 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( 927 ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY ); 928 xTrans->parseStrict( aURL ); 929 INetURLObject aINetURLObject(aURL.Complete); 930 INetProtocol aINetProtocol = aINetURLObject.GetProtocol(); 931 SvtExtendedSecurityOptions aExtendedSecurityOptions; 932 SvtExtendedSecurityOptions::OpenHyperlinkMode eMode = aExtendedSecurityOptions.GetOpenHyperlinkMode(); 933 if ( eMode == SvtExtendedSecurityOptions::OPEN_WITHSECURITYCHECK ) 934 { 935 /*!!! pb: #i49802# no security warning any longer 936 ardovm: Restored security checks in March 2021 */ 937 // Check if file URL is a directory. This is not insecure! 938 sal_Bool bIsDir = aINetURLObject.hasFinalSlash() || 939 ( osl::Directory(aURL.Main).open() == 940 osl::Directory::E_None ); 941 // Use SvtExtendedSecurityOptions::IsSecureHyperlink() 942 // to check the extension of the link destination. 943 sal_Bool bSafeExtension = aExtendedSecurityOptions.IsSecureHyperlink(aURL.Complete); 944 // We consider some protocols unsafe 945 sal_Bool bUnsafeProtocol; 946 switch (aINetProtocol) { 947 case INET_PROT_HTTP: 948 case INET_PROT_HTTPS: 949 bSafeExtension = true; // trust the browser to prevent unsafe extensions 950 // case INET_PROT_FTP: 951 case INET_PROT_VND_SUN_STAR_HELP: 952 case INET_PROT_MAILTO: 953 bUnsafeProtocol = false; 954 break; 955 default: // Anything else, including INET_PROT_FILE 956 bUnsafeProtocol = true; 957 break; 958 } 959 if ( (!bIsDir && !bSafeExtension) || bUnsafeProtocol ) 960 { 961 // Security check for local files depending on the extension 962 vos::OGuard aGuard( Application::GetSolarMutex() ); 963 Window *pWindow = SFX_APP()->GetTopWindow(); 964 965 String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE )); 966 WarningBox aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_HYPERLINK )); 967 aSecurityWarningBox.SetText( aSecurityWarningBoxTitle ); 968 969 // Replace %s with the real file name 970 String aMsgText = aSecurityWarningBox.GetMessText(); 971 String aMainURL( aURL.Main ); 972 String aFileNameInMsg; 973 974 if (!utl::LocalFileHelper::ConvertURLToPhysicalName( aMainURL, aFileNameInMsg )) { 975 aFileNameInMsg = aMainURL; 976 } 977 aMsgText.SearchAndReplaceAscii( "%s", aFileNameInMsg ); 978 aSecurityWarningBox.SetMessText( aMsgText ); 979 980 if( aSecurityWarningBox.Execute() == RET_NO ) 981 return; 982 } 983 } 984 else if ( eMode == SvtExtendedSecurityOptions::OPEN_NEVER && aINetProtocol != INET_PROT_VND_SUN_STAR_HELP ) 985 { 986 vos::OGuard aGuard( Application::GetSolarMutex() ); 987 Window *pWindow = SFX_APP()->GetTopWindow(); 988 989 String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE )); 990 WarningBox aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_NO_HYPERLINKS )); 991 aSecurityWarningBox.SetText( aSecurityWarningBoxTitle ); 992 aSecurityWarningBox.Execute(); 993 return; 994 } 995 996 aTypeName = xTypeDetection->queryTypeByURL( aURL.Main ); 997 SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher(); 998 const SfxFilter* pFilter = rMatcher.GetFilter4EA( aTypeName ); 999 if ( !pFilter || !( pFilter->IsOwnFormat() )) 1000 { 1001 // hyperlink does not link to own type => special handling (http, ftp) browser and (other external protocols) OS 1002 Reference< XSystemShellExecute > xSystemShellExecute( 1003 com::sun::star::system::SystemShellExecute::create( 1004 ::comphelper::getProcessComponentContext() ) ); 1005 if ( xSystemShellExecute.is() ) 1006 { 1007 if ( aINetProtocol == INET_PROT_MAILTO ) 1008 { 1009 // don't dispatch mailto hyperlink to desktop dispatcher 1010 rReq.RemoveItem( SID_TARGETNAME ); 1011 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_self") ) ); 1012 } 1013 else if ( aINetProtocol == INET_PROT_FTP || 1014 aINetProtocol == INET_PROT_HTTP || 1015 aINetProtocol == INET_PROT_HTTPS ) 1016 { 1017 try 1018 { 1019 // start browser 1020 ::rtl::OUString aURLString( aURL.Complete ); 1021 xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS ); 1022 } 1023 catch ( ::com::sun::star::lang::IllegalArgumentException& ) 1024 { 1025 vos::OGuard aGuard( Application::GetSolarMutex() ); 1026 Window *pWindow = SFX_APP()->GetTopWindow(); 1027 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1028 } 1029 catch ( ::com::sun::star::system::SystemShellExecuteException& ) 1030 { 1031 vos::OGuard aGuard( Application::GetSolarMutex() ); 1032 Window *pWindow = SFX_APP()->GetTopWindow(); 1033 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1034 } 1035 1036 return; 1037 } 1038 else 1039 { 1040 // check for "internal" protocols that should not be forwarded to the system 1041 Sequence < ::rtl::OUString > aProtocols(2); 1042 1043 // add special protocols that always should be treated as internal 1044 aProtocols[0] = ::rtl::OUString::createFromAscii("private:*"); 1045 aProtocols[1] = ::rtl::OUString::createFromAscii("vnd.sun.star.*"); 1046 1047 try 1048 { 1049 // get registered protocol handlers from configuration 1050 Reference < XNameAccess > xAccess( ::comphelper::ConfigurationHelper::openConfig( ::comphelper::getProcessServiceFactory(), 1051 ::rtl::OUString::createFromAscii("org.openoffice.Office.ProtocolHandler/HandlerSet"), ::comphelper::ConfigurationHelper::E_READONLY ), UNO_QUERY ); 1052 if ( xAccess.is() ) 1053 { 1054 Sequence < ::rtl::OUString > aNames = xAccess->getElementNames(); 1055 for ( sal_Int32 nName = 0; nName < aNames.getLength(); nName ++) 1056 { 1057 Reference < XPropertySet > xSet; 1058 Any aRet = xAccess->getByName( aNames[nName] ); 1059 aRet >>= xSet; 1060 if ( xSet.is() ) 1061 { 1062 // copy protocols 1063 aRet = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("Protocols") ); 1064 Sequence < ::rtl::OUString > aTmp; 1065 aRet >>= aTmp; 1066 1067 // todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols 1068 sal_Int32 nLength = aProtocols.getLength(); 1069 aProtocols.realloc( nLength+aTmp.getLength() ); 1070 for ( sal_Int32 n=0; n<aTmp.getLength(); n++ ) 1071 aProtocols[(++nLength)-1] = aTmp[n]; 1072 } 1073 } 1074 } 1075 } 1076 catch ( Exception& ) 1077 { 1078 // registered protocols could not be read 1079 } 1080 1081 sal_Bool bFound = sal_False; 1082 for ( sal_Int32 nProt=0; nProt<aProtocols.getLength(); nProt++ ) 1083 { 1084 WildCard aPattern(aProtocols[nProt]); 1085 if ( aPattern.Matches( aURL.Complete ) ) 1086 { 1087 bFound = sal_True; 1088 break; 1089 } 1090 } 1091 1092 if ( !bFound ) 1093 { 1094 sal_Bool bLoadInternal = sal_False; 1095 1096 // security reservation: => we have to check the referer before executing 1097 if (SFX_APP()->IsSecureURL(rtl::OUString(), &aReferer)) 1098 { 1099 ::rtl::OUString aURLString( aURL.Complete ); 1100 1101 try 1102 { 1103 // give os this file 1104 xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS ); 1105 } 1106 catch ( ::com::sun::star::lang::IllegalArgumentException& ) 1107 { 1108 vos::OGuard aGuard( Application::GetSolarMutex() ); 1109 Window *pWindow = SFX_APP()->GetTopWindow(); 1110 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1111 } 1112 catch ( ::com::sun::star::system::SystemShellExecuteException& ) 1113 { 1114 if ( !pFilter ) 1115 { 1116 vos::OGuard aGuard( Application::GetSolarMutex() ); 1117 Window *pWindow = SFX_APP()->GetTopWindow(); 1118 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1119 } 1120 else 1121 { 1122 rReq.RemoveItem( SID_TARGETNAME ); 1123 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); 1124 bLoadInternal = sal_True; 1125 } 1126 } 1127 } 1128 else 1129 { 1130 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aURL.Complete ); 1131 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED ); 1132 } 1133 1134 if ( !bLoadInternal ) 1135 return; 1136 } 1137 } 1138 } 1139 } 1140 else 1141 { 1142 // hyperlink document must be loaded into a new frame 1143 rReq.RemoveItem( SID_TARGETNAME ); 1144 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); 1145 } 1146 } 1147 } 1148 1149 if ( !SFX_APP()->IsSecureURL( INetURLObject(aFileName), &aReferer ) ) 1150 { 1151 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aFileName ); 1152 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED ); 1153 return; 1154 } 1155 1156 SfxFrame* pTargetFrame = NULL; 1157 Reference< XFrame > xTargetFrame; 1158 1159 SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False); 1160 if ( pFrameItem ) 1161 pTargetFrame = pFrameItem->GetFrame(); 1162 1163 if ( !pTargetFrame ) 1164 { 1165 SFX_REQUEST_ARG(rReq, pUnoFrameItem, SfxUnoFrameItem, SID_FILLFRAME, sal_False); 1166 if ( pUnoFrameItem ) 1167 xTargetFrame = pUnoFrameItem->GetFrame(); 1168 } 1169 1170 if ( !pTargetFrame && !xTargetFrame.is() && SfxViewFrame::Current() ) 1171 pTargetFrame = &SfxViewFrame::Current()->GetFrame(); 1172 1173 // check if caller has set a callback 1174 SFX_REQUEST_ARG(rReq, pLinkItem, SfxLinkItem, SID_DONELINK, sal_False ); 1175 1176 // remove from Itemset, because it confuses the parameter transformation 1177 if ( pLinkItem ) 1178 pLinkItem = (SfxLinkItem*) pLinkItem->Clone(); 1179 1180 rReq.RemoveItem( SID_DONELINK ); 1181 1182 // check if the view must be hidden 1183 sal_Bool bHidden = sal_False; 1184 SFX_REQUEST_ARG(rReq, pHidItem, SfxBoolItem, SID_HIDDEN, sal_False); 1185 if ( pHidItem ) 1186 bHidden = pHidItem->GetValue(); 1187 1188 // This request is a UI call. We have to set the right values inside the MediaDescriptor 1189 // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate. 1190 // But we have to look for already existing values or for real hidden requests. 1191 SFX_REQUEST_ARG(rReq, pPreviewItem, SfxBoolItem, SID_PREVIEW, sal_False); 1192 if (!bHidden && ( !pPreviewItem || !pPreviewItem->GetValue() ) ) 1193 { 1194 SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False); 1195 SFX_REQUEST_ARG(rReq, pMacroExecItem , SfxUInt16Item, SID_MACROEXECMODE , sal_False); 1196 SFX_REQUEST_ARG(rReq, pDocTemplateItem, SfxUInt16Item, SID_UPDATEDOCMODE , sal_False); 1197 1198 if (!pInteractionItem) 1199 { 1200 Reference < ::com::sun::star::task::XInteractionHandler > xHdl( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY ); 1201 if (xHdl.is()) 1202 rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHdl)) ); 1203 } 1204 if (!pMacroExecItem) 1205 rReq.AppendItem( SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::USE_CONFIG) ); 1206 if (!pDocTemplateItem) 1207 rReq.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG) ); 1208 } 1209 1210 // extract target name 1211 ::rtl::OUString aTarget; 1212 SFX_REQUEST_ARG(rReq, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False); 1213 if ( pTargetItem ) 1214 aTarget = pTargetItem->GetValue(); 1215 else 1216 { 1217 SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, sal_False ); 1218 if ( pNewViewItem && pNewViewItem->GetValue() ) 1219 aTarget = String::CreateFromAscii("_blank" ); 1220 } 1221 1222 if ( bHidden ) 1223 { 1224 aTarget = String::CreateFromAscii("_blank"); 1225 DBG_ASSERT( rReq.IsSynchronCall() || pLinkItem, "Hidden load process must be done synchronously!" ); 1226 } 1227 1228 Reference < XController > xController; 1229 // if ( ( !bIsBlankTarget && pFrame ) || pLinkItem || !rReq.IsSynchronCall() ) 1230 // { 1231 // if a frame is given, it must be used for the starting point of the targeting mechanism 1232 // this code is also used if asynchronous loading is possible, because loadComponent always is synchron 1233 if ( !xTargetFrame.is() ) 1234 { 1235 if ( pTargetFrame ) 1236 { 1237 xTargetFrame = pTargetFrame->GetFrameInterface(); 1238 } 1239 else 1240 { 1241 xTargetFrame.set( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); 1242 } 1243 } 1244 1245 // make URL ready 1246 SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_FILE_NAME, sal_False ); 1247 aFileName = pURLItem->GetValue(); 1248 if( aFileName.Len() && aFileName.GetChar(0) == '#' ) // Mark without URL 1249 { 1250 SfxViewFrame *pView = pTargetFrame ? pTargetFrame->GetCurrentViewFrame() : 0; 1251 if ( !pView ) 1252 pView = SfxViewFrame::Current(); 1253 pView->GetViewShell()->JumpToMark( aFileName.Copy(1) ); 1254 rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) ); 1255 return; 1256 } 1257 1258 // convert items to properties for framework API calls 1259 Sequence < PropertyValue > aArgs; 1260 TransformItems( SID_OPENDOC, *rReq.GetArgs(), aArgs ); 1261 1262 // TODO/LATER: either remove LinkItem or create an asynchronous process for it 1263 if( bHidden || pLinkItem || rReq.IsSynchronCall() ) 1264 { 1265 // if loading must be done synchron, we must wait for completion to get a return value 1266 // find frame by myself; I must know the exact frame to get the controller for the return value from it 1267 //if( aTarget.getLength() ) 1268 // xTargetFrame = xTargetFrame->findFrame( aTarget, FrameSearchFlag::ALL ); 1269 Reference < XComponent > xComp; 1270 1271 try 1272 { 1273 xComp = ::comphelper::SynchronousDispatch::dispatch( xTargetFrame, aFileName, aTarget, 0, aArgs ); 1274 // Reference < XComponentLoader > xLoader( xTargetFrame, UNO_QUERY ); 1275 // xComp = xLoader->loadComponentFromURL( aFileName, aTarget, 0, aArgs ); 1276 } 1277 catch(const RuntimeException&) 1278 { 1279 throw; 1280 } 1281 catch(const ::com::sun::star::uno::Exception&) 1282 { 1283 } 1284 1285 Reference < XModel > xModel( xComp, UNO_QUERY ); 1286 if ( xModel.is() ) 1287 xController = xModel->getCurrentController(); 1288 else 1289 xController = Reference < XController >( xComp, UNO_QUERY ); 1290 1291 } 1292 else 1293 { 1294 URL aURL; 1295 aURL.Complete = aFileName; 1296 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY ); 1297 xTrans->parseStrict( aURL ); 1298 1299 Reference < XDispatchProvider > xProv( xTargetFrame, UNO_QUERY ); 1300 Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, aTarget, FrameSearchFlag::ALL ) : Reference < XDispatch >();; 1301 RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - SfxApplication::OpenDocExec_Impl" ); 1302 if ( xDisp.is() ) 1303 xDisp->dispatch( aURL, aArgs ); 1304 } 1305 /* 1306 } 1307 else 1308 { 1309 // synchron loading without a given frame or as blank frame 1310 SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False ); 1311 1312 // Desktop service must exists! dont catch() or check for problems here ... 1313 // But loading of documents can fail by other reasons. Handle it more gracefully. 1314 Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); 1315 Reference < XComponent > xComp; 1316 try 1317 { 1318 xComp = xDesktop->loadComponentFromURL( pFileNameItem->GetValue(), aTarget, 0, aArgs ); 1319 } 1320 catch(const RuntimeException&) 1321 { 1322 throw; 1323 } 1324 catch(const ::com::sun::star::uno::Exception&) 1325 { 1326 xDesktop.clear(); 1327 xComp.clear(); 1328 } 1329 1330 Reference < XModel > xModel( xComp, UNO_QUERY ); 1331 if ( xModel.is() ) 1332 xController = xModel->getCurrentController(); 1333 else 1334 xController = Reference < XController >( xComp, UNO_QUERY ); 1335 }*/ 1336 1337 if ( xController.is() ) 1338 { 1339 // try to find the SfxFrame for the controller 1340 SfxFrame* pCntrFrame = NULL; 1341 for ( SfxViewShell* pShell = SfxViewShell::GetFirst( 0, sal_False ); pShell; pShell = SfxViewShell::GetNext( *pShell, 0, sal_False ) ) 1342 { 1343 if ( pShell->GetController() == xController ) 1344 { 1345 pCntrFrame = &pShell->GetViewFrame()->GetFrame(); 1346 break; 1347 } 1348 } 1349 1350 if ( pCntrFrame ) 1351 { 1352 SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument(); 1353 DBG_ASSERT( pSh, "Controller without ObjectShell ?!" ); 1354 1355 rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) ); 1356 1357 if ( bHidden ) 1358 pSh->RestoreNoDelete(); 1359 } 1360 } 1361 1362 if ( pLinkItem ) 1363 { 1364 SfxPoolItem* pRet = rReq.GetReturnValue()->Clone(); 1365 pLinkItem->GetValue().Call(pRet); 1366 delete pLinkItem; 1367 } 1368 } 1369