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