xref: /AOO41X/main/sfx2/source/appl/appopen.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sfx2.hxx"
26 #include <com/sun/star/uno/Reference.h>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <com/sun/star/frame/FrameSearchFlag.hpp>
29 #include <com/sun/star/frame/XComponentLoader.hpp>
30 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
31 #include <com/sun/star/frame/XDispatchProvider.hpp>
32 #include <com/sun/star/util/XCloseable.hpp>
33 #include <com/sun/star/frame/XFrame.hpp>
34 #include <com/sun/star/frame/XDesktop.hpp>
35 #include <com/sun/star/frame/DispatchResultState.hpp>
36 #include <com/sun/star/frame/XDispatchResultListener.hpp>
37 #include <com/sun/star/util/URL.hpp>
38 #include <com/sun/star/util/XURLTransformer.hpp>
39 #include <com/sun/star/system/XSystemShellExecute.hpp>
40 #include <com/sun/star/document/XTypeDetection.hpp>
41 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
42 #include <com/sun/star/document/MacroExecMode.hpp>
43 #include <com/sun/star/document/UpdateDocMode.hpp>
44 #include <com/sun/star/task/ErrorCodeRequest.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/embed/ElementModes.hpp>
47 #include <com/sun/star/container/XNameAccess.hpp>
48 #include <com/sun/star/uno/Sequence.h>
49 #include <comphelper/processfactory.hxx>
50 #include <cppuhelper/implbase1.hxx>
51 #include <rtl/ustring.hxx>
52 
53 
54 #include <comphelper/storagehelper.hxx>
55 #include <comphelper/synchronousdispatch.hxx>
56 #include <comphelper/configurationhelper.hxx>
57 #include <comphelper/sequenceasvector.hxx>
58 
59 #include <vcl/wrkwin.hxx>
60 #include <svl/intitem.hxx>
61 #include <vcl/msgbox.hxx>
62 #include <svl/stritem.hxx>
63 #include <svl/eitem.hxx>
64 #include <sfx2/doctempl.hxx>
65 #include <svtools/sfxecode.hxx>
66 #include <framework/preventduplicateinteraction.hxx>
67 #include <svtools/ehdl.hxx>
68 #include <basic/sbxobj.hxx>
69 #include <svl/urihelper.hxx>
70 #include <unotools/localfilehelper.hxx>
71 #include <unotools/pathoptions.hxx>
72 #include <unotools/moduleoptions.hxx>
73 #include <svtools/templdlg.hxx>
74 #include <osl/file.hxx>
75 #include <unotools/extendedsecurityoptions.hxx>
76 #include <comphelper/docpasswordhelper.hxx>
77 #include <vcl/svapp.hxx>
78 
79 #include <vos/mutex.hxx>
80 
81 #include <rtl/logfile.hxx>
82 
83 #include <sfx2/app.hxx>
84 #include <sfx2/bindings.hxx>
85 #include <sfx2/dispatch.hxx>
86 #include <sfx2/docfile.hxx>
87 #include <sfx2/fcontnr.hxx>
88 #include <sfx2/new.hxx>
89 #include <sfx2/objitem.hxx>
90 #include <sfx2/objsh.hxx>
91 #include <svl/slstitm.hxx>
92 #include "objshimp.hxx"
93 #include "openflag.hxx"
94 #include <sfx2/passwd.hxx>
95 #include "referers.hxx"
96 #include <sfx2/request.hxx>
97 #include "sfx2/sfxresid.hxx"
98 #include <sfx2/viewsh.hxx>
99 #include "app.hrc"
100 #include <sfx2/viewfrm.hxx>
101 #include <sfx2/sfxuno.hxx>
102 #include <sfx2/objface.hxx>
103 #include <sfx2/filedlghelper.hxx>
104 #include <sfx2/docfac.hxx>
105 #include <sfx2/event.hxx>
106 
107 #define _SVSTDARR_STRINGSDTOR
108 #include <svl/svstdarr.hxx>
109 
110 using namespace ::com::sun::star;
111 using namespace ::com::sun::star::beans;
112 using namespace ::com::sun::star::frame;
113 using namespace ::com::sun::star::lang;
114 using namespace ::com::sun::star::uno;
115 using namespace ::com::sun::star::util;
116 using namespace ::com::sun::star::system;
117 using namespace ::com::sun::star::task;
118 using namespace ::com::sun::star::container;
119 using namespace ::cppu;
120 using namespace ::sfx2;
121 
122 namespace css = ::com::sun::star;
123 
124 //=========================================================================
125 
126 class SfxOpenDocStatusListener_Impl : public WeakImplHelper1< XDispatchResultListener >
127 {
128 public:
129     sal_Bool    bFinished;
130     sal_Bool    bSuccess;
131     virtual void SAL_CALL   dispatchFinished( const DispatchResultEvent& Event ) throw(RuntimeException);
132     virtual void SAL_CALL   disposing( const EventObject& Source ) throw(RuntimeException);
133                             SfxOpenDocStatusListener_Impl()
134                                 : bFinished( sal_False )
135                                 , bSuccess( sal_False )
136                             {}
137 };
138 
139 void SAL_CALL SfxOpenDocStatusListener_Impl::dispatchFinished( const DispatchResultEvent& aEvent ) throw(RuntimeException)
140 {
141     bSuccess = ( aEvent.State == DispatchResultState::SUCCESS );
142     bFinished = sal_True;
143 }
144 
145 void SAL_CALL SfxOpenDocStatusListener_Impl::disposing( const EventObject& ) throw(RuntimeException)
146 {
147 }
148 
149 SfxObjectShellRef SfxApplication::DocAlreadyLoaded
150 (
151     const String&   rName,      // Name des Dokuments mit Pfad
152     sal_Bool            bSilent,    // sal_True: nicht nach neuer Sicht fragen
153     sal_Bool            bActivate,   // soll bestehende Sicht aktiviert werden
154     sal_Bool            bForbidVisible,
155     const String*   pPostStr
156 )
157 
158 /*  [Beschreibung]
159 
160     Stellt fest, ob ein Dokument mit dem Namen 'rName' bereits geladen
161     ist und liefert einen Pointer darauf zu"uck.
162 
163     Ist das Dokument noch nicht geladen, wird ein 0-Pointer zur"uckgeliefert.
164 */
165 
166 {
167     // zu suchenden Namen als URL aufbereiten
168     INetURLObject aUrlToFind( rName );
169     DBG_ASSERT( aUrlToFind.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL" );
170     String aPostString;
171     if (  pPostStr )
172         aPostString = *pPostStr;
173 
174     // noch offen?
175     SfxObjectShellRef xDoc;
176 
177     if ( !aUrlToFind.HasError() )
178     {
179         // dann bei den normal geoeffneten Docs
180         if ( !xDoc.Is() )
181         {
182             xDoc = SfxObjectShell::GetFirst( 0, sal_False ); // auch hidden Docs
183             while( xDoc.Is() )
184             {
185                 if ( xDoc->GetMedium() &&
186                      xDoc->GetCreateMode() == SFX_CREATE_MODE_STANDARD &&
187                      !xDoc->IsAbortingImport() && !xDoc->IsLoading() )
188                 {
189                     // Vergleiche anhand der URLs
190                     INetURLObject aUrl( xDoc->GetMedium()->GetName() );
191                     if ( !aUrl.HasError() && aUrl == aUrlToFind &&
192                          (!bForbidVisible || !SfxViewFrame::GetFirst( xDoc, sal_True )) &&
193                          !xDoc->IsLoading())
194                     {
195                             break;
196                     }
197                 }
198                 xDoc = SfxObjectShell::GetNext( *xDoc, 0, sal_False );
199             }
200         }
201     }
202 
203     // gefunden?
204     if ( xDoc.Is() && bActivate )
205     {
206         DBG_ASSERT(
207             !bForbidVisible, "Unsichtbares kann nicht aktiviert werden" );
208 
209         SfxViewFrame* pFrame;
210         for( pFrame = SfxViewFrame::GetFirst( xDoc );
211              pFrame && !pFrame->IsVisible();
212              pFrame = SfxViewFrame::GetNext( *pFrame, xDoc ) ) ;
213         if ( pFrame )
214         {
215             SfxViewFrame *pCur = SfxViewFrame::Current();
216             if ( !bSilent && pFrame == pCur )
217                 InfoBox( 0, SfxResId(RID_DOCALREADYLOADED_DLG)).Execute();
218             if ( bActivate )
219             {
220                 pFrame->MakeActive_Impl( sal_True );
221             }
222         }
223     }
224     return xDoc;
225 }
226 
227 //====================================================================
228 
229 void SetTemplate_Impl( const String &rFileName,
230                         const String &rLongName,
231                         SfxObjectShell *pDoc)
232 {
233     // write TemplateName to DocumentInfo of document
234     // TemplateDate stays as default (=current date)
235     pDoc->ResetFromTemplate( rLongName, rFileName );
236 }
237 
238 //====================================================================
239 class SfxDocPasswordVerifier : public ::comphelper::IDocPasswordVerifier
240 {
241 public:
242     inline explicit     SfxDocPasswordVerifier( const Reference< embed::XStorage >& rxStorage ) :
243                             mxStorage( rxStorage ) {}
244 
245     virtual ::comphelper::DocPasswordVerifierResult
246                         verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData );
247     virtual ::comphelper::DocPasswordVerifierResult
248                         verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData );
249 
250 
251 private:
252     Reference< embed::XStorage > mxStorage;
253 };
254 
255 //--------------------------------------------------------------------
256 ::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
257 {
258     o_rEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( rPassword );
259     return verifyEncryptionData( o_rEncryptionData );
260 }
261 
262 
263 //--------------------------------------------------------------------
264 ::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
265 {
266     ::comphelper::DocPasswordVerifierResult eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
267     try
268     {
269         // check the encryption data
270         // if the data correct is the stream will be opened successfuly
271         // and immediatelly closed
272         ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( mxStorage, rEncryptionData );
273 
274         mxStorage->openStreamElement(
275                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) ),
276                 embed::ElementModes::READ | embed::ElementModes::NOCREATE );
277 
278         // no exception -> success
279         eResult = ::comphelper::DocPasswordVerifierResult_OK;
280     }
281     catch( const packages::WrongPasswordException& )
282     {
283         eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
284     }
285     catch( const uno::Exception& )
286     {
287         // unknown error, report it as wrong password
288         // TODO/LATER: we need an additional way to report unknown problems in this case
289         eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
290     }
291     return eResult;
292 }
293 
294 //====================================================================
295 
296 //--------------------------------------------------------------------
297 
298 sal_uInt32 CheckPasswd_Impl
299 (
300     //Window *pWin,             // Parent des Dialogs
301     SfxObjectShell*  pDoc,
302     SfxItemPool&     /*rPool*/, // Pool, falls ein Set erzeugt werden mus
303     SfxMedium*       pFile      // das Medium, dessen Passwort gfs. erfragt werden soll
304 )
305 
306 /*  [Beschreibung]
307 
308     Zu einem Medium das Passwort erfragen; funktioniert nur, wenn es sich
309     um einen Storage handelt.
310     Wenn in der Documentinfo das Passwort-Flag gesetzt ist, wird
311     das Passwort vom Benutzer per Dialog erfragt und an dem Set
312     des Mediums gesetzt; das Set wird, wenn nicht vorhanden, erzeugt.
313 */
314 {
315     sal_uIntPtr nRet = ERRCODE_NONE;
316 
317     if( ( !pFile->GetFilter() || pFile->IsStorage() ) )
318     {
319         uno::Reference< embed::XStorage > xStorage = pFile->GetStorage( sal_True );
320         if( xStorage.is() )
321         {
322             uno::Reference< beans::XPropertySet > xStorageProps( xStorage, uno::UNO_QUERY );
323             if ( xStorageProps.is() )
324             {
325                 sal_Bool bIsEncrypted = sal_False;
326                 try {
327                     xStorageProps->getPropertyValue( ::rtl::OUString::createFromAscii("HasEncryptedEntries") )
328                         >>= bIsEncrypted;
329                 } catch( uno::Exception& )
330                 {
331                     // TODO/LATER:
332                     // the storage either has no encrypted elements or it's just
333                     // does not allow to detect it, probably it should be implemented laiter
334                     /*
335                     bIsEncrypted = ( aInfo.Load( xStorage ) && aInfo.IsPasswd() );
336                     */
337                 }
338 
339                 if ( bIsEncrypted )
340                 {
341                     Window* pWin = pDoc ? pDoc->GetDialogParent( pFile ) : NULL;
342                     if ( pWin )
343                         pWin->Show();
344 
345                     nRet = ERRCODE_SFX_CANTGETPASSWD;
346 
347                     SfxItemSet *pSet = pFile->GetItemSet();
348                     if( pSet )
349                     {
350                         Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = pFile->GetInteractionHandler();
351                         if( xInteractionHandler.is() )
352                         {
353                             // use the comphelper password helper to request a password
354                             ::rtl::OUString aPassword;
355                             SFX_ITEMSET_ARG( pSet, pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
356                             if ( pPasswordItem )
357                                 aPassword = pPasswordItem->GetValue();
358 
359                             uno::Sequence< beans::NamedValue > aEncryptionData;
360                             SFX_ITEMSET_ARG( pSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False);
361                             if ( pEncryptionDataItem )
362                                 pEncryptionDataItem->GetValue() >>= aEncryptionData;
363 
364                             ::rtl::OUString aDocumentName = INetURLObject( pFile->GetOrigURL() ).GetMainURL( INetURLObject::DECODE_WITH_CHARSET );
365 
366                             SfxDocPasswordVerifier aVerifier( xStorage );
367                             aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
368                                 aVerifier, aEncryptionData, aPassword, xInteractionHandler, aDocumentName, comphelper::DocPasswordRequestType_STANDARD );
369 
370                             pSet->ClearItem( SID_PASSWORD );
371                             pSet->ClearItem( SID_ENCRYPTIONDATA );
372 
373                             if ( aEncryptionData.getLength() > 0 )
374                             {
375                                 pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
376 
377                                 try
378                                 {
379                                     // update the version list of the medium using the new password
380                                     pFile->GetVersionList();
381                                 }
382                                 catch( uno::Exception& )
383                                 {
384                                     // TODO/LATER: set the error code
385                                 }
386 
387                                 nRet = ERRCODE_NONE;
388                             }
389                             else
390                                 nRet = ERRCODE_IO_ABORT;
391                         }
392                     }
393                 }
394             }
395             else
396             {
397                 OSL_ENSURE( sal_False, "A storage must implement XPropertySet interface!" );
398                 nRet = ERRCODE_SFX_CANTGETPASSWD;
399             }
400         }
401     }
402 
403     return nRet;
404 }
405 
406 //--------------------------------------------------------------------
407 
408 
409 sal_uIntPtr SfxApplication::LoadTemplate( SfxObjectShellLock& xDoc, const String &rFileName, sal_Bool bCopy, SfxItemSet* pSet )
410 {
411     const SfxFilter* pFilter = NULL;
412     SfxMedium aMedium( rFileName,  ( STREAM_READ | STREAM_SHARE_DENYNONE ), sal_False );
413 
414     if ( !aMedium.GetStorage( sal_True ).is() )
415         aMedium.GetInStream();
416 
417     if ( aMedium.GetError() )
418     {
419         delete pSet;
420         return aMedium.GetErrorCode();
421     }
422 
423     aMedium.UseInteractionHandler( sal_True );
424     sal_uIntPtr nErr = GetFilterMatcher().GuessFilter( aMedium,&pFilter,SFX_FILTER_TEMPLATE, 0 );
425     if ( 0 != nErr)
426     {
427         delete pSet;
428         return ERRCODE_SFX_NOTATEMPLATE;
429     }
430 
431     if( !pFilter || !pFilter->IsAllowedAsTemplate() )
432     {
433         delete pSet;
434         return ERRCODE_SFX_NOTATEMPLATE;
435     }
436 
437     if ( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER )
438     {
439         DBG_ASSERT( !xDoc.Is(), "Sorry, not implemented!" );
440         delete pSet;
441         SfxStringItem aName( SID_FILE_NAME, rFileName );
442         SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii("private:user") );
443         SfxStringItem aFlags( SID_OPTIONS, String::CreateFromAscii("T") );
444         SfxBoolItem aHidden( SID_HIDDEN, sal_True );
445         const SfxPoolItem *pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, &aName, &aHidden, &aReferer, &aFlags, 0L );
446         const SfxObjectItem *pObj = PTR_CAST( SfxObjectItem, pRet );
447         if ( pObj )
448             xDoc = PTR_CAST( SfxObjectShell, pObj->GetShell() );
449         else
450         {
451             const SfxViewFrameItem *pView = PTR_CAST( SfxViewFrameItem, pRet );
452             if ( pView )
453             {
454                 SfxViewFrame *pFrame = pView->GetFrame();
455                 if ( pFrame )
456                     xDoc = pFrame->GetObjectShell();
457             }
458         }
459 
460         if ( !xDoc.Is() )
461             return ERRCODE_SFX_DOLOADFAILED;
462     }
463     else
464     {
465         if ( !xDoc.Is() )
466             xDoc = SfxObjectShell::CreateObject( pFilter->GetServiceName() );
467 
468         SfxMedium *pMedium = new SfxMedium( rFileName, STREAM_STD_READ, sal_False, pFilter, pSet );
469         if(!xDoc->DoLoad(pMedium))
470         {
471             ErrCode nErrCode = xDoc->GetErrorCode();
472             xDoc->DoClose();
473             xDoc.Clear();
474             return nErrCode;
475         }
476     }
477 
478     if( bCopy )
479     {
480         try
481         {
482             // TODO: introduce error handling
483 
484             uno::Reference< embed::XStorage > xTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
485             if( !xTempStorage.is() )
486                 throw uno::RuntimeException();
487 
488             xDoc->GetStorage()->copyToStorage( xTempStorage );
489 
490 //REMOVE                // the following operations should be done in one step
491 //REMOVE                xDoc->DoHandsOff();
492             if ( !xDoc->DoSaveCompleted( new SfxMedium( xTempStorage, String() ) ) )
493                 throw uno::RuntimeException();
494         }
495         catch( uno::Exception& )
496         {
497             xDoc->DoClose();
498             xDoc.Clear();
499 
500             // TODO: transfer correct error outside
501             return ERRCODE_SFX_GENERAL;
502         }
503 
504         SetTemplate_Impl( rFileName, String(), xDoc );
505     }
506     else
507         SetTemplate_Impl( rFileName, String(), xDoc );
508 
509     xDoc->SetNoName();
510     xDoc->InvalidateName();
511     xDoc->SetModified(sal_False);
512     xDoc->ResetError();
513 
514     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >  xModel ( xDoc->GetModel(), ::com::sun::star::uno::UNO_QUERY );
515     if ( xModel.is() )
516     {
517         SfxItemSet* pNew = xDoc->GetMedium()->GetItemSet()->Clone();
518         pNew->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
519         pNew->ClearItem( SID_FILTER_NAME );
520         //pNew->Put( SfxStringItem( SID_FILTER_NAME, xDoc->GetFactory().GetFilter(0)->GetFilterName() ) );
521         ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs;
522         TransformItems( SID_OPENDOC, *pNew, aArgs );
523         sal_Int32 nLength = aArgs.getLength();
524         aArgs.realloc( nLength + 1 );
525         aArgs[nLength].Name = DEFINE_CONST_UNICODE("Title");
526         aArgs[nLength].Value <<= ::rtl::OUString( xDoc->GetTitle( SFX_TITLE_DETECT ) );
527         xModel->attachResource( ::rtl::OUString(), aArgs );
528         delete pNew;
529     }
530 
531     return xDoc->GetErrorCode();
532 }
533 
534 //--------------------------------------------------------------------
535 
536 void SfxApplication::NewDocDirectExec_Impl( SfxRequest& rReq )
537 {
538     DBG_MEMTEST();
539 
540     SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, sal_False);
541     String aFactName;
542     if ( pFactoryItem )
543         aFactName = pFactoryItem->GetValue();
544    else
545         aFactName = SvtModuleOptions().GetDefaultModuleName();
546 
547 
548     SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, GetPool() );
549     String aFact = String::CreateFromAscii("private:factory/");
550     aFact += aFactName;
551     aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) );
552     aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, GetFrame() ) );
553     aReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii( "_default" ) ) );
554 
555     // TODO/LATER: Should the other arguments be transfered as well?
556     SFX_REQUEST_ARG( rReq, pDefaultPathItem, SfxStringItem, SID_DEFAULTFILEPATH, sal_False);
557     if ( pDefaultPathItem )
558         aReq.AppendItem( *pDefaultPathItem );
559     SFX_REQUEST_ARG( rReq, pDefaultNameItem, SfxStringItem, SID_DEFAULTFILENAME, sal_False);
560     if ( pDefaultNameItem )
561         aReq.AppendItem( *pDefaultNameItem );
562 
563     SFX_APP()->ExecuteSlot( aReq );
564     const SfxViewFrameItem* pItem = PTR_CAST( SfxViewFrameItem, aReq.GetReturnValue() );
565     if ( pItem )
566         rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) );
567 }
568 
569 //--------------------------------------------------------------------
570 
571 void SfxApplication::NewDocExec_Impl( SfxRequest& rReq )
572 {
573     DBG_MEMTEST();
574 
575     // keine Parameter vom BASIC nur Factory angegeben?
576     SFX_REQUEST_ARG(rReq, pTemplNameItem, SfxStringItem, SID_TEMPLATE_NAME, sal_False);
577     SFX_REQUEST_ARG(rReq, pTemplFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False);
578     SFX_REQUEST_ARG(rReq, pTemplRegionNameItem, SfxStringItem, SID_TEMPLATE_REGIONNAME, sal_False);
579 
580     SfxObjectShellLock xDoc;
581 
582     String  aTemplateRegion, aTemplateName, aTemplateFileName;
583     sal_Bool    bDirect = sal_False; // "uber FileName anstelle Region/Template
584     SfxErrorContext aEc(ERRCTX_SFX_NEWDOC);
585     if ( !pTemplNameItem && !pTemplFileNameItem )
586     {
587         Window* pTopWin = GetTopWindow();
588         SvtDocumentTemplateDialog* pDocTemplDlg = new SvtDocumentTemplateDialog( NULL );
589         int nRet = pDocTemplDlg->Execute();
590         sal_Bool bNewWin = sal_False;
591         if ( nRet == RET_OK )
592         {
593             rReq.Done();
594             if ( pTopWin != GetTopWindow() )
595             {
596                 // the dialogue opens a document -> a new TopWindow appears
597                 pTopWin = GetTopWindow();
598                 bNewWin = sal_True;
599             }
600         }
601 
602         delete pDocTemplDlg;
603         if ( bNewWin && pTopWin )
604             // after the destruction of the dialogue its parent comes to top,
605             // but we want that the new document is on top
606             pTopWin->ToTop();
607 
608         return;
609     }
610     else
611     {
612         // Template-Name
613         if ( pTemplNameItem )
614             aTemplateName = pTemplNameItem->GetValue();
615 
616         // Template-Region
617         if ( pTemplRegionNameItem )
618             aTemplateRegion = pTemplRegionNameItem->GetValue();
619 
620         // Template-File-Name
621         if ( pTemplFileNameItem )
622         {
623             aTemplateFileName = pTemplFileNameItem->GetValue();
624             bDirect = sal_True;
625         }
626     }
627 
628     sal_uIntPtr lErr = 0;
629     SfxItemSet* pSet = new SfxAllItemSet( GetPool() );
630     pSet->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) );
631     if ( !bDirect )
632     {
633         SfxDocumentTemplates aTmpFac;
634         if( !aTemplateFileName.Len() )
635             aTmpFac.GetFull( aTemplateRegion, aTemplateName, aTemplateFileName );
636 
637         if( !aTemplateFileName.Len() )
638             lErr = ERRCODE_SFX_TEMPLATENOTFOUND;
639     }
640 
641     INetURLObject aObj( aTemplateFileName );
642     SfxErrorContext aEC( ERRCTX_SFX_LOADTEMPLATE, aObj.PathToFileName() );
643 
644     if ( lErr != ERRCODE_NONE )
645     {
646         sal_uIntPtr lFatalErr = ERRCODE_TOERROR(lErr);
647         if ( lFatalErr )
648             ErrorHandler::HandleError(lErr);
649     }
650     else
651     {
652         SfxCallMode eMode = SFX_CALLMODE_SYNCHRON;
653 
654         const SfxPoolItem *pRet=0;
655         SfxStringItem aReferer( SID_REFERER, DEFINE_CONST_UNICODE("private:user") );
656         SfxStringItem aTarget( SID_TARGETNAME, DEFINE_CONST_UNICODE("_default") );
657         if ( aTemplateFileName.Len() )
658         {
659             DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" );
660 
661             SfxStringItem aName( SID_FILE_NAME, aObj.GetMainURL( INetURLObject::NO_DECODE ) );
662             SfxStringItem aTemplName( SID_TEMPLATE_NAME, aTemplateName );
663             SfxStringItem aTemplRegionName( SID_TEMPLATE_REGIONNAME, aTemplateRegion );
664             pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, &aTemplName, &aTemplRegionName, 0L );
665         }
666         else
667         {
668             SfxStringItem aName( SID_FILE_NAME, DEFINE_CONST_UNICODE("private:factory") );
669             pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, 0L );
670         }
671 
672         if ( pRet )
673             rReq.SetReturnValue( *pRet );
674     }
675 }
676 
677 //---------------------------------------------------------------------------
678 
679 void SfxApplication::OpenDocExec_Impl( SfxRequest& rReq )
680 {
681     DBG_MEMTEST();
682 
683     sal_uInt16 nSID = rReq.GetSlot();
684     SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );
685     if ( pFileNameItem )
686     {
687         String aCommand( pFileNameItem->GetValue() );
688         const SfxSlot* pSlot = GetInterface()->GetSlot( aCommand );
689         if ( pSlot )
690         {
691             pFileNameItem = NULL;
692         }
693         else
694         {
695             sal_Int32 nIndex = aCommand.SearchAscii("slot:");
696             if ( !nIndex )
697             {
698                 sal_uInt16 nSlotId = (sal_uInt16) String( aCommand, 5, aCommand.Len()-5 ).ToInt32();
699                 if ( nSlotId == SID_OPENDOC )
700                     pFileNameItem = NULL;
701             }
702         }
703     }
704 
705     if ( !pFileNameItem )
706     {
707         // get FileName from dialog
708         SvStringsDtor* pURLList = NULL;
709         String aFilter;
710         SfxItemSet* pSet = NULL;
711         String aPath;
712         SFX_REQUEST_ARG( rReq, pFolderNameItem, SfxStringItem, SID_PATH, sal_False );
713         if ( pFolderNameItem )
714             aPath = pFolderNameItem->GetValue();
715         else if ( nSID == SID_OPENTEMPLATE )
716         {
717             aPath = SvtPathOptions().GetTemplatePath();
718             sal_Int32 nTokenCount = aPath.GetTokenCount( ';' );
719             aPath = aPath.GetToken(
720                 sal::static_int_cast< xub_StrLen >(
721                     nTokenCount ? ( nTokenCount - 1 ) : 0 ),
722                 ';' );
723         }
724 
725         sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG;
726         SFX_REQUEST_ARG( rReq, pSystemDialogItem, SfxBoolItem, SID_FILE_DIALOG, sal_False );
727         if ( pSystemDialogItem )
728             nDialog = pSystemDialogItem->GetValue() ? SFX2_IMPL_DIALOG_SYSTEM : SFX2_IMPL_DIALOG_OOO;
729 
730         String sStandardDir;
731 
732         SFX_REQUEST_ARG( rReq, pStandardDirItem, SfxStringItem, SID_STANDARD_DIR, sal_False );
733         if ( pStandardDirItem )
734             sStandardDir = pStandardDirItem->GetValue();
735 
736         ::com::sun::star::uno::Sequence< ::rtl::OUString >  aBlackList;
737 
738         SFX_REQUEST_ARG( rReq, pBlackListItem, SfxStringListItem, SID_BLACK_LIST, sal_False );
739         if ( pBlackListItem )
740             pBlackListItem->GetStringList( aBlackList );
741 
742 
743         sal_uIntPtr nErr = sfx2::FileOpenDialog_Impl(
744                 WB_OPEN | SFXWB_MULTISELECTION | SFXWB_SHOWVERSIONS, String(), pURLList, aFilter, pSet, &aPath, nDialog, sStandardDir, aBlackList );
745 
746         if ( nErr == ERRCODE_ABORT )
747         {
748             delete pURLList;
749             return;
750         }
751 
752         rReq.SetArgs( *(SfxAllItemSet*)pSet );
753         if (aFilter.Len() >0 )
754             rReq.AppendItem( SfxStringItem( SID_FILTER_NAME, aFilter ) );
755         rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
756         rReq.AppendItem( SfxStringItem( SID_REFERER, String::CreateFromAscii(SFX_REFERER_USER) ) );
757         delete pSet;
758 
759         if ( pURLList->Count() )
760         {
761             if ( nSID == SID_OPENTEMPLATE )
762                 rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_False ) );
763 
764             // This helper wraps an existing (or may new created InteractionHandler)
765             // intercept all incoming interactions and provide usefull informations
766             // later if the following transaction was finished.
767 
768             ::framework::PreventDuplicateInteraction*                 pHandler       = new ::framework::PreventDuplicateInteraction(::comphelper::getProcessServiceFactory());
769             css::uno::Reference< css::task::XInteractionHandler >     xHandler       (static_cast< css::task::XInteractionHandler* >(pHandler), css::uno::UNO_QUERY);
770             css::uno::Reference< css::task::XInteractionHandler >     xWrappedHandler;
771 
772             // wrap existing handler or create new UUI handler
773             SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
774             if (pInteractionItem)
775             {
776                 pInteractionItem->GetValue() >>= xWrappedHandler;
777                 rReq.RemoveItem( SID_INTERACTIONHANDLER );
778             }
779             if (xWrappedHandler.is())
780                 pHandler->setHandler(xWrappedHandler);
781             else
782                 pHandler->useDefaultUUIHandler();
783             rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHandler)) );
784 
785             // define rules for this handler
786             css::uno::Type                                            aInteraction = ::getCppuType(static_cast< css::task::ErrorCodeRequest* >(0));
787             ::framework::PreventDuplicateInteraction::InteractionInfo aRule        (aInteraction, 1);
788             pHandler->addInteractionRule(aRule);
789 
790             for ( sal_uInt16 i = 0; i < pURLList->Count(); ++i )
791             {
792                 String aURL = *(pURLList->GetObject(i));
793                 rReq.RemoveItem( SID_FILE_NAME );
794                 rReq.AppendItem( SfxStringItem( SID_FILE_NAME, aURL ) );
795 
796                 // synchron ausf"uhren, damit beim Reschedulen nicht schon das n"achste Dokument
797                 // geladen wird
798                 // TODO/LATER: use URLList argument and always remove one document after another, each step in asychronous execution, until finished
799                 // but only if reschedule is a problem
800                 GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, *rReq.GetArgs() );
801 
802                 // check for special interaction "NO MORE DOCUMENTS ALLOWED" and
803                 // break loop then. Otherwise we risk showing the same interaction more then once.
804                 if ( pHandler->getInteractionInfo(aInteraction, &aRule) )
805                 {
806                     if (aRule.m_nCallCount > 0)
807                     {
808                         if (aRule.m_xRequest.is())
809                         {
810                             css::task::ErrorCodeRequest aRequest;
811                             if (aRule.m_xRequest->getRequest() >>= aRequest)
812                             {
813                                 if (aRequest.ErrCode ==
814                                     sal::static_int_cast< sal_Int32 >(
815                                         ERRCODE_SFX_NOMOREDOCUMENTSALLOWED))
816                                     break;
817                             }
818                         }
819                     }
820                 }
821             }
822 
823             delete pURLList;
824             return;
825         }
826         delete pURLList;
827     }
828 
829     if ( !rReq.IsSynchronCall() )
830     {
831         // now check wether a stream is already there
832         // if not: download it in a thread and restart the call
833         // return;
834     }
835 
836     sal_Bool bHyperlinkUsed = sal_False;
837 
838     if ( SID_OPENURL == nSID )
839     {
840         // SID_OPENURL does the same as SID_OPENDOC!
841         rReq.SetSlot( SID_OPENDOC );
842         nSID = SID_OPENDOC;
843     }
844     else if ( nSID == SID_OPENTEMPLATE )
845     {
846         rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_False ) );
847     }
848     // pass URL to OS by using ShellExecuter or open it internal
849     // if it seams to be an own format.
850     /* Attention!
851             There exist two possibilities to open hyperlinks:
852             a) using SID_OPENHYPERLINK (new)
853             b) using SID_BROWSE        (old)
854      */
855     else if ( nSID == SID_OPENHYPERLINK )
856     {
857         rReq.SetSlot( SID_OPENDOC );
858         nSID = SID_OPENDOC;
859         bHyperlinkUsed = sal_True;
860     }
861 
862     // no else here! It's optional ...
863     if (!bHyperlinkUsed)
864     {
865         SFX_REQUEST_ARG(rReq, pHyperLinkUsedItem, SfxBoolItem, SID_BROWSE, sal_False);
866         if ( pHyperLinkUsedItem )
867             bHyperlinkUsed = pHyperLinkUsedItem->GetValue();
868         // no "official" item, so remove it from ItemSet before using UNO-API
869         rReq.RemoveItem( SID_BROWSE );
870     }
871 
872     SFX_REQUEST_ARG( rReq, pFileName, SfxStringItem, SID_FILE_NAME, sal_False );
873     String aFileName = pFileName->GetValue();
874 
875     String aReferer;
876     SFX_REQUEST_ARG( rReq, pRefererItem, SfxStringItem, SID_REFERER, sal_False );
877     if ( pRefererItem )
878         aReferer = pRefererItem->GetValue();
879 
880     SFX_REQUEST_ARG( rReq, pFileFlagsItem, SfxStringItem, SID_OPTIONS, sal_False);
881     if ( pFileFlagsItem )
882     {
883         String aFileFlags = pFileFlagsItem->GetValue();
884         aFileFlags.ToUpperAscii();
885         if ( STRING_NOTFOUND != aFileFlags.Search( 0x0054 ) )               // T = 54h
886         {
887             rReq.RemoveItem( SID_TEMPLATE );
888             rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_True ) );
889         }
890 
891         if ( STRING_NOTFOUND != aFileFlags.Search( 0x0048 ) )               // H = 48h
892         {
893             rReq.RemoveItem( SID_HIDDEN );
894             rReq.AppendItem( SfxBoolItem( SID_HIDDEN, sal_True ) );
895         }
896 
897         if ( STRING_NOTFOUND != aFileFlags.Search( 0x0052 ) )               // R = 52h
898         {
899             rReq.RemoveItem( SID_DOC_READONLY );
900             rReq.AppendItem( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
901         }
902 
903         if ( STRING_NOTFOUND != aFileFlags.Search( 0x0042 ) )               // B = 42h
904         {
905             rReq.RemoveItem( SID_PREVIEW );
906             rReq.AppendItem( SfxBoolItem( SID_PREVIEW, sal_True ) );
907         }
908 
909         if ( STRING_NOTFOUND != aFileFlags.Search( 0x0053 ) )               // S = 53h
910         {
911             // not supported anymore
912             //rReq.RemoveItem( SID_SILENT );
913             //rReq.AppendItem( SfxBoolItem( SID_SILENT, sal_True ) );
914         }
915 
916         rReq.RemoveItem( SID_OPTIONS );
917     }
918 
919     // Mark without URL cannot be handled by hyperlink code
920     if ( bHyperlinkUsed && aFileName.Len() && aFileName.GetChar(0) != '#' )
921     {
922         Reference< ::com::sun::star::document::XTypeDetection > xTypeDetection(
923                                                                     ::comphelper::getProcessServiceFactory()->createInstance(
924                                                                     ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" )),
925                                                                     UNO_QUERY );
926         if ( xTypeDetection.is() )
927         {
928             URL             aURL;
929             ::rtl::OUString aTypeName;
930 
931             aURL.Complete = aFileName;
932             Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance(
933                                                     ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
934             xTrans->parseStrict( aURL );
935 
936             INetProtocol aINetProtocol = INetURLObject( aURL.Complete ).GetProtocol();
937             SvtExtendedSecurityOptions aExtendedSecurityOptions;
938             SvtExtendedSecurityOptions::OpenHyperlinkMode eMode = aExtendedSecurityOptions.GetOpenHyperlinkMode();
939             if ( eMode == SvtExtendedSecurityOptions::OPEN_WITHSECURITYCHECK )
940             {
941                 if ( aINetProtocol == INET_PROT_FILE )
942                 {
943 /*!!! pb: #i49802# no security warning any longer
944                     // Check if file URL is a directory. This is not insecure!
945                     osl::Directory aDir( aURL.Main );
946                     sal_Bool bIsDir = ( aDir.open() == osl::Directory::E_None );
947 
948                     if ( !bIsDir && !aExtendedSecurityOptions.IsSecureHyperlink( aURL.Complete ) )
949                     {
950                         // Security check for local files depending on the extension
951                         vos::OGuard aGuard( Application::GetSolarMutex() );
952                         Window *pWindow = SFX_APP()->GetTopWindow();
953 
954                         String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE ));
955                         WarningBox  aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_HYPERLINK ));
956                         aSecurityWarningBox.SetText( aSecurityWarningBoxTitle );
957 
958                         // Replace %s with the real file name
959                         String aMsgText = aSecurityWarningBox.GetMessText();
960                         String aMainURL( aURL.Main );
961                         String aFileName;
962 
963                         utl::LocalFileHelper::ConvertURLToPhysicalName( aMainURL, aFileName );
964                         aMsgText.SearchAndReplaceAscii( "%s", aFileName );
965                         aSecurityWarningBox.SetMessText( aMsgText );
966 
967                         if( aSecurityWarningBox.Execute() == RET_NO )
968                             return;
969                     }
970 */
971                 }
972             }
973             else if ( eMode == SvtExtendedSecurityOptions::OPEN_NEVER && aINetProtocol != INET_PROT_VND_SUN_STAR_HELP )
974             {
975                 vos::OGuard aGuard( Application::GetSolarMutex() );
976                 Window *pWindow = SFX_APP()->GetTopWindow();
977 
978                 String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE ));
979                 WarningBox  aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_NO_HYPERLINKS ));
980                 aSecurityWarningBox.SetText( aSecurityWarningBoxTitle );
981                 aSecurityWarningBox.Execute();
982                 return;
983             }
984 
985             aTypeName = xTypeDetection->queryTypeByURL( aURL.Main );
986             SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher();
987             const SfxFilter* pFilter = rMatcher.GetFilter4EA( aTypeName );
988             if ( !pFilter || !( pFilter->IsOwnFormat() ))
989             {
990                 // hyperlink does not link to own type => special handling (http, ftp) browser and (other external protocols) OS
991                 Reference< XSystemShellExecute > xSystemShellExecute( ::comphelper::getProcessServiceFactory()->createInstance(
992                                                     ::rtl::OUString::createFromAscii( "com.sun.star.system.SystemShellExecute" )), UNO_QUERY );
993                 if ( xSystemShellExecute.is() )
994                 {
995                     if ( aINetProtocol == INET_PROT_MAILTO )
996                     {
997                         // don't dispatch mailto hyperlink to desktop dispatcher
998                         rReq.RemoveItem( SID_TARGETNAME );
999                         rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_self") ) );
1000                     }
1001                     else if ( aINetProtocol == INET_PROT_FTP ||
1002                          aINetProtocol == INET_PROT_HTTP ||
1003                          aINetProtocol == INET_PROT_HTTPS )
1004                     {
1005                         try
1006                         {
1007                             // start browser
1008                             ::rtl::OUString aURLString( aURL.Complete );
1009                             xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS );
1010                         }
1011                         catch ( ::com::sun::star::lang::IllegalArgumentException& )
1012                         {
1013                             vos::OGuard aGuard( Application::GetSolarMutex() );
1014                             Window *pWindow = SFX_APP()->GetTopWindow();
1015                             ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
1016                         }
1017                         catch ( ::com::sun::star::system::SystemShellExecuteException& )
1018                         {
1019                             vos::OGuard aGuard( Application::GetSolarMutex() );
1020                             Window *pWindow = SFX_APP()->GetTopWindow();
1021                             ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
1022                         }
1023 
1024                         return;
1025                     }
1026                     else
1027                     {
1028                         // check for "internal" protocols that should not be forwarded to the system
1029                         Sequence < ::rtl::OUString > aProtocols(2);
1030 
1031                         // add special protocols that always should be treated as internal
1032                         aProtocols[0] = ::rtl::OUString::createFromAscii("private:*");
1033                         aProtocols[1] = ::rtl::OUString::createFromAscii("vnd.sun.star.*");
1034 
1035                         try
1036                         {
1037                             // get registered protocol handlers from configuration
1038                             Reference < XNameAccess > xAccess( ::comphelper::ConfigurationHelper::openConfig( ::comphelper::getProcessServiceFactory(),
1039                                 ::rtl::OUString::createFromAscii("org.openoffice.Office.ProtocolHandler/HandlerSet"), ::comphelper::ConfigurationHelper::E_READONLY ), UNO_QUERY );
1040                             if ( xAccess.is() )
1041                             {
1042                                 Sequence < ::rtl::OUString > aNames = xAccess->getElementNames();
1043                                 for ( sal_Int32 nName = 0; nName < aNames.getLength(); nName ++)
1044                                 {
1045                                     Reference < XPropertySet > xSet;
1046                                     Any aRet = xAccess->getByName( aNames[nName] );
1047                                     aRet >>= xSet;
1048                                     if ( xSet.is() )
1049                                     {
1050                                         // copy protocols
1051                                         aRet = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("Protocols") );
1052                                         Sequence < ::rtl::OUString > aTmp;
1053                                         aRet >>= aTmp;
1054 
1055                                         // todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols
1056                                         sal_Int32 nLength = aProtocols.getLength();
1057                                         aProtocols.realloc( nLength+aTmp.getLength() );
1058                                         for ( sal_Int32 n=0; n<aTmp.getLength(); n++ )
1059                                             aProtocols[(++nLength)-1] = aTmp[n];
1060                                     }
1061                                 }
1062                             }
1063                         }
1064                         catch ( Exception& )
1065                         {
1066                             // registered protocols could not be read
1067                         }
1068 
1069                         sal_Bool bFound = sal_False;
1070                         for ( sal_Int32 nProt=0; nProt<aProtocols.getLength(); nProt++ )
1071                         {
1072                             WildCard aPattern(aProtocols[nProt]);
1073                             if ( aPattern.Matches( aURL.Complete ) )
1074                             {
1075                                 bFound = sal_True;
1076                                 break;
1077                             }
1078                         }
1079 
1080                         if ( !bFound )
1081                         {
1082                             sal_Bool bLoadInternal = sal_False;
1083 
1084                             // security reservation: => we have to check the referer before executing
1085                             if (SFX_APP()->IsSecureURL(rtl::OUString(), &aReferer))
1086                             {
1087                                 ::rtl::OUString aURLString( aURL.Complete );
1088 
1089                                 try
1090                                 {
1091                                     // give os this file
1092                                     xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS );
1093                                 }
1094                                 catch ( ::com::sun::star::lang::IllegalArgumentException& )
1095                                 {
1096                                     vos::OGuard aGuard( Application::GetSolarMutex() );
1097                                     Window *pWindow = SFX_APP()->GetTopWindow();
1098                                     ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
1099                                 }
1100                                 catch ( ::com::sun::star::system::SystemShellExecuteException& )
1101                                 {
1102                                     if ( !pFilter )
1103                                     {
1104                                         vos::OGuard aGuard( Application::GetSolarMutex() );
1105                                         Window *pWindow = SFX_APP()->GetTopWindow();
1106                                         ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
1107                                     }
1108                                     else
1109                                     {
1110                                         rReq.RemoveItem( SID_TARGETNAME );
1111                                         rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
1112                                         bLoadInternal = sal_True;
1113                                     }
1114                                 }
1115                             }
1116                             else
1117                             {
1118                                 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aURL.Complete );
1119                                 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
1120                             }
1121 
1122                             if ( !bLoadInternal )
1123                                 return;
1124                         }
1125                     }
1126                 }
1127             }
1128             else
1129             {
1130                 // hyperlink document must be loaded into a new frame
1131                 rReq.RemoveItem( SID_TARGETNAME );
1132                 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
1133             }
1134         }
1135     }
1136 
1137     if ( !SFX_APP()->IsSecureURL( INetURLObject(aFileName), &aReferer ) )
1138     {
1139         SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aFileName );
1140         ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
1141         return;
1142     }
1143 
1144     SfxFrame* pTargetFrame = NULL;
1145     Reference< XFrame > xTargetFrame;
1146 
1147     SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False);
1148     if ( pFrameItem )
1149         pTargetFrame = pFrameItem->GetFrame();
1150 
1151     if ( !pTargetFrame )
1152     {
1153         SFX_REQUEST_ARG(rReq, pUnoFrameItem, SfxUnoFrameItem, SID_FILLFRAME, sal_False);
1154         if ( pUnoFrameItem )
1155             xTargetFrame = pUnoFrameItem->GetFrame();
1156     }
1157 
1158     if ( !pTargetFrame && !xTargetFrame.is() && SfxViewFrame::Current() )
1159         pTargetFrame = &SfxViewFrame::Current()->GetFrame();
1160 
1161     // check if caller has set a callback
1162     SFX_REQUEST_ARG(rReq, pLinkItem, SfxLinkItem, SID_DONELINK, sal_False );
1163 
1164     // remove from Itemset, because it confuses the parameter transformation
1165     if ( pLinkItem )
1166         pLinkItem = (SfxLinkItem*) pLinkItem->Clone();
1167 
1168     rReq.RemoveItem( SID_DONELINK );
1169 
1170     // check if the view must be hidden
1171     sal_Bool bHidden = sal_False;
1172     SFX_REQUEST_ARG(rReq, pHidItem, SfxBoolItem, SID_HIDDEN, sal_False);
1173     if ( pHidItem )
1174         bHidden = pHidItem->GetValue();
1175 
1176     // This request is a UI call. We have to set the right values inside the MediaDescriptor
1177     // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate.
1178     // But we have to look for already existing values or for real hidden requests.
1179     SFX_REQUEST_ARG(rReq, pPreviewItem, SfxBoolItem, SID_PREVIEW, sal_False);
1180     if (!bHidden && ( !pPreviewItem || !pPreviewItem->GetValue() ) )
1181     {
1182         SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
1183         SFX_REQUEST_ARG(rReq, pMacroExecItem  , SfxUInt16Item, SID_MACROEXECMODE     , sal_False);
1184         SFX_REQUEST_ARG(rReq, pDocTemplateItem, SfxUInt16Item, SID_UPDATEDOCMODE     , sal_False);
1185 
1186         if (!pInteractionItem)
1187         {
1188             Reference < ::com::sun::star::task::XInteractionHandler > xHdl( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY );
1189             if (xHdl.is())
1190                 rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHdl)) );
1191         }
1192         if (!pMacroExecItem)
1193             rReq.AppendItem( SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::USE_CONFIG) );
1194         if (!pDocTemplateItem)
1195             rReq.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG) );
1196     }
1197 
1198     // extract target name
1199     ::rtl::OUString aTarget;
1200     SFX_REQUEST_ARG(rReq, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False);
1201     if ( pTargetItem )
1202         aTarget = pTargetItem->GetValue();
1203     else
1204     {
1205         SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, sal_False );
1206         if ( pNewViewItem && pNewViewItem->GetValue() )
1207             aTarget = String::CreateFromAscii("_blank" );
1208     }
1209 
1210     if ( bHidden )
1211     {
1212         aTarget = String::CreateFromAscii("_blank");
1213         DBG_ASSERT( rReq.IsSynchronCall() || pLinkItem, "Hidden load process must be done synchronously!" );
1214     }
1215 
1216     Reference < XController > xController;
1217 //    if ( ( !bIsBlankTarget && pFrame ) || pLinkItem || !rReq.IsSynchronCall() )
1218 //    {
1219         // if a frame is given, it must be used for the starting point of the targetting mechanism
1220         // this code is also used if asynchronous loading is possible, because loadComponent always is synchron
1221         if ( !xTargetFrame.is() )
1222         {
1223             if ( pTargetFrame )
1224             {
1225                 xTargetFrame = pTargetFrame->GetFrameInterface();
1226             }
1227             else
1228             {
1229                 xTargetFrame.set( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY );
1230             }
1231         }
1232 
1233         // make URL ready
1234         SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_FILE_NAME, sal_False );
1235         aFileName = pURLItem->GetValue();
1236         if( aFileName.Len() && aFileName.GetChar(0) == '#' ) // Mark without URL
1237         {
1238             SfxViewFrame *pView = pTargetFrame ? pTargetFrame->GetCurrentViewFrame() : 0;
1239             if ( !pView )
1240                 pView = SfxViewFrame::Current();
1241             pView->GetViewShell()->JumpToMark( aFileName.Copy(1) );
1242             rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) );
1243             return;
1244         }
1245 
1246         // convert items to properties for framework API calls
1247         Sequence < PropertyValue > aArgs;
1248         TransformItems( SID_OPENDOC, *rReq.GetArgs(), aArgs );
1249 
1250         // TODO/LATER: either remove LinkItem or create an asynchronous process for it
1251         if( bHidden || pLinkItem || rReq.IsSynchronCall() )
1252         {
1253             // if loading must be done synchron, we must wait for completion to get a return value
1254             // find frame by myself; I must konw the exact frame to get the controller for the return value from it
1255             //if( aTarget.getLength() )
1256             //    xTargetFrame = xTargetFrame->findFrame( aTarget, FrameSearchFlag::ALL );
1257             Reference < XComponent > xComp;
1258 
1259             try
1260             {
1261                 xComp = ::comphelper::SynchronousDispatch::dispatch( xTargetFrame, aFileName, aTarget, 0, aArgs );
1262 //                Reference < XComponentLoader > xLoader( xTargetFrame, UNO_QUERY );
1263 //                xComp = xLoader->loadComponentFromURL( aFileName, aTarget, 0, aArgs );
1264             }
1265             catch(const RuntimeException&)
1266             {
1267                 throw;
1268             }
1269             catch(const ::com::sun::star::uno::Exception&)
1270             {
1271             }
1272 
1273             Reference < XModel > xModel( xComp, UNO_QUERY );
1274             if ( xModel.is() )
1275                 xController = xModel->getCurrentController();
1276             else
1277                 xController = Reference < XController >( xComp, UNO_QUERY );
1278 
1279         }
1280         else
1281         {
1282             URL aURL;
1283             aURL.Complete = aFileName;
1284             Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
1285             xTrans->parseStrict( aURL );
1286 
1287             Reference < XDispatchProvider > xProv( xTargetFrame, UNO_QUERY );
1288             Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, aTarget, FrameSearchFlag::ALL ) : Reference < XDispatch >();;
1289             RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - SfxApplication::OpenDocExec_Impl" );
1290             if ( xDisp.is() )
1291                 xDisp->dispatch( aURL, aArgs );
1292         }
1293     /*
1294     }
1295     else
1296     {
1297         // synchron loading without a given frame or as blank frame
1298         SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );
1299 
1300         // Desktop service must exists! dont catch() or check for problems here ...
1301         // But loading of documents can fail by other reasons. Handle it more gracefully.
1302         Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY );
1303         Reference < XComponent >       xComp;
1304         try
1305         {
1306             xComp = xDesktop->loadComponentFromURL( pFileNameItem->GetValue(), aTarget, 0, aArgs );
1307         }
1308         catch(const RuntimeException&)
1309         {
1310             throw;
1311         }
1312         catch(const ::com::sun::star::uno::Exception&)
1313         {
1314             xDesktop.clear();
1315             xComp.clear();
1316         }
1317 
1318         Reference < XModel > xModel( xComp, UNO_QUERY );
1319         if ( xModel.is() )
1320             xController = xModel->getCurrentController();
1321         else
1322             xController = Reference < XController >( xComp, UNO_QUERY );
1323     }*/
1324 
1325     if ( xController.is() )
1326     {
1327         // try to find the SfxFrame for the controller
1328         SfxFrame* pCntrFrame = NULL;
1329         for ( SfxViewShell* pShell = SfxViewShell::GetFirst( 0, sal_False ); pShell; pShell = SfxViewShell::GetNext( *pShell, 0, sal_False ) )
1330         {
1331             if ( pShell->GetController() == xController )
1332             {
1333                 pCntrFrame = &pShell->GetViewFrame()->GetFrame();
1334                 break;
1335             }
1336         }
1337 
1338         if ( pCntrFrame )
1339         {
1340             SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument();
1341             DBG_ASSERT( pSh, "Controller without ObjectShell ?!" );
1342 
1343             rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) );
1344 
1345             if ( bHidden )
1346                 pSh->RestoreNoDelete();
1347         }
1348     }
1349 
1350     if ( pLinkItem )
1351     {
1352         SfxPoolItem* pRet = rReq.GetReturnValue()->Clone();
1353         pLinkItem->GetValue().Call(pRet);
1354         delete pLinkItem;
1355     }
1356 }
1357