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