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 <comphelper/string.hxx>
21 : #include <sfx2/linkmgr.hxx>
22 : #include <com/sun/star/document/UpdateDocMode.hpp>
23 : #include <sfx2/objsh.hxx>
24 : #include <svl/urihelper.hxx>
25 : #include <sot/formats.hxx>
26 : #include <tools/urlobj.hxx>
27 : #include <sot/exchange.hxx>
28 : #include <tools/debug.hxx>
29 : #include <vcl/msgbox.hxx>
30 : #include <sfx2/lnkbase.hxx>
31 : #include <sfx2/app.hxx>
32 : #include <vcl/graph.hxx>
33 : #include <svl/stritem.hxx>
34 : #include <svl/eitem.hxx>
35 : #include <svl/intitem.hxx>
36 : #include <unotools/localfilehelper.hxx>
37 : #include <i18nlangtag/languagetag.hxx>
38 : #include <sfx2/request.hxx>
39 : #include <vcl/dibtools.hxx>
40 : #include "unotools/charclass.hxx"
41 :
42 : #include "fileobj.hxx"
43 : #include "impldde.hxx"
44 : #include "app.hrc"
45 : #include <sfx2/sfxresid.hxx>
46 :
47 : #include <com/sun/star/lang/XComponent.hpp>
48 : #include <com/sun/star/util/XCloseable.hpp>
49 :
50 : using ::com::sun::star::uno::UNO_QUERY;
51 : using ::com::sun::star::uno::Reference;
52 : using ::com::sun::star::lang::XComponent;
53 : using ::com::sun::star::util::XCloseable;
54 :
55 : namespace sfx2
56 : {
57 :
58 20 : class SvxInternalLink : public sfx2::SvLinkSource
59 : {
60 : public:
61 10 : SvxInternalLink() {}
62 :
63 : virtual bool Connect( sfx2::SvBaseLink* ) SAL_OVERRIDE;
64 : };
65 :
66 :
67 6716 : LinkManager::LinkManager(SfxObjectShell* p)
68 6716 : : pPersist( p )
69 : {
70 6716 : }
71 :
72 :
73 13418 : LinkManager::~LinkManager()
74 : {
75 6709 : for( size_t n = 0; n < aLinkTbl.size(); ++n)
76 : {
77 0 : SvBaseLinkRef* pTmp = aLinkTbl[ n ];
78 0 : if( pTmp->Is() )
79 : {
80 0 : (*pTmp)->Disconnect();
81 0 : (*pTmp)->SetLinkManager( NULL );
82 : }
83 0 : delete pTmp;
84 : }
85 6709 : }
86 :
87 0 : void LinkManager::InsertCachedComp(const Reference<XComponent>& xComp)
88 : {
89 0 : maCachedComps.push_back(xComp);
90 0 : }
91 :
92 16 : void LinkManager::CloseCachedComps()
93 : {
94 16 : CompVector::iterator itr = maCachedComps.begin(), itrEnd = maCachedComps.end();
95 16 : for (; itr != itrEnd; ++itr)
96 : {
97 0 : Reference<XCloseable> xCloseable(*itr, UNO_QUERY);
98 0 : if (!xCloseable.is())
99 0 : continue;
100 :
101 0 : xCloseable->close(true);
102 0 : }
103 16 : maCachedComps.clear();
104 16 : }
105 :
106 :
107 :
108 70 : void LinkManager::Remove( SvBaseLink *pLink )
109 : {
110 : // No duplicate links inserted
111 70 : int bFound = sal_False;
112 140 : for( size_t n = 0; n < aLinkTbl.size(); )
113 : {
114 52 : SvBaseLinkRef* pTmp = aLinkTbl[ n ];
115 52 : if( pLink == *pTmp )
116 : {
117 52 : (*pTmp)->Disconnect();
118 52 : (*pTmp)->SetLinkManager( NULL );
119 52 : (*pTmp).Clear();
120 52 : bFound = sal_True;
121 : }
122 :
123 : // Remove empty ones if they exist
124 52 : if( !pTmp->Is() )
125 : {
126 52 : delete pTmp;
127 52 : aLinkTbl.erase( aLinkTbl.begin() + n );
128 52 : if( bFound )
129 122 : return ;
130 : }
131 : else
132 0 : ++n;
133 : }
134 : }
135 :
136 :
137 34 : void LinkManager::Remove( size_t nPos, size_t nCnt )
138 : {
139 34 : if( nCnt && nPos < aLinkTbl.size() )
140 : {
141 34 : if (sal::static_int_cast<size_t>(nPos + nCnt) > aLinkTbl.size())
142 0 : nCnt = aLinkTbl.size() - nPos;
143 :
144 70 : for( size_t n = nPos; n < nPos + nCnt; ++n)
145 : {
146 36 : SvBaseLinkRef* pTmp = aLinkTbl[ n ];
147 36 : if( pTmp->Is() )
148 : {
149 36 : (*pTmp)->Disconnect();
150 36 : (*pTmp)->SetLinkManager( NULL );
151 : }
152 36 : delete pTmp;
153 : }
154 34 : aLinkTbl.erase( aLinkTbl.begin() + nPos, aLinkTbl.begin() + nPos + nCnt );
155 : }
156 34 : }
157 :
158 :
159 88 : bool LinkManager::Insert( SvBaseLink* pLink )
160 : {
161 90 : for( size_t n = 0; n < aLinkTbl.size(); ++n )
162 : {
163 2 : SvBaseLinkRef* pTmp = aLinkTbl[ n ];
164 2 : if( !pTmp->Is() )
165 : {
166 0 : delete pTmp;
167 0 : aLinkTbl.erase( aLinkTbl.begin() + n-- );
168 : }
169 2 : else if( pLink == *pTmp )
170 0 : return false; // No duplicate links inserted
171 : }
172 :
173 88 : SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink );
174 88 : pLink->SetLinkManager( this );
175 88 : aLinkTbl.push_back( pTmp );
176 88 : return true;
177 : }
178 :
179 :
180 70 : bool LinkManager::InsertLink( SvBaseLink * pLink,
181 : sal_uInt16 nObjType,
182 : sal_uInt16 nUpdateMode,
183 : const OUString* pName )
184 : {
185 : // This First
186 70 : pLink->SetObjType( nObjType );
187 70 : if( pName )
188 70 : pLink->SetName( *pName );
189 70 : pLink->SetUpdateMode( nUpdateMode );
190 70 : return Insert( pLink );
191 : }
192 :
193 :
194 6 : bool LinkManager::InsertDDELink( SvBaseLink * pLink,
195 : const OUString& rServer,
196 : const OUString& rTopic,
197 : const OUString& rItem )
198 : {
199 6 : if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
200 0 : return false;
201 :
202 6 : OUString sCmd;
203 6 : ::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem );
204 :
205 6 : pLink->SetObjType( OBJECT_CLIENT_DDE );
206 6 : pLink->SetName( sCmd );
207 6 : return Insert( pLink );
208 : }
209 :
210 :
211 12 : bool LinkManager::InsertDDELink( SvBaseLink * pLink )
212 : {
213 : DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" );
214 12 : if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
215 0 : return false;
216 :
217 12 : if( pLink->GetObjType() == OBJECT_CLIENT_SO )
218 0 : pLink->SetObjType( OBJECT_CLIENT_DDE );
219 :
220 12 : return Insert( pLink );
221 : }
222 :
223 :
224 : // Obtain the string for the dialog
225 398 : bool LinkManager::GetDisplayNames( const SvBaseLink * pLink,
226 : OUString* pType,
227 : OUString* pFile,
228 : OUString* pLinkStr,
229 : OUString* pFilter ) const
230 : {
231 398 : bool bRet = false;
232 398 : const OUString sLNm( pLink->GetLinkSourceName() );
233 398 : if( !sLNm.isEmpty() )
234 : {
235 398 : switch( pLink->GetObjType() )
236 : {
237 : case OBJECT_CLIENT_FILE:
238 : case OBJECT_CLIENT_GRF:
239 : case OBJECT_CLIENT_OLE:
240 : {
241 378 : sal_Int32 nPos = 0;
242 378 : OUString sFile( sLNm.getToken( 0, ::sfx2::cTokenSeparator, nPos ) );
243 756 : OUString sRange( sLNm.getToken( 0, ::sfx2::cTokenSeparator, nPos ) );
244 :
245 378 : if( pFile )
246 374 : *pFile = sFile;
247 378 : if( pLinkStr )
248 178 : *pLinkStr = sRange;
249 378 : if( pFilter )
250 286 : *pFilter = nPos == -1 ? OUString() : sLNm.copy(nPos);
251 :
252 378 : if( pType )
253 : {
254 10 : sal_uInt16 nObjType = pLink->GetObjType();
255 30 : *pType = SfxResId(
256 0 : ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
257 : ? RID_SVXSTR_FILELINK
258 10 : : RID_SVXSTR_GRAFIKLINK).toString();
259 : }
260 756 : bRet = true;
261 : }
262 378 : break;
263 : case OBJECT_CLIENT_DDE:
264 : {
265 20 : sal_Int32 nTmp = 0;
266 20 : OUString sCmd( sLNm );
267 40 : OUString sServer( sCmd.getToken( 0, cTokenSeparator, nTmp ) );
268 40 : OUString sTopic( sCmd.getToken( 0, cTokenSeparator, nTmp ) );
269 :
270 20 : if( pType )
271 10 : *pType = sServer;
272 20 : if( pFile )
273 10 : *pFile = sTopic;
274 20 : if( pLinkStr )
275 10 : *pLinkStr = sCmd.copy( nTmp );
276 40 : bRet = true;
277 : }
278 20 : break;
279 : default:
280 0 : break;
281 : }
282 : }
283 :
284 398 : return bRet;
285 : }
286 :
287 0 : void LinkManager::UpdateAllLinks(
288 : bool bAskUpdate,
289 : bool /*bCallErrHdl*/,
290 : bool bUpdateGrfLinks,
291 : vcl::Window* pParentWin )
292 : {
293 : // First make a copy of the array in order to update links
294 : // links in ... no contact between them!
295 0 : std::vector<SvBaseLink*> aTmpArr;
296 0 : for( size_t n = 0; n < aLinkTbl.size(); ++n )
297 : {
298 0 : SvBaseLink* pLink = *aLinkTbl[ n ];
299 0 : if( !pLink )
300 : {
301 0 : Remove( n-- );
302 0 : continue;
303 : }
304 0 : aTmpArr.push_back( pLink );
305 : }
306 :
307 0 : for( size_t n = 0; n < aTmpArr.size(); ++n )
308 : {
309 0 : SvBaseLink* pLink = aTmpArr[ n ];
310 :
311 : // search first in the array after the entry
312 0 : bool bFound = false;
313 0 : for( size_t i = 0; i < aLinkTbl.size(); ++i )
314 0 : if( pLink == *aLinkTbl[ i ] )
315 : {
316 0 : bFound = true;
317 0 : break;
318 : }
319 :
320 0 : if( !bFound )
321 0 : continue; // was not available!
322 :
323 : // Graphic-Links not to update yet
324 0 : if( !pLink->IsVisible() ||
325 0 : ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() ))
326 0 : continue;
327 :
328 0 : if( bAskUpdate )
329 : {
330 0 : int nRet = QueryBox( pParentWin, WB_YES_NO | WB_DEF_YES, SfxResId( STR_QUERY_UPDATE_LINKS ).toString() ).Execute();
331 0 : if( RET_YES != nRet )
332 : {
333 0 : SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
334 :
335 0 : if(pShell)
336 : {
337 0 : comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = pShell->getEmbeddedObjectContainer();
338 0 : rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false);
339 : }
340 :
341 0 : return ; // nothing should be updated
342 : }
343 0 : bAskUpdate = false; // once is enough
344 : }
345 :
346 0 : pLink->Update();
347 : }
348 0 : CloseCachedComps();
349 : }
350 :
351 :
352 :
353 98 : SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink )
354 : {
355 98 : switch( pLink->GetObjType() )
356 : {
357 : case OBJECT_CLIENT_FILE:
358 : case OBJECT_CLIENT_GRF:
359 : case OBJECT_CLIENT_OLE:
360 88 : return new SvFileObject;
361 : case OBJECT_INTERN:
362 10 : return new SvxInternalLink;
363 : case OBJECT_CLIENT_DDE:
364 0 : return new SvDDEObject;
365 : default:
366 0 : return SvLinkSourceRef();
367 : }
368 : }
369 :
370 12 : bool LinkManager::InsertServer( SvLinkSource* pObj )
371 : {
372 : // no duplicate inserts
373 12 : if( !pObj )
374 0 : return false;
375 :
376 12 : return aServerTbl.insert( pObj ).second;
377 : }
378 :
379 :
380 10 : void LinkManager::RemoveServer( SvLinkSource* pObj )
381 : {
382 10 : aServerTbl.erase( pObj );
383 10 : }
384 :
385 :
386 8 : void MakeLnkName( OUString& rName, const OUString* pType, const OUString& rFile,
387 : const OUString& rLink, const OUString* pFilter )
388 : {
389 8 : if( pType )
390 : {
391 6 : rName = comphelper::string::strip(*pType, ' ');
392 6 : rName += OUString(cTokenSeparator);
393 : }
394 2 : else if( !rName.isEmpty() )
395 2 : rName = "";
396 :
397 8 : rName += rFile;
398 :
399 8 : rName = comphelper::string::strip(rName, ' ');
400 8 : rName += OUString(cTokenSeparator);
401 8 : rName = comphelper::string::strip(rName, ' ');
402 8 : rName += rLink;
403 8 : if( pFilter )
404 : {
405 2 : rName += OUString(cTokenSeparator);
406 2 : rName += *pFilter;
407 2 : rName = comphelper::string::strip(rName, ' ');
408 : }
409 8 : }
410 :
411 520 : void LinkManager::ReconnectDdeLink(SfxObjectShell& rServer)
412 : {
413 520 : SfxMedium* pMed = rServer.GetMedium();
414 520 : if (!pMed)
415 520 : return;
416 :
417 520 : const ::sfx2::SvBaseLinks& rLinks = GetLinks();
418 520 : size_t n = rLinks.size();
419 :
420 530 : for (size_t i = 0; i < n; ++i)
421 : {
422 10 : ::sfx2::SvBaseLink* p = *rLinks[i];
423 10 : OUString aType, aFile, aLink, aFilter;
424 10 : if (!GetDisplayNames(p, &aType, &aFile, &aLink, &aFilter))
425 0 : continue;
426 :
427 10 : if (aType != "soffice")
428 : // DDE connections between OOo apps are always named 'soffice'.
429 10 : continue;
430 :
431 0 : OUString aTmp;
432 0 : OUString aURL = aFile;
433 0 : if (utl::LocalFileHelper::ConvertPhysicalNameToURL(aFile, aTmp))
434 0 : aURL = aTmp;
435 :
436 0 : if (!aURL.equalsIgnoreAsciiCase(pMed->GetName()))
437 : // This DDE link is not associated with this server shell... Skip it.
438 0 : continue;
439 :
440 0 : if (aLink.isEmpty())
441 0 : continue;
442 :
443 0 : LinkServerShell(aLink, rServer, *p);
444 0 : }
445 : }
446 :
447 0 : void LinkManager::LinkServerShell(const OUString& rPath, SfxObjectShell& rServer, ::sfx2::SvBaseLink& rLink) const
448 : {
449 0 : ::sfx2::SvLinkSource* pSrvSrc = rServer.DdeCreateLinkSource(rPath);
450 0 : if (pSrvSrc)
451 : {
452 0 : ::com::sun::star::datatransfer::DataFlavor aFl;
453 0 : SotExchange::GetFormatDataFlavor(rLink.GetContentType(), aFl);
454 0 : rLink.SetObj(pSrvSrc);
455 : pSrvSrc->AddDataAdvise(
456 : &rLink, aFl.MimeType,
457 0 : sfx2::LINKUPDATE_ONCALL == rLink.GetUpdateMode() ? ADVISEMODE_ONLYONCE : 0);
458 : }
459 0 : }
460 :
461 70 : bool LinkManager::InsertFileLink(
462 : sfx2::SvBaseLink& rLink, sal_uInt16 nFileType, const OUString& rFileNm,
463 : const OUString* pFilterNm, const OUString* pRange)
464 : {
465 70 : if (!(OBJECT_CLIENT_SO & rLink.GetObjType()))
466 0 : return false;
467 :
468 70 : OUStringBuffer aBuf;
469 70 : aBuf.append(rFileNm);
470 70 : aBuf.append(sfx2::cTokenSeparator);
471 :
472 70 : if (pRange)
473 38 : aBuf.append(*pRange);
474 :
475 70 : if (pFilterNm)
476 : {
477 48 : aBuf.append(sfx2::cTokenSeparator);
478 48 : aBuf.append(*pFilterNm);
479 : }
480 :
481 140 : OUString aCmd = aBuf.makeStringAndClear();
482 140 : return InsertLink(&rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &aCmd);
483 : }
484 :
485 : // A transfer is aborted, so cancel all download media
486 : // (for now this is only of interest for the file links!)
487 4595 : void LinkManager::CancelTransfers()
488 : {
489 : SvFileObject* pFileObj;
490 : sfx2::SvBaseLink* pLnk;
491 :
492 4595 : const sfx2::SvBaseLinks& rLnks = GetLinks();
493 9198 : for( size_t n = rLnks.size(); n; )
494 24 : if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
495 24 : OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
496 : 0 != ( pFileObj = static_cast<SvFileObject*>(pLnk->GetObj()) ) )
497 8 : pFileObj->CancelTransfers();
498 4595 : }
499 : // For the purpose of sending Status information from the file object to
500 : // the base link, there exist a dedicated ClipBoardId. The SvData-object
501 : // gets the appropriate information as a string
502 : // For now this is required for file object in conjunction with JavaScript
503 : // - needs information about Load/Abort/Error
504 74 : sal_uIntPtr LinkManager::RegisterStatusInfoId()
505 : {
506 : static sal_uIntPtr nFormat = 0;
507 :
508 74 : if( !nFormat )
509 : {
510 : nFormat = SotExchange::RegisterFormatName(
511 2 : OUString("StatusInfo from SvxInternalLink"));
512 : }
513 74 : return nFormat;
514 : }
515 :
516 :
517 :
518 28 : bool LinkManager::GetGraphicFromAny( const OUString& rMimeType,
519 : const ::com::sun::star::uno::Any & rValue,
520 : Graphic& rGrf )
521 : {
522 28 : bool bRet = false;
523 28 : ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
524 28 : if( rValue.hasValue() && ( rValue >>= aSeq ) )
525 : {
526 56 : SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(),
527 56 : STREAM_READ );
528 28 : aMemStm.Seek( 0 );
529 :
530 28 : switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
531 : {
532 : case SOT_FORMATSTR_ID_SVXB:
533 : {
534 28 : ReadGraphic( aMemStm, rGrf );
535 28 : bRet = true;
536 : }
537 28 : break;
538 : case FORMAT_GDIMETAFILE:
539 : {
540 0 : GDIMetaFile aMtf;
541 0 : aMtf.Read( aMemStm );
542 0 : rGrf = aMtf;
543 0 : bRet = true;
544 : }
545 0 : break;
546 : case FORMAT_BITMAP:
547 : {
548 0 : Bitmap aBmp;
549 0 : ReadDIB(aBmp, aMemStm, true);
550 0 : rGrf = aBmp;
551 0 : bRet = true;
552 : }
553 0 : break;
554 28 : }
555 : }
556 28 : return bRet;
557 : }
558 :
559 :
560 :
561 40 : OUString lcl_DDE_RelToAbs( const OUString& rTopic, const OUString& rBaseURL )
562 : {
563 40 : OUString sRet;
564 80 : INetURLObject aURL( rTopic );
565 40 : if( INET_PROT_NOT_VALID == aURL.GetProtocol() )
566 40 : utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
567 40 : if( sRet.isEmpty() )
568 40 : sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
569 80 : return sRet;
570 : }
571 :
572 10 : bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
573 : {
574 10 : SfxObjectShell* pFndShell = 0;
575 10 : sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
576 20 : OUString sTopic, sItem, sReferer;
577 10 : LinkManager* pLinkMgr = pLink->GetLinkManager();
578 10 : if (pLinkMgr && pLinkMgr->GetDisplayNames(pLink, 0, &sTopic, &sItem) && !sTopic.isEmpty())
579 : {
580 : // first only loop over the DocumentShells the shells and find those
581 : // with the name:
582 10 : CharClass aCC( LanguageTag( LANGUAGE_SYSTEM) );
583 :
584 10 : TypeId aType( TYPE(SfxObjectShell) );
585 :
586 10 : bool bFirst = true;
587 10 : SfxObjectShell* pShell = pLinkMgr->GetPersist();
588 10 : if( pShell && pShell->GetMedium() )
589 : {
590 10 : sReferer = pShell->GetMedium()->GetBaseURL();
591 10 : SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, false );
592 10 : if ( pItem )
593 10 : nUpdateMode = pItem->GetValue();
594 : }
595 :
596 20 : OUString sNmURL(aCC.lowercase(lcl_DDE_RelToAbs(sTopic, sReferer)));
597 :
598 10 : if ( !pShell )
599 : {
600 0 : bFirst = false;
601 0 : pShell = SfxObjectShell::GetFirst( &aType, false );
602 : }
603 :
604 20 : OUString sTmp;
605 40 : while( pShell )
606 : {
607 30 : if( sTmp.isEmpty() )
608 : {
609 30 : sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
610 30 : sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
611 : }
612 :
613 :
614 30 : sTmp = aCC.lowercase( sTmp );
615 30 : if( sTmp == sNmURL ) // we want these
616 : {
617 10 : pFndShell = pShell;
618 10 : break;
619 : }
620 :
621 20 : if( bFirst )
622 : {
623 10 : bFirst = false;
624 10 : pShell = SfxObjectShell::GetFirst( &aType, false );
625 : }
626 : else
627 10 : pShell = SfxObjectShell::GetNext( *pShell, &aType, false );
628 :
629 20 : sTmp = "";
630 10 : }
631 : }
632 :
633 : // empty topics are not allowed - which document is it
634 10 : if( sTopic.isEmpty() )
635 0 : return false;
636 :
637 10 : if (pFndShell)
638 : {
639 10 : sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
640 10 : if( pNewSrc )
641 : {
642 10 : ::com::sun::star::datatransfer::DataFlavor aFl;
643 10 : SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
644 :
645 10 : pLink->SetObj( pNewSrc );
646 : pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
647 10 : sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode()
648 : ? ADVISEMODE_ONLYONCE
649 10 : : 0 );
650 10 : return true;
651 : }
652 : }
653 : else
654 : {
655 : // then try to download the file:
656 0 : INetURLObject aURL( sTopic );
657 0 : INetProtocol eOld = aURL.GetProtocol();
658 0 : aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
659 0 : if( INET_PROT_NOT_VALID != eOld ||
660 0 : INET_PROT_HTTP != aURL.GetProtocol() )
661 : {
662 0 : SfxStringItem aName( SID_FILE_NAME, sTopic );
663 0 : SfxBoolItem aMinimized(SID_MINIMIZED, true);
664 0 : SfxBoolItem aHidden(SID_HIDDEN, true);
665 0 : SfxStringItem aTarget( SID_TARGETNAME, OUString("_blank") );
666 0 : SfxStringItem aReferer( SID_REFERER, sReferer );
667 0 : SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
668 0 : SfxBoolItem aReadOnly(SID_DOC_READONLY, false);
669 :
670 : // Disable automatic re-connection to avoid this link instance
671 : // being destroyed at re-connection.
672 0 : SfxBoolItem aDdeConnect(SID_DDE_RECONNECT_ONLOAD, false);
673 :
674 : // #i14200# (DDE-link crashes wordprocessor)
675 0 : SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
676 0 : aArgs.Put(aReferer);
677 0 : aArgs.Put(aTarget);
678 0 : aArgs.Put(aHidden);
679 0 : aArgs.Put(aMinimized);
680 0 : aArgs.Put(aName);
681 0 : aArgs.Put(aUpdate);
682 0 : aArgs.Put(aReadOnly);
683 0 : aArgs.Put(aDdeConnect);
684 0 : Reference<XComponent> xComp = SfxObjectShell::CreateAndLoadComponent(aArgs);
685 0 : pFndShell = SfxObjectShell::GetShellFromComponent(xComp);
686 0 : if (xComp.is() && pFndShell)
687 : {
688 0 : pLinkMgr->InsertCachedComp(xComp);
689 0 : pLinkMgr->LinkServerShell(sItem, *pFndShell, *pLink);
690 0 : return true;
691 0 : }
692 0 : }
693 : }
694 :
695 10 : return false;
696 : }
697 :
698 :
699 951 : }
700 :
701 :
702 :
703 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|