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