bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / unoobj / linkuno.cxx
blob3cff46ba828756e0dcff953b556c944e6157ac7d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svl/smplhint.hxx>
21 #include <sfx2/linkmgr.hxx>
22 #include <vcl/svapp.hxx>
24 #include "linkuno.hxx"
25 #include "miscuno.hxx"
26 #include "convuno.hxx"
27 #include "docsh.hxx"
28 #include "docfunc.hxx"
29 #include "tablink.hxx"
30 #include "arealink.hxx"
31 #include "hints.hxx"
32 #include "unonames.hxx"
33 #include "rangeseq.hxx"
34 #include "token.hxx"
36 #include <vector>
37 #include <climits>
39 using namespace com::sun::star;
40 using namespace formula;
41 using ::com::sun::star::uno::Any;
42 using ::com::sun::star::uno::Reference;
43 using ::com::sun::star::uno::Sequence;
44 using ::com::sun::star::uno::UNO_QUERY;
45 using ::com::sun::star::uno::UNO_QUERY_THROW;
46 using ::com::sun::star::lang::IllegalArgumentException;
47 using ::com::sun::star::uno::RuntimeException;
48 using ::std::vector;
50 //------------------------------------------------------------------------
52 // fuer Sheet- und Area-Links benutzt:
53 static const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap()
55 static SfxItemPropertyMapEntry aSheetLinkMap_Impl[] =
57 {MAP_CHAR_LEN(SC_UNONAME_FILTER), 0, &getCppuType((OUString*)0), 0, 0 },
58 {MAP_CHAR_LEN(SC_UNONAME_FILTOPT), 0, &getCppuType((OUString*)0), 0, 0 },
59 {MAP_CHAR_LEN(SC_UNONAME_LINKURL), 0, &getCppuType((OUString*)0), 0, 0 },
60 {MAP_CHAR_LEN(SC_UNONAME_REFDELAY), 0, &getCppuType((sal_Int32*)0), 0, 0 },
61 {MAP_CHAR_LEN(SC_UNONAME_REFPERIOD), 0, &getCppuType((sal_Int32*)0), 0, 0 },
62 {0,0,0,0,0,0}
64 return aSheetLinkMap_Impl;
67 //------------------------------------------------------------------------
69 SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj, "ScAreaLinkObj", "com.sun.star.sheet.CellAreaLink" )
70 SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj, "ScAreaLinksObj", "com.sun.star.sheet.CellAreaLinks" )
71 SC_SIMPLE_SERVICE_INFO( ScDDELinkObj, "ScDDELinkObj", "com.sun.star.sheet.DDELink" )
72 SC_SIMPLE_SERVICE_INFO( ScDDELinksObj, "ScDDELinksObj", "com.sun.star.sheet.DDELinks" )
73 SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj, "ScSheetLinkObj", "com.sun.star.sheet.SheetLink" )
74 SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj, "ScSheetLinksObj", "com.sun.star.sheet.SheetLinks" )
76 //------------------------------------------------------------------------
78 ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const String& rName) :
79 aPropSet( lcl_GetSheetLinkMap() ),
80 pDocShell( pDocSh ),
81 aFileName( rName )
83 pDocShell->GetDocument()->AddUnoObject(*this);
86 ScSheetLinkObj::~ScSheetLinkObj()
88 if (pDocShell)
89 pDocShell->GetDocument()->RemoveUnoObject(*this);
92 void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
94 //! notify if links in document are changed
95 // UpdateRef is not needed here
97 if ( rHint.ISA( SfxSimpleHint ) )
99 if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
100 pDocShell = NULL; // pointer is invalid
102 else if ( rHint.ISA( ScLinkRefreshedHint ) )
104 const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
105 if ( rLH.GetLinkType() == SC_LINKREFTYPE_SHEET && rLH.GetUrl() == aFileName )
106 Refreshed_Impl();
110 ScTableLink* ScSheetLinkObj::GetLink_Impl() const
112 if (pDocShell)
114 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
115 sal_uInt16 nCount = pLinkManager->GetLinks().size();
116 for (sal_uInt16 i=0; i<nCount; i++)
118 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
119 if (pBase->ISA(ScTableLink))
121 ScTableLink* pTabLink = (ScTableLink*)pBase;
122 if ( pTabLink->GetFileName().equals(aFileName) )
123 return pTabLink;
127 return NULL; // nicht gefunden
130 // XNamed
132 OUString SAL_CALL ScSheetLinkObj::getName() throw(uno::RuntimeException)
134 SolarMutexGuard aGuard;
135 return getFileName(); // Name ist der Dateiname (URL)
138 void SAL_CALL ScSheetLinkObj::setName( const OUString& aName ) throw(uno::RuntimeException)
140 SolarMutexGuard aGuard;
141 setFileName(aName); // Name ist der Dateiname (URL)
144 // XRefreshable
146 void SAL_CALL ScSheetLinkObj::refresh() throw(uno::RuntimeException)
148 SolarMutexGuard aGuard;
149 ScTableLink* pLink = GetLink_Impl();
150 if (pLink)
151 pLink->Refresh( pLink->GetFileName(), pLink->GetFilterName(), NULL, pLink->GetRefreshDelay() );
154 void SAL_CALL ScSheetLinkObj::addRefreshListener(
155 const uno::Reference<util::XRefreshListener >& xListener )
156 throw(uno::RuntimeException)
158 SolarMutexGuard aGuard;
159 uno::Reference<util::XRefreshListener>* pObj =
160 new uno::Reference<util::XRefreshListener>( xListener );
161 aRefreshListeners.push_back( pObj );
163 // hold one additional ref to keep this object alive as long as there are listeners
164 if ( aRefreshListeners.size() == 1 )
165 acquire();
168 void SAL_CALL ScSheetLinkObj::removeRefreshListener(
169 const uno::Reference<util::XRefreshListener >& xListener )
170 throw(uno::RuntimeException)
172 SolarMutexGuard aGuard;
173 sal_uInt16 nCount = aRefreshListeners.size();
174 for ( sal_uInt16 n=nCount; n--; )
176 uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
177 if ( rObj == xListener )
179 aRefreshListeners.erase( aRefreshListeners.begin() + n );
180 if ( aRefreshListeners.empty() )
181 release(); // release ref for listeners
182 break;
187 void ScSheetLinkObj::Refreshed_Impl()
189 lang::EventObject aEvent;
190 aEvent.Source.set((cppu::OWeakObject*)this);
191 for ( sal_uInt16 n=0; n<aRefreshListeners.size(); n++ )
192 aRefreshListeners[n]->refreshed( aEvent );
195 void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
197 ScTableLink* pLink = GetLink_Impl();
198 if( pLink )
199 pLink->SetRefreshDelay( (sal_uLong) nRefresh );
202 // XPropertySet
204 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSheetLinkObj::getPropertySetInfo()
205 throw(uno::RuntimeException)
207 SolarMutexGuard aGuard;
208 static uno::Reference<beans::XPropertySetInfo> aRef(
209 new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
210 return aRef;
213 void SAL_CALL ScSheetLinkObj::setPropertyValue(
214 const OUString& aPropertyName, const uno::Any& aValue )
215 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
216 lang::IllegalArgumentException, lang::WrappedTargetException,
217 uno::RuntimeException)
219 SolarMutexGuard aGuard;
220 String aNameString(aPropertyName);
221 OUString aValStr;
222 if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
224 if ( aValue >>= aValStr )
225 setFileName( aValStr );
227 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
229 if ( aValue >>= aValStr )
230 setFilter( aValStr );
232 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
234 if ( aValue >>= aValStr )
235 setFilterOptions( aValStr );
237 else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
239 sal_Int32 nRefresh = 0;
240 if ( aValue >>= nRefresh )
241 setRefreshDelay( nRefresh );
243 else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
245 sal_Int32 nRefresh = 0;
246 if ( aValue >>= nRefresh )
247 setRefreshDelay( nRefresh );
251 uno::Any SAL_CALL ScSheetLinkObj::getPropertyValue( const OUString& aPropertyName )
252 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
253 uno::RuntimeException)
255 SolarMutexGuard aGuard;
256 String aNameString(aPropertyName);
257 uno::Any aRet;
258 if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
259 aRet <<= getFileName();
260 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
261 aRet <<= getFilter();
262 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
263 aRet <<= getFilterOptions();
264 else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
265 aRet <<= getRefreshDelay();
266 else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
267 aRet <<= getRefreshDelay();
268 return aRet;
271 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj )
273 // internal:
275 OUString ScSheetLinkObj::getFileName(void) const
277 SolarMutexGuard aGuard;
278 return aFileName;
281 void ScSheetLinkObj::setFileName(const OUString& rNewName)
283 SolarMutexGuard aGuard;
284 ScTableLink* pLink = GetLink_Impl();
285 if (pLink)
287 // pLink->Refresh mit neuem Dateinamen bringt sfx2::LinkManager durcheinander
288 // darum per Hand die Tabellen umsetzen und Link per UpdateLinks neu erzeugen
290 String aNewStr(ScGlobal::GetAbsDocName( String(rNewName), pDocShell ));
292 // zuerst Tabellen umsetzen
294 ScDocument* pDoc = pDocShell->GetDocument();
295 SCTAB nTabCount = pDoc->GetTableCount();
296 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
297 if ( pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab) == OUString(aFileName) ) // alte Datei
298 pDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), aNewStr,
299 pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
300 pDoc->GetLinkTab(nTab),
301 pDoc->GetLinkRefreshDelay(nTab) ); // nur Datei aendern
303 // Links updaten
304 //! Undo !!!
306 pLink = NULL; // wird bei UpdateLinks ungueltig
307 pDocShell->UpdateLinks(); // alter Link raus, evtl. neuen Link anlegen
309 // Daten kopieren
311 aFileName = aNewStr;
312 pLink = GetLink_Impl(); // neuer Link mit neuem Namen
313 if (pLink)
314 pLink->Update(); // inkl. Paint & Undo fuer Daten
318 OUString ScSheetLinkObj::getFilter(void) const
320 SolarMutexGuard aGuard;
321 OUString aRet;
322 ScTableLink* pLink = GetLink_Impl();
323 if (pLink)
324 aRet = pLink->GetFilterName();
325 return aRet;
328 void ScSheetLinkObj::setFilter(const OUString& Filter)
330 SolarMutexGuard aGuard;
331 ScTableLink* pLink = GetLink_Impl();
332 if (pLink)
334 String aFilterStr(Filter);
335 pLink->Refresh( aFileName, aFilterStr, NULL, pLink->GetRefreshDelay() );
339 OUString ScSheetLinkObj::getFilterOptions(void) const
341 SolarMutexGuard aGuard;
342 OUString aRet;
343 ScTableLink* pLink = GetLink_Impl();
344 if (pLink)
345 aRet = pLink->GetOptions();
346 return aRet;
349 void ScSheetLinkObj::setFilterOptions(const OUString& FilterOptions)
351 SolarMutexGuard aGuard;
352 ScTableLink* pLink = GetLink_Impl();
353 if (pLink)
355 String aOptStr(FilterOptions);
356 pLink->Refresh( aFileName, pLink->GetFilterName(), &aOptStr, pLink->GetRefreshDelay() );
360 sal_Int32 ScSheetLinkObj::getRefreshDelay(void) const
362 SolarMutexGuard aGuard;
363 sal_Int32 nRet = 0;
364 ScTableLink* pLink = GetLink_Impl();
365 if (pLink)
366 nRet = (sal_Int32) pLink->GetRefreshDelay();
367 return nRet;
370 void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
372 SolarMutexGuard aGuard;
373 ModifyRefreshDelay_Impl( nRefreshDelay );
376 //------------------------------------------------------------------------
378 ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) :
379 pDocShell( pDocSh )
381 pDocShell->GetDocument()->AddUnoObject(*this);
384 ScSheetLinksObj::~ScSheetLinksObj()
386 if (pDocShell)
387 pDocShell->GetDocument()->RemoveUnoObject(*this);
390 void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
392 // Referenz-Update interessiert hier nicht
394 if ( rHint.ISA( SfxSimpleHint ) &&
395 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
397 pDocShell = NULL; // ungueltig geworden
401 // XSheetLinks
403 ScSheetLinkObj* ScSheetLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
405 if (!pDocShell)
406 return NULL;
408 typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
409 StrSetType aNames;
410 ScDocument* pDoc = pDocShell->GetDocument();
411 SCTAB nTabCount = pDoc->GetTableCount();
412 sal_Int32 nCount = 0;
413 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
415 if (!pDoc->IsLinked(nTab))
416 continue;
418 OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
419 if (aNames.insert(aLinkDoc).second)
421 // unique document name.
422 if (nCount == nIndex)
423 return new ScSheetLinkObj( pDocShell, aLinkDoc );
424 ++nCount;
428 return NULL; // kein Dokument oder Index zu gross
431 ScSheetLinkObj* ScSheetLinksObj::GetObjectByName_Impl(const OUString& aName)
433 // Name ist der Dateiname
435 if (pDocShell)
437 String aNameStr(aName);
439 ScDocument* pDoc = pDocShell->GetDocument();
440 SCTAB nTabCount = pDoc->GetTableCount();
441 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
442 if (pDoc->IsLinked(nTab))
444 //! case-insensitiv ???
445 String aLinkDoc = pDoc->GetLinkDoc( nTab );
446 if ( aLinkDoc == aNameStr )
447 return new ScSheetLinkObj( pDocShell, aNameStr );
451 return NULL;
454 // XEnumerationAccess
456 uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration()
457 throw(uno::RuntimeException)
459 SolarMutexGuard aGuard;
460 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.SheetLinksEnumeration"));
463 // XIndexAccess
465 sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException)
467 typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
469 SolarMutexGuard aGuard;
470 if (!pDocShell)
471 return 0;
473 sal_Int32 nCount = 0;
475 StrSetType aNames;
476 ScDocument* pDoc = pDocShell->GetDocument();
477 SCTAB nTabCount = pDoc->GetTableCount();
478 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
480 if (!pDoc->IsLinked(nTab))
481 continue;
483 OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
484 if (aNames.insert(aLinkDoc).second)
485 ++nCount;
487 return nCount;
490 uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex )
491 throw(lang::IndexOutOfBoundsException,
492 lang::WrappedTargetException, uno::RuntimeException)
494 SolarMutexGuard aGuard;
495 uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex));
496 if (xLink.is())
497 return uno::makeAny(xLink);
498 else
499 throw lang::IndexOutOfBoundsException();
502 uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException)
504 SolarMutexGuard aGuard;
505 return getCppuType((uno::Reference<beans::XPropertySet>*)0);
508 sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException)
510 SolarMutexGuard aGuard;
511 return ( getCount() != 0 );
514 uno::Any SAL_CALL ScSheetLinksObj::getByName( const OUString& aName )
515 throw(container::NoSuchElementException,
516 lang::WrappedTargetException, uno::RuntimeException)
518 SolarMutexGuard aGuard;
519 uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName));
520 if (xLink.is())
521 return uno::makeAny(xLink);
522 else
523 throw container::NoSuchElementException();
524 // return uno::Any();
527 sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const OUString& aName )
528 throw(uno::RuntimeException)
530 SolarMutexGuard aGuard;
531 // Name ist der Dateiname
533 if (pDocShell)
535 String aNameStr(aName);
537 ScDocument* pDoc = pDocShell->GetDocument();
538 SCTAB nTabCount = pDoc->GetTableCount();
539 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
540 if (pDoc->IsLinked(nTab))
542 //! case-insensitiv ???
543 String aLinkDoc(pDoc->GetLinkDoc( nTab ));
544 if ( aLinkDoc == aNameStr )
545 return sal_True;
548 return false;
551 uno::Sequence<OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException)
553 typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
555 SolarMutexGuard aGuard;
556 // Name ist der Dateiname
558 if (!pDocShell)
559 return uno::Sequence<OUString>();
561 StrSetType aNames;
562 ScDocument* pDoc = pDocShell->GetDocument();
563 SCTAB nTabCount = pDoc->GetTableCount();
565 sal_Int32 nLinkCount = getCount();
566 uno::Sequence<OUString> aSeq(nLinkCount);
567 OUString* pAry = aSeq.getArray();
568 sal_uInt16 nPos = 0;
569 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
571 if (!pDoc->IsLinked(nTab))
572 continue;
574 OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
575 if (aNames.insert(aLinkDoc).second)
576 pAry[nPos++] = aLinkDoc;
578 OSL_ENSURE( nPos==nLinkCount, "verzaehlt" );
579 return aSeq;
582 //------------------------------------------------------------------------
584 static ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, sal_uInt16 nPos )
586 if (pDocShell)
588 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
589 sal_uInt16 nTotalCount = pLinkManager->GetLinks().size();
590 sal_uInt16 nAreaCount = 0;
591 for (sal_uInt16 i=0; i<nTotalCount; i++)
593 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
594 if (pBase->ISA(ScAreaLink))
596 if ( nAreaCount == nPos )
597 return (ScAreaLink*)pBase;
598 ++nAreaCount;
602 return NULL; // nicht gefunden
605 ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, sal_uInt16 nP) :
606 aPropSet( lcl_GetSheetLinkMap() ),
607 pDocShell( pDocSh ),
608 nPos( nP )
610 pDocShell->GetDocument()->AddUnoObject(*this);
613 ScAreaLinkObj::~ScAreaLinkObj()
615 if (pDocShell)
616 pDocShell->GetDocument()->RemoveUnoObject(*this);
619 void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
621 //! notify if links in document are changed
622 // UpdateRef is not needed here
624 if ( rHint.ISA( SfxSimpleHint ) )
626 if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
627 pDocShell = NULL; // pointer is invalid
629 else if ( rHint.ISA( ScLinkRefreshedHint ) )
631 const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
632 if ( rLH.GetLinkType() == SC_LINKREFTYPE_AREA )
634 // get this link to compare dest position
635 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
636 if ( pLink && pLink->GetDestArea().aStart == rLH.GetDestPos() )
637 Refreshed_Impl();
642 // XFileLink
644 void ScAreaLinkObj::Modify_Impl( const OUString* pNewFile, const OUString* pNewFilter,
645 const OUString* pNewOptions, const OUString* pNewSource,
646 const table::CellRangeAddress* pNewDest )
648 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
649 if (pLink)
651 String aFile (pLink->GetFile());
652 String aFilter (pLink->GetFilter());
653 String aOptions (pLink->GetOptions());
654 String aSource (pLink->GetSource());
655 ScRange aDest (pLink->GetDestArea());
656 sal_uLong nRefresh = pLink->GetRefreshDelay();
658 //! Undo fuer Loeschen
659 //! Undo zusammenfassen
661 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
662 pLinkManager->Remove( pLink );
663 pLink = NULL; // bei Remove geloescht
665 sal_Bool bFitBlock = sal_True; // verschieben, wenn durch Update Groesse geaendert
666 if (pNewFile)
668 aFile = String( *pNewFile );
669 aFile = ScGlobal::GetAbsDocName( aFile, pDocShell ); //! in InsertAreaLink?
671 if (pNewFilter)
672 aFilter = String( *pNewFilter );
673 if (pNewOptions)
674 aOptions = String( *pNewOptions );
675 if (pNewSource)
676 aSource = String( *pNewSource );
677 if (pNewDest)
679 ScUnoConversion::FillScRange( aDest, *pNewDest );
680 bFitBlock = false; // neuer Bereich angegeben -> keine Inhalte verschieben
682 pDocShell->GetDocFunc().InsertAreaLink( aFile, aFilter, aOptions, aSource,
683 aDest, nRefresh, bFitBlock, sal_True );
687 void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
689 ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos );
690 if( pLink )
691 pLink->SetRefreshDelay( (sal_uLong) nRefresh );
694 // XRefreshable
696 void SAL_CALL ScAreaLinkObj::refresh() throw(uno::RuntimeException)
698 SolarMutexGuard aGuard;
699 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
700 if (pLink)
701 pLink->Refresh( pLink->GetFile(), pLink->GetFilter(), pLink->GetSource(), pLink->GetRefreshDelay() );
704 void SAL_CALL ScAreaLinkObj::addRefreshListener(
705 const uno::Reference<util::XRefreshListener >& xListener )
706 throw(uno::RuntimeException)
708 SolarMutexGuard aGuard;
709 uno::Reference<util::XRefreshListener>* pObj =
710 new uno::Reference<util::XRefreshListener>( xListener );
711 aRefreshListeners.push_back( pObj );
713 // hold one additional ref to keep this object alive as long as there are listeners
714 if ( aRefreshListeners.size() == 1 )
715 acquire();
718 void SAL_CALL ScAreaLinkObj::removeRefreshListener(
719 const uno::Reference<util::XRefreshListener >& xListener )
720 throw(uno::RuntimeException)
722 SolarMutexGuard aGuard;
723 sal_uInt16 nCount = aRefreshListeners.size();
724 for ( sal_uInt16 n=nCount; n--; )
726 uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
727 if ( rObj == xListener )
729 aRefreshListeners.erase( aRefreshListeners.begin() + n );
730 if ( aRefreshListeners.empty() )
731 release(); // release ref for listeners
732 break;
737 void ScAreaLinkObj::Refreshed_Impl()
739 lang::EventObject aEvent;
740 aEvent.Source.set((cppu::OWeakObject*)this);
741 for ( sal_uInt16 n=0; n<aRefreshListeners.size(); n++ )
742 aRefreshListeners[n]->refreshed( aEvent );
745 // XPropertySet
747 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAreaLinkObj::getPropertySetInfo()
748 throw(uno::RuntimeException)
750 SolarMutexGuard aGuard;
751 static uno::Reference<beans::XPropertySetInfo> aRef(
752 new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
753 return aRef;
756 void SAL_CALL ScAreaLinkObj::setPropertyValue(
757 const OUString& aPropertyName, const uno::Any& aValue )
758 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
759 lang::IllegalArgumentException, lang::WrappedTargetException,
760 uno::RuntimeException)
762 SolarMutexGuard aGuard;
763 String aNameString(aPropertyName);
764 OUString aValStr;
765 if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
767 if ( aValue >>= aValStr )
768 setFileName( aValStr );
770 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
772 if ( aValue >>= aValStr )
773 setFilter( aValStr );
775 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
777 if ( aValue >>= aValStr )
778 setFilterOptions( aValStr );
780 else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
782 sal_Int32 nRefresh = 0;
783 if ( aValue >>= nRefresh )
784 setRefreshDelay( nRefresh );
786 else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
788 sal_Int32 nRefresh = 0;
789 if ( aValue >>= nRefresh )
790 setRefreshDelay( nRefresh );
794 uno::Any SAL_CALL ScAreaLinkObj::getPropertyValue( const OUString& aPropertyName )
795 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
796 uno::RuntimeException)
798 SolarMutexGuard aGuard;
799 String aNameString(aPropertyName);
800 uno::Any aRet;
801 if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
802 aRet <<= getFileName();
803 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
804 aRet <<= getFilter();
805 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
806 aRet <<= getFilterOptions();
807 else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
808 aRet <<= getRefreshDelay();
809 else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
810 aRet <<= getRefreshDelay();
811 return aRet;
814 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj )
816 // internal:
818 OUString ScAreaLinkObj::getFileName(void) const
820 SolarMutexGuard aGuard;
821 OUString aRet;
822 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
823 if (pLink)
824 aRet = pLink->GetFile();
825 return aRet;
828 void ScAreaLinkObj::setFileName(const OUString& rNewName)
830 SolarMutexGuard aGuard;
831 Modify_Impl( &rNewName, NULL, NULL, NULL, NULL );
834 OUString ScAreaLinkObj::getFilter(void) const
836 SolarMutexGuard aGuard;
837 OUString aRet;
838 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
839 if (pLink)
840 aRet = pLink->GetFilter();
841 return aRet;
844 void ScAreaLinkObj::setFilter(const OUString& Filter)
846 SolarMutexGuard aGuard;
847 Modify_Impl( NULL, &Filter, NULL, NULL, NULL );
850 OUString ScAreaLinkObj::getFilterOptions(void) const
852 SolarMutexGuard aGuard;
853 OUString aRet;
854 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
855 if (pLink)
856 aRet = pLink->GetOptions();
857 return aRet;
860 void ScAreaLinkObj::setFilterOptions(const OUString& FilterOptions)
862 SolarMutexGuard aGuard;
863 Modify_Impl( NULL, NULL, &FilterOptions, NULL, NULL );
866 sal_Int32 ScAreaLinkObj::getRefreshDelay(void) const
868 SolarMutexGuard aGuard;
869 sal_Int32 nRet = 0;
870 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
871 if (pLink)
872 nRet = (sal_Int32) pLink->GetRefreshDelay();
873 return nRet;
876 void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
878 SolarMutexGuard aGuard;
879 ModifyRefreshDelay_Impl( nRefreshDelay );
882 // XAreaLink
884 OUString SAL_CALL ScAreaLinkObj::getSourceArea() throw(uno::RuntimeException)
886 SolarMutexGuard aGuard;
887 OUString aRet;
888 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
889 if (pLink)
890 aRet = pLink->GetSource();
891 return aRet;
894 void SAL_CALL ScAreaLinkObj::setSourceArea( const OUString& aSourceArea )
895 throw(uno::RuntimeException)
897 SolarMutexGuard aGuard;
898 Modify_Impl( NULL, NULL, NULL, &aSourceArea, NULL );
901 table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() throw(uno::RuntimeException)
903 SolarMutexGuard aGuard;
904 table::CellRangeAddress aRet;
905 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
906 if (pLink)
907 ScUnoConversion::FillApiRange( aRet, pLink->GetDestArea() );
908 return aRet;
911 void SAL_CALL ScAreaLinkObj::setDestArea( const table::CellRangeAddress& aDestArea )
912 throw(uno::RuntimeException)
914 SolarMutexGuard aGuard;
915 Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea );
918 //------------------------------------------------------------------------
920 ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) :
921 pDocShell( pDocSh )
923 pDocShell->GetDocument()->AddUnoObject(*this);
926 ScAreaLinksObj::~ScAreaLinksObj()
928 if (pDocShell)
929 pDocShell->GetDocument()->RemoveUnoObject(*this);
932 void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
934 // Referenz-Update interessiert hier nicht
936 if ( rHint.ISA( SfxSimpleHint ) &&
937 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
939 pDocShell = NULL; // ungueltig geworden
943 // XAreaLinks
945 ScAreaLinkObj* ScAreaLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
947 if ( pDocShell && nIndex >= 0 && nIndex < getCount() )
948 return new ScAreaLinkObj( pDocShell, (sal_uInt16)nIndex );
950 return NULL; // nicht gefunden
953 void SAL_CALL ScAreaLinksObj::insertAtPosition( const table::CellAddress& aDestPos,
954 const OUString& aFileName,
955 const OUString& aSourceArea,
956 const OUString& aFilter,
957 const OUString& aFilterOptions )
958 throw(uno::RuntimeException)
960 SolarMutexGuard aGuard;
961 if (pDocShell)
963 String aFileStr (aFileName);
964 String aFilterStr (aFilter);
965 String aOptionStr (aFilterOptions);
966 String aSourceStr (aSourceArea);
967 ScAddress aDestAddr( (SCCOL)aDestPos.Column, (SCROW)aDestPos.Row, aDestPos.Sheet );
969 aFileStr = ScGlobal::GetAbsDocName( aFileStr, pDocShell ); //! in InsertAreaLink ???
970 pDocShell->GetDocFunc().InsertAreaLink( aFileStr, aFilterStr, aOptionStr,
971 aSourceStr, ScRange(aDestAddr),
972 0, false, sal_True ); // don't move contents
976 void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
978 SolarMutexGuard aGuard;
979 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, (sal_uInt16)nIndex);
980 if (pLink)
982 //! SetAddUndo oder so
984 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
985 pLinkManager->Remove( pLink );
989 // XEnumerationAccess
991 uno::Reference<container::XEnumeration> SAL_CALL ScAreaLinksObj::createEnumeration()
992 throw(uno::RuntimeException)
994 SolarMutexGuard aGuard;
995 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.CellAreaLinksEnumeration"));
998 // XIndexAccess
1000 sal_Int32 SAL_CALL ScAreaLinksObj::getCount() throw(uno::RuntimeException)
1002 SolarMutexGuard aGuard;
1003 sal_Int32 nAreaCount = 0;
1004 if (pDocShell)
1006 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
1007 sal_uInt16 nTotalCount = pLinkManager->GetLinks().size();
1008 for (sal_uInt16 i=0; i<nTotalCount; i++)
1010 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
1011 if (pBase->ISA(ScAreaLink))
1012 ++nAreaCount;
1015 return nAreaCount;
1018 uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex )
1019 throw(lang::IndexOutOfBoundsException,
1020 lang::WrappedTargetException, uno::RuntimeException)
1022 SolarMutexGuard aGuard;
1023 uno::Reference<sheet::XAreaLink> xLink(GetObjectByIndex_Impl(nIndex));
1024 if (xLink.is())
1025 return uno::makeAny(xLink);
1026 else
1027 throw lang::IndexOutOfBoundsException();
1030 uno::Type SAL_CALL ScAreaLinksObj::getElementType() throw(uno::RuntimeException)
1032 SolarMutexGuard aGuard;
1033 return getCppuType((uno::Reference<sheet::XAreaLink>*)0);
1036 sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException)
1038 SolarMutexGuard aGuard;
1039 return ( getCount() != 0 );
1042 //------------------------------------------------------------------------
1044 ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const String& rA,
1045 const String& rT, const String& rI) :
1046 pDocShell( pDocSh ),
1047 aAppl( rA ),
1048 aTopic( rT ),
1049 aItem( rI )
1051 pDocShell->GetDocument()->AddUnoObject(*this);
1054 ScDDELinkObj::~ScDDELinkObj()
1056 if (pDocShell)
1057 pDocShell->GetDocument()->RemoveUnoObject(*this);
1060 void ScDDELinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1062 //! notify if links in document are changed
1063 // UpdateRef is not needed here
1065 if ( rHint.ISA( SfxSimpleHint ) )
1067 if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1068 pDocShell = NULL; // pointer is invalid
1070 else if ( rHint.ISA( ScLinkRefreshedHint ) )
1072 const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
1073 if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE &&
1074 rLH.GetDdeAppl() == aAppl &&
1075 rLH.GetDdeTopic() == aTopic &&
1076 rLH.GetDdeItem() == aItem ) //! mode is ignored
1077 Refreshed_Impl();
1081 // XNamed
1083 static String lcl_BuildDDEName( const String& rAppl, const String& rTopic, const String& rItem )
1085 // Appl|Topic!Item (wie Excel)
1086 String aRet = rAppl;
1087 aRet += '|';
1088 aRet += rTopic;
1089 aRet += '!';
1090 aRet += rItem;
1091 return aRet;
1094 OUString SAL_CALL ScDDELinkObj::getName() throw(uno::RuntimeException)
1096 SolarMutexGuard aGuard;
1097 return lcl_BuildDDEName( aAppl, aTopic, aItem );
1100 void SAL_CALL ScDDELinkObj::setName( const OUString& /* aName */ ) throw(uno::RuntimeException)
1102 // name can't be changed (formulas wouldn't find the link)
1103 throw uno::RuntimeException();
1106 // XDDELink
1108 OUString SAL_CALL ScDDELinkObj::getApplication() throw(uno::RuntimeException)
1110 SolarMutexGuard aGuard;
1111 //! Test, ob Link noch im Dokument enthalten?
1113 return aAppl;
1116 OUString SAL_CALL ScDDELinkObj::getTopic() throw(uno::RuntimeException)
1118 SolarMutexGuard aGuard;
1119 //! Test, ob Link noch im Dokument enthalten?
1121 return aTopic;
1124 OUString SAL_CALL ScDDELinkObj::getItem() throw(uno::RuntimeException)
1126 SolarMutexGuard aGuard;
1127 //! Test, ob Link noch im Dokument enthalten?
1129 return aItem;
1132 // XRefreshable
1134 void SAL_CALL ScDDELinkObj::refresh() throw(uno::RuntimeException)
1136 SolarMutexGuard aGuard;
1137 if (pDocShell)
1139 ScDocument* pDoc = pDocShell->GetDocument();
1140 (void)pDoc->UpdateDdeLink( aAppl, aTopic, aItem );
1141 //! Fehler abfragen
1145 void SAL_CALL ScDDELinkObj::addRefreshListener(
1146 const uno::Reference<util::XRefreshListener >& xListener )
1147 throw(uno::RuntimeException)
1149 SolarMutexGuard aGuard;
1150 uno::Reference<util::XRefreshListener>* pObj =
1151 new uno::Reference<util::XRefreshListener>( xListener );
1152 aRefreshListeners.push_back( pObj );
1154 // hold one additional ref to keep this object alive as long as there are listeners
1155 if ( aRefreshListeners.size() == 1 )
1156 acquire();
1159 void SAL_CALL ScDDELinkObj::removeRefreshListener(
1160 const uno::Reference<util::XRefreshListener >& xListener )
1161 throw(uno::RuntimeException)
1163 SolarMutexGuard aGuard;
1164 sal_uInt16 nCount = aRefreshListeners.size();
1165 for ( sal_uInt16 n=nCount; n--; )
1167 uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
1168 if ( rObj == xListener )
1170 aRefreshListeners.erase( aRefreshListeners.begin() + n );
1171 if ( aRefreshListeners.empty() )
1172 release(); // release ref for listeners
1173 break;
1178 // XDDELinkResults
1180 uno::Sequence< uno::Sequence< uno::Any > > ScDDELinkObj::getResults( )
1181 throw (uno::RuntimeException)
1183 SolarMutexGuard aGuard;
1184 uno::Sequence< uno::Sequence< uno::Any > > aReturn;
1185 bool bSuccess = false;
1187 if ( pDocShell )
1189 ScDocument* pDoc = pDocShell->GetDocument();
1190 if ( pDoc )
1192 sal_uInt16 nPos = 0;
1193 if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1195 const ScMatrix* pMatrix = pDoc->GetDdeLinkResultMatrix( nPos );
1196 if ( pMatrix )
1198 uno::Any aAny;
1199 if ( ScRangeToSequence::FillMixedArray( aAny, pMatrix, true ) )
1201 aAny >>= aReturn;
1204 bSuccess = true;
1209 if ( !bSuccess )
1211 throw uno::RuntimeException( OUString(
1212 "ScDDELinkObj::getResults: failed to get results!" ),
1213 uno::Reference< uno::XInterface >() );
1216 return aReturn;
1219 void ScDDELinkObj::setResults( const uno::Sequence< uno::Sequence< uno::Any > >& aResults )
1220 throw (uno::RuntimeException)
1222 SolarMutexGuard aGuard;
1223 bool bSuccess = false;
1225 if ( pDocShell )
1227 ScDocument* pDoc = pDocShell->GetDocument();
1228 if ( pDoc )
1230 sal_uInt16 nPos = 0;
1231 if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1233 uno::Any aAny;
1234 aAny <<= aResults;
1235 ScMatrixRef xMatrix = ScSequenceToMatrix::CreateMixedMatrix( aAny );
1236 bSuccess = pDoc->SetDdeLinkResultMatrix( nPos, xMatrix );
1241 if ( !bSuccess )
1243 throw uno::RuntimeException( OUString(
1244 "ScDDELinkObj::setResults: failed to set results!" ),
1245 uno::Reference< uno::XInterface >() );
1249 void ScDDELinkObj::Refreshed_Impl()
1251 lang::EventObject aEvent;
1252 aEvent.Source.set((cppu::OWeakObject*)this);
1253 for ( sal_uInt16 n=0; n<aRefreshListeners.size(); n++ )
1254 aRefreshListeners[n]->refreshed( aEvent );
1257 //------------------------------------------------------------------------
1259 ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) :
1260 pDocShell( pDocSh )
1262 pDocShell->GetDocument()->AddUnoObject(*this);
1265 ScDDELinksObj::~ScDDELinksObj()
1267 if (pDocShell)
1268 pDocShell->GetDocument()->RemoveUnoObject(*this);
1271 void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1273 // Referenz-Update interessiert hier nicht
1275 if ( rHint.ISA( SfxSimpleHint ) &&
1276 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1278 pDocShell = NULL; // ungueltig geworden
1282 // XDDELinks
1284 ScDDELinkObj* ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
1286 if (pDocShell)
1288 OUString aAppl, aTopic, aItem;
1289 if ( nIndex <= USHRT_MAX &&
1290 pDocShell->GetDocument()->GetDdeLinkData( (sal_uInt16)nIndex, aAppl, aTopic, aItem ) )
1291 return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1293 return NULL;
1296 ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const OUString& aName)
1298 if (pDocShell)
1300 String aNamStr(aName);
1301 OUString aAppl, aTopic, aItem;
1303 ScDocument* pDoc = pDocShell->GetDocument();
1304 sal_uInt16 nCount = pDoc->GetDdeLinkCount();
1305 for (sal_uInt16 i=0; i<nCount; i++)
1307 pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1308 if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1309 return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1312 return NULL;
1315 // XEnumerationAccess
1317 uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration()
1318 throw(uno::RuntimeException)
1320 SolarMutexGuard aGuard;
1321 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DDELinksEnumeration"));
1324 // XIndexAccess
1326 sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException)
1328 SolarMutexGuard aGuard;
1329 sal_Int32 nAreaCount = 0;
1330 if (pDocShell)
1331 nAreaCount = pDocShell->GetDocument()->GetDdeLinkCount();
1332 return nAreaCount;
1335 uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex )
1336 throw(lang::IndexOutOfBoundsException,
1337 lang::WrappedTargetException, uno::RuntimeException)
1339 SolarMutexGuard aGuard;
1340 uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex));
1341 if (xLink.is())
1342 return uno::makeAny(xLink);
1343 else
1344 throw lang::IndexOutOfBoundsException();
1347 uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException)
1349 SolarMutexGuard aGuard;
1350 return getCppuType((uno::Reference<sheet::XDDELink>*)0);
1353 sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException)
1355 SolarMutexGuard aGuard;
1356 return ( getCount() != 0 );
1359 uno::Any SAL_CALL ScDDELinksObj::getByName( const OUString& aName )
1360 throw(container::NoSuchElementException,
1361 lang::WrappedTargetException, uno::RuntimeException)
1363 SolarMutexGuard aGuard;
1364 uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName));
1365 if (xLink.is())
1366 return uno::makeAny(xLink);
1367 else
1368 throw container::NoSuchElementException();
1371 uno::Sequence<OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException)
1373 SolarMutexGuard aGuard;
1374 if (pDocShell)
1376 OUString aAppl, aTopic, aItem;
1378 ScDocument* pDoc = pDocShell->GetDocument();
1379 sal_uInt16 nCount = pDoc->GetDdeLinkCount();
1380 uno::Sequence<OUString> aSeq(nCount);
1381 OUString* pAry = aSeq.getArray();
1383 for (sal_uInt16 i=0; i<nCount; i++)
1385 pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1386 pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem);
1388 return aSeq;
1390 return uno::Sequence<OUString>();
1393 sal_Bool SAL_CALL ScDDELinksObj::hasByName( const OUString& aName )
1394 throw(uno::RuntimeException)
1396 SolarMutexGuard aGuard;
1397 if (pDocShell)
1399 String aNamStr(aName);
1400 OUString aAppl, aTopic, aItem;
1402 ScDocument* pDoc = pDocShell->GetDocument();
1403 sal_uInt16 nCount = pDoc->GetDdeLinkCount();
1404 for (sal_uInt16 i=0; i<nCount; i++)
1406 pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1407 if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1408 return sal_True;
1411 return false;
1414 // XDDELinks
1416 uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
1417 const OUString& aApplication, const OUString& aTopic,
1418 const OUString& aItem, ::com::sun::star::sheet::DDELinkMode nMode )
1419 throw (uno::RuntimeException)
1421 SolarMutexGuard aGuard;
1422 uno::Reference< sheet::XDDELink > xLink;
1424 if ( pDocShell )
1426 ScDocument* pDoc = pDocShell->GetDocument();
1427 if ( pDoc )
1429 sal_uInt8 nMod = SC_DDE_DEFAULT;
1430 switch ( nMode )
1432 case sheet::DDELinkMode_DEFAULT:
1434 nMod = SC_DDE_DEFAULT;
1436 break;
1437 case sheet::DDELinkMode_ENGLISH:
1439 nMod = SC_DDE_ENGLISH;
1441 break;
1442 case sheet::DDELinkMode_TEXT:
1444 nMod = SC_DDE_TEXT;
1446 break;
1447 default:
1450 break;
1453 if ( pDoc->CreateDdeLink( aApplication, aTopic, aItem, nMod, ScMatrixRef() ) )
1455 const OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) );
1456 xLink.set( GetObjectByName_Impl( aName ) );
1461 if ( !xLink.is() )
1463 throw uno::RuntimeException( OUString(
1464 "ScDDELinksObj::addDDELink: cannot add DDE link!" ),
1465 uno::Reference< uno::XInterface >() );
1468 return xLink;
1471 // ============================================================================
1473 ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
1474 mpTable(pTable),
1475 mnIndex(nIndex)
1479 ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
1483 void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue)
1484 throw (IllegalArgumentException, RuntimeException)
1486 SolarMutexGuard aGuard;
1487 if (nRow < 0 || nCol < 0)
1488 throw IllegalArgumentException();
1490 ScExternalRefCache::TokenRef pToken;
1491 double fVal = 0.0;
1492 OUString aVal;
1493 if (rValue >>= fVal)
1494 pToken.reset(new FormulaDoubleToken(fVal));
1495 else if (rValue >>= aVal)
1496 pToken.reset(new FormulaStringToken(aVal));
1497 else
1498 // unidentified value type.
1499 return;
1501 mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken);
1504 Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow)
1505 throw (IllegalArgumentException, RuntimeException)
1507 SolarMutexGuard aGuard;
1508 if (nRow < 0 || nCol < 0)
1509 throw IllegalArgumentException();
1511 FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get();
1512 if (!pToken)
1513 throw IllegalArgumentException();
1515 Any aValue;
1516 switch (pToken->GetType())
1518 case svDouble:
1520 double fVal = pToken->GetDouble();
1521 aValue <<= fVal;
1523 break;
1524 case svString:
1526 OUString aVal = pToken->GetString();
1527 aValue <<= aVal;
1529 break;
1530 default:
1531 throw IllegalArgumentException();
1533 return aValue;
1536 Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows()
1537 throw (RuntimeException)
1539 SolarMutexGuard aGuard;
1540 vector<SCROW> aRows;
1541 mpTable->getAllRows(aRows);
1542 size_t nSize = aRows.size();
1543 Sequence<sal_Int32> aRowsSeq(nSize);
1544 for (size_t i = 0; i < nSize; ++i)
1545 aRowsSeq[i] = aRows[i];
1547 return aRowsSeq;
1550 Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow)
1551 throw (IllegalArgumentException, RuntimeException)
1553 SolarMutexGuard aGuard;
1554 if (nRow < 0)
1555 throw IllegalArgumentException();
1557 vector<SCCOL> aCols;
1558 mpTable->getAllCols(static_cast<SCROW>(nRow), aCols);
1559 size_t nSize = aCols.size();
1560 Sequence<sal_Int32> aColsSeq(nSize);
1561 for (size_t i = 0; i < nSize; ++i)
1562 aColsSeq[i] = aCols[i];
1564 return aColsSeq;
1567 sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
1568 throw (RuntimeException)
1570 return static_cast< sal_Int32 >( mnIndex );
1573 // ============================================================================
1575 ScExternalDocLinkObj::ScExternalDocLinkObj(ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
1576 mpRefMgr(pRefMgr), mnFileId(nFileId)
1580 ScExternalDocLinkObj::~ScExternalDocLinkObj()
1584 Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache(
1585 const OUString& aSheetName, sal_Bool bDynamicCache )
1586 throw (RuntimeException)
1588 SolarMutexGuard aGuard;
1589 size_t nIndex = 0;
1590 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
1591 if (!bDynamicCache)
1592 // Set the whole table cached to prevent access to the source document.
1593 pTable->setWholeTableCached();
1595 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1596 return aSheetCache;
1599 Any SAL_CALL ScExternalDocLinkObj::getByName(const OUString &aName)
1600 throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
1602 SolarMutexGuard aGuard;
1603 size_t nIndex = 0;
1604 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex);
1605 if (!pTable)
1606 throw container::NoSuchElementException();
1608 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1610 Any aAny;
1611 aAny <<= aSheetCache;
1612 return aAny;
1615 Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
1616 throw (RuntimeException)
1618 SolarMutexGuard aGuard;
1619 vector<OUString> aTabNames;
1620 mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
1622 // #i116940# be consistent with getByName: include only table names which have a cache already
1623 vector<OUString> aValidNames;
1624 for (vector<OUString>::iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter)
1625 if (mpRefMgr->getCacheTable(mnFileId, *aIter, false))
1626 aValidNames.push_back(*aIter);
1628 size_t n = aValidNames.size();
1629 Sequence<OUString> aSeq(n);
1630 for (size_t i = 0; i < n; ++i)
1631 aSeq[i] = aValidNames[i];
1632 return aSeq;
1635 sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
1636 throw (RuntimeException)
1638 SolarMutexGuard aGuard;
1640 // #i116940# be consistent with getByName: allow only table names which have a cache already
1641 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false);
1642 return (pTable.get() != NULL);
1645 sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
1646 throw (RuntimeException)
1648 SolarMutexGuard aGuard;
1650 // #i116940# be consistent with getByName: count only table names which have a cache already
1651 return getElementNames().getLength();
1654 Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex)
1655 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
1657 SolarMutexGuard aGuard;
1659 // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
1660 // the entries which have a cache already. Quick solution: Use getElementNames.
1661 Sequence< OUString > aNames( getElementNames() );
1662 if (nApiIndex < 0 || nApiIndex >= aNames.getLength())
1663 throw lang::IndexOutOfBoundsException();
1665 size_t nIndex = 0;
1666 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex);
1667 if (!pTable)
1668 throw lang::IndexOutOfBoundsException();
1670 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1672 Any aAny;
1673 aAny <<= aSheetCache;
1674 return aAny;
1677 Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration()
1678 throw (RuntimeException)
1680 SolarMutexGuard aGuard;
1681 Reference< container::XEnumeration > aRef(
1682 new ScIndexEnumeration(this, OUString(
1683 "com.sun.star.sheet.ExternalDocLink")));
1684 return aRef;
1687 uno::Type SAL_CALL ScExternalDocLinkObj::getElementType()
1688 throw (RuntimeException)
1690 SolarMutexGuard aGuard;
1691 return getCppuType(static_cast<Reference<sheet::XExternalDocLink>*>(0));
1694 sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
1695 throw (RuntimeException)
1697 SolarMutexGuard aGuard;
1699 // #i116940# be consistent with getByName: count only table names which have a cache already
1700 return ( getElementNames().getLength() > 0 );
1703 sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
1704 throw (RuntimeException)
1706 return static_cast<sal_Int32>(mnFileId);
1709 // ============================================================================
1711 ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
1712 mpDocShell(pDocShell),
1713 mpRefMgr(pDocShell->GetDocument()->GetExternalRefManager())
1717 ScExternalDocLinksObj::~ScExternalDocLinksObj()
1721 Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink(
1722 const OUString& aDocName )
1723 throw (RuntimeException)
1725 SolarMutexGuard aGuard;
1726 sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocName);
1727 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1728 return aDocLink;
1731 Any SAL_CALL ScExternalDocLinksObj::getByName(const OUString &aName)
1732 throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
1734 SolarMutexGuard aGuard;
1735 if (!mpRefMgr->hasExternalFile(aName))
1736 throw container::NoSuchElementException();
1738 sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aName);
1739 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1741 Any aAny;
1742 aAny <<= aDocLink;
1743 return aAny;
1746 Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames()
1747 throw (RuntimeException)
1749 SolarMutexGuard aGuard;
1750 sal_uInt16 n = mpRefMgr->getExternalFileCount();
1751 Sequence<OUString> aSeq(n);
1752 for (sal_uInt16 i = 0; i < n; ++i)
1754 const OUString* pName = mpRefMgr->getExternalFileName(i);
1755 aSeq[i] = pName ? *pName : OUString();
1758 return aSeq;
1761 sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName)
1762 throw (RuntimeException)
1764 SolarMutexGuard aGuard;
1765 return mpRefMgr->hasExternalFile(aName);
1768 sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount()
1769 throw (RuntimeException)
1771 SolarMutexGuard aGuard;
1772 return mpRefMgr->getExternalFileCount();
1775 Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex)
1776 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
1778 SolarMutexGuard aGuard;
1779 if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min())
1780 throw lang::IndexOutOfBoundsException();
1782 sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex);
1784 if (!mpRefMgr->hasExternalFile(nFileId))
1785 throw lang::IndexOutOfBoundsException();
1787 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1788 Any aAny;
1789 aAny <<= aDocLink;
1790 return aAny;
1793 Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration()
1794 throw (RuntimeException)
1796 SolarMutexGuard aGuard;
1797 Reference< container::XEnumeration > aRef(
1798 new ScIndexEnumeration(this, OUString(
1799 "com.sun.star.sheet.ExternalDocLinks")));
1800 return aRef;
1803 uno::Type SAL_CALL ScExternalDocLinksObj::getElementType()
1804 throw (RuntimeException)
1806 SolarMutexGuard aGuard;
1807 return getCppuType(static_cast<Reference<sheet::XExternalDocLinks>*>(0));
1810 sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements()
1811 throw (RuntimeException)
1813 SolarMutexGuard aGuard;
1814 return mpRefMgr->getExternalFileCount() > 0;
1817 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */