fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / unoobj / linkuno.cxx
blob13772e37070e3b314d2f950b0afaf909daf8f9f0
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>
23 #include <svl/sharedstringpool.hxx>
25 #include "linkuno.hxx"
26 #include "miscuno.hxx"
27 #include "convuno.hxx"
28 #include "docsh.hxx"
29 #include "docfunc.hxx"
30 #include "tablink.hxx"
31 #include "arealink.hxx"
32 #include "hints.hxx"
33 #include "unonames.hxx"
34 #include "rangeseq.hxx"
35 #include "token.hxx"
36 #include "scmatrix.hxx"
37 #include <documentlinkmgr.hxx>
39 #include <vector>
40 #include <climits>
42 using namespace com::sun::star;
43 using namespace formula;
44 using ::com::sun::star::uno::Any;
45 using ::com::sun::star::uno::Reference;
46 using ::com::sun::star::uno::Sequence;
47 using ::com::sun::star::uno::UNO_QUERY;
48 using ::com::sun::star::uno::UNO_QUERY_THROW;
49 using ::com::sun::star::lang::IllegalArgumentException;
50 using ::com::sun::star::uno::RuntimeException;
51 using ::std::vector;
53 // fuer Sheet- und Area-Links benutzt:
54 static const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap()
56 static const SfxItemPropertyMapEntry aSheetLinkMap_Impl[] =
58 {OUString(SC_UNONAME_FILTER), 0, cppu::UnoType<OUString>::get(), 0, 0 },
59 {OUString(SC_UNONAME_FILTOPT), 0, cppu::UnoType<OUString>::get(), 0, 0 },
60 {OUString(SC_UNONAME_LINKURL), 0, cppu::UnoType<OUString>::get(), 0, 0 },
61 {OUString(SC_UNONAME_REFDELAY), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
62 {OUString(SC_UNONAME_REFPERIOD), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
63 { OUString(), 0, css::uno::Type(), 0, 0 }
65 return aSheetLinkMap_Impl;
68 SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj, "ScAreaLinkObj", "com.sun.star.sheet.CellAreaLink" )
69 SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj, "ScAreaLinksObj", "com.sun.star.sheet.CellAreaLinks" )
70 SC_SIMPLE_SERVICE_INFO( ScDDELinkObj, "ScDDELinkObj", "com.sun.star.sheet.DDELink" )
71 SC_SIMPLE_SERVICE_INFO( ScDDELinksObj, "ScDDELinksObj", "com.sun.star.sheet.DDELinks" )
72 SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj, "ScSheetLinkObj", "com.sun.star.sheet.SheetLink" )
73 SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj, "ScSheetLinksObj", "com.sun.star.sheet.SheetLinks" )
75 ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const OUString& rName) :
76 aPropSet( lcl_GetSheetLinkMap() ),
77 pDocShell( pDocSh ),
78 aFileName( rName )
80 pDocShell->GetDocument().AddUnoObject(*this);
83 ScSheetLinkObj::~ScSheetLinkObj()
85 SolarMutexGuard g;
87 if (pDocShell)
88 pDocShell->GetDocument().RemoveUnoObject(*this);
91 void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
93 //! notify if links in document are changed
94 // UpdateRef is not needed here
96 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
97 if ( pSimpleHint )
99 if ( pSimpleHint->GetId() == SFX_HINT_DYING )
100 pDocShell = NULL; // pointer is invalid
102 else if ( dynamic_cast<const ScLinkRefreshedHint*>(&rHint) )
104 const ScLinkRefreshedHint& rLH = static_cast<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 size_t nCount = pLinkManager->GetLinks().size();
116 for (size_t i=0; i<nCount; i++)
118 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
119 if (pBase->ISA(ScTableLink))
121 ScTableLink* pTabLink = static_cast<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, std::exception)
134 SolarMutexGuard aGuard;
135 return getFileName(); // Name ist der Dateiname (URL)
138 void SAL_CALL ScSheetLinkObj::setName( const OUString& aName ) throw(uno::RuntimeException, std::exception)
140 SolarMutexGuard aGuard;
141 setFileName(aName); // Name ist der Dateiname (URL)
144 // XRefreshable
146 void SAL_CALL ScSheetLinkObj::refresh()
147 throw (uno::RuntimeException, std::exception)
149 SolarMutexGuard aGuard;
150 ScTableLink* pLink = GetLink_Impl();
151 if (pLink)
152 pLink->Refresh( pLink->GetFileName(), pLink->GetFilterName(), NULL, pLink->GetRefreshDelay() );
155 void SAL_CALL ScSheetLinkObj::addRefreshListener(
156 const uno::Reference<util::XRefreshListener >& xListener )
157 throw (uno::RuntimeException, std::exception)
159 SolarMutexGuard aGuard;
160 uno::Reference<util::XRefreshListener>* pObj =
161 new uno::Reference<util::XRefreshListener>( xListener );
162 aRefreshListeners.push_back( pObj );
164 // hold one additional ref to keep this object alive as long as there are listeners
165 if ( aRefreshListeners.size() == 1 )
166 acquire();
169 void SAL_CALL ScSheetLinkObj::removeRefreshListener(
170 const uno::Reference<util::XRefreshListener >& xListener )
171 throw(uno::RuntimeException, std::exception)
173 SolarMutexGuard aGuard;
174 size_t nCount = aRefreshListeners.size();
175 for ( size_t n=nCount; n--; )
177 uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
178 if ( rObj == xListener )
180 aRefreshListeners.erase( aRefreshListeners.begin() + n );
181 if ( aRefreshListeners.empty() )
182 release(); // release ref for listeners
183 break;
188 void ScSheetLinkObj::Refreshed_Impl()
190 lang::EventObject aEvent;
191 aEvent.Source.set((cppu::OWeakObject*)this);
192 for ( size_t n=0; n<aRefreshListeners.size(); n++ )
193 aRefreshListeners[n]->refreshed( aEvent );
196 void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
198 ScTableLink* pLink = GetLink_Impl();
199 if( pLink )
200 pLink->SetRefreshDelay( (sal_uLong) nRefresh );
203 // XPropertySet
205 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSheetLinkObj::getPropertySetInfo()
206 throw(uno::RuntimeException, std::exception)
208 SolarMutexGuard aGuard;
209 static uno::Reference<beans::XPropertySetInfo> aRef(
210 new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
211 return aRef;
214 void SAL_CALL ScSheetLinkObj::setPropertyValue(
215 const OUString& aPropertyName, const uno::Any& aValue )
216 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
217 lang::IllegalArgumentException, lang::WrappedTargetException,
218 uno::RuntimeException, std::exception)
220 SolarMutexGuard aGuard;
221 OUString aNameString(aPropertyName);
222 OUString aValStr;
223 if ( aNameString == SC_UNONAME_LINKURL )
225 if ( aValue >>= aValStr )
226 setFileName( aValStr );
228 else if ( aNameString == SC_UNONAME_FILTER )
230 if ( aValue >>= aValStr )
231 setFilter( aValStr );
233 else if ( aNameString == SC_UNONAME_FILTOPT )
235 if ( aValue >>= aValStr )
236 setFilterOptions( aValStr );
238 else if ( aNameString == SC_UNONAME_REFPERIOD )
240 sal_Int32 nRefresh = 0;
241 if ( aValue >>= nRefresh )
242 setRefreshDelay( nRefresh );
244 else if ( aNameString == SC_UNONAME_REFDELAY )
246 sal_Int32 nRefresh = 0;
247 if ( aValue >>= nRefresh )
248 setRefreshDelay( nRefresh );
252 uno::Any SAL_CALL ScSheetLinkObj::getPropertyValue( const OUString& aPropertyName )
253 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
254 uno::RuntimeException, std::exception)
256 SolarMutexGuard aGuard;
257 OUString aNameString(aPropertyName);
258 uno::Any aRet;
259 if ( aNameString == SC_UNONAME_LINKURL )
260 aRet <<= getFileName();
261 else if ( aNameString == SC_UNONAME_FILTER )
262 aRet <<= getFilter();
263 else if ( aNameString == SC_UNONAME_FILTOPT )
264 aRet <<= getFilterOptions();
265 else if ( aNameString == SC_UNONAME_REFPERIOD )
266 aRet <<= getRefreshDelay();
267 else if ( aNameString == SC_UNONAME_REFDELAY )
268 aRet <<= getRefreshDelay();
269 return aRet;
272 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj )
274 // internal:
276 OUString ScSheetLinkObj::getFileName() const
278 SolarMutexGuard aGuard;
279 return aFileName;
282 void ScSheetLinkObj::setFileName(const OUString& rNewName)
284 SolarMutexGuard aGuard;
285 ScTableLink* pLink = GetLink_Impl();
286 if (pLink)
288 // pLink->Refresh mit neuem Dateinamen bringt sfx2::LinkManager durcheinander
289 // darum per Hand die Tabellen umsetzen und Link per UpdateLinks neu erzeugen
291 OUString aNewStr(ScGlobal::GetAbsDocName( rNewName, pDocShell ));
293 // zuerst Tabellen umsetzen
295 ScDocument& rDoc = pDocShell->GetDocument();
296 SCTAB nTabCount = rDoc.GetTableCount();
297 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
298 if ( rDoc.IsLinked(nTab) && rDoc.GetLinkDoc(nTab) == aFileName ) // alte Datei
299 rDoc.SetLink( nTab, rDoc.GetLinkMode(nTab), aNewStr,
300 rDoc.GetLinkFlt(nTab), rDoc.GetLinkOpt(nTab),
301 rDoc.GetLinkTab(nTab),
302 rDoc.GetLinkRefreshDelay(nTab) ); // nur Datei aendern
304 // Links updaten
305 //! Undo !!!
307 pLink = NULL; // wird bei UpdateLinks ungueltig
308 pDocShell->UpdateLinks(); // alter Link raus, evtl. neuen Link anlegen
310 // Daten kopieren
312 aFileName = aNewStr;
313 pLink = GetLink_Impl(); // neuer Link mit neuem Namen
314 if (pLink)
315 pLink->Update(); // inkl. Paint & Undo fuer Daten
319 OUString ScSheetLinkObj::getFilter() const
321 SolarMutexGuard aGuard;
322 OUString aRet;
323 ScTableLink* pLink = GetLink_Impl();
324 if (pLink)
325 aRet = pLink->GetFilterName();
326 return aRet;
329 void ScSheetLinkObj::setFilter(const OUString& Filter)
331 SolarMutexGuard aGuard;
332 ScTableLink* pLink = GetLink_Impl();
333 if (pLink)
335 OUString aFilterStr(Filter);
336 pLink->Refresh( aFileName, aFilterStr, NULL, pLink->GetRefreshDelay() );
340 OUString ScSheetLinkObj::getFilterOptions() const
342 SolarMutexGuard aGuard;
343 OUString aRet;
344 ScTableLink* pLink = GetLink_Impl();
345 if (pLink)
346 aRet = pLink->GetOptions();
347 return aRet;
350 void ScSheetLinkObj::setFilterOptions(const OUString& FilterOptions)
352 SolarMutexGuard aGuard;
353 ScTableLink* pLink = GetLink_Impl();
354 if (pLink)
356 OUString aOptStr(FilterOptions);
357 pLink->Refresh( aFileName, pLink->GetFilterName(), &aOptStr, pLink->GetRefreshDelay() );
361 sal_Int32 ScSheetLinkObj::getRefreshDelay() const
363 SolarMutexGuard aGuard;
364 sal_Int32 nRet = 0;
365 ScTableLink* pLink = GetLink_Impl();
366 if (pLink)
367 nRet = (sal_Int32) pLink->GetRefreshDelay();
368 return nRet;
371 void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
373 SolarMutexGuard aGuard;
374 ModifyRefreshDelay_Impl( nRefreshDelay );
377 ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) :
378 pDocShell( pDocSh )
380 pDocShell->GetDocument().AddUnoObject(*this);
383 ScSheetLinksObj::~ScSheetLinksObj()
385 SolarMutexGuard g;
387 if (pDocShell)
388 pDocShell->GetDocument().RemoveUnoObject(*this);
391 void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
393 // Referenz-Update interessiert hier nicht
395 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
396 if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
398 pDocShell = NULL; // ungueltig geworden
402 // XSheetLinks
404 ScSheetLinkObj* ScSheetLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
406 if (!pDocShell)
407 return NULL;
409 typedef std::unordered_set<OUString, OUStringHash> StrSetType;
410 StrSetType aNames;
411 ScDocument& rDoc = pDocShell->GetDocument();
412 SCTAB nTabCount = rDoc.GetTableCount();
413 sal_Int32 nCount = 0;
414 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
416 if (!rDoc.IsLinked(nTab))
417 continue;
419 OUString aLinkDoc = rDoc.GetLinkDoc(nTab);
420 if (aNames.insert(aLinkDoc).second)
422 // unique document name.
423 if (nCount == nIndex)
424 return new ScSheetLinkObj( pDocShell, aLinkDoc );
425 ++nCount;
429 return NULL; // kein Dokument oder Index zu gross
432 ScSheetLinkObj* ScSheetLinksObj::GetObjectByName_Impl(const OUString& aName)
434 // Name ist der Dateiname
436 if (pDocShell)
438 OUString aNameStr(aName);
440 ScDocument& rDoc = pDocShell->GetDocument();
441 SCTAB nTabCount = rDoc.GetTableCount();
442 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
443 if (rDoc.IsLinked(nTab))
445 //! case-insensitive ???
446 OUString aLinkDoc = rDoc.GetLinkDoc( nTab );
447 if ( aLinkDoc == aNameStr )
448 return new ScSheetLinkObj( pDocShell, aNameStr );
452 return NULL;
455 // XEnumerationAccess
456 uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration()
457 throw(uno::RuntimeException, std::exception)
459 SolarMutexGuard aGuard;
460 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.SheetLinksEnumeration"));
463 // XIndexAccess
464 sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException, std::exception)
466 typedef std::unordered_set<OUString, OUStringHash> StrSetType;
468 SolarMutexGuard aGuard;
469 if (!pDocShell)
470 return 0;
472 sal_Int32 nCount = 0;
474 StrSetType aNames;
475 ScDocument& rDoc = pDocShell->GetDocument();
476 SCTAB nTabCount = rDoc.GetTableCount();
477 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
479 if (!rDoc.IsLinked(nTab))
480 continue;
482 OUString aLinkDoc = rDoc.GetLinkDoc(nTab);
483 if (aNames.insert(aLinkDoc).second)
484 ++nCount;
486 return nCount;
489 uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex )
490 throw(lang::IndexOutOfBoundsException,
491 lang::WrappedTargetException, uno::RuntimeException, std::exception)
493 SolarMutexGuard aGuard;
494 uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex));
495 if (xLink.is())
496 return uno::makeAny(xLink);
497 else
498 throw lang::IndexOutOfBoundsException();
501 uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException, std::exception)
503 SolarMutexGuard aGuard;
504 return cppu::UnoType<beans::XPropertySet>::get();
507 sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException, std::exception)
509 SolarMutexGuard aGuard;
510 return ( getCount() != 0 );
513 uno::Any SAL_CALL ScSheetLinksObj::getByName( const OUString& aName )
514 throw(container::NoSuchElementException,
515 lang::WrappedTargetException, uno::RuntimeException, std::exception)
517 SolarMutexGuard aGuard;
518 uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName));
519 if (xLink.is())
520 return uno::makeAny(xLink);
521 else
522 throw container::NoSuchElementException();
523 // return uno::Any();
526 sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const OUString& aName )
527 throw(uno::RuntimeException, std::exception)
529 SolarMutexGuard aGuard;
530 // Name ist der Dateiname
532 if (pDocShell)
534 OUString aNameStr(aName);
536 ScDocument& rDoc = pDocShell->GetDocument();
537 SCTAB nTabCount = rDoc.GetTableCount();
538 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
539 if (rDoc.IsLinked(nTab))
541 //! case-insensitiv ???
542 OUString aLinkDoc(rDoc.GetLinkDoc( nTab ));
543 if ( aLinkDoc == aNameStr )
544 return sal_True;
547 return false;
550 uno::Sequence<OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException, std::exception)
552 typedef std::unordered_set<OUString, OUStringHash> StrSetType;
554 SolarMutexGuard aGuard;
555 // Name ist der Dateiname
557 if (!pDocShell)
558 return uno::Sequence<OUString>();
560 StrSetType aNames;
561 ScDocument& rDoc = pDocShell->GetDocument();
562 SCTAB nTabCount = rDoc.GetTableCount();
564 sal_Int32 nLinkCount = getCount();
565 uno::Sequence<OUString> aSeq(nLinkCount);
566 OUString* pAry = aSeq.getArray();
567 size_t nPos = 0;
568 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
570 if (!rDoc.IsLinked(nTab))
571 continue;
573 OUString aLinkDoc = rDoc.GetLinkDoc(nTab);
574 if (aNames.insert(aLinkDoc).second)
575 pAry[nPos++] = aLinkDoc;
577 OSL_ENSURE( nPos==static_cast<size_t>(nLinkCount), "verzaehlt" );
578 return aSeq;
581 static ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, size_t nPos )
583 if (pDocShell)
585 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager();
586 size_t nTotalCount = pLinkManager->GetLinks().size();
587 size_t nAreaCount = 0;
588 for (size_t i=0; i<nTotalCount; i++)
590 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
591 if (pBase->ISA(ScAreaLink))
593 if ( nAreaCount == nPos )
594 return static_cast<ScAreaLink*>(pBase);
595 ++nAreaCount;
599 return NULL; // nicht gefunden
602 ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, size_t nP) :
603 aPropSet( lcl_GetSheetLinkMap() ),
604 pDocShell( pDocSh ),
605 nPos( nP )
607 pDocShell->GetDocument().AddUnoObject(*this);
610 ScAreaLinkObj::~ScAreaLinkObj()
612 SolarMutexGuard g;
614 if (pDocShell)
615 pDocShell->GetDocument().RemoveUnoObject(*this);
618 void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
620 //! notify if links in document are changed
621 // UpdateRef is not needed here
623 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
624 if ( pSimpleHint )
626 if ( pSimpleHint->GetId() == SFX_HINT_DYING )
627 pDocShell = NULL; // pointer is invalid
629 else if ( dynamic_cast<const ScLinkRefreshedHint*>(&rHint) )
631 const ScLinkRefreshedHint& rLH = static_cast<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 OUString aFile (pLink->GetFile());
652 OUString aFilter (pLink->GetFilter());
653 OUString aOptions (pLink->GetOptions());
654 OUString 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 bool bFitBlock = true; // verschieben, wenn durch Update Groesse geaendert
666 if (pNewFile)
668 aFile = *pNewFile;
669 aFile = ScGlobal::GetAbsDocName( aFile, pDocShell ); //! in InsertAreaLink?
671 if (pNewFilter)
672 aFilter = *pNewFilter;
673 if (pNewOptions)
674 aOptions = *pNewOptions;
675 if (pNewSource)
676 aSource = *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, 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()
697 throw(uno::RuntimeException, std::exception)
699 SolarMutexGuard aGuard;
700 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
701 if (pLink)
702 pLink->Refresh( pLink->GetFile(), pLink->GetFilter(), pLink->GetSource(), pLink->GetRefreshDelay() );
705 void SAL_CALL ScAreaLinkObj::addRefreshListener(
706 const uno::Reference<util::XRefreshListener >& xListener )
707 throw (uno::RuntimeException, std::exception)
709 SolarMutexGuard aGuard;
710 uno::Reference<util::XRefreshListener>* pObj =
711 new uno::Reference<util::XRefreshListener>( xListener );
712 aRefreshListeners.push_back( pObj );
714 // hold one additional ref to keep this object alive as long as there are listeners
715 if ( aRefreshListeners.size() == 1 )
716 acquire();
719 void SAL_CALL ScAreaLinkObj::removeRefreshListener(
720 const uno::Reference<util::XRefreshListener >& xListener )
721 throw(uno::RuntimeException, std::exception)
723 SolarMutexGuard aGuard;
724 size_t nCount = aRefreshListeners.size();
725 for ( size_t n=nCount; n--; )
727 uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
728 if ( rObj == xListener )
730 aRefreshListeners.erase( aRefreshListeners.begin() + n );
731 if ( aRefreshListeners.empty() )
732 release(); // release ref for listeners
733 break;
736 if(n == 0)
737 break;
741 void ScAreaLinkObj::Refreshed_Impl()
743 lang::EventObject aEvent;
744 aEvent.Source.set((cppu::OWeakObject*)this);
745 for ( size_t n=0; n<aRefreshListeners.size(); n++ )
746 aRefreshListeners[n]->refreshed( aEvent );
749 // XPropertySet
751 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAreaLinkObj::getPropertySetInfo()
752 throw(uno::RuntimeException, std::exception)
754 SolarMutexGuard aGuard;
755 static uno::Reference<beans::XPropertySetInfo> aRef(
756 new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
757 return aRef;
760 void SAL_CALL ScAreaLinkObj::setPropertyValue(
761 const OUString& aPropertyName, const uno::Any& aValue )
762 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
763 lang::IllegalArgumentException, lang::WrappedTargetException,
764 uno::RuntimeException, std::exception)
766 SolarMutexGuard aGuard;
767 OUString aNameString(aPropertyName);
768 OUString aValStr;
769 if ( aNameString == SC_UNONAME_LINKURL )
771 if ( aValue >>= aValStr )
772 setFileName( aValStr );
774 else if ( aNameString == SC_UNONAME_FILTER )
776 if ( aValue >>= aValStr )
777 setFilter( aValStr );
779 else if ( aNameString == SC_UNONAME_FILTOPT )
781 if ( aValue >>= aValStr )
782 setFilterOptions( aValStr );
784 else if ( aNameString == SC_UNONAME_REFPERIOD )
786 sal_Int32 nRefresh = 0;
787 if ( aValue >>= nRefresh )
788 setRefreshDelay( nRefresh );
790 else if ( aNameString == SC_UNONAME_REFDELAY )
792 sal_Int32 nRefresh = 0;
793 if ( aValue >>= nRefresh )
794 setRefreshDelay( nRefresh );
798 uno::Any SAL_CALL ScAreaLinkObj::getPropertyValue( const OUString& aPropertyName )
799 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
800 uno::RuntimeException, std::exception)
802 SolarMutexGuard aGuard;
803 OUString aNameString(aPropertyName);
804 uno::Any aRet;
805 if ( aNameString == SC_UNONAME_LINKURL )
806 aRet <<= getFileName();
807 else if ( aNameString == SC_UNONAME_FILTER )
808 aRet <<= getFilter();
809 else if ( aNameString == SC_UNONAME_FILTOPT )
810 aRet <<= getFilterOptions();
811 else if ( aNameString == SC_UNONAME_REFPERIOD )
812 aRet <<= getRefreshDelay();
813 else if ( aNameString == SC_UNONAME_REFDELAY )
814 aRet <<= getRefreshDelay();
815 return aRet;
818 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj )
820 // internal:
822 OUString ScAreaLinkObj::getFileName() const
824 SolarMutexGuard aGuard;
825 OUString aRet;
826 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
827 if (pLink)
828 aRet = pLink->GetFile();
829 return aRet;
832 void ScAreaLinkObj::setFileName(const OUString& rNewName)
834 SolarMutexGuard aGuard;
835 Modify_Impl( &rNewName, NULL, NULL, NULL, NULL );
838 OUString ScAreaLinkObj::getFilter() const
840 SolarMutexGuard aGuard;
841 OUString aRet;
842 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
843 if (pLink)
844 aRet = pLink->GetFilter();
845 return aRet;
848 void ScAreaLinkObj::setFilter(const OUString& Filter)
850 SolarMutexGuard aGuard;
851 Modify_Impl( NULL, &Filter, NULL, NULL, NULL );
854 OUString ScAreaLinkObj::getFilterOptions() const
856 SolarMutexGuard aGuard;
857 OUString aRet;
858 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
859 if (pLink)
860 aRet = pLink->GetOptions();
861 return aRet;
864 void ScAreaLinkObj::setFilterOptions(const OUString& FilterOptions)
866 SolarMutexGuard aGuard;
867 Modify_Impl( NULL, NULL, &FilterOptions, NULL, NULL );
870 sal_Int32 ScAreaLinkObj::getRefreshDelay() const
872 SolarMutexGuard aGuard;
873 sal_Int32 nRet = 0;
874 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
875 if (pLink)
876 nRet = (sal_Int32) pLink->GetRefreshDelay();
877 return nRet;
880 void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
882 SolarMutexGuard aGuard;
883 ModifyRefreshDelay_Impl( nRefreshDelay );
886 // XAreaLink
888 OUString SAL_CALL ScAreaLinkObj::getSourceArea() throw(uno::RuntimeException, std::exception)
890 SolarMutexGuard aGuard;
891 OUString aRet;
892 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
893 if (pLink)
894 aRet = pLink->GetSource();
895 return aRet;
898 void SAL_CALL ScAreaLinkObj::setSourceArea( const OUString& aSourceArea )
899 throw(uno::RuntimeException, std::exception)
901 SolarMutexGuard aGuard;
902 Modify_Impl( NULL, NULL, NULL, &aSourceArea, NULL );
905 table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() throw(uno::RuntimeException, std::exception)
907 SolarMutexGuard aGuard;
908 table::CellRangeAddress aRet;
909 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
910 if (pLink)
911 ScUnoConversion::FillApiRange( aRet, pLink->GetDestArea() );
912 return aRet;
915 void SAL_CALL ScAreaLinkObj::setDestArea( const table::CellRangeAddress& aDestArea )
916 throw(uno::RuntimeException, std::exception)
918 SolarMutexGuard aGuard;
919 Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea );
922 ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) :
923 pDocShell( pDocSh )
925 pDocShell->GetDocument().AddUnoObject(*this);
928 ScAreaLinksObj::~ScAreaLinksObj()
930 SolarMutexGuard g;
932 if (pDocShell)
933 pDocShell->GetDocument().RemoveUnoObject(*this);
936 void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
938 // Referenz-Update interessiert hier nicht
940 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
941 if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
943 pDocShell = NULL; // ungueltig geworden
947 // XAreaLinks
949 ScAreaLinkObj* ScAreaLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
951 if ( pDocShell && nIndex >= 0 && nIndex < getCount() )
952 return new ScAreaLinkObj( pDocShell, (size_t)nIndex );
954 return NULL; // nicht gefunden
957 void SAL_CALL ScAreaLinksObj::insertAtPosition( const table::CellAddress& aDestPos,
958 const OUString& aFileName,
959 const OUString& aSourceArea,
960 const OUString& aFilter,
961 const OUString& aFilterOptions )
962 throw(uno::RuntimeException, std::exception)
964 SolarMutexGuard aGuard;
965 if (pDocShell)
967 OUString aFileStr (aFileName);
968 OUString aFilterStr (aFilter);
969 OUString aOptionStr (aFilterOptions);
970 OUString aSourceStr (aSourceArea);
971 ScAddress aDestAddr( (SCCOL)aDestPos.Column, (SCROW)aDestPos.Row, aDestPos.Sheet );
973 aFileStr = ScGlobal::GetAbsDocName( aFileStr, pDocShell ); //! in InsertAreaLink ???
974 pDocShell->GetDocFunc().InsertAreaLink( aFileStr, aFilterStr, aOptionStr,
975 aSourceStr, ScRange(aDestAddr),
976 0, false, true ); // don't move contents
980 void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException, std::exception)
982 SolarMutexGuard aGuard;
983 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, (size_t)nIndex);
984 if (pLink)
986 //! SetAddUndo oder so
988 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager();
989 pLinkManager->Remove( pLink );
993 // XEnumerationAccess
995 uno::Reference<container::XEnumeration> SAL_CALL ScAreaLinksObj::createEnumeration()
996 throw(uno::RuntimeException, std::exception)
998 SolarMutexGuard aGuard;
999 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.CellAreaLinksEnumeration"));
1002 // XIndexAccess
1004 sal_Int32 SAL_CALL ScAreaLinksObj::getCount() throw(uno::RuntimeException, std::exception)
1006 SolarMutexGuard aGuard;
1007 sal_Int32 nAreaCount = 0;
1008 if (pDocShell)
1010 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager();
1011 size_t nTotalCount = pLinkManager->GetLinks().size();
1012 for (size_t i=0; i<nTotalCount; i++)
1014 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
1015 if (pBase->ISA(ScAreaLink))
1016 ++nAreaCount;
1019 return nAreaCount;
1022 uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex )
1023 throw(lang::IndexOutOfBoundsException,
1024 lang::WrappedTargetException, uno::RuntimeException, std::exception)
1026 SolarMutexGuard aGuard;
1027 uno::Reference<sheet::XAreaLink> xLink(GetObjectByIndex_Impl(nIndex));
1028 if (xLink.is())
1029 return uno::makeAny(xLink);
1030 else
1031 throw lang::IndexOutOfBoundsException();
1034 uno::Type SAL_CALL ScAreaLinksObj::getElementType() throw(uno::RuntimeException, std::exception)
1036 SolarMutexGuard aGuard;
1037 return cppu::UnoType<sheet::XAreaLink>::get();
1040 sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException, std::exception)
1042 SolarMutexGuard aGuard;
1043 return ( getCount() != 0 );
1046 ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const OUString& rA,
1047 const OUString& rT, const OUString& rI) :
1048 pDocShell( pDocSh ),
1049 aAppl( rA ),
1050 aTopic( rT ),
1051 aItem( rI )
1053 pDocShell->GetDocument().AddUnoObject(*this);
1056 ScDDELinkObj::~ScDDELinkObj()
1058 SolarMutexGuard g;
1060 if (pDocShell)
1061 pDocShell->GetDocument().RemoveUnoObject(*this);
1064 void ScDDELinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1066 //! notify if links in document are changed
1067 // UpdateRef is not needed here
1069 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
1070 if ( pSimpleHint )
1072 if ( pSimpleHint->GetId() == SFX_HINT_DYING )
1073 pDocShell = NULL; // pointer is invalid
1075 else if ( dynamic_cast<const ScLinkRefreshedHint*>(&rHint) )
1077 const ScLinkRefreshedHint& rLH = static_cast<const ScLinkRefreshedHint&>(rHint);
1078 if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE &&
1079 rLH.GetDdeAppl() == aAppl &&
1080 rLH.GetDdeTopic() == aTopic &&
1081 rLH.GetDdeItem() == aItem ) //! mode is ignored
1082 Refreshed_Impl();
1086 // XNamed
1088 static OUString lcl_BuildDDEName( const OUString& rAppl, const OUString& rTopic, const OUString& rItem )
1090 // Appl|Topic!Item (wie Excel)
1091 OUString aRet = rAppl + "|" + rTopic + "!" + rItem;
1092 return aRet;
1095 OUString SAL_CALL ScDDELinkObj::getName() throw(uno::RuntimeException, std::exception)
1097 SolarMutexGuard aGuard;
1098 return lcl_BuildDDEName( aAppl, aTopic, aItem );
1101 void SAL_CALL ScDDELinkObj::setName( const OUString& /* aName */ ) throw(uno::RuntimeException, std::exception)
1103 // name can't be changed (formulas wouldn't find the link)
1104 throw uno::RuntimeException();
1107 // XDDELink
1109 OUString SAL_CALL ScDDELinkObj::getApplication() throw(uno::RuntimeException, std::exception)
1111 SolarMutexGuard aGuard;
1112 //! Test, ob Link noch im Dokument enthalten?
1114 return aAppl;
1117 OUString SAL_CALL ScDDELinkObj::getTopic() throw(uno::RuntimeException, std::exception)
1119 SolarMutexGuard aGuard;
1120 //! Test, ob Link noch im Dokument enthalten?
1122 return aTopic;
1125 OUString SAL_CALL ScDDELinkObj::getItem() throw(uno::RuntimeException, std::exception)
1127 SolarMutexGuard aGuard;
1128 //! Test, ob Link noch im Dokument enthalten?
1130 return aItem;
1133 // XRefreshable
1135 void SAL_CALL ScDDELinkObj::refresh() throw(uno::RuntimeException, std::exception)
1137 SolarMutexGuard aGuard;
1138 if (pDocShell)
1140 sc::DocumentLinkManager& rMgr = pDocShell->GetDocument().GetDocLinkManager();
1141 rMgr.updateDdeLink(aAppl, aTopic, aItem);
1145 void SAL_CALL ScDDELinkObj::addRefreshListener(
1146 const uno::Reference<util::XRefreshListener >& xListener )
1147 throw (uno::RuntimeException, std::exception)
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, std::exception)
1163 SolarMutexGuard aGuard;
1164 size_t nCount = aRefreshListeners.size();
1165 for ( size_t 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, std::exception)
1183 SolarMutexGuard aGuard;
1184 uno::Sequence< uno::Sequence< uno::Any > > aReturn;
1185 bool bSuccess = false;
1187 if ( pDocShell )
1189 ScDocument& rDoc = pDocShell->GetDocument();
1190 size_t nPos = 0;
1191 if ( rDoc.FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1193 const ScMatrix* pMatrix = rDoc.GetDdeLinkResultMatrix( nPos );
1194 if ( pMatrix )
1196 uno::Any aAny;
1197 if ( ScRangeToSequence::FillMixedArray( aAny, pMatrix, true ) )
1199 aAny >>= aReturn;
1202 bSuccess = true;
1206 if ( !bSuccess )
1208 throw uno::RuntimeException(
1209 "ScDDELinkObj::getResults: failed to get results!" );
1212 return aReturn;
1215 void ScDDELinkObj::setResults( const uno::Sequence< uno::Sequence< uno::Any > >& aResults )
1216 throw (uno::RuntimeException, std::exception)
1218 SolarMutexGuard aGuard;
1219 bool bSuccess = false;
1221 if ( pDocShell )
1223 ScDocument& rDoc = pDocShell->GetDocument();
1224 size_t nPos = 0;
1225 if ( rDoc.FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1227 uno::Any aAny;
1228 aAny <<= aResults;
1229 ScMatrixRef xMatrix = ScSequenceToMatrix::CreateMixedMatrix( aAny );
1230 bSuccess = rDoc.SetDdeLinkResultMatrix( nPos, xMatrix );
1234 if ( !bSuccess )
1236 throw uno::RuntimeException(
1237 "ScDDELinkObj::setResults: failed to set results!" );
1241 void ScDDELinkObj::Refreshed_Impl()
1243 lang::EventObject aEvent;
1244 aEvent.Source.set((cppu::OWeakObject*)this);
1245 for ( size_t n=0; n<aRefreshListeners.size(); n++ )
1246 aRefreshListeners[n]->refreshed( aEvent );
1249 ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) :
1250 pDocShell( pDocSh )
1252 pDocShell->GetDocument().AddUnoObject(*this);
1255 ScDDELinksObj::~ScDDELinksObj()
1257 SolarMutexGuard g;
1259 if (pDocShell)
1260 pDocShell->GetDocument().RemoveUnoObject(*this);
1263 void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1265 // Referenz-Update interessiert hier nicht
1267 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
1268 if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
1270 pDocShell = NULL; // ungueltig geworden
1274 // XDDELinks
1276 ScDDELinkObj* ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
1278 if (pDocShell)
1280 OUString aAppl, aTopic, aItem;
1281 if ( pDocShell->GetDocument().GetDdeLinkData( (size_t)nIndex, aAppl, aTopic, aItem ) )
1282 return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1284 return NULL;
1287 ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const OUString& aName)
1289 if (pDocShell)
1291 OUString aNamStr(aName);
1292 OUString aAppl, aTopic, aItem;
1294 ScDocument& rDoc = pDocShell->GetDocument();
1295 size_t nCount = rDoc.GetDocLinkManager().getDdeLinkCount();
1296 for (size_t i=0; i<nCount; i++)
1298 rDoc.GetDdeLinkData( i, aAppl, aTopic, aItem );
1299 if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1300 return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1303 return NULL;
1306 // XEnumerationAccess
1308 uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration()
1309 throw(uno::RuntimeException, std::exception)
1311 SolarMutexGuard aGuard;
1312 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DDELinksEnumeration"));
1315 // XIndexAccess
1317 sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException, std::exception)
1319 SolarMutexGuard aGuard;
1320 sal_Int32 nAreaCount = 0;
1321 if (pDocShell)
1322 nAreaCount = pDocShell->GetDocument().GetDocLinkManager().getDdeLinkCount();
1323 return nAreaCount;
1326 uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex )
1327 throw(lang::IndexOutOfBoundsException,
1328 lang::WrappedTargetException, uno::RuntimeException, std::exception)
1330 SolarMutexGuard aGuard;
1331 uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex));
1332 if (xLink.is())
1333 return uno::makeAny(xLink);
1334 else
1335 throw lang::IndexOutOfBoundsException();
1338 uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException, std::exception)
1340 SolarMutexGuard aGuard;
1341 return cppu::UnoType<sheet::XDDELink>::get();
1344 sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException, std::exception)
1346 SolarMutexGuard aGuard;
1347 return ( getCount() != 0 );
1350 uno::Any SAL_CALL ScDDELinksObj::getByName( const OUString& aName )
1351 throw(container::NoSuchElementException,
1352 lang::WrappedTargetException, uno::RuntimeException, std::exception)
1354 SolarMutexGuard aGuard;
1355 uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName));
1356 if (xLink.is())
1357 return uno::makeAny(xLink);
1358 else
1359 throw container::NoSuchElementException();
1362 uno::Sequence<OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException, std::exception)
1364 SolarMutexGuard aGuard;
1365 if (pDocShell)
1367 OUString aAppl, aTopic, aItem;
1369 ScDocument& rDoc = pDocShell->GetDocument();
1370 size_t nCount = pDocShell->GetDocument().GetDocLinkManager().getDdeLinkCount();
1371 uno::Sequence<OUString> aSeq(nCount);
1372 OUString* pAry = aSeq.getArray();
1374 for (size_t i=0; i<nCount; i++)
1376 rDoc.GetDdeLinkData( i, aAppl, aTopic, aItem );
1377 pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem);
1379 return aSeq;
1381 return uno::Sequence<OUString>();
1384 sal_Bool SAL_CALL ScDDELinksObj::hasByName( const OUString& aName )
1385 throw(uno::RuntimeException, std::exception)
1387 SolarMutexGuard aGuard;
1388 if (pDocShell)
1390 OUString aNamStr(aName);
1391 OUString aAppl, aTopic, aItem;
1393 ScDocument& rDoc = pDocShell->GetDocument();
1394 size_t nCount = pDocShell->GetDocument().GetDocLinkManager().getDdeLinkCount();
1395 for (size_t i=0; i<nCount; i++)
1397 rDoc.GetDdeLinkData( i, aAppl, aTopic, aItem );
1398 if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1399 return sal_True;
1402 return false;
1405 // XDDELinks
1407 uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
1408 const OUString& aApplication, const OUString& aTopic,
1409 const OUString& aItem, ::com::sun::star::sheet::DDELinkMode nMode )
1410 throw (uno::RuntimeException, std::exception)
1412 SolarMutexGuard aGuard;
1413 uno::Reference< sheet::XDDELink > xLink;
1415 if ( pDocShell )
1417 ScDocument& rDoc = pDocShell->GetDocument();
1418 sal_uInt8 nMod = SC_DDE_DEFAULT;
1419 switch ( nMode )
1421 case sheet::DDELinkMode_DEFAULT:
1423 nMod = SC_DDE_DEFAULT;
1425 break;
1426 case sheet::DDELinkMode_ENGLISH:
1428 nMod = SC_DDE_ENGLISH;
1430 break;
1431 case sheet::DDELinkMode_TEXT:
1433 nMod = SC_DDE_TEXT;
1435 break;
1436 default:
1439 break;
1442 if ( rDoc.CreateDdeLink( aApplication, aTopic, aItem, nMod, ScMatrixRef() ) )
1444 const OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) );
1445 xLink.set( GetObjectByName_Impl( aName ) );
1449 if ( !xLink.is() )
1451 throw uno::RuntimeException(
1452 "ScDDELinksObj::addDDELink: cannot add DDE link!" );
1455 return xLink;
1458 ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScDocShell* pDocShell, ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
1459 mpDocShell(pDocShell),
1460 mpTable(pTable),
1461 mnIndex(nIndex)
1465 ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
1469 void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue)
1470 throw (IllegalArgumentException, RuntimeException, std::exception)
1472 SolarMutexGuard aGuard;
1473 if (nRow < 0 || nCol < 0)
1474 throw IllegalArgumentException();
1476 ScExternalRefCache::TokenRef pToken;
1477 double fVal = 0.0;
1478 OUString aVal;
1479 if (rValue >>= fVal)
1480 pToken.reset(new FormulaDoubleToken(fVal));
1481 else if (rValue >>= aVal)
1483 svl::SharedStringPool& rPool = mpDocShell->GetDocument().GetSharedStringPool();
1484 svl::SharedString aSS = rPool.intern(aVal);
1485 pToken.reset(new FormulaStringToken(aSS));
1487 else
1488 // unidentified value type.
1489 return;
1491 mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken);
1494 Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow)
1495 throw (IllegalArgumentException, RuntimeException, std::exception)
1497 SolarMutexGuard aGuard;
1498 if (nRow < 0 || nCol < 0)
1499 throw IllegalArgumentException();
1501 FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get();
1502 if (!pToken)
1503 throw IllegalArgumentException();
1505 Any aValue;
1506 switch (pToken->GetType())
1508 case svDouble:
1510 double fVal = pToken->GetDouble();
1511 aValue <<= fVal;
1513 break;
1514 case svString:
1516 OUString aVal = pToken->GetString().getString();
1517 aValue <<= aVal;
1519 break;
1520 default:
1521 throw IllegalArgumentException();
1523 return aValue;
1526 Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows()
1527 throw (RuntimeException, std::exception)
1529 SolarMutexGuard aGuard;
1530 vector<SCROW> aRows;
1531 mpTable->getAllRows(aRows);
1532 size_t nSize = aRows.size();
1533 Sequence<sal_Int32> aRowsSeq(nSize);
1534 for (size_t i = 0; i < nSize; ++i)
1535 aRowsSeq[i] = aRows[i];
1537 return aRowsSeq;
1540 Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow)
1541 throw (IllegalArgumentException, RuntimeException, std::exception)
1543 SolarMutexGuard aGuard;
1544 if (nRow < 0)
1545 throw IllegalArgumentException();
1547 vector<SCCOL> aCols;
1548 mpTable->getAllCols(static_cast<SCROW>(nRow), aCols);
1549 size_t nSize = aCols.size();
1550 Sequence<sal_Int32> aColsSeq(nSize);
1551 for (size_t i = 0; i < nSize; ++i)
1552 aColsSeq[i] = aCols[i];
1554 return aColsSeq;
1557 sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
1558 throw (RuntimeException, std::exception)
1560 return static_cast< sal_Int32 >( mnIndex );
1563 ScExternalDocLinkObj::ScExternalDocLinkObj(ScDocShell* pDocShell, ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
1564 mpDocShell(pDocShell), mpRefMgr(pRefMgr), mnFileId(nFileId)
1568 ScExternalDocLinkObj::~ScExternalDocLinkObj()
1572 Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache(
1573 const OUString& aSheetName, sal_Bool bDynamicCache )
1574 throw (RuntimeException, std::exception)
1576 SolarMutexGuard aGuard;
1577 size_t nIndex = 0;
1578 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
1579 if (!bDynamicCache)
1580 // Set the whole table cached to prevent access to the source document.
1581 pTable->setWholeTableCached();
1583 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
1584 return aSheetCache;
1587 Any SAL_CALL ScExternalDocLinkObj::getByName(const OUString &aName)
1588 throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException, std::exception)
1590 SolarMutexGuard aGuard;
1591 size_t nIndex = 0;
1592 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex);
1593 if (!pTable)
1594 throw container::NoSuchElementException();
1596 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
1598 Any aAny;
1599 aAny <<= aSheetCache;
1600 return aAny;
1603 Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
1604 throw (RuntimeException, std::exception)
1606 SolarMutexGuard aGuard;
1607 vector<OUString> aTabNames;
1608 mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
1610 // #i116940# be consistent with getByName: include only table names which have a cache already
1611 vector<OUString> aValidNames;
1612 for (vector<OUString>::iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter)
1613 if (mpRefMgr->getCacheTable(mnFileId, *aIter, false))
1614 aValidNames.push_back(*aIter);
1616 size_t n = aValidNames.size();
1617 Sequence<OUString> aSeq(n);
1618 for (size_t i = 0; i < n; ++i)
1619 aSeq[i] = aValidNames[i];
1620 return aSeq;
1623 sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
1624 throw (RuntimeException, std::exception)
1626 SolarMutexGuard aGuard;
1628 // #i116940# be consistent with getByName: allow only table names which have a cache already
1629 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false);
1630 return (pTable.get() != NULL);
1633 sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
1634 throw (RuntimeException, std::exception)
1636 SolarMutexGuard aGuard;
1638 // #i116940# be consistent with getByName: count only table names which have a cache already
1639 return getElementNames().getLength();
1642 Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex)
1643 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException, std::exception)
1645 SolarMutexGuard aGuard;
1647 // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
1648 // the entries which have a cache already. Quick solution: Use getElementNames.
1649 Sequence< OUString > aNames( getElementNames() );
1650 if (nApiIndex < 0 || nApiIndex >= aNames.getLength())
1651 throw lang::IndexOutOfBoundsException();
1653 size_t nIndex = 0;
1654 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex);
1655 if (!pTable)
1656 throw lang::IndexOutOfBoundsException();
1658 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
1660 Any aAny;
1661 aAny <<= aSheetCache;
1662 return aAny;
1665 Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration()
1666 throw (RuntimeException, std::exception)
1668 SolarMutexGuard aGuard;
1669 Reference< container::XEnumeration > aRef(
1670 new ScIndexEnumeration(this, OUString(
1671 "com.sun.star.sheet.ExternalDocLink")));
1672 return aRef;
1675 uno::Type SAL_CALL ScExternalDocLinkObj::getElementType()
1676 throw (RuntimeException, std::exception)
1678 SolarMutexGuard aGuard;
1679 return cppu::UnoType<sheet::XExternalDocLink>::get();
1682 sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
1683 throw (RuntimeException, std::exception)
1685 SolarMutexGuard aGuard;
1687 // #i116940# be consistent with getByName: count only table names which have a cache already
1688 return ( getElementNames().getLength() > 0 );
1691 sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
1692 throw (RuntimeException, std::exception)
1694 return static_cast<sal_Int32>(mnFileId);
1697 ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
1698 mpDocShell(pDocShell),
1699 mpRefMgr(pDocShell->GetDocument().GetExternalRefManager())
1703 ScExternalDocLinksObj::~ScExternalDocLinksObj()
1707 Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink(
1708 const OUString& aDocName )
1709 throw (RuntimeException, std::exception)
1711 SolarMutexGuard aGuard;
1712 OUString aDocUrl( ScGlobal::GetAbsDocName( aDocName, mpDocShell));
1713 sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocUrl);
1714 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId));
1715 return aDocLink;
1718 Any SAL_CALL ScExternalDocLinksObj::getByName(const OUString &aName)
1719 throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException, std::exception)
1721 SolarMutexGuard aGuard;
1722 OUString aDocUrl( ScGlobal::GetAbsDocName( aName, mpDocShell));
1723 if (!mpRefMgr->hasExternalFile(aDocUrl))
1724 throw container::NoSuchElementException();
1726 sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocUrl);
1727 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId));
1729 Any aAny;
1730 aAny <<= aDocLink;
1731 return aAny;
1734 Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames()
1735 throw (RuntimeException, std::exception)
1737 SolarMutexGuard aGuard;
1738 sal_uInt16 n = mpRefMgr->getExternalFileCount();
1739 Sequence<OUString> aSeq(n);
1740 for (sal_uInt16 i = 0; i < n; ++i)
1742 const OUString* pName = mpRefMgr->getExternalFileName(i);
1743 aSeq[i] = pName ? *pName : OUString();
1746 return aSeq;
1749 sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName)
1750 throw (RuntimeException, std::exception)
1752 SolarMutexGuard aGuard;
1753 return mpRefMgr->hasExternalFile(aName);
1756 sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount()
1757 throw (RuntimeException, std::exception)
1759 SolarMutexGuard aGuard;
1760 return mpRefMgr->getExternalFileCount();
1763 Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex)
1764 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException, std::exception)
1766 SolarMutexGuard aGuard;
1767 if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min())
1768 throw lang::IndexOutOfBoundsException();
1770 sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex);
1772 if (!mpRefMgr->hasExternalFile(nFileId))
1773 throw lang::IndexOutOfBoundsException();
1775 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId));
1776 Any aAny;
1777 aAny <<= aDocLink;
1778 return aAny;
1781 Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration()
1782 throw (RuntimeException, std::exception)
1784 SolarMutexGuard aGuard;
1785 Reference< container::XEnumeration > aRef(
1786 new ScIndexEnumeration(this, OUString(
1787 "com.sun.star.sheet.ExternalDocLinks")));
1788 return aRef;
1791 uno::Type SAL_CALL ScExternalDocLinksObj::getElementType()
1792 throw (RuntimeException, std::exception)
1794 SolarMutexGuard aGuard;
1795 return cppu::UnoType<sheet::XExternalDocLinks>::get();
1798 sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements()
1799 throw (RuntimeException, std::exception)
1801 SolarMutexGuard aGuard;
1802 return mpRefMgr->getExternalFileCount() > 0;
1805 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */