1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sfx2.hxx" 26 #include <com/sun/star/uno/Reference.h> 27 #include <com/sun/star/beans/PropertyValue.hpp> 28 #include <com/sun/star/frame/FrameSearchFlag.hpp> 29 #include <com/sun/star/frame/XComponentLoader.hpp> 30 #include <com/sun/star/frame/XNotifyingDispatch.hpp> 31 #include <com/sun/star/frame/XDispatchProvider.hpp> 32 #include <com/sun/star/util/XCloseable.hpp> 33 #include <com/sun/star/frame/XFrame.hpp> 34 #include <com/sun/star/frame/XDesktop.hpp> 35 #include <com/sun/star/frame/DispatchResultState.hpp> 36 #include <com/sun/star/frame/XDispatchResultListener.hpp> 37 #include <com/sun/star/util/URL.hpp> 38 #include <com/sun/star/util/XURLTransformer.hpp> 39 #include <com/sun/star/system/SystemShellExecute.hpp> 40 #include <com/sun/star/document/XTypeDetection.hpp> 41 #include <com/sun/star/system/SystemShellExecuteFlags.hpp> 42 #include <com/sun/star/document/MacroExecMode.hpp> 43 #include <com/sun/star/document/UpdateDocMode.hpp> 44 #include <com/sun/star/task/ErrorCodeRequest.hpp> 45 #include <com/sun/star/beans/XPropertySet.hpp> 46 #include <com/sun/star/embed/ElementModes.hpp> 47 #include <com/sun/star/container/XNameAccess.hpp> 48 #include <com/sun/star/uno/Sequence.h> 49 #include <comphelper/processfactory.hxx> 50 #include <cppuhelper/implbase1.hxx> 51 #include <rtl/ustring.hxx> 52 53 54 #include <comphelper/storagehelper.hxx> 55 #include <comphelper/synchronousdispatch.hxx> 56 #include <comphelper/configurationhelper.hxx> 57 #include <comphelper/sequenceasvector.hxx> 58 59 #include <vcl/wrkwin.hxx> 60 #include <svl/intitem.hxx> 61 #include <vcl/msgbox.hxx> 62 #include <svl/stritem.hxx> 63 #include <svl/eitem.hxx> 64 #include <sfx2/doctempl.hxx> 65 #include <svtools/sfxecode.hxx> 66 #include <framework/preventduplicateinteraction.hxx> 67 #include <svtools/ehdl.hxx> 68 #include <basic/sbxobj.hxx> 69 #include <svl/urihelper.hxx> 70 #include <unotools/localfilehelper.hxx> 71 #include <unotools/pathoptions.hxx> 72 #include <unotools/moduleoptions.hxx> 73 #include <svtools/templdlg.hxx> 74 #include <osl/file.hxx> 75 #include <unotools/extendedsecurityoptions.hxx> 76 #include <comphelper/docpasswordhelper.hxx> 77 #include <vcl/svapp.hxx> 78 79 #include <vos/mutex.hxx> 80 81 #include <rtl/logfile.hxx> 82 83 #include <sfx2/app.hxx> 84 #include <sfx2/bindings.hxx> 85 #include <sfx2/dispatch.hxx> 86 #include <sfx2/docfile.hxx> 87 #include <sfx2/fcontnr.hxx> 88 #include <sfx2/new.hxx> 89 #include <sfx2/objitem.hxx> 90 #include <sfx2/objsh.hxx> 91 #include <svl/slstitm.hxx> 92 #include "objshimp.hxx" 93 #include "openflag.hxx" 94 #include <sfx2/passwd.hxx> 95 #include "referers.hxx" 96 #include <sfx2/request.hxx> 97 #include "sfx2/sfxresid.hxx" 98 #include <sfx2/viewsh.hxx> 99 #include "app.hrc" 100 #include <sfx2/viewfrm.hxx> 101 #include <sfx2/sfxuno.hxx> 102 #include <sfx2/objface.hxx> 103 #include <sfx2/filedlghelper.hxx> 104 #include <sfx2/docfac.hxx> 105 #include <sfx2/event.hxx> 106 107 #define _SVSTDARR_STRINGSDTOR 108 #include <svl/svstdarr.hxx> 109 110 using namespace ::com::sun::star; 111 using namespace ::com::sun::star::beans; 112 using namespace ::com::sun::star::frame; 113 using namespace ::com::sun::star::lang; 114 using namespace ::com::sun::star::uno; 115 using namespace ::com::sun::star::util; 116 using namespace ::com::sun::star::system; 117 using namespace ::com::sun::star::task; 118 using namespace ::com::sun::star::container; 119 using namespace ::cppu; 120 using namespace ::sfx2; 121 122 namespace css = ::com::sun::star; 123 124 //========================================================================= 125 126 class SfxOpenDocStatusListener_Impl : public WeakImplHelper1< XDispatchResultListener > 127 { 128 public: 129 sal_Bool bFinished; 130 sal_Bool bSuccess; 131 virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& Event ) throw(RuntimeException); 132 virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException); 133 SfxOpenDocStatusListener_Impl() 134 : bFinished( sal_False ) 135 , bSuccess( sal_False ) 136 {} 137 }; 138 139 void SAL_CALL SfxOpenDocStatusListener_Impl::dispatchFinished( const DispatchResultEvent& aEvent ) throw(RuntimeException) 140 { 141 bSuccess = ( aEvent.State == DispatchResultState::SUCCESS ); 142 bFinished = sal_True; 143 } 144 145 void SAL_CALL SfxOpenDocStatusListener_Impl::disposing( const EventObject& ) throw(RuntimeException) 146 { 147 } 148 149 SfxObjectShellRef SfxApplication::DocAlreadyLoaded 150 ( 151 const String& rName, // Name 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 successfully 271 // and immediately 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 transferred 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 useful 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( 992 com::sun::star::system::SystemShellExecute::create( 993 ::comphelper::getProcessComponentContext() ) ); 994 if ( xSystemShellExecute.is() ) 995 { 996 if ( aINetProtocol == INET_PROT_MAILTO ) 997 { 998 // don't dispatch mailto hyperlink to desktop dispatcher 999 rReq.RemoveItem( SID_TARGETNAME ); 1000 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_self") ) ); 1001 } 1002 else if ( aINetProtocol == INET_PROT_FTP || 1003 aINetProtocol == INET_PROT_HTTP || 1004 aINetProtocol == INET_PROT_HTTPS ) 1005 { 1006 try 1007 { 1008 // start browser 1009 ::rtl::OUString aURLString( aURL.Complete ); 1010 xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS ); 1011 } 1012 catch ( ::com::sun::star::lang::IllegalArgumentException& ) 1013 { 1014 vos::OGuard aGuard( Application::GetSolarMutex() ); 1015 Window *pWindow = SFX_APP()->GetTopWindow(); 1016 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1017 } 1018 catch ( ::com::sun::star::system::SystemShellExecuteException& ) 1019 { 1020 vos::OGuard aGuard( Application::GetSolarMutex() ); 1021 Window *pWindow = SFX_APP()->GetTopWindow(); 1022 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1023 } 1024 1025 return; 1026 } 1027 else 1028 { 1029 // check for "internal" protocols that should not be forwarded to the system 1030 Sequence < ::rtl::OUString > aProtocols(2); 1031 1032 // add special protocols that always should be treated as internal 1033 aProtocols[0] = ::rtl::OUString::createFromAscii("private:*"); 1034 aProtocols[1] = ::rtl::OUString::createFromAscii("vnd.sun.star.*"); 1035 1036 try 1037 { 1038 // get registered protocol handlers from configuration 1039 Reference < XNameAccess > xAccess( ::comphelper::ConfigurationHelper::openConfig( ::comphelper::getProcessServiceFactory(), 1040 ::rtl::OUString::createFromAscii("org.openoffice.Office.ProtocolHandler/HandlerSet"), ::comphelper::ConfigurationHelper::E_READONLY ), UNO_QUERY ); 1041 if ( xAccess.is() ) 1042 { 1043 Sequence < ::rtl::OUString > aNames = xAccess->getElementNames(); 1044 for ( sal_Int32 nName = 0; nName < aNames.getLength(); nName ++) 1045 { 1046 Reference < XPropertySet > xSet; 1047 Any aRet = xAccess->getByName( aNames[nName] ); 1048 aRet >>= xSet; 1049 if ( xSet.is() ) 1050 { 1051 // copy protocols 1052 aRet = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("Protocols") ); 1053 Sequence < ::rtl::OUString > aTmp; 1054 aRet >>= aTmp; 1055 1056 // todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols 1057 sal_Int32 nLength = aProtocols.getLength(); 1058 aProtocols.realloc( nLength+aTmp.getLength() ); 1059 for ( sal_Int32 n=0; n<aTmp.getLength(); n++ ) 1060 aProtocols[(++nLength)-1] = aTmp[n]; 1061 } 1062 } 1063 } 1064 } 1065 catch ( Exception& ) 1066 { 1067 // registered protocols could not be read 1068 } 1069 1070 sal_Bool bFound = sal_False; 1071 for ( sal_Int32 nProt=0; nProt<aProtocols.getLength(); nProt++ ) 1072 { 1073 WildCard aPattern(aProtocols[nProt]); 1074 if ( aPattern.Matches( aURL.Complete ) ) 1075 { 1076 bFound = sal_True; 1077 break; 1078 } 1079 } 1080 1081 if ( !bFound ) 1082 { 1083 sal_Bool bLoadInternal = sal_False; 1084 1085 // security reservation: => we have to check the referer before executing 1086 if (SFX_APP()->IsSecureURL(rtl::OUString(), &aReferer)) 1087 { 1088 ::rtl::OUString aURLString( aURL.Complete ); 1089 1090 try 1091 { 1092 // give os this file 1093 xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS ); 1094 } 1095 catch ( ::com::sun::star::lang::IllegalArgumentException& ) 1096 { 1097 vos::OGuard aGuard( Application::GetSolarMutex() ); 1098 Window *pWindow = SFX_APP()->GetTopWindow(); 1099 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1100 } 1101 catch ( ::com::sun::star::system::SystemShellExecuteException& ) 1102 { 1103 if ( !pFilter ) 1104 { 1105 vos::OGuard aGuard( Application::GetSolarMutex() ); 1106 Window *pWindow = SFX_APP()->GetTopWindow(); 1107 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); 1108 } 1109 else 1110 { 1111 rReq.RemoveItem( SID_TARGETNAME ); 1112 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); 1113 bLoadInternal = sal_True; 1114 } 1115 } 1116 } 1117 else 1118 { 1119 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aURL.Complete ); 1120 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED ); 1121 } 1122 1123 if ( !bLoadInternal ) 1124 return; 1125 } 1126 } 1127 } 1128 } 1129 else 1130 { 1131 // hyperlink document must be loaded into a new frame 1132 rReq.RemoveItem( SID_TARGETNAME ); 1133 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); 1134 } 1135 } 1136 } 1137 1138 if ( !SFX_APP()->IsSecureURL( INetURLObject(aFileName), &aReferer ) ) 1139 { 1140 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aFileName ); 1141 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED ); 1142 return; 1143 } 1144 1145 SfxFrame* pTargetFrame = NULL; 1146 Reference< XFrame > xTargetFrame; 1147 1148 SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False); 1149 if ( pFrameItem ) 1150 pTargetFrame = pFrameItem->GetFrame(); 1151 1152 if ( !pTargetFrame ) 1153 { 1154 SFX_REQUEST_ARG(rReq, pUnoFrameItem, SfxUnoFrameItem, SID_FILLFRAME, sal_False); 1155 if ( pUnoFrameItem ) 1156 xTargetFrame = pUnoFrameItem->GetFrame(); 1157 } 1158 1159 if ( !pTargetFrame && !xTargetFrame.is() && SfxViewFrame::Current() ) 1160 pTargetFrame = &SfxViewFrame::Current()->GetFrame(); 1161 1162 // check if caller has set a callback 1163 SFX_REQUEST_ARG(rReq, pLinkItem, SfxLinkItem, SID_DONELINK, sal_False ); 1164 1165 // remove from Itemset, because it confuses the parameter transformation 1166 if ( pLinkItem ) 1167 pLinkItem = (SfxLinkItem*) pLinkItem->Clone(); 1168 1169 rReq.RemoveItem( SID_DONELINK ); 1170 1171 // check if the view must be hidden 1172 sal_Bool bHidden = sal_False; 1173 SFX_REQUEST_ARG(rReq, pHidItem, SfxBoolItem, SID_HIDDEN, sal_False); 1174 if ( pHidItem ) 1175 bHidden = pHidItem->GetValue(); 1176 1177 // This request is a UI call. We have to set the right values inside the MediaDescriptor 1178 // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate. 1179 // But we have to look for already existing values or for real hidden requests. 1180 SFX_REQUEST_ARG(rReq, pPreviewItem, SfxBoolItem, SID_PREVIEW, sal_False); 1181 if (!bHidden && ( !pPreviewItem || !pPreviewItem->GetValue() ) ) 1182 { 1183 SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False); 1184 SFX_REQUEST_ARG(rReq, pMacroExecItem , SfxUInt16Item, SID_MACROEXECMODE , sal_False); 1185 SFX_REQUEST_ARG(rReq, pDocTemplateItem, SfxUInt16Item, SID_UPDATEDOCMODE , sal_False); 1186 1187 if (!pInteractionItem) 1188 { 1189 Reference < ::com::sun::star::task::XInteractionHandler > xHdl( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY ); 1190 if (xHdl.is()) 1191 rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHdl)) ); 1192 } 1193 if (!pMacroExecItem) 1194 rReq.AppendItem( SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::USE_CONFIG) ); 1195 if (!pDocTemplateItem) 1196 rReq.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG) ); 1197 } 1198 1199 // extract target name 1200 ::rtl::OUString aTarget; 1201 SFX_REQUEST_ARG(rReq, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False); 1202 if ( pTargetItem ) 1203 aTarget = pTargetItem->GetValue(); 1204 else 1205 { 1206 SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, sal_False ); 1207 if ( pNewViewItem && pNewViewItem->GetValue() ) 1208 aTarget = String::CreateFromAscii("_blank" ); 1209 } 1210 1211 if ( bHidden ) 1212 { 1213 aTarget = String::CreateFromAscii("_blank"); 1214 DBG_ASSERT( rReq.IsSynchronCall() || pLinkItem, "Hidden load process must be done synchronously!" ); 1215 } 1216 1217 Reference < XController > xController; 1218 // if ( ( !bIsBlankTarget && pFrame ) || pLinkItem || !rReq.IsSynchronCall() ) 1219 // { 1220 // if a frame is given, it must be used for the starting point of the targeting mechanism 1221 // this code is also used if asynchronous loading is possible, because loadComponent always is synchron 1222 if ( !xTargetFrame.is() ) 1223 { 1224 if ( pTargetFrame ) 1225 { 1226 xTargetFrame = pTargetFrame->GetFrameInterface(); 1227 } 1228 else 1229 { 1230 xTargetFrame.set( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); 1231 } 1232 } 1233 1234 // make URL ready 1235 SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_FILE_NAME, sal_False ); 1236 aFileName = pURLItem->GetValue(); 1237 if( aFileName.Len() && aFileName.GetChar(0) == '#' ) // Mark without URL 1238 { 1239 SfxViewFrame *pView = pTargetFrame ? pTargetFrame->GetCurrentViewFrame() : 0; 1240 if ( !pView ) 1241 pView = SfxViewFrame::Current(); 1242 pView->GetViewShell()->JumpToMark( aFileName.Copy(1) ); 1243 rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) ); 1244 return; 1245 } 1246 1247 // convert items to properties for framework API calls 1248 Sequence < PropertyValue > aArgs; 1249 TransformItems( SID_OPENDOC, *rReq.GetArgs(), aArgs ); 1250 1251 // TODO/LATER: either remove LinkItem or create an asynchronous process for it 1252 if( bHidden || pLinkItem || rReq.IsSynchronCall() ) 1253 { 1254 // if loading must be done synchron, we must wait for completion to get a return value 1255 // find frame by myself; I must know the exact frame to get the controller for the return value from it 1256 //if( aTarget.getLength() ) 1257 // xTargetFrame = xTargetFrame->findFrame( aTarget, FrameSearchFlag::ALL ); 1258 Reference < XComponent > xComp; 1259 1260 try 1261 { 1262 xComp = ::comphelper::SynchronousDispatch::dispatch( xTargetFrame, aFileName, aTarget, 0, aArgs ); 1263 // Reference < XComponentLoader > xLoader( xTargetFrame, UNO_QUERY ); 1264 // xComp = xLoader->loadComponentFromURL( aFileName, aTarget, 0, aArgs ); 1265 } 1266 catch(const RuntimeException&) 1267 { 1268 throw; 1269 } 1270 catch(const ::com::sun::star::uno::Exception&) 1271 { 1272 } 1273 1274 Reference < XModel > xModel( xComp, UNO_QUERY ); 1275 if ( xModel.is() ) 1276 xController = xModel->getCurrentController(); 1277 else 1278 xController = Reference < XController >( xComp, UNO_QUERY ); 1279 1280 } 1281 else 1282 { 1283 URL aURL; 1284 aURL.Complete = aFileName; 1285 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY ); 1286 xTrans->parseStrict( aURL ); 1287 1288 Reference < XDispatchProvider > xProv( xTargetFrame, UNO_QUERY ); 1289 Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, aTarget, FrameSearchFlag::ALL ) : Reference < XDispatch >();; 1290 RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - SfxApplication::OpenDocExec_Impl" ); 1291 if ( xDisp.is() ) 1292 xDisp->dispatch( aURL, aArgs ); 1293 } 1294 /* 1295 } 1296 else 1297 { 1298 // synchron loading without a given frame or as blank frame 1299 SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False ); 1300 1301 // Desktop service must exists! dont catch() or check for problems here ... 1302 // But loading of documents can fail by other reasons. Handle it more gracefully. 1303 Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); 1304 Reference < XComponent > xComp; 1305 try 1306 { 1307 xComp = xDesktop->loadComponentFromURL( pFileNameItem->GetValue(), aTarget, 0, aArgs ); 1308 } 1309 catch(const RuntimeException&) 1310 { 1311 throw; 1312 } 1313 catch(const ::com::sun::star::uno::Exception&) 1314 { 1315 xDesktop.clear(); 1316 xComp.clear(); 1317 } 1318 1319 Reference < XModel > xModel( xComp, UNO_QUERY ); 1320 if ( xModel.is() ) 1321 xController = xModel->getCurrentController(); 1322 else 1323 xController = Reference < XController >( xComp, UNO_QUERY ); 1324 }*/ 1325 1326 if ( xController.is() ) 1327 { 1328 // try to find the SfxFrame for the controller 1329 SfxFrame* pCntrFrame = NULL; 1330 for ( SfxViewShell* pShell = SfxViewShell::GetFirst( 0, sal_False ); pShell; pShell = SfxViewShell::GetNext( *pShell, 0, sal_False ) ) 1331 { 1332 if ( pShell->GetController() == xController ) 1333 { 1334 pCntrFrame = &pShell->GetViewFrame()->GetFrame(); 1335 break; 1336 } 1337 } 1338 1339 if ( pCntrFrame ) 1340 { 1341 SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument(); 1342 DBG_ASSERT( pSh, "Controller without ObjectShell ?!" ); 1343 1344 rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) ); 1345 1346 if ( bHidden ) 1347 pSh->RestoreNoDelete(); 1348 } 1349 } 1350 1351 if ( pLinkItem ) 1352 { 1353 SfxPoolItem* pRet = rReq.GetReturnValue()->Clone(); 1354 pLinkItem->GetValue().Call(pRet); 1355 delete pLinkItem; 1356 } 1357 } 1358