Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / appl / appopen.cxx
blob3c619e76eee03880a375bd87328718ac9c8565a2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <com/sun/star/uno/Reference.h>
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/frame/FrameSearchFlag.hpp>
32 #include <com/sun/star/frame/XComponentLoader.hpp>
33 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
34 #include <com/sun/star/frame/XDispatchProvider.hpp>
35 #include <com/sun/star/util/XCloseable.hpp>
36 #include <com/sun/star/frame/XFrame.hpp>
37 #include <com/sun/star/frame/XDesktop.hpp>
38 #include <com/sun/star/frame/DispatchResultState.hpp>
39 #include <com/sun/star/frame/XDispatchResultListener.hpp>
40 #include <com/sun/star/util/URL.hpp>
41 #include <com/sun/star/util/XURLTransformer.hpp>
42 #include <com/sun/star/system/SystemShellExecuteException.hpp>
43 #include <com/sun/star/document/XTypeDetection.hpp>
44 #include <com/sun/star/document/MacroExecMode.hpp>
45 #include <com/sun/star/document/UpdateDocMode.hpp>
46 #include <com/sun/star/task/ErrorCodeRequest.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <com/sun/star/embed/ElementModes.hpp>
49 #include <com/sun/star/container/XNameAccess.hpp>
50 #include <com/sun/star/uno/Sequence.h>
51 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
52 #include <cppuhelper/implbase1.hxx>
53 #include <rtl/ustring.hxx>
55 #include <comphelper/configurationhelper.hxx>
56 #include <comphelper/processfactory.hxx>
57 #include <comphelper/sequenceasvector.hxx>
58 #include <comphelper/storagehelper.hxx>
59 #include <comphelper/string.hxx>
60 #include <comphelper/synchronousdispatch.hxx>
62 #include <vcl/wrkwin.hxx>
63 #include <svl/intitem.hxx>
64 #include <vcl/msgbox.hxx>
65 #include <svl/stritem.hxx>
66 #include <svl/eitem.hxx>
67 #include <sfx2/doctempl.hxx>
68 #include <svtools/sfxecode.hxx>
69 #include <framework/preventduplicateinteraction.hxx>
70 #include <svtools/ehdl.hxx>
71 #include <basic/sbxobj.hxx>
72 #include <svl/urihelper.hxx>
73 #include <unotools/localfilehelper.hxx>
74 #include <unotools/pathoptions.hxx>
75 #include <unotools/moduleoptions.hxx>
76 #include <svtools/templdlg.hxx>
77 #include <osl/file.hxx>
78 #include <unotools/extendedsecurityoptions.hxx>
79 #include <comphelper/docpasswordhelper.hxx>
80 #include <vcl/svapp.hxx>
82 #include <osl/mutex.hxx>
84 #include <rtl/logfile.hxx>
86 #include <sfx2/app.hxx>
87 #include <sfx2/bindings.hxx>
88 #include <sfx2/dispatch.hxx>
89 #include <sfx2/docfile.hxx>
90 #include <sfx2/fcontnr.hxx>
91 #include <sfx2/new.hxx>
92 #include <sfx2/objitem.hxx>
93 #include <sfx2/objsh.hxx>
94 #include <svl/slstitm.hxx>
95 #include "objshimp.hxx"
96 #include "openflag.hxx"
97 #include <sfx2/passwd.hxx>
98 #include "referers.hxx"
99 #include <sfx2/request.hxx>
100 #include "sfx2/sfxresid.hxx"
101 #include <sfx2/viewsh.hxx>
102 #include "app.hrc"
103 #include <sfx2/viewfrm.hxx>
104 #include <sfx2/sfxuno.hxx>
105 #include <sfx2/objface.hxx>
106 #include <sfx2/filedlghelper.hxx>
107 #include <sfx2/docfac.hxx>
108 #include <sfx2/event.hxx>
109 #include <svl/svstdarr.hxx>
110 #include "openuriexternally.hxx"
112 using namespace ::com::sun::star;
113 using namespace ::com::sun::star::beans;
114 using namespace ::com::sun::star::frame;
115 using namespace ::com::sun::star::lang;
116 using namespace ::com::sun::star::uno;
117 using namespace ::com::sun::star::util;
118 using namespace ::com::sun::star::task;
119 using namespace ::com::sun::star::container;
120 using namespace ::cppu;
121 using namespace ::sfx2;
123 namespace css = ::com::sun::star;
125 //=========================================================================
127 class SfxOpenDocStatusListener_Impl : public WeakImplHelper1< XDispatchResultListener >
129 public:
130 sal_Bool bFinished;
131 sal_Bool bSuccess;
132 virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& Event ) throw(RuntimeException);
133 virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException);
134 SfxOpenDocStatusListener_Impl()
135 : bFinished( sal_False )
136 , bSuccess( sal_False )
140 void SAL_CALL SfxOpenDocStatusListener_Impl::dispatchFinished( const DispatchResultEvent& aEvent ) throw(RuntimeException)
142 bSuccess = ( aEvent.State == DispatchResultState::SUCCESS );
143 bFinished = sal_True;
146 void SAL_CALL SfxOpenDocStatusListener_Impl::disposing( const EventObject& ) throw(RuntimeException)
150 SfxObjectShellRef SfxApplication::DocAlreadyLoaded
152 const String& rName, // Name of Documents including path
153 sal_Bool bSilent, // sal_True: do not ask for a new view
154 sal_Bool bActivate, // existing view to be activated
155 sal_Bool bForbidVisible,
156 const String* pPostStr
159 /* [Description]
161 Determines whether a document with the name 'rName' already is loaded and
162 returns a pointer to this document.
164 If the document is not loaded, a 0-pointer is returned.
168 // prepare to search for names as URL
169 INetURLObject aUrlToFind( rName );
170 DBG_ASSERT( aUrlToFind.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL" );
171 String aPostString;
172 if ( pPostStr )
173 aPostString = *pPostStr;
175 // still open?
176 SfxObjectShellRef xDoc;
178 if ( !aUrlToFind.HasError() )
180 // then with the normally open Documents
181 if ( !xDoc.Is() )
183 xDoc = SfxObjectShell::GetFirst( 0, sal_False ); // also hidden Documents
184 while( xDoc.Is() )
186 if ( xDoc->GetMedium() &&
187 xDoc->GetCreateMode() == SFX_CREATE_MODE_STANDARD &&
188 !xDoc->IsAbortingImport() && !xDoc->IsLoading() )
190 // Comparisons between URLs
191 INetURLObject aUrl( xDoc->GetMedium()->GetName() );
192 if ( !aUrl.HasError() && aUrl == aUrlToFind &&
193 (!bForbidVisible || !SfxViewFrame::GetFirst( xDoc, sal_True )) &&
194 !xDoc->IsLoading())
196 break;
199 xDoc = SfxObjectShell::GetNext( *xDoc, 0, sal_False );
204 // Found?
205 if ( xDoc.Is() && bActivate )
207 DBG_ASSERT(!bForbidVisible, "Invisible can not be enabled" );
209 SfxViewFrame* pFrame;
210 for( pFrame = SfxViewFrame::GetFirst( xDoc );
211 pFrame && !pFrame->IsVisible();
212 pFrame = SfxViewFrame::GetNext( *pFrame, xDoc ) ) ;
213 if ( pFrame )
215 SfxViewFrame *pCur = SfxViewFrame::Current();
216 if ( !bSilent && pFrame == pCur )
217 InfoBox( 0, SfxResId(RID_DOCALREADYLOADED_DLG)).Execute();
218 if ( bActivate )
220 pFrame->MakeActive_Impl( sal_True );
224 return xDoc;
227 //====================================================================
229 void SetTemplate_Impl( const String &rFileName,
230 const String &rLongName,
231 SfxObjectShell *pDoc)
233 // write TemplateName to DocumentInfo of document
234 // TemplateDate stays as default (=current date)
235 pDoc->ResetFromTemplate( rLongName, rFileName );
238 //====================================================================
239 class SfxDocPasswordVerifier : public ::comphelper::IDocPasswordVerifier
241 public:
242 inline explicit SfxDocPasswordVerifier( const Reference< embed::XStorage >& rxStorage ) :
243 mxStorage( rxStorage ) {}
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 );
251 private:
252 Reference< embed::XStorage > mxStorage;
255 //--------------------------------------------------------------------
256 ::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
258 o_rEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( rPassword );
259 return verifyEncryptionData( o_rEncryptionData );
263 //--------------------------------------------------------------------
264 ::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
266 ::comphelper::DocPasswordVerifierResult eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
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 );
274 mxStorage->openStreamElement(
275 ::rtl::OUString( "content.xml" ),
276 embed::ElementModes::READ | embed::ElementModes::NOCREATE );
278 // no exception -> success
279 eResult = ::comphelper::DocPasswordVerifierResult_OK;
281 catch( const packages::WrongPasswordException& )
283 eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
285 catch( const uno::Exception& )
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;
291 return eResult;
294 //====================================================================
296 //--------------------------------------------------------------------
298 sal_uInt32 CheckPasswd_Impl
300 SfxObjectShell* pDoc,
301 SfxItemPool& /*rPool*/, // Pool, if a Set has to be created
302 SfxMedium* pFile // the Medium and its Password shold be obtained
305 /* [Description]
307 Ask for the password for a medium, only works if it concerns storage.
308 If the password flag is set in the Document Info, then the password is
309 requested through a user dialogue and the set at the Set of the medium.
310 If the set does not exist the it is created.
313 sal_uIntPtr nRet = ERRCODE_NONE;
315 if( ( !pFile->GetFilter() || pFile->IsStorage() ) )
317 uno::Reference< embed::XStorage > xStorage = pFile->GetStorage( sal_True );
318 if( xStorage.is() )
320 uno::Reference< beans::XPropertySet > xStorageProps( xStorage, uno::UNO_QUERY );
321 if ( xStorageProps.is() )
323 sal_Bool bIsEncrypted = sal_False;
324 try {
325 xStorageProps->getPropertyValue( ::rtl::OUString("HasEncryptedEntries") )
326 >>= bIsEncrypted;
327 } catch( uno::Exception& )
329 // TODO/LATER:
330 // the storage either has no encrypted elements or it's just
331 // does not allow to detect it, probably it should be implemented laiter
334 if ( bIsEncrypted )
336 Window* pWin = pDoc ? pDoc->GetDialogParent( pFile ) : NULL;
337 if ( pWin )
338 pWin->Show();
340 nRet = ERRCODE_SFX_CANTGETPASSWD;
342 SfxItemSet *pSet = pFile->GetItemSet();
343 if( pSet )
345 Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = pFile->GetInteractionHandler();
346 if( xInteractionHandler.is() )
348 // use the comphelper password helper to request a password
349 ::rtl::OUString aPassword;
350 SFX_ITEMSET_ARG( pSet, pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
351 if ( pPasswordItem )
352 aPassword = pPasswordItem->GetValue();
354 uno::Sequence< beans::NamedValue > aEncryptionData;
355 SFX_ITEMSET_ARG( pSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False);
356 if ( pEncryptionDataItem )
357 pEncryptionDataItem->GetValue() >>= aEncryptionData;
359 ::rtl::OUString aDocumentName = INetURLObject( pFile->GetOrigURL() ).GetMainURL( INetURLObject::DECODE_WITH_CHARSET );
361 SfxDocPasswordVerifier aVerifier( xStorage );
362 aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
363 aVerifier, aEncryptionData, aPassword, xInteractionHandler, aDocumentName, comphelper::DocPasswordRequestType_STANDARD );
365 pSet->ClearItem( SID_PASSWORD );
366 pSet->ClearItem( SID_ENCRYPTIONDATA );
368 if ( aEncryptionData.getLength() > 0 )
370 pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
374 // update the version list of the medium using the new password
375 pFile->GetVersionList();
377 catch( uno::Exception& )
379 // TODO/LATER: set the error code
382 nRet = ERRCODE_NONE;
384 else
385 nRet = ERRCODE_IO_ABORT;
390 else
392 OSL_FAIL( "A storage must implement XPropertySet interface!" );
393 nRet = ERRCODE_SFX_CANTGETPASSWD;
398 return nRet;
401 //--------------------------------------------------------------------
404 sal_uIntPtr SfxApplication::LoadTemplate( SfxObjectShellLock& xDoc, const String &rFileName, sal_Bool bCopy, SfxItemSet* pSet )
406 const SfxFilter* pFilter = NULL;
407 SfxMedium aMedium( rFileName, ( STREAM_READ | STREAM_SHARE_DENYNONE ) );
409 if ( !aMedium.GetStorage( sal_True ).is() )
410 aMedium.GetInStream();
412 if ( aMedium.GetError() )
414 delete pSet;
415 return aMedium.GetErrorCode();
418 aMedium.UseInteractionHandler( sal_True );
419 sal_uIntPtr nErr = GetFilterMatcher().GuessFilter( aMedium,&pFilter,SFX_FILTER_TEMPLATE, 0 );
420 if ( 0 != nErr)
422 delete pSet;
423 return ERRCODE_SFX_NOTATEMPLATE;
426 if( !pFilter || !pFilter->IsAllowedAsTemplate() )
428 delete pSet;
429 return ERRCODE_SFX_NOTATEMPLATE;
432 if ( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER )
434 DBG_ASSERT( !xDoc.Is(), "Sorry, not implemented!" );
435 delete pSet;
436 SfxStringItem aName( SID_FILE_NAME, rFileName );
437 SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii("private:user") );
438 SfxStringItem aFlags( SID_OPTIONS, String::CreateFromAscii("T") );
439 SfxBoolItem aHidden( SID_HIDDEN, sal_True );
440 const SfxPoolItem *pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, &aName, &aHidden, &aReferer, &aFlags, 0L );
441 const SfxObjectItem *pObj = PTR_CAST( SfxObjectItem, pRet );
442 if ( pObj )
443 xDoc = PTR_CAST( SfxObjectShell, pObj->GetShell() );
444 else
446 const SfxViewFrameItem *pView = PTR_CAST( SfxViewFrameItem, pRet );
447 if ( pView )
449 SfxViewFrame *pFrame = pView->GetFrame();
450 if ( pFrame )
451 xDoc = pFrame->GetObjectShell();
455 if ( !xDoc.Is() )
456 return ERRCODE_SFX_DOLOADFAILED;
458 else
460 if ( !xDoc.Is() )
461 xDoc = SfxObjectShell::CreateObject( pFilter->GetServiceName() );
463 SfxMedium *pMedium = new SfxMedium( rFileName, STREAM_STD_READ, pFilter, pSet );
464 if(!xDoc->DoLoad(pMedium))
466 ErrCode nErrCode = xDoc->GetErrorCode();
467 xDoc->DoClose();
468 xDoc.Clear();
469 return nErrCode;
473 if( bCopy )
477 // TODO: introduce error handling
479 uno::Reference< embed::XStorage > xTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
480 if( !xTempStorage.is() )
481 throw uno::RuntimeException();
483 xDoc->GetStorage()->copyToStorage( xTempStorage );
485 if ( !xDoc->DoSaveCompleted( new SfxMedium( xTempStorage, String() ) ) )
486 throw uno::RuntimeException();
488 catch( uno::Exception& )
490 xDoc->DoClose();
491 xDoc.Clear();
493 // TODO: transfer correct error outside
494 return ERRCODE_SFX_GENERAL;
497 SetTemplate_Impl( rFileName, String(), xDoc );
499 else
500 SetTemplate_Impl( rFileName, String(), xDoc );
502 xDoc->SetNoName();
503 xDoc->InvalidateName();
504 xDoc->SetModified(sal_False);
505 xDoc->ResetError();
507 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel ( xDoc->GetModel(), ::com::sun::star::uno::UNO_QUERY );
508 if ( xModel.is() )
510 SfxItemSet* pNew = xDoc->GetMedium()->GetItemSet()->Clone();
511 pNew->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
512 pNew->ClearItem( SID_FILTER_NAME );
513 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs;
514 TransformItems( SID_OPENDOC, *pNew, aArgs );
515 sal_Int32 nLength = aArgs.getLength();
516 aArgs.realloc( nLength + 1 );
517 aArgs[nLength].Name = DEFINE_CONST_UNICODE("Title");
518 aArgs[nLength].Value <<= ::rtl::OUString( xDoc->GetTitle( SFX_TITLE_DETECT ) );
519 xModel->attachResource( ::rtl::OUString(), aArgs );
520 delete pNew;
523 return xDoc->GetErrorCode();
526 //--------------------------------------------------------------------
528 void SfxApplication::NewDocDirectExec_Impl( SfxRequest& rReq )
530 SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, sal_False);
531 String aFactName;
532 if ( pFactoryItem )
533 aFactName = pFactoryItem->GetValue();
534 else
535 aFactName = SvtModuleOptions().GetDefaultModuleName();
538 SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, GetPool() );
539 String aFact = String::CreateFromAscii("private:factory/");
540 aFact += aFactName;
541 aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) );
542 aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, GetFrame() ) );
543 aReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii( "_default" ) ) );
545 // TODO/LATER: Should the other arguments be transfered as well?
546 SFX_REQUEST_ARG( rReq, pDefaultPathItem, SfxStringItem, SID_DEFAULTFILEPATH, sal_False);
547 if ( pDefaultPathItem )
548 aReq.AppendItem( *pDefaultPathItem );
549 SFX_REQUEST_ARG( rReq, pDefaultNameItem, SfxStringItem, SID_DEFAULTFILENAME, sal_False);
550 if ( pDefaultNameItem )
551 aReq.AppendItem( *pDefaultNameItem );
553 SFX_APP()->ExecuteSlot( aReq );
554 const SfxViewFrameItem* pItem = PTR_CAST( SfxViewFrameItem, aReq.GetReturnValue() );
555 if ( pItem )
556 rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) );
559 //--------------------------------------------------------------------
561 void SfxApplication::NewDocExec_Impl( SfxRequest& rReq )
563 // No Parameter from BASIC only Factory given?
564 SFX_REQUEST_ARG(rReq, pTemplNameItem, SfxStringItem, SID_TEMPLATE_NAME, sal_False);
565 SFX_REQUEST_ARG(rReq, pTemplFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False);
566 SFX_REQUEST_ARG(rReq, pTemplRegionNameItem, SfxStringItem, SID_TEMPLATE_REGIONNAME, sal_False);
568 SfxObjectShellLock xDoc;
570 String aTemplateRegion, aTemplateName, aTemplateFileName;
571 sal_Bool bDirect = sal_False; // through FileName instead of Region/Template
572 SfxErrorContext aEc(ERRCTX_SFX_NEWDOC);
573 if ( !pTemplNameItem && !pTemplFileNameItem )
575 Window* pTopWin = GetTopWindow();
576 SvtDocumentTemplateDialog* pDocTemplDlg = new SvtDocumentTemplateDialog( NULL );
577 int nRet = pDocTemplDlg->Execute();
578 sal_Bool bNewWin = sal_False;
579 if ( nRet == RET_OK )
581 rReq.Done();
582 if ( pTopWin != GetTopWindow() )
584 // the dialogue opens a document -> a new TopWindow appears
585 pTopWin = GetTopWindow();
586 bNewWin = sal_True;
590 delete pDocTemplDlg;
591 if ( bNewWin && pTopWin )
592 // after the destruction of the dialogue its parent comes to top,
593 // but we want that the new document is on top
594 pTopWin->ToTop();
596 return;
598 else
600 // Template-Name
601 if ( pTemplNameItem )
602 aTemplateName = pTemplNameItem->GetValue();
604 // Template-Region
605 if ( pTemplRegionNameItem )
606 aTemplateRegion = pTemplRegionNameItem->GetValue();
608 // Template-File-Name
609 if ( pTemplFileNameItem )
611 aTemplateFileName = pTemplFileNameItem->GetValue();
612 bDirect = sal_True;
616 sal_uIntPtr lErr = 0;
617 SfxItemSet* pSet = new SfxAllItemSet( GetPool() );
618 pSet->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) );
619 if ( !bDirect )
621 SfxDocumentTemplates aTmpFac;
622 if( !aTemplateFileName.Len() )
623 aTmpFac.GetFull( aTemplateRegion, aTemplateName, aTemplateFileName );
625 if( !aTemplateFileName.Len() )
626 lErr = ERRCODE_SFX_TEMPLATENOTFOUND;
629 INetURLObject aObj( aTemplateFileName );
630 SfxErrorContext aEC( ERRCTX_SFX_LOADTEMPLATE, aObj.PathToFileName() );
632 if ( lErr != ERRCODE_NONE )
634 sal_uIntPtr lFatalErr = ERRCODE_TOERROR(lErr);
635 if ( lFatalErr )
636 ErrorHandler::HandleError(lErr);
638 else
640 SfxCallMode eMode = SFX_CALLMODE_SYNCHRON;
642 const SfxPoolItem *pRet=0;
643 SfxStringItem aReferer( SID_REFERER, DEFINE_CONST_UNICODE("private:user") );
644 SfxStringItem aTarget( SID_TARGETNAME, DEFINE_CONST_UNICODE("_default") );
645 if ( aTemplateFileName.Len() )
647 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" );
649 SfxStringItem aName( SID_FILE_NAME, aObj.GetMainURL( INetURLObject::NO_DECODE ) );
650 SfxStringItem aTemplName( SID_TEMPLATE_NAME, aTemplateName );
651 SfxStringItem aTemplRegionName( SID_TEMPLATE_REGIONNAME, aTemplateRegion );
652 pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, &aTemplName, &aTemplRegionName, 0L );
654 else
656 SfxStringItem aName( SID_FILE_NAME, DEFINE_CONST_UNICODE("private:factory") );
657 pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, 0L );
660 if ( pRet )
661 rReq.SetReturnValue( *pRet );
665 //---------------------------------------------------------------------------
667 namespace {
670 * Check if a given filter type should open the hyperlinked document
671 * natively.
673 * @param rFilter filter object
675 bool lcl_isFilterNativelySupported(const SfxFilter& rFilter)
677 if (rFilter.IsOwnFormat())
678 return true;
680 ::rtl::OUString aName = rFilter.GetFilterName();
681 if (aName.indexOf(::rtl::OUString("MS Excel")) == 0)
682 // We can handle all Excel variants natively.
683 return true;
685 return false;
690 void SfxApplication::OpenDocExec_Impl( SfxRequest& rReq )
692 rtl::OUString aDocService;
693 SFX_REQUEST_ARG(rReq, pDocSrvItem, SfxStringItem, SID_DOC_SERVICE, false);
694 if (pDocSrvItem)
695 aDocService = pDocSrvItem->GetValue();
697 sal_uInt16 nSID = rReq.GetSlot();
698 SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );
699 if ( pFileNameItem )
701 String aCommand( pFileNameItem->GetValue() );
702 const SfxSlot* pSlot = GetInterface()->GetSlot( aCommand );
703 if ( pSlot )
705 pFileNameItem = NULL;
707 else
709 sal_Int32 nIndex = aCommand.SearchAscii("slot:");
710 if ( !nIndex )
712 sal_uInt16 nSlotId = (sal_uInt16) String( aCommand, 5, aCommand.Len()-5 ).ToInt32();
713 if ( nSlotId == SID_OPENDOC )
714 pFileNameItem = NULL;
719 if ( !pFileNameItem )
721 // get FileName from dialog
722 std::vector<rtl::OUString> pURLList;
723 String aFilter;
724 SfxItemSet* pSet = NULL;
725 String aPath;
726 SFX_REQUEST_ARG( rReq, pFolderNameItem, SfxStringItem, SID_PATH, sal_False );
727 if ( pFolderNameItem )
728 aPath = pFolderNameItem->GetValue();
729 else if ( nSID == SID_OPENTEMPLATE )
731 aPath = SvtPathOptions().GetTemplatePath();
732 sal_Int32 nTokenCount = comphelper::string::getTokenCount(aPath, ';');
733 aPath = aPath.GetToken(
734 sal::static_int_cast< xub_StrLen >(
735 nTokenCount ? ( nTokenCount - 1 ) : 0 ),
736 ';' );
739 sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG;
740 SFX_REQUEST_ARG( rReq, pSystemDialogItem, SfxBoolItem, SID_FILE_DIALOG, sal_False );
741 if ( pSystemDialogItem )
742 nDialog = pSystemDialogItem->GetValue() ? SFX2_IMPL_DIALOG_SYSTEM : SFX2_IMPL_DIALOG_OOO;
744 String sStandardDir;
746 SFX_REQUEST_ARG( rReq, pStandardDirItem, SfxStringItem, SID_STANDARD_DIR, sal_False );
747 if ( pStandardDirItem )
748 sStandardDir = pStandardDirItem->GetValue();
750 ::com::sun::star::uno::Sequence< ::rtl::OUString > aBlackList;
752 SFX_REQUEST_ARG( rReq, pBlackListItem, SfxStringListItem, SID_BLACK_LIST, sal_False );
753 if ( pBlackListItem )
754 pBlackListItem->GetStringList( aBlackList );
757 sal_uIntPtr nErr = sfx2::FileOpenDialog_Impl(
758 ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
759 SFXWB_MULTISELECTION, String(), pURLList,
760 aFilter, pSet, &aPath, nDialog, sStandardDir, aBlackList );
762 if ( nErr == ERRCODE_ABORT )
764 pURLList.clear();
765 return;
768 rReq.SetArgs( *(SfxAllItemSet*)pSet );
769 if (aFilter.Len() >0 )
770 rReq.AppendItem( SfxStringItem( SID_FILTER_NAME, aFilter ) );
771 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
772 rReq.AppendItem( SfxStringItem( SID_REFERER, String::CreateFromAscii(SFX_REFERER_USER) ) );
773 delete pSet;
775 if(!pURLList.empty())
777 if ( nSID == SID_OPENTEMPLATE )
778 rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_False ) );
780 // This helper wraps an existing (or may new created InteractionHandler)
781 // intercept all incoming interactions and provide usefull informations
782 // later if the following transaction was finished.
784 ::framework::PreventDuplicateInteraction* pHandler = new ::framework::PreventDuplicateInteraction(::comphelper::getProcessServiceFactory());
785 css::uno::Reference< css::task::XInteractionHandler > xHandler (static_cast< css::task::XInteractionHandler* >(pHandler), css::uno::UNO_QUERY);
786 css::uno::Reference< css::task::XInteractionHandler > xWrappedHandler;
788 // wrap existing handler or create new UUI handler
789 SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
790 if (pInteractionItem)
792 pInteractionItem->GetValue() >>= xWrappedHandler;
793 rReq.RemoveItem( SID_INTERACTIONHANDLER );
795 if (xWrappedHandler.is())
796 pHandler->setHandler(xWrappedHandler);
797 else
798 pHandler->useDefaultUUIHandler();
799 rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHandler)) );
801 // define rules for this handler
802 css::uno::Type aInteraction = ::getCppuType(static_cast< css::task::ErrorCodeRequest* >(0));
803 ::framework::PreventDuplicateInteraction::InteractionInfo aRule (aInteraction, 1);
804 pHandler->addInteractionRule(aRule);
806 if (!aDocService.isEmpty())
808 rReq.RemoveItem(SID_DOC_SERVICE);
809 rReq.AppendItem(SfxStringItem(SID_DOC_SERVICE, aDocService));
812 for(std::vector<rtl::OUString>::const_iterator i = pURLList.begin(); i != pURLList.end(); ++i)
814 rReq.RemoveItem( SID_FILE_NAME );
815 rReq.AppendItem( SfxStringItem( SID_FILE_NAME, *i ) );
817 // Run synchronous, so that not the next document is loaded
818 // when rescheduling
819 // TODO/LATER: use URLList argument and always remove one document after another, each step in asychronous execution, until finished
820 // but only if reschedule is a problem
821 GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, *rReq.GetArgs() );
823 // check for special interaction "NO MORE DOCUMENTS ALLOWED" and
824 // break loop then. Otherwise we risk showing the same interaction more then once.
825 if ( pHandler->getInteractionInfo(aInteraction, &aRule) )
827 if (aRule.m_nCallCount > 0)
829 if (aRule.m_xRequest.is())
831 css::task::ErrorCodeRequest aRequest;
832 if (aRule.m_xRequest->getRequest() >>= aRequest)
834 if (aRequest.ErrCode ==
835 sal::static_int_cast< sal_Int32 >(
836 ERRCODE_SFX_NOMOREDOCUMENTSALLOWED))
837 break;
844 pURLList.clear();
845 return;
847 pURLList.clear();
850 sal_Bool bHyperlinkUsed = sal_False;
852 if ( SID_OPENURL == nSID )
854 // SID_OPENURL does the same as SID_OPENDOC!
855 rReq.SetSlot( SID_OPENDOC );
856 nSID = SID_OPENDOC;
858 else if ( nSID == SID_OPENTEMPLATE )
860 rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_False ) );
862 // pass URL to OS by using ShellExecuter or open it internal
863 // if it seams to be an own format.
864 /* Attention!
865 There exist two possibilities to open hyperlinks:
866 a) using SID_OPENHYPERLINK (new)
867 b) using SID_BROWSE (old)
869 else if ( nSID == SID_OPENHYPERLINK )
871 rReq.SetSlot( SID_OPENDOC );
872 nSID = SID_OPENDOC;
873 bHyperlinkUsed = sal_True;
876 // no else here! It's optional ...
877 if (!bHyperlinkUsed)
879 SFX_REQUEST_ARG(rReq, pHyperLinkUsedItem, SfxBoolItem, SID_BROWSE, sal_False);
880 if ( pHyperLinkUsedItem )
881 bHyperlinkUsed = pHyperLinkUsedItem->GetValue();
882 // no "official" item, so remove it from ItemSet before using UNO-API
883 rReq.RemoveItem( SID_BROWSE );
886 SFX_REQUEST_ARG( rReq, pFileName, SfxStringItem, SID_FILE_NAME, sal_False );
887 String aFileName = pFileName->GetValue();
889 String aReferer;
890 SFX_REQUEST_ARG( rReq, pRefererItem, SfxStringItem, SID_REFERER, sal_False );
891 if ( pRefererItem )
892 aReferer = pRefererItem->GetValue();
894 SFX_REQUEST_ARG( rReq, pFileFlagsItem, SfxStringItem, SID_OPTIONS, sal_False);
895 if ( pFileFlagsItem )
897 String aFileFlags = pFileFlagsItem->GetValue();
898 aFileFlags.ToUpperAscii();
899 if ( STRING_NOTFOUND != aFileFlags.Search( 0x0054 ) ) // T = 54h
901 rReq.RemoveItem( SID_TEMPLATE );
902 rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_True ) );
905 if ( STRING_NOTFOUND != aFileFlags.Search( 0x0048 ) ) // H = 48h
907 rReq.RemoveItem( SID_HIDDEN );
908 rReq.AppendItem( SfxBoolItem( SID_HIDDEN, sal_True ) );
911 if ( STRING_NOTFOUND != aFileFlags.Search( 0x0052 ) ) // R = 52h
913 rReq.RemoveItem( SID_DOC_READONLY );
914 rReq.AppendItem( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
917 if ( STRING_NOTFOUND != aFileFlags.Search( 0x0042 ) ) // B = 42h
919 rReq.RemoveItem( SID_PREVIEW );
920 rReq.AppendItem( SfxBoolItem( SID_PREVIEW, sal_True ) );
923 rReq.RemoveItem( SID_OPTIONS );
926 // Mark without URL cannot be handled by hyperlink code
927 if ( bHyperlinkUsed && aFileName.Len() && aFileName.GetChar(0) != '#' )
929 Reference< ::com::sun::star::document::XTypeDetection > xTypeDetection(
930 ::comphelper::getProcessServiceFactory()->createInstance(
931 ::rtl::OUString("com.sun.star.document.TypeDetection")),
932 UNO_QUERY );
933 if ( xTypeDetection.is() )
935 URL aURL;
936 ::rtl::OUString aTypeName;
938 aURL.Complete = aFileName;
939 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance(
940 ::rtl::OUString("com.sun.star.util.URLTransformer")), UNO_QUERY );
941 xTrans->parseStrict( aURL );
943 INetProtocol aINetProtocol = INetURLObject( aURL.Complete ).GetProtocol();
944 SvtExtendedSecurityOptions aExtendedSecurityOptions;
945 SvtExtendedSecurityOptions::OpenHyperlinkMode eMode = aExtendedSecurityOptions.GetOpenHyperlinkMode();
947 if ( eMode == SvtExtendedSecurityOptions::OPEN_NEVER && aINetProtocol != INET_PROT_VND_SUN_STAR_HELP )
949 SolarMutexGuard aGuard;
950 Window *pWindow = SFX_APP()->GetTopWindow();
952 String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE ));
953 WarningBox aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_NO_HYPERLINKS ));
954 aSecurityWarningBox.SetText( aSecurityWarningBoxTitle );
955 aSecurityWarningBox.Execute();
956 return;
959 aTypeName = xTypeDetection->queryTypeByURL( aURL.Main );
960 SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher();
961 const SfxFilter* pFilter = rMatcher.GetFilter4EA( aTypeName );
962 if (!pFilter || !lcl_isFilterNativelySupported(*pFilter))
964 // hyperlink does not link to own type => special handling (http, ftp) browser and (other external protocols) OS
965 if ( aINetProtocol == INET_PROT_MAILTO )
967 // don't dispatch mailto hyperlink to desktop dispatcher
968 rReq.RemoveItem( SID_TARGETNAME );
969 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_self") ) );
971 else if ( aINetProtocol == INET_PROT_FTP ||
972 aINetProtocol == INET_PROT_HTTP ||
973 aINetProtocol == INET_PROT_HTTPS )
975 sfx2::openUriExternally(aURL.Complete, true);
976 return;
978 else
980 // check for "internal" protocols that should not be forwarded to the system
981 Sequence < ::rtl::OUString > aProtocols(2);
983 // add special protocols that always should be treated as internal
984 aProtocols[0] = ::rtl::OUString("private:*");
985 aProtocols[1] = ::rtl::OUString("vnd.sun.star.*");
989 // get registered protocol handlers from configuration
990 Reference < XNameAccess > xAccess( ::comphelper::ConfigurationHelper::openConfig( ::comphelper::getProcessServiceFactory(),
991 ::rtl::OUString("org.openoffice.Office.ProtocolHandler/HandlerSet"), ::comphelper::ConfigurationHelper::E_READONLY ), UNO_QUERY );
992 if ( xAccess.is() )
994 Sequence < ::rtl::OUString > aNames = xAccess->getElementNames();
995 for ( sal_Int32 nName = 0; nName < aNames.getLength(); nName ++)
997 Reference < XPropertySet > xSet;
998 Any aRet = xAccess->getByName( aNames[nName] );
999 aRet >>= xSet;
1000 if ( xSet.is() )
1002 // copy protocols
1003 aRet = xSet->getPropertyValue( ::rtl::OUString("Protocols") );
1004 Sequence < ::rtl::OUString > aTmp;
1005 aRet >>= aTmp;
1007 // todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols
1008 sal_Int32 nLength = aProtocols.getLength();
1009 aProtocols.realloc( nLength+aTmp.getLength() );
1010 for ( sal_Int32 n=0; n<aTmp.getLength(); n++ )
1011 aProtocols[(++nLength)-1] = aTmp[n];
1016 catch ( Exception& )
1018 // registered protocols could not be read
1021 sal_Bool bFound = sal_False;
1022 for ( sal_Int32 nProt=0; nProt<aProtocols.getLength(); nProt++ )
1024 WildCard aPattern(aProtocols[nProt]);
1025 if ( aPattern.Matches( aURL.Complete ) )
1027 bFound = sal_True;
1028 break;
1032 if ( !bFound )
1034 sal_Bool bLoadInternal = sal_False;
1036 // security reservation: => we have to check the referer before executing
1037 if (SFX_APP()->IsSecureURL(rtl::OUString(), &aReferer))
1041 sfx2::openUriExternally(
1042 aURL.Complete, pFilter == 0);
1044 catch ( ::com::sun::star::system::SystemShellExecuteException& )
1046 rReq.RemoveItem( SID_TARGETNAME );
1047 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
1048 bLoadInternal = sal_True;
1051 else
1053 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aURL.Complete );
1054 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
1057 if ( !bLoadInternal )
1058 return;
1062 else
1064 // hyperlink document must be loaded into a new frame
1065 rReq.RemoveItem( SID_TARGETNAME );
1066 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
1071 if ( !SFX_APP()->IsSecureURL( INetURLObject(aFileName), &aReferer ) )
1073 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aFileName );
1074 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
1075 return;
1078 SfxFrame* pTargetFrame = NULL;
1079 Reference< XFrame > xTargetFrame;
1081 SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False);
1082 if ( pFrameItem )
1083 pTargetFrame = pFrameItem->GetFrame();
1085 if ( !pTargetFrame )
1087 SFX_REQUEST_ARG(rReq, pUnoFrameItem, SfxUnoFrameItem, SID_FILLFRAME, sal_False);
1088 if ( pUnoFrameItem )
1089 xTargetFrame = pUnoFrameItem->GetFrame();
1092 if ( !pTargetFrame && !xTargetFrame.is() && SfxViewFrame::Current() )
1093 pTargetFrame = &SfxViewFrame::Current()->GetFrame();
1095 // check if caller has set a callback
1096 SFX_REQUEST_ARG(rReq, pLinkItem, SfxLinkItem, SID_DONELINK, sal_False );
1098 // remove from Itemset, because it confuses the parameter transformation
1099 if ( pLinkItem )
1100 pLinkItem = (SfxLinkItem*) pLinkItem->Clone();
1102 rReq.RemoveItem( SID_DONELINK );
1104 // check if the view must be hidden
1105 sal_Bool bHidden = sal_False;
1106 SFX_REQUEST_ARG(rReq, pHidItem, SfxBoolItem, SID_HIDDEN, sal_False);
1107 if ( pHidItem )
1108 bHidden = pHidItem->GetValue();
1110 // This request is a UI call. We have to set the right values inside the MediaDescriptor
1111 // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate.
1112 // But we have to look for already existing values or for real hidden requests.
1113 SFX_REQUEST_ARG(rReq, pPreviewItem, SfxBoolItem, SID_PREVIEW, sal_False);
1114 if (!bHidden && ( !pPreviewItem || !pPreviewItem->GetValue() ) )
1116 SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
1117 SFX_REQUEST_ARG(rReq, pMacroExecItem , SfxUInt16Item, SID_MACROEXECMODE , sal_False);
1118 SFX_REQUEST_ARG(rReq, pDocTemplateItem, SfxUInt16Item, SID_UPDATEDOCMODE , sal_False);
1120 if (!pInteractionItem)
1122 Reference < ::com::sun::star::task::XInteractionHandler > xHdl( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY );
1123 if (xHdl.is())
1124 rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHdl)) );
1126 if (!pMacroExecItem)
1127 rReq.AppendItem( SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::USE_CONFIG) );
1128 if (!pDocTemplateItem)
1129 rReq.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG) );
1132 // extract target name
1133 ::rtl::OUString aTarget;
1134 SFX_REQUEST_ARG(rReq, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False);
1135 if ( pTargetItem )
1136 aTarget = pTargetItem->GetValue();
1137 else
1139 SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, sal_False );
1140 if ( pNewViewItem && pNewViewItem->GetValue() )
1141 aTarget = String::CreateFromAscii("_blank" );
1144 if ( bHidden )
1146 aTarget = String::CreateFromAscii("_blank");
1147 DBG_ASSERT( rReq.IsSynchronCall() || pLinkItem, "Hidden load process must be done synchronously!" );
1150 Reference < XController > xController;
1151 // if a frame is given, it must be used for the starting point of the targetting mechanism
1152 // this code is also used if asynchronous loading is possible, because loadComponent always is synchron
1153 if ( !xTargetFrame.is() )
1155 if ( pTargetFrame )
1157 xTargetFrame = pTargetFrame->GetFrameInterface();
1159 else
1161 xTargetFrame.set( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString("com.sun.star.frame.Desktop")), UNO_QUERY );
1165 // make URL ready
1166 SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_FILE_NAME, sal_False );
1167 aFileName = pURLItem->GetValue();
1168 if( aFileName.Len() && aFileName.GetChar(0) == '#' ) // Mark without URL
1170 SfxViewFrame *pView = pTargetFrame ? pTargetFrame->GetCurrentViewFrame() : 0;
1171 if ( !pView )
1172 pView = SfxViewFrame::Current();
1173 pView->GetViewShell()->JumpToMark( aFileName.Copy(1) );
1174 rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) );
1175 return;
1178 // convert items to properties for framework API calls
1179 Sequence < PropertyValue > aArgs;
1180 TransformItems( SID_OPENDOC, *rReq.GetArgs(), aArgs );
1182 // TODO/LATER: either remove LinkItem or create an asynchronous process for it
1183 if( bHidden || pLinkItem || rReq.IsSynchronCall() )
1185 // if loading must be done synchron, we must wait for completion to get a return value
1186 // find frame by myself; I must konw the exact frame to get the controller for the return value from it
1187 Reference < XComponent > xComp;
1191 xComp = ::comphelper::SynchronousDispatch::dispatch( xTargetFrame, aFileName, aTarget, 0, aArgs );
1193 catch(const RuntimeException&)
1195 throw;
1197 catch(const ::com::sun::star::uno::Exception&)
1201 Reference < XModel > xModel( xComp, UNO_QUERY );
1202 if ( xModel.is() )
1203 xController = xModel->getCurrentController();
1204 else
1205 xController = Reference < XController >( xComp, UNO_QUERY );
1208 else
1210 URL aURL;
1211 aURL.Complete = aFileName;
1212 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString("com.sun.star.util.URLTransformer")), UNO_QUERY );
1213 xTrans->parseStrict( aURL );
1215 Reference < XDispatchProvider > xProv( xTargetFrame, UNO_QUERY );
1216 Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, aTarget, FrameSearchFlag::ALL ) : Reference < XDispatch >();;
1217 RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - SfxApplication::OpenDocExec_Impl" );
1218 if ( xDisp.is() )
1219 xDisp->dispatch( aURL, aArgs );
1222 if ( xController.is() )
1224 // try to find the SfxFrame for the controller
1225 SfxFrame* pCntrFrame = NULL;
1226 for ( SfxViewShell* pShell = SfxViewShell::GetFirst( 0, sal_False ); pShell; pShell = SfxViewShell::GetNext( *pShell, 0, sal_False ) )
1228 if ( pShell->GetController() == xController )
1230 pCntrFrame = &pShell->GetViewFrame()->GetFrame();
1231 break;
1235 if ( pCntrFrame )
1237 SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument();
1238 DBG_ASSERT( pSh, "Controller without ObjectShell ?!" );
1240 rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) );
1242 if ( bHidden )
1243 pSh->RestoreNoDelete();
1247 if ( pLinkItem )
1249 SfxPoolItem* pRet = rReq.GetReturnValue()->Clone();
1250 pLinkItem->GetValue().Call(pRet);
1251 delete pLinkItem;
1255 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */