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 <svl/smplhint.hxx>
21 : #include <sfx2/linkmgr.hxx>
22 : #include <vcl/svapp.hxx>
23 :
24 : #include "linkuno.hxx"
25 : #include "miscuno.hxx"
26 : #include "convuno.hxx"
27 : #include "docsh.hxx"
28 : #include "docfunc.hxx"
29 : #include "tablink.hxx"
30 : #include "arealink.hxx"
31 : #include "hints.hxx"
32 : #include "unonames.hxx"
33 : #include "rangeseq.hxx"
34 : #include "token.hxx"
35 :
36 : #include <vector>
37 : #include <climits>
38 :
39 : using namespace com::sun::star;
40 : using namespace formula;
41 : using ::com::sun::star::uno::Any;
42 : using ::com::sun::star::uno::Reference;
43 : using ::com::sun::star::uno::Sequence;
44 : using ::com::sun::star::uno::UNO_QUERY;
45 : using ::com::sun::star::uno::UNO_QUERY_THROW;
46 : using ::com::sun::star::lang::IllegalArgumentException;
47 : using ::com::sun::star::uno::RuntimeException;
48 : using ::rtl::OUString;
49 : using ::std::vector;
50 :
51 : //------------------------------------------------------------------------
52 :
53 : // fuer Sheet- und Area-Links benutzt:
54 0 : static const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap()
55 : {
56 : static SfxItemPropertyMapEntry aSheetLinkMap_Impl[] =
57 : {
58 0 : {MAP_CHAR_LEN(SC_UNONAME_FILTER), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
59 0 : {MAP_CHAR_LEN(SC_UNONAME_FILTOPT), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
60 0 : {MAP_CHAR_LEN(SC_UNONAME_LINKURL), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
61 0 : {MAP_CHAR_LEN(SC_UNONAME_REFDELAY), 0, &getCppuType((sal_Int32*)0), 0, 0 },
62 0 : {MAP_CHAR_LEN(SC_UNONAME_REFPERIOD), 0, &getCppuType((sal_Int32*)0), 0, 0 },
63 : {0,0,0,0,0,0}
64 0 : };
65 0 : return aSheetLinkMap_Impl;
66 : }
67 :
68 : //------------------------------------------------------------------------
69 :
70 0 : SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj, "ScAreaLinkObj", "com.sun.star.sheet.CellAreaLink" )
71 0 : SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj, "ScAreaLinksObj", "com.sun.star.sheet.CellAreaLinks" )
72 0 : SC_SIMPLE_SERVICE_INFO( ScDDELinkObj, "ScDDELinkObj", "com.sun.star.sheet.DDELink" )
73 0 : SC_SIMPLE_SERVICE_INFO( ScDDELinksObj, "ScDDELinksObj", "com.sun.star.sheet.DDELinks" )
74 0 : SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj, "ScSheetLinkObj", "com.sun.star.sheet.SheetLink" )
75 0 : SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj, "ScSheetLinksObj", "com.sun.star.sheet.SheetLinks" )
76 :
77 : //------------------------------------------------------------------------
78 :
79 0 : ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const String& rName) :
80 : aPropSet( lcl_GetSheetLinkMap() ),
81 : pDocShell( pDocSh ),
82 0 : aFileName( rName )
83 : {
84 0 : pDocShell->GetDocument()->AddUnoObject(*this);
85 0 : }
86 :
87 0 : ScSheetLinkObj::~ScSheetLinkObj()
88 : {
89 0 : if (pDocShell)
90 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
91 0 : }
92 :
93 0 : void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
94 : {
95 : //! notify if links in document are changed
96 : // UpdateRef is not needed here
97 :
98 0 : if ( rHint.ISA( SfxSimpleHint ) )
99 : {
100 0 : if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
101 0 : pDocShell = NULL; // pointer is invalid
102 : }
103 0 : else if ( rHint.ISA( ScLinkRefreshedHint ) )
104 : {
105 0 : const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
106 0 : if ( rLH.GetLinkType() == SC_LINKREFTYPE_SHEET && rLH.GetUrl() == aFileName )
107 0 : Refreshed_Impl();
108 : }
109 0 : }
110 :
111 0 : ScTableLink* ScSheetLinkObj::GetLink_Impl() const
112 : {
113 0 : if (pDocShell)
114 : {
115 0 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
116 0 : sal_uInt16 nCount = pLinkManager->GetLinks().size();
117 0 : for (sal_uInt16 i=0; i<nCount; i++)
118 : {
119 0 : ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
120 0 : if (pBase->ISA(ScTableLink))
121 : {
122 0 : ScTableLink* pTabLink = (ScTableLink*)pBase;
123 0 : if ( pTabLink->GetFileName().equals(aFileName) )
124 0 : return pTabLink;
125 : }
126 : }
127 : }
128 0 : return NULL; // nicht gefunden
129 : }
130 :
131 : // XNamed
132 :
133 0 : rtl::OUString SAL_CALL ScSheetLinkObj::getName() throw(uno::RuntimeException)
134 : {
135 0 : SolarMutexGuard aGuard;
136 0 : return getFileName(); // Name ist der Dateiname (URL)
137 : }
138 :
139 0 : void SAL_CALL ScSheetLinkObj::setName( const rtl::OUString& aName ) throw(uno::RuntimeException)
140 : {
141 0 : SolarMutexGuard aGuard;
142 0 : setFileName(aName); // Name ist der Dateiname (URL)
143 0 : }
144 :
145 : // XRefreshable
146 :
147 0 : void SAL_CALL ScSheetLinkObj::refresh() throw(uno::RuntimeException)
148 : {
149 0 : SolarMutexGuard aGuard;
150 0 : ScTableLink* pLink = GetLink_Impl();
151 0 : if (pLink)
152 0 : pLink->Refresh( pLink->GetFileName(), pLink->GetFilterName(), NULL, pLink->GetRefreshDelay() );
153 0 : }
154 :
155 0 : void SAL_CALL ScSheetLinkObj::addRefreshListener(
156 : const uno::Reference<util::XRefreshListener >& xListener )
157 : throw(uno::RuntimeException)
158 : {
159 0 : SolarMutexGuard aGuard;
160 : uno::Reference<util::XRefreshListener>* pObj =
161 0 : new uno::Reference<util::XRefreshListener>( xListener );
162 0 : aRefreshListeners.push_back( pObj );
163 :
164 : // hold one additional ref to keep this object alive as long as there are listeners
165 0 : if ( aRefreshListeners.size() == 1 )
166 0 : acquire();
167 0 : }
168 :
169 0 : void SAL_CALL ScSheetLinkObj::removeRefreshListener(
170 : const uno::Reference<util::XRefreshListener >& xListener )
171 : throw(uno::RuntimeException)
172 : {
173 0 : SolarMutexGuard aGuard;
174 0 : sal_uInt16 nCount = aRefreshListeners.size();
175 0 : for ( sal_uInt16 n=nCount; n--; )
176 : {
177 0 : uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
178 0 : if ( rObj == xListener )
179 : {
180 0 : aRefreshListeners.erase( aRefreshListeners.begin() + n );
181 0 : if ( aRefreshListeners.empty() )
182 0 : release(); // release ref for listeners
183 0 : break;
184 : }
185 0 : }
186 0 : }
187 :
188 0 : void ScSheetLinkObj::Refreshed_Impl()
189 : {
190 0 : lang::EventObject aEvent;
191 0 : aEvent.Source.set((cppu::OWeakObject*)this);
192 0 : for ( sal_uInt16 n=0; n<aRefreshListeners.size(); n++ )
193 0 : aRefreshListeners[n]->refreshed( aEvent );
194 0 : }
195 :
196 0 : void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
197 : {
198 0 : ScTableLink* pLink = GetLink_Impl();
199 0 : if( pLink )
200 0 : pLink->SetRefreshDelay( (sal_uLong) nRefresh );
201 0 : }
202 :
203 : // XPropertySet
204 :
205 0 : uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSheetLinkObj::getPropertySetInfo()
206 : throw(uno::RuntimeException)
207 : {
208 0 : SolarMutexGuard aGuard;
209 : static uno::Reference<beans::XPropertySetInfo> aRef(
210 0 : new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
211 0 : return aRef;
212 : }
213 :
214 0 : void SAL_CALL ScSheetLinkObj::setPropertyValue(
215 : const rtl::OUString& aPropertyName, const uno::Any& aValue )
216 : throw(beans::UnknownPropertyException, beans::PropertyVetoException,
217 : lang::IllegalArgumentException, lang::WrappedTargetException,
218 : uno::RuntimeException)
219 : {
220 0 : SolarMutexGuard aGuard;
221 0 : String aNameString(aPropertyName);
222 0 : rtl::OUString aValStr;
223 0 : if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
224 : {
225 0 : if ( aValue >>= aValStr )
226 0 : setFileName( aValStr );
227 : }
228 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
229 : {
230 0 : if ( aValue >>= aValStr )
231 0 : setFilter( aValStr );
232 : }
233 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
234 : {
235 0 : if ( aValue >>= aValStr )
236 0 : setFilterOptions( aValStr );
237 : }
238 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
239 : {
240 0 : sal_Int32 nRefresh = 0;
241 0 : if ( aValue >>= nRefresh )
242 0 : setRefreshDelay( nRefresh );
243 : }
244 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
245 : {
246 0 : sal_Int32 nRefresh = 0;
247 0 : if ( aValue >>= nRefresh )
248 0 : setRefreshDelay( nRefresh );
249 0 : }
250 0 : }
251 :
252 0 : uno::Any SAL_CALL ScSheetLinkObj::getPropertyValue( const rtl::OUString& aPropertyName )
253 : throw(beans::UnknownPropertyException, lang::WrappedTargetException,
254 : uno::RuntimeException)
255 : {
256 0 : SolarMutexGuard aGuard;
257 0 : String aNameString(aPropertyName);
258 0 : uno::Any aRet;
259 0 : if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
260 0 : aRet <<= getFileName();
261 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
262 0 : aRet <<= getFilter();
263 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
264 0 : aRet <<= getFilterOptions();
265 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
266 0 : aRet <<= getRefreshDelay();
267 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
268 0 : aRet <<= getRefreshDelay();
269 0 : return aRet;
270 : }
271 :
272 0 : SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj )
273 :
274 : // internal:
275 :
276 0 : rtl::OUString ScSheetLinkObj::getFileName(void) const
277 : {
278 0 : SolarMutexGuard aGuard;
279 0 : return aFileName;
280 : }
281 :
282 0 : void ScSheetLinkObj::setFileName(const rtl::OUString& rNewName)
283 : {
284 0 : SolarMutexGuard aGuard;
285 0 : ScTableLink* pLink = GetLink_Impl();
286 0 : if (pLink)
287 : {
288 : // pLink->Refresh mit neuem Dateinamen bringt sfx2::LinkManager durcheinander
289 : // darum per Hand die Tabellen umsetzen und Link per UpdateLinks neu erzeugen
290 :
291 0 : String aNewStr(ScGlobal::GetAbsDocName( String(rNewName), pDocShell ));
292 :
293 : // zuerst Tabellen umsetzen
294 :
295 0 : ScDocument* pDoc = pDocShell->GetDocument();
296 0 : SCTAB nTabCount = pDoc->GetTableCount();
297 0 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
298 0 : if ( pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab) == rtl::OUString(aFileName) ) // alte Datei
299 0 : pDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), aNewStr,
300 : pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
301 : pDoc->GetLinkTab(nTab),
302 0 : pDoc->GetLinkRefreshDelay(nTab) ); // nur Datei aendern
303 :
304 : // Links updaten
305 : //! Undo !!!
306 :
307 0 : pLink = NULL; // wird bei UpdateLinks ungueltig
308 0 : pDocShell->UpdateLinks(); // alter Link raus, evtl. neuen Link anlegen
309 :
310 : // Daten kopieren
311 :
312 0 : aFileName = aNewStr;
313 0 : pLink = GetLink_Impl(); // neuer Link mit neuem Namen
314 0 : if (pLink)
315 0 : pLink->Update(); // inkl. Paint & Undo fuer Daten
316 0 : }
317 0 : }
318 :
319 0 : rtl::OUString ScSheetLinkObj::getFilter(void) const
320 : {
321 0 : SolarMutexGuard aGuard;
322 0 : rtl::OUString aRet;
323 0 : ScTableLink* pLink = GetLink_Impl();
324 0 : if (pLink)
325 0 : aRet = pLink->GetFilterName();
326 0 : return aRet;
327 : }
328 :
329 0 : void ScSheetLinkObj::setFilter(const rtl::OUString& Filter)
330 : {
331 0 : SolarMutexGuard aGuard;
332 0 : ScTableLink* pLink = GetLink_Impl();
333 0 : if (pLink)
334 : {
335 0 : String aFilterStr(Filter);
336 0 : pLink->Refresh( aFileName, aFilterStr, NULL, pLink->GetRefreshDelay() );
337 0 : }
338 0 : }
339 :
340 0 : rtl::OUString ScSheetLinkObj::getFilterOptions(void) const
341 : {
342 0 : SolarMutexGuard aGuard;
343 0 : rtl::OUString aRet;
344 0 : ScTableLink* pLink = GetLink_Impl();
345 0 : if (pLink)
346 0 : aRet = pLink->GetOptions();
347 0 : return aRet;
348 : }
349 :
350 0 : void ScSheetLinkObj::setFilterOptions(const rtl::OUString& FilterOptions)
351 : {
352 0 : SolarMutexGuard aGuard;
353 0 : ScTableLink* pLink = GetLink_Impl();
354 0 : if (pLink)
355 : {
356 0 : String aOptStr(FilterOptions);
357 0 : pLink->Refresh( aFileName, pLink->GetFilterName(), &aOptStr, pLink->GetRefreshDelay() );
358 0 : }
359 0 : }
360 :
361 0 : sal_Int32 ScSheetLinkObj::getRefreshDelay(void) const
362 : {
363 0 : SolarMutexGuard aGuard;
364 0 : sal_Int32 nRet = 0;
365 0 : ScTableLink* pLink = GetLink_Impl();
366 0 : if (pLink)
367 0 : nRet = (sal_Int32) pLink->GetRefreshDelay();
368 0 : return nRet;
369 : }
370 :
371 0 : void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
372 : {
373 0 : SolarMutexGuard aGuard;
374 0 : ModifyRefreshDelay_Impl( nRefreshDelay );
375 0 : }
376 :
377 : //------------------------------------------------------------------------
378 :
379 0 : ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) :
380 0 : pDocShell( pDocSh )
381 : {
382 0 : pDocShell->GetDocument()->AddUnoObject(*this);
383 0 : }
384 :
385 0 : ScSheetLinksObj::~ScSheetLinksObj()
386 : {
387 0 : if (pDocShell)
388 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
389 0 : }
390 :
391 0 : void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
392 : {
393 : // Referenz-Update interessiert hier nicht
394 :
395 0 : if ( rHint.ISA( SfxSimpleHint ) &&
396 0 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
397 : {
398 0 : pDocShell = NULL; // ungueltig geworden
399 : }
400 0 : }
401 :
402 : // XSheetLinks
403 :
404 0 : ScSheetLinkObj* ScSheetLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
405 : {
406 0 : if (!pDocShell)
407 0 : return NULL;
408 :
409 : typedef boost::unordered_set<rtl::OUString, rtl::OUStringHash> StrSetType;
410 0 : StrSetType aNames;
411 0 : ScDocument* pDoc = pDocShell->GetDocument();
412 0 : SCTAB nTabCount = pDoc->GetTableCount();
413 0 : sal_Int32 nCount = 0;
414 0 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
415 : {
416 0 : if (!pDoc->IsLinked(nTab))
417 0 : continue;
418 :
419 0 : rtl::OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
420 0 : if (aNames.insert(aLinkDoc).second)
421 : {
422 : // unique document name.
423 0 : if (nCount == nIndex)
424 0 : return new ScSheetLinkObj( pDocShell, aLinkDoc );
425 0 : ++nCount;
426 : }
427 0 : }
428 :
429 0 : return NULL; // kein Dokument oder Index zu gross
430 : }
431 :
432 0 : ScSheetLinkObj* ScSheetLinksObj::GetObjectByName_Impl(const rtl::OUString& aName)
433 : {
434 : // Name ist der Dateiname
435 :
436 0 : if (pDocShell)
437 : {
438 0 : String aNameStr(aName);
439 :
440 0 : ScDocument* pDoc = pDocShell->GetDocument();
441 0 : SCTAB nTabCount = pDoc->GetTableCount();
442 0 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
443 0 : if (pDoc->IsLinked(nTab))
444 : {
445 : //! case-insensitiv ???
446 0 : String aLinkDoc = pDoc->GetLinkDoc( nTab );
447 0 : if ( aLinkDoc == aNameStr )
448 0 : return new ScSheetLinkObj( pDocShell, aNameStr );
449 0 : }
450 : }
451 :
452 0 : return NULL;
453 : }
454 :
455 : // XEnumerationAccess
456 :
457 0 : uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration()
458 : throw(uno::RuntimeException)
459 : {
460 0 : SolarMutexGuard aGuard;
461 0 : return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetLinksEnumeration")));
462 : }
463 :
464 : // XIndexAccess
465 :
466 0 : sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException)
467 : {
468 : typedef boost::unordered_set<rtl::OUString, rtl::OUStringHash> StrSetType;
469 :
470 0 : SolarMutexGuard aGuard;
471 0 : if (!pDocShell)
472 0 : return 0;
473 :
474 0 : sal_Int32 nCount = 0;
475 :
476 0 : StrSetType aNames;
477 0 : ScDocument* pDoc = pDocShell->GetDocument();
478 0 : SCTAB nTabCount = pDoc->GetTableCount();
479 0 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
480 : {
481 0 : if (!pDoc->IsLinked(nTab))
482 0 : continue;
483 :
484 0 : rtl::OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
485 0 : if (aNames.insert(aLinkDoc).second)
486 0 : ++nCount;
487 0 : }
488 0 : return nCount;
489 : }
490 :
491 0 : uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex )
492 : throw(lang::IndexOutOfBoundsException,
493 : lang::WrappedTargetException, uno::RuntimeException)
494 : {
495 0 : SolarMutexGuard aGuard;
496 0 : uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex));
497 0 : if (xLink.is())
498 0 : return uno::makeAny(xLink);
499 : else
500 0 : throw lang::IndexOutOfBoundsException();
501 : }
502 :
503 0 : uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException)
504 : {
505 0 : SolarMutexGuard aGuard;
506 0 : return getCppuType((uno::Reference<beans::XPropertySet>*)0);
507 : }
508 :
509 0 : sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException)
510 : {
511 0 : SolarMutexGuard aGuard;
512 0 : return ( getCount() != 0 );
513 : }
514 :
515 0 : uno::Any SAL_CALL ScSheetLinksObj::getByName( const rtl::OUString& aName )
516 : throw(container::NoSuchElementException,
517 : lang::WrappedTargetException, uno::RuntimeException)
518 : {
519 0 : SolarMutexGuard aGuard;
520 0 : uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName));
521 0 : if (xLink.is())
522 0 : return uno::makeAny(xLink);
523 : else
524 0 : throw container::NoSuchElementException();
525 : // return uno::Any();
526 : }
527 :
528 0 : sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const rtl::OUString& aName )
529 : throw(uno::RuntimeException)
530 : {
531 0 : SolarMutexGuard aGuard;
532 : // Name ist der Dateiname
533 :
534 0 : if (pDocShell)
535 : {
536 0 : String aNameStr(aName);
537 :
538 0 : ScDocument* pDoc = pDocShell->GetDocument();
539 0 : SCTAB nTabCount = pDoc->GetTableCount();
540 0 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
541 0 : if (pDoc->IsLinked(nTab))
542 : {
543 : //! case-insensitiv ???
544 0 : String aLinkDoc(pDoc->GetLinkDoc( nTab ));
545 0 : if ( aLinkDoc == aNameStr )
546 0 : return sal_True;
547 0 : }
548 : }
549 0 : return false;
550 : }
551 :
552 0 : uno::Sequence<rtl::OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException)
553 : {
554 : typedef boost::unordered_set<rtl::OUString, rtl::OUStringHash> StrSetType;
555 :
556 0 : SolarMutexGuard aGuard;
557 : // Name ist der Dateiname
558 :
559 0 : if (!pDocShell)
560 0 : return uno::Sequence<rtl::OUString>();
561 :
562 0 : StrSetType aNames;
563 0 : ScDocument* pDoc = pDocShell->GetDocument();
564 0 : SCTAB nTabCount = pDoc->GetTableCount();
565 :
566 0 : sal_Int32 nLinkCount = getCount();
567 0 : uno::Sequence<rtl::OUString> aSeq(nLinkCount);
568 0 : rtl::OUString* pAry = aSeq.getArray();
569 0 : sal_uInt16 nPos = 0;
570 0 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
571 : {
572 0 : if (!pDoc->IsLinked(nTab))
573 0 : continue;
574 :
575 0 : rtl::OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
576 0 : if (aNames.insert(aLinkDoc).second)
577 0 : pAry[nPos++] = aLinkDoc;
578 0 : }
579 : OSL_ENSURE( nPos==nLinkCount, "verzaehlt" );
580 0 : return aSeq;
581 : }
582 :
583 : //------------------------------------------------------------------------
584 :
585 0 : static ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, sal_uInt16 nPos )
586 : {
587 0 : if (pDocShell)
588 : {
589 0 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
590 0 : sal_uInt16 nTotalCount = pLinkManager->GetLinks().size();
591 0 : sal_uInt16 nAreaCount = 0;
592 0 : for (sal_uInt16 i=0; i<nTotalCount; i++)
593 : {
594 0 : ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
595 0 : if (pBase->ISA(ScAreaLink))
596 : {
597 0 : if ( nAreaCount == nPos )
598 0 : return (ScAreaLink*)pBase;
599 0 : ++nAreaCount;
600 : }
601 : }
602 : }
603 0 : return NULL; // nicht gefunden
604 : }
605 :
606 0 : ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, sal_uInt16 nP) :
607 : aPropSet( lcl_GetSheetLinkMap() ),
608 : pDocShell( pDocSh ),
609 0 : nPos( nP )
610 : {
611 0 : pDocShell->GetDocument()->AddUnoObject(*this);
612 0 : }
613 :
614 0 : ScAreaLinkObj::~ScAreaLinkObj()
615 : {
616 0 : if (pDocShell)
617 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
618 0 : }
619 :
620 0 : void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
621 : {
622 : //! notify if links in document are changed
623 : // UpdateRef is not needed here
624 :
625 0 : if ( rHint.ISA( SfxSimpleHint ) )
626 : {
627 0 : if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
628 0 : pDocShell = NULL; // pointer is invalid
629 : }
630 0 : else if ( rHint.ISA( ScLinkRefreshedHint ) )
631 : {
632 0 : const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
633 0 : if ( rLH.GetLinkType() == SC_LINKREFTYPE_AREA )
634 : {
635 : // get this link to compare dest position
636 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
637 0 : if ( pLink && pLink->GetDestArea().aStart == rLH.GetDestPos() )
638 0 : Refreshed_Impl();
639 : }
640 : }
641 0 : }
642 :
643 : // XFileLink
644 :
645 0 : void ScAreaLinkObj::Modify_Impl( const rtl::OUString* pNewFile, const rtl::OUString* pNewFilter,
646 : const rtl::OUString* pNewOptions, const rtl::OUString* pNewSource,
647 : const table::CellRangeAddress* pNewDest )
648 : {
649 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
650 0 : if (pLink)
651 : {
652 0 : String aFile (pLink->GetFile());
653 0 : String aFilter (pLink->GetFilter());
654 0 : String aOptions (pLink->GetOptions());
655 0 : String aSource (pLink->GetSource());
656 0 : ScRange aDest (pLink->GetDestArea());
657 0 : sal_uLong nRefresh = pLink->GetRefreshDelay();
658 :
659 : //! Undo fuer Loeschen
660 : //! Undo zusammenfassen
661 :
662 0 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
663 0 : pLinkManager->Remove( pLink );
664 0 : pLink = NULL; // bei Remove geloescht
665 :
666 0 : sal_Bool bFitBlock = sal_True; // verschieben, wenn durch Update Groesse geaendert
667 0 : if (pNewFile)
668 : {
669 0 : aFile = String( *pNewFile );
670 0 : aFile = ScGlobal::GetAbsDocName( aFile, pDocShell ); //! in InsertAreaLink?
671 : }
672 0 : if (pNewFilter)
673 0 : aFilter = String( *pNewFilter );
674 0 : if (pNewOptions)
675 0 : aOptions = String( *pNewOptions );
676 0 : if (pNewSource)
677 0 : aSource = String( *pNewSource );
678 0 : if (pNewDest)
679 : {
680 0 : ScUnoConversion::FillScRange( aDest, *pNewDest );
681 0 : bFitBlock = false; // neuer Bereich angegeben -> keine Inhalte verschieben
682 : }
683 0 : pDocShell->GetDocFunc().InsertAreaLink( aFile, aFilter, aOptions, aSource,
684 0 : aDest, nRefresh, bFitBlock, sal_True );
685 : }
686 0 : }
687 :
688 0 : void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
689 : {
690 0 : ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos );
691 0 : if( pLink )
692 0 : pLink->SetRefreshDelay( (sal_uLong) nRefresh );
693 0 : }
694 :
695 : // XRefreshable
696 :
697 0 : void SAL_CALL ScAreaLinkObj::refresh() throw(uno::RuntimeException)
698 : {
699 0 : SolarMutexGuard aGuard;
700 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
701 0 : if (pLink)
702 0 : pLink->Refresh( pLink->GetFile(), pLink->GetFilter(), pLink->GetSource(), pLink->GetRefreshDelay() );
703 0 : }
704 :
705 0 : void SAL_CALL ScAreaLinkObj::addRefreshListener(
706 : const uno::Reference<util::XRefreshListener >& xListener )
707 : throw(uno::RuntimeException)
708 : {
709 0 : SolarMutexGuard aGuard;
710 : uno::Reference<util::XRefreshListener>* pObj =
711 0 : new uno::Reference<util::XRefreshListener>( xListener );
712 0 : aRefreshListeners.push_back( pObj );
713 :
714 : // hold one additional ref to keep this object alive as long as there are listeners
715 0 : if ( aRefreshListeners.size() == 1 )
716 0 : acquire();
717 0 : }
718 :
719 0 : void SAL_CALL ScAreaLinkObj::removeRefreshListener(
720 : const uno::Reference<util::XRefreshListener >& xListener )
721 : throw(uno::RuntimeException)
722 : {
723 0 : SolarMutexGuard aGuard;
724 0 : sal_uInt16 nCount = aRefreshListeners.size();
725 0 : for ( sal_uInt16 n=nCount; n--; )
726 : {
727 0 : uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
728 0 : if ( rObj == xListener )
729 : {
730 0 : aRefreshListeners.erase( aRefreshListeners.begin() + n );
731 0 : if ( aRefreshListeners.empty() )
732 0 : release(); // release ref for listeners
733 0 : break;
734 : }
735 0 : }
736 0 : }
737 :
738 0 : void ScAreaLinkObj::Refreshed_Impl()
739 : {
740 0 : lang::EventObject aEvent;
741 0 : aEvent.Source.set((cppu::OWeakObject*)this);
742 0 : for ( sal_uInt16 n=0; n<aRefreshListeners.size(); n++ )
743 0 : aRefreshListeners[n]->refreshed( aEvent );
744 0 : }
745 :
746 : // XPropertySet
747 :
748 0 : uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAreaLinkObj::getPropertySetInfo()
749 : throw(uno::RuntimeException)
750 : {
751 0 : SolarMutexGuard aGuard;
752 : static uno::Reference<beans::XPropertySetInfo> aRef(
753 0 : new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
754 0 : return aRef;
755 : }
756 :
757 0 : void SAL_CALL ScAreaLinkObj::setPropertyValue(
758 : const rtl::OUString& aPropertyName, const uno::Any& aValue )
759 : throw(beans::UnknownPropertyException, beans::PropertyVetoException,
760 : lang::IllegalArgumentException, lang::WrappedTargetException,
761 : uno::RuntimeException)
762 : {
763 0 : SolarMutexGuard aGuard;
764 0 : String aNameString(aPropertyName);
765 0 : rtl::OUString aValStr;
766 0 : if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
767 : {
768 0 : if ( aValue >>= aValStr )
769 0 : setFileName( aValStr );
770 : }
771 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
772 : {
773 0 : if ( aValue >>= aValStr )
774 0 : setFilter( aValStr );
775 : }
776 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
777 : {
778 0 : if ( aValue >>= aValStr )
779 0 : setFilterOptions( aValStr );
780 : }
781 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
782 : {
783 0 : sal_Int32 nRefresh = 0;
784 0 : if ( aValue >>= nRefresh )
785 0 : setRefreshDelay( nRefresh );
786 : }
787 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
788 : {
789 0 : sal_Int32 nRefresh = 0;
790 0 : if ( aValue >>= nRefresh )
791 0 : setRefreshDelay( nRefresh );
792 0 : }
793 0 : }
794 :
795 0 : uno::Any SAL_CALL ScAreaLinkObj::getPropertyValue( const rtl::OUString& aPropertyName )
796 : throw(beans::UnknownPropertyException, lang::WrappedTargetException,
797 : uno::RuntimeException)
798 : {
799 0 : SolarMutexGuard aGuard;
800 0 : String aNameString(aPropertyName);
801 0 : uno::Any aRet;
802 0 : if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
803 0 : aRet <<= getFileName();
804 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
805 0 : aRet <<= getFilter();
806 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
807 0 : aRet <<= getFilterOptions();
808 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
809 0 : aRet <<= getRefreshDelay();
810 0 : else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
811 0 : aRet <<= getRefreshDelay();
812 0 : return aRet;
813 : }
814 :
815 0 : SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj )
816 :
817 : // internal:
818 :
819 0 : rtl::OUString ScAreaLinkObj::getFileName(void) const
820 : {
821 0 : SolarMutexGuard aGuard;
822 0 : rtl::OUString aRet;
823 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
824 0 : if (pLink)
825 0 : aRet = pLink->GetFile();
826 0 : return aRet;
827 : }
828 :
829 0 : void ScAreaLinkObj::setFileName(const rtl::OUString& rNewName)
830 : {
831 0 : SolarMutexGuard aGuard;
832 0 : Modify_Impl( &rNewName, NULL, NULL, NULL, NULL );
833 0 : }
834 :
835 0 : rtl::OUString ScAreaLinkObj::getFilter(void) const
836 : {
837 0 : SolarMutexGuard aGuard;
838 0 : rtl::OUString aRet;
839 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
840 0 : if (pLink)
841 0 : aRet = pLink->GetFilter();
842 0 : return aRet;
843 : }
844 :
845 0 : void ScAreaLinkObj::setFilter(const rtl::OUString& Filter)
846 : {
847 0 : SolarMutexGuard aGuard;
848 0 : Modify_Impl( NULL, &Filter, NULL, NULL, NULL );
849 0 : }
850 :
851 0 : rtl::OUString ScAreaLinkObj::getFilterOptions(void) const
852 : {
853 0 : SolarMutexGuard aGuard;
854 0 : rtl::OUString aRet;
855 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
856 0 : if (pLink)
857 0 : aRet = pLink->GetOptions();
858 0 : return aRet;
859 : }
860 :
861 0 : void ScAreaLinkObj::setFilterOptions(const rtl::OUString& FilterOptions)
862 : {
863 0 : SolarMutexGuard aGuard;
864 0 : Modify_Impl( NULL, NULL, &FilterOptions, NULL, NULL );
865 0 : }
866 :
867 0 : sal_Int32 ScAreaLinkObj::getRefreshDelay(void) const
868 : {
869 0 : SolarMutexGuard aGuard;
870 0 : sal_Int32 nRet = 0;
871 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
872 0 : if (pLink)
873 0 : nRet = (sal_Int32) pLink->GetRefreshDelay();
874 0 : return nRet;
875 : }
876 :
877 0 : void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
878 : {
879 0 : SolarMutexGuard aGuard;
880 0 : ModifyRefreshDelay_Impl( nRefreshDelay );
881 0 : }
882 :
883 : // XAreaLink
884 :
885 0 : rtl::OUString SAL_CALL ScAreaLinkObj::getSourceArea() throw(uno::RuntimeException)
886 : {
887 0 : SolarMutexGuard aGuard;
888 0 : rtl::OUString aRet;
889 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
890 0 : if (pLink)
891 0 : aRet = pLink->GetSource();
892 0 : return aRet;
893 : }
894 :
895 0 : void SAL_CALL ScAreaLinkObj::setSourceArea( const rtl::OUString& aSourceArea )
896 : throw(uno::RuntimeException)
897 : {
898 0 : SolarMutexGuard aGuard;
899 0 : Modify_Impl( NULL, NULL, NULL, &aSourceArea, NULL );
900 0 : }
901 :
902 0 : table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() throw(uno::RuntimeException)
903 : {
904 0 : SolarMutexGuard aGuard;
905 0 : table::CellRangeAddress aRet;
906 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
907 0 : if (pLink)
908 0 : ScUnoConversion::FillApiRange( aRet, pLink->GetDestArea() );
909 0 : return aRet;
910 : }
911 :
912 0 : void SAL_CALL ScAreaLinkObj::setDestArea( const table::CellRangeAddress& aDestArea )
913 : throw(uno::RuntimeException)
914 : {
915 0 : SolarMutexGuard aGuard;
916 0 : Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea );
917 0 : }
918 :
919 : //------------------------------------------------------------------------
920 :
921 3 : ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) :
922 3 : pDocShell( pDocSh )
923 : {
924 3 : pDocShell->GetDocument()->AddUnoObject(*this);
925 3 : }
926 :
927 9 : ScAreaLinksObj::~ScAreaLinksObj()
928 : {
929 3 : if (pDocShell)
930 3 : pDocShell->GetDocument()->RemoveUnoObject(*this);
931 6 : }
932 :
933 0 : void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
934 : {
935 : // Referenz-Update interessiert hier nicht
936 :
937 0 : if ( rHint.ISA( SfxSimpleHint ) &&
938 0 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
939 : {
940 0 : pDocShell = NULL; // ungueltig geworden
941 : }
942 0 : }
943 :
944 : // XAreaLinks
945 :
946 0 : ScAreaLinkObj* ScAreaLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
947 : {
948 0 : if ( pDocShell && nIndex >= 0 && nIndex < getCount() )
949 0 : return new ScAreaLinkObj( pDocShell, (sal_uInt16)nIndex );
950 :
951 0 : return NULL; // nicht gefunden
952 : }
953 :
954 0 : void SAL_CALL ScAreaLinksObj::insertAtPosition( const table::CellAddress& aDestPos,
955 : const rtl::OUString& aFileName,
956 : const rtl::OUString& aSourceArea,
957 : const rtl::OUString& aFilter,
958 : const rtl::OUString& aFilterOptions )
959 : throw(uno::RuntimeException)
960 : {
961 0 : SolarMutexGuard aGuard;
962 0 : if (pDocShell)
963 : {
964 0 : String aFileStr (aFileName);
965 0 : String aFilterStr (aFilter);
966 0 : String aOptionStr (aFilterOptions);
967 0 : String aSourceStr (aSourceArea);
968 0 : ScAddress aDestAddr( (SCCOL)aDestPos.Column, (SCROW)aDestPos.Row, aDestPos.Sheet );
969 :
970 0 : aFileStr = ScGlobal::GetAbsDocName( aFileStr, pDocShell ); //! in InsertAreaLink ???
971 0 : pDocShell->GetDocFunc().InsertAreaLink( aFileStr, aFilterStr, aOptionStr,
972 : aSourceStr, ScRange(aDestAddr),
973 0 : 0, false, sal_True ); // don't move contents
974 0 : }
975 0 : }
976 :
977 0 : void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
978 : {
979 0 : SolarMutexGuard aGuard;
980 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, (sal_uInt16)nIndex);
981 0 : if (pLink)
982 : {
983 : //! SetAddUndo oder so
984 :
985 0 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
986 0 : pLinkManager->Remove( pLink );
987 0 : }
988 0 : }
989 :
990 : // XEnumerationAccess
991 :
992 0 : uno::Reference<container::XEnumeration> SAL_CALL ScAreaLinksObj::createEnumeration()
993 : throw(uno::RuntimeException)
994 : {
995 0 : SolarMutexGuard aGuard;
996 0 : return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.CellAreaLinksEnumeration")));
997 : }
998 :
999 : // XIndexAccess
1000 :
1001 3 : sal_Int32 SAL_CALL ScAreaLinksObj::getCount() throw(uno::RuntimeException)
1002 : {
1003 3 : SolarMutexGuard aGuard;
1004 3 : sal_Int32 nAreaCount = 0;
1005 3 : if (pDocShell)
1006 : {
1007 3 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
1008 3 : sal_uInt16 nTotalCount = pLinkManager->GetLinks().size();
1009 3 : for (sal_uInt16 i=0; i<nTotalCount; i++)
1010 : {
1011 0 : ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
1012 0 : if (pBase->ISA(ScAreaLink))
1013 0 : ++nAreaCount;
1014 : }
1015 : }
1016 3 : return nAreaCount;
1017 : }
1018 :
1019 0 : uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex )
1020 : throw(lang::IndexOutOfBoundsException,
1021 : lang::WrappedTargetException, uno::RuntimeException)
1022 : {
1023 0 : SolarMutexGuard aGuard;
1024 0 : uno::Reference<sheet::XAreaLink> xLink(GetObjectByIndex_Impl(nIndex));
1025 0 : if (xLink.is())
1026 0 : return uno::makeAny(xLink);
1027 : else
1028 0 : throw lang::IndexOutOfBoundsException();
1029 : }
1030 :
1031 0 : uno::Type SAL_CALL ScAreaLinksObj::getElementType() throw(uno::RuntimeException)
1032 : {
1033 0 : SolarMutexGuard aGuard;
1034 0 : return getCppuType((uno::Reference<sheet::XAreaLink>*)0);
1035 : }
1036 :
1037 0 : sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException)
1038 : {
1039 0 : SolarMutexGuard aGuard;
1040 0 : return ( getCount() != 0 );
1041 : }
1042 :
1043 : //------------------------------------------------------------------------
1044 :
1045 0 : ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const String& rA,
1046 : const String& rT, const String& rI) :
1047 : pDocShell( pDocSh ),
1048 : aAppl( rA ),
1049 : aTopic( rT ),
1050 0 : aItem( rI )
1051 : {
1052 0 : pDocShell->GetDocument()->AddUnoObject(*this);
1053 0 : }
1054 :
1055 0 : ScDDELinkObj::~ScDDELinkObj()
1056 : {
1057 0 : if (pDocShell)
1058 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
1059 0 : }
1060 :
1061 0 : void ScDDELinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1062 : {
1063 : //! notify if links in document are changed
1064 : // UpdateRef is not needed here
1065 :
1066 0 : if ( rHint.ISA( SfxSimpleHint ) )
1067 : {
1068 0 : if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1069 0 : pDocShell = NULL; // pointer is invalid
1070 : }
1071 0 : else if ( rHint.ISA( ScLinkRefreshedHint ) )
1072 : {
1073 0 : const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
1074 0 : if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE &&
1075 0 : rLH.GetDdeAppl() == aAppl &&
1076 0 : rLH.GetDdeTopic() == aTopic &&
1077 0 : rLH.GetDdeItem() == aItem ) //! mode is ignored
1078 0 : Refreshed_Impl();
1079 : }
1080 0 : }
1081 :
1082 : // XNamed
1083 :
1084 0 : static String lcl_BuildDDEName( const String& rAppl, const String& rTopic, const String& rItem )
1085 : {
1086 : // Appl|Topic!Item (wie Excel)
1087 0 : String aRet = rAppl;
1088 0 : aRet += '|';
1089 0 : aRet += rTopic;
1090 0 : aRet += '!';
1091 0 : aRet += rItem;
1092 0 : return aRet;
1093 : }
1094 :
1095 0 : rtl::OUString SAL_CALL ScDDELinkObj::getName() throw(uno::RuntimeException)
1096 : {
1097 0 : SolarMutexGuard aGuard;
1098 0 : return lcl_BuildDDEName( aAppl, aTopic, aItem );
1099 : }
1100 :
1101 0 : void SAL_CALL ScDDELinkObj::setName( const rtl::OUString& /* aName */ ) throw(uno::RuntimeException)
1102 : {
1103 : // name can't be changed (formulas wouldn't find the link)
1104 0 : throw uno::RuntimeException();
1105 : }
1106 :
1107 : // XDDELink
1108 :
1109 0 : rtl::OUString SAL_CALL ScDDELinkObj::getApplication() throw(uno::RuntimeException)
1110 : {
1111 0 : SolarMutexGuard aGuard;
1112 : //! Test, ob Link noch im Dokument enthalten?
1113 :
1114 0 : return aAppl;
1115 : }
1116 :
1117 0 : rtl::OUString SAL_CALL ScDDELinkObj::getTopic() throw(uno::RuntimeException)
1118 : {
1119 0 : SolarMutexGuard aGuard;
1120 : //! Test, ob Link noch im Dokument enthalten?
1121 :
1122 0 : return aTopic;
1123 : }
1124 :
1125 0 : rtl::OUString SAL_CALL ScDDELinkObj::getItem() throw(uno::RuntimeException)
1126 : {
1127 0 : SolarMutexGuard aGuard;
1128 : //! Test, ob Link noch im Dokument enthalten?
1129 :
1130 0 : return aItem;
1131 : }
1132 :
1133 : // XRefreshable
1134 :
1135 0 : void SAL_CALL ScDDELinkObj::refresh() throw(uno::RuntimeException)
1136 : {
1137 0 : SolarMutexGuard aGuard;
1138 0 : if (pDocShell)
1139 : {
1140 0 : ScDocument* pDoc = pDocShell->GetDocument();
1141 0 : (void)pDoc->UpdateDdeLink( aAppl, aTopic, aItem );
1142 : //! Fehler abfragen
1143 0 : }
1144 0 : }
1145 :
1146 0 : void SAL_CALL ScDDELinkObj::addRefreshListener(
1147 : const uno::Reference<util::XRefreshListener >& xListener )
1148 : throw(uno::RuntimeException)
1149 : {
1150 0 : SolarMutexGuard aGuard;
1151 : uno::Reference<util::XRefreshListener>* pObj =
1152 0 : new uno::Reference<util::XRefreshListener>( xListener );
1153 0 : aRefreshListeners.push_back( pObj );
1154 :
1155 : // hold one additional ref to keep this object alive as long as there are listeners
1156 0 : if ( aRefreshListeners.size() == 1 )
1157 0 : acquire();
1158 0 : }
1159 :
1160 0 : void SAL_CALL ScDDELinkObj::removeRefreshListener(
1161 : const uno::Reference<util::XRefreshListener >& xListener )
1162 : throw(uno::RuntimeException)
1163 : {
1164 0 : SolarMutexGuard aGuard;
1165 0 : sal_uInt16 nCount = aRefreshListeners.size();
1166 0 : for ( sal_uInt16 n=nCount; n--; )
1167 : {
1168 0 : uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
1169 0 : if ( rObj == xListener )
1170 : {
1171 0 : aRefreshListeners.erase( aRefreshListeners.begin() + n );
1172 0 : if ( aRefreshListeners.empty() )
1173 0 : release(); // release ref for listeners
1174 0 : break;
1175 : }
1176 0 : }
1177 0 : }
1178 :
1179 : // XDDELinkResults
1180 :
1181 0 : uno::Sequence< uno::Sequence< uno::Any > > ScDDELinkObj::getResults( )
1182 : throw (uno::RuntimeException)
1183 : {
1184 0 : SolarMutexGuard aGuard;
1185 0 : uno::Sequence< uno::Sequence< uno::Any > > aReturn;
1186 0 : bool bSuccess = false;
1187 :
1188 0 : if ( pDocShell )
1189 : {
1190 0 : ScDocument* pDoc = pDocShell->GetDocument();
1191 0 : if ( pDoc )
1192 : {
1193 0 : sal_uInt16 nPos = 0;
1194 0 : if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1195 : {
1196 0 : const ScMatrix* pMatrix = pDoc->GetDdeLinkResultMatrix( nPos );
1197 0 : if ( pMatrix )
1198 : {
1199 0 : uno::Any aAny;
1200 0 : if ( ScRangeToSequence::FillMixedArray( aAny, pMatrix, true ) )
1201 : {
1202 0 : aAny >>= aReturn;
1203 0 : }
1204 : }
1205 0 : bSuccess = true;
1206 : }
1207 : }
1208 : }
1209 :
1210 0 : if ( !bSuccess )
1211 : {
1212 : throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1213 : "ScDDELinkObj::getResults: failed to get results!" ) ),
1214 0 : uno::Reference< uno::XInterface >() );
1215 : }
1216 :
1217 0 : return aReturn;
1218 : }
1219 :
1220 0 : void ScDDELinkObj::setResults( const uno::Sequence< uno::Sequence< uno::Any > >& aResults )
1221 : throw (uno::RuntimeException)
1222 : {
1223 0 : SolarMutexGuard aGuard;
1224 0 : bool bSuccess = false;
1225 :
1226 0 : if ( pDocShell )
1227 : {
1228 0 : ScDocument* pDoc = pDocShell->GetDocument();
1229 0 : if ( pDoc )
1230 : {
1231 0 : sal_uInt16 nPos = 0;
1232 0 : if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1233 : {
1234 0 : uno::Any aAny;
1235 0 : aAny <<= aResults;
1236 0 : ScMatrixRef xMatrix = ScSequenceToMatrix::CreateMixedMatrix( aAny );
1237 0 : bSuccess = pDoc->SetDdeLinkResultMatrix( nPos, xMatrix );
1238 : }
1239 : }
1240 : }
1241 :
1242 0 : if ( !bSuccess )
1243 : {
1244 : throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1245 : "ScDDELinkObj::setResults: failed to set results!" ) ),
1246 0 : uno::Reference< uno::XInterface >() );
1247 0 : }
1248 0 : }
1249 :
1250 0 : void ScDDELinkObj::Refreshed_Impl()
1251 : {
1252 0 : lang::EventObject aEvent;
1253 0 : aEvent.Source.set((cppu::OWeakObject*)this);
1254 0 : for ( sal_uInt16 n=0; n<aRefreshListeners.size(); n++ )
1255 0 : aRefreshListeners[n]->refreshed( aEvent );
1256 0 : }
1257 :
1258 : //------------------------------------------------------------------------
1259 :
1260 2 : ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) :
1261 2 : pDocShell( pDocSh )
1262 : {
1263 2 : pDocShell->GetDocument()->AddUnoObject(*this);
1264 2 : }
1265 :
1266 6 : ScDDELinksObj::~ScDDELinksObj()
1267 : {
1268 2 : if (pDocShell)
1269 2 : pDocShell->GetDocument()->RemoveUnoObject(*this);
1270 4 : }
1271 :
1272 0 : void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1273 : {
1274 : // Referenz-Update interessiert hier nicht
1275 :
1276 0 : if ( rHint.ISA( SfxSimpleHint ) &&
1277 0 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1278 : {
1279 0 : pDocShell = NULL; // ungueltig geworden
1280 : }
1281 0 : }
1282 :
1283 : // XDDELinks
1284 :
1285 0 : ScDDELinkObj* ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
1286 : {
1287 0 : if (pDocShell)
1288 : {
1289 0 : rtl::OUString aAppl, aTopic, aItem;
1290 0 : if ( nIndex <= USHRT_MAX &&
1291 0 : pDocShell->GetDocument()->GetDdeLinkData( (sal_uInt16)nIndex, aAppl, aTopic, aItem ) )
1292 0 : return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1293 : }
1294 0 : return NULL;
1295 : }
1296 :
1297 0 : ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const rtl::OUString& aName)
1298 : {
1299 0 : if (pDocShell)
1300 : {
1301 0 : String aNamStr(aName);
1302 0 : rtl::OUString aAppl, aTopic, aItem;
1303 :
1304 0 : ScDocument* pDoc = pDocShell->GetDocument();
1305 0 : sal_uInt16 nCount = pDoc->GetDdeLinkCount();
1306 0 : for (sal_uInt16 i=0; i<nCount; i++)
1307 : {
1308 0 : pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1309 0 : if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1310 0 : return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1311 0 : }
1312 : }
1313 0 : return NULL;
1314 : }
1315 :
1316 : // XEnumerationAccess
1317 :
1318 0 : uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration()
1319 : throw(uno::RuntimeException)
1320 : {
1321 0 : SolarMutexGuard aGuard;
1322 0 : return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DDELinksEnumeration")));
1323 : }
1324 :
1325 : // XIndexAccess
1326 :
1327 2 : sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException)
1328 : {
1329 2 : SolarMutexGuard aGuard;
1330 2 : sal_Int32 nAreaCount = 0;
1331 2 : if (pDocShell)
1332 2 : nAreaCount = pDocShell->GetDocument()->GetDdeLinkCount();
1333 2 : return nAreaCount;
1334 : }
1335 :
1336 0 : uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex )
1337 : throw(lang::IndexOutOfBoundsException,
1338 : lang::WrappedTargetException, uno::RuntimeException)
1339 : {
1340 0 : SolarMutexGuard aGuard;
1341 0 : uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex));
1342 0 : if (xLink.is())
1343 0 : return uno::makeAny(xLink);
1344 : else
1345 0 : throw lang::IndexOutOfBoundsException();
1346 : }
1347 :
1348 0 : uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException)
1349 : {
1350 0 : SolarMutexGuard aGuard;
1351 0 : return getCppuType((uno::Reference<sheet::XDDELink>*)0);
1352 : }
1353 :
1354 0 : sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException)
1355 : {
1356 0 : SolarMutexGuard aGuard;
1357 0 : return ( getCount() != 0 );
1358 : }
1359 :
1360 0 : uno::Any SAL_CALL ScDDELinksObj::getByName( const rtl::OUString& aName )
1361 : throw(container::NoSuchElementException,
1362 : lang::WrappedTargetException, uno::RuntimeException)
1363 : {
1364 0 : SolarMutexGuard aGuard;
1365 0 : uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName));
1366 0 : if (xLink.is())
1367 0 : return uno::makeAny(xLink);
1368 : else
1369 0 : throw container::NoSuchElementException();
1370 : }
1371 :
1372 0 : uno::Sequence<rtl::OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException)
1373 : {
1374 0 : SolarMutexGuard aGuard;
1375 0 : if (pDocShell)
1376 : {
1377 0 : rtl::OUString aAppl, aTopic, aItem;
1378 :
1379 0 : ScDocument* pDoc = pDocShell->GetDocument();
1380 0 : sal_uInt16 nCount = pDoc->GetDdeLinkCount();
1381 0 : uno::Sequence<rtl::OUString> aSeq(nCount);
1382 0 : rtl::OUString* pAry = aSeq.getArray();
1383 :
1384 0 : for (sal_uInt16 i=0; i<nCount; i++)
1385 : {
1386 0 : pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1387 0 : pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem);
1388 : }
1389 0 : return aSeq;
1390 : }
1391 0 : return uno::Sequence<rtl::OUString>();
1392 : }
1393 :
1394 0 : sal_Bool SAL_CALL ScDDELinksObj::hasByName( const rtl::OUString& aName )
1395 : throw(uno::RuntimeException)
1396 : {
1397 0 : SolarMutexGuard aGuard;
1398 0 : if (pDocShell)
1399 : {
1400 0 : String aNamStr(aName);
1401 0 : rtl::OUString aAppl, aTopic, aItem;
1402 :
1403 0 : ScDocument* pDoc = pDocShell->GetDocument();
1404 0 : sal_uInt16 nCount = pDoc->GetDdeLinkCount();
1405 0 : for (sal_uInt16 i=0; i<nCount; i++)
1406 : {
1407 0 : pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1408 0 : if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1409 0 : return sal_True;
1410 0 : }
1411 : }
1412 0 : return false;
1413 : }
1414 :
1415 : // XDDELinks
1416 :
1417 0 : uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
1418 : const ::rtl::OUString& aApplication, const ::rtl::OUString& aTopic,
1419 : const ::rtl::OUString& aItem, ::com::sun::star::sheet::DDELinkMode nMode )
1420 : throw (uno::RuntimeException)
1421 : {
1422 0 : SolarMutexGuard aGuard;
1423 0 : uno::Reference< sheet::XDDELink > xLink;
1424 :
1425 0 : if ( pDocShell )
1426 : {
1427 0 : ScDocument* pDoc = pDocShell->GetDocument();
1428 0 : if ( pDoc )
1429 : {
1430 0 : sal_uInt8 nMod = SC_DDE_DEFAULT;
1431 0 : switch ( nMode )
1432 : {
1433 : case sheet::DDELinkMode_DEFAULT:
1434 : {
1435 0 : nMod = SC_DDE_DEFAULT;
1436 : }
1437 0 : break;
1438 : case sheet::DDELinkMode_ENGLISH:
1439 : {
1440 0 : nMod = SC_DDE_ENGLISH;
1441 : }
1442 0 : break;
1443 : case sheet::DDELinkMode_TEXT:
1444 : {
1445 0 : nMod = SC_DDE_TEXT;
1446 : }
1447 0 : break;
1448 : default:
1449 : {
1450 : }
1451 0 : break;
1452 : }
1453 :
1454 0 : if ( pDoc->CreateDdeLink( aApplication, aTopic, aItem, nMod, ScMatrixRef() ) )
1455 : {
1456 0 : const ::rtl::OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) );
1457 0 : xLink.set( GetObjectByName_Impl( aName ) );
1458 : }
1459 : }
1460 : }
1461 :
1462 0 : if ( !xLink.is() )
1463 : {
1464 : throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1465 : "ScDDELinksObj::addDDELink: cannot add DDE link!" ) ),
1466 0 : uno::Reference< uno::XInterface >() );
1467 : }
1468 :
1469 0 : return xLink;
1470 : }
1471 :
1472 : // ============================================================================
1473 :
1474 0 : ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
1475 : mpTable(pTable),
1476 0 : mnIndex(nIndex)
1477 : {
1478 0 : }
1479 :
1480 0 : ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
1481 : {
1482 0 : }
1483 :
1484 0 : void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue)
1485 : throw (IllegalArgumentException, RuntimeException)
1486 : {
1487 0 : SolarMutexGuard aGuard;
1488 0 : if (nRow < 0 || nCol < 0)
1489 0 : throw IllegalArgumentException();
1490 :
1491 0 : ScExternalRefCache::TokenRef pToken;
1492 0 : double fVal = 0.0;
1493 0 : OUString aVal;
1494 0 : if (rValue >>= fVal)
1495 0 : pToken.reset(new FormulaDoubleToken(fVal));
1496 0 : else if (rValue >>= aVal)
1497 0 : pToken.reset(new FormulaStringToken(aVal));
1498 : else
1499 : // unidentified value type.
1500 0 : return;
1501 :
1502 0 : mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken);
1503 : }
1504 :
1505 0 : Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow)
1506 : throw (IllegalArgumentException, RuntimeException)
1507 : {
1508 0 : SolarMutexGuard aGuard;
1509 0 : if (nRow < 0 || nCol < 0)
1510 0 : throw IllegalArgumentException();
1511 :
1512 0 : FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get();
1513 0 : if (!pToken)
1514 0 : throw IllegalArgumentException();
1515 :
1516 0 : Any aValue;
1517 0 : switch (pToken->GetType())
1518 : {
1519 : case svDouble:
1520 : {
1521 0 : double fVal = pToken->GetDouble();
1522 0 : aValue <<= fVal;
1523 : }
1524 0 : break;
1525 : case svString:
1526 : {
1527 0 : OUString aVal = pToken->GetString();
1528 0 : aValue <<= aVal;
1529 : }
1530 0 : break;
1531 : default:
1532 0 : throw IllegalArgumentException();
1533 : }
1534 0 : return aValue;
1535 : }
1536 :
1537 0 : Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows()
1538 : throw (RuntimeException)
1539 : {
1540 0 : SolarMutexGuard aGuard;
1541 0 : vector<SCROW> aRows;
1542 0 : mpTable->getAllRows(aRows);
1543 0 : size_t nSize = aRows.size();
1544 0 : Sequence<sal_Int32> aRowsSeq(nSize);
1545 0 : for (size_t i = 0; i < nSize; ++i)
1546 0 : aRowsSeq[i] = aRows[i];
1547 :
1548 0 : return aRowsSeq;
1549 : }
1550 :
1551 0 : Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow)
1552 : throw (IllegalArgumentException, RuntimeException)
1553 : {
1554 0 : SolarMutexGuard aGuard;
1555 0 : if (nRow < 0)
1556 0 : throw IllegalArgumentException();
1557 :
1558 0 : vector<SCCOL> aCols;
1559 0 : mpTable->getAllCols(static_cast<SCROW>(nRow), aCols);
1560 0 : size_t nSize = aCols.size();
1561 0 : Sequence<sal_Int32> aColsSeq(nSize);
1562 0 : for (size_t i = 0; i < nSize; ++i)
1563 0 : aColsSeq[i] = aCols[i];
1564 :
1565 0 : return aColsSeq;
1566 : }
1567 :
1568 0 : sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
1569 : throw (RuntimeException)
1570 : {
1571 0 : return static_cast< sal_Int32 >( mnIndex );
1572 : }
1573 :
1574 : // ============================================================================
1575 :
1576 0 : ScExternalDocLinkObj::ScExternalDocLinkObj(ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
1577 0 : mpRefMgr(pRefMgr), mnFileId(nFileId)
1578 : {
1579 0 : }
1580 :
1581 0 : ScExternalDocLinkObj::~ScExternalDocLinkObj()
1582 : {
1583 0 : }
1584 :
1585 0 : Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache(
1586 : const OUString& aSheetName, sal_Bool bDynamicCache )
1587 : throw (RuntimeException)
1588 : {
1589 0 : SolarMutexGuard aGuard;
1590 0 : size_t nIndex = 0;
1591 0 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
1592 0 : if (!bDynamicCache)
1593 : // Set the whole table cached to prevent access to the source document.
1594 0 : pTable->setWholeTableCached();
1595 :
1596 0 : Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1597 0 : return aSheetCache;
1598 : }
1599 :
1600 0 : Any SAL_CALL ScExternalDocLinkObj::getByName(const::rtl::OUString &aName)
1601 : throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
1602 : {
1603 0 : SolarMutexGuard aGuard;
1604 0 : size_t nIndex = 0;
1605 0 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex);
1606 0 : if (!pTable)
1607 0 : throw container::NoSuchElementException();
1608 :
1609 0 : Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1610 :
1611 0 : Any aAny;
1612 0 : aAny <<= aSheetCache;
1613 0 : return aAny;
1614 : }
1615 :
1616 0 : Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
1617 : throw (RuntimeException)
1618 : {
1619 0 : SolarMutexGuard aGuard;
1620 0 : vector<OUString> aTabNames;
1621 0 : mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
1622 :
1623 : // #i116940# be consistent with getByName: include only table names which have a cache already
1624 0 : vector<OUString> aValidNames;
1625 0 : for (vector<OUString>::iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter)
1626 0 : if (mpRefMgr->getCacheTable(mnFileId, *aIter, false))
1627 0 : aValidNames.push_back(*aIter);
1628 :
1629 0 : size_t n = aValidNames.size();
1630 0 : Sequence<OUString> aSeq(n);
1631 0 : for (size_t i = 0; i < n; ++i)
1632 0 : aSeq[i] = aValidNames[i];
1633 0 : return aSeq;
1634 : }
1635 :
1636 0 : sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
1637 : throw (RuntimeException)
1638 : {
1639 0 : SolarMutexGuard aGuard;
1640 :
1641 : // #i116940# be consistent with getByName: allow only table names which have a cache already
1642 0 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false);
1643 0 : return (pTable.get() != NULL);
1644 : }
1645 :
1646 0 : sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
1647 : throw (RuntimeException)
1648 : {
1649 0 : SolarMutexGuard aGuard;
1650 :
1651 : // #i116940# be consistent with getByName: count only table names which have a cache already
1652 0 : return getElementNames().getLength();
1653 : }
1654 :
1655 0 : Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex)
1656 : throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
1657 : {
1658 0 : SolarMutexGuard aGuard;
1659 :
1660 : // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
1661 : // the entries which have a cache already. Quick solution: Use getElementNames.
1662 0 : Sequence< OUString > aNames( getElementNames() );
1663 0 : if (nApiIndex < 0 || nApiIndex >= aNames.getLength())
1664 0 : throw lang::IndexOutOfBoundsException();
1665 :
1666 0 : size_t nIndex = 0;
1667 0 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex);
1668 0 : if (!pTable)
1669 0 : throw lang::IndexOutOfBoundsException();
1670 :
1671 0 : Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1672 :
1673 0 : Any aAny;
1674 0 : aAny <<= aSheetCache;
1675 0 : return aAny;
1676 : }
1677 :
1678 0 : Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration()
1679 : throw (RuntimeException)
1680 : {
1681 0 : SolarMutexGuard aGuard;
1682 : Reference< container::XEnumeration > aRef(
1683 : new ScIndexEnumeration(this, OUString(RTL_CONSTASCII_USTRINGPARAM(
1684 0 : "com.sun.star.sheet.ExternalDocLink"))));
1685 0 : return aRef;
1686 : }
1687 :
1688 0 : uno::Type SAL_CALL ScExternalDocLinkObj::getElementType()
1689 : throw (RuntimeException)
1690 : {
1691 0 : SolarMutexGuard aGuard;
1692 0 : return getCppuType(static_cast<Reference<sheet::XExternalDocLink>*>(0));
1693 : }
1694 :
1695 0 : sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
1696 : throw (RuntimeException)
1697 : {
1698 0 : SolarMutexGuard aGuard;
1699 :
1700 : // #i116940# be consistent with getByName: count only table names which have a cache already
1701 0 : return ( getElementNames().getLength() > 0 );
1702 : }
1703 :
1704 0 : sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
1705 : throw (RuntimeException)
1706 : {
1707 0 : return static_cast<sal_Int32>(mnFileId);
1708 : }
1709 :
1710 : // ============================================================================
1711 :
1712 0 : ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
1713 : mpDocShell(pDocShell),
1714 0 : mpRefMgr(pDocShell->GetDocument()->GetExternalRefManager())
1715 : {
1716 0 : }
1717 :
1718 0 : ScExternalDocLinksObj::~ScExternalDocLinksObj()
1719 : {
1720 0 : }
1721 :
1722 0 : Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink(
1723 : const OUString& aDocName )
1724 : throw (RuntimeException)
1725 : {
1726 0 : SolarMutexGuard aGuard;
1727 0 : sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocName);
1728 0 : Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1729 0 : return aDocLink;
1730 : }
1731 :
1732 0 : Any SAL_CALL ScExternalDocLinksObj::getByName(const::rtl::OUString &aName)
1733 : throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
1734 : {
1735 0 : SolarMutexGuard aGuard;
1736 0 : if (!mpRefMgr->hasExternalFile(aName))
1737 0 : throw container::NoSuchElementException();
1738 :
1739 0 : sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aName);
1740 0 : Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1741 :
1742 0 : Any aAny;
1743 0 : aAny <<= aDocLink;
1744 0 : return aAny;
1745 : }
1746 :
1747 0 : Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames()
1748 : throw (RuntimeException)
1749 : {
1750 0 : SolarMutexGuard aGuard;
1751 0 : sal_uInt16 n = mpRefMgr->getExternalFileCount();
1752 0 : Sequence<OUString> aSeq(n);
1753 0 : for (sal_uInt16 i = 0; i < n; ++i)
1754 : {
1755 0 : const OUString* pName = mpRefMgr->getExternalFileName(i);
1756 0 : aSeq[i] = pName ? *pName : OUString();
1757 : }
1758 :
1759 0 : return aSeq;
1760 : }
1761 :
1762 0 : sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName)
1763 : throw (RuntimeException)
1764 : {
1765 0 : SolarMutexGuard aGuard;
1766 0 : return mpRefMgr->hasExternalFile(aName);
1767 : }
1768 :
1769 0 : sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount()
1770 : throw (RuntimeException)
1771 : {
1772 0 : SolarMutexGuard aGuard;
1773 0 : return mpRefMgr->getExternalFileCount();
1774 : }
1775 :
1776 0 : Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex)
1777 : throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
1778 : {
1779 0 : SolarMutexGuard aGuard;
1780 0 : if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min())
1781 0 : throw lang::IndexOutOfBoundsException();
1782 :
1783 0 : sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex);
1784 :
1785 0 : if (!mpRefMgr->hasExternalFile(nFileId))
1786 0 : throw lang::IndexOutOfBoundsException();
1787 :
1788 0 : Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1789 0 : Any aAny;
1790 0 : aAny <<= aDocLink;
1791 0 : return aAny;
1792 : }
1793 :
1794 0 : Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration()
1795 : throw (RuntimeException)
1796 : {
1797 0 : SolarMutexGuard aGuard;
1798 : Reference< container::XEnumeration > aRef(
1799 : new ScIndexEnumeration(this, OUString(RTL_CONSTASCII_USTRINGPARAM(
1800 0 : "com.sun.star.sheet.ExternalDocLinks"))));
1801 0 : return aRef;
1802 : }
1803 :
1804 0 : uno::Type SAL_CALL ScExternalDocLinksObj::getElementType()
1805 : throw (RuntimeException)
1806 : {
1807 0 : SolarMutexGuard aGuard;
1808 0 : return getCppuType(static_cast<Reference<sheet::XExternalDocLinks>*>(0));
1809 : }
1810 :
1811 0 : sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements()
1812 : throw (RuntimeException)
1813 : {
1814 0 : SolarMutexGuard aGuard;
1815 0 : return mpRefMgr->getExternalFileCount() > 0;
1816 : }
1817 :
1818 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|