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