merge the formfield patch from ooo-build
[ooovba.git] / sfx2 / source / appl / appopen.cxx
blob9039ba9541e7e8c0aaa396c226a6d6880243d592
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>
106 #include "app.hrc"
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 >
135 public:
136 BOOL bFinished;
137 BOOL bSuccess;
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()
141 : bFinished( FALSE )
142 , bSuccess( FALSE )
146 void SAL_CALL SfxOpenDocStatusListener_Impl::dispatchFinished( const DispatchResultEvent& aEvent ) throw(RuntimeException)
148 bSuccess = ( aEvent.State == DispatchResultState::SUCCESS );
149 bFinished = TRUE;
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
161 BOOL bForbidVisible,
162 const String* pPostStr
165 /* [Beschreibung]
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" );
177 String aPostString;
178 if ( pPostStr )
179 aPostString = *pPostStr;
181 // noch offen?
182 SfxObjectShellRef xDoc;
184 if ( !aUrlToFind.HasError() )
186 // dann bei den normal geoeffneten Docs
187 if ( !xDoc.Is() )
189 xDoc = SfxObjectShell::GetFirst( 0, FALSE ); // auch hidden Docs
190 while( xDoc.Is() )
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 )) &&
200 !xDoc->IsLoading())
202 break;
205 xDoc = SfxObjectShell::GetNext( *xDoc, 0, FALSE );
210 // gefunden?
211 if ( xDoc.Is() && bActivate )
213 DBG_ASSERT(
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) ) ) ;
222 if ( pFrame )
224 SfxViewFrame *pCur = SfxViewFrame::Current();
225 if ( !bSilent && pFrame == pCur )
226 InfoBox( 0, SfxResId(RID_DOCALREADYLOADED_DLG)).Execute();
227 if ( bActivate )
229 pFrame->MakeActive_Impl( TRUE );
233 return xDoc;
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
251 public:
252 inline explicit SfxDocPasswordVerifier( const Reference< embed::XStorage >& rxStorage ) :
253 mxStorage( rxStorage ) {}
255 virtual ::comphelper::DocPasswordVerifierResult
256 verifyPassword( const ::rtl::OUString& rPassword );
258 private:
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;
288 return eResult;
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
301 /* [Beschreibung]
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 );
315 if( xStorage.is() )
317 uno::Reference< beans::XPropertySet > xStorageProps( xStorage, uno::UNO_QUERY );
318 if ( xStorageProps.is() )
320 sal_Bool bIsEncrypted = sal_False;
321 try {
322 xStorageProps->getPropertyValue( ::rtl::OUString::createFromAscii("HasEncryptedEntries") )
323 >>= bIsEncrypted;
324 } catch( uno::Exception& )
326 // TODO/LATER:
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() );
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 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
368 nRet = ERRCODE_NONE;
370 else
371 nRet = ERRCODE_IO_ABORT;
376 else
378 OSL_ENSURE( sal_False, "A storage must implement XPropertySet interface!" );
379 nRet = ERRCODE_SFX_CANTGETPASSWD;
384 return nRet;
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() )
400 delete pSet;
401 return aMedium.GetErrorCode();
404 aMedium.UseInteractionHandler( TRUE );
405 ULONG nErr = GetFilterMatcher().GuessFilter( aMedium,&pFilter,SFX_FILTER_TEMPLATE, 0 );
406 if ( 0 != nErr)
408 delete pSet;
409 return ERRCODE_SFX_NOTATEMPLATE;
412 if( !pFilter || !pFilter->IsAllowedAsTemplate() )
414 delete pSet;
415 return ERRCODE_SFX_NOTATEMPLATE;
418 if ( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER )
420 DBG_ASSERT( !xDoc.Is(), "Sorry, not implemented!" );
421 delete pSet;
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 );
428 if ( pObj )
429 xDoc = PTR_CAST( SfxObjectShell, pObj->GetShell() );
430 else
432 const SfxViewFrameItem *pView = PTR_CAST( SfxViewFrameItem, pRet );
433 if ( pView )
435 SfxViewFrame *pFrame = pView->GetFrame();
436 if ( pFrame )
437 xDoc = pFrame->GetObjectShell();
441 if ( !xDoc.Is() )
442 return ERRCODE_SFX_DOLOADFAILED;
444 else
446 if ( !xDoc.Is() )
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();
453 xDoc->DoClose();
454 xDoc.Clear();
455 return nErrCode;
459 if( bCopy )
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& )
478 xDoc->DoClose();
479 xDoc.Clear();
481 // TODO: transfer correct error outside
482 return ERRCODE_SFX_GENERAL;
485 SetTemplate_Impl( rFileName, String(), xDoc );
487 else
488 SetTemplate_Impl( rFileName, String(), xDoc );
490 xDoc->SetNoName();
491 xDoc->InvalidateName();
492 xDoc->SetModified(FALSE);
493 xDoc->ResetError();
495 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel ( xDoc->GetModel(), ::com::sun::star::uno::UNO_QUERY );
496 if ( xModel.is() )
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 );
509 delete pNew;
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( '?' );
525 String aParam;
526 if ( nPos != STRING_NOTFOUND )
528 aParam = aFact.Copy( nPos, aFact.Len() );
529 aFact.Erase( nPos, aFact.Len() );
530 aParam.Erase(0,1);
533 xDoc = SfxObjectShell::CreateObjectByFactoryName( aFact );
534 aParam = INetURLObject::decode( aParam, '%', INetURLObject::DECODE_WITH_CHARSET );
535 if( xDoc.Is() )
536 xDoc->DoInitNew_Impl( aParam );
538 if ( xDoc.Is() )
540 if ( pSet )
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 );
550 if ( pTitleItem )
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 );
555 if ( xModel.is() )
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 );
569 delete pNew;
573 return xDoc;
576 void SfxApplication::NewDocDirectExec_Impl( SfxRequest& rReq )
578 DBG_MEMTEST();
580 SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, FALSE);
581 String aFactName;
582 if ( pFactoryItem )
583 aFactName = pFactoryItem->GetValue();
584 else
585 aFactName = SvtModuleOptions().GetDefaultModuleName();
588 SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, GetPool() );
589 String aFact = String::CreateFromAscii("private:factory/");
590 aFact += aFactName;
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() );
605 if ( pItem )
606 rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) );
609 const SfxPoolItem* SfxApplication::NewDocDirectExec_ImplOld( SfxRequest& rReq )
611 DBG_MEMTEST();
613 SFX_REQUEST_ARG(rReq, pHidden, SfxBoolItem, SID_HIDDEN, FALSE);
614 //(mba)/task
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??
624 String aFactory;
625 rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, TRUE ) );
626 SFX_REQUEST_ARG( rReq, pFactoryName, SfxStringItem, SID_NEWDOCDIRECT, FALSE );
627 if( pFactoryName )
628 aFactory = pFactoryName->GetValue();
629 else
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() );
651 if ( xDoc.Is() )
653 SFX_REQUEST_ARG(rReq, pReadonly, SfxBoolItem, SID_DOC_READONLY, FALSE);
654 if ( pReadonly )
655 xDoc->GetMedium()->GetItemSet()->Put( *pReadonly );
657 SFX_REQUEST_ARG(rReq, pPreview, SfxBoolItem, SID_PREVIEW, FALSE);
658 if ( pPreview )
659 xDoc->GetMedium()->GetItemSet()->Put( *pPreview );
661 SFX_REQUEST_ARG(rReq, pSilent, SfxBoolItem, SID_SILENT, FALSE);
662 if ( pSilent )
663 xDoc->GetMedium()->GetItemSet()->Put( *pSilent );
665 SFX_REQUEST_ARG(rReq, pFlags, SfxStringItem, SID_OPTIONS, FALSE);
666 if ( pFlags )
667 xDoc->GetMedium()->GetItemSet()->Put( *pFlags );
670 // View erzeugen
671 if ( xDoc.Is() )
673 SFX_REQUEST_ARG(rReq, pHidden, SfxBoolItem, SID_HIDDEN, FALSE);
674 BOOL bHidden = FALSE;
675 if ( pHidden )
677 xDoc->GetMedium()->GetItemSet()->Put( *pHidden, SID_HIDDEN );
678 bHidden = pHidden->GetValue();
681 SFX_REQUEST_ARG(rReq, pViewId, SfxUInt16Item, SID_VIEW_ID, FALSE);
682 USHORT nViewId = 0;
683 if ( pViewId )
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();
692 if( pInternalArgs )
693 xDoc->GetMedium()->GetItemSet()->Put( *pInternalArgs );
694 SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, FALSE);
696 SfxFrame* pFrame = NULL;
697 if (pFrameItem)
698 pFrame = pFrameItem->GetFrame();
699 else
700 pFrame = (SfxFrame*)SfxTopFrame::Create(xDoc, nViewId, bHidden, pInternalArgs);
701 if ( pFrame )
703 if ( pFrame->GetCurrentDocument() == xDoc || pFrame->PrepareClose_Impl( TRUE, TRUE ) == TRUE )
705 if ( bHidden )
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 ) );
716 else
717 xDoc->DoClose();
720 else
721 xDoc.Clear();
725 return rReq.GetReturnValue();
727 //(mba)/task
729 if ( !pHidden || !pHidden->GetValue() )
730 Application::GetAppWindow()->LeaveWait();
734 //--------------------------------------------------------------------
736 void SfxApplication::NewDocExec_Impl( SfxRequest& rReq )
738 DBG_MEMTEST();
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 )
758 rReq.Done();
759 if ( pTopWin != GetTopWindow() )
761 // the dialogue opens a document -> a new TopWindow appears
762 pTopWin = GetTopWindow();
763 bNewWin = sal_True;
767 delete pDocTemplDlg;
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
771 pTopWin->ToTop();
773 return;
775 else
777 // Template-Name
778 if ( pTemplNameItem )
779 aTemplateName = pTemplNameItem->GetValue();
781 // Template-Region
782 if ( pTemplRegionNameItem )
783 aTemplateRegion = pTemplRegionNameItem->GetValue();
785 // Template-File-Name
786 if ( pTemplFileNameItem )
788 aTemplateFileName = pTemplFileNameItem->GetValue();
789 bDirect = TRUE;
793 ULONG lErr = 0;
794 SfxItemSet* pSet = new SfxAllItemSet( GetPool() );
795 pSet->Put( SfxBoolItem( SID_TEMPLATE, TRUE ) );
796 if ( !bDirect )
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);
812 if ( lFatalErr )
813 ErrorHandler::HandleError(lErr);
815 else
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 );
831 else
833 SfxStringItem aName( SID_FILE_NAME, DEFINE_CONST_UNICODE("private:factory") );
834 pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, 0L );
837 if ( pRet )
838 rReq.SetReturnValue( *pRet );
842 //---------------------------------------------------------------------------
844 namespace {
846 /**
847 * Check if a given filter type should open the hyperlinked document
848 * natively.
850 * @param rFilter filter object
852 bool lcl_isFilterNativelySupported(const SfxFilter& rFilter)
854 if (rFilter.IsOwnFormat())
855 return true;
857 ::rtl::OUString aName = rFilter.GetFilterName();
858 if (aName.indexOf(::rtl::OUString::createFromAscii("MS Excel")) == 0)
859 // We can handle all Excel variants natively.
860 return true;
862 return false;
867 void SfxApplication::OpenDocExec_Impl( SfxRequest& rReq )
869 DBG_MEMTEST();
871 USHORT nSID = rReq.GetSlot();
872 SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, FALSE );
873 if ( pFileNameItem )
875 String aCommand( pFileNameItem->GetValue() );
876 const SfxSlot* pSlot = GetInterface()->GetSlot( aCommand );
877 if ( pSlot )
879 pFileNameItem = NULL;
881 else
883 sal_Int32 nIndex = aCommand.SearchAscii("slot:");
884 if ( !nIndex )
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;
897 String aFilter;
898 SfxItemSet* pSet = NULL;
899 String aPath;
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 ),
910 ';' );
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;
918 String sStandardDir;
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 )
936 delete pURLList;
937 return;
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) ) );
945 delete pSet;
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);
969 else
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
985 // geladen wird
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))
1004 break;
1011 delete pURLList;
1012 return;
1014 delete pURLList;
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
1021 // return;
1024 BOOL bHyperlinkUsed = FALSE;
1026 if ( SID_OPENURL == nSID )
1028 // SID_OPENURL does the same as SID_OPENDOC!
1029 rReq.SetSlot( SID_OPENDOC );
1030 nSID = 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.
1038 /* Attention!
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 );
1046 nSID = 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();
1063 String aReferer;
1064 SFX_REQUEST_ARG( rReq, pRefererItem, SfxStringItem, SID_REFERER, FALSE );
1065 if ( pRefererItem )
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" )),
1113 UNO_QUERY );
1114 if ( xTypeDetection.is() )
1116 URL aURL;
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 );
1149 String aFileName;
1151 utl::LocalFileHelper::ConvertURLToPhysicalName( aMainURL, aFileName );
1152 aMsgText.SearchAndReplaceAscii( "%s", aFileName );
1153 aSecurityWarningBox.SetMessText( aMsgText );
1155 if( aSecurityWarningBox.Execute() == RET_NO )
1156 return;
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();
1170 return;
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 )
1195 // start browser
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();
1212 return;
1214 else
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 );
1228 if ( xAccess.is() )
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] );
1235 aRet >>= xSet;
1236 if ( xSet.is() )
1238 // copy protocols
1239 aRet = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("Protocols") );
1240 Sequence < ::rtl::OUString > aTmp;
1241 aRet >>= 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 ) )
1263 bFound = sal_True;
1264 break;
1268 if ( !bFound )
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& )
1290 if ( !pFilter )
1292 vos::OGuard aGuard( Application::GetSolarMutex() );
1293 Window *pWindow = SFX_APP()->GetTopWindow();
1294 ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
1296 else
1298 rReq.RemoveItem( SID_TARGETNAME );
1299 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
1300 bLoadInternal = TRUE;
1304 else
1306 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aURL.Complete );
1307 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
1310 if ( !bLoadInternal )
1311 return;
1316 else
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 );
1329 return;
1332 SFX_REQUEST_ARG(rReq, pFrmItem, SfxFrameItem, SID_DOCFRAME, FALSE);
1333 SfxFrame *pFrame = NULL;
1334 if ( pFrmItem )
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
1343 if ( pLinkItem )
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
1360 if ( !bCreateView )
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);
1366 if ( pHidItem )
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 );
1382 if (xHdl.is())
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);
1394 if ( pTargetItem )
1395 aTarget = pTargetItem->GetValue();
1396 else
1398 SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, FALSE );
1399 if ( pNewViewItem && pNewViewItem->GetValue() )
1400 aTarget = String::CreateFromAscii("_blank" );
1403 if ( bHidden )
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() )
1411 // {
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;
1415 if ( pFrame )
1416 xFrame = pFrame->GetFrameInterface();
1417 else
1418 xFrame = Reference < XFrame >( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY );
1420 // make URL ready
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;
1426 if ( !pView )
1427 pView = SfxViewFrame::Current();
1428 pView->GetViewShell()->JumpToMark( aFileName.Copy(1) );
1429 rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) );
1430 return;
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&)
1454 throw;
1456 catch(const ::com::sun::star::uno::Exception&)
1460 Reference < XModel > xModel( xComp, UNO_QUERY );
1461 if ( xModel.is() )
1462 xController = xModel->getCurrentController();
1463 else
1464 xController = Reference < XController >( xComp, UNO_QUERY );
1467 else
1469 URL aURL;
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" );
1477 if ( xDisp.is() )
1478 xDisp->dispatch( aURL, aArgs );
1482 else
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&)
1497 throw;
1499 catch(const ::com::sun::star::uno::Exception&)
1501 xDesktop.clear();
1502 xComp.clear();
1505 Reference < XModel > xModel( xComp, UNO_QUERY );
1506 if ( xModel.is() )
1507 xController = xModel->getCurrentController();
1508 else
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();
1521 break;
1525 if ( pCntrFrame )
1527 SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument();
1528 DBG_ASSERT( pSh, "Controller without ObjectShell ?!" );
1530 if ( bCreateView )
1531 rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) );
1532 else
1533 rReq.SetReturnValue( SfxObjectItem( 0, pSh ) );
1535 if( ( bHidden || !bCreateView ) )
1536 pSh->RestoreNoDelete();
1540 if ( pLinkItem )
1542 SfxPoolItem* pRet = rReq.GetReturnValue()->Clone();
1543 pLinkItem->GetValue().Call(pRet);
1544 delete pLinkItem;