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 0 : static const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap()
55 : {
56 : static const SfxItemPropertyMapEntry aSheetLinkMap_Impl[] =
57 : {
58 0 : {OUString(SC_UNONAME_FILTER), 0, getCppuType((OUString*)0), 0, 0 },
59 0 : {OUString(SC_UNONAME_FILTOPT), 0, getCppuType((OUString*)0), 0, 0 },
60 0 : {OUString(SC_UNONAME_LINKURL), 0, getCppuType((OUString*)0), 0, 0 },
61 0 : {OUString(SC_UNONAME_REFDELAY), 0, getCppuType((sal_Int32*)0), 0, 0 },
62 0 : {OUString(SC_UNONAME_REFPERIOD), 0, getCppuType((sal_Int32*)0), 0, 0 },
63 : { OUString(), 0, css::uno::Type(), 0, 0 }
64 0 : };
65 0 : return aSheetLinkMap_Impl;
66 : }
67 :
68 0 : 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 0 : ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const OUString& rName) :
76 : aPropSet( lcl_GetSheetLinkMap() ),
77 : pDocShell( pDocSh ),
78 0 : aFileName( rName )
79 : {
80 0 : pDocShell->GetDocument()->AddUnoObject(*this);
81 0 : }
82 :
83 0 : ScSheetLinkObj::~ScSheetLinkObj()
84 : {
85 0 : if (pDocShell)
86 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
87 0 : }
88 :
89 0 : void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
90 : {
91 : //! notify if links in document are changed
92 : // UpdateRef is not needed here
93 :
94 0 : if ( rHint.ISA( SfxSimpleHint ) )
95 : {
96 0 : if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
97 0 : 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 0 : }
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 0 : ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) :
375 0 : pDocShell( pDocSh )
376 : {
377 0 : pDocShell->GetDocument()->AddUnoObject(*this);
378 0 : }
379 :
380 0 : ScSheetLinksObj::~ScSheetLinksObj()
381 : {
382 0 : if (pDocShell)
383 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
384 0 : }
385 :
386 0 : void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
387 : {
388 : // Referenz-Update interessiert hier nicht
389 :
390 0 : if ( rHint.ISA( SfxSimpleHint ) &&
391 0 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
392 : {
393 0 : pDocShell = NULL; // ungueltig geworden
394 : }
395 0 : }
396 :
397 : // XSheetLinks
398 :
399 0 : ScSheetLinkObj* ScSheetLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
400 : {
401 0 : if (!pDocShell)
402 0 : return NULL;
403 :
404 : typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
405 0 : StrSetType aNames;
406 0 : ScDocument* pDoc = pDocShell->GetDocument();
407 0 : SCTAB nTabCount = pDoc->GetTableCount();
408 0 : sal_Int32 nCount = 0;
409 0 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
410 : {
411 0 : if (!pDoc->IsLinked(nTab))
412 0 : continue;
413 :
414 0 : OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
415 0 : if (aNames.insert(aLinkDoc).second)
416 : {
417 : // unique document name.
418 0 : if (nCount == nIndex)
419 0 : return new ScSheetLinkObj( pDocShell, aLinkDoc );
420 0 : ++nCount;
421 : }
422 0 : }
423 :
424 0 : return NULL; // kein Dokument oder Index zu gross
425 : }
426 :
427 0 : ScSheetLinkObj* ScSheetLinksObj::GetObjectByName_Impl(const OUString& aName)
428 : {
429 : // Name ist der Dateiname
430 :
431 0 : if (pDocShell)
432 : {
433 0 : OUString aNameStr(aName);
434 :
435 0 : ScDocument* pDoc = pDocShell->GetDocument();
436 0 : SCTAB nTabCount = pDoc->GetTableCount();
437 0 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
438 0 : if (pDoc->IsLinked(nTab))
439 : {
440 : //! case-insensitiv ???
441 0 : OUString aLinkDoc = pDoc->GetLinkDoc( nTab );
442 0 : if ( aLinkDoc == aNameStr )
443 0 : return new ScSheetLinkObj( pDocShell, aNameStr );
444 0 : }
445 : }
446 :
447 0 : return NULL;
448 : }
449 :
450 : // XEnumerationAccess
451 :
452 0 : uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration()
453 : throw(uno::RuntimeException, std::exception)
454 : {
455 0 : SolarMutexGuard aGuard;
456 0 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.SheetLinksEnumeration"));
457 : }
458 :
459 : // XIndexAccess
460 :
461 0 : sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException, std::exception)
462 : {
463 : typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
464 :
465 0 : SolarMutexGuard aGuard;
466 0 : if (!pDocShell)
467 0 : return 0;
468 :
469 0 : sal_Int32 nCount = 0;
470 :
471 0 : StrSetType aNames;
472 0 : ScDocument* pDoc = pDocShell->GetDocument();
473 0 : SCTAB nTabCount = pDoc->GetTableCount();
474 0 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
475 : {
476 0 : if (!pDoc->IsLinked(nTab))
477 0 : continue;
478 :
479 0 : OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
480 0 : if (aNames.insert(aLinkDoc).second)
481 0 : ++nCount;
482 0 : }
483 0 : return nCount;
484 : }
485 :
486 0 : uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex )
487 : throw(lang::IndexOutOfBoundsException,
488 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
489 : {
490 0 : SolarMutexGuard aGuard;
491 0 : uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex));
492 0 : if (xLink.is())
493 0 : return uno::makeAny(xLink);
494 : else
495 0 : throw lang::IndexOutOfBoundsException();
496 : }
497 :
498 0 : uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException, std::exception)
499 : {
500 0 : SolarMutexGuard aGuard;
501 0 : return getCppuType((uno::Reference<beans::XPropertySet>*)0);
502 : }
503 :
504 0 : sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException, std::exception)
505 : {
506 0 : SolarMutexGuard aGuard;
507 0 : return ( getCount() != 0 );
508 : }
509 :
510 0 : uno::Any SAL_CALL ScSheetLinksObj::getByName( const OUString& aName )
511 : throw(container::NoSuchElementException,
512 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
513 : {
514 0 : SolarMutexGuard aGuard;
515 0 : uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName));
516 0 : if (xLink.is())
517 0 : return uno::makeAny(xLink);
518 : else
519 0 : throw container::NoSuchElementException();
520 : // return uno::Any();
521 : }
522 :
523 0 : sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const OUString& aName )
524 : throw(uno::RuntimeException, std::exception)
525 : {
526 0 : SolarMutexGuard aGuard;
527 : // Name ist der Dateiname
528 :
529 0 : if (pDocShell)
530 : {
531 0 : OUString aNameStr(aName);
532 :
533 0 : ScDocument* pDoc = pDocShell->GetDocument();
534 0 : SCTAB nTabCount = pDoc->GetTableCount();
535 0 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
536 0 : if (pDoc->IsLinked(nTab))
537 : {
538 : //! case-insensitiv ???
539 0 : OUString aLinkDoc(pDoc->GetLinkDoc( nTab ));
540 0 : if ( aLinkDoc == aNameStr )
541 0 : return sal_True;
542 0 : }
543 : }
544 0 : return false;
545 : }
546 :
547 0 : uno::Sequence<OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException, std::exception)
548 : {
549 : typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
550 :
551 0 : SolarMutexGuard aGuard;
552 : // Name ist der Dateiname
553 :
554 0 : if (!pDocShell)
555 0 : return uno::Sequence<OUString>();
556 :
557 0 : StrSetType aNames;
558 0 : ScDocument* pDoc = pDocShell->GetDocument();
559 0 : SCTAB nTabCount = pDoc->GetTableCount();
560 :
561 0 : sal_Int32 nLinkCount = getCount();
562 0 : uno::Sequence<OUString> aSeq(nLinkCount);
563 0 : OUString* pAry = aSeq.getArray();
564 0 : size_t nPos = 0;
565 0 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
566 : {
567 0 : if (!pDoc->IsLinked(nTab))
568 0 : continue;
569 :
570 0 : OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
571 0 : if (aNames.insert(aLinkDoc).second)
572 0 : pAry[nPos++] = aLinkDoc;
573 0 : }
574 : OSL_ENSURE( nPos==static_cast<size_t>(nLinkCount), "verzaehlt" );
575 0 : return aSeq;
576 : }
577 :
578 0 : static ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, size_t nPos )
579 : {
580 0 : if (pDocShell)
581 : {
582 0 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
583 0 : size_t nTotalCount = pLinkManager->GetLinks().size();
584 0 : size_t nAreaCount = 0;
585 0 : for (size_t i=0; i<nTotalCount; i++)
586 : {
587 0 : ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
588 0 : if (pBase->ISA(ScAreaLink))
589 : {
590 0 : if ( nAreaCount == nPos )
591 0 : return static_cast<ScAreaLink*>(pBase);
592 0 : ++nAreaCount;
593 : }
594 : }
595 : }
596 0 : return NULL; // nicht gefunden
597 : }
598 :
599 0 : ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, size_t nP) :
600 : aPropSet( lcl_GetSheetLinkMap() ),
601 : pDocShell( pDocSh ),
602 0 : nPos( nP )
603 : {
604 0 : pDocShell->GetDocument()->AddUnoObject(*this);
605 0 : }
606 :
607 0 : ScAreaLinkObj::~ScAreaLinkObj()
608 : {
609 0 : if (pDocShell)
610 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
611 0 : }
612 :
613 0 : void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
614 : {
615 : //! notify if links in document are changed
616 : // UpdateRef is not needed here
617 :
618 0 : if ( rHint.ISA( SfxSimpleHint ) )
619 : {
620 0 : if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
621 0 : pDocShell = NULL; // pointer is invalid
622 : }
623 0 : else if ( rHint.ISA( ScLinkRefreshedHint ) )
624 : {
625 0 : const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
626 0 : if ( rLH.GetLinkType() == SC_LINKREFTYPE_AREA )
627 : {
628 : // get this link to compare dest position
629 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
630 0 : if ( pLink && pLink->GetDestArea().aStart == rLH.GetDestPos() )
631 0 : Refreshed_Impl();
632 : }
633 : }
634 0 : }
635 :
636 : // XFileLink
637 :
638 0 : void ScAreaLinkObj::Modify_Impl( const OUString* pNewFile, const OUString* pNewFilter,
639 : const OUString* pNewOptions, const OUString* pNewSource,
640 : const table::CellRangeAddress* pNewDest )
641 : {
642 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
643 0 : if (pLink)
644 : {
645 0 : OUString aFile (pLink->GetFile());
646 0 : OUString aFilter (pLink->GetFilter());
647 0 : OUString aOptions (pLink->GetOptions());
648 0 : OUString aSource (pLink->GetSource());
649 0 : ScRange aDest (pLink->GetDestArea());
650 0 : sal_uLong nRefresh = pLink->GetRefreshDelay();
651 :
652 : //! Undo fuer Loeschen
653 : //! Undo zusammenfassen
654 :
655 0 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
656 0 : pLinkManager->Remove( pLink );
657 0 : pLink = NULL; // bei Remove geloescht
658 :
659 0 : sal_Bool bFitBlock = sal_True; // verschieben, wenn durch Update Groesse geaendert
660 0 : if (pNewFile)
661 : {
662 0 : aFile = *pNewFile;
663 0 : aFile = ScGlobal::GetAbsDocName( aFile, pDocShell ); //! in InsertAreaLink?
664 : }
665 0 : if (pNewFilter)
666 0 : aFilter = *pNewFilter;
667 0 : if (pNewOptions)
668 0 : aOptions = *pNewOptions;
669 0 : if (pNewSource)
670 0 : aSource = *pNewSource;
671 0 : if (pNewDest)
672 : {
673 0 : ScUnoConversion::FillScRange( aDest, *pNewDest );
674 0 : bFitBlock = false; // neuer Bereich angegeben -> keine Inhalte verschieben
675 : }
676 0 : pDocShell->GetDocFunc().InsertAreaLink( aFile, aFilter, aOptions, aSource,
677 0 : aDest, nRefresh, bFitBlock, true );
678 : }
679 0 : }
680 :
681 0 : void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
682 : {
683 0 : ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos );
684 0 : if( pLink )
685 0 : pLink->SetRefreshDelay( (sal_uLong) nRefresh );
686 0 : }
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 0 : void ScAreaLinkObj::Refreshed_Impl()
736 : {
737 0 : lang::EventObject aEvent;
738 0 : aEvent.Source.set((cppu::OWeakObject*)this);
739 0 : for ( size_t n=0; n<aRefreshListeners.size(); n++ )
740 0 : aRefreshListeners[n]->refreshed( aEvent );
741 0 : }
742 :
743 : // XPropertySet
744 :
745 0 : uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAreaLinkObj::getPropertySetInfo()
746 : throw(uno::RuntimeException, std::exception)
747 : {
748 0 : SolarMutexGuard aGuard;
749 : static uno::Reference<beans::XPropertySetInfo> aRef(
750 0 : new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
751 0 : return aRef;
752 : }
753 :
754 0 : 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 0 : SolarMutexGuard aGuard;
761 0 : OUString aNameString(aPropertyName);
762 0 : OUString aValStr;
763 0 : if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
764 : {
765 0 : if ( aValue >>= aValStr )
766 0 : setFileName( aValStr );
767 : }
768 0 : else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
769 : {
770 0 : if ( aValue >>= aValStr )
771 0 : setFilter( aValStr );
772 : }
773 0 : else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
774 : {
775 0 : if ( aValue >>= aValStr )
776 0 : setFilterOptions( aValStr );
777 : }
778 0 : else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
779 : {
780 0 : sal_Int32 nRefresh = 0;
781 0 : if ( aValue >>= nRefresh )
782 0 : setRefreshDelay( nRefresh );
783 : }
784 0 : else if ( aNameString.equalsAscii( SC_UNONAME_REFDELAY ) )
785 : {
786 0 : sal_Int32 nRefresh = 0;
787 0 : if ( aValue >>= nRefresh )
788 0 : setRefreshDelay( nRefresh );
789 0 : }
790 0 : }
791 :
792 0 : uno::Any SAL_CALL ScAreaLinkObj::getPropertyValue( const OUString& aPropertyName )
793 : throw(beans::UnknownPropertyException, lang::WrappedTargetException,
794 : uno::RuntimeException, std::exception)
795 : {
796 0 : SolarMutexGuard aGuard;
797 0 : OUString aNameString(aPropertyName);
798 0 : uno::Any aRet;
799 0 : if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
800 0 : aRet <<= getFileName();
801 0 : else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
802 0 : aRet <<= getFilter();
803 0 : else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
804 0 : aRet <<= getFilterOptions();
805 0 : else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
806 0 : aRet <<= getRefreshDelay();
807 0 : else if ( aNameString.equalsAscii( SC_UNONAME_REFDELAY ) )
808 0 : aRet <<= getRefreshDelay();
809 0 : return aRet;
810 : }
811 :
812 0 : SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj )
813 :
814 : // internal:
815 :
816 0 : OUString ScAreaLinkObj::getFileName(void) const
817 : {
818 0 : SolarMutexGuard aGuard;
819 0 : OUString aRet;
820 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
821 0 : if (pLink)
822 0 : aRet = pLink->GetFile();
823 0 : return aRet;
824 : }
825 :
826 0 : void ScAreaLinkObj::setFileName(const OUString& rNewName)
827 : {
828 0 : SolarMutexGuard aGuard;
829 0 : Modify_Impl( &rNewName, NULL, NULL, NULL, NULL );
830 0 : }
831 :
832 0 : OUString ScAreaLinkObj::getFilter(void) const
833 : {
834 0 : SolarMutexGuard aGuard;
835 0 : OUString aRet;
836 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
837 0 : if (pLink)
838 0 : aRet = pLink->GetFilter();
839 0 : return aRet;
840 : }
841 :
842 0 : void ScAreaLinkObj::setFilter(const OUString& Filter)
843 : {
844 0 : SolarMutexGuard aGuard;
845 0 : Modify_Impl( NULL, &Filter, NULL, NULL, NULL );
846 0 : }
847 :
848 0 : OUString ScAreaLinkObj::getFilterOptions(void) const
849 : {
850 0 : SolarMutexGuard aGuard;
851 0 : OUString aRet;
852 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
853 0 : if (pLink)
854 0 : aRet = pLink->GetOptions();
855 0 : return aRet;
856 : }
857 :
858 0 : void ScAreaLinkObj::setFilterOptions(const OUString& FilterOptions)
859 : {
860 0 : SolarMutexGuard aGuard;
861 0 : Modify_Impl( NULL, NULL, &FilterOptions, NULL, NULL );
862 0 : }
863 :
864 0 : sal_Int32 ScAreaLinkObj::getRefreshDelay(void) const
865 : {
866 0 : SolarMutexGuard aGuard;
867 0 : sal_Int32 nRet = 0;
868 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
869 0 : if (pLink)
870 0 : nRet = (sal_Int32) pLink->GetRefreshDelay();
871 0 : return nRet;
872 : }
873 :
874 0 : void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
875 : {
876 0 : SolarMutexGuard aGuard;
877 0 : ModifyRefreshDelay_Impl( nRefreshDelay );
878 0 : }
879 :
880 : // XAreaLink
881 :
882 0 : OUString SAL_CALL ScAreaLinkObj::getSourceArea() throw(uno::RuntimeException, std::exception)
883 : {
884 0 : SolarMutexGuard aGuard;
885 0 : OUString aRet;
886 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
887 0 : if (pLink)
888 0 : aRet = pLink->GetSource();
889 0 : return aRet;
890 : }
891 :
892 0 : void SAL_CALL ScAreaLinkObj::setSourceArea( const OUString& aSourceArea )
893 : throw(uno::RuntimeException, std::exception)
894 : {
895 0 : SolarMutexGuard aGuard;
896 0 : Modify_Impl( NULL, NULL, NULL, &aSourceArea, NULL );
897 0 : }
898 :
899 0 : table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() throw(uno::RuntimeException, std::exception)
900 : {
901 0 : SolarMutexGuard aGuard;
902 0 : table::CellRangeAddress aRet;
903 0 : ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
904 0 : if (pLink)
905 0 : ScUnoConversion::FillApiRange( aRet, pLink->GetDestArea() );
906 0 : return aRet;
907 : }
908 :
909 0 : void SAL_CALL ScAreaLinkObj::setDestArea( const table::CellRangeAddress& aDestArea )
910 : throw(uno::RuntimeException, std::exception)
911 : {
912 0 : SolarMutexGuard aGuard;
913 0 : Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea );
914 0 : }
915 :
916 0 : ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) :
917 0 : pDocShell( pDocSh )
918 : {
919 0 : pDocShell->GetDocument()->AddUnoObject(*this);
920 0 : }
921 :
922 0 : ScAreaLinksObj::~ScAreaLinksObj()
923 : {
924 0 : if (pDocShell)
925 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
926 0 : }
927 :
928 0 : void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
929 : {
930 : // Referenz-Update interessiert hier nicht
931 :
932 0 : if ( rHint.ISA( SfxSimpleHint ) &&
933 0 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
934 : {
935 0 : pDocShell = NULL; // ungueltig geworden
936 : }
937 0 : }
938 :
939 : // XAreaLinks
940 :
941 0 : ScAreaLinkObj* ScAreaLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
942 : {
943 0 : if ( pDocShell && nIndex >= 0 && nIndex < getCount() )
944 0 : return new ScAreaLinkObj( pDocShell, (size_t)nIndex );
945 :
946 0 : return NULL; // nicht gefunden
947 : }
948 :
949 0 : 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 0 : SolarMutexGuard aGuard;
957 0 : if (pDocShell)
958 : {
959 0 : OUString aFileStr (aFileName);
960 0 : OUString aFilterStr (aFilter);
961 0 : OUString aOptionStr (aFilterOptions);
962 0 : OUString aSourceStr (aSourceArea);
963 0 : ScAddress aDestAddr( (SCCOL)aDestPos.Column, (SCROW)aDestPos.Row, aDestPos.Sheet );
964 :
965 0 : aFileStr = ScGlobal::GetAbsDocName( aFileStr, pDocShell ); //! in InsertAreaLink ???
966 0 : pDocShell->GetDocFunc().InsertAreaLink( aFileStr, aFilterStr, aOptionStr,
967 : aSourceStr, ScRange(aDestAddr),
968 0 : 0, false, true ); // don't move contents
969 0 : }
970 0 : }
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 0 : uno::Reference<container::XEnumeration> SAL_CALL ScAreaLinksObj::createEnumeration()
988 : throw(uno::RuntimeException, std::exception)
989 : {
990 0 : SolarMutexGuard aGuard;
991 0 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.CellAreaLinksEnumeration"));
992 : }
993 :
994 : // XIndexAccess
995 :
996 0 : sal_Int32 SAL_CALL ScAreaLinksObj::getCount() throw(uno::RuntimeException, std::exception)
997 : {
998 0 : SolarMutexGuard aGuard;
999 0 : sal_Int32 nAreaCount = 0;
1000 0 : if (pDocShell)
1001 : {
1002 0 : sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
1003 0 : size_t nTotalCount = pLinkManager->GetLinks().size();
1004 0 : for (size_t i=0; i<nTotalCount; i++)
1005 : {
1006 0 : ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
1007 0 : if (pBase->ISA(ScAreaLink))
1008 0 : ++nAreaCount;
1009 : }
1010 : }
1011 0 : return nAreaCount;
1012 : }
1013 :
1014 0 : uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex )
1015 : throw(lang::IndexOutOfBoundsException,
1016 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
1017 : {
1018 0 : SolarMutexGuard aGuard;
1019 0 : uno::Reference<sheet::XAreaLink> xLink(GetObjectByIndex_Impl(nIndex));
1020 0 : if (xLink.is())
1021 0 : return uno::makeAny(xLink);
1022 : else
1023 0 : throw lang::IndexOutOfBoundsException();
1024 : }
1025 :
1026 0 : uno::Type SAL_CALL ScAreaLinksObj::getElementType() throw(uno::RuntimeException, std::exception)
1027 : {
1028 0 : SolarMutexGuard aGuard;
1029 0 : return getCppuType((uno::Reference<sheet::XAreaLink>*)0);
1030 : }
1031 :
1032 0 : sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException, std::exception)
1033 : {
1034 0 : SolarMutexGuard aGuard;
1035 0 : return ( getCount() != 0 );
1036 : }
1037 :
1038 0 : ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const OUString& rA,
1039 : const OUString& rT, const OUString& rI) :
1040 : pDocShell( pDocSh ),
1041 : aAppl( rA ),
1042 : aTopic( rT ),
1043 0 : aItem( rI )
1044 : {
1045 0 : pDocShell->GetDocument()->AddUnoObject(*this);
1046 0 : }
1047 :
1048 0 : ScDDELinkObj::~ScDDELinkObj()
1049 : {
1050 0 : if (pDocShell)
1051 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
1052 0 : }
1053 :
1054 0 : void ScDDELinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1055 : {
1056 : //! notify if links in document are changed
1057 : // UpdateRef is not needed here
1058 :
1059 0 : if ( rHint.ISA( SfxSimpleHint ) )
1060 : {
1061 0 : if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1062 0 : pDocShell = NULL; // pointer is invalid
1063 : }
1064 0 : else if ( rHint.ISA( ScLinkRefreshedHint ) )
1065 : {
1066 0 : const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
1067 0 : if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE &&
1068 0 : rLH.GetDdeAppl() == aAppl &&
1069 0 : rLH.GetDdeTopic() == aTopic &&
1070 0 : rLH.GetDdeItem() == aItem ) //! mode is ignored
1071 0 : Refreshed_Impl();
1072 : }
1073 0 : }
1074 :
1075 : // XNamed
1076 :
1077 0 : static OUString lcl_BuildDDEName( const OUString& rAppl, const OUString& rTopic, const OUString& rItem )
1078 : {
1079 : // Appl|Topic!Item (wie Excel)
1080 0 : OUString aRet = rAppl + "|" + rTopic + "!" + rItem;
1081 0 : return aRet;
1082 : }
1083 :
1084 0 : OUString SAL_CALL ScDDELinkObj::getName() throw(uno::RuntimeException, std::exception)
1085 : {
1086 0 : SolarMutexGuard aGuard;
1087 0 : 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 0 : OUString SAL_CALL ScDDELinkObj::getApplication() throw(uno::RuntimeException, std::exception)
1099 : {
1100 0 : SolarMutexGuard aGuard;
1101 : //! Test, ob Link noch im Dokument enthalten?
1102 :
1103 0 : return aAppl;
1104 : }
1105 :
1106 0 : OUString SAL_CALL ScDDELinkObj::getTopic() throw(uno::RuntimeException, std::exception)
1107 : {
1108 0 : SolarMutexGuard aGuard;
1109 : //! Test, ob Link noch im Dokument enthalten?
1110 :
1111 0 : return aTopic;
1112 : }
1113 :
1114 0 : OUString SAL_CALL ScDDELinkObj::getItem() throw(uno::RuntimeException, std::exception)
1115 : {
1116 0 : SolarMutexGuard aGuard;
1117 : //! Test, ob Link noch im Dokument enthalten?
1118 :
1119 0 : return aItem;
1120 : }
1121 :
1122 : // XRefreshable
1123 :
1124 0 : void SAL_CALL ScDDELinkObj::refresh() throw(uno::RuntimeException, std::exception)
1125 : {
1126 0 : SolarMutexGuard aGuard;
1127 0 : if (pDocShell)
1128 : {
1129 0 : sc::DocumentLinkManager& rMgr = pDocShell->GetDocument()->GetDocLinkManager();
1130 0 : rMgr.updateDdeLink(aAppl, aTopic, aItem);
1131 0 : }
1132 0 : }
1133 :
1134 0 : void SAL_CALL ScDDELinkObj::addRefreshListener(
1135 : const uno::Reference<util::XRefreshListener >& xListener )
1136 : throw (uno::RuntimeException, std::exception)
1137 : {
1138 0 : SolarMutexGuard aGuard;
1139 : uno::Reference<util::XRefreshListener>* pObj =
1140 0 : new uno::Reference<util::XRefreshListener>( xListener );
1141 0 : aRefreshListeners.push_back( pObj );
1142 :
1143 : // hold one additional ref to keep this object alive as long as there are listeners
1144 0 : if ( aRefreshListeners.size() == 1 )
1145 0 : acquire();
1146 0 : }
1147 :
1148 0 : void SAL_CALL ScDDELinkObj::removeRefreshListener(
1149 : const uno::Reference<util::XRefreshListener >& xListener )
1150 : throw(uno::RuntimeException, std::exception)
1151 : {
1152 0 : SolarMutexGuard aGuard;
1153 0 : size_t nCount = aRefreshListeners.size();
1154 0 : for ( size_t n=nCount; n--; )
1155 : {
1156 0 : uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
1157 0 : if ( rObj == xListener )
1158 : {
1159 0 : aRefreshListeners.erase( aRefreshListeners.begin() + n );
1160 0 : if ( aRefreshListeners.empty() )
1161 0 : release(); // release ref for listeners
1162 0 : break;
1163 : }
1164 0 : }
1165 0 : }
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 0 : void ScDDELinkObj::Refreshed_Impl()
1239 : {
1240 0 : lang::EventObject aEvent;
1241 0 : aEvent.Source.set((cppu::OWeakObject*)this);
1242 0 : for ( size_t n=0; n<aRefreshListeners.size(); n++ )
1243 0 : aRefreshListeners[n]->refreshed( aEvent );
1244 0 : }
1245 :
1246 0 : ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) :
1247 0 : pDocShell( pDocSh )
1248 : {
1249 0 : pDocShell->GetDocument()->AddUnoObject(*this);
1250 0 : }
1251 :
1252 0 : ScDDELinksObj::~ScDDELinksObj()
1253 : {
1254 0 : if (pDocShell)
1255 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
1256 0 : }
1257 :
1258 0 : void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1259 : {
1260 : // Referenz-Update interessiert hier nicht
1261 :
1262 0 : if ( rHint.ISA( SfxSimpleHint ) &&
1263 0 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1264 : {
1265 0 : pDocShell = NULL; // ungueltig geworden
1266 : }
1267 0 : }
1268 :
1269 : // XDDELinks
1270 :
1271 0 : ScDDELinkObj* ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
1272 : {
1273 0 : if (pDocShell)
1274 : {
1275 0 : OUString aAppl, aTopic, aItem;
1276 0 : if ( pDocShell->GetDocument()->GetDdeLinkData( (size_t)nIndex, aAppl, aTopic, aItem ) )
1277 0 : return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1278 : }
1279 0 : return NULL;
1280 : }
1281 :
1282 0 : ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const OUString& aName)
1283 : {
1284 0 : if (pDocShell)
1285 : {
1286 0 : OUString aNamStr(aName);
1287 0 : OUString aAppl, aTopic, aItem;
1288 :
1289 0 : ScDocument* pDoc = pDocShell->GetDocument();
1290 0 : size_t nCount = pDoc->GetDocLinkManager().getDdeLinkCount();
1291 0 : for (size_t i=0; i<nCount; i++)
1292 : {
1293 0 : pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1294 0 : if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1295 0 : return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1296 0 : }
1297 : }
1298 0 : return NULL;
1299 : }
1300 :
1301 : // XEnumerationAccess
1302 :
1303 0 : uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration()
1304 : throw(uno::RuntimeException, std::exception)
1305 : {
1306 0 : SolarMutexGuard aGuard;
1307 0 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DDELinksEnumeration"));
1308 : }
1309 :
1310 : // XIndexAccess
1311 :
1312 0 : sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException, std::exception)
1313 : {
1314 0 : SolarMutexGuard aGuard;
1315 0 : sal_Int32 nAreaCount = 0;
1316 0 : if (pDocShell)
1317 0 : nAreaCount = pDocShell->GetDocument()->GetDocLinkManager().getDdeLinkCount();
1318 0 : return nAreaCount;
1319 : }
1320 :
1321 0 : uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex )
1322 : throw(lang::IndexOutOfBoundsException,
1323 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
1324 : {
1325 0 : SolarMutexGuard aGuard;
1326 0 : uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex));
1327 0 : if (xLink.is())
1328 0 : return uno::makeAny(xLink);
1329 : else
1330 0 : throw lang::IndexOutOfBoundsException();
1331 : }
1332 :
1333 0 : uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException, std::exception)
1334 : {
1335 0 : SolarMutexGuard aGuard;
1336 0 : return getCppuType((uno::Reference<sheet::XDDELink>*)0);
1337 : }
1338 :
1339 0 : sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException, std::exception)
1340 : {
1341 0 : SolarMutexGuard aGuard;
1342 0 : return ( getCount() != 0 );
1343 : }
1344 :
1345 0 : uno::Any SAL_CALL ScDDELinksObj::getByName( const OUString& aName )
1346 : throw(container::NoSuchElementException,
1347 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
1348 : {
1349 0 : SolarMutexGuard aGuard;
1350 0 : uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName));
1351 0 : if (xLink.is())
1352 0 : return uno::makeAny(xLink);
1353 : else
1354 0 : throw container::NoSuchElementException();
1355 : }
1356 :
1357 0 : uno::Sequence<OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException, std::exception)
1358 : {
1359 0 : SolarMutexGuard aGuard;
1360 0 : if (pDocShell)
1361 : {
1362 0 : OUString aAppl, aTopic, aItem;
1363 :
1364 0 : ScDocument* pDoc = pDocShell->GetDocument();
1365 0 : size_t nCount = pDocShell->GetDocument()->GetDocLinkManager().getDdeLinkCount();
1366 0 : uno::Sequence<OUString> aSeq(nCount);
1367 0 : OUString* pAry = aSeq.getArray();
1368 :
1369 0 : for (size_t i=0; i<nCount; i++)
1370 : {
1371 0 : pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1372 0 : pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem);
1373 : }
1374 0 : return aSeq;
1375 : }
1376 0 : return uno::Sequence<OUString>();
1377 : }
1378 :
1379 0 : sal_Bool SAL_CALL ScDDELinksObj::hasByName( const OUString& aName )
1380 : throw(uno::RuntimeException, std::exception)
1381 : {
1382 0 : SolarMutexGuard aGuard;
1383 0 : if (pDocShell)
1384 : {
1385 0 : OUString aNamStr(aName);
1386 0 : OUString aAppl, aTopic, aItem;
1387 :
1388 0 : ScDocument* pDoc = pDocShell->GetDocument();
1389 0 : size_t nCount = pDocShell->GetDocument()->GetDocLinkManager().getDdeLinkCount();
1390 0 : for (size_t i=0; i<nCount; i++)
1391 : {
1392 0 : pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1393 0 : if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1394 0 : return sal_True;
1395 0 : }
1396 : }
1397 0 : 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 0 : ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScDocShell* pDocShell, ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
1458 : mpDocShell(pDocShell),
1459 : mpTable(pTable),
1460 0 : mnIndex(nIndex)
1461 : {
1462 0 : }
1463 :
1464 0 : ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
1465 : {
1466 0 : }
1467 :
1468 0 : void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue)
1469 : throw (IllegalArgumentException, RuntimeException, std::exception)
1470 : {
1471 0 : SolarMutexGuard aGuard;
1472 0 : if (nRow < 0 || nCol < 0)
1473 0 : throw IllegalArgumentException();
1474 :
1475 0 : ScExternalRefCache::TokenRef pToken;
1476 0 : double fVal = 0.0;
1477 0 : OUString aVal;
1478 0 : if (rValue >>= fVal)
1479 0 : pToken.reset(new FormulaDoubleToken(fVal));
1480 0 : else if (rValue >>= aVal)
1481 : {
1482 0 : svl::SharedStringPool& rPool = mpDocShell->GetDocument()->GetSharedStringPool();
1483 0 : svl::SharedString aSS = rPool.intern(aVal);
1484 0 : pToken.reset(new FormulaStringToken(aSS));
1485 : }
1486 : else
1487 : // unidentified value type.
1488 0 : return;
1489 :
1490 0 : 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 0 : sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
1557 : throw (RuntimeException, std::exception)
1558 : {
1559 0 : return static_cast< sal_Int32 >( mnIndex );
1560 : }
1561 :
1562 0 : ScExternalDocLinkObj::ScExternalDocLinkObj(ScDocShell* pDocShell, ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
1563 0 : mpDocShell(pDocShell), mpRefMgr(pRefMgr), mnFileId(nFileId)
1564 : {
1565 0 : }
1566 :
1567 0 : ScExternalDocLinkObj::~ScExternalDocLinkObj()
1568 : {
1569 0 : }
1570 :
1571 0 : Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache(
1572 : const OUString& aSheetName, sal_Bool bDynamicCache )
1573 : throw (RuntimeException, std::exception)
1574 : {
1575 0 : SolarMutexGuard aGuard;
1576 0 : size_t nIndex = 0;
1577 0 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
1578 0 : if (!bDynamicCache)
1579 : // Set the whole table cached to prevent access to the source document.
1580 0 : pTable->setWholeTableCached();
1581 :
1582 0 : Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
1583 0 : 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 0 : Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
1603 : throw (RuntimeException, std::exception)
1604 : {
1605 0 : SolarMutexGuard aGuard;
1606 0 : vector<OUString> aTabNames;
1607 0 : mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
1608 :
1609 : // #i116940# be consistent with getByName: include only table names which have a cache already
1610 0 : vector<OUString> aValidNames;
1611 0 : for (vector<OUString>::iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter)
1612 0 : if (mpRefMgr->getCacheTable(mnFileId, *aIter, false))
1613 0 : aValidNames.push_back(*aIter);
1614 :
1615 0 : size_t n = aValidNames.size();
1616 0 : Sequence<OUString> aSeq(n);
1617 0 : for (size_t i = 0; i < n; ++i)
1618 0 : aSeq[i] = aValidNames[i];
1619 0 : 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 0 : Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex)
1642 : throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException, std::exception)
1643 : {
1644 0 : 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 0 : Sequence< OUString > aNames( getElementNames() );
1649 0 : if (nApiIndex < 0 || nApiIndex >= aNames.getLength())
1650 0 : throw lang::IndexOutOfBoundsException();
1651 :
1652 0 : size_t nIndex = 0;
1653 0 : ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex);
1654 0 : if (!pTable)
1655 0 : throw lang::IndexOutOfBoundsException();
1656 :
1657 0 : Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
1658 :
1659 0 : Any aAny;
1660 0 : aAny <<= aSheetCache;
1661 0 : 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 0 : ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
1697 : mpDocShell(pDocShell),
1698 0 : mpRefMgr(pDocShell->GetDocument()->GetExternalRefManager())
1699 : {
1700 0 : }
1701 :
1702 0 : ScExternalDocLinksObj::~ScExternalDocLinksObj()
1703 : {
1704 0 : }
1705 :
1706 0 : Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink(
1707 : const OUString& aDocName )
1708 : throw (RuntimeException, std::exception)
1709 : {
1710 0 : SolarMutexGuard aGuard;
1711 0 : sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocName);
1712 0 : Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId));
1713 0 : 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: */
|