Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/uno/Reference.h>
21 : #include <com/sun/star/beans/PropertyValue.hpp>
22 : #include <com/sun/star/frame/FrameSearchFlag.hpp>
23 : #include <com/sun/star/frame/XComponentLoader.hpp>
24 : #include <com/sun/star/frame/XNotifyingDispatch.hpp>
25 : #include <com/sun/star/frame/XDispatchProvider.hpp>
26 : #include <com/sun/star/util/XCloseable.hpp>
27 : #include <com/sun/star/frame/XFrame.hpp>
28 : #include <com/sun/star/frame/Desktop.hpp>
29 : #include <com/sun/star/frame/DispatchResultState.hpp>
30 : #include <com/sun/star/frame/XDispatchResultListener.hpp>
31 : #include <com/sun/star/util/URL.hpp>
32 : #include <com/sun/star/util/URLTransformer.hpp>
33 : #include <com/sun/star/util/XURLTransformer.hpp>
34 : #include <com/sun/star/system/SystemShellExecuteException.hpp>
35 : #include <com/sun/star/document/XTypeDetection.hpp>
36 : #include <com/sun/star/document/MacroExecMode.hpp>
37 : #include <com/sun/star/document/UpdateDocMode.hpp>
38 : #include <com/sun/star/task/ErrorCodeRequest.hpp>
39 : #include <com/sun/star/task/InteractionHandler.hpp>
40 : #include <com/sun/star/beans/XPropertySet.hpp>
41 : #include <com/sun/star/embed/ElementModes.hpp>
42 : #include <com/sun/star/container/XNameAccess.hpp>
43 : #include <com/sun/star/uno/Sequence.h>
44 : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
45 : #include <cppuhelper/implbase1.hxx>
46 : #include <rtl/ustring.hxx>
47 :
48 : #include <comphelper/processfactory.hxx>
49 : #include <comphelper/sequenceasvector.hxx>
50 : #include <comphelper/storagehelper.hxx>
51 : #include <comphelper/string.hxx>
52 : #include <comphelper/synchronousdispatch.hxx>
53 :
54 : #include <vcl/wrkwin.hxx>
55 : #include <svl/intitem.hxx>
56 : #include <vcl/layout.hxx>
57 : #include <svl/stritem.hxx>
58 : #include <svl/eitem.hxx>
59 : #include <sfx2/doctempl.hxx>
60 : #include <svtools/sfxecode.hxx>
61 : #include <framework/preventduplicateinteraction.hxx>
62 : #include <svtools/ehdl.hxx>
63 : #include <basic/sbxobj.hxx>
64 : #include <svl/urihelper.hxx>
65 : #include <unotools/localfilehelper.hxx>
66 : #include <unotools/pathoptions.hxx>
67 : #include <unotools/moduleoptions.hxx>
68 : #include <svtools/miscopt.hxx>
69 : #include <osl/file.hxx>
70 : #include <unotools/extendedsecurityoptions.hxx>
71 : #include <comphelper/docpasswordhelper.hxx>
72 : #include <vcl/svapp.hxx>
73 :
74 : #include <osl/mutex.hxx>
75 :
76 :
77 : #include <sfx2/app.hxx>
78 : #include <sfx2/bindings.hxx>
79 : #include <sfx2/dispatch.hxx>
80 : #include <sfx2/docfile.hxx>
81 : #include <sfx2/fcontnr.hxx>
82 : #include <sfx2/new.hxx>
83 : #include <sfx2/objitem.hxx>
84 : #include <sfx2/objsh.hxx>
85 : #include <svl/slstitm.hxx>
86 : #include "appopen.hxx"
87 : #include "objshimp.hxx"
88 : #include "openflag.hxx"
89 : #include <sfx2/passwd.hxx>
90 : #include <sfx2/request.hxx>
91 : #include <sfx2/sfxresid.hxx>
92 : #include <sfx2/viewsh.hxx>
93 : #include "app.hrc"
94 : #include <sfx2/viewfrm.hxx>
95 : #include <sfx2/sfxuno.hxx>
96 : #include <sfx2/objface.hxx>
97 : #include <sfx2/filedlghelper.hxx>
98 : #include <sfx2/docfac.hxx>
99 : #include <sfx2/event.hxx>
100 : #include <sfx2/templatedlg.hxx>
101 : #include "openuriexternally.hxx"
102 :
103 : #include <officecfg/Office/ProtocolHandler.hxx>
104 :
105 : using namespace ::com::sun::star;
106 : using namespace ::com::sun::star::beans;
107 : using namespace ::com::sun::star::frame;
108 : using namespace ::com::sun::star::lang;
109 : using namespace ::com::sun::star::uno;
110 : using namespace ::com::sun::star::util;
111 : using namespace ::com::sun::star::task;
112 : using namespace ::com::sun::star::container;
113 : using namespace ::cppu;
114 : using namespace ::sfx2;
115 :
116 68 : void SetTemplate_Impl( const OUString &rFileName,
117 : const OUString &rLongName,
118 : SfxObjectShell *pDoc)
119 : {
120 : // write TemplateName to DocumentProperties of document
121 : // TemplateDate stays as default (=current date)
122 68 : pDoc->ResetFromTemplate( rLongName, rFileName );
123 68 : }
124 :
125 :
126 0 : class SfxDocPasswordVerifier : public ::comphelper::IDocPasswordVerifier
127 : {
128 : public:
129 0 : inline explicit SfxDocPasswordVerifier( const Reference< embed::XStorage >& rxStorage ) :
130 0 : mxStorage( rxStorage ) {}
131 :
132 : virtual ::comphelper::DocPasswordVerifierResult
133 : verifyPassword( const OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData ) SAL_OVERRIDE;
134 : virtual ::comphelper::DocPasswordVerifierResult
135 : verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData ) SAL_OVERRIDE;
136 :
137 :
138 : private:
139 : Reference< embed::XStorage > mxStorage;
140 : };
141 :
142 :
143 0 : ::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyPassword( const OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
144 : {
145 0 : o_rEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( rPassword );
146 0 : return verifyEncryptionData( o_rEncryptionData );
147 : }
148 :
149 :
150 :
151 0 : ::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
152 : {
153 0 : ::comphelper::DocPasswordVerifierResult eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
154 : try
155 : {
156 : // check the encryption data
157 : // if the data correct is the stream will be opened successfully
158 : // and immediatelly closed
159 0 : ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( mxStorage, rEncryptionData );
160 :
161 0 : mxStorage->openStreamElement(
162 : OUString( "content.xml" ),
163 0 : embed::ElementModes::READ | embed::ElementModes::NOCREATE );
164 :
165 : // no exception -> success
166 0 : eResult = ::comphelper::DocPasswordVerifierResult_OK;
167 : }
168 0 : catch( const packages::WrongPasswordException& )
169 : {
170 0 : eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
171 : }
172 0 : catch( const uno::Exception& )
173 : {
174 : // unknown error, report it as wrong password
175 : // TODO/LATER: we need an additional way to report unknown problems in this case
176 0 : eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
177 : }
178 0 : return eResult;
179 : }
180 :
181 :
182 :
183 :
184 :
185 612 : sal_uInt32 CheckPasswd_Impl
186 : (
187 : SfxObjectShell* pDoc,
188 : SfxItemPool& /*rPool*/, // Pool, if a Set has to be created
189 : SfxMedium* pFile // the Medium and its Password shold be obtained
190 : )
191 :
192 : /* [Description]
193 :
194 : Ask for the password for a medium, only works if it concerns storage.
195 : If the password flag is set in the Document Info, then the password is
196 : requested through a user dialogue and the set at the Set of the medium.
197 : If the set does not exist the it is created.
198 : */
199 : {
200 612 : sal_uIntPtr nRet = ERRCODE_NONE;
201 :
202 612 : if( ( !pFile->GetFilter() || pFile->IsStorage() ) )
203 : {
204 612 : uno::Reference< embed::XStorage > xStorage = pFile->GetStorage( true );
205 612 : if( xStorage.is() )
206 : {
207 612 : uno::Reference< beans::XPropertySet > xStorageProps( xStorage, uno::UNO_QUERY );
208 612 : if ( xStorageProps.is() )
209 : {
210 612 : bool bIsEncrypted = false;
211 : try {
212 612 : xStorageProps->getPropertyValue("HasEncryptedEntries")
213 616 : >>= bIsEncrypted;
214 4 : } catch( uno::Exception& )
215 : {
216 : // TODO/LATER:
217 : // the storage either has no encrypted elements or it's just
218 : // does not allow to detect it, probably it should be implemented laiter
219 : }
220 :
221 612 : if ( bIsEncrypted )
222 : {
223 8 : vcl::Window* pWin = pDoc ? pDoc->GetDialogParent( pFile ) : NULL;
224 8 : if ( pWin )
225 0 : pWin->Show();
226 :
227 8 : nRet = ERRCODE_SFX_CANTGETPASSWD;
228 :
229 8 : SfxItemSet *pSet = pFile->GetItemSet();
230 8 : if( pSet )
231 : {
232 8 : Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = pFile->GetInteractionHandler();
233 8 : if( xInteractionHandler.is() )
234 : {
235 : // use the comphelper password helper to request a password
236 0 : OUString aPassword;
237 0 : SFX_ITEMSET_ARG( pSet, pPasswordItem, SfxStringItem, SID_PASSWORD, false);
238 0 : if ( pPasswordItem )
239 0 : aPassword = pPasswordItem->GetValue();
240 :
241 0 : uno::Sequence< beans::NamedValue > aEncryptionData;
242 0 : SFX_ITEMSET_ARG( pSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false);
243 0 : if ( pEncryptionDataItem )
244 0 : pEncryptionDataItem->GetValue() >>= aEncryptionData;
245 :
246 0 : OUString aDocumentName = INetURLObject( pFile->GetOrigURL() ).GetMainURL( INetURLObject::DECODE_WITH_CHARSET );
247 :
248 0 : SfxDocPasswordVerifier aVerifier( xStorage );
249 0 : aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
250 0 : aVerifier, aEncryptionData, aPassword, xInteractionHandler, aDocumentName, comphelper::DocPasswordRequestType_STANDARD );
251 :
252 0 : pSet->ClearItem( SID_PASSWORD );
253 0 : pSet->ClearItem( SID_ENCRYPTIONDATA );
254 :
255 0 : if ( aEncryptionData.getLength() > 0 )
256 : {
257 0 : pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
258 :
259 : try
260 : {
261 : // update the version list of the medium using the new password
262 0 : pFile->GetVersionList();
263 : }
264 0 : catch( uno::Exception& )
265 : {
266 : // TODO/LATER: set the error code
267 : }
268 :
269 0 : nRet = ERRCODE_NONE;
270 : }
271 : else
272 0 : nRet = ERRCODE_IO_ABORT;
273 8 : }
274 : }
275 : }
276 : }
277 : else
278 : {
279 : OSL_FAIL( "A storage must implement XPropertySet interface!" );
280 0 : nRet = ERRCODE_SFX_CANTGETPASSWD;
281 612 : }
282 612 : }
283 : }
284 :
285 612 : return nRet;
286 : }
287 :
288 :
289 :
290 :
291 0 : sal_uIntPtr SfxApplication::LoadTemplate( SfxObjectShellLock& xDoc, const OUString &rFileName, bool bCopy, SfxItemSet* pSet )
292 : {
293 0 : const SfxFilter* pFilter = NULL;
294 0 : SfxMedium aMedium( rFileName, ( STREAM_READ | STREAM_SHARE_DENYNONE ) );
295 :
296 0 : if ( !aMedium.GetStorage( false ).is() )
297 0 : aMedium.GetInStream();
298 :
299 0 : if ( aMedium.GetError() )
300 : {
301 0 : delete pSet;
302 0 : return aMedium.GetErrorCode();
303 : }
304 :
305 0 : aMedium.UseInteractionHandler( true );
306 0 : sal_uIntPtr nErr = GetFilterMatcher().GuessFilter( aMedium,&pFilter,SFX_FILTER_TEMPLATE, 0 );
307 0 : if ( 0 != nErr)
308 : {
309 0 : delete pSet;
310 0 : return ERRCODE_SFX_NOTATEMPLATE;
311 : }
312 :
313 0 : if( !pFilter || !pFilter->IsAllowedAsTemplate() )
314 : {
315 0 : delete pSet;
316 0 : return ERRCODE_SFX_NOTATEMPLATE;
317 : }
318 :
319 0 : if ( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER )
320 : {
321 : DBG_ASSERT( !xDoc.Is(), "Sorry, not implemented!" );
322 0 : delete pSet;
323 0 : SfxStringItem aName( SID_FILE_NAME, rFileName );
324 0 : SfxStringItem aReferer( SID_REFERER, OUString("private:user") );
325 0 : SfxStringItem aFlags( SID_OPTIONS, OUString("T") );
326 0 : SfxBoolItem aHidden( SID_HIDDEN, true );
327 0 : const SfxPoolItem *pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, SfxCallMode::SYNCHRON, &aName, &aHidden, &aReferer, &aFlags, 0L );
328 0 : const SfxObjectItem *pObj = PTR_CAST( SfxObjectItem, pRet );
329 0 : if ( pObj )
330 0 : xDoc = const_cast<SfxObjectShell*>(PTR_CAST( SfxObjectShell, pObj->GetShell() ));
331 : else
332 : {
333 0 : const SfxViewFrameItem *pView = PTR_CAST( SfxViewFrameItem, pRet );
334 0 : if ( pView )
335 : {
336 0 : SfxViewFrame *pFrame = pView->GetFrame();
337 0 : if ( pFrame )
338 0 : xDoc = pFrame->GetObjectShell();
339 : }
340 : }
341 :
342 0 : if ( !xDoc.Is() )
343 0 : return ERRCODE_SFX_DOLOADFAILED;
344 : }
345 : else
346 : {
347 0 : if ( !xDoc.Is() )
348 0 : xDoc = SfxObjectShell::CreateObject( pFilter->GetServiceName() );
349 :
350 : //pMedium takes ownership of pSet
351 0 : SfxMedium *pMedium = new SfxMedium( rFileName, STREAM_STD_READ, pFilter, pSet );
352 0 : if(!xDoc->DoLoad(pMedium))
353 : {
354 0 : ErrCode nErrCode = xDoc->GetErrorCode();
355 0 : xDoc->DoClose();
356 0 : xDoc.Clear();
357 0 : return nErrCode;
358 : }
359 : }
360 :
361 0 : if( bCopy )
362 : {
363 : try
364 : {
365 : // TODO: introduce error handling
366 :
367 0 : uno::Reference< embed::XStorage > xTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
368 0 : if( !xTempStorage.is() )
369 0 : throw uno::RuntimeException();
370 :
371 0 : xDoc->GetStorage()->copyToStorage( xTempStorage );
372 :
373 0 : if ( !xDoc->DoSaveCompleted( new SfxMedium( xTempStorage, OUString() ) ) )
374 0 : throw uno::RuntimeException();
375 : }
376 0 : catch( uno::Exception& )
377 : {
378 0 : xDoc->DoClose();
379 0 : xDoc.Clear();
380 :
381 : // TODO: transfer correct error outside
382 0 : return ERRCODE_SFX_GENERAL;
383 : }
384 :
385 0 : SetTemplate_Impl( rFileName, OUString(), xDoc );
386 : }
387 : else
388 0 : SetTemplate_Impl( rFileName, OUString(), xDoc );
389 :
390 0 : xDoc->SetNoName();
391 0 : xDoc->InvalidateName();
392 0 : xDoc->SetModified(false);
393 0 : xDoc->ResetError();
394 :
395 0 : ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel ( xDoc->GetModel(), ::com::sun::star::uno::UNO_QUERY );
396 0 : if ( xModel.is() )
397 : {
398 0 : SfxItemSet* pNew = xDoc->GetMedium()->GetItemSet()->Clone();
399 0 : pNew->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
400 0 : pNew->ClearItem( SID_FILTER_NAME );
401 0 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs;
402 0 : TransformItems( SID_OPENDOC, *pNew, aArgs );
403 0 : sal_Int32 nLength = aArgs.getLength();
404 0 : aArgs.realloc( nLength + 1 );
405 0 : aArgs[nLength].Name = "Title";
406 0 : aArgs[nLength].Value <<= OUString( xDoc->GetTitle( SFX_TITLE_DETECT ) );
407 0 : xModel->attachResource( OUString(), aArgs );
408 0 : delete pNew;
409 : }
410 :
411 0 : return xDoc->GetErrorCode();
412 : }
413 :
414 :
415 :
416 0 : void SfxApplication::NewDocDirectExec_Impl( SfxRequest& rReq )
417 : {
418 0 : SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, false);
419 0 : OUString aFactName;
420 0 : if ( pFactoryItem )
421 0 : aFactName = pFactoryItem->GetValue();
422 : else
423 0 : aFactName = SvtModuleOptions().GetDefaultModuleName();
424 :
425 :
426 0 : SfxRequest aReq( SID_OPENDOC, SfxCallMode::SYNCHRON, GetPool() );
427 0 : OUString aFact("private:factory/");
428 0 : aFact += aFactName;
429 0 : aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) );
430 0 : aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, GetFrame() ) );
431 0 : aReq.AppendItem( SfxStringItem( SID_TARGETNAME, OUString( "_default" ) ) );
432 :
433 : // TODO/LATER: Should the other arguments be transferred as well?
434 0 : SFX_REQUEST_ARG( rReq, pDefaultPathItem, SfxStringItem, SID_DEFAULTFILEPATH, false);
435 0 : if ( pDefaultPathItem )
436 0 : aReq.AppendItem( *pDefaultPathItem );
437 0 : SFX_REQUEST_ARG( rReq, pDefaultNameItem, SfxStringItem, SID_DEFAULTFILENAME, false);
438 0 : if ( pDefaultNameItem )
439 0 : aReq.AppendItem( *pDefaultNameItem );
440 :
441 0 : SfxGetpApp()->ExecuteSlot( aReq );
442 0 : const SfxViewFrameItem* pItem = PTR_CAST( SfxViewFrameItem, aReq.GetReturnValue() );
443 0 : if ( pItem )
444 0 : rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) );
445 0 : }
446 :
447 :
448 :
449 0 : void SfxApplication::NewDocExec_Impl( SfxRequest& rReq )
450 : {
451 : // No Parameter from BASIC only Factory given?
452 0 : SFX_REQUEST_ARG(rReq, pTemplNameItem, SfxStringItem, SID_TEMPLATE_NAME, false);
453 0 : SFX_REQUEST_ARG(rReq, pTemplFileNameItem, SfxStringItem, SID_FILE_NAME, false);
454 0 : SFX_REQUEST_ARG(rReq, pTemplRegionNameItem, SfxStringItem, SID_TEMPLATE_REGIONNAME, false);
455 :
456 0 : SfxObjectShellLock xDoc;
457 :
458 0 : OUString aTemplateRegion, aTemplateName, aTemplateFileName;
459 0 : bool bDirect = false; // through FileName instead of Region/Template
460 0 : SfxErrorContext aEc(ERRCTX_SFX_NEWDOC);
461 0 : if ( !pTemplNameItem && !pTemplFileNameItem )
462 : {
463 0 : bool bNewWin = false;
464 0 : vcl::Window* pTopWin = GetTopWindow();
465 :
466 0 : SfxTemplateManagerDlg aTemplDlg;
467 0 : int nRet = aTemplDlg.Execute();
468 0 : if ( nRet == RET_OK )
469 : {
470 0 : rReq.Done();
471 0 : if ( pTopWin != GetTopWindow() )
472 : {
473 : // the dialogue opens a document -> a new TopWindow appears
474 0 : pTopWin = GetTopWindow();
475 0 : bNewWin = true;
476 : }
477 : }
478 :
479 0 : if ( bNewWin && pTopWin )
480 : // after the destruction of the dialogue its parent comes to top,
481 : // but we want that the new document is on top
482 0 : pTopWin->ToTop();
483 :
484 0 : return;
485 : }
486 : else
487 : {
488 : // Template-Name
489 0 : if ( pTemplNameItem )
490 0 : aTemplateName = pTemplNameItem->GetValue();
491 :
492 : // Template-Region
493 0 : if ( pTemplRegionNameItem )
494 0 : aTemplateRegion = pTemplRegionNameItem->GetValue();
495 :
496 : // Template-File-Name
497 0 : if ( pTemplFileNameItem )
498 : {
499 0 : aTemplateFileName = pTemplFileNameItem->GetValue();
500 0 : bDirect = true;
501 : }
502 : }
503 :
504 0 : sal_uIntPtr lErr = 0;
505 0 : SfxItemSet* pSet = new SfxAllItemSet( GetPool() );
506 0 : pSet->Put( SfxBoolItem( SID_TEMPLATE, true ) );
507 0 : if ( !bDirect )
508 : {
509 0 : SfxDocumentTemplates aTmpFac;
510 0 : if( aTemplateFileName.isEmpty() )
511 0 : aTmpFac.GetFull( aTemplateRegion, aTemplateName, aTemplateFileName );
512 :
513 0 : if( aTemplateFileName.isEmpty() )
514 0 : lErr = ERRCODE_SFX_TEMPLATENOTFOUND;
515 : }
516 :
517 0 : INetURLObject aObj( aTemplateFileName );
518 0 : SfxErrorContext aEC( ERRCTX_SFX_LOADTEMPLATE, aObj.PathToFileName() );
519 :
520 0 : if ( lErr != ERRCODE_NONE )
521 : {
522 0 : sal_uIntPtr lFatalErr = ERRCODE_TOERROR(lErr);
523 0 : if ( lFatalErr )
524 0 : ErrorHandler::HandleError(lErr);
525 : }
526 : else
527 : {
528 0 : SfxCallMode eMode = SfxCallMode::SYNCHRON;
529 :
530 0 : const SfxPoolItem *pRet=0;
531 0 : SfxStringItem aReferer( SID_REFERER, "private:user" );
532 0 : SfxStringItem aTarget( SID_TARGETNAME, "_default" );
533 0 : if ( !aTemplateFileName.isEmpty() )
534 : {
535 : DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" );
536 :
537 0 : SfxStringItem aName( SID_FILE_NAME, aObj.GetMainURL( INetURLObject::NO_DECODE ) );
538 0 : SfxStringItem aTemplName( SID_TEMPLATE_NAME, aTemplateName );
539 0 : SfxStringItem aTemplRegionName( SID_TEMPLATE_REGIONNAME, aTemplateRegion );
540 0 : pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, &aTemplName, &aTemplRegionName, 0L );
541 : }
542 : else
543 : {
544 0 : SfxStringItem aName( SID_FILE_NAME, "private:factory" );
545 0 : pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, 0L );
546 : }
547 :
548 0 : if ( pRet )
549 0 : rReq.SetReturnValue( *pRet );
550 0 : }
551 : }
552 :
553 :
554 :
555 : namespace {
556 :
557 : /**
558 : * Check if a given filter type should open the hyperlinked document
559 : * natively.
560 : *
561 : * @param rFilter filter object
562 : */
563 0 : bool lcl_isFilterNativelySupported(const SfxFilter& rFilter)
564 : {
565 0 : if (rFilter.IsOwnFormat())
566 0 : return true;
567 :
568 0 : OUString aName = rFilter.GetFilterName();
569 0 : if (aName.startsWith("MS Excel"))
570 : // We can handle all Excel variants natively.
571 0 : return true;
572 :
573 0 : return false;
574 : }
575 :
576 : }
577 :
578 0 : void SfxApplication::OpenDocExec_Impl( SfxRequest& rReq )
579 : {
580 0 : OUString aDocService;
581 0 : SFX_REQUEST_ARG(rReq, pDocSrvItem, SfxStringItem, SID_DOC_SERVICE, false);
582 0 : if (pDocSrvItem)
583 0 : aDocService = pDocSrvItem->GetValue();
584 :
585 0 : sal_uInt16 nSID = rReq.GetSlot();
586 0 : SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, false );
587 0 : if ( pFileNameItem )
588 : {
589 0 : OUString aCommand( pFileNameItem->GetValue() );
590 0 : const SfxSlot* pSlot = GetInterface()->GetSlot( aCommand );
591 0 : if ( pSlot )
592 : {
593 0 : pFileNameItem = NULL;
594 : }
595 : else
596 : {
597 0 : if ( aCommand.startsWith("slot:") )
598 : {
599 0 : sal_uInt16 nSlotId = (sal_uInt16) aCommand.copy(5).toInt32();
600 0 : if ( nSlotId == SID_OPENDOC )
601 0 : pFileNameItem = NULL;
602 : }
603 0 : }
604 : }
605 :
606 0 : if ( !pFileNameItem )
607 : {
608 : // get FileName from dialog
609 0 : std::vector<OUString> pURLList;
610 0 : OUString aFilter;
611 0 : SfxItemSet* pSet = NULL;
612 0 : OUString aPath;
613 0 : SFX_REQUEST_ARG( rReq, pFolderNameItem, SfxStringItem, SID_PATH, false );
614 0 : if ( pFolderNameItem )
615 0 : aPath = pFolderNameItem->GetValue();
616 0 : else if ( nSID == SID_OPENTEMPLATE )
617 : {
618 0 : aPath = SvtPathOptions().GetTemplatePath();
619 0 : sal_Int32 nTokenCount = comphelper::string::getTokenCount(aPath, ';');
620 0 : aPath = aPath.getToken( nTokenCount ? ( nTokenCount - 1 ) : 0 , ';' );
621 : }
622 :
623 0 : sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG;
624 0 : SFX_REQUEST_ARG( rReq, pSystemDialogItem, SfxBoolItem, SID_FILE_DIALOG, false );
625 0 : if ( pSystemDialogItem )
626 0 : nDialog = pSystemDialogItem->GetValue() ? SFX2_IMPL_DIALOG_SYSTEM : SFX2_IMPL_DIALOG_OOO;
627 :
628 0 : OUString sStandardDir;
629 :
630 0 : SFX_REQUEST_ARG( rReq, pStandardDirItem, SfxStringItem, SID_STANDARD_DIR, false );
631 0 : if ( pStandardDirItem )
632 0 : sStandardDir = pStandardDirItem->GetValue();
633 :
634 0 : ::com::sun::star::uno::Sequence< OUString > aBlackList;
635 :
636 0 : SFX_REQUEST_ARG( rReq, pBlackListItem, SfxStringListItem, SID_BLACK_LIST, false );
637 0 : if ( pBlackListItem )
638 0 : pBlackListItem->GetStringList( aBlackList );
639 :
640 :
641 : sal_uIntPtr nErr = sfx2::FileOpenDialog_Impl(
642 : ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
643 : SFXWB_MULTISELECTION, OUString(), pURLList,
644 0 : aFilter, pSet, &aPath, nDialog, sStandardDir, aBlackList );
645 :
646 0 : if ( nErr == ERRCODE_ABORT )
647 : {
648 0 : pURLList.clear();
649 0 : return;
650 : }
651 :
652 0 : rReq.SetArgs( *static_cast<SfxAllItemSet*>(pSet) );
653 0 : if ( !aFilter.isEmpty() )
654 0 : rReq.AppendItem( SfxStringItem( SID_FILTER_NAME, aFilter ) );
655 0 : rReq.AppendItem( SfxStringItem( SID_TARGETNAME, OUString("_default") ) );
656 0 : rReq.AppendItem( SfxStringItem( SID_REFERER, "private:user" ) );
657 0 : delete pSet;
658 :
659 0 : if(!pURLList.empty())
660 : {
661 0 : if ( nSID == SID_OPENTEMPLATE )
662 0 : rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, false ) );
663 :
664 : // This helper wraps an existing (or may new created InteractionHandler)
665 : // intercept all incoming interactions and provide useful information
666 : // later if the following transaction was finished.
667 :
668 0 : ::framework::PreventDuplicateInteraction* pHandler = new ::framework::PreventDuplicateInteraction(::comphelper::getProcessComponentContext());
669 0 : css::uno::Reference< css::task::XInteractionHandler > xHandler (static_cast< css::task::XInteractionHandler* >(pHandler), css::uno::UNO_QUERY);
670 0 : css::uno::Reference< css::task::XInteractionHandler > xWrappedHandler;
671 :
672 : // wrap existing handler or create new UUI handler
673 0 : SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, false);
674 0 : if (pInteractionItem)
675 : {
676 0 : pInteractionItem->GetValue() >>= xWrappedHandler;
677 0 : rReq.RemoveItem( SID_INTERACTIONHANDLER );
678 : }
679 0 : if (xWrappedHandler.is())
680 0 : pHandler->setHandler(xWrappedHandler);
681 : else
682 0 : pHandler->useDefaultUUIHandler();
683 0 : rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHandler)) );
684 :
685 : // define rules for this handler
686 0 : css::uno::Type aInteraction = ::cppu::UnoType<css::task::ErrorCodeRequest>::get();
687 0 : ::framework::PreventDuplicateInteraction::InteractionInfo aRule (aInteraction, 1);
688 0 : pHandler->addInteractionRule(aRule);
689 :
690 0 : if (!aDocService.isEmpty())
691 : {
692 0 : rReq.RemoveItem(SID_DOC_SERVICE);
693 0 : rReq.AppendItem(SfxStringItem(SID_DOC_SERVICE, aDocService));
694 : }
695 :
696 0 : for(std::vector<OUString>::const_iterator i = pURLList.begin(); i != pURLList.end(); ++i)
697 : {
698 0 : rReq.RemoveItem( SID_FILE_NAME );
699 0 : rReq.AppendItem( SfxStringItem( SID_FILE_NAME, *i ) );
700 :
701 : // Run synchronous, so that not the next document is loaded
702 : // when rescheduling
703 : // TODO/LATER: use URLList argument and always remove one document after another, each step in asychronous execution, until finished
704 : // but only if reschedule is a problem
705 0 : GetDispatcher_Impl()->Execute( SID_OPENDOC, SfxCallMode::SYNCHRON, *rReq.GetArgs() );
706 :
707 : // check for special interaction "NO MORE DOCUMENTS ALLOWED" and
708 : // break loop then. Otherwise we risk showing the same interaction more than once.
709 0 : if ( pHandler->getInteractionInfo(aInteraction, &aRule) )
710 : {
711 0 : if (aRule.m_nCallCount > 0)
712 : {
713 0 : if (aRule.m_xRequest.is())
714 : {
715 0 : css::task::ErrorCodeRequest aRequest;
716 0 : if (aRule.m_xRequest->getRequest() >>= aRequest)
717 : {
718 0 : if (aRequest.ErrCode ==
719 : sal::static_int_cast< sal_Int32 >(
720 0 : ERRCODE_SFX_NOMOREDOCUMENTSALLOWED))
721 0 : break;
722 0 : }
723 : }
724 : }
725 : }
726 : }
727 :
728 0 : pURLList.clear();
729 0 : return;
730 : }
731 0 : pURLList.clear();
732 : }
733 :
734 0 : bool bHyperlinkUsed = false;
735 :
736 0 : if ( SID_OPENURL == nSID )
737 : {
738 : // SID_OPENURL does the same as SID_OPENDOC!
739 0 : rReq.SetSlot( SID_OPENDOC );
740 0 : nSID = SID_OPENDOC;
741 : }
742 0 : else if ( nSID == SID_OPENTEMPLATE )
743 : {
744 0 : rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, false ) );
745 : }
746 : // pass URL to OS by using ShellExecuter or open it internal
747 : // if it seems to be an own format.
748 : /* Attention!
749 : There exist two possibilities to open hyperlinks:
750 : a) using SID_OPENHYPERLINK (new)
751 : b) using SID_BROWSE (old)
752 : */
753 0 : else if ( nSID == SID_OPENHYPERLINK )
754 : {
755 0 : rReq.SetSlot( SID_OPENDOC );
756 0 : nSID = SID_OPENDOC;
757 0 : bHyperlinkUsed = true;
758 : }
759 :
760 : // no else here! It's optional ...
761 0 : if (!bHyperlinkUsed)
762 : {
763 0 : SFX_REQUEST_ARG(rReq, pHyperLinkUsedItem, SfxBoolItem, SID_BROWSE, false);
764 0 : if ( pHyperLinkUsedItem )
765 0 : bHyperlinkUsed = pHyperLinkUsedItem->GetValue();
766 : // no "official" item, so remove it from ItemSet before using UNO-API
767 0 : rReq.RemoveItem( SID_BROWSE );
768 : }
769 :
770 0 : SFX_REQUEST_ARG( rReq, pFileName, SfxStringItem, SID_FILE_NAME, false );
771 0 : OUString aFileName = pFileName->GetValue();
772 :
773 0 : OUString aReferer;
774 0 : SFX_REQUEST_ARG( rReq, pRefererItem, SfxStringItem, SID_REFERER, false );
775 0 : if ( pRefererItem )
776 0 : aReferer = pRefererItem->GetValue();
777 :
778 0 : SFX_REQUEST_ARG( rReq, pFileFlagsItem, SfxStringItem, SID_OPTIONS, false);
779 0 : if ( pFileFlagsItem )
780 : {
781 0 : OUString aFileFlags = pFileFlagsItem->GetValue();
782 0 : aFileFlags = aFileFlags.toAsciiUpperCase();
783 0 : if ( -1 != aFileFlags.indexOf( 0x0054 ) ) // T = 54h
784 : {
785 0 : rReq.RemoveItem( SID_TEMPLATE );
786 0 : rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, true ) );
787 : }
788 :
789 0 : if ( -1 != aFileFlags.indexOf( 0x0048 ) ) // H = 48h
790 : {
791 0 : rReq.RemoveItem( SID_HIDDEN );
792 0 : rReq.AppendItem( SfxBoolItem( SID_HIDDEN, true ) );
793 : }
794 :
795 0 : if ( -1 != aFileFlags.indexOf( 0x0052 ) ) // R = 52h
796 : {
797 0 : rReq.RemoveItem( SID_DOC_READONLY );
798 0 : rReq.AppendItem( SfxBoolItem( SID_DOC_READONLY, true ) );
799 : }
800 :
801 0 : if ( -1 != aFileFlags.indexOf( 0x0042 ) ) // B = 42h
802 : {
803 0 : rReq.RemoveItem( SID_PREVIEW );
804 0 : rReq.AppendItem( SfxBoolItem( SID_PREVIEW, true ) );
805 : }
806 :
807 0 : rReq.RemoveItem( SID_OPTIONS );
808 : }
809 :
810 : // Mark without URL cannot be handled by hyperlink code
811 0 : if ( bHyperlinkUsed && !aFileName.isEmpty() && aFileName[0] != '#' )
812 : {
813 : Reference< ::com::sun::star::document::XTypeDetection > xTypeDetection(
814 0 : ::comphelper::getProcessServiceFactory()->createInstance(
815 0 : OUString("com.sun.star.document.TypeDetection")),
816 0 : UNO_QUERY );
817 0 : if ( xTypeDetection.is() )
818 : {
819 0 : URL aURL;
820 0 : OUString aTypeName;
821 :
822 0 : aURL.Complete = aFileName;
823 0 : Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
824 0 : xTrans->parseStrict( aURL );
825 :
826 0 : INetProtocol aINetProtocol = INetURLObject( aURL.Complete ).GetProtocol();
827 0 : SvtExtendedSecurityOptions aExtendedSecurityOptions;
828 0 : SvtExtendedSecurityOptions::OpenHyperlinkMode eMode = aExtendedSecurityOptions.GetOpenHyperlinkMode();
829 :
830 0 : if ( eMode == SvtExtendedSecurityOptions::OPEN_NEVER && aINetProtocol != INET_PROT_VND_SUN_STAR_HELP )
831 : {
832 0 : SolarMutexGuard aGuard;
833 0 : vcl::Window *pWindow = SfxGetpApp()->GetTopWindow();
834 :
835 : MessageDialog aSecurityWarningBox(pWindow,
836 : SfxResId(STR_SECURITY_WARNING_NO_HYPERLINKS),
837 0 : VCL_MESSAGE_WARNING);
838 0 : aSecurityWarningBox.SetText( SfxResId(RID_SECURITY_WARNING_TITLE).toString() );
839 0 : aSecurityWarningBox.Execute();
840 0 : return;
841 : }
842 :
843 0 : aTypeName = xTypeDetection->queryTypeByURL( aURL.Main );
844 0 : SfxFilterMatcher& rMatcher = SfxGetpApp()->GetFilterMatcher();
845 0 : const SfxFilter* pFilter = rMatcher.GetFilter4EA( aTypeName );
846 0 : if (!pFilter || !lcl_isFilterNativelySupported(*pFilter))
847 : {
848 : // hyperlink does not link to own type => special handling (http, ftp) browser and (other external protocols) OS
849 0 : if ( aINetProtocol == INET_PROT_MAILTO )
850 : {
851 : // don't dispatch mailto hyperlink to desktop dispatcher
852 0 : rReq.RemoveItem( SID_TARGETNAME );
853 0 : rReq.AppendItem( SfxStringItem( SID_TARGETNAME, OUString("_self") ) );
854 : }
855 0 : else if ( aINetProtocol == INET_PROT_FTP ||
856 0 : aINetProtocol == INET_PROT_HTTP ||
857 : aINetProtocol == INET_PROT_HTTPS )
858 : {
859 0 : sfx2::openUriExternally(aURL.Complete, true);
860 0 : return;
861 : }
862 : else
863 : {
864 : // check for "internal" protocols that should not be forwarded to the system
865 0 : Sequence < OUString > aProtocols(2);
866 :
867 : // add special protocols that always should be treated as internal
868 0 : aProtocols[0] = "private:*";
869 0 : aProtocols[1] = "vnd.sun.star.*";
870 :
871 : // get registered protocol handlers from configuration
872 0 : Reference < XNameAccess > xAccess(officecfg::Office::ProtocolHandler::HandlerSet::get());
873 0 : Sequence < OUString > aNames = xAccess->getElementNames();
874 0 : for ( sal_Int32 nName = 0; nName < aNames.getLength(); nName ++)
875 : {
876 0 : Reference < XPropertySet > xSet;
877 0 : Any aRet = xAccess->getByName( aNames[nName] );
878 0 : aRet >>= xSet;
879 0 : if ( xSet.is() )
880 : {
881 : // copy protocols
882 0 : aRet = xSet->getPropertyValue("Protocols");
883 0 : Sequence < OUString > aTmp;
884 0 : aRet >>= aTmp;
885 :
886 : // todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols
887 0 : sal_Int32 nLength = aProtocols.getLength();
888 0 : aProtocols.realloc( nLength+aTmp.getLength() );
889 0 : for ( sal_Int32 n=0; n<aTmp.getLength(); n++ )
890 0 : aProtocols[(++nLength)-1] = aTmp[n];
891 : }
892 0 : }
893 :
894 0 : bool bFound = false;
895 0 : for ( sal_Int32 nProt=0; nProt<aProtocols.getLength(); nProt++ )
896 : {
897 0 : WildCard aPattern(aProtocols[nProt]);
898 0 : if ( aPattern.Matches( aURL.Complete ) )
899 : {
900 0 : bFound = true;
901 0 : break;
902 : }
903 0 : }
904 :
905 0 : if ( !bFound )
906 : {
907 0 : bool bLoadInternal = false;
908 : try
909 : {
910 : sfx2::openUriExternally(
911 0 : aURL.Complete, pFilter == 0);
912 : }
913 0 : catch ( ::com::sun::star::system::SystemShellExecuteException& )
914 : {
915 0 : rReq.RemoveItem( SID_TARGETNAME );
916 0 : rReq.AppendItem( SfxStringItem( SID_TARGETNAME, OUString("_default") ) );
917 0 : bLoadInternal = true;
918 : }
919 0 : if ( !bLoadInternal )
920 0 : return;
921 0 : }
922 : }
923 : }
924 : else
925 : {
926 : // hyperlink document must be loaded into a new frame
927 0 : rReq.RemoveItem( SID_TARGETNAME );
928 0 : rReq.AppendItem( SfxStringItem( SID_TARGETNAME, OUString("_default") ) );
929 0 : }
930 0 : }
931 : }
932 :
933 0 : if (!SvtSecurityOptions().isSecureMacroUri(aFileName, aReferer))
934 : {
935 0 : SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aFileName );
936 0 : ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
937 0 : return;
938 : }
939 :
940 0 : SfxFrame* pTargetFrame = NULL;
941 0 : Reference< XFrame > xTargetFrame;
942 :
943 0 : SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, false);
944 0 : if ( pFrameItem )
945 0 : pTargetFrame = pFrameItem->GetFrame();
946 :
947 0 : if ( !pTargetFrame )
948 : {
949 0 : SFX_REQUEST_ARG(rReq, pUnoFrameItem, SfxUnoFrameItem, SID_FILLFRAME, false);
950 0 : if ( pUnoFrameItem )
951 0 : xTargetFrame = pUnoFrameItem->GetFrame();
952 : }
953 :
954 0 : if ( !pTargetFrame && !xTargetFrame.is() && SfxViewFrame::Current() )
955 0 : pTargetFrame = &SfxViewFrame::Current()->GetFrame();
956 :
957 : // check if caller has set a callback
958 0 : SFX_REQUEST_ARG(rReq, pLinkItem, SfxLinkItem, SID_DONELINK, false );
959 :
960 : // remove from Itemset, because it confuses the parameter transformation
961 0 : if ( pLinkItem )
962 0 : pLinkItem = static_cast<SfxLinkItem*>( pLinkItem->Clone() );
963 :
964 0 : rReq.RemoveItem( SID_DONELINK );
965 :
966 : // check if the view must be hidden
967 0 : bool bHidden = false;
968 0 : SFX_REQUEST_ARG(rReq, pHidItem, SfxBoolItem, SID_HIDDEN, false);
969 0 : if ( pHidItem )
970 0 : bHidden = pHidItem->GetValue();
971 :
972 : // This request is a UI call. We have to set the right values inside the MediaDescriptor
973 : // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate.
974 : // But we have to look for already existing values or for real hidden requests.
975 0 : SFX_REQUEST_ARG(rReq, pPreviewItem, SfxBoolItem, SID_PREVIEW, false);
976 0 : if (!bHidden && ( !pPreviewItem || !pPreviewItem->GetValue() ) )
977 : {
978 0 : SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, false);
979 0 : SFX_REQUEST_ARG(rReq, pMacroExecItem , SfxUInt16Item, SID_MACROEXECMODE , false);
980 0 : SFX_REQUEST_ARG(rReq, pDocTemplateItem, SfxUInt16Item, SID_UPDATEDOCMODE , false);
981 :
982 0 : if (!pInteractionItem)
983 : {
984 0 : Reference < task::XInteractionHandler2 > xHdl = task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), 0 );
985 0 : rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHdl)) );
986 : }
987 0 : if (!pMacroExecItem)
988 0 : rReq.AppendItem( SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::USE_CONFIG) );
989 0 : if (!pDocTemplateItem)
990 0 : rReq.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG) );
991 : }
992 :
993 : // extract target name
994 0 : OUString aTarget;
995 0 : SFX_REQUEST_ARG(rReq, pTargetItem, SfxStringItem, SID_TARGETNAME, false);
996 0 : if ( pTargetItem )
997 0 : aTarget = pTargetItem->GetValue();
998 : else
999 : {
1000 0 : SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, false );
1001 0 : if ( pNewViewItem && pNewViewItem->GetValue() )
1002 0 : aTarget = "_blank" ;
1003 : }
1004 :
1005 0 : if ( bHidden )
1006 : {
1007 0 : aTarget = "_blank";
1008 : DBG_ASSERT( rReq.IsSynchronCall() || pLinkItem, "Hidden load process must be done synchronously!" );
1009 : }
1010 :
1011 0 : Reference < XController > xController;
1012 : // if a frame is given, it must be used for the starting point of the targetting mechanism
1013 : // this code is also used if asynchronous loading is possible, because loadComponent always is synchron
1014 0 : if ( !xTargetFrame.is() )
1015 : {
1016 0 : if ( pTargetFrame )
1017 : {
1018 0 : xTargetFrame = pTargetFrame->GetFrameInterface();
1019 : }
1020 : else
1021 : {
1022 0 : xTargetFrame.set( Desktop::create(::comphelper::getProcessComponentContext()), UNO_QUERY );
1023 : }
1024 : }
1025 :
1026 : // make URL ready
1027 0 : SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_FILE_NAME, false );
1028 0 : aFileName = pURLItem->GetValue();
1029 0 : if( aFileName.startsWith("#") ) // Mark without URL
1030 : {
1031 0 : SfxViewFrame *pView = pTargetFrame ? pTargetFrame->GetCurrentViewFrame() : 0;
1032 0 : if ( !pView )
1033 0 : pView = SfxViewFrame::Current();
1034 0 : pView->GetViewShell()->JumpToMark( aFileName.copy(1) );
1035 0 : rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) );
1036 0 : return;
1037 : }
1038 :
1039 : // convert items to properties for framework API calls
1040 0 : Sequence < PropertyValue > aArgs;
1041 0 : TransformItems( SID_OPENDOC, *rReq.GetArgs(), aArgs );
1042 : // Any Referer (that was relevant in the above call to
1043 : // SvtSecurityOptions::isSecureMacroUri) is no longer relevant, assuming
1044 : // this "open" request is initiated directly by the user:
1045 0 : for (sal_Int32 i = 0; i != aArgs.getLength(); ++i) {
1046 0 : if (aArgs[i].Name == "Referer") {
1047 0 : ++i;
1048 0 : for (; i != aArgs.getLength(); ++i) {
1049 0 : aArgs[i - 1] = aArgs[i];
1050 : }
1051 0 : aArgs.realloc(aArgs.getLength()-1);
1052 0 : break;
1053 : }
1054 : }
1055 :
1056 : // TODO/LATER: either remove LinkItem or create an asynchronous process for it
1057 0 : if( bHidden || pLinkItem || rReq.IsSynchronCall() )
1058 : {
1059 : // if loading must be done synchron, we must wait for completion to get a return value
1060 : // find frame by myself; I must konw the exact frame to get the controller for the return value from it
1061 0 : Reference < XComponent > xComp;
1062 :
1063 : try
1064 : {
1065 0 : xComp = ::comphelper::SynchronousDispatch::dispatch( xTargetFrame, aFileName, aTarget, 0, aArgs );
1066 : }
1067 0 : catch(const RuntimeException&)
1068 : {
1069 0 : throw;
1070 : }
1071 0 : catch(const ::com::sun::star::uno::Exception&)
1072 : {
1073 : }
1074 :
1075 0 : Reference < XModel > xModel( xComp, UNO_QUERY );
1076 0 : if ( xModel.is() )
1077 0 : xController = xModel->getCurrentController();
1078 : else
1079 0 : xController = Reference < XController >( xComp, UNO_QUERY );
1080 :
1081 : }
1082 : else
1083 : {
1084 0 : URL aURL;
1085 0 : aURL.Complete = aFileName;
1086 0 : Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
1087 0 : xTrans->parseStrict( aURL );
1088 :
1089 0 : Reference < XDispatchProvider > xProv( xTargetFrame, UNO_QUERY );
1090 0 : Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, aTarget, FrameSearchFlag::ALL ) : Reference < XDispatch >();;
1091 : SAL_INFO( "sfx.appl", "PERFORMANCE - SfxApplication::OpenDocExec_Impl" );
1092 0 : if ( xDisp.is() )
1093 0 : xDisp->dispatch( aURL, aArgs );
1094 : }
1095 :
1096 0 : if ( xController.is() )
1097 : {
1098 : // try to find the SfxFrame for the controller
1099 0 : SfxFrame* pCntrFrame = NULL;
1100 0 : for ( SfxViewShell* pShell = SfxViewShell::GetFirst( 0, false ); pShell; pShell = SfxViewShell::GetNext( *pShell, 0, false ) )
1101 : {
1102 0 : if ( pShell->GetController() == xController )
1103 : {
1104 0 : pCntrFrame = &pShell->GetViewFrame()->GetFrame();
1105 0 : break;
1106 : }
1107 : }
1108 :
1109 0 : if ( pCntrFrame )
1110 : {
1111 0 : SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument();
1112 : DBG_ASSERT( pSh, "Controller without ObjectShell ?!" );
1113 :
1114 0 : rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) );
1115 :
1116 0 : if ( bHidden )
1117 0 : pSh->RestoreNoDelete();
1118 : }
1119 : }
1120 :
1121 0 : if ( pLinkItem )
1122 : {
1123 0 : SfxPoolItem* pRet = rReq.GetReturnValue()->Clone();
1124 0 : pLinkItem->GetValue().Call(pRet);
1125 0 : delete pLinkItem;
1126 0 : }
1127 951 : }
1128 :
1129 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|