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_FTP: 948 case INET_PROT_VND_SUN_STAR_HELP: 949 case INET_PROT_HTTP: 950 case INET_PROT_HTTPS: 951 case INET_PROT_MAILTO: 952 bUnsafeProtocol = false; 953 break; 954 default: // Anything else, including INET_PROT_FILE 955 bUnsafeProtocol = true; 956 break; 957 } 958 if ( (!bIsDir && !bSafeExtension) || bUnsafeProtocol ) 959 { 960 // Security check for local files depending on the extension 961 vos::OGuard aGuard( Application::GetSolarMutex() ); 962 Window *pWindow = SFX_APP()->GetTopWindow(); 963 964 String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE )); 965 WarningBox aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_HYPERLINK )); 966 aSecurityWarningBox.SetText( aSecurityWarningBoxTitle ); 967 968 // Replace %s with the real file name 969 String aMsgText = aSecurityWarningBox.GetMessText(); 970 String aMainURL( aURL.Main ); 971 String aFileNameInMsg; 972 973 if (!utl::LocalFileHelper::ConvertURLToPhysicalName( aMainURL, aFileNameInMsg )) { 974 aFileNameInMsg = aMainURL; 975 } 976 aMsgText.SearchAndReplaceAscii( "%s", aFileNameInMsg ); 977 aSecurityWarningBox.SetMessText( aMsgText ); 978 979 if( aSecurityWarningBox.Execute() == RET_NO ) 980 return; 981 } 982 } 983 else if ( eMode == SvtExtendedSecurityOptions::OPEN_NEVER && aINetProtocol != INET_PROT_VND_SUN_STAR_HELP ) 984 { 985 vos::OGuard aGuard( Application::GetSolarMutex() ); 986 Window *pWindow = SFX_APP()->GetTopWindow(); 987 988 String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE )); 989 WarningBox aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_NO_HYPERLINKS )); 990 aSecurityWarningBox.SetText( aSecurityWarningBoxTitle ); 991 aSecurityWarningBox.Execute(); 992 return; 993 } 994 995 aTypeName = xTypeDetection->queryTypeByURL( aURL.Main ); 996 SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher(); 997 const SfxFilter* pFilter = rMatcher.GetFilter4EA( aTypeName ); 998 if ( !pFilter || !( pFilter->IsOwnFormat() )) 999 { 1000 // hyperlink does not link to own type => special handling (http, ftp) browser and (other external protocols) OS 1001 Reference< XSystemShellExecute > xSystemShellExecute( 1002 com::sun::star::system::SystemShellExecute::create( 1003 ::comphelper::getProcessComponentContext() ) ); 1004 if ( xSystemShellExecute.is() ) 1005 { 1006 if ( aINetProtocol == INET_PROT_MAILTO ) 1007 { 1008 // don't dispatch mailto hyperlink to desktop dispatcher 1009 rReq.RemoveItem( SID_TARGETNAME ); 1010 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_self") ) ); 1011 } 1012 else if ( aINetProtocol == INET_PROT_FTP || 1013 aINetProtocol == INET_PROT_HTTP || 1014 aINetProtocol == INET_PROT_HTTPS ) 1015 { 1016 try 1017 { 1018 // start browser 1019 ::rtl::OUString aURLString( aURL.Complete ); 1020 xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS ); 1021 } 1022 catch ( ::com::sun::star::lang::IllegalArgumentException& ) 1023 { 1024 vos::OGuard aGuard( Application::GetSolarMutex() ); 1025 Window *pWindow = SFX_APP()->GetTopWindow(); 1026 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1027 } 1028 catch ( ::com::sun::star::system::SystemShellExecuteException& ) 1029 { 1030 vos::OGuard aGuard( Application::GetSolarMutex() ); 1031 Window *pWindow = SFX_APP()->GetTopWindow(); 1032 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1033 } 1034 1035 return; 1036 } 1037 else 1038 { 1039 // check for "internal" protocols that should not be forwarded to the system 1040 Sequence < ::rtl::OUString > aProtocols(2); 1041 1042 // add special protocols that always should be treated as internal 1043 aProtocols[0] = ::rtl::OUString::createFromAscii("private:*"); 1044 aProtocols[1] = ::rtl::OUString::createFromAscii("vnd.sun.star.*"); 1045 1046 try 1047 { 1048 // get registered protocol handlers from configuration 1049 Reference < XNameAccess > xAccess( ::comphelper::ConfigurationHelper::openConfig( ::comphelper::getProcessServiceFactory(), 1050 ::rtl::OUString::createFromAscii("org.openoffice.Office.ProtocolHandler/HandlerSet"), ::comphelper::ConfigurationHelper::E_READONLY ), UNO_QUERY ); 1051 if ( xAccess.is() ) 1052 { 1053 Sequence < ::rtl::OUString > aNames = xAccess->getElementNames(); 1054 for ( sal_Int32 nName = 0; nName < aNames.getLength(); nName ++) 1055 { 1056 Reference < XPropertySet > xSet; 1057 Any aRet = xAccess->getByName( aNames[nName] ); 1058 aRet >>= xSet; 1059 if ( xSet.is() ) 1060 { 1061 // copy protocols 1062 aRet = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("Protocols") ); 1063 Sequence < ::rtl::OUString > aTmp; 1064 aRet >>= aTmp; 1065 1066 // todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols 1067 sal_Int32 nLength = aProtocols.getLength(); 1068 aProtocols.realloc( nLength+aTmp.getLength() ); 1069 for ( sal_Int32 n=0; n<aTmp.getLength(); n++ ) 1070 aProtocols[(++nLength)-1] = aTmp[n]; 1071 } 1072 } 1073 } 1074 } 1075 catch ( Exception& ) 1076 { 1077 // registered protocols could not be read 1078 } 1079 1080 sal_Bool bFound = sal_False; 1081 for ( sal_Int32 nProt=0; nProt<aProtocols.getLength(); nProt++ ) 1082 { 1083 WildCard aPattern(aProtocols[nProt]); 1084 if ( aPattern.Matches( aURL.Complete ) ) 1085 { 1086 bFound = sal_True; 1087 break; 1088 } 1089 } 1090 1091 if ( !bFound ) 1092 { 1093 sal_Bool bLoadInternal = sal_False; 1094 1095 // security reservation: => we have to check the referer before executing 1096 if (SFX_APP()->IsSecureURL(rtl::OUString(), &aReferer)) 1097 { 1098 ::rtl::OUString aURLString( aURL.Complete ); 1099 1100 try 1101 { 1102 // give os this file 1103 xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS ); 1104 } 1105 catch ( ::com::sun::star::lang::IllegalArgumentException& ) 1106 { 1107 vos::OGuard aGuard( Application::GetSolarMutex() ); 1108 Window *pWindow = SFX_APP()->GetTopWindow(); 1109 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1110 } 1111 catch ( ::com::sun::star::system::SystemShellExecuteException& ) 1112 { 1113 if ( !pFilter ) 1114 { 1115 vos::OGuard aGuard( Application::GetSolarMutex() ); 1116 Window *pWindow = SFX_APP()->GetTopWindow(); 1117 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1118 } 1119 else 1120 { 1121 rReq.RemoveItem( SID_TARGETNAME ); 1122 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); 1123 bLoadInternal = sal_True; 1124 } 1125 } 1126 } 1127 else 1128 { 1129 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aURL.Complete ); 1130 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED ); 1131 } 1132 1133 if ( !bLoadInternal ) 1134 return; 1135 } 1136 } 1137 } 1138 } 1139 else 1140 { 1141 // hyperlink document must be loaded into a new frame 1142 rReq.RemoveItem( SID_TARGETNAME ); 1143 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); 1144 } 1145 } 1146 } 1147 1148 if ( !SFX_APP()->IsSecureURL( INetURLObject(aFileName), &aReferer ) ) 1149 { 1150 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aFileName ); 1151 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED ); 1152 return; 1153 } 1154 1155 SfxFrame* pTargetFrame = NULL; 1156 Reference< XFrame > xTargetFrame; 1157 1158 SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False); 1159 if ( pFrameItem ) 1160 pTargetFrame = pFrameItem->GetFrame(); 1161 1162 if ( !pTargetFrame ) 1163 { 1164 SFX_REQUEST_ARG(rReq, pUnoFrameItem, SfxUnoFrameItem, SID_FILLFRAME, sal_False); 1165 if ( pUnoFrameItem ) 1166 xTargetFrame = pUnoFrameItem->GetFrame(); 1167 } 1168 1169 if ( !pTargetFrame && !xTargetFrame.is() && SfxViewFrame::Current() ) 1170 pTargetFrame = &SfxViewFrame::Current()->GetFrame(); 1171 1172 // check if caller has set a callback 1173 SFX_REQUEST_ARG(rReq, pLinkItem, SfxLinkItem, SID_DONELINK, sal_False ); 1174 1175 // remove from Itemset, because it confuses the parameter transformation 1176 if ( pLinkItem ) 1177 pLinkItem = (SfxLinkItem*) pLinkItem->Clone(); 1178 1179 rReq.RemoveItem( SID_DONELINK ); 1180 1181 // check if the view must be hidden 1182 sal_Bool bHidden = sal_False; 1183 SFX_REQUEST_ARG(rReq, pHidItem, SfxBoolItem, SID_HIDDEN, sal_False); 1184 if ( pHidItem ) 1185 bHidden = pHidItem->GetValue(); 1186 1187 // This request is a UI call. We have to set the right values inside the MediaDescriptor 1188 // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate. 1189 // But we have to look for already existing values or for real hidden requests. 1190 SFX_REQUEST_ARG(rReq, pPreviewItem, SfxBoolItem, SID_PREVIEW, sal_False); 1191 if (!bHidden && ( !pPreviewItem || !pPreviewItem->GetValue() ) ) 1192 { 1193 SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False); 1194 SFX_REQUEST_ARG(rReq, pMacroExecItem , SfxUInt16Item, SID_MACROEXECMODE , sal_False); 1195 SFX_REQUEST_ARG(rReq, pDocTemplateItem, SfxUInt16Item, SID_UPDATEDOCMODE , sal_False); 1196 1197 if (!pInteractionItem) 1198 { 1199 Reference < ::com::sun::star::task::XInteractionHandler > xHdl( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY ); 1200 if (xHdl.is()) 1201 rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHdl)) ); 1202 } 1203 if (!pMacroExecItem) 1204 rReq.AppendItem( SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::USE_CONFIG) ); 1205 if (!pDocTemplateItem) 1206 rReq.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG) ); 1207 } 1208 1209 // extract target name 1210 ::rtl::OUString aTarget; 1211 SFX_REQUEST_ARG(rReq, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False); 1212 if ( pTargetItem ) 1213 aTarget = pTargetItem->GetValue(); 1214 else 1215 { 1216 SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, sal_False ); 1217 if ( pNewViewItem && pNewViewItem->GetValue() ) 1218 aTarget = String::CreateFromAscii("_blank" ); 1219 } 1220 1221 if ( bHidden ) 1222 { 1223 aTarget = String::CreateFromAscii("_blank"); 1224 DBG_ASSERT( rReq.IsSynchronCall() || pLinkItem, "Hidden load process must be done synchronously!" ); 1225 } 1226 1227 Reference < XController > xController; 1228 // if ( ( !bIsBlankTarget && pFrame ) || pLinkItem || !rReq.IsSynchronCall() ) 1229 // { 1230 // if a frame is given, it must be used for the starting point of the targeting mechanism 1231 // this code is also used if asynchronous loading is possible, because loadComponent always is synchron 1232 if ( !xTargetFrame.is() ) 1233 { 1234 if ( pTargetFrame ) 1235 { 1236 xTargetFrame = pTargetFrame->GetFrameInterface(); 1237 } 1238 else 1239 { 1240 xTargetFrame.set( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); 1241 } 1242 } 1243 1244 // make URL ready 1245 SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_FILE_NAME, sal_False ); 1246 aFileName = pURLItem->GetValue(); 1247 if( aFileName.Len() && aFileName.GetChar(0) == '#' ) // Mark without URL 1248 { 1249 SfxViewFrame *pView = pTargetFrame ? pTargetFrame->GetCurrentViewFrame() : 0; 1250 if ( !pView ) 1251 pView = SfxViewFrame::Current(); 1252 pView->GetViewShell()->JumpToMark( aFileName.Copy(1) ); 1253 rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) ); 1254 return; 1255 } 1256 1257 // convert items to properties for framework API calls 1258 Sequence < PropertyValue > aArgs; 1259 TransformItems( SID_OPENDOC, *rReq.GetArgs(), aArgs ); 1260 1261 // TODO/LATER: either remove LinkItem or create an asynchronous process for it 1262 if( bHidden || pLinkItem || rReq.IsSynchronCall() ) 1263 { 1264 // if loading must be done synchron, we must wait for completion to get a return value 1265 // find frame by myself; I must know the exact frame to get the controller for the return value from it 1266 //if( aTarget.getLength() ) 1267 // xTargetFrame = xTargetFrame->findFrame( aTarget, FrameSearchFlag::ALL ); 1268 Reference < XComponent > xComp; 1269 1270 try 1271 { 1272 xComp = ::comphelper::SynchronousDispatch::dispatch( xTargetFrame, aFileName, aTarget, 0, aArgs ); 1273 // Reference < XComponentLoader > xLoader( xTargetFrame, UNO_QUERY ); 1274 // xComp = xLoader->loadComponentFromURL( aFileName, aTarget, 0, aArgs ); 1275 } 1276 catch(const RuntimeException&) 1277 { 1278 throw; 1279 } 1280 catch(const ::com::sun::star::uno::Exception&) 1281 { 1282 } 1283 1284 Reference < XModel > xModel( xComp, UNO_QUERY ); 1285 if ( xModel.is() ) 1286 xController = xModel->getCurrentController(); 1287 else 1288 xController = Reference < XController >( xComp, UNO_QUERY ); 1289 1290 } 1291 else 1292 { 1293 URL aURL; 1294 aURL.Complete = aFileName; 1295 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY ); 1296 xTrans->parseStrict( aURL ); 1297 1298 Reference < XDispatchProvider > xProv( xTargetFrame, UNO_QUERY ); 1299 Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, aTarget, FrameSearchFlag::ALL ) : Reference < XDispatch >();; 1300 RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - SfxApplication::OpenDocExec_Impl" ); 1301 if ( xDisp.is() ) 1302 xDisp->dispatch( aURL, aArgs ); 1303 } 1304 /* 1305 } 1306 else 1307 { 1308 // synchron loading without a given frame or as blank frame 1309 SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False ); 1310 1311 // Desktop service must exists! dont catch() or check for problems here ... 1312 // But loading of documents can fail by other reasons. Handle it more gracefully. 1313 Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); 1314 Reference < XComponent > xComp; 1315 try 1316 { 1317 xComp = xDesktop->loadComponentFromURL( pFileNameItem->GetValue(), aTarget, 0, aArgs ); 1318 } 1319 catch(const RuntimeException&) 1320 { 1321 throw; 1322 } 1323 catch(const ::com::sun::star::uno::Exception&) 1324 { 1325 xDesktop.clear(); 1326 xComp.clear(); 1327 } 1328 1329 Reference < XModel > xModel( xComp, UNO_QUERY ); 1330 if ( xModel.is() ) 1331 xController = xModel->getCurrentController(); 1332 else 1333 xController = Reference < XController >( xComp, UNO_QUERY ); 1334 }*/ 1335 1336 if ( xController.is() ) 1337 { 1338 // try to find the SfxFrame for the controller 1339 SfxFrame* pCntrFrame = NULL; 1340 for ( SfxViewShell* pShell = SfxViewShell::GetFirst( 0, sal_False ); pShell; pShell = SfxViewShell::GetNext( *pShell, 0, sal_False ) ) 1341 { 1342 if ( pShell->GetController() == xController ) 1343 { 1344 pCntrFrame = &pShell->GetViewFrame()->GetFrame(); 1345 break; 1346 } 1347 } 1348 1349 if ( pCntrFrame ) 1350 { 1351 SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument(); 1352 DBG_ASSERT( pSh, "Controller without ObjectShell ?!" ); 1353 1354 rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) ); 1355 1356 if ( bHidden ) 1357 pSh->RestoreNoDelete(); 1358 } 1359 } 1360 1361 if ( pLinkItem ) 1362 { 1363 SfxPoolItem* pRet = rReq.GetReturnValue()->Clone(); 1364 pLinkItem->GetValue().Call(pRet); 1365 delete pLinkItem; 1366 } 1367 } 1368