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 10 : static const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap()
55 : {
56 : static const SfxItemPropertyMapEntry aSheetLinkMap_Impl[] =
57 : {
58 4 : {OUString(SC_UNONAME_FILTER), 0, cppu::UnoType<OUString>::get(), 0, 0 },
59 4 : {OUString(SC_UNONAME_FILTOPT), 0, cppu::UnoType<OUString>::get(), 0, 0 },
60 4 : {OUString(SC_UNONAME_LINKURL), 0, cppu::UnoType<OUString>::get(), 0, 0 },
61 4 : {OUString(SC_UNONAME_REFDELAY), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
62 4 : {OUString(SC_UNONAME_REFPERIOD), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
63 : { OUString(), 0, css::uno::Type(), 0, 0 }
64 34 : };
65 10 : return aSheetLinkMap_Impl;
66 : }
67 :
68 2 : 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 5 : ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const OUString& rName) :
76 : aPropSet( lcl_GetSheetLinkMap() ),
77 : pDocShell( pDocSh ),
78 5 : aFileName( rName )
79 : {
80 5 : pDocShell->GetDocument().AddUnoObject(*this);
81 5 : }
82 :
83 15 : ScSheetLinkObj::~ScSheetLinkObj()
84 : {
85 5 : SolarMutexGuard g;
86 :
87 5 : if (pDocShell)
88 0 : pDocShell->GetDocument().RemoveUnoObject(*this);
89 10 : }
90 :
91 5 : void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
92 : {
93 : //! notify if links in document are changed
94 : // UpdateRef is not needed here
95 :
96 5 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
97 5 : if ( pSimpleHint )
98 : {
99 5 : if ( pSimpleHint->GetId() == SFX_HINT_DYING )
100 5 : 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 5 : }
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(static_cast<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 == SC_UNONAME_LINKURL )
224 : {
225 0 : if ( aValue >>= aValStr )
226 0 : setFileName( aValStr );
227 : }
228 0 : else if ( aNameString == SC_UNONAME_FILTER )
229 : {
230 0 : if ( aValue >>= aValStr )
231 0 : setFilter( aValStr );
232 : }
233 0 : else if ( aNameString == SC_UNONAME_FILTOPT )
234 : {
235 0 : if ( aValue >>= aValStr )
236 0 : setFilterOptions( aValStr );
237 : }
238 0 : else if ( aNameString == 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 == 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 == SC_UNONAME_LINKURL )
260 0 : aRet <<= getFileName();
261 0 : else if ( aNameString == SC_UNONAME_FILTER )
262 0 : aRet <<= getFilter();
263 0 : else if ( aNameString == SC_UNONAME_FILTOPT )
264 0 : aRet <<= getFilterOptions();
265 0 : else if ( aNameString == SC_UNONAME_REFPERIOD )
266 0 : aRet <<= getRefreshDelay();
267 0 : else if ( aNameString == 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() 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() 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() 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() 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 6 : ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) :
378 6 : pDocShell( pDocSh )
379 : {
380 6 : pDocShell->GetDocument().AddUnoObject(*this);
381 6 : }
382 :
383 18 : ScSheetLinksObj::~ScSheetLinksObj()
384 : {
385 6 : SolarMutexGuard g;
386 :
387 6 : if (pDocShell)
388 0 : pDocShell->GetDocument().RemoveUnoObject(*this);
389 12 : }
390 :
391 180 : void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
392 : {
393 : // Referenz-Update interessiert hier nicht
394 :
395 180 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
396 180 : if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
397 : {
398 6 : pDocShell = NULL; // ungueltig geworden
399 : }
400 180 : }
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 std::unordered_set<OUString, OUStringHash> StrSetType;
410 6 : StrSetType aNames;
411 6 : ScDocument& rDoc = pDocShell->GetDocument();
412 6 : SCTAB nTabCount = rDoc.GetTableCount();
413 6 : sal_Int32 nCount = 0;
414 8 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
415 : {
416 6 : if (!rDoc.IsLinked(nTab))
417 0 : continue;
418 :
419 6 : OUString aLinkDoc = rDoc.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 : OUString aNameStr(aName);
439 :
440 2 : ScDocument& rDoc = pDocShell->GetDocument();
441 2 : SCTAB nTabCount = rDoc.GetTableCount();
442 3 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
443 2 : if (rDoc.IsLinked(nTab))
444 : {
445 : //! case-insensitive ???
446 2 : OUString aLinkDoc = rDoc.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 2 : uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration()
457 : throw(uno::RuntimeException, std::exception)
458 : {
459 2 : SolarMutexGuard aGuard;
460 2 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.SheetLinksEnumeration"));
461 : }
462 :
463 : // XIndexAccess
464 5 : sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException, std::exception)
465 : {
466 : typedef std::unordered_set<OUString, OUStringHash> StrSetType;
467 :
468 5 : SolarMutexGuard aGuard;
469 5 : if (!pDocShell)
470 0 : return 0;
471 :
472 5 : sal_Int32 nCount = 0;
473 :
474 10 : StrSetType aNames;
475 5 : ScDocument& rDoc = pDocShell->GetDocument();
476 5 : SCTAB nTabCount = rDoc.GetTableCount();
477 10 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
478 : {
479 5 : if (!rDoc.IsLinked(nTab))
480 0 : continue;
481 :
482 5 : OUString aLinkDoc = rDoc.GetLinkDoc(nTab);
483 5 : if (aNames.insert(aLinkDoc).second)
484 5 : ++nCount;
485 5 : }
486 10 : return nCount;
487 : }
488 :
489 6 : uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex )
490 : throw(lang::IndexOutOfBoundsException,
491 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
492 : {
493 6 : SolarMutexGuard aGuard;
494 12 : uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex));
495 6 : if (xLink.is())
496 8 : return uno::makeAny(xLink);
497 : else
498 8 : throw lang::IndexOutOfBoundsException();
499 : }
500 :
501 1 : uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException, std::exception)
502 : {
503 1 : SolarMutexGuard aGuard;
504 1 : return cppu::UnoType<beans::XPropertySet>::get();
505 : }
506 :
507 1 : sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException, std::exception)
508 : {
509 1 : SolarMutexGuard aGuard;
510 1 : return ( getCount() != 0 );
511 : }
512 :
513 2 : uno::Any SAL_CALL ScSheetLinksObj::getByName( const OUString& aName )
514 : throw(container::NoSuchElementException,
515 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
516 : {
517 2 : SolarMutexGuard aGuard;
518 4 : uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName));
519 2 : if (xLink.is())
520 2 : return uno::makeAny(xLink);
521 : else
522 3 : throw container::NoSuchElementException();
523 : // return uno::Any();
524 : }
525 :
526 2 : sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const OUString& aName )
527 : throw(uno::RuntimeException, std::exception)
528 : {
529 2 : SolarMutexGuard aGuard;
530 : // Name ist der Dateiname
531 :
532 2 : if (pDocShell)
533 : {
534 2 : OUString aNameStr(aName);
535 :
536 2 : ScDocument& rDoc = pDocShell->GetDocument();
537 2 : SCTAB nTabCount = rDoc.GetTableCount();
538 3 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
539 2 : if (rDoc.IsLinked(nTab))
540 : {
541 : //! case-insensitiv ???
542 2 : OUString aLinkDoc(rDoc.GetLinkDoc( nTab ));
543 2 : if ( aLinkDoc == aNameStr )
544 1 : return sal_True;
545 1 : }
546 : }
547 1 : return false;
548 : }
549 :
550 1 : uno::Sequence<OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException, std::exception)
551 : {
552 : typedef std::unordered_set<OUString, OUStringHash> StrSetType;
553 :
554 1 : SolarMutexGuard aGuard;
555 : // Name ist der Dateiname
556 :
557 1 : if (!pDocShell)
558 0 : return uno::Sequence<OUString>();
559 :
560 2 : StrSetType aNames;
561 1 : ScDocument& rDoc = pDocShell->GetDocument();
562 1 : SCTAB nTabCount = rDoc.GetTableCount();
563 :
564 1 : sal_Int32 nLinkCount = getCount();
565 2 : uno::Sequence<OUString> aSeq(nLinkCount);
566 1 : OUString* pAry = aSeq.getArray();
567 1 : size_t nPos = 0;
568 2 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
569 : {
570 1 : if (!rDoc.IsLinked(nTab))
571 0 : continue;
572 :
573 1 : OUString aLinkDoc = rDoc.GetLinkDoc(nTab);
574 1 : if (aNames.insert(aLinkDoc).second)
575 1 : pAry[nPos++] = aLinkDoc;
576 1 : }
577 : OSL_ENSURE( nPos==static_cast<size_t>(nLinkCount), "verzaehlt" );
578 2 : return aSeq;
579 : }
580 :
581 61 : static ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, size_t nPos )
582 : {
583 61 : if (pDocShell)
584 : {
585 61 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager();
586 61 : size_t nTotalCount = pLinkManager->GetLinks().size();
587 61 : size_t nAreaCount = 0;
588 61 : for (size_t i=0; i<nTotalCount; i++)
589 : {
590 61 : ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
591 61 : if (pBase->ISA(ScAreaLink))
592 : {
593 61 : if ( nAreaCount == nPos )
594 61 : return static_cast<ScAreaLink*>(pBase);
595 0 : ++nAreaCount;
596 : }
597 : }
598 : }
599 0 : return NULL; // nicht gefunden
600 : }
601 :
602 5 : ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, size_t nP) :
603 : aPropSet( lcl_GetSheetLinkMap() ),
604 : pDocShell( pDocSh ),
605 5 : nPos( nP )
606 : {
607 5 : pDocShell->GetDocument().AddUnoObject(*this);
608 5 : }
609 :
610 15 : ScAreaLinkObj::~ScAreaLinkObj()
611 : {
612 5 : SolarMutexGuard g;
613 :
614 5 : if (pDocShell)
615 0 : pDocShell->GetDocument().RemoveUnoObject(*this);
616 10 : }
617 :
618 7 : void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
619 : {
620 : //! notify if links in document are changed
621 : // UpdateRef is not needed here
622 :
623 7 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
624 7 : if ( pSimpleHint )
625 : {
626 6 : if ( pSimpleHint->GetId() == SFX_HINT_DYING )
627 5 : pDocShell = NULL; // pointer is invalid
628 : }
629 1 : else if ( dynamic_cast<const ScLinkRefreshedHint*>(&rHint) )
630 : {
631 1 : const ScLinkRefreshedHint& rLH = static_cast<const ScLinkRefreshedHint&>(rHint);
632 1 : if ( rLH.GetLinkType() == SC_LINKREFTYPE_AREA )
633 : {
634 : // get this link to compare dest position
635 1 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
636 1 : if ( pLink && pLink->GetDestArea().aStart == rLH.GetDestPos() )
637 1 : Refreshed_Impl();
638 : }
639 : }
640 7 : }
641 :
642 : // XFileLink
643 :
644 13 : void ScAreaLinkObj::Modify_Impl( const OUString* pNewFile, const OUString* pNewFilter,
645 : const OUString* pNewOptions, const OUString* pNewSource,
646 : const table::CellRangeAddress* pNewDest )
647 : {
648 13 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
649 13 : if (pLink)
650 : {
651 13 : OUString aFile (pLink->GetFile());
652 26 : OUString aFilter (pLink->GetFilter());
653 26 : OUString aOptions (pLink->GetOptions());
654 26 : OUString aSource (pLink->GetSource());
655 13 : ScRange aDest (pLink->GetDestArea());
656 13 : sal_uLong nRefresh = pLink->GetRefreshDelay();
657 :
658 : //! Undo fuer Loeschen
659 : //! Undo zusammenfassen
660 :
661 13 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager();
662 13 : pLinkManager->Remove( pLink );
663 13 : pLink = NULL; // bei Remove geloescht
664 :
665 13 : bool bFitBlock = true; // verschieben, wenn durch Update Groesse geaendert
666 13 : if (pNewFile)
667 : {
668 3 : aFile = *pNewFile;
669 3 : aFile = ScGlobal::GetAbsDocName( aFile, pDocShell ); //! in InsertAreaLink?
670 : }
671 13 : if (pNewFilter)
672 3 : aFilter = *pNewFilter;
673 13 : if (pNewOptions)
674 3 : aOptions = *pNewOptions;
675 13 : if (pNewSource)
676 2 : aSource = *pNewSource;
677 13 : if (pNewDest)
678 : {
679 2 : ScUnoConversion::FillScRange( aDest, *pNewDest );
680 2 : bFitBlock = false; // neuer Bereich angegeben -> keine Inhalte verschieben
681 : }
682 13 : pDocShell->GetDocFunc().InsertAreaLink( aFile, aFilter, aOptions, aSource,
683 39 : aDest, nRefresh, bFitBlock, true );
684 : }
685 13 : }
686 :
687 6 : void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
688 : {
689 6 : ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos );
690 6 : if( pLink )
691 6 : pLink->SetRefreshDelay( (sal_uLong) nRefresh );
692 6 : }
693 :
694 : // XRefreshable
695 :
696 0 : void SAL_CALL ScAreaLinkObj::refresh()
697 : throw(uno::RuntimeException, std::exception)
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, std::exception)
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, std::exception)
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(static_cast<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, std::exception)
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, std::exception)
765 : {
766 15 : SolarMutexGuard aGuard;
767 30 : OUString aNameString(aPropertyName);
768 30 : OUString aValStr;
769 15 : if ( aNameString == SC_UNONAME_LINKURL )
770 : {
771 3 : if ( aValue >>= aValStr )
772 3 : setFileName( aValStr );
773 : }
774 12 : else if ( aNameString == SC_UNONAME_FILTER )
775 : {
776 3 : if ( aValue >>= aValStr )
777 3 : setFilter( aValStr );
778 : }
779 9 : else if ( aNameString == SC_UNONAME_FILTOPT )
780 : {
781 3 : if ( aValue >>= aValStr )
782 3 : setFilterOptions( aValStr );
783 : }
784 6 : else if ( aNameString == 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 == 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, std::exception)
801 : {
802 35 : SolarMutexGuard aGuard;
803 70 : OUString aNameString(aPropertyName);
804 35 : uno::Any aRet;
805 35 : if ( aNameString == SC_UNONAME_LINKURL )
806 7 : aRet <<= getFileName();
807 28 : else if ( aNameString == SC_UNONAME_FILTER )
808 7 : aRet <<= getFilter();
809 21 : else if ( aNameString == SC_UNONAME_FILTOPT )
810 7 : aRet <<= getFilterOptions();
811 14 : else if ( aNameString == SC_UNONAME_REFPERIOD )
812 7 : aRet <<= getRefreshDelay();
813 7 : else if ( aNameString == 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() 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() 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() 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() 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, std::exception)
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, std::exception)
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, std::exception)
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, std::exception)
917 : {
918 2 : SolarMutexGuard aGuard;
919 2 : Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea );
920 2 : }
921 :
922 36 : ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) :
923 36 : pDocShell( pDocSh )
924 : {
925 36 : pDocShell->GetDocument().AddUnoObject(*this);
926 36 : }
927 :
928 108 : ScAreaLinksObj::~ScAreaLinksObj()
929 : {
930 36 : SolarMutexGuard g;
931 :
932 36 : if (pDocShell)
933 29 : pDocShell->GetDocument().RemoveUnoObject(*this);
934 72 : }
935 :
936 157 : void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
937 : {
938 : // Referenz-Update interessiert hier nicht
939 :
940 157 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
941 157 : if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
942 : {
943 7 : pDocShell = NULL; // ungueltig geworden
944 : }
945 157 : }
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, std::exception)
963 : {
964 3 : SolarMutexGuard aGuard;
965 3 : if (pDocShell)
966 : {
967 3 : OUString aFileStr (aFileName);
968 6 : OUString aFilterStr (aFilter);
969 6 : OUString aOptionStr (aFilterOptions);
970 6 : OUString 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 9 : 0, false, true ); // don't move contents
977 3 : }
978 3 : }
979 :
980 0 : void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException, std::exception)
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, std::exception)
997 : {
998 2 : SolarMutexGuard aGuard;
999 2 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.CellAreaLinksEnumeration"));
1000 : }
1001 :
1002 : // XIndexAccess
1003 :
1004 40 : sal_Int32 SAL_CALL ScAreaLinksObj::getCount() throw(uno::RuntimeException, std::exception)
1005 : {
1006 40 : SolarMutexGuard aGuard;
1007 40 : sal_Int32 nAreaCount = 0;
1008 40 : if (pDocShell)
1009 : {
1010 40 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager();
1011 40 : size_t nTotalCount = pLinkManager->GetLinks().size();
1012 53 : for (size_t i=0; i<nTotalCount; i++)
1013 : {
1014 13 : ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
1015 13 : if (pBase->ISA(ScAreaLink))
1016 11 : ++nAreaCount;
1017 : }
1018 : }
1019 40 : return nAreaCount;
1020 : }
1021 :
1022 7 : uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex )
1023 : throw(lang::IndexOutOfBoundsException,
1024 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
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, std::exception)
1035 : {
1036 1 : SolarMutexGuard aGuard;
1037 1 : return cppu::UnoType<sheet::XAreaLink>::get();
1038 : }
1039 :
1040 1 : sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException, std::exception)
1041 : {
1042 1 : SolarMutexGuard aGuard;
1043 1 : return ( getCount() != 0 );
1044 : }
1045 :
1046 6 : ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const OUString& rA,
1047 : const OUString& rT, const OUString& rI) :
1048 : pDocShell( pDocSh ),
1049 : aAppl( rA ),
1050 : aTopic( rT ),
1051 6 : aItem( rI )
1052 : {
1053 6 : pDocShell->GetDocument().AddUnoObject(*this);
1054 6 : }
1055 :
1056 18 : ScDDELinkObj::~ScDDELinkObj()
1057 : {
1058 6 : SolarMutexGuard g;
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 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
1070 8 : if ( pSimpleHint )
1071 : {
1072 6 : if ( pSimpleHint->GetId() == SFX_HINT_DYING )
1073 6 : pDocShell = NULL; // pointer is invalid
1074 : }
1075 2 : else if ( dynamic_cast<const ScLinkRefreshedHint*>(&rHint) )
1076 : {
1077 2 : const ScLinkRefreshedHint& rLH = static_cast<const ScLinkRefreshedHint&>(rHint);
1078 6 : if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE &&
1079 4 : rLH.GetDdeAppl() == aAppl &&
1080 6 : rLH.GetDdeTopic() == aTopic &&
1081 2 : rLH.GetDdeItem() == aItem ) //! mode is ignored
1082 2 : Refreshed_Impl();
1083 : }
1084 8 : }
1085 :
1086 : // XNamed
1087 :
1088 9 : static OUString lcl_BuildDDEName( const OUString& rAppl, const OUString& rTopic, const OUString& rItem )
1089 : {
1090 : // Appl|Topic!Item (wie Excel)
1091 9 : OUString aRet = rAppl + "|" + rTopic + "!" + rItem;
1092 9 : return aRet;
1093 : }
1094 :
1095 2 : OUString SAL_CALL ScDDELinkObj::getName() throw(uno::RuntimeException, std::exception)
1096 : {
1097 2 : SolarMutexGuard aGuard;
1098 2 : return lcl_BuildDDEName( aAppl, aTopic, aItem );
1099 : }
1100 :
1101 0 : void SAL_CALL ScDDELinkObj::setName( const OUString& /* aName */ ) throw(uno::RuntimeException, std::exception)
1102 : {
1103 : // name can't be changed (formulas wouldn't find the link)
1104 0 : throw uno::RuntimeException();
1105 : }
1106 :
1107 : // XDDELink
1108 :
1109 1 : OUString SAL_CALL ScDDELinkObj::getApplication() throw(uno::RuntimeException, std::exception)
1110 : {
1111 1 : SolarMutexGuard aGuard;
1112 : //! Test, ob Link noch im Dokument enthalten?
1113 :
1114 1 : return aAppl;
1115 : }
1116 :
1117 1 : OUString SAL_CALL ScDDELinkObj::getTopic() throw(uno::RuntimeException, std::exception)
1118 : {
1119 1 : SolarMutexGuard aGuard;
1120 : //! Test, ob Link noch im Dokument enthalten?
1121 :
1122 1 : return aTopic;
1123 : }
1124 :
1125 1 : OUString SAL_CALL ScDDELinkObj::getItem() throw(uno::RuntimeException, std::exception)
1126 : {
1127 1 : SolarMutexGuard aGuard;
1128 : //! Test, ob Link noch im Dokument enthalten?
1129 :
1130 1 : return aItem;
1131 : }
1132 :
1133 : // XRefreshable
1134 :
1135 2 : void SAL_CALL ScDDELinkObj::refresh() throw(uno::RuntimeException, std::exception)
1136 : {
1137 2 : SolarMutexGuard aGuard;
1138 2 : if (pDocShell)
1139 : {
1140 2 : sc::DocumentLinkManager& rMgr = pDocShell->GetDocument().GetDocLinkManager();
1141 2 : rMgr.updateDdeLink(aAppl, aTopic, aItem);
1142 2 : }
1143 2 : }
1144 :
1145 1 : void SAL_CALL ScDDELinkObj::addRefreshListener(
1146 : const uno::Reference<util::XRefreshListener >& xListener )
1147 : throw (uno::RuntimeException, std::exception)
1148 : {
1149 1 : SolarMutexGuard aGuard;
1150 : uno::Reference<util::XRefreshListener>* pObj =
1151 1 : new uno::Reference<util::XRefreshListener>( xListener );
1152 1 : aRefreshListeners.push_back( pObj );
1153 :
1154 : // hold one additional ref to keep this object alive as long as there are listeners
1155 1 : if ( aRefreshListeners.size() == 1 )
1156 1 : acquire();
1157 1 : }
1158 :
1159 1 : void SAL_CALL ScDDELinkObj::removeRefreshListener(
1160 : const uno::Reference<util::XRefreshListener >& xListener )
1161 : throw(uno::RuntimeException, std::exception)
1162 : {
1163 1 : SolarMutexGuard aGuard;
1164 1 : size_t nCount = aRefreshListeners.size();
1165 2 : for ( size_t n=nCount; n--; )
1166 : {
1167 1 : uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
1168 1 : if ( rObj == xListener )
1169 : {
1170 1 : aRefreshListeners.erase( aRefreshListeners.begin() + n );
1171 1 : if ( aRefreshListeners.empty() )
1172 1 : release(); // release ref for listeners
1173 1 : break;
1174 : }
1175 1 : }
1176 1 : }
1177 :
1178 : // XDDELinkResults
1179 :
1180 0 : uno::Sequence< uno::Sequence< uno::Any > > ScDDELinkObj::getResults( )
1181 : throw (uno::RuntimeException, std::exception)
1182 : {
1183 0 : SolarMutexGuard aGuard;
1184 0 : uno::Sequence< uno::Sequence< uno::Any > > aReturn;
1185 0 : bool bSuccess = false;
1186 :
1187 0 : if ( pDocShell )
1188 : {
1189 0 : ScDocument& rDoc = pDocShell->GetDocument();
1190 0 : size_t nPos = 0;
1191 0 : if ( rDoc.FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1192 : {
1193 0 : const ScMatrix* pMatrix = rDoc.GetDdeLinkResultMatrix( nPos );
1194 0 : if ( pMatrix )
1195 : {
1196 0 : uno::Any aAny;
1197 0 : if ( ScRangeToSequence::FillMixedArray( aAny, pMatrix, true ) )
1198 : {
1199 0 : aAny >>= aReturn;
1200 0 : }
1201 : }
1202 0 : bSuccess = true;
1203 : }
1204 : }
1205 :
1206 0 : if ( !bSuccess )
1207 : {
1208 : throw uno::RuntimeException(
1209 0 : "ScDDELinkObj::getResults: failed to get results!" );
1210 : }
1211 :
1212 0 : return aReturn;
1213 : }
1214 :
1215 0 : void ScDDELinkObj::setResults( const uno::Sequence< uno::Sequence< uno::Any > >& aResults )
1216 : throw (uno::RuntimeException, std::exception)
1217 : {
1218 0 : SolarMutexGuard aGuard;
1219 0 : bool bSuccess = false;
1220 :
1221 0 : if ( pDocShell )
1222 : {
1223 0 : ScDocument& rDoc = pDocShell->GetDocument();
1224 0 : size_t nPos = 0;
1225 0 : if ( rDoc.FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1226 : {
1227 0 : uno::Any aAny;
1228 0 : aAny <<= aResults;
1229 0 : ScMatrixRef xMatrix = ScSequenceToMatrix::CreateMixedMatrix( aAny );
1230 0 : bSuccess = rDoc.SetDdeLinkResultMatrix( nPos, xMatrix );
1231 : }
1232 : }
1233 :
1234 0 : if ( !bSuccess )
1235 : {
1236 : throw uno::RuntimeException(
1237 0 : "ScDDELinkObj::setResults: failed to set results!" );
1238 0 : }
1239 0 : }
1240 :
1241 2 : void ScDDELinkObj::Refreshed_Impl()
1242 : {
1243 2 : lang::EventObject aEvent;
1244 2 : aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
1245 3 : for ( size_t n=0; n<aRefreshListeners.size(); n++ )
1246 3 : aRefreshListeners[n]->refreshed( aEvent );
1247 2 : }
1248 :
1249 36 : ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) :
1250 36 : pDocShell( pDocSh )
1251 : {
1252 36 : pDocShell->GetDocument().AddUnoObject(*this);
1253 36 : }
1254 :
1255 108 : ScDDELinksObj::~ScDDELinksObj()
1256 : {
1257 36 : SolarMutexGuard g;
1258 :
1259 36 : if (pDocShell)
1260 29 : pDocShell->GetDocument().RemoveUnoObject(*this);
1261 72 : }
1262 :
1263 149 : void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1264 : {
1265 : // Referenz-Update interessiert hier nicht
1266 :
1267 149 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
1268 149 : if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
1269 : {
1270 7 : pDocShell = NULL; // ungueltig geworden
1271 : }
1272 149 : }
1273 :
1274 : // XDDELinks
1275 :
1276 6 : ScDDELinkObj* ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
1277 : {
1278 6 : if (pDocShell)
1279 : {
1280 8 : OUString aAppl, aTopic, aItem;
1281 6 : if ( pDocShell->GetDocument().GetDdeLinkData( (size_t)nIndex, aAppl, aTopic, aItem ) )
1282 6 : return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1283 : }
1284 2 : return NULL;
1285 : }
1286 :
1287 3 : ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const OUString& aName)
1288 : {
1289 3 : if (pDocShell)
1290 : {
1291 3 : OUString aNamStr(aName);
1292 4 : OUString aAppl, aTopic, aItem;
1293 :
1294 3 : ScDocument& rDoc = pDocShell->GetDocument();
1295 3 : size_t nCount = rDoc.GetDocLinkManager().getDdeLinkCount();
1296 4 : for (size_t i=0; i<nCount; i++)
1297 : {
1298 3 : rDoc.GetDdeLinkData( i, aAppl, aTopic, aItem );
1299 3 : if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1300 2 : return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1301 1 : }
1302 : }
1303 1 : return NULL;
1304 : }
1305 :
1306 : // XEnumerationAccess
1307 :
1308 2 : uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration()
1309 : throw(uno::RuntimeException, std::exception)
1310 : {
1311 2 : SolarMutexGuard aGuard;
1312 2 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DDELinksEnumeration"));
1313 : }
1314 :
1315 : // XIndexAccess
1316 :
1317 33 : sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException, std::exception)
1318 : {
1319 33 : SolarMutexGuard aGuard;
1320 33 : sal_Int32 nAreaCount = 0;
1321 33 : if (pDocShell)
1322 33 : nAreaCount = pDocShell->GetDocument().GetDocLinkManager().getDdeLinkCount();
1323 33 : return nAreaCount;
1324 : }
1325 :
1326 6 : uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex )
1327 : throw(lang::IndexOutOfBoundsException,
1328 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
1329 : {
1330 6 : SolarMutexGuard aGuard;
1331 12 : uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex));
1332 6 : if (xLink.is())
1333 8 : return uno::makeAny(xLink);
1334 : else
1335 8 : throw lang::IndexOutOfBoundsException();
1336 : }
1337 :
1338 1 : uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException, std::exception)
1339 : {
1340 1 : SolarMutexGuard aGuard;
1341 1 : return cppu::UnoType<sheet::XDDELink>::get();
1342 : }
1343 :
1344 1 : sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException, std::exception)
1345 : {
1346 1 : SolarMutexGuard aGuard;
1347 1 : return ( getCount() != 0 );
1348 : }
1349 :
1350 3 : uno::Any SAL_CALL ScDDELinksObj::getByName( const OUString& aName )
1351 : throw(container::NoSuchElementException,
1352 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
1353 : {
1354 3 : SolarMutexGuard aGuard;
1355 6 : uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName));
1356 3 : if (xLink.is())
1357 4 : return uno::makeAny(xLink);
1358 : else
1359 4 : throw container::NoSuchElementException();
1360 : }
1361 :
1362 2 : uno::Sequence<OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException, std::exception)
1363 : {
1364 2 : SolarMutexGuard aGuard;
1365 2 : if (pDocShell)
1366 : {
1367 4 : OUString aAppl, aTopic, aItem;
1368 :
1369 2 : ScDocument& rDoc = pDocShell->GetDocument();
1370 2 : size_t nCount = pDocShell->GetDocument().GetDocLinkManager().getDdeLinkCount();
1371 4 : uno::Sequence<OUString> aSeq(nCount);
1372 2 : OUString* pAry = aSeq.getArray();
1373 :
1374 4 : for (size_t i=0; i<nCount; i++)
1375 : {
1376 2 : rDoc.GetDdeLinkData( i, aAppl, aTopic, aItem );
1377 2 : pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem);
1378 : }
1379 4 : return aSeq;
1380 : }
1381 0 : return uno::Sequence<OUString>();
1382 : }
1383 :
1384 2 : sal_Bool SAL_CALL ScDDELinksObj::hasByName( const OUString& aName )
1385 : throw(uno::RuntimeException, std::exception)
1386 : {
1387 2 : SolarMutexGuard aGuard;
1388 2 : if (pDocShell)
1389 : {
1390 2 : OUString aNamStr(aName);
1391 3 : OUString aAppl, aTopic, aItem;
1392 :
1393 2 : ScDocument& rDoc = pDocShell->GetDocument();
1394 2 : size_t nCount = pDocShell->GetDocument().GetDocLinkManager().getDdeLinkCount();
1395 3 : for (size_t i=0; i<nCount; i++)
1396 : {
1397 2 : rDoc.GetDdeLinkData( i, aAppl, aTopic, aItem );
1398 2 : if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1399 1 : return sal_True;
1400 1 : }
1401 : }
1402 1 : return false;
1403 : }
1404 :
1405 : // XDDELinks
1406 :
1407 0 : uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
1408 : const OUString& aApplication, const OUString& aTopic,
1409 : const OUString& aItem, ::com::sun::star::sheet::DDELinkMode nMode )
1410 : throw (uno::RuntimeException, std::exception)
1411 : {
1412 0 : SolarMutexGuard aGuard;
1413 0 : uno::Reference< sheet::XDDELink > xLink;
1414 :
1415 0 : if ( pDocShell )
1416 : {
1417 0 : ScDocument& rDoc = pDocShell->GetDocument();
1418 0 : sal_uInt8 nMod = SC_DDE_DEFAULT;
1419 0 : switch ( nMode )
1420 : {
1421 : case sheet::DDELinkMode_DEFAULT:
1422 : {
1423 0 : nMod = SC_DDE_DEFAULT;
1424 : }
1425 0 : break;
1426 : case sheet::DDELinkMode_ENGLISH:
1427 : {
1428 0 : nMod = SC_DDE_ENGLISH;
1429 : }
1430 0 : break;
1431 : case sheet::DDELinkMode_TEXT:
1432 : {
1433 0 : nMod = SC_DDE_TEXT;
1434 : }
1435 0 : break;
1436 : default:
1437 : {
1438 : }
1439 0 : break;
1440 : }
1441 :
1442 0 : if ( rDoc.CreateDdeLink( aApplication, aTopic, aItem, nMod, ScMatrixRef() ) )
1443 : {
1444 0 : const OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) );
1445 0 : xLink.set( GetObjectByName_Impl( aName ) );
1446 : }
1447 : }
1448 :
1449 0 : if ( !xLink.is() )
1450 : {
1451 : throw uno::RuntimeException(
1452 0 : "ScDDELinksObj::addDDELink: cannot add DDE link!" );
1453 : }
1454 :
1455 0 : return xLink;
1456 : }
1457 :
1458 6 : ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScDocShell* pDocShell, ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
1459 : mpDocShell(pDocShell),
1460 : mpTable(pTable),
1461 6 : mnIndex(nIndex)
1462 : {
1463 6 : }
1464 :
1465 12 : ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
1466 : {
1467 12 : }
1468 :
1469 4 : void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue)
1470 : throw (IllegalArgumentException, RuntimeException, std::exception)
1471 : {
1472 4 : SolarMutexGuard aGuard;
1473 4 : if (nRow < 0 || nCol < 0)
1474 0 : throw IllegalArgumentException();
1475 :
1476 8 : ScExternalRefCache::TokenRef pToken;
1477 4 : double fVal = 0.0;
1478 8 : OUString aVal;
1479 4 : if (rValue >>= fVal)
1480 0 : pToken.reset(new FormulaDoubleToken(fVal));
1481 4 : else if (rValue >>= aVal)
1482 : {
1483 4 : svl::SharedStringPool& rPool = mpDocShell->GetDocument().GetSharedStringPool();
1484 4 : svl::SharedString aSS = rPool.intern(aVal);
1485 4 : pToken.reset(new FormulaStringToken(aSS));
1486 : }
1487 : else
1488 : // unidentified value type.
1489 4 : return;
1490 :
1491 8 : mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken);
1492 : }
1493 :
1494 0 : Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow)
1495 : throw (IllegalArgumentException, RuntimeException, std::exception)
1496 : {
1497 0 : SolarMutexGuard aGuard;
1498 0 : if (nRow < 0 || nCol < 0)
1499 0 : throw IllegalArgumentException();
1500 :
1501 0 : FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get();
1502 0 : if (!pToken)
1503 0 : throw IllegalArgumentException();
1504 :
1505 0 : Any aValue;
1506 0 : switch (pToken->GetType())
1507 : {
1508 : case svDouble:
1509 : {
1510 0 : double fVal = pToken->GetDouble();
1511 0 : aValue <<= fVal;
1512 : }
1513 0 : break;
1514 : case svString:
1515 : {
1516 0 : OUString aVal = pToken->GetString().getString();
1517 0 : aValue <<= aVal;
1518 : }
1519 0 : break;
1520 : default:
1521 0 : throw IllegalArgumentException();
1522 : }
1523 0 : return aValue;
1524 : }
1525 :
1526 0 : Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows()
1527 : throw (RuntimeException, std::exception)
1528 : {
1529 0 : SolarMutexGuard aGuard;
1530 0 : vector<SCROW> aRows;
1531 0 : mpTable->getAllRows(aRows);
1532 0 : size_t nSize = aRows.size();
1533 0 : Sequence<sal_Int32> aRowsSeq(nSize);
1534 0 : for (size_t i = 0; i < nSize; ++i)
1535 0 : aRowsSeq[i] = aRows[i];
1536 :
1537 0 : return aRowsSeq;
1538 : }
1539 :
1540 0 : Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow)
1541 : throw (IllegalArgumentException, RuntimeException, std::exception)
1542 : {
1543 0 : SolarMutexGuard aGuard;
1544 0 : if (nRow < 0)
1545 0 : throw IllegalArgumentException();
1546 :
1547 0 : vector<SCCOL> aCols;
1548 0 : mpTable->getAllCols(static_cast<SCROW>(nRow), aCols);
1549 0 : size_t nSize = aCols.size();
1550 0 : Sequence<sal_Int32> aColsSeq(nSize);
1551 0 : for (size_t i = 0; i < nSize; ++i)
1552 0 : aColsSeq[i] = aCols[i];
1553 :
1554 0 : return aColsSeq;
1555 : }
1556 :
1557 3 : sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
1558 : throw (RuntimeException, std::exception)
1559 : {
1560 3 : return static_cast< sal_Int32 >( mnIndex );
1561 : }
1562 :
1563 1 : ScExternalDocLinkObj::ScExternalDocLinkObj(ScDocShell* pDocShell, ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
1564 1 : mpDocShell(pDocShell), mpRefMgr(pRefMgr), mnFileId(nFileId)
1565 : {
1566 1 : }
1567 :
1568 2 : ScExternalDocLinkObj::~ScExternalDocLinkObj()
1569 : {
1570 2 : }
1571 :
1572 3 : Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache(
1573 : const OUString& aSheetName, sal_Bool bDynamicCache )
1574 : throw (RuntimeException, std::exception)
1575 : {
1576 3 : SolarMutexGuard aGuard;
1577 3 : size_t nIndex = 0;
1578 6 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
1579 3 : if (!bDynamicCache)
1580 : // Set the whole table cached to prevent access to the source document.
1581 3 : pTable->setWholeTableCached();
1582 :
1583 3 : Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
1584 6 : return aSheetCache;
1585 : }
1586 :
1587 0 : Any SAL_CALL ScExternalDocLinkObj::getByName(const OUString &aName)
1588 : throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException, std::exception)
1589 : {
1590 0 : SolarMutexGuard aGuard;
1591 0 : size_t nIndex = 0;
1592 0 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex);
1593 0 : if (!pTable)
1594 0 : throw container::NoSuchElementException();
1595 :
1596 0 : Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
1597 :
1598 0 : Any aAny;
1599 0 : aAny <<= aSheetCache;
1600 0 : return aAny;
1601 : }
1602 :
1603 3 : Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
1604 : throw (RuntimeException, std::exception)
1605 : {
1606 3 : SolarMutexGuard aGuard;
1607 6 : vector<OUString> aTabNames;
1608 3 : mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
1609 :
1610 : // #i116940# be consistent with getByName: include only table names which have a cache already
1611 6 : vector<OUString> aValidNames;
1612 12 : for (vector<OUString>::iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter)
1613 9 : if (mpRefMgr->getCacheTable(mnFileId, *aIter, false))
1614 9 : aValidNames.push_back(*aIter);
1615 :
1616 3 : size_t n = aValidNames.size();
1617 3 : Sequence<OUString> aSeq(n);
1618 12 : for (size_t i = 0; i < n; ++i)
1619 9 : aSeq[i] = aValidNames[i];
1620 6 : return aSeq;
1621 : }
1622 :
1623 0 : sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
1624 : throw (RuntimeException, std::exception)
1625 : {
1626 0 : SolarMutexGuard aGuard;
1627 :
1628 : // #i116940# be consistent with getByName: allow only table names which have a cache already
1629 0 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false);
1630 0 : return (pTable.get() != NULL);
1631 : }
1632 :
1633 0 : sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
1634 : throw (RuntimeException, std::exception)
1635 : {
1636 0 : SolarMutexGuard aGuard;
1637 :
1638 : // #i116940# be consistent with getByName: count only table names which have a cache already
1639 0 : return getElementNames().getLength();
1640 : }
1641 :
1642 3 : Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex)
1643 : throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException, std::exception)
1644 : {
1645 3 : SolarMutexGuard aGuard;
1646 :
1647 : // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
1648 : // the entries which have a cache already. Quick solution: Use getElementNames.
1649 6 : Sequence< OUString > aNames( getElementNames() );
1650 3 : if (nApiIndex < 0 || nApiIndex >= aNames.getLength())
1651 0 : throw lang::IndexOutOfBoundsException();
1652 :
1653 3 : size_t nIndex = 0;
1654 6 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex);
1655 3 : if (!pTable)
1656 0 : throw lang::IndexOutOfBoundsException();
1657 :
1658 6 : Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
1659 :
1660 3 : Any aAny;
1661 3 : aAny <<= aSheetCache;
1662 6 : return aAny;
1663 : }
1664 :
1665 0 : Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration()
1666 : throw (RuntimeException, std::exception)
1667 : {
1668 0 : SolarMutexGuard aGuard;
1669 : Reference< container::XEnumeration > aRef(
1670 : new ScIndexEnumeration(this, OUString(
1671 0 : "com.sun.star.sheet.ExternalDocLink")));
1672 0 : return aRef;
1673 : }
1674 :
1675 0 : uno::Type SAL_CALL ScExternalDocLinkObj::getElementType()
1676 : throw (RuntimeException, std::exception)
1677 : {
1678 0 : SolarMutexGuard aGuard;
1679 0 : return cppu::UnoType<sheet::XExternalDocLink>::get();
1680 : }
1681 :
1682 0 : sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
1683 : throw (RuntimeException, std::exception)
1684 : {
1685 0 : SolarMutexGuard aGuard;
1686 :
1687 : // #i116940# be consistent with getByName: count only table names which have a cache already
1688 0 : return ( getElementNames().getLength() > 0 );
1689 : }
1690 :
1691 0 : sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
1692 : throw (RuntimeException, std::exception)
1693 : {
1694 0 : return static_cast<sal_Int32>(mnFileId);
1695 : }
1696 :
1697 3 : ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
1698 : mpDocShell(pDocShell),
1699 3 : mpRefMgr(pDocShell->GetDocument().GetExternalRefManager())
1700 : {
1701 3 : }
1702 :
1703 6 : ScExternalDocLinksObj::~ScExternalDocLinksObj()
1704 : {
1705 6 : }
1706 :
1707 1 : Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink(
1708 : const OUString& aDocName )
1709 : throw (RuntimeException, std::exception)
1710 : {
1711 1 : SolarMutexGuard aGuard;
1712 2 : OUString aDocUrl( ScGlobal::GetAbsDocName( aDocName, mpDocShell));
1713 1 : sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocUrl);
1714 1 : Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId));
1715 2 : return aDocLink;
1716 : }
1717 :
1718 0 : Any SAL_CALL ScExternalDocLinksObj::getByName(const OUString &aName)
1719 : throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException, std::exception)
1720 : {
1721 0 : SolarMutexGuard aGuard;
1722 0 : OUString aDocUrl( ScGlobal::GetAbsDocName( aName, mpDocShell));
1723 0 : if (!mpRefMgr->hasExternalFile(aDocUrl))
1724 0 : throw container::NoSuchElementException();
1725 :
1726 0 : sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocUrl);
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 156 : }
1804 :
1805 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|