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