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