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