1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: appopen.cxx,v $
10 * $Revision: 1.121.96.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
33 #include <com/sun/star/uno/Reference.h>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/frame/FrameSearchFlag.hpp>
36 #include <com/sun/star/frame/XComponentLoader.hpp>
37 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
38 #include <com/sun/star/frame/XDispatchProvider.hpp>
39 #include <com/sun/star/util/XCloseable.hpp>
40 #include <com/sun/star/frame/XFrame.hpp>
41 #include <com/sun/star/frame/XDesktop.hpp>
42 #include <com/sun/star/frame/DispatchResultState.hpp>
43 #include <com/sun/star/frame/XDispatchResultListener.hpp>
44 #include <com/sun/star/util/URL.hpp>
45 #include <com/sun/star/util/XURLTransformer.hpp>
46 #include <com/sun/star/system/XSystemShellExecute.hpp>
47 #include <com/sun/star/document/XTypeDetection.hpp>
48 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
49 #include <com/sun/star/document/MacroExecMode.hpp>
50 #include <com/sun/star/document/UpdateDocMode.hpp>
51 #include <com/sun/star/task/ErrorCodeRequest.hpp>
52 #include <com/sun/star/beans/XPropertySet.hpp>
53 #include <com/sun/star/embed/ElementModes.hpp>
54 #include <com/sun/star/container/XNameAccess.hpp>
55 #include <com/sun/star/uno/Sequence.h>
56 #include <comphelper/processfactory.hxx>
57 #include <cppuhelper/implbase1.hxx>
58 #include <rtl/ustring.hxx>
61 #include <comphelper/storagehelper.hxx>
62 #include <comphelper/synchronousdispatch.hxx>
63 #include <comphelper/configurationhelper.hxx>
64 #include <comphelper/sequenceasvector.hxx>
66 #include <vcl/wrkwin.hxx>
67 #include <svtools/intitem.hxx>
68 #include <vcl/msgbox.hxx>
69 #include <svtools/stritem.hxx>
70 #include <svtools/eitem.hxx>
71 #include <sfx2/doctempl.hxx>
72 #include <svtools/sfxecode.hxx>
73 #include <framework/preventduplicateinteraction.hxx>
74 #include <svtools/ehdl.hxx>
75 #include <basic/sbxobj.hxx>
76 #include <svtools/urihelper.hxx>
77 #include <unotools/localfilehelper.hxx>
78 #include <svtools/pathoptions.hxx>
79 #include <svtools/moduleoptions.hxx>
80 #include <svtools/templdlg.hxx>
81 #include <osl/file.hxx>
82 #include <svtools/extendedsecurityoptions.hxx>
83 #include <comphelper/docpasswordhelper.hxx>
84 #include <vcl/svapp.hxx>
86 #include <vos/mutex.hxx>
88 #include <rtl/logfile.hxx>
90 #include <sfx2/app.hxx>
91 #include <sfx2/bindings.hxx>
92 #include <sfx2/dispatch.hxx>
93 #include <sfx2/docfile.hxx>
94 #include <sfx2/fcontnr.hxx>
95 #include <sfx2/new.hxx>
96 #include <sfx2/objitem.hxx>
97 #include <sfx2/objsh.hxx>
98 #include <svtools/slstitm.hxx>
99 #include "objshimp.hxx"
100 #include "openflag.hxx"
101 #include <sfx2/passwd.hxx>
102 #include "referers.hxx"
103 #include <sfx2/request.hxx>
104 #include "sfxresid.hxx"
105 #include <sfx2/viewsh.hxx>
107 #include <sfx2/topfrm.hxx>
108 #include <sfx2/sfxuno.hxx>
109 #include <sfx2/objface.hxx>
110 #include <sfx2/filedlghelper.hxx>
111 #include <sfx2/docfac.hxx>
112 #include <sfx2/event.hxx>
114 #define _SVSTDARR_STRINGSDTOR
115 #include <svtools/svstdarr.hxx>
117 using namespace ::com::sun::star
;
118 using namespace ::com::sun::star::beans
;
119 using namespace ::com::sun::star::frame
;
120 using namespace ::com::sun::star::lang
;
121 using namespace ::com::sun::star::uno
;
122 using namespace ::com::sun::star::util
;
123 using namespace ::com::sun::star::system
;
124 using namespace ::com::sun::star::task
;
125 using namespace ::com::sun::star::container
;
126 using namespace ::cppu
;
127 using namespace ::sfx2
;
129 namespace css
= ::com::sun::star
;
131 //=========================================================================
133 class SfxOpenDocStatusListener_Impl
: public WeakImplHelper1
< XDispatchResultListener
>
138 virtual void SAL_CALL
dispatchFinished( const DispatchResultEvent
& Event
) throw(RuntimeException
);
139 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw(RuntimeException
);
140 SfxOpenDocStatusListener_Impl()
146 void SAL_CALL
SfxOpenDocStatusListener_Impl::dispatchFinished( const DispatchResultEvent
& aEvent
) throw(RuntimeException
)
148 bSuccess
= ( aEvent
.State
== DispatchResultState::SUCCESS
);
152 void SAL_CALL
SfxOpenDocStatusListener_Impl::disposing( const EventObject
& ) throw(RuntimeException
)
156 SfxObjectShellRef
SfxApplication::DocAlreadyLoaded
158 const String
& rName
, // Name des Dokuments mit Pfad
159 BOOL bSilent
, // TRUE: nicht nach neuer Sicht fragen
160 BOOL bActivate
, // soll bestehende Sicht aktiviert werden
162 const String
* pPostStr
167 Stellt fest, ob ein Dokument mit dem Namen 'rName' bereits geladen
168 ist und liefert einen Pointer darauf zu"uck.
170 Ist das Dokument noch nicht geladen, wird ein 0-Pointer zur"uckgeliefert.
174 // zu suchenden Namen als URL aufbereiten
175 INetURLObject
aUrlToFind( rName
);
176 DBG_ASSERT( aUrlToFind
.GetProtocol() != INET_PROT_NOT_VALID
, "Invalid URL" );
179 aPostString
= *pPostStr
;
182 SfxObjectShellRef xDoc
;
184 if ( !aUrlToFind
.HasError() )
186 // dann bei den normal geoeffneten Docs
189 xDoc
= SfxObjectShell::GetFirst( 0, FALSE
); // auch hidden Docs
192 if ( xDoc
->GetMedium() &&
193 xDoc
->GetCreateMode() == SFX_CREATE_MODE_STANDARD
&&
194 !xDoc
->IsAbortingImport() && !xDoc
->IsLoading() )
196 // Vergleiche anhand der URLs
197 INetURLObject
aUrl( xDoc
->GetMedium()->GetName() );
198 if ( !aUrl
.HasError() && aUrl
== aUrlToFind
&&
199 (!bForbidVisible
|| !SfxViewFrame::GetFirst( xDoc
, 0, TRUE
)) &&
205 xDoc
= SfxObjectShell::GetNext( *xDoc
, 0, FALSE
);
211 if ( xDoc
.Is() && bActivate
)
214 !bForbidVisible
, "Unsichtbares kann nicht aktiviert werden" );
216 SfxTopViewFrame
*pFrame
;
217 for( pFrame
= (SfxTopViewFrame
*)
218 SfxViewFrame::GetFirst( xDoc
, TYPE(SfxTopViewFrame
) );
219 pFrame
&& !pFrame
->IsVisible_Impl();
220 pFrame
= (SfxTopViewFrame
*)
221 SfxViewFrame::GetNext( *pFrame
, xDoc
, TYPE(SfxTopViewFrame
) ) ) ;
224 SfxViewFrame
*pCur
= SfxViewFrame::Current();
225 if ( !bSilent
&& pFrame
== pCur
)
226 InfoBox( 0, SfxResId(RID_DOCALREADYLOADED_DLG
)).Execute();
229 pFrame
->MakeActive_Impl( TRUE
);
236 //====================================================================
238 void SetTemplate_Impl( const String
&rFileName
,
239 const String
&rLongName
,
240 SfxObjectShell
*pDoc
)
242 // write TemplateName to DocumentInfo of document
243 // TemplateDate stays as default (=current date)
244 pDoc
->ResetFromTemplate( rLongName
, rFileName
);
247 //--------------------------------------------------------------------
249 class SfxDocPasswordVerifier
: public ::comphelper::IDocPasswordVerifier
252 inline explicit SfxDocPasswordVerifier( const Reference
< embed::XStorage
>& rxStorage
) :
253 mxStorage( rxStorage
) {}
255 virtual ::comphelper::DocPasswordVerifierResult
256 verifyPassword( const ::rtl::OUString
& rPassword
);
259 Reference
< embed::XStorage
> mxStorage
;
262 ::comphelper::DocPasswordVerifierResult
SfxDocPasswordVerifier::verifyPassword( const ::rtl::OUString
& rPassword
)
264 ::comphelper::DocPasswordVerifierResult eResult
= ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD
;
267 // check the password
268 // if the password correct is the stream will be opened successfuly
269 // and immediatelly closed
270 ::comphelper::OStorageHelper::SetCommonStoragePassword( mxStorage
, rPassword
);
272 mxStorage
->openStreamElement(
273 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) ),
274 embed::ElementModes::READ
| embed::ElementModes::NOCREATE
);
276 // no exception -> success
277 eResult
= ::comphelper::DocPasswordVerifierResult_OK
;
279 catch( const packages::WrongPasswordException
& )
281 eResult
= ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD
;
283 catch( const uno::Exception
& )
285 // unknown error, do not try to ask again
286 eResult
= ::comphelper::DocPasswordVerifierResult_ABORT
;
291 //--------------------------------------------------------------------
293 sal_uInt32 CheckPasswd_Impl
295 //Window *pWin, // Parent des Dialogs
296 SfxObjectShell
* pDoc
,
297 SfxItemPool
& /*rPool*/, // Pool, falls ein Set erzeugt werden mus
298 SfxMedium
* pFile
// das Medium, dessen Passwort gfs. erfragt werden soll
303 Zu einem Medium das Passwort erfragen; funktioniert nur, wenn es sich
304 um einen Storage handelt.
305 Wenn in der Documentinfo das Passwort-Flag gesetzt ist, wird
306 das Passwort vom Benutzer per Dialog erfragt und an dem Set
307 des Mediums gesetzt; das Set wird, wenn nicht vorhanden, erzeugt.
310 ULONG nRet
= ERRCODE_NONE
;
312 if( ( !pFile
->GetFilter() || pFile
->IsStorage() ) )
314 uno::Reference
< embed::XStorage
> xStorage
= pFile
->GetStorage( sal_True
);
317 uno::Reference
< beans::XPropertySet
> xStorageProps( xStorage
, uno::UNO_QUERY
);
318 if ( xStorageProps
.is() )
320 sal_Bool bIsEncrypted
= sal_False
;
322 xStorageProps
->getPropertyValue( ::rtl::OUString::createFromAscii("HasEncryptedEntries") )
324 } catch( uno::Exception
& )
327 // the storage either has no encrypted elements or it's just
328 // does not allow to detect it, probably it should be implemented laiter
330 bIsEncrypted = ( aInfo.Load( xStorage ) && aInfo.IsPasswd() );
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 aDocumentName
= INetURLObject( pFile
->GetOrigURL() ).GetMainURL( INetURLObject::DECODE_WITH_CHARSET
);
350 SfxDocPasswordVerifier
aVerifier( xStorage
);
351 ::rtl::OUString aPassword
= ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
352 aVerifier
, ::rtl::OUString(), xInteractionHandler
, aDocumentName
, comphelper::DocPasswordRequestType_STANDARD
);
354 if ( aPassword
.getLength() > 0 )
356 pSet
->Put( SfxStringItem( SID_PASSWORD
, aPassword
) );
360 // update the version list of the medium using the new password
361 pFile
->GetVersionList();
363 catch( uno::Exception
& )
365 // TODO/LATER: set the error code
371 nRet
= ERRCODE_IO_ABORT
;
378 OSL_ENSURE( sal_False
, "A storage must implement XPropertySet interface!" );
379 nRet
= ERRCODE_SFX_CANTGETPASSWD
;
387 //--------------------------------------------------------------------
390 ULONG
SfxApplication::LoadTemplate( SfxObjectShellLock
& xDoc
, const String
&rFileName
, BOOL bCopy
, SfxItemSet
* pSet
)
392 const SfxFilter
* pFilter
= NULL
;
393 SfxMedium
aMedium( rFileName
, ( STREAM_READ
| STREAM_SHARE_DENYNONE
), FALSE
);
395 if ( !aMedium
.GetStorage( sal_True
).is() )
396 aMedium
.GetInStream();
398 if ( aMedium
.GetError() )
401 return aMedium
.GetErrorCode();
404 aMedium
.UseInteractionHandler( TRUE
);
405 ULONG nErr
= GetFilterMatcher().GuessFilter( aMedium
,&pFilter
,SFX_FILTER_TEMPLATE
, 0 );
409 return ERRCODE_SFX_NOTATEMPLATE
;
412 if( !pFilter
|| !pFilter
->IsAllowedAsTemplate() )
415 return ERRCODE_SFX_NOTATEMPLATE
;
418 if ( pFilter
->GetFilterFlags() & SFX_FILTER_STARONEFILTER
)
420 DBG_ASSERT( !xDoc
.Is(), "Sorry, not implemented!" );
422 SfxStringItem
aName( SID_FILE_NAME
, rFileName
);
423 SfxStringItem
aReferer( SID_REFERER
, String::CreateFromAscii("private:user") );
424 SfxStringItem
aFlags( SID_OPTIONS
, String::CreateFromAscii("T") );
425 SfxBoolItem
aHidden( SID_HIDDEN
, TRUE
);
426 const SfxPoolItem
*pRet
= GetDispatcher_Impl()->Execute( SID_OPENDOC
, SFX_CALLMODE_SYNCHRON
, &aName
, &aHidden
, &aReferer
, &aFlags
, 0L );
427 const SfxObjectItem
*pObj
= PTR_CAST( SfxObjectItem
, pRet
);
429 xDoc
= PTR_CAST( SfxObjectShell
, pObj
->GetShell() );
432 const SfxViewFrameItem
*pView
= PTR_CAST( SfxViewFrameItem
, pRet
);
435 SfxViewFrame
*pFrame
= pView
->GetFrame();
437 xDoc
= pFrame
->GetObjectShell();
442 return ERRCODE_SFX_DOLOADFAILED
;
447 xDoc
= SfxObjectShell::CreateObject( pFilter
->GetServiceName() );
449 SfxMedium
*pMedium
= new SfxMedium( rFileName
, STREAM_STD_READ
, FALSE
, pFilter
, pSet
);
450 if(!xDoc
->DoLoad(pMedium
))
452 ErrCode nErrCode
= xDoc
->GetErrorCode();
463 // TODO: introduce error handling
465 uno::Reference
< embed::XStorage
> xTempStorage
= ::comphelper::OStorageHelper::GetTemporaryStorage();
466 if( !xTempStorage
.is() )
467 throw uno::RuntimeException();
469 xDoc
->GetStorage()->copyToStorage( xTempStorage
);
471 //REMOVE // the following operations should be done in one step
472 //REMOVE xDoc->DoHandsOff();
473 if ( !xDoc
->DoSaveCompleted( new SfxMedium( xTempStorage
, String() ) ) )
474 throw uno::RuntimeException();
476 catch( uno::Exception
& )
481 // TODO: transfer correct error outside
482 return ERRCODE_SFX_GENERAL
;
485 SetTemplate_Impl( rFileName
, String(), xDoc
);
488 SetTemplate_Impl( rFileName
, String(), xDoc
);
491 xDoc
->InvalidateName();
492 xDoc
->SetModified(FALSE
);
495 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XModel
> xModel ( xDoc
->GetModel(), ::com::sun::star::uno::UNO_QUERY
);
498 SfxItemSet
* pNew
= xDoc
->GetMedium()->GetItemSet()->Clone();
499 pNew
->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL
);
500 pNew
->ClearItem( SID_FILTER_NAME
);
501 //pNew->Put( SfxStringItem( SID_FILTER_NAME, xDoc->GetFactory().GetFilter(0)->GetFilterName() ) );
502 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
> aArgs
;
503 TransformItems( SID_OPENDOC
, *pNew
, aArgs
);
504 sal_Int32 nLength
= aArgs
.getLength();
505 aArgs
.realloc( nLength
+ 1 );
506 aArgs
[nLength
].Name
= DEFINE_CONST_UNICODE("Title");
507 aArgs
[nLength
].Value
<<= ::rtl::OUString( xDoc
->GetTitle( SFX_TITLE_DETECT
) );
508 xModel
->attachResource( ::rtl::OUString(), aArgs
);
512 return xDoc
->GetErrorCode();
515 //--------------------------------------------------------------------
517 SfxObjectShellLock
SfxApplication::NewDoc_Impl( const String
& rFact
, const SfxItemSet
*pSet
)
519 SfxObjectShellLock xDoc
;
520 String
aFact( rFact
);
521 String aPrefix
= String::CreateFromAscii( "private:factory/" );
522 if ( aPrefix
.Len() == aFact
.Match( aPrefix
) )
523 aFact
.Erase( 0, aPrefix
.Len() );
524 USHORT nPos
= aFact
.Search( '?' );
526 if ( nPos
!= STRING_NOTFOUND
)
528 aParam
= aFact
.Copy( nPos
, aFact
.Len() );
529 aFact
.Erase( nPos
, aFact
.Len() );
533 xDoc
= SfxObjectShell::CreateObjectByFactoryName( aFact
);
534 aParam
= INetURLObject::decode( aParam
, '%', INetURLObject::DECODE_WITH_CHARSET
);
536 xDoc
->DoInitNew_Impl( aParam
);
542 // TODO/LATER: Should the other arguments be transfered as well?
543 SFX_ITEMSET_ARG( pSet
, pDefaultPathItem
, SfxStringItem
, SID_DEFAULTFILEPATH
, FALSE
);
544 if ( pDefaultPathItem
)
545 xDoc
->GetMedium()->GetItemSet()->Put( *pDefaultPathItem
);
546 SFX_ITEMSET_ARG( pSet
, pDefaultNameItem
, SfxStringItem
, SID_DEFAULTFILENAME
, FALSE
);
547 if ( pDefaultNameItem
)
548 xDoc
->GetMedium()->GetItemSet()->Put( *pDefaultNameItem
);
549 SFX_ITEMSET_ARG( pSet
, pTitleItem
, SfxStringItem
, SID_DOCINFO_TITLE
, FALSE
);
551 xDoc
->GetMedium()->GetItemSet()->Put( *pTitleItem
);
554 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XModel
> xModel ( xDoc
->GetModel(), ::com::sun::star::uno::UNO_QUERY
);
557 SfxItemSet
* pNew
= xDoc
->GetMedium()->GetItemSet()->Clone();
558 pNew
->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL
);
559 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
> aArgs
;
560 TransformItems( SID_OPENDOC
, *pNew
, aArgs
);
562 sal_Int32 nLength
= aArgs
.getLength();
563 aArgs
.realloc( nLength
+ 1 );
565 aArgs
[nLength
].Name
= DEFINE_CONST_UNICODE("Title");
566 aArgs
[nLength
].Value
<<= ::rtl::OUString( xDoc
->GetTitle( SFX_TITLE_DETECT
) );
568 xModel
->attachResource( ::rtl::OUString(), aArgs
);
576 void SfxApplication::NewDocDirectExec_Impl( SfxRequest
& rReq
)
580 SFX_REQUEST_ARG( rReq
, pFactoryItem
, SfxStringItem
, SID_NEWDOCDIRECT
, FALSE
);
583 aFactName
= pFactoryItem
->GetValue();
585 aFactName
= SvtModuleOptions().GetDefaultModuleName();
588 SfxRequest
aReq( SID_OPENDOC
, SFX_CALLMODE_SYNCHRON
, GetPool() );
589 String aFact
= String::CreateFromAscii("private:factory/");
591 aReq
.AppendItem( SfxStringItem( SID_FILE_NAME
, aFact
) );
592 aReq
.AppendItem( SfxFrameItem( SID_DOCFRAME
, GetFrame() ) );
593 aReq
.AppendItem( SfxStringItem( SID_TARGETNAME
, String::CreateFromAscii( "_default" ) ) );
595 // TODO/LATER: Should the other arguments be transfered as well?
596 SFX_REQUEST_ARG( rReq
, pDefaultPathItem
, SfxStringItem
, SID_DEFAULTFILEPATH
, FALSE
);
597 if ( pDefaultPathItem
)
598 aReq
.AppendItem( *pDefaultPathItem
);
599 SFX_REQUEST_ARG( rReq
, pDefaultNameItem
, SfxStringItem
, SID_DEFAULTFILENAME
, FALSE
);
600 if ( pDefaultNameItem
)
601 aReq
.AppendItem( *pDefaultNameItem
);
603 SFX_APP()->ExecuteSlot( aReq
);
604 const SfxViewFrameItem
* pItem
= PTR_CAST( SfxViewFrameItem
, aReq
.GetReturnValue() );
606 rReq
.SetReturnValue( SfxFrameItem( 0, pItem
->GetFrame() ) );
609 const SfxPoolItem
* SfxApplication::NewDocDirectExec_ImplOld( SfxRequest
& rReq
)
613 SFX_REQUEST_ARG(rReq, pHidden, SfxBoolItem, SID_HIDDEN, FALSE);
616 if ( !pHidden || !pHidden->GetValue() )
617 Application::GetAppWindow()->EnterWait();
619 SfxObjectShellLock xDoc
;
621 // Factory-RegNo kann per Parameter angegeben sein
622 SfxErrorContext
aEc(ERRCTX_SFX_NEWDOCDIRECT
);
623 rReq
.GetArgs(); // -Wall required??
625 rReq
.AppendItem( SfxBoolItem( SID_TEMPLATE
, TRUE
) );
626 SFX_REQUEST_ARG( rReq
, pFactoryName
, SfxStringItem
, SID_NEWDOCDIRECT
, FALSE
);
628 aFactory
= pFactoryName
->GetValue();
630 aFactory
= SvtModuleOptions().GetDefaultModuleName();
632 SFX_REQUEST_ARG( rReq
, pFileFlagsItem
, SfxStringItem
, SID_OPTIONS
, FALSE
);
633 if ( pFileFlagsItem
)
635 // Werte auf einzelne Items verteilen
636 String aFileFlags
= pFileFlagsItem
->GetValue();
637 aFileFlags
.ToUpperAscii();
638 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0054 ) ) // T = 54h
639 rReq
.AppendItem( SfxBoolItem( SID_TEMPLATE
, TRUE
) );
640 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0048 ) ) // H = 48h
641 rReq
.AppendItem( SfxBoolItem( SID_HIDDEN
, TRUE
) );
642 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0052 ) ) // R = 52h
643 rReq
.AppendItem( SfxBoolItem( SID_DOC_READONLY
, TRUE
) );
644 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0042 ) ) // B = 42h
645 rReq
.AppendItem( SfxBoolItem( SID_PREVIEW
, TRUE
) );
646 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0053 ) ) // S = 53h
647 rReq
.AppendItem( SfxBoolItem( SID_SILENT
, TRUE
) );
650 xDoc
= NewDoc_Impl( aFactory
, rReq
.GetArgs() );
653 SFX_REQUEST_ARG(rReq
, pReadonly
, SfxBoolItem
, SID_DOC_READONLY
, FALSE
);
655 xDoc
->GetMedium()->GetItemSet()->Put( *pReadonly
);
657 SFX_REQUEST_ARG(rReq
, pPreview
, SfxBoolItem
, SID_PREVIEW
, FALSE
);
659 xDoc
->GetMedium()->GetItemSet()->Put( *pPreview
);
661 SFX_REQUEST_ARG(rReq
, pSilent
, SfxBoolItem
, SID_SILENT
, FALSE
);
663 xDoc
->GetMedium()->GetItemSet()->Put( *pSilent
);
665 SFX_REQUEST_ARG(rReq
, pFlags
, SfxStringItem
, SID_OPTIONS
, FALSE
);
667 xDoc
->GetMedium()->GetItemSet()->Put( *pFlags
);
673 SFX_REQUEST_ARG(rReq
, pHidden
, SfxBoolItem
, SID_HIDDEN
, FALSE
);
674 BOOL bHidden
= FALSE
;
677 xDoc
->GetMedium()->GetItemSet()->Put( *pHidden
, SID_HIDDEN
);
678 bHidden
= pHidden
->GetValue();
681 SFX_REQUEST_ARG(rReq
, pViewId
, SfxUInt16Item
, SID_VIEW_ID
, FALSE
);
685 xDoc
->GetMedium()->GetItemSet()->Put( *pViewId
, SID_VIEW_ID
);
686 nViewId
= pViewId
->GetValue();
689 xDoc
->SetActivateEvent_Impl( SFX_EVENT_CREATEDOC
);
690 // xDoc->Get_Impl()->nLoadedFlags = SFX_LOADED_ALL;
691 const SfxItemSet
* pInternalArgs
= rReq
.GetInternalArgs_Impl();
693 xDoc
->GetMedium()->GetItemSet()->Put( *pInternalArgs
);
694 SFX_REQUEST_ARG(rReq
, pFrameItem
, SfxFrameItem
, SID_DOCFRAME
, FALSE
);
696 SfxFrame
* pFrame
= NULL
;
698 pFrame
= pFrameItem
->GetFrame();
700 pFrame
= (SfxFrame
*)SfxTopFrame::Create(xDoc
, nViewId
, bHidden
, pInternalArgs
);
703 if ( pFrame
->GetCurrentDocument() == xDoc
|| pFrame
->PrepareClose_Impl( TRUE
, TRUE
) == TRUE
)
707 xDoc
->RestoreNoDelete();
708 xDoc
->OwnerLock( TRUE
);
709 xDoc
->Get_Impl()->bHiddenLockedByAPI
= TRUE
;
712 if ( pFrame
->GetCurrentDocument() != xDoc
)
714 if ( pFrame
->InsertDocument( xDoc
) )
715 rReq
.SetReturnValue( SfxFrameItem( 0, pFrame
) );
725 return rReq
.GetReturnValue();
729 if ( !pHidden || !pHidden->GetValue() )
730 Application::GetAppWindow()->LeaveWait();
734 //--------------------------------------------------------------------
736 void SfxApplication::NewDocExec_Impl( SfxRequest
& rReq
)
740 // keine Parameter vom BASIC nur Factory angegeben?
741 SFX_REQUEST_ARG(rReq
, pTemplNameItem
, SfxStringItem
, SID_TEMPLATE_NAME
, FALSE
);
742 SFX_REQUEST_ARG(rReq
, pTemplFileNameItem
, SfxStringItem
, SID_FILE_NAME
, FALSE
);
743 SFX_REQUEST_ARG(rReq
, pTemplRegionNameItem
, SfxStringItem
, SID_TEMPLATE_REGIONNAME
, FALSE
);
745 SfxObjectShellLock xDoc
;
747 String aTemplateRegion
, aTemplateName
, aTemplateFileName
;
748 BOOL bDirect
= FALSE
; // "uber FileName anstelle Region/Template
749 SfxErrorContext
aEc(ERRCTX_SFX_NEWDOC
);
750 if ( !pTemplNameItem
&& !pTemplFileNameItem
)
752 Window
* pTopWin
= GetTopWindow();
753 SvtDocumentTemplateDialog
* pDocTemplDlg
= new SvtDocumentTemplateDialog( NULL
);
754 int nRet
= pDocTemplDlg
->Execute();
755 sal_Bool bNewWin
= sal_False
;
756 if ( nRet
== RET_OK
)
759 if ( pTopWin
!= GetTopWindow() )
761 // the dialogue opens a document -> a new TopWindow appears
762 pTopWin
= GetTopWindow();
768 if ( bNewWin
&& pTopWin
)
769 // after the destruction of the dialogue its parent comes to top,
770 // but we want that the new document is on top
778 if ( pTemplNameItem
)
779 aTemplateName
= pTemplNameItem
->GetValue();
782 if ( pTemplRegionNameItem
)
783 aTemplateRegion
= pTemplRegionNameItem
->GetValue();
785 // Template-File-Name
786 if ( pTemplFileNameItem
)
788 aTemplateFileName
= pTemplFileNameItem
->GetValue();
794 SfxItemSet
* pSet
= new SfxAllItemSet( GetPool() );
795 pSet
->Put( SfxBoolItem( SID_TEMPLATE
, TRUE
) );
798 SfxDocumentTemplates aTmpFac
;
799 if( !aTemplateFileName
.Len() )
800 aTmpFac
.GetFull( aTemplateRegion
, aTemplateName
, aTemplateFileName
);
802 if( !aTemplateFileName
.Len() )
803 lErr
= ERRCODE_SFX_TEMPLATENOTFOUND
;
806 INetURLObject
aObj( aTemplateFileName
);
807 SfxErrorContext
aEC( ERRCTX_SFX_LOADTEMPLATE
, aObj
.PathToFileName() );
809 if ( lErr
!= ERRCODE_NONE
)
811 ULONG lFatalErr
= ERRCODE_TOERROR(lErr
);
813 ErrorHandler::HandleError(lErr
);
817 SfxCallMode eMode
= SFX_CALLMODE_SYNCHRON
;
819 const SfxPoolItem
*pRet
=0;
820 SfxStringItem
aReferer( SID_REFERER
, DEFINE_CONST_UNICODE("private:user") );
821 SfxStringItem
aTarget( SID_TARGETNAME
, DEFINE_CONST_UNICODE("_default") );
822 if ( aTemplateFileName
.Len() )
824 DBG_ASSERT( aObj
.GetProtocol() != INET_PROT_NOT_VALID
, "Illegal URL!" );
826 SfxStringItem
aName( SID_FILE_NAME
, aObj
.GetMainURL( INetURLObject::NO_DECODE
) );
827 SfxStringItem
aTemplName( SID_TEMPLATE_NAME
, aTemplateName
);
828 SfxStringItem
aTemplRegionName( SID_TEMPLATE_REGIONNAME
, aTemplateRegion
);
829 pRet
= GetDispatcher_Impl()->Execute( SID_OPENDOC
, eMode
, &aName
, &aTarget
, &aReferer
, &aTemplName
, &aTemplRegionName
, 0L );
833 SfxStringItem
aName( SID_FILE_NAME
, DEFINE_CONST_UNICODE("private:factory") );
834 pRet
= GetDispatcher_Impl()->Execute( SID_OPENDOC
, eMode
, &aName
, &aTarget
, &aReferer
, 0L );
838 rReq
.SetReturnValue( *pRet
);
842 //---------------------------------------------------------------------------
847 * Check if a given filter type should open the hyperlinked document
850 * @param rFilter filter object
852 bool lcl_isFilterNativelySupported(const SfxFilter
& rFilter
)
854 if (rFilter
.IsOwnFormat())
857 ::rtl::OUString aName
= rFilter
.GetFilterName();
858 if (aName
.indexOf(::rtl::OUString::createFromAscii("MS Excel")) == 0)
859 // We can handle all Excel variants natively.
867 void SfxApplication::OpenDocExec_Impl( SfxRequest
& rReq
)
871 USHORT nSID
= rReq
.GetSlot();
872 SFX_REQUEST_ARG( rReq
, pFileNameItem
, SfxStringItem
, SID_FILE_NAME
, FALSE
);
875 String
aCommand( pFileNameItem
->GetValue() );
876 const SfxSlot
* pSlot
= GetInterface()->GetSlot( aCommand
);
879 pFileNameItem
= NULL
;
883 sal_Int32 nIndex
= aCommand
.SearchAscii("slot:");
886 USHORT nSlotId
= (USHORT
) String( aCommand
, 5, aCommand
.Len()-5 ).ToInt32();
887 if ( nSlotId
== SID_OPENDOC
)
888 pFileNameItem
= NULL
;
893 if ( !pFileNameItem
)
895 // get FileName from dialog
896 SvStringsDtor
* pURLList
= NULL
;
898 SfxItemSet
* pSet
= NULL
;
900 SFX_REQUEST_ARG( rReq
, pFolderNameItem
, SfxStringItem
, SID_PATH
, FALSE
);
901 if ( pFolderNameItem
)
902 aPath
= pFolderNameItem
->GetValue();
903 else if ( nSID
== SID_OPENTEMPLATE
)
905 aPath
= SvtPathOptions().GetTemplatePath();
906 sal_Int32 nTokenCount
= aPath
.GetTokenCount( ';' );
907 aPath
= aPath
.GetToken(
908 sal::static_int_cast
< xub_StrLen
>(
909 nTokenCount
? ( nTokenCount
- 1 ) : 0 ),
913 sal_Int16 nDialog
= SFX2_IMPL_DIALOG_CONFIG
;
914 SFX_REQUEST_ARG( rReq
, pSystemDialogItem
, SfxBoolItem
, SID_FILE_DIALOG
, FALSE
);
915 if ( pSystemDialogItem
)
916 nDialog
= pSystemDialogItem
->GetValue() ? SFX2_IMPL_DIALOG_SYSTEM
: SFX2_IMPL_DIALOG_OOO
;
920 SFX_REQUEST_ARG( rReq
, pStandardDirItem
, SfxStringItem
, SID_STANDARD_DIR
, FALSE
);
921 if ( pStandardDirItem
)
922 sStandardDir
= pStandardDirItem
->GetValue();
924 ::com::sun::star::uno::Sequence
< ::rtl::OUString
> aBlackList
;
926 SFX_REQUEST_ARG( rReq
, pBlackListItem
, SfxStringListItem
, SID_BLACK_LIST
, FALSE
);
927 if ( pBlackListItem
)
928 pBlackListItem
->GetStringList( aBlackList
);
931 ULONG nErr
= sfx2::FileOpenDialog_Impl(
932 WB_OPEN
| SFXWB_MULTISELECTION
| SFXWB_SHOWVERSIONS
, String(), pURLList
, aFilter
, pSet
, &aPath
, nDialog
, sStandardDir
, aBlackList
);
934 if ( nErr
== ERRCODE_ABORT
)
940 rReq
.SetArgs( *(SfxAllItemSet
*)pSet
);
941 if (aFilter
.Len() >0 )
942 rReq
.AppendItem( SfxStringItem( SID_FILTER_NAME
, aFilter
) );
943 rReq
.AppendItem( SfxStringItem( SID_TARGETNAME
, String::CreateFromAscii("_default") ) );
944 rReq
.AppendItem( SfxStringItem( SID_REFERER
, String::CreateFromAscii(SFX_REFERER_USER
) ) );
947 if ( pURLList
->Count() )
949 if ( nSID
== SID_OPENTEMPLATE
)
950 rReq
.AppendItem( SfxBoolItem( SID_TEMPLATE
, FALSE
) );
952 // This helper wraps an existing (or may new created InteractionHandler)
953 // intercept all incoming interactions and provide usefull informations
954 // later if the following transaction was finished.
956 ::framework::PreventDuplicateInteraction
* pHandler
= new ::framework::PreventDuplicateInteraction(::comphelper::getProcessServiceFactory());
957 css::uno::Reference
< css::task::XInteractionHandler
> xHandler (static_cast< css::task::XInteractionHandler
* >(pHandler
), css::uno::UNO_QUERY
);
958 css::uno::Reference
< css::task::XInteractionHandler
> xWrappedHandler
;
960 // wrap existing handler or create new UUI handler
961 SFX_REQUEST_ARG(rReq
, pInteractionItem
, SfxUnoAnyItem
, SID_INTERACTIONHANDLER
, FALSE
);
962 if (pInteractionItem
)
964 pInteractionItem
->GetValue() >>= xWrappedHandler
;
965 rReq
.RemoveItem( SID_INTERACTIONHANDLER
);
967 if (xWrappedHandler
.is())
968 pHandler
->setHandler(xWrappedHandler
);
970 pHandler
->useDefaultUUIHandler();
971 rReq
.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER
,::com::sun::star::uno::makeAny(xHandler
)) );
973 // define rules for this handler
974 css::uno::Type aInteraction
= ::getCppuType(static_cast< css::task::ErrorCodeRequest
* >(0));
975 ::framework::PreventDuplicateInteraction::InteractionInfo
aRule (aInteraction
, 1);
976 pHandler
->addInteractionRule(aRule
);
978 for ( USHORT i
= 0; i
< pURLList
->Count(); ++i
)
980 String aURL
= *(pURLList
->GetObject(i
));
981 rReq
.RemoveItem( SID_FILE_NAME
);
982 rReq
.AppendItem( SfxStringItem( SID_FILE_NAME
, aURL
) );
984 // synchron ausf"uhren, damit beim Reschedulen nicht schon das n"achste Dokument
986 // TODO/LATER: use URLList argument and always remove one document after another, each step in asychronous execution, until finished
987 // but only if reschedule is a problem
988 GetDispatcher_Impl()->Execute( SID_OPENDOC
, SFX_CALLMODE_SYNCHRON
, *rReq
.GetArgs() );
990 // check for special interaction "NO MORE DOCUMENTS ALLOWED" and
991 // break loop then. Otherwise we risk showing the same interaction more then once.
992 if ( pHandler
->getInteractionInfo(aInteraction
, &aRule
) )
994 if (aRule
.m_nCallCount
> 0)
996 if (aRule
.m_xRequest
.is())
998 css::task::ErrorCodeRequest aRequest
;
999 if (aRule
.m_xRequest
->getRequest() >>= aRequest
)
1001 if (aRequest
.ErrCode
==
1002 sal::static_int_cast
< sal_Int32
>(
1003 ERRCODE_SFX_NOMOREDOCUMENTSALLOWED
))
1017 if ( !rReq
.IsSynchronCall() )
1019 // now check wether a stream is already there
1020 // if not: download it in a thread and restart the call
1024 BOOL bHyperlinkUsed
= FALSE
;
1026 if ( SID_OPENURL
== nSID
)
1028 // SID_OPENURL does the same as SID_OPENDOC!
1029 rReq
.SetSlot( SID_OPENDOC
);
1032 else if ( nSID
== SID_OPENTEMPLATE
)
1034 rReq
.AppendItem( SfxBoolItem( SID_TEMPLATE
, FALSE
) );
1036 // pass URL to OS by using ShellExecuter or open it internal
1037 // if it seams to be an own format.
1039 There exist two possibilities to open hyperlinks:
1040 a) using SID_OPENHYPERLINK (new)
1041 b) using SID_BROWSE (old)
1043 else if ( nSID
== SID_OPENHYPERLINK
)
1045 rReq
.SetSlot( SID_OPENDOC
);
1047 bHyperlinkUsed
= TRUE
;
1050 // no else here! It's optional ...
1051 if (!bHyperlinkUsed
)
1053 SFX_REQUEST_ARG(rReq
, pHyperLinkUsedItem
, SfxBoolItem
, SID_BROWSE
, FALSE
);
1054 if ( pHyperLinkUsedItem
)
1055 bHyperlinkUsed
= pHyperLinkUsedItem
->GetValue();
1056 // no "official" item, so remove it from ItemSet before using UNO-API
1057 rReq
.RemoveItem( SID_BROWSE
);
1060 SFX_REQUEST_ARG( rReq
, pFileName
, SfxStringItem
, SID_FILE_NAME
, FALSE
);
1061 String aFileName
= pFileName
->GetValue();
1064 SFX_REQUEST_ARG( rReq
, pRefererItem
, SfxStringItem
, SID_REFERER
, FALSE
);
1066 aReferer
= pRefererItem
->GetValue();
1068 SFX_REQUEST_ARG( rReq
, pFileFlagsItem
, SfxStringItem
, SID_OPTIONS
, FALSE
);
1069 if ( pFileFlagsItem
)
1071 String aFileFlags
= pFileFlagsItem
->GetValue();
1072 aFileFlags
.ToUpperAscii();
1073 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0054 ) ) // T = 54h
1075 rReq
.RemoveItem( SID_TEMPLATE
);
1076 rReq
.AppendItem( SfxBoolItem( SID_TEMPLATE
, TRUE
) );
1079 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0048 ) ) // H = 48h
1081 rReq
.RemoveItem( SID_HIDDEN
);
1082 rReq
.AppendItem( SfxBoolItem( SID_HIDDEN
, TRUE
) );
1085 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0052 ) ) // R = 52h
1087 rReq
.RemoveItem( SID_DOC_READONLY
);
1088 rReq
.AppendItem( SfxBoolItem( SID_DOC_READONLY
, TRUE
) );
1091 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0042 ) ) // B = 42h
1093 rReq
.RemoveItem( SID_PREVIEW
);
1094 rReq
.AppendItem( SfxBoolItem( SID_PREVIEW
, TRUE
) );
1097 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 0x0053 ) ) // S = 53h
1099 // not supported anymore
1100 //rReq.RemoveItem( SID_SILENT );
1101 //rReq.AppendItem( SfxBoolItem( SID_SILENT, TRUE ) );
1104 rReq
.RemoveItem( SID_OPTIONS
);
1107 // Mark without URL cannot be handled by hyperlink code
1108 if ( bHyperlinkUsed
&& aFileName
.Len() && aFileName
.GetChar(0) != '#' )
1110 Reference
< ::com::sun::star::document::XTypeDetection
> xTypeDetection(
1111 ::comphelper::getProcessServiceFactory()->createInstance(
1112 ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" )),
1114 if ( xTypeDetection
.is() )
1117 ::rtl::OUString aTypeName
;
1119 aURL
.Complete
= aFileName
;
1120 Reference
< XURLTransformer
> xTrans( ::comphelper::getProcessServiceFactory()->createInstance(
1121 ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY
);
1122 xTrans
->parseStrict( aURL
);
1124 INetProtocol aINetProtocol
= INetURLObject( aURL
.Complete
).GetProtocol();
1125 SvtExtendedSecurityOptions aExtendedSecurityOptions
;
1126 SvtExtendedSecurityOptions::OpenHyperlinkMode eMode
= aExtendedSecurityOptions
.GetOpenHyperlinkMode();
1127 if ( eMode
== SvtExtendedSecurityOptions::OPEN_WITHSECURITYCHECK
)
1129 if ( aINetProtocol
== INET_PROT_FILE
)
1131 /*!!! pb: #i49802# no security warning any longer
1132 // Check if file URL is a directory. This is not insecure!
1133 osl::Directory aDir( aURL.Main );
1134 sal_Bool bIsDir = ( aDir.open() == osl::Directory::E_None );
1136 if ( !bIsDir && !aExtendedSecurityOptions.IsSecureHyperlink( aURL.Complete ) )
1138 // Security check for local files depending on the extension
1139 vos::OGuard aGuard( Application::GetSolarMutex() );
1140 Window *pWindow = SFX_APP()->GetTopWindow();
1142 String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE ));
1143 WarningBox aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_HYPERLINK ));
1144 aSecurityWarningBox.SetText( aSecurityWarningBoxTitle );
1146 // Replace %s with the real file name
1147 String aMsgText = aSecurityWarningBox.GetMessText();
1148 String aMainURL( aURL.Main );
1151 utl::LocalFileHelper::ConvertURLToPhysicalName( aMainURL, aFileName );
1152 aMsgText.SearchAndReplaceAscii( "%s", aFileName );
1153 aSecurityWarningBox.SetMessText( aMsgText );
1155 if( aSecurityWarningBox.Execute() == RET_NO )
1161 else if ( eMode
== SvtExtendedSecurityOptions::OPEN_NEVER
&& aINetProtocol
!= INET_PROT_VND_SUN_STAR_HELP
)
1163 vos::OGuard
aGuard( Application::GetSolarMutex() );
1164 Window
*pWindow
= SFX_APP()->GetTopWindow();
1166 String
aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE
));
1167 WarningBox
aSecurityWarningBox( pWindow
, SfxResId( RID_SECURITY_WARNING_NO_HYPERLINKS
));
1168 aSecurityWarningBox
.SetText( aSecurityWarningBoxTitle
);
1169 aSecurityWarningBox
.Execute();
1173 aTypeName
= xTypeDetection
->queryTypeByURL( aURL
.Main
);
1174 SfxFilterMatcher
& rMatcher
= SFX_APP()->GetFilterMatcher();
1175 const SfxFilter
* pFilter
= rMatcher
.GetFilter4EA( aTypeName
);
1176 if (!pFilter
|| !lcl_isFilterNativelySupported(*pFilter
))
1178 // hyperlink does not link to own type => special handling (http, ftp) browser and (other external protocols) OS
1179 Reference
< XSystemShellExecute
> xSystemShellExecute( ::comphelper::getProcessServiceFactory()->createInstance(
1180 ::rtl::OUString::createFromAscii( "com.sun.star.system.SystemShellExecute" )), UNO_QUERY
);
1181 if ( xSystemShellExecute
.is() )
1183 if ( aINetProtocol
== INET_PROT_MAILTO
)
1185 // don't dispatch mailto hyperlink to desktop dispatcher
1186 rReq
.RemoveItem( SID_TARGETNAME
);
1187 rReq
.AppendItem( SfxStringItem( SID_TARGETNAME
, String::CreateFromAscii("_self") ) );
1189 else if ( aINetProtocol
== INET_PROT_FTP
||
1190 aINetProtocol
== INET_PROT_HTTP
||
1191 aINetProtocol
== INET_PROT_HTTPS
)
1196 ::rtl::OUString
aURLString( aURL
.Complete
);
1197 xSystemShellExecute
->execute( aURLString
, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS
);
1199 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
1201 vos::OGuard
aGuard( Application::GetSolarMutex() );
1202 Window
*pWindow
= SFX_APP()->GetTopWindow();
1203 ErrorBox( pWindow
, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND
)).Execute();
1205 catch ( ::com::sun::star::system::SystemShellExecuteException
& )
1207 vos::OGuard
aGuard( Application::GetSolarMutex() );
1208 Window
*pWindow
= SFX_APP()->GetTopWindow();
1209 ErrorBox( pWindow
, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND
)).Execute();
1216 // check for "internal" protocols that should not be forwarded to the system
1217 Sequence
< ::rtl::OUString
> aProtocols(2);
1219 // add special protocols that always should be treated as internal
1220 aProtocols
[0] = ::rtl::OUString::createFromAscii("private:*");
1221 aProtocols
[1] = ::rtl::OUString::createFromAscii("vnd.sun.star.*");
1225 // get registered protocol handlers from configuration
1226 Reference
< XNameAccess
> xAccess( ::comphelper::ConfigurationHelper::openConfig( ::comphelper::getProcessServiceFactory(),
1227 ::rtl::OUString::createFromAscii("org.openoffice.Office.ProtocolHandler/HandlerSet"), ::comphelper::ConfigurationHelper::E_READONLY
), UNO_QUERY
);
1230 Sequence
< ::rtl::OUString
> aNames
= xAccess
->getElementNames();
1231 for ( sal_Int32 nName
= 0; nName
< aNames
.getLength(); nName
++)
1233 Reference
< XPropertySet
> xSet
;
1234 Any aRet
= xAccess
->getByName( aNames
[nName
] );
1239 aRet
= xSet
->getPropertyValue( ::rtl::OUString::createFromAscii("Protocols") );
1240 Sequence
< ::rtl::OUString
> aTmp
;
1243 // todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols
1244 sal_Int32 nLength
= aProtocols
.getLength();
1245 aProtocols
.realloc( nLength
+aTmp
.getLength() );
1246 for ( sal_Int32 n
=0; n
<aTmp
.getLength(); n
++ )
1247 aProtocols
[(++nLength
)-1] = aTmp
[n
];
1252 catch ( Exception
& )
1254 // registered protocols could not be read
1257 sal_Bool bFound
= sal_False
;
1258 for ( sal_Int32 nProt
=0; nProt
<aProtocols
.getLength(); nProt
++ )
1260 WildCard
aPattern(aProtocols
[nProt
]);
1261 if ( aPattern
.Matches( aURL
.Complete
) )
1270 BOOL bLoadInternal
= FALSE
;
1272 // security reservation: => we have to check the referer before executing
1273 if (SFX_APP()->IsSecureURL(rtl::OUString(), &aReferer
))
1275 ::rtl::OUString
aURLString( aURL
.Complete
);
1279 // give os this file
1280 xSystemShellExecute
->execute( aURLString
, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS
);
1282 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
1284 vos::OGuard
aGuard( Application::GetSolarMutex() );
1285 Window
*pWindow
= SFX_APP()->GetTopWindow();
1286 ErrorBox( pWindow
, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND
)).Execute();
1288 catch ( ::com::sun::star::system::SystemShellExecuteException
& )
1292 vos::OGuard
aGuard( Application::GetSolarMutex() );
1293 Window
*pWindow
= SFX_APP()->GetTopWindow();
1294 ErrorBox( pWindow
, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND
)).Execute();
1298 rReq
.RemoveItem( SID_TARGETNAME
);
1299 rReq
.AppendItem( SfxStringItem( SID_TARGETNAME
, String::CreateFromAscii("_default") ) );
1300 bLoadInternal
= TRUE
;
1306 SfxErrorContext
aCtx( ERRCTX_SFX_OPENDOC
, aURL
.Complete
);
1307 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED
);
1310 if ( !bLoadInternal
)
1318 // hyperlink document must be loaded into a new frame
1319 rReq
.RemoveItem( SID_TARGETNAME
);
1320 rReq
.AppendItem( SfxStringItem( SID_TARGETNAME
, String::CreateFromAscii("_default") ) );
1325 if ( !SFX_APP()->IsSecureURL( INetURLObject(aFileName
), &aReferer
) )
1327 SfxErrorContext
aCtx( ERRCTX_SFX_OPENDOC
, aFileName
);
1328 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED
);
1332 SFX_REQUEST_ARG(rReq
, pFrmItem
, SfxFrameItem
, SID_DOCFRAME
, FALSE
);
1333 SfxFrame
*pFrame
= NULL
;
1335 pFrame
= pFrmItem
->GetFrame();
1336 else if ( SfxViewFrame::Current() )
1337 pFrame
= SfxViewFrame::Current()->GetFrame();
1339 // check if caller has set a callback
1340 SFX_REQUEST_ARG(rReq
, pLinkItem
, SfxLinkItem
, SID_DONELINK
, FALSE
);
1342 // remove from Itemset, because it confuses the parameter transformation
1344 pLinkItem
= (SfxLinkItem
*) pLinkItem
->Clone();
1346 rReq
.RemoveItem( SID_DONELINK
);
1348 // check if caller wants to create a view
1349 BOOL bCreateView
= TRUE
;
1350 SFX_REQUEST_ARG( rReq
, pCreateViewItem
, SfxBoolItem
, SID_VIEW
, FALSE
);
1351 if ( pCreateViewItem
)
1353 if ( !pCreateViewItem
->GetValue() )
1354 bCreateView
= FALSE
;
1355 // this is an "SFX only" parameter
1356 rReq
.RemoveItem( SID_VIEW
);
1359 // we can't load without a view - switch to hidden view
1361 rReq
.AppendItem( SfxBoolItem( SID_HIDDEN
, TRUE
) );
1363 // check if the view must be hidden
1364 BOOL bHidden
= FALSE
;
1365 SFX_REQUEST_ARG(rReq
, pHidItem
, SfxBoolItem
, SID_HIDDEN
, FALSE
);
1367 bHidden
= pHidItem
->GetValue();
1369 // This request is a UI call. We have to set the right values inside the MediaDescriptor
1370 // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate.
1371 // But we have to look for already existing values or for real hidden requests.
1372 SFX_REQUEST_ARG(rReq
, pPreviewItem
, SfxBoolItem
, SID_PREVIEW
, FALSE
);
1373 if (!bHidden
&& ( !pPreviewItem
|| !pPreviewItem
->GetValue() ) )
1375 SFX_REQUEST_ARG(rReq
, pInteractionItem
, SfxUnoAnyItem
, SID_INTERACTIONHANDLER
, FALSE
);
1376 SFX_REQUEST_ARG(rReq
, pMacroExecItem
, SfxUInt16Item
, SID_MACROEXECMODE
, FALSE
);
1377 SFX_REQUEST_ARG(rReq
, pDocTemplateItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, FALSE
);
1379 if (!pInteractionItem
)
1381 Reference
< ::com::sun::star::task::XInteractionHandler
> xHdl( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY
);
1383 rReq
.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER
,::com::sun::star::uno::makeAny(xHdl
)) );
1385 if (!pMacroExecItem
)
1386 rReq
.AppendItem( SfxUInt16Item(SID_MACROEXECMODE
,::com::sun::star::document::MacroExecMode::USE_CONFIG
) );
1387 if (!pDocTemplateItem
)
1388 rReq
.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE
,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG
) );
1391 // extract target name
1392 ::rtl::OUString aTarget
;
1393 SFX_REQUEST_ARG(rReq
, pTargetItem
, SfxStringItem
, SID_TARGETNAME
, FALSE
);
1395 aTarget
= pTargetItem
->GetValue();
1398 SFX_REQUEST_ARG( rReq
, pNewViewItem
, SfxBoolItem
, SID_OPEN_NEW_VIEW
, FALSE
);
1399 if ( pNewViewItem
&& pNewViewItem
->GetValue() )
1400 aTarget
= String::CreateFromAscii("_blank" );
1405 aTarget
= String::CreateFromAscii("_blank");
1406 DBG_ASSERT( rReq
.IsSynchronCall() || pLinkItem
, "Hidden load process must be done synchronously!" );
1409 Reference
< XController
> xController
;
1410 // if ( ( !bIsBlankTarget && pFrame ) || pLinkItem || !rReq.IsSynchronCall() )
1412 // if a frame is given, it must be used for the starting point of the targetting mechanism
1413 // this code is also used if asynchronous loading is possible, because loadComponent always is synchron
1414 Reference
< XFrame
> xFrame
;
1416 xFrame
= pFrame
->GetFrameInterface();
1418 xFrame
= Reference
< XFrame
>( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY
);
1421 SFX_REQUEST_ARG( rReq
, pURLItem
, SfxStringItem
, SID_FILE_NAME
, FALSE
);
1422 aFileName
= pURLItem
->GetValue();
1423 if( aFileName
.Len() && aFileName
.GetChar(0) == '#' ) // Mark without URL
1425 SfxViewFrame
*pView
= pFrame
? pFrame
->GetCurrentViewFrame() : 0;
1427 pView
= SfxViewFrame::Current();
1428 pView
->GetViewShell()->JumpToMark( aFileName
.Copy(1) );
1429 rReq
.SetReturnValue( SfxViewFrameItem( 0, pView
) );
1433 // convert items to properties for framework API calls
1434 Sequence
< PropertyValue
> aArgs
;
1435 TransformItems( SID_OPENDOC
, *rReq
.GetArgs(), aArgs
);
1437 // TODO/LATER: either remove LinkItem or create an asynchronous process for it
1438 if( bHidden
|| pLinkItem
|| rReq
.IsSynchronCall() )
1440 // if loading must be done synchron, we must wait for completion to get a return value
1441 // find frame by myself; I must konw the exact frame to get the controller for the return value from it
1442 //if( aTarget.getLength() )
1443 // xFrame = xFrame->findFrame( aTarget, FrameSearchFlag::ALL );
1444 Reference
< XComponent
> xComp
;
1448 xComp
= ::comphelper::SynchronousDispatch::dispatch( xFrame
, aFileName
, aTarget
, 0, aArgs
);
1449 // Reference < XComponentLoader > xLoader( xFrame, UNO_QUERY );
1450 // xComp = xLoader->loadComponentFromURL( aFileName, aTarget, 0, aArgs );
1452 catch(const RuntimeException
&)
1456 catch(const ::com::sun::star::uno::Exception
&)
1460 Reference
< XModel
> xModel( xComp
, UNO_QUERY
);
1462 xController
= xModel
->getCurrentController();
1464 xController
= Reference
< XController
>( xComp
, UNO_QUERY
);
1470 aURL
.Complete
= aFileName
;
1471 Reference
< XURLTransformer
> xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY
);
1472 xTrans
->parseStrict( aURL
);
1474 Reference
< XDispatchProvider
> xProv( xFrame
, UNO_QUERY
);
1475 Reference
< XDispatch
> xDisp
= xProv
.is() ? xProv
->queryDispatch( aURL
, aTarget
, FrameSearchFlag::ALL
) : Reference
< XDispatch
>();;
1476 RTL_LOGFILE_PRODUCT_CONTEXT( aLog2
, "PERFORMANCE - SfxApplication::OpenDocExec_Impl" );
1478 xDisp
->dispatch( aURL
, aArgs
);
1484 // synchron loading without a given frame or as blank frame
1485 SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, FALSE );
1487 // Desktop service must exists! dont catch() or check for problems here ...
1488 // But loading of documents can fail by other reasons. Handle it more gracefully.
1489 Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY );
1490 Reference < XComponent > xComp;
1493 xComp = xDesktop->loadComponentFromURL( pFileNameItem->GetValue(), aTarget, 0, aArgs );
1495 catch(const RuntimeException&)
1499 catch(const ::com::sun::star::uno::Exception&)
1505 Reference < XModel > xModel( xComp, UNO_QUERY );
1507 xController = xModel->getCurrentController();
1509 xController = Reference < XController >( xComp, UNO_QUERY );
1512 if ( xController
.is() )
1514 // try to find the SfxFrame for the controller
1515 SfxFrame
* pCntrFrame
= NULL
;
1516 for ( SfxViewShell
* pShell
= SfxViewShell::GetFirst( 0, FALSE
); pShell
; pShell
= SfxViewShell::GetNext( *pShell
, 0, FALSE
) )
1518 if ( pShell
->GetController() == xController
)
1520 pCntrFrame
= pShell
->GetViewFrame()->GetFrame();
1527 SfxObjectShell
* pSh
= pCntrFrame
->GetCurrentDocument();
1528 DBG_ASSERT( pSh
, "Controller without ObjectShell ?!" );
1531 rReq
.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame
->GetCurrentViewFrame() ) );
1533 rReq
.SetReturnValue( SfxObjectItem( 0, pSh
) );
1535 if( ( bHidden
|| !bCreateView
) )
1536 pSh
->RestoreNoDelete();
1542 SfxPoolItem
* pRet
= rReq
.GetReturnValue()->Clone();
1543 pLinkItem
->GetValue().Call(pRet
);