Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / unoobj / linkuno.cxx
blob2d19a4631db0c036970f8fc51269183bebb7aba9
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"
35 #include "scmatrix.hxx"
37 #include <vector>
38 #include <climits>
40 using namespace com::sun::star;
41 using namespace formula;
42 using ::com::sun::star::uno::Any;
43 using ::com::sun::star::uno::Reference;
44 using ::com::sun::star::uno::Sequence;
45 using ::com::sun::star::uno::UNO_QUERY;
46 using ::com::sun::star::uno::UNO_QUERY_THROW;
47 using ::com::sun::star::lang::IllegalArgumentException;
48 using ::com::sun::star::uno::RuntimeException;
49 using ::std::vector;
51 //------------------------------------------------------------------------
53 // fuer Sheet- und Area-Links benutzt:
54 static const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap()
56 static const SfxItemPropertyMapEntry aSheetLinkMap_Impl[] =
58 {MAP_CHAR_LEN(SC_UNONAME_FILTER), 0, &getCppuType((OUString*)0), 0, 0 },
59 {MAP_CHAR_LEN(SC_UNONAME_FILTOPT), 0, &getCppuType((OUString*)0), 0, 0 },
60 {MAP_CHAR_LEN(SC_UNONAME_LINKURL), 0, &getCppuType((OUString*)0), 0, 0 },
61 {MAP_CHAR_LEN(SC_UNONAME_REFDELAY), 0, &getCppuType((sal_Int32*)0), 0, 0 },
62 {MAP_CHAR_LEN(SC_UNONAME_REFPERIOD), 0, &getCppuType((sal_Int32*)0), 0, 0 },
63 {0,0,0,0,0,0}
65 return aSheetLinkMap_Impl;
68 //------------------------------------------------------------------------
70 SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj, "ScAreaLinkObj", "com.sun.star.sheet.CellAreaLink" )
71 SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj, "ScAreaLinksObj", "com.sun.star.sheet.CellAreaLinks" )
72 SC_SIMPLE_SERVICE_INFO( ScDDELinkObj, "ScDDELinkObj", "com.sun.star.sheet.DDELink" )
73 SC_SIMPLE_SERVICE_INFO( ScDDELinksObj, "ScDDELinksObj", "com.sun.star.sheet.DDELinks" )
74 SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj, "ScSheetLinkObj", "com.sun.star.sheet.SheetLink" )
75 SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj, "ScSheetLinksObj", "com.sun.star.sheet.SheetLinks" )
77 //------------------------------------------------------------------------
79 ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const OUString& rName) :
80 aPropSet( lcl_GetSheetLinkMap() ),
81 pDocShell( pDocSh ),
82 aFileName( rName )
84 pDocShell->GetDocument()->AddUnoObject(*this);
87 ScSheetLinkObj::~ScSheetLinkObj()
89 if (pDocShell)
90 pDocShell->GetDocument()->RemoveUnoObject(*this);
93 void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
95 //! notify if links in document are changed
96 // UpdateRef is not needed here
98 if ( rHint.ISA( SfxSimpleHint ) )
100 if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
101 pDocShell = NULL; // pointer is invalid
103 else if ( rHint.ISA( ScLinkRefreshedHint ) )
105 const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
106 if ( rLH.GetLinkType() == SC_LINKREFTYPE_SHEET && rLH.GetUrl() == aFileName )
107 Refreshed_Impl();
111 ScTableLink* ScSheetLinkObj::GetLink_Impl() const
113 if (pDocShell)
115 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
116 size_t nCount = pLinkManager->GetLinks().size();
117 for (size_t i=0; i<nCount; i++)
119 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
120 if (pBase->ISA(ScTableLink))
122 ScTableLink* pTabLink = (ScTableLink*)pBase;
123 if ( pTabLink->GetFileName().equals(aFileName) )
124 return pTabLink;
128 return NULL; // nicht gefunden
131 // XNamed
133 OUString SAL_CALL ScSheetLinkObj::getName() throw(uno::RuntimeException)
135 SolarMutexGuard aGuard;
136 return getFileName(); // Name ist der Dateiname (URL)
139 void SAL_CALL ScSheetLinkObj::setName( const OUString& aName ) throw(uno::RuntimeException)
141 SolarMutexGuard aGuard;
142 setFileName(aName); // Name ist der Dateiname (URL)
145 // XRefreshable
147 void SAL_CALL ScSheetLinkObj::refresh() throw(uno::RuntimeException)
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)
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)
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)
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)
220 SolarMutexGuard aGuard;
221 OUString aNameString(aPropertyName);
222 OUString aValStr;
223 if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
225 if ( aValue >>= aValStr )
226 setFileName( aValStr );
228 else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
230 if ( aValue >>= aValStr )
231 setFilter( aValStr );
233 else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
235 if ( aValue >>= aValStr )
236 setFilterOptions( aValStr );
238 else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
240 sal_Int32 nRefresh = 0;
241 if ( aValue >>= nRefresh )
242 setRefreshDelay( nRefresh );
244 else if ( aNameString.equalsAscii( 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)
256 SolarMutexGuard aGuard;
257 OUString aNameString(aPropertyName);
258 uno::Any aRet;
259 if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
260 aRet <<= getFileName();
261 else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
262 aRet <<= getFilter();
263 else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
264 aRet <<= getFilterOptions();
265 else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
266 aRet <<= getRefreshDelay();
267 else if ( aNameString.equalsAscii( SC_UNONAME_REFDELAY ) )
268 aRet <<= getRefreshDelay();
269 return aRet;
272 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj )
274 // internal:
276 OUString ScSheetLinkObj::getFileName(void) 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* pDoc = pDocShell->GetDocument();
296 SCTAB nTabCount = pDoc->GetTableCount();
297 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
298 if ( pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab) == aFileName ) // alte Datei
299 pDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), aNewStr,
300 pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
301 pDoc->GetLinkTab(nTab),
302 pDoc->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(void) 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(void) 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(void) 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 //------------------------------------------------------------------------
379 ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) :
380 pDocShell( pDocSh )
382 pDocShell->GetDocument()->AddUnoObject(*this);
385 ScSheetLinksObj::~ScSheetLinksObj()
387 if (pDocShell)
388 pDocShell->GetDocument()->RemoveUnoObject(*this);
391 void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
393 // Referenz-Update interessiert hier nicht
395 if ( rHint.ISA( SfxSimpleHint ) &&
396 ((const SfxSimpleHint&)rHint).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 boost::unordered_set<OUString, OUStringHash> StrSetType;
410 StrSetType aNames;
411 ScDocument* pDoc = pDocShell->GetDocument();
412 SCTAB nTabCount = pDoc->GetTableCount();
413 sal_Int32 nCount = 0;
414 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
416 if (!pDoc->IsLinked(nTab))
417 continue;
419 OUString aLinkDoc = pDoc->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* pDoc = pDocShell->GetDocument();
441 SCTAB nTabCount = pDoc->GetTableCount();
442 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
443 if (pDoc->IsLinked(nTab))
445 //! case-insensitiv ???
446 OUString aLinkDoc = pDoc->GetLinkDoc( nTab );
447 if ( aLinkDoc == aNameStr )
448 return new ScSheetLinkObj( pDocShell, aNameStr );
452 return NULL;
455 // XEnumerationAccess
457 uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration()
458 throw(uno::RuntimeException)
460 SolarMutexGuard aGuard;
461 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.SheetLinksEnumeration"));
464 // XIndexAccess
466 sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException)
468 typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
470 SolarMutexGuard aGuard;
471 if (!pDocShell)
472 return 0;
474 sal_Int32 nCount = 0;
476 StrSetType aNames;
477 ScDocument* pDoc = pDocShell->GetDocument();
478 SCTAB nTabCount = pDoc->GetTableCount();
479 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
481 if (!pDoc->IsLinked(nTab))
482 continue;
484 OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
485 if (aNames.insert(aLinkDoc).second)
486 ++nCount;
488 return nCount;
491 uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex )
492 throw(lang::IndexOutOfBoundsException,
493 lang::WrappedTargetException, uno::RuntimeException)
495 SolarMutexGuard aGuard;
496 uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex));
497 if (xLink.is())
498 return uno::makeAny(xLink);
499 else
500 throw lang::IndexOutOfBoundsException();
503 uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException)
505 SolarMutexGuard aGuard;
506 return getCppuType((uno::Reference<beans::XPropertySet>*)0);
509 sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException)
511 SolarMutexGuard aGuard;
512 return ( getCount() != 0 );
515 uno::Any SAL_CALL ScSheetLinksObj::getByName( const OUString& aName )
516 throw(container::NoSuchElementException,
517 lang::WrappedTargetException, uno::RuntimeException)
519 SolarMutexGuard aGuard;
520 uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName));
521 if (xLink.is())
522 return uno::makeAny(xLink);
523 else
524 throw container::NoSuchElementException();
525 // return uno::Any();
528 sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const OUString& aName )
529 throw(uno::RuntimeException)
531 SolarMutexGuard aGuard;
532 // Name ist der Dateiname
534 if (pDocShell)
536 OUString aNameStr(aName);
538 ScDocument* pDoc = pDocShell->GetDocument();
539 SCTAB nTabCount = pDoc->GetTableCount();
540 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
541 if (pDoc->IsLinked(nTab))
543 //! case-insensitiv ???
544 OUString aLinkDoc(pDoc->GetLinkDoc( nTab ));
545 if ( aLinkDoc == aNameStr )
546 return sal_True;
549 return false;
552 uno::Sequence<OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException)
554 typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
556 SolarMutexGuard aGuard;
557 // Name ist der Dateiname
559 if (!pDocShell)
560 return uno::Sequence<OUString>();
562 StrSetType aNames;
563 ScDocument* pDoc = pDocShell->GetDocument();
564 SCTAB nTabCount = pDoc->GetTableCount();
566 sal_Int32 nLinkCount = getCount();
567 uno::Sequence<OUString> aSeq(nLinkCount);
568 OUString* pAry = aSeq.getArray();
569 size_t nPos = 0;
570 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
572 if (!pDoc->IsLinked(nTab))
573 continue;
575 OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
576 if (aNames.insert(aLinkDoc).second)
577 pAry[nPos++] = aLinkDoc;
579 OSL_ENSURE( nPos==static_cast<size_t>(nLinkCount), "verzaehlt" );
580 return aSeq;
583 //------------------------------------------------------------------------
585 static ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, size_t nPos )
587 if (pDocShell)
589 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
590 size_t nTotalCount = pLinkManager->GetLinks().size();
591 size_t nAreaCount = 0;
592 for (size_t i=0; i<nTotalCount; i++)
594 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
595 if (pBase->ISA(ScAreaLink))
597 if ( nAreaCount == nPos )
598 return static_cast<ScAreaLink*>(pBase);
599 ++nAreaCount;
603 return NULL; // nicht gefunden
606 ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, size_t nP) :
607 aPropSet( lcl_GetSheetLinkMap() ),
608 pDocShell( pDocSh ),
609 nPos( nP )
611 pDocShell->GetDocument()->AddUnoObject(*this);
614 ScAreaLinkObj::~ScAreaLinkObj()
616 if (pDocShell)
617 pDocShell->GetDocument()->RemoveUnoObject(*this);
620 void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
622 //! notify if links in document are changed
623 // UpdateRef is not needed here
625 if ( rHint.ISA( SfxSimpleHint ) )
627 if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
628 pDocShell = NULL; // pointer is invalid
630 else if ( rHint.ISA( ScLinkRefreshedHint ) )
632 const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
633 if ( rLH.GetLinkType() == SC_LINKREFTYPE_AREA )
635 // get this link to compare dest position
636 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
637 if ( pLink && pLink->GetDestArea().aStart == rLH.GetDestPos() )
638 Refreshed_Impl();
643 // XFileLink
645 void ScAreaLinkObj::Modify_Impl( const OUString* pNewFile, const OUString* pNewFilter,
646 const OUString* pNewOptions, const OUString* pNewSource,
647 const table::CellRangeAddress* pNewDest )
649 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
650 if (pLink)
652 OUString aFile (pLink->GetFile());
653 OUString aFilter (pLink->GetFilter());
654 OUString aOptions (pLink->GetOptions());
655 OUString aSource (pLink->GetSource());
656 ScRange aDest (pLink->GetDestArea());
657 sal_uLong nRefresh = pLink->GetRefreshDelay();
659 //! Undo fuer Loeschen
660 //! Undo zusammenfassen
662 sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
663 pLinkManager->Remove( pLink );
664 pLink = NULL; // bei Remove geloescht
666 sal_Bool bFitBlock = sal_True; // verschieben, wenn durch Update Groesse geaendert
667 if (pNewFile)
669 aFile = *pNewFile;
670 aFile = ScGlobal::GetAbsDocName( aFile, pDocShell ); //! in InsertAreaLink?
672 if (pNewFilter)
673 aFilter = *pNewFilter;
674 if (pNewOptions)
675 aOptions = *pNewOptions;
676 if (pNewSource)
677 aSource = *pNewSource;
678 if (pNewDest)
680 ScUnoConversion::FillScRange( aDest, *pNewDest );
681 bFitBlock = false; // neuer Bereich angegeben -> keine Inhalte verschieben
683 pDocShell->GetDocFunc().InsertAreaLink( aFile, aFilter, aOptions, aSource,
684 aDest, nRefresh, bFitBlock, sal_True );
688 void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
690 ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos );
691 if( pLink )
692 pLink->SetRefreshDelay( (sal_uLong) nRefresh );
695 // XRefreshable
697 void SAL_CALL ScAreaLinkObj::refresh() throw(uno::RuntimeException)
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)
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)
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)
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)
766 SolarMutexGuard aGuard;
767 OUString aNameString(aPropertyName);
768 OUString aValStr;
769 if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
771 if ( aValue >>= aValStr )
772 setFileName( aValStr );
774 else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
776 if ( aValue >>= aValStr )
777 setFilter( aValStr );
779 else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
781 if ( aValue >>= aValStr )
782 setFilterOptions( aValStr );
784 else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
786 sal_Int32 nRefresh = 0;
787 if ( aValue >>= nRefresh )
788 setRefreshDelay( nRefresh );
790 else if ( aNameString.equalsAscii( 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)
802 SolarMutexGuard aGuard;
803 OUString aNameString(aPropertyName);
804 uno::Any aRet;
805 if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
806 aRet <<= getFileName();
807 else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
808 aRet <<= getFilter();
809 else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
810 aRet <<= getFilterOptions();
811 else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
812 aRet <<= getRefreshDelay();
813 else if ( aNameString.equalsAscii( SC_UNONAME_REFDELAY ) )
814 aRet <<= getRefreshDelay();
815 return aRet;
818 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj )
820 // internal:
822 OUString ScAreaLinkObj::getFileName(void) 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(void) 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(void) 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(void) 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)
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)
901 SolarMutexGuard aGuard;
902 Modify_Impl( NULL, NULL, NULL, &aSourceArea, NULL );
905 table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() throw(uno::RuntimeException)
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)
918 SolarMutexGuard aGuard;
919 Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea );
922 //------------------------------------------------------------------------
924 ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) :
925 pDocShell( pDocSh )
927 pDocShell->GetDocument()->AddUnoObject(*this);
930 ScAreaLinksObj::~ScAreaLinksObj()
932 if (pDocShell)
933 pDocShell->GetDocument()->RemoveUnoObject(*this);
936 void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
938 // Referenz-Update interessiert hier nicht
940 if ( rHint.ISA( SfxSimpleHint ) &&
941 ((const SfxSimpleHint&)rHint).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)
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, sal_True ); // don't move contents
980 void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
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)
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)
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)
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)
1036 SolarMutexGuard aGuard;
1037 return getCppuType((uno::Reference<sheet::XAreaLink>*)0);
1040 sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException)
1042 SolarMutexGuard aGuard;
1043 return ( getCount() != 0 );
1046 //------------------------------------------------------------------------
1048 ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const OUString& rA,
1049 const OUString& rT, const OUString& rI) :
1050 pDocShell( pDocSh ),
1051 aAppl( rA ),
1052 aTopic( rT ),
1053 aItem( rI )
1055 pDocShell->GetDocument()->AddUnoObject(*this);
1058 ScDDELinkObj::~ScDDELinkObj()
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 if ( rHint.ISA( SfxSimpleHint ) )
1071 if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1072 pDocShell = NULL; // pointer is invalid
1074 else if ( rHint.ISA( ScLinkRefreshedHint ) )
1076 const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
1077 if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE &&
1078 rLH.GetDdeAppl() == aAppl &&
1079 rLH.GetDdeTopic() == aTopic &&
1080 rLH.GetDdeItem() == aItem ) //! mode is ignored
1081 Refreshed_Impl();
1085 // XNamed
1087 static OUString lcl_BuildDDEName( const OUString& rAppl, const OUString& rTopic, const OUString& rItem )
1089 // Appl|Topic!Item (wie Excel)
1090 OUString aRet = rAppl + "|" + rTopic + "!" + 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 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)
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 size_t 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 size_t 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 ( size_t 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 ( pDocShell->GetDocument()->GetDdeLinkData( (size_t)nIndex, aAppl, aTopic, aItem ) )
1290 return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1292 return NULL;
1295 ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const OUString& aName)
1297 if (pDocShell)
1299 OUString aNamStr(aName);
1300 OUString aAppl, aTopic, aItem;
1302 ScDocument* pDoc = pDocShell->GetDocument();
1303 size_t nCount = pDoc->GetDdeLinkCount();
1304 for (size_t i=0; i<nCount; i++)
1306 pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1307 if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1308 return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1311 return NULL;
1314 // XEnumerationAccess
1316 uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration()
1317 throw(uno::RuntimeException)
1319 SolarMutexGuard aGuard;
1320 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DDELinksEnumeration"));
1323 // XIndexAccess
1325 sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException)
1327 SolarMutexGuard aGuard;
1328 sal_Int32 nAreaCount = 0;
1329 if (pDocShell)
1330 nAreaCount = pDocShell->GetDocument()->GetDdeLinkCount();
1331 return nAreaCount;
1334 uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex )
1335 throw(lang::IndexOutOfBoundsException,
1336 lang::WrappedTargetException, uno::RuntimeException)
1338 SolarMutexGuard aGuard;
1339 uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex));
1340 if (xLink.is())
1341 return uno::makeAny(xLink);
1342 else
1343 throw lang::IndexOutOfBoundsException();
1346 uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException)
1348 SolarMutexGuard aGuard;
1349 return getCppuType((uno::Reference<sheet::XDDELink>*)0);
1352 sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException)
1354 SolarMutexGuard aGuard;
1355 return ( getCount() != 0 );
1358 uno::Any SAL_CALL ScDDELinksObj::getByName( const OUString& aName )
1359 throw(container::NoSuchElementException,
1360 lang::WrappedTargetException, uno::RuntimeException)
1362 SolarMutexGuard aGuard;
1363 uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName));
1364 if (xLink.is())
1365 return uno::makeAny(xLink);
1366 else
1367 throw container::NoSuchElementException();
1370 uno::Sequence<OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException)
1372 SolarMutexGuard aGuard;
1373 if (pDocShell)
1375 OUString aAppl, aTopic, aItem;
1377 ScDocument* pDoc = pDocShell->GetDocument();
1378 size_t nCount = pDoc->GetDdeLinkCount();
1379 uno::Sequence<OUString> aSeq(nCount);
1380 OUString* pAry = aSeq.getArray();
1382 for (size_t i=0; i<nCount; i++)
1384 pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1385 pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem);
1387 return aSeq;
1389 return uno::Sequence<OUString>();
1392 sal_Bool SAL_CALL ScDDELinksObj::hasByName( const OUString& aName )
1393 throw(uno::RuntimeException)
1395 SolarMutexGuard aGuard;
1396 if (pDocShell)
1398 OUString aNamStr(aName);
1399 OUString aAppl, aTopic, aItem;
1401 ScDocument* pDoc = pDocShell->GetDocument();
1402 size_t nCount = pDoc->GetDdeLinkCount();
1403 for (size_t i=0; i<nCount; i++)
1405 pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1406 if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1407 return sal_True;
1410 return false;
1413 // XDDELinks
1415 uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
1416 const OUString& aApplication, const OUString& aTopic,
1417 const OUString& aItem, ::com::sun::star::sheet::DDELinkMode nMode )
1418 throw (uno::RuntimeException)
1420 SolarMutexGuard aGuard;
1421 uno::Reference< sheet::XDDELink > xLink;
1423 if ( pDocShell )
1425 ScDocument* pDoc = pDocShell->GetDocument();
1426 if ( pDoc )
1428 sal_uInt8 nMod = SC_DDE_DEFAULT;
1429 switch ( nMode )
1431 case sheet::DDELinkMode_DEFAULT:
1433 nMod = SC_DDE_DEFAULT;
1435 break;
1436 case sheet::DDELinkMode_ENGLISH:
1438 nMod = SC_DDE_ENGLISH;
1440 break;
1441 case sheet::DDELinkMode_TEXT:
1443 nMod = SC_DDE_TEXT;
1445 break;
1446 default:
1449 break;
1452 if ( pDoc->CreateDdeLink( aApplication, aTopic, aItem, nMod, ScMatrixRef() ) )
1454 const OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) );
1455 xLink.set( GetObjectByName_Impl( aName ) );
1460 if ( !xLink.is() )
1462 throw uno::RuntimeException( OUString(
1463 "ScDDELinksObj::addDDELink: cannot add DDE link!" ),
1464 uno::Reference< uno::XInterface >() );
1467 return xLink;
1470 // ============================================================================
1472 ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
1473 mpTable(pTable),
1474 mnIndex(nIndex)
1478 ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
1482 void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue)
1483 throw (IllegalArgumentException, RuntimeException)
1485 SolarMutexGuard aGuard;
1486 if (nRow < 0 || nCol < 0)
1487 throw IllegalArgumentException();
1489 ScExternalRefCache::TokenRef pToken;
1490 double fVal = 0.0;
1491 OUString aVal;
1492 if (rValue >>= fVal)
1493 pToken.reset(new FormulaDoubleToken(fVal));
1494 else if (rValue >>= aVal)
1495 pToken.reset(new FormulaStringToken(aVal));
1496 else
1497 // unidentified value type.
1498 return;
1500 mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken);
1503 Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow)
1504 throw (IllegalArgumentException, RuntimeException)
1506 SolarMutexGuard aGuard;
1507 if (nRow < 0 || nCol < 0)
1508 throw IllegalArgumentException();
1510 FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get();
1511 if (!pToken)
1512 throw IllegalArgumentException();
1514 Any aValue;
1515 switch (pToken->GetType())
1517 case svDouble:
1519 double fVal = pToken->GetDouble();
1520 aValue <<= fVal;
1522 break;
1523 case svString:
1525 OUString aVal = pToken->GetString().getString();
1526 aValue <<= aVal;
1528 break;
1529 default:
1530 throw IllegalArgumentException();
1532 return aValue;
1535 Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows()
1536 throw (RuntimeException)
1538 SolarMutexGuard aGuard;
1539 vector<SCROW> aRows;
1540 mpTable->getAllRows(aRows);
1541 size_t nSize = aRows.size();
1542 Sequence<sal_Int32> aRowsSeq(nSize);
1543 for (size_t i = 0; i < nSize; ++i)
1544 aRowsSeq[i] = aRows[i];
1546 return aRowsSeq;
1549 Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow)
1550 throw (IllegalArgumentException, RuntimeException)
1552 SolarMutexGuard aGuard;
1553 if (nRow < 0)
1554 throw IllegalArgumentException();
1556 vector<SCCOL> aCols;
1557 mpTable->getAllCols(static_cast<SCROW>(nRow), aCols);
1558 size_t nSize = aCols.size();
1559 Sequence<sal_Int32> aColsSeq(nSize);
1560 for (size_t i = 0; i < nSize; ++i)
1561 aColsSeq[i] = aCols[i];
1563 return aColsSeq;
1566 sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
1567 throw (RuntimeException)
1569 return static_cast< sal_Int32 >( mnIndex );
1572 // ============================================================================
1574 ScExternalDocLinkObj::ScExternalDocLinkObj(ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
1575 mpRefMgr(pRefMgr), mnFileId(nFileId)
1579 ScExternalDocLinkObj::~ScExternalDocLinkObj()
1583 Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache(
1584 const OUString& aSheetName, sal_Bool bDynamicCache )
1585 throw (RuntimeException)
1587 SolarMutexGuard aGuard;
1588 size_t nIndex = 0;
1589 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
1590 if (!bDynamicCache)
1591 // Set the whole table cached to prevent access to the source document.
1592 pTable->setWholeTableCached();
1594 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1595 return aSheetCache;
1598 Any SAL_CALL ScExternalDocLinkObj::getByName(const OUString &aName)
1599 throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
1601 SolarMutexGuard aGuard;
1602 size_t nIndex = 0;
1603 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex);
1604 if (!pTable)
1605 throw container::NoSuchElementException();
1607 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1609 Any aAny;
1610 aAny <<= aSheetCache;
1611 return aAny;
1614 Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
1615 throw (RuntimeException)
1617 SolarMutexGuard aGuard;
1618 vector<OUString> aTabNames;
1619 mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
1621 // #i116940# be consistent with getByName: include only table names which have a cache already
1622 vector<OUString> aValidNames;
1623 for (vector<OUString>::iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter)
1624 if (mpRefMgr->getCacheTable(mnFileId, *aIter, false))
1625 aValidNames.push_back(*aIter);
1627 size_t n = aValidNames.size();
1628 Sequence<OUString> aSeq(n);
1629 for (size_t i = 0; i < n; ++i)
1630 aSeq[i] = aValidNames[i];
1631 return aSeq;
1634 sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
1635 throw (RuntimeException)
1637 SolarMutexGuard aGuard;
1639 // #i116940# be consistent with getByName: allow only table names which have a cache already
1640 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false);
1641 return (pTable.get() != NULL);
1644 sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
1645 throw (RuntimeException)
1647 SolarMutexGuard aGuard;
1649 // #i116940# be consistent with getByName: count only table names which have a cache already
1650 return getElementNames().getLength();
1653 Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex)
1654 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
1656 SolarMutexGuard aGuard;
1658 // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
1659 // the entries which have a cache already. Quick solution: Use getElementNames.
1660 Sequence< OUString > aNames( getElementNames() );
1661 if (nApiIndex < 0 || nApiIndex >= aNames.getLength())
1662 throw lang::IndexOutOfBoundsException();
1664 size_t nIndex = 0;
1665 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex);
1666 if (!pTable)
1667 throw lang::IndexOutOfBoundsException();
1669 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1671 Any aAny;
1672 aAny <<= aSheetCache;
1673 return aAny;
1676 Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration()
1677 throw (RuntimeException)
1679 SolarMutexGuard aGuard;
1680 Reference< container::XEnumeration > aRef(
1681 new ScIndexEnumeration(this, OUString(
1682 "com.sun.star.sheet.ExternalDocLink")));
1683 return aRef;
1686 uno::Type SAL_CALL ScExternalDocLinkObj::getElementType()
1687 throw (RuntimeException)
1689 SolarMutexGuard aGuard;
1690 return getCppuType(static_cast<Reference<sheet::XExternalDocLink>*>(0));
1693 sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
1694 throw (RuntimeException)
1696 SolarMutexGuard aGuard;
1698 // #i116940# be consistent with getByName: count only table names which have a cache already
1699 return ( getElementNames().getLength() > 0 );
1702 sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
1703 throw (RuntimeException)
1705 return static_cast<sal_Int32>(mnFileId);
1708 // ============================================================================
1710 ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
1711 mpDocShell(pDocShell),
1712 mpRefMgr(pDocShell->GetDocument()->GetExternalRefManager())
1716 ScExternalDocLinksObj::~ScExternalDocLinksObj()
1720 Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink(
1721 const OUString& aDocName )
1722 throw (RuntimeException)
1724 SolarMutexGuard aGuard;
1725 sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocName);
1726 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1727 return aDocLink;
1730 Any SAL_CALL ScExternalDocLinksObj::getByName(const OUString &aName)
1731 throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
1733 SolarMutexGuard aGuard;
1734 if (!mpRefMgr->hasExternalFile(aName))
1735 throw container::NoSuchElementException();
1737 sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aName);
1738 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1740 Any aAny;
1741 aAny <<= aDocLink;
1742 return aAny;
1745 Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames()
1746 throw (RuntimeException)
1748 SolarMutexGuard aGuard;
1749 sal_uInt16 n = mpRefMgr->getExternalFileCount();
1750 Sequence<OUString> aSeq(n);
1751 for (sal_uInt16 i = 0; i < n; ++i)
1753 const OUString* pName = mpRefMgr->getExternalFileName(i);
1754 aSeq[i] = pName ? *pName : OUString();
1757 return aSeq;
1760 sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName)
1761 throw (RuntimeException)
1763 SolarMutexGuard aGuard;
1764 return mpRefMgr->hasExternalFile(aName);
1767 sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount()
1768 throw (RuntimeException)
1770 SolarMutexGuard aGuard;
1771 return mpRefMgr->getExternalFileCount();
1774 Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex)
1775 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
1777 SolarMutexGuard aGuard;
1778 if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min())
1779 throw lang::IndexOutOfBoundsException();
1781 sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex);
1783 if (!mpRefMgr->hasExternalFile(nFileId))
1784 throw lang::IndexOutOfBoundsException();
1786 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1787 Any aAny;
1788 aAny <<= aDocLink;
1789 return aAny;
1792 Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration()
1793 throw (RuntimeException)
1795 SolarMutexGuard aGuard;
1796 Reference< container::XEnumeration > aRef(
1797 new ScIndexEnumeration(this, OUString(
1798 "com.sun.star.sheet.ExternalDocLinks")));
1799 return aRef;
1802 uno::Type SAL_CALL ScExternalDocLinksObj::getElementType()
1803 throw (RuntimeException)
1805 SolarMutexGuard aGuard;
1806 return getCppuType(static_cast<Reference<sheet::XExternalDocLinks>*>(0));
1809 sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements()
1810 throw (RuntimeException)
1812 SolarMutexGuard aGuard;
1813 return mpRefMgr->getExternalFileCount() > 0;
1816 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */