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