xref: /AOO41X/main/sfx2/source/appl/appopen.cxx (revision 6a6ec68d792bd477e5b23798f42a1a9de0925497)
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/SystemShellExecute.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(
992                     com::sun::star::system::SystemShellExecute::create(
993                         ::comphelper::getProcessComponentContext() ) );
994                 if ( xSystemShellExecute.is() )
995                 {
996                     if ( aINetProtocol == INET_PROT_MAILTO )
997                     {
998                         // don't dispatch mailto hyperlink to desktop dispatcher
999                         rReq.RemoveItem( SID_TARGETNAME );
1000                         rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_self") ) );
1001                     }
1002                     else if ( aINetProtocol == INET_PROT_FTP ||
1003                          aINetProtocol == INET_PROT_HTTP ||
1004                          aINetProtocol == INET_PROT_HTTPS )
1005                     {
1006                         try
1007                         {
1008                             // start browser
1009                             ::rtl::OUString aURLString( aURL.Complete );
1010                             xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS );
1011                         }
1012                         catch ( ::com::sun::star::lang::IllegalArgumentException& )
1013                         {
1014                             vos::OGuard aGuard( Application::GetSolarMutex() );
1015                             Window *pWindow = SFX_APP()->GetTopWindow();
1016                             ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
1017                         }
1018                         catch ( ::com::sun::star::system::SystemShellExecuteException& )
1019                         {
1020                             vos::OGuard aGuard( Application::GetSolarMutex() );
1021                             Window *pWindow = SFX_APP()->GetTopWindow();
1022                             ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
1023                         }
1024 
1025                         return;
1026                     }
1027                     else
1028                     {
1029                         // check for "internal" protocols that should not be forwarded to the system
1030                         Sequence < ::rtl::OUString > aProtocols(2);
1031 
1032                         // add special protocols that always should be treated as internal
1033                         aProtocols[0] = ::rtl::OUString::createFromAscii("private:*");
1034                         aProtocols[1] = ::rtl::OUString::createFromAscii("vnd.sun.star.*");
1035 
1036                         try
1037                         {
1038                             // get registered protocol handlers from configuration
1039                             Reference < XNameAccess > xAccess( ::comphelper::ConfigurationHelper::openConfig( ::comphelper::getProcessServiceFactory(),
1040                                 ::rtl::OUString::createFromAscii("org.openoffice.Office.ProtocolHandler/HandlerSet"), ::comphelper::ConfigurationHelper::E_READONLY ), UNO_QUERY );
1041                             if ( xAccess.is() )
1042                             {
1043                                 Sequence < ::rtl::OUString > aNames = xAccess->getElementNames();
1044                                 for ( sal_Int32 nName = 0; nName < aNames.getLength(); nName ++)
1045                                 {
1046                                     Reference < XPropertySet > xSet;
1047                                     Any aRet = xAccess->getByName( aNames[nName] );
1048                                     aRet >>= xSet;
1049                                     if ( xSet.is() )
1050                                     {
1051                                         // copy protocols
1052                                         aRet = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("Protocols") );
1053                                         Sequence < ::rtl::OUString > aTmp;
1054                                         aRet >>= aTmp;
1055 
1056                                         // todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols
1057                                         sal_Int32 nLength = aProtocols.getLength();
1058                                         aProtocols.realloc( nLength+aTmp.getLength() );
1059                                         for ( sal_Int32 n=0; n<aTmp.getLength(); n++ )
1060                                             aProtocols[(++nLength)-1] = aTmp[n];
1061                                     }
1062                                 }
1063                             }
1064                         }
1065                         catch ( Exception& )
1066                         {
1067                             // registered protocols could not be read
1068                         }
1069 
1070                         sal_Bool bFound = sal_False;
1071                         for ( sal_Int32 nProt=0; nProt<aProtocols.getLength(); nProt++ )
1072                         {
1073                             WildCard aPattern(aProtocols[nProt]);
1074                             if ( aPattern.Matches( aURL.Complete ) )
1075                             {
1076                                 bFound = sal_True;
1077                                 break;
1078                             }
1079                         }
1080 
1081                         if ( !bFound )
1082                         {
1083                             sal_Bool bLoadInternal = sal_False;
1084 
1085                             // security reservation: => we have to check the referer before executing
1086                             if (SFX_APP()->IsSecureURL(rtl::OUString(), &aReferer))
1087                             {
1088                                 ::rtl::OUString aURLString( aURL.Complete );
1089 
1090                                 try
1091                                 {
1092                                     // give os this file
1093                                     xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS );
1094                                 }
1095                                 catch ( ::com::sun::star::lang::IllegalArgumentException& )
1096                                 {
1097                                     vos::OGuard aGuard( Application::GetSolarMutex() );
1098                                     Window *pWindow = SFX_APP()->GetTopWindow();
1099                                     ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
1100                                 }
1101                                 catch ( ::com::sun::star::system::SystemShellExecuteException& )
1102                                 {
1103                                     if ( !pFilter )
1104                                     {
1105                                         vos::OGuard aGuard( Application::GetSolarMutex() );
1106                                         Window *pWindow = SFX_APP()->GetTopWindow();
1107                                         ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
1108                                     }
1109                                     else
1110                                     {
1111                                         rReq.RemoveItem( SID_TARGETNAME );
1112                                         rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
1113                                         bLoadInternal = sal_True;
1114                                     }
1115                                 }
1116                             }
1117                             else
1118                             {
1119                                 SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aURL.Complete );
1120                                 ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
1121                             }
1122 
1123                             if ( !bLoadInternal )
1124                                 return;
1125                         }
1126                     }
1127                 }
1128             }
1129             else
1130             {
1131                 // hyperlink document must be loaded into a new frame
1132                 rReq.RemoveItem( SID_TARGETNAME );
1133                 rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
1134             }
1135         }
1136     }
1137 
1138     if ( !SFX_APP()->IsSecureURL( INetURLObject(aFileName), &aReferer ) )
1139     {
1140         SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aFileName );
1141         ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
1142         return;
1143     }
1144 
1145     SfxFrame* pTargetFrame = NULL;
1146     Reference< XFrame > xTargetFrame;
1147 
1148     SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False);
1149     if ( pFrameItem )
1150         pTargetFrame = pFrameItem->GetFrame();
1151 
1152     if ( !pTargetFrame )
1153     {
1154         SFX_REQUEST_ARG(rReq, pUnoFrameItem, SfxUnoFrameItem, SID_FILLFRAME, sal_False);
1155         if ( pUnoFrameItem )
1156             xTargetFrame = pUnoFrameItem->GetFrame();
1157     }
1158 
1159     if ( !pTargetFrame && !xTargetFrame.is() && SfxViewFrame::Current() )
1160         pTargetFrame = &SfxViewFrame::Current()->GetFrame();
1161 
1162     // check if caller has set a callback
1163     SFX_REQUEST_ARG(rReq, pLinkItem, SfxLinkItem, SID_DONELINK, sal_False );
1164 
1165     // remove from Itemset, because it confuses the parameter transformation
1166     if ( pLinkItem )
1167         pLinkItem = (SfxLinkItem*) pLinkItem->Clone();
1168 
1169     rReq.RemoveItem( SID_DONELINK );
1170 
1171     // check if the view must be hidden
1172     sal_Bool bHidden = sal_False;
1173     SFX_REQUEST_ARG(rReq, pHidItem, SfxBoolItem, SID_HIDDEN, sal_False);
1174     if ( pHidItem )
1175         bHidden = pHidItem->GetValue();
1176 
1177     // This request is a UI call. We have to set the right values inside the MediaDescriptor
1178     // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate.
1179     // But we have to look for already existing values or for real hidden requests.
1180     SFX_REQUEST_ARG(rReq, pPreviewItem, SfxBoolItem, SID_PREVIEW, sal_False);
1181     if (!bHidden && ( !pPreviewItem || !pPreviewItem->GetValue() ) )
1182     {
1183         SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
1184         SFX_REQUEST_ARG(rReq, pMacroExecItem  , SfxUInt16Item, SID_MACROEXECMODE     , sal_False);
1185         SFX_REQUEST_ARG(rReq, pDocTemplateItem, SfxUInt16Item, SID_UPDATEDOCMODE     , sal_False);
1186 
1187         if (!pInteractionItem)
1188         {
1189             Reference < ::com::sun::star::task::XInteractionHandler > xHdl( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY );
1190             if (xHdl.is())
1191                 rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHdl)) );
1192         }
1193         if (!pMacroExecItem)
1194             rReq.AppendItem( SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::USE_CONFIG) );
1195         if (!pDocTemplateItem)
1196             rReq.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG) );
1197     }
1198 
1199     // extract target name
1200     ::rtl::OUString aTarget;
1201     SFX_REQUEST_ARG(rReq, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False);
1202     if ( pTargetItem )
1203         aTarget = pTargetItem->GetValue();
1204     else
1205     {
1206         SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, sal_False );
1207         if ( pNewViewItem && pNewViewItem->GetValue() )
1208             aTarget = String::CreateFromAscii("_blank" );
1209     }
1210 
1211     if ( bHidden )
1212     {
1213         aTarget = String::CreateFromAscii("_blank");
1214         DBG_ASSERT( rReq.IsSynchronCall() || pLinkItem, "Hidden load process must be done synchronously!" );
1215     }
1216 
1217     Reference < XController > xController;
1218 //    if ( ( !bIsBlankTarget && pFrame ) || pLinkItem || !rReq.IsSynchronCall() )
1219 //    {
1220         // if a frame is given, it must be used for the starting point of the targetting mechanism
1221         // this code is also used if asynchronous loading is possible, because loadComponent always is synchron
1222         if ( !xTargetFrame.is() )
1223         {
1224             if ( pTargetFrame )
1225             {
1226                 xTargetFrame = pTargetFrame->GetFrameInterface();
1227             }
1228             else
1229             {
1230                 xTargetFrame.set( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY );
1231             }
1232         }
1233 
1234         // make URL ready
1235         SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_FILE_NAME, sal_False );
1236         aFileName = pURLItem->GetValue();
1237         if( aFileName.Len() && aFileName.GetChar(0) == '#' ) // Mark without URL
1238         {
1239             SfxViewFrame *pView = pTargetFrame ? pTargetFrame->GetCurrentViewFrame() : 0;
1240             if ( !pView )
1241                 pView = SfxViewFrame::Current();
1242             pView->GetViewShell()->JumpToMark( aFileName.Copy(1) );
1243             rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) );
1244             return;
1245         }
1246 
1247         // convert items to properties for framework API calls
1248         Sequence < PropertyValue > aArgs;
1249         TransformItems( SID_OPENDOC, *rReq.GetArgs(), aArgs );
1250 
1251         // TODO/LATER: either remove LinkItem or create an asynchronous process for it
1252         if( bHidden || pLinkItem || rReq.IsSynchronCall() )
1253         {
1254             // if loading must be done synchron, we must wait for completion to get a return value
1255             // find frame by myself; I must konw the exact frame to get the controller for the return value from it
1256             //if( aTarget.getLength() )
1257             //    xTargetFrame = xTargetFrame->findFrame( aTarget, FrameSearchFlag::ALL );
1258             Reference < XComponent > xComp;
1259 
1260             try
1261             {
1262                 xComp = ::comphelper::SynchronousDispatch::dispatch( xTargetFrame, aFileName, aTarget, 0, aArgs );
1263 //                Reference < XComponentLoader > xLoader( xTargetFrame, UNO_QUERY );
1264 //                xComp = xLoader->loadComponentFromURL( aFileName, aTarget, 0, aArgs );
1265             }
1266             catch(const RuntimeException&)
1267             {
1268                 throw;
1269             }
1270             catch(const ::com::sun::star::uno::Exception&)
1271             {
1272             }
1273 
1274             Reference < XModel > xModel( xComp, UNO_QUERY );
1275             if ( xModel.is() )
1276                 xController = xModel->getCurrentController();
1277             else
1278                 xController = Reference < XController >( xComp, UNO_QUERY );
1279 
1280         }
1281         else
1282         {
1283             URL aURL;
1284             aURL.Complete = aFileName;
1285             Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
1286             xTrans->parseStrict( aURL );
1287 
1288             Reference < XDispatchProvider > xProv( xTargetFrame, UNO_QUERY );
1289             Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, aTarget, FrameSearchFlag::ALL ) : Reference < XDispatch >();;
1290             RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - SfxApplication::OpenDocExec_Impl" );
1291             if ( xDisp.is() )
1292                 xDisp->dispatch( aURL, aArgs );
1293         }
1294     /*
1295     }
1296     else
1297     {
1298         // synchron loading without a given frame or as blank frame
1299         SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );
1300 
1301         // Desktop service must exists! dont catch() or check for problems here ...
1302         // But loading of documents can fail by other reasons. Handle it more gracefully.
1303         Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY );
1304         Reference < XComponent >       xComp;
1305         try
1306         {
1307             xComp = xDesktop->loadComponentFromURL( pFileNameItem->GetValue(), aTarget, 0, aArgs );
1308         }
1309         catch(const RuntimeException&)
1310         {
1311             throw;
1312         }
1313         catch(const ::com::sun::star::uno::Exception&)
1314         {
1315             xDesktop.clear();
1316             xComp.clear();
1317         }
1318 
1319         Reference < XModel > xModel( xComp, UNO_QUERY );
1320         if ( xModel.is() )
1321             xController = xModel->getCurrentController();
1322         else
1323             xController = Reference < XController >( xComp, UNO_QUERY );
1324     }*/
1325 
1326     if ( xController.is() )
1327     {
1328         // try to find the SfxFrame for the controller
1329         SfxFrame* pCntrFrame = NULL;
1330         for ( SfxViewShell* pShell = SfxViewShell::GetFirst( 0, sal_False ); pShell; pShell = SfxViewShell::GetNext( *pShell, 0, sal_False ) )
1331         {
1332             if ( pShell->GetController() == xController )
1333             {
1334                 pCntrFrame = &pShell->GetViewFrame()->GetFrame();
1335                 break;
1336             }
1337         }
1338 
1339         if ( pCntrFrame )
1340         {
1341             SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument();
1342             DBG_ASSERT( pSh, "Controller without ObjectShell ?!" );
1343 
1344             rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) );
1345 
1346             if ( bHidden )
1347                 pSh->RestoreNoDelete();
1348         }
1349     }
1350 
1351     if ( pLinkItem )
1352     {
1353         SfxPoolItem* pRet = rReq.GetReturnValue()->Clone();
1354         pLinkItem->GetValue().Call(pRet);
1355         delete pLinkItem;
1356     }
1357 }
1358