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>
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
>
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
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" );
173 aPostString
= *pPostStr
;
176 SfxObjectShellRef xDoc
;
178 if ( !aUrlToFind
.HasError() )
180 // then with the normally open Documents
183 xDoc
= SfxObjectShell::GetFirst( 0, sal_False
); // also hidden Documents
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
)) &&
199 xDoc
= SfxObjectShell::GetNext( *xDoc
, 0, sal_False
);
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
) ) ;
215 SfxViewFrame
*pCur
= SfxViewFrame::Current();
216 if ( !bSilent
&& pFrame
== pCur
)
217 InfoBox( 0, SfxResId(RID_DOCALREADYLOADED_DLG
)).Execute();
220 pFrame
->MakeActive_Impl( sal_True
);
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
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
);
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
;
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
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
);
320 uno::Reference
< beans::XPropertySet
> xStorageProps( xStorage
, uno::UNO_QUERY
);
321 if ( xStorageProps
.is() )
323 sal_Bool bIsEncrypted
= sal_False
;
325 xStorageProps
->getPropertyValue( ::rtl::OUString("HasEncryptedEntries") )
327 } catch( uno::Exception
& )
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
336 Window
* pWin
= pDoc
? pDoc
->GetDialogParent( pFile
) : NULL
;
340 nRet
= ERRCODE_SFX_CANTGETPASSWD
;
342 SfxItemSet
*pSet
= pFile
->GetItemSet();
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
);
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
385 nRet
= ERRCODE_IO_ABORT
;
392 OSL_FAIL( "A storage must implement XPropertySet interface!" );
393 nRet
= ERRCODE_SFX_CANTGETPASSWD
;
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() )
415 return aMedium
.GetErrorCode();
418 aMedium
.UseInteractionHandler( sal_True
);
419 sal_uIntPtr nErr
= GetFilterMatcher().GuessFilter( aMedium
,&pFilter
,SFX_FILTER_TEMPLATE
, 0 );
423 return ERRCODE_SFX_NOTATEMPLATE
;
426 if( !pFilter
|| !pFilter
->IsAllowedAsTemplate() )
429 return ERRCODE_SFX_NOTATEMPLATE
;
432 if ( pFilter
->GetFilterFlags() & SFX_FILTER_STARONEFILTER
)
434 DBG_ASSERT( !xDoc
.Is(), "Sorry, not implemented!" );
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
);
443 xDoc
= PTR_CAST( SfxObjectShell
, pObj
->GetShell() );
446 const SfxViewFrameItem
*pView
= PTR_CAST( SfxViewFrameItem
, pRet
);
449 SfxViewFrame
*pFrame
= pView
->GetFrame();
451 xDoc
= pFrame
->GetObjectShell();
456 return ERRCODE_SFX_DOLOADFAILED
;
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();
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
& )
493 // TODO: transfer correct error outside
494 return ERRCODE_SFX_GENERAL
;
497 SetTemplate_Impl( rFileName
, String(), xDoc
);
500 SetTemplate_Impl( rFileName
, String(), xDoc
);
503 xDoc
->InvalidateName();
504 xDoc
->SetModified(sal_False
);
507 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XModel
> xModel ( xDoc
->GetModel(), ::com::sun::star::uno::UNO_QUERY
);
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
);
523 return xDoc
->GetErrorCode();
526 //--------------------------------------------------------------------
528 void SfxApplication::NewDocDirectExec_Impl( SfxRequest
& rReq
)
530 SFX_REQUEST_ARG( rReq
, pFactoryItem
, SfxStringItem
, SID_NEWDOCDIRECT
, sal_False
);
533 aFactName
= pFactoryItem
->GetValue();
535 aFactName
= SvtModuleOptions().GetDefaultModuleName();
538 SfxRequest
aReq( SID_OPENDOC
, SFX_CALLMODE_SYNCHRON
, GetPool() );
539 String aFact
= String::CreateFromAscii("private:factory/");
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() );
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
)
582 if ( pTopWin
!= GetTopWindow() )
584 // the dialogue opens a document -> a new TopWindow appears
585 pTopWin
= GetTopWindow();
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
601 if ( pTemplNameItem
)
602 aTemplateName
= pTemplNameItem
->GetValue();
605 if ( pTemplRegionNameItem
)
606 aTemplateRegion
= pTemplRegionNameItem
->GetValue();
608 // Template-File-Name
609 if ( pTemplFileNameItem
)
611 aTemplateFileName
= pTemplFileNameItem
->GetValue();
616 sal_uIntPtr lErr
= 0;
617 SfxItemSet
* pSet
= new SfxAllItemSet( GetPool() );
618 pSet
->Put( SfxBoolItem( SID_TEMPLATE
, sal_True
) );
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
);
636 ErrorHandler::HandleError(lErr
);
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 );
656 SfxStringItem
aName( SID_FILE_NAME
, DEFINE_CONST_UNICODE("private:factory") );
657 pRet
= GetDispatcher_Impl()->Execute( SID_OPENDOC
, eMode
, &aName
, &aTarget
, &aReferer
, 0L );
661 rReq
.SetReturnValue( *pRet
);
665 //---------------------------------------------------------------------------
670 * Check if a given filter type should open the hyperlinked document
673 * @param rFilter filter object
675 bool lcl_isFilterNativelySupported(const SfxFilter
& rFilter
)
677 if (rFilter
.IsOwnFormat())
680 ::rtl::OUString aName
= rFilter
.GetFilterName();
681 if (aName
.indexOf(::rtl::OUString("MS Excel")) == 0)
682 // We can handle all Excel variants natively.
690 void SfxApplication::OpenDocExec_Impl( SfxRequest
& rReq
)
692 rtl::OUString aDocService
;
693 SFX_REQUEST_ARG(rReq
, pDocSrvItem
, SfxStringItem
, SID_DOC_SERVICE
, false);
695 aDocService
= pDocSrvItem
->GetValue();
697 sal_uInt16 nSID
= rReq
.GetSlot();
698 SFX_REQUEST_ARG( rReq
, pFileNameItem
, SfxStringItem
, SID_FILE_NAME
, sal_False
);
701 String
aCommand( pFileNameItem
->GetValue() );
702 const SfxSlot
* pSlot
= GetInterface()->GetSlot( aCommand
);
705 pFileNameItem
= NULL
;
709 sal_Int32 nIndex
= aCommand
.SearchAscii("slot:");
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
;
724 SfxItemSet
* pSet
= NULL
;
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 ),
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
;
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
)
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
) ) );
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
);
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
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
))
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
);
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.
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
);
873 bHyperlinkUsed
= sal_True
;
876 // no else here! It's optional ...
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();
890 SFX_REQUEST_ARG( rReq
, pRefererItem
, SfxStringItem
, SID_REFERER
, sal_False
);
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")),
933 if ( xTypeDetection
.is() )
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();
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);
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
);
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
] );
1003 aRet
= xSet
->getPropertyValue( ::rtl::OUString("Protocols") );
1004 Sequence
< ::rtl::OUString
> 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
) )
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
;
1053 SfxErrorContext
aCtx( ERRCTX_SFX_OPENDOC
, aURL
.Complete
);
1054 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED
);
1057 if ( !bLoadInternal
)
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
);
1078 SfxFrame
* pTargetFrame
= NULL
;
1079 Reference
< XFrame
> xTargetFrame
;
1081 SFX_REQUEST_ARG(rReq
, pFrameItem
, SfxFrameItem
, SID_DOCFRAME
, sal_False
);
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
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
);
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
);
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
);
1136 aTarget
= pTargetItem
->GetValue();
1139 SFX_REQUEST_ARG( rReq
, pNewViewItem
, SfxBoolItem
, SID_OPEN_NEW_VIEW
, sal_False
);
1140 if ( pNewViewItem
&& pNewViewItem
->GetValue() )
1141 aTarget
= String::CreateFromAscii("_blank" );
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() )
1157 xTargetFrame
= pTargetFrame
->GetFrameInterface();
1161 xTargetFrame
.set( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString("com.sun.star.frame.Desktop")), UNO_QUERY
);
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;
1172 pView
= SfxViewFrame::Current();
1173 pView
->GetViewShell()->JumpToMark( aFileName
.Copy(1) );
1174 rReq
.SetReturnValue( SfxViewFrameItem( 0, pView
) );
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
&)
1197 catch(const ::com::sun::star::uno::Exception
&)
1201 Reference
< XModel
> xModel( xComp
, UNO_QUERY
);
1203 xController
= xModel
->getCurrentController();
1205 xController
= Reference
< XController
>( xComp
, UNO_QUERY
);
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" );
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();
1237 SfxObjectShell
* pSh
= pCntrFrame
->GetCurrentDocument();
1238 DBG_ASSERT( pSh
, "Controller without ObjectShell ?!" );
1240 rReq
.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame
->GetCurrentViewFrame() ) );
1243 pSh
->RestoreNoDelete();
1249 SfxPoolItem
* pRet
= rReq
.GetReturnValue()->Clone();
1250 pLinkItem
->GetValue().Call(pRet
);
1255 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */