update dev300-m58
[ooovba.git] / sc / source / ui / unoobj / linkuno.cxx
blob0b17a028189a9ce5930df410d2eb5943bb091845
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: linkuno.cxx,v $
10 * $Revision: 1.18.134.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 #include <svtools/smplhint.hxx>
37 #include <svx/linkmgr.hxx>
39 #include "linkuno.hxx"
40 #include "miscuno.hxx"
41 #include "convuno.hxx"
42 #include "docsh.hxx"
43 #include "docfunc.hxx"
44 #include "collect.hxx"
45 #include "tablink.hxx"
46 #include "arealink.hxx"
47 #include "unoguard.hxx"
48 #include "hints.hxx"
49 #include "unonames.hxx"
50 #include "rangeseq.hxx"
51 #include "token.hxx"
53 #include <vector>
54 #include <climits>
56 using namespace com::sun::star;
57 using namespace formula;
58 using ::com::sun::star::uno::Any;
59 using ::com::sun::star::uno::Reference;
60 using ::com::sun::star::uno::Sequence;
61 using ::com::sun::star::uno::UNO_QUERY;
62 using ::com::sun::star::uno::UNO_QUERY_THROW;
63 using ::com::sun::star::lang::IllegalArgumentException;
64 using ::com::sun::star::uno::RuntimeException;
65 using ::rtl::OUString;
66 using ::std::vector;
68 //------------------------------------------------------------------------
70 // fuer Sheet- und Area-Links benutzt:
71 const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap()
73 static SfxItemPropertyMapEntry aSheetLinkMap_Impl[] =
75 {MAP_CHAR_LEN(SC_UNONAME_FILTER), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
76 {MAP_CHAR_LEN(SC_UNONAME_FILTOPT), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
77 {MAP_CHAR_LEN(SC_UNONAME_LINKURL), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
78 {MAP_CHAR_LEN(SC_UNONAME_REFDELAY), 0, &getCppuType((sal_Int32*)0), 0, 0 },
79 {MAP_CHAR_LEN(SC_UNONAME_REFPERIOD), 0, &getCppuType((sal_Int32*)0), 0, 0 },
80 {0,0,0,0,0,0}
82 return aSheetLinkMap_Impl;
85 //------------------------------------------------------------------------
87 SV_IMPL_PTRARR( XRefreshListenerArr_Impl, XRefreshListenerPtr );
89 SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj, "ScAreaLinkObj", "com.sun.star.sheet.CellAreaLink" )
90 SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj, "ScAreaLinksObj", "com.sun.star.sheet.CellAreaLinks" )
91 SC_SIMPLE_SERVICE_INFO( ScDDELinkObj, "ScDDELinkObj", "com.sun.star.sheet.DDELink" )
92 SC_SIMPLE_SERVICE_INFO( ScDDELinksObj, "ScDDELinksObj", "com.sun.star.sheet.DDELinks" )
93 SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj, "ScSheetLinkObj", "com.sun.star.sheet.SheetLink" )
94 SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj, "ScSheetLinksObj", "com.sun.star.sheet.SheetLinks" )
96 //------------------------------------------------------------------------
98 ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const String& rName) :
99 aPropSet( lcl_GetSheetLinkMap() ),
100 pDocShell( pDocSh ),
101 aFileName( rName )
103 pDocShell->GetDocument()->AddUnoObject(*this);
106 ScSheetLinkObj::~ScSheetLinkObj()
108 if (pDocShell)
109 pDocShell->GetDocument()->RemoveUnoObject(*this);
112 void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
114 //! notify if links in document are changed
115 // UpdateRef is not needed here
117 if ( rHint.ISA( SfxSimpleHint ) )
119 if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
120 pDocShell = NULL; // pointer is invalid
122 else if ( rHint.ISA( ScLinkRefreshedHint ) )
124 const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
125 if ( rLH.GetLinkType() == SC_LINKREFTYPE_SHEET && rLH.GetUrl() == aFileName )
126 Refreshed_Impl();
130 ScTableLink* ScSheetLinkObj::GetLink_Impl() const
132 if (pDocShell)
134 SvxLinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
135 USHORT nCount = pLinkManager->GetLinks().Count();
136 for (USHORT i=0; i<nCount; i++)
138 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
139 if (pBase->ISA(ScTableLink))
141 ScTableLink* pTabLink = (ScTableLink*)pBase;
142 if ( pTabLink->GetFileName() == aFileName )
143 return pTabLink;
147 return NULL; // nicht gefunden
150 // XNamed
152 rtl::OUString SAL_CALL ScSheetLinkObj::getName() throw(uno::RuntimeException)
154 ScUnoGuard aGuard;
155 return getFileName(); // Name ist der Dateiname (URL)
158 void SAL_CALL ScSheetLinkObj::setName( const rtl::OUString& aName ) throw(uno::RuntimeException)
160 ScUnoGuard aGuard;
161 setFileName(aName); // Name ist der Dateiname (URL)
164 // XRefreshable
166 void SAL_CALL ScSheetLinkObj::refresh() throw(uno::RuntimeException)
168 ScUnoGuard aGuard;
169 ScTableLink* pLink = GetLink_Impl();
170 if (pLink)
171 pLink->Refresh( pLink->GetFileName(), pLink->GetFilterName(), NULL, pLink->GetRefreshDelay() );
174 void SAL_CALL ScSheetLinkObj::addRefreshListener(
175 const uno::Reference<util::XRefreshListener >& xListener )
176 throw(uno::RuntimeException)
178 ScUnoGuard aGuard;
179 uno::Reference<util::XRefreshListener>* pObj =
180 new uno::Reference<util::XRefreshListener>( xListener );
181 aRefreshListeners.Insert( pObj, aRefreshListeners.Count() );
183 // hold one additional ref to keep this object alive as long as there are listeners
184 if ( aRefreshListeners.Count() == 1 )
185 acquire();
188 void SAL_CALL ScSheetLinkObj::removeRefreshListener(
189 const uno::Reference<util::XRefreshListener >& xListener )
190 throw(uno::RuntimeException)
192 ScUnoGuard aGuard;
193 USHORT nCount = aRefreshListeners.Count();
194 for ( USHORT n=nCount; n--; )
196 uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n];
197 if ( *pObj == xListener )
199 aRefreshListeners.DeleteAndDestroy( n );
200 if ( aRefreshListeners.Count() == 0 )
201 release(); // release ref for listeners
202 break;
207 void ScSheetLinkObj::Refreshed_Impl()
209 lang::EventObject aEvent;
210 aEvent.Source.set((cppu::OWeakObject*)this);
211 for ( USHORT n=0; n<aRefreshListeners.Count(); n++ )
212 (*aRefreshListeners[n])->refreshed( aEvent );
215 void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
217 ScTableLink* pLink = GetLink_Impl();
218 if( pLink )
219 pLink->SetRefreshDelay( (ULONG) nRefresh );
222 // XPropertySet
224 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSheetLinkObj::getPropertySetInfo()
225 throw(uno::RuntimeException)
227 ScUnoGuard aGuard;
228 static uno::Reference<beans::XPropertySetInfo> aRef(
229 new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
230 return aRef;
233 void SAL_CALL ScSheetLinkObj::setPropertyValue(
234 const rtl::OUString& aPropertyName, const uno::Any& aValue )
235 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
236 lang::IllegalArgumentException, lang::WrappedTargetException,
237 uno::RuntimeException)
239 ScUnoGuard aGuard;
240 String aNameString(aPropertyName);
241 rtl::OUString aValStr;
242 if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
244 if ( aValue >>= aValStr )
245 setFileName( aValStr );
247 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
249 if ( aValue >>= aValStr )
250 setFilter( aValStr );
252 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
254 if ( aValue >>= aValStr )
255 setFilterOptions( aValStr );
257 else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
259 sal_Int32 nRefresh = 0;
260 if ( aValue >>= nRefresh )
261 setRefreshDelay( nRefresh );
263 else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
265 sal_Int32 nRefresh = 0;
266 if ( aValue >>= nRefresh )
267 setRefreshDelay( nRefresh );
271 uno::Any SAL_CALL ScSheetLinkObj::getPropertyValue( const rtl::OUString& aPropertyName )
272 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
273 uno::RuntimeException)
275 ScUnoGuard aGuard;
276 String aNameString(aPropertyName);
277 uno::Any aRet;
278 if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
279 aRet <<= getFileName();
280 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
281 aRet <<= getFilter();
282 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
283 aRet <<= getFilterOptions();
284 else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
285 aRet <<= getRefreshDelay();
286 else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
287 aRet <<= getRefreshDelay();
288 return aRet;
291 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj )
293 // internal:
295 rtl::OUString ScSheetLinkObj::getFileName(void) const
297 ScUnoGuard aGuard;
298 return aFileName;
301 void ScSheetLinkObj::setFileName(const rtl::OUString& rNewName)
303 ScUnoGuard aGuard;
304 ScTableLink* pLink = GetLink_Impl();
305 if (pLink)
307 // pLink->Refresh mit neuem Dateinamen bringt SvxLinkManager durcheinander
308 // darum per Hand die Tabellen umsetzen und Link per UpdateLinks neu erzeugen
310 String aNewStr(ScGlobal::GetAbsDocName( String(rNewName), pDocShell ));
312 // zuerst Tabellen umsetzen
314 ScDocument* pDoc = pDocShell->GetDocument();
315 SCTAB nTabCount = pDoc->GetTableCount();
316 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
317 if ( pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab) == aFileName ) // alte Datei
318 pDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), aNewStr,
319 pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
320 pDoc->GetLinkTab(nTab),
321 pDoc->GetLinkRefreshDelay(nTab) ); // nur Datei aendern
323 // Links updaten
324 //! Undo !!!
326 pLink = NULL; // wird bei UpdateLinks ungueltig
327 pDocShell->UpdateLinks(); // alter Link raus, evtl. neuen Link anlegen
329 // Daten kopieren
331 aFileName = aNewStr;
332 pLink = GetLink_Impl(); // neuer Link mit neuem Namen
333 if (pLink)
334 pLink->Update(); // inkl. Paint & Undo fuer Daten
338 rtl::OUString ScSheetLinkObj::getFilter(void) const
340 ScUnoGuard aGuard;
341 rtl::OUString aRet;
342 ScTableLink* pLink = GetLink_Impl();
343 if (pLink)
344 aRet = pLink->GetFilterName();
345 return aRet;
348 void ScSheetLinkObj::setFilter(const rtl::OUString& Filter)
350 ScUnoGuard aGuard;
351 ScTableLink* pLink = GetLink_Impl();
352 if (pLink)
354 String aFilterStr(Filter);
355 pLink->Refresh( aFileName, aFilterStr, NULL, pLink->GetRefreshDelay() );
359 rtl::OUString ScSheetLinkObj::getFilterOptions(void) const
361 ScUnoGuard aGuard;
362 rtl::OUString aRet;
363 ScTableLink* pLink = GetLink_Impl();
364 if (pLink)
365 aRet = pLink->GetOptions();
366 return aRet;
369 void ScSheetLinkObj::setFilterOptions(const rtl::OUString& FilterOptions)
371 ScUnoGuard aGuard;
372 ScTableLink* pLink = GetLink_Impl();
373 if (pLink)
375 String aOptStr(FilterOptions);
376 pLink->Refresh( aFileName, pLink->GetFilterName(), &aOptStr, pLink->GetRefreshDelay() );
380 sal_Int32 ScSheetLinkObj::getRefreshDelay(void) const
382 ScUnoGuard aGuard;
383 sal_Int32 nRet = 0;
384 ScTableLink* pLink = GetLink_Impl();
385 if (pLink)
386 nRet = (sal_Int32) pLink->GetRefreshDelay();
387 return nRet;
390 void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
392 ScUnoGuard aGuard;
393 ModifyRefreshDelay_Impl( nRefreshDelay );
396 //------------------------------------------------------------------------
398 ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) :
399 pDocShell( pDocSh )
401 pDocShell->GetDocument()->AddUnoObject(*this);
404 ScSheetLinksObj::~ScSheetLinksObj()
406 if (pDocShell)
407 pDocShell->GetDocument()->RemoveUnoObject(*this);
410 void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
412 // Referenz-Update interessiert hier nicht
414 if ( rHint.ISA( SfxSimpleHint ) &&
415 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
417 pDocShell = NULL; // ungueltig geworden
421 // XSheetLinks
423 ScSheetLinkObj* ScSheetLinksObj::GetObjectByIndex_Impl(INT32 nIndex)
425 if (pDocShell)
427 INT32 nCount = 0;
428 ScStrCollection aNames; // um doppelte wegzulassen
429 ScDocument* pDoc = pDocShell->GetDocument();
430 SCTAB nTabCount = pDoc->GetTableCount();
431 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
432 if (pDoc->IsLinked(nTab))
434 String aLinkDoc = pDoc->GetLinkDoc( nTab );
435 StrData* pData = new StrData(aLinkDoc);
436 if (aNames.Insert(pData))
438 if ( nCount == nIndex )
439 return new ScSheetLinkObj( pDocShell, aLinkDoc );
440 ++nCount;
442 else
443 delete pData;
446 return NULL; // kein Dokument oder Index zu gross
449 ScSheetLinkObj* ScSheetLinksObj::GetObjectByName_Impl(const rtl::OUString& aName)
451 // Name ist der Dateiname
453 if (pDocShell)
455 String aNameStr(aName);
457 ScDocument* pDoc = pDocShell->GetDocument();
458 SCTAB nTabCount = pDoc->GetTableCount();
459 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
460 if (pDoc->IsLinked(nTab))
462 //! case-insensitiv ???
463 String aLinkDoc = pDoc->GetLinkDoc( nTab );
464 if ( aLinkDoc == aNameStr )
465 return new ScSheetLinkObj( pDocShell, aNameStr );
469 return NULL;
472 // XEnumerationAccess
474 uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration()
475 throw(uno::RuntimeException)
477 ScUnoGuard aGuard;
478 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetLinksEnumeration")));
481 // XIndexAccess
483 sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException)
485 ScUnoGuard aGuard;
486 INT32 nCount = 0;
487 if (pDocShell)
489 ScStrCollection aNames; // um doppelte wegzulassen
490 ScDocument* pDoc = pDocShell->GetDocument();
491 SCTAB nTabCount = pDoc->GetTableCount();
492 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
493 if (pDoc->IsLinked(nTab))
495 String aLinkDoc(pDoc->GetLinkDoc( nTab ));
496 StrData* pData = new StrData(aLinkDoc);
497 if (aNames.Insert(pData))
498 ++nCount;
499 else
500 delete pData;
503 return nCount;
506 uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex )
507 throw(lang::IndexOutOfBoundsException,
508 lang::WrappedTargetException, uno::RuntimeException)
510 ScUnoGuard aGuard;
511 uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex));
512 if (xLink.is())
513 return uno::makeAny(xLink);
514 else
515 throw lang::IndexOutOfBoundsException();
516 // return uno::Any();
519 uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException)
521 ScUnoGuard aGuard;
522 return getCppuType((uno::Reference<beans::XPropertySet>*)0);
525 sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException)
527 ScUnoGuard aGuard;
528 return ( getCount() != 0 );
531 uno::Any SAL_CALL ScSheetLinksObj::getByName( const rtl::OUString& aName )
532 throw(container::NoSuchElementException,
533 lang::WrappedTargetException, uno::RuntimeException)
535 ScUnoGuard aGuard;
536 uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName));
537 if (xLink.is())
538 return uno::makeAny(xLink);
539 else
540 throw container::NoSuchElementException();
541 // return uno::Any();
544 sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const rtl::OUString& aName )
545 throw(uno::RuntimeException)
547 ScUnoGuard aGuard;
548 // Name ist der Dateiname
550 if (pDocShell)
552 String aNameStr(aName);
554 ScDocument* pDoc = pDocShell->GetDocument();
555 SCTAB nTabCount = pDoc->GetTableCount();
556 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
557 if (pDoc->IsLinked(nTab))
559 //! case-insensitiv ???
560 String aLinkDoc(pDoc->GetLinkDoc( nTab ));
561 if ( aLinkDoc == aNameStr )
562 return TRUE;
565 return FALSE;
568 uno::Sequence<rtl::OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException)
570 ScUnoGuard aGuard;
571 // Name ist der Dateiname
573 if (pDocShell)
575 ScStrCollection aNames; // um doppelte wegzulassen
576 ScDocument* pDoc = pDocShell->GetDocument();
577 SCTAB nTabCount = pDoc->GetTableCount();
578 String aName;
580 INT32 nLinkCount = getCount();
581 uno::Sequence<rtl::OUString> aSeq(nLinkCount);
582 rtl::OUString* pAry = aSeq.getArray();
583 USHORT nPos = 0;
584 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
586 if (pDoc->IsLinked(nTab))
588 String aLinkDoc(pDoc->GetLinkDoc( nTab ));
589 StrData* pData = new StrData(aLinkDoc);
590 if (aNames.Insert(pData))
591 pAry[nPos++] = aLinkDoc;
592 else
593 delete pData;
596 DBG_ASSERT( nPos==nLinkCount, "verzaehlt" );
597 return aSeq;
599 return uno::Sequence<rtl::OUString>();
602 //------------------------------------------------------------------------
604 ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, USHORT nPos )
606 if (pDocShell)
608 SvxLinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
609 USHORT nTotalCount = pLinkManager->GetLinks().Count();
610 USHORT nAreaCount = 0;
611 for (USHORT i=0; i<nTotalCount; i++)
613 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
614 if (pBase->ISA(ScAreaLink))
616 if ( nAreaCount == nPos )
617 return (ScAreaLink*)pBase;
618 ++nAreaCount;
622 return NULL; // nicht gefunden
625 ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, USHORT nP) :
626 aPropSet( lcl_GetSheetLinkMap() ),
627 pDocShell( pDocSh ),
628 nPos( nP )
630 pDocShell->GetDocument()->AddUnoObject(*this);
633 ScAreaLinkObj::~ScAreaLinkObj()
635 if (pDocShell)
636 pDocShell->GetDocument()->RemoveUnoObject(*this);
639 void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
641 //! notify if links in document are changed
642 // UpdateRef is not needed here
644 if ( rHint.ISA( SfxSimpleHint ) )
646 if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
647 pDocShell = NULL; // pointer is invalid
649 else if ( rHint.ISA( ScLinkRefreshedHint ) )
651 const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
652 if ( rLH.GetLinkType() == SC_LINKREFTYPE_AREA )
654 // get this link to compare dest position
655 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
656 if ( pLink && pLink->GetDestArea().aStart == rLH.GetDestPos() )
657 Refreshed_Impl();
662 // XFileLink
664 void ScAreaLinkObj::Modify_Impl( const rtl::OUString* pNewFile, const rtl::OUString* pNewFilter,
665 const rtl::OUString* pNewOptions, const rtl::OUString* pNewSource,
666 const table::CellRangeAddress* pNewDest )
668 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
669 if (pLink)
671 String aFile (pLink->GetFile());
672 String aFilter (pLink->GetFilter());
673 String aOptions (pLink->GetOptions());
674 String aSource (pLink->GetSource());
675 ScRange aDest (pLink->GetDestArea());
676 ULONG nRefresh = pLink->GetRefreshDelay();
678 //! Undo fuer Loeschen
679 //! Undo zusammenfassen
681 SvxLinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
682 pLinkManager->Remove( pLink );
683 pLink = NULL; // bei Remove geloescht
685 BOOL bFitBlock = TRUE; // verschieben, wenn durch Update Groesse geaendert
686 if (pNewFile)
688 aFile = String( *pNewFile );
689 aFile = ScGlobal::GetAbsDocName( aFile, pDocShell ); //! in InsertAreaLink?
691 if (pNewFilter)
692 aFilter = String( *pNewFilter );
693 if (pNewOptions)
694 aOptions = String( *pNewOptions );
695 if (pNewSource)
696 aSource = String( *pNewSource );
697 if (pNewDest)
699 ScUnoConversion::FillScRange( aDest, *pNewDest );
700 bFitBlock = FALSE; // neuer Bereich angegeben -> keine Inhalte verschieben
703 ScDocFunc aFunc(*pDocShell);
704 aFunc.InsertAreaLink( aFile, aFilter, aOptions, aSource, aDest, nRefresh, bFitBlock, TRUE );
708 void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
710 ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos );
711 if( pLink )
712 pLink->SetRefreshDelay( (ULONG) nRefresh );
715 // XRefreshable
717 void SAL_CALL ScAreaLinkObj::refresh() throw(uno::RuntimeException)
719 ScUnoGuard aGuard;
720 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
721 if (pLink)
722 pLink->Refresh( pLink->GetFile(), pLink->GetFilter(), pLink->GetSource(), pLink->GetRefreshDelay() );
725 void SAL_CALL ScAreaLinkObj::addRefreshListener(
726 const uno::Reference<util::XRefreshListener >& xListener )
727 throw(uno::RuntimeException)
729 ScUnoGuard aGuard;
730 uno::Reference<util::XRefreshListener>* pObj =
731 new uno::Reference<util::XRefreshListener>( xListener );
732 aRefreshListeners.Insert( pObj, aRefreshListeners.Count() );
734 // hold one additional ref to keep this object alive as long as there are listeners
735 if ( aRefreshListeners.Count() == 1 )
736 acquire();
739 void SAL_CALL ScAreaLinkObj::removeRefreshListener(
740 const uno::Reference<util::XRefreshListener >& xListener )
741 throw(uno::RuntimeException)
743 ScUnoGuard aGuard;
744 USHORT nCount = aRefreshListeners.Count();
745 for ( USHORT n=nCount; n--; )
747 uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n];
748 if ( *pObj == xListener )
750 aRefreshListeners.DeleteAndDestroy( n );
751 if ( aRefreshListeners.Count() == 0 )
752 release(); // release ref for listeners
753 break;
758 void ScAreaLinkObj::Refreshed_Impl()
760 lang::EventObject aEvent;
761 aEvent.Source.set((cppu::OWeakObject*)this);
762 for ( USHORT n=0; n<aRefreshListeners.Count(); n++ )
763 (*aRefreshListeners[n])->refreshed( aEvent );
766 // XPropertySet
768 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAreaLinkObj::getPropertySetInfo()
769 throw(uno::RuntimeException)
771 ScUnoGuard aGuard;
772 static uno::Reference<beans::XPropertySetInfo> aRef(
773 new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
774 return aRef;
777 void SAL_CALL ScAreaLinkObj::setPropertyValue(
778 const rtl::OUString& aPropertyName, const uno::Any& aValue )
779 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
780 lang::IllegalArgumentException, lang::WrappedTargetException,
781 uno::RuntimeException)
783 ScUnoGuard aGuard;
784 String aNameString(aPropertyName);
785 rtl::OUString aValStr;
786 if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
788 if ( aValue >>= aValStr )
789 setFileName( aValStr );
791 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
793 if ( aValue >>= aValStr )
794 setFilter( aValStr );
796 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
798 if ( aValue >>= aValStr )
799 setFilterOptions( aValStr );
801 else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
803 sal_Int32 nRefresh = 0;
804 if ( aValue >>= nRefresh )
805 setRefreshDelay( nRefresh );
807 else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
809 sal_Int32 nRefresh = 0;
810 if ( aValue >>= nRefresh )
811 setRefreshDelay( nRefresh );
815 uno::Any SAL_CALL ScAreaLinkObj::getPropertyValue( const rtl::OUString& aPropertyName )
816 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
817 uno::RuntimeException)
819 ScUnoGuard aGuard;
820 String aNameString(aPropertyName);
821 uno::Any aRet;
822 if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
823 aRet <<= getFileName();
824 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
825 aRet <<= getFilter();
826 else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
827 aRet <<= getFilterOptions();
828 else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
829 aRet <<= getRefreshDelay();
830 else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
831 aRet <<= getRefreshDelay();
832 return aRet;
835 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj )
837 // internal:
839 rtl::OUString ScAreaLinkObj::getFileName(void) const
841 ScUnoGuard aGuard;
842 rtl::OUString aRet;
843 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
844 if (pLink)
845 aRet = pLink->GetFile();
846 return aRet;
849 void ScAreaLinkObj::setFileName(const rtl::OUString& rNewName)
851 ScUnoGuard aGuard;
852 Modify_Impl( &rNewName, NULL, NULL, NULL, NULL );
855 rtl::OUString ScAreaLinkObj::getFilter(void) const
857 ScUnoGuard aGuard;
858 rtl::OUString aRet;
859 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
860 if (pLink)
861 aRet = pLink->GetFilter();
862 return aRet;
865 void ScAreaLinkObj::setFilter(const rtl::OUString& Filter)
867 ScUnoGuard aGuard;
868 Modify_Impl( NULL, &Filter, NULL, NULL, NULL );
871 rtl::OUString ScAreaLinkObj::getFilterOptions(void) const
873 ScUnoGuard aGuard;
874 rtl::OUString aRet;
875 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
876 if (pLink)
877 aRet = pLink->GetOptions();
878 return aRet;
881 void ScAreaLinkObj::setFilterOptions(const rtl::OUString& FilterOptions)
883 ScUnoGuard aGuard;
884 Modify_Impl( NULL, NULL, &FilterOptions, NULL, NULL );
887 sal_Int32 ScAreaLinkObj::getRefreshDelay(void) const
889 ScUnoGuard aGuard;
890 sal_Int32 nRet = 0;
891 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
892 if (pLink)
893 nRet = (sal_Int32) pLink->GetRefreshDelay();
894 return nRet;
897 void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
899 ScUnoGuard aGuard;
900 ModifyRefreshDelay_Impl( nRefreshDelay );
903 // XAreaLink
905 rtl::OUString SAL_CALL ScAreaLinkObj::getSourceArea() throw(uno::RuntimeException)
907 ScUnoGuard aGuard;
908 rtl::OUString aRet;
909 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
910 if (pLink)
911 aRet = pLink->GetSource();
912 return aRet;
915 void SAL_CALL ScAreaLinkObj::setSourceArea( const rtl::OUString& aSourceArea )
916 throw(uno::RuntimeException)
918 ScUnoGuard aGuard;
919 Modify_Impl( NULL, NULL, NULL, &aSourceArea, NULL );
922 table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() throw(uno::RuntimeException)
924 ScUnoGuard aGuard;
925 table::CellRangeAddress aRet;
926 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
927 if (pLink)
928 ScUnoConversion::FillApiRange( aRet, pLink->GetDestArea() );
929 return aRet;
932 void SAL_CALL ScAreaLinkObj::setDestArea( const table::CellRangeAddress& aDestArea )
933 throw(uno::RuntimeException)
935 ScUnoGuard aGuard;
936 Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea );
939 //------------------------------------------------------------------------
941 ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) :
942 pDocShell( pDocSh )
944 pDocShell->GetDocument()->AddUnoObject(*this);
947 ScAreaLinksObj::~ScAreaLinksObj()
949 if (pDocShell)
950 pDocShell->GetDocument()->RemoveUnoObject(*this);
953 void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
955 // Referenz-Update interessiert hier nicht
957 if ( rHint.ISA( SfxSimpleHint ) &&
958 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
960 pDocShell = NULL; // ungueltig geworden
964 // XAreaLinks
966 ScAreaLinkObj* ScAreaLinksObj::GetObjectByIndex_Impl(INT32 nIndex)
968 if ( pDocShell && nIndex >= 0 && nIndex < getCount() )
969 return new ScAreaLinkObj( pDocShell, (USHORT)nIndex );
971 return NULL; // nicht gefunden
974 void SAL_CALL ScAreaLinksObj::insertAtPosition( const table::CellAddress& aDestPos,
975 const rtl::OUString& aFileName,
976 const rtl::OUString& aSourceArea,
977 const rtl::OUString& aFilter,
978 const rtl::OUString& aFilterOptions )
979 throw(uno::RuntimeException)
981 ScUnoGuard aGuard;
982 if (pDocShell)
984 String aFileStr (aFileName);
985 String aFilterStr (aFilter);
986 String aOptionStr (aFilterOptions);
987 String aSourceStr (aSourceArea);
988 ScAddress aDestAddr( (SCCOL)aDestPos.Column, (SCROW)aDestPos.Row, aDestPos.Sheet );
990 aFileStr = ScGlobal::GetAbsDocName( aFileStr, pDocShell ); //! in InsertAreaLink ???
992 ScDocFunc aFunc(*pDocShell);
993 aFunc.InsertAreaLink( aFileStr, aFilterStr, aOptionStr,
994 aSourceStr, ScRange(aDestAddr),
995 0, FALSE, TRUE ); // keine Inhalte verschieben
999 void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
1001 ScUnoGuard aGuard;
1002 ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, (USHORT)nIndex);
1003 if (pLink)
1005 //! SetAddUndo oder so
1007 SvxLinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
1008 pLinkManager->Remove( pLink );
1012 // XEnumerationAccess
1014 uno::Reference<container::XEnumeration> SAL_CALL ScAreaLinksObj::createEnumeration()
1015 throw(uno::RuntimeException)
1017 ScUnoGuard aGuard;
1018 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.CellAreaLinksEnumeration")));
1021 // XIndexAccess
1023 sal_Int32 SAL_CALL ScAreaLinksObj::getCount() throw(uno::RuntimeException)
1025 ScUnoGuard aGuard;
1026 INT32 nAreaCount = 0;
1027 if (pDocShell)
1029 SvxLinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
1030 USHORT nTotalCount = pLinkManager->GetLinks().Count();
1031 for (USHORT i=0; i<nTotalCount; i++)
1033 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
1034 if (pBase->ISA(ScAreaLink))
1035 ++nAreaCount;
1038 return nAreaCount;
1041 uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex )
1042 throw(lang::IndexOutOfBoundsException,
1043 lang::WrappedTargetException, uno::RuntimeException)
1045 ScUnoGuard aGuard;
1046 uno::Reference<sheet::XAreaLink> xLink(GetObjectByIndex_Impl(nIndex));
1047 if (xLink.is())
1048 return uno::makeAny(xLink);
1049 else
1050 throw lang::IndexOutOfBoundsException();
1051 // return uno::Any();
1054 uno::Type SAL_CALL ScAreaLinksObj::getElementType() throw(uno::RuntimeException)
1056 ScUnoGuard aGuard;
1057 return getCppuType((uno::Reference<sheet::XAreaLink>*)0);
1060 sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException)
1062 ScUnoGuard aGuard;
1063 return ( getCount() != 0 );
1066 //------------------------------------------------------------------------
1068 ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const String& rA,
1069 const String& rT, const String& rI) :
1070 pDocShell( pDocSh ),
1071 aAppl( rA ),
1072 aTopic( rT ),
1073 aItem( rI )
1075 pDocShell->GetDocument()->AddUnoObject(*this);
1078 ScDDELinkObj::~ScDDELinkObj()
1080 if (pDocShell)
1081 pDocShell->GetDocument()->RemoveUnoObject(*this);
1084 void ScDDELinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1086 //! notify if links in document are changed
1087 // UpdateRef is not needed here
1089 if ( rHint.ISA( SfxSimpleHint ) )
1091 if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1092 pDocShell = NULL; // pointer is invalid
1094 else if ( rHint.ISA( ScLinkRefreshedHint ) )
1096 const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
1097 if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE &&
1098 rLH.GetDdeAppl() == aAppl &&
1099 rLH.GetDdeTopic() == aTopic &&
1100 rLH.GetDdeItem() == aItem ) //! mode is ignored
1101 Refreshed_Impl();
1105 // XNamed
1107 String lcl_BuildDDEName( const String& rAppl, const String& rTopic, const String& rItem )
1109 // Appl|Topic!Item (wie Excel)
1110 String aRet = rAppl;
1111 aRet += '|';
1112 aRet += rTopic;
1113 aRet += '!';
1114 aRet += rItem;
1115 return aRet;
1118 rtl::OUString SAL_CALL ScDDELinkObj::getName() throw(uno::RuntimeException)
1120 ScUnoGuard aGuard;
1121 return lcl_BuildDDEName( aAppl, aTopic, aItem );
1124 void SAL_CALL ScDDELinkObj::setName( const rtl::OUString& /* aName */ ) throw(uno::RuntimeException)
1126 // name can't be changed (formulas wouldn't find the link)
1127 throw uno::RuntimeException();
1130 // XDDELink
1132 rtl::OUString SAL_CALL ScDDELinkObj::getApplication() throw(uno::RuntimeException)
1134 ScUnoGuard aGuard;
1135 //! Test, ob Link noch im Dokument enthalten?
1137 return aAppl;
1140 rtl::OUString SAL_CALL ScDDELinkObj::getTopic() throw(uno::RuntimeException)
1142 ScUnoGuard aGuard;
1143 //! Test, ob Link noch im Dokument enthalten?
1145 return aTopic;
1148 rtl::OUString SAL_CALL ScDDELinkObj::getItem() throw(uno::RuntimeException)
1150 ScUnoGuard aGuard;
1151 //! Test, ob Link noch im Dokument enthalten?
1153 return aItem;
1156 // XRefreshable
1158 void SAL_CALL ScDDELinkObj::refresh() throw(uno::RuntimeException)
1160 ScUnoGuard aGuard;
1161 if (pDocShell)
1163 ScDocument* pDoc = pDocShell->GetDocument();
1164 (void)pDoc->UpdateDdeLink( aAppl, aTopic, aItem );
1165 //! Fehler abfragen
1169 void SAL_CALL ScDDELinkObj::addRefreshListener(
1170 const uno::Reference<util::XRefreshListener >& xListener )
1171 throw(uno::RuntimeException)
1173 ScUnoGuard aGuard;
1174 uno::Reference<util::XRefreshListener>* pObj =
1175 new uno::Reference<util::XRefreshListener>( xListener );
1176 aRefreshListeners.Insert( pObj, aRefreshListeners.Count() );
1178 // hold one additional ref to keep this object alive as long as there are listeners
1179 if ( aRefreshListeners.Count() == 1 )
1180 acquire();
1183 void SAL_CALL ScDDELinkObj::removeRefreshListener(
1184 const uno::Reference<util::XRefreshListener >& xListener )
1185 throw(uno::RuntimeException)
1187 ScUnoGuard aGuard;
1188 USHORT nCount = aRefreshListeners.Count();
1189 for ( USHORT n=nCount; n--; )
1191 uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n];
1192 if ( *pObj == xListener )
1194 aRefreshListeners.DeleteAndDestroy( n );
1195 if ( aRefreshListeners.Count() == 0 )
1196 release(); // release ref for listeners
1197 break;
1202 // XDDELinkResults
1204 uno::Sequence< uno::Sequence< uno::Any > > ScDDELinkObj::getResults( )
1205 throw (uno::RuntimeException)
1207 ScUnoGuard aGuard;
1208 uno::Sequence< uno::Sequence< uno::Any > > aReturn;
1209 bool bSuccess = false;
1211 if ( pDocShell )
1213 ScDocument* pDoc = pDocShell->GetDocument();
1214 if ( pDoc )
1216 USHORT nPos = 0;
1217 if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1219 const ScMatrix* pMatrix = pDoc->GetDdeLinkResultMatrix( nPos );
1220 if ( pMatrix )
1222 uno::Any aAny;
1223 if ( ScRangeToSequence::FillMixedArray( aAny, pMatrix, true ) )
1225 aAny >>= aReturn;
1228 bSuccess = true;
1233 if ( !bSuccess )
1235 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1236 "ScDDELinkObj::getResults: failed to get results!" ) ),
1237 uno::Reference< uno::XInterface >() );
1240 return aReturn;
1243 void ScDDELinkObj::setResults( const uno::Sequence< uno::Sequence< uno::Any > >& aResults )
1244 throw (uno::RuntimeException)
1246 ScUnoGuard aGuard;
1247 bool bSuccess = false;
1249 if ( pDocShell )
1251 ScDocument* pDoc = pDocShell->GetDocument();
1252 if ( pDoc )
1254 USHORT nPos = 0;
1255 if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
1257 uno::Any aAny;
1258 aAny <<= aResults;
1259 ScMatrixRef xMatrix = ScSequenceToMatrix::CreateMixedMatrix( aAny );
1260 bSuccess = pDoc->SetDdeLinkResultMatrix( nPos, xMatrix );
1265 if ( !bSuccess )
1267 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1268 "ScDDELinkObj::setResults: failed to set results!" ) ),
1269 uno::Reference< uno::XInterface >() );
1273 void ScDDELinkObj::Refreshed_Impl()
1275 lang::EventObject aEvent;
1276 aEvent.Source.set((cppu::OWeakObject*)this);
1277 for ( USHORT n=0; n<aRefreshListeners.Count(); n++ )
1278 (*aRefreshListeners[n])->refreshed( aEvent );
1281 //------------------------------------------------------------------------
1283 ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) :
1284 pDocShell( pDocSh )
1286 pDocShell->GetDocument()->AddUnoObject(*this);
1289 ScDDELinksObj::~ScDDELinksObj()
1291 if (pDocShell)
1292 pDocShell->GetDocument()->RemoveUnoObject(*this);
1295 void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1297 // Referenz-Update interessiert hier nicht
1299 if ( rHint.ISA( SfxSimpleHint ) &&
1300 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1302 pDocShell = NULL; // ungueltig geworden
1306 // XDDELinks
1308 ScDDELinkObj* ScDDELinksObj::GetObjectByIndex_Impl(INT32 nIndex)
1310 if (pDocShell)
1312 String aAppl, aTopic, aItem;
1313 if ( nIndex <= USHRT_MAX &&
1314 pDocShell->GetDocument()->GetDdeLinkData( (USHORT)nIndex, aAppl, aTopic, aItem ) )
1315 return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1317 return NULL;
1320 ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const rtl::OUString& aName)
1322 if (pDocShell)
1324 String aNamStr(aName);
1325 String aAppl, aTopic, aItem;
1327 ScDocument* pDoc = pDocShell->GetDocument();
1328 USHORT nCount = pDoc->GetDdeLinkCount();
1329 for (USHORT i=0; i<nCount; i++)
1331 pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1332 if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1333 return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
1336 return NULL;
1339 // XEnumerationAccess
1341 uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration()
1342 throw(uno::RuntimeException)
1344 ScUnoGuard aGuard;
1345 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DDELinksEnumeration")));
1348 // XIndexAccess
1350 sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException)
1352 ScUnoGuard aGuard;
1353 INT32 nAreaCount = 0;
1354 if (pDocShell)
1355 nAreaCount = pDocShell->GetDocument()->GetDdeLinkCount();
1356 return nAreaCount;
1359 uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex )
1360 throw(lang::IndexOutOfBoundsException,
1361 lang::WrappedTargetException, uno::RuntimeException)
1363 ScUnoGuard aGuard;
1364 uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex));
1365 if (xLink.is())
1366 return uno::makeAny(xLink);
1367 else
1368 throw lang::IndexOutOfBoundsException();
1369 // return uno::Any();
1372 uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException)
1374 ScUnoGuard aGuard;
1375 return getCppuType((uno::Reference<sheet::XDDELink>*)0);
1378 sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException)
1380 ScUnoGuard aGuard;
1381 return ( getCount() != 0 );
1384 uno::Any SAL_CALL ScDDELinksObj::getByName( const rtl::OUString& aName )
1385 throw(container::NoSuchElementException,
1386 lang::WrappedTargetException, uno::RuntimeException)
1388 ScUnoGuard aGuard;
1389 uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName));
1390 if (xLink.is())
1391 return uno::makeAny(xLink);
1392 else
1393 throw container::NoSuchElementException();
1394 // return uno::Any();
1397 uno::Sequence<rtl::OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException)
1399 ScUnoGuard aGuard;
1400 if (pDocShell)
1402 String aAppl, aTopic, aItem;
1404 ScDocument* pDoc = pDocShell->GetDocument();
1405 USHORT nCount = pDoc->GetDdeLinkCount();
1406 uno::Sequence<rtl::OUString> aSeq(nCount);
1407 rtl::OUString* pAry = aSeq.getArray();
1409 for (USHORT i=0; i<nCount; i++)
1411 pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1412 pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem);
1414 return aSeq;
1416 return uno::Sequence<rtl::OUString>();
1419 sal_Bool SAL_CALL ScDDELinksObj::hasByName( const rtl::OUString& aName )
1420 throw(uno::RuntimeException)
1422 ScUnoGuard aGuard;
1423 if (pDocShell)
1425 String aNamStr(aName);
1426 String aAppl, aTopic, aItem;
1428 ScDocument* pDoc = pDocShell->GetDocument();
1429 USHORT nCount = pDoc->GetDdeLinkCount();
1430 for (USHORT i=0; i<nCount; i++)
1432 pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
1433 if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
1434 return TRUE;
1437 return FALSE;
1440 // XDDELinks
1442 uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
1443 const ::rtl::OUString& aApplication, const ::rtl::OUString& aTopic,
1444 const ::rtl::OUString& aItem, ::com::sun::star::sheet::DDELinkMode nMode )
1445 throw (uno::RuntimeException)
1447 ScUnoGuard aGuard;
1448 uno::Reference< sheet::XDDELink > xLink;
1450 if ( pDocShell )
1452 ScDocument* pDoc = pDocShell->GetDocument();
1453 if ( pDoc )
1455 BYTE nMod = SC_DDE_DEFAULT;
1456 switch ( nMode )
1458 case sheet::DDELinkMode_DEFAULT:
1460 nMod = SC_DDE_DEFAULT;
1462 break;
1463 case sheet::DDELinkMode_ENGLISH:
1465 nMod = SC_DDE_ENGLISH;
1467 break;
1468 case sheet::DDELinkMode_TEXT:
1470 nMod = SC_DDE_TEXT;
1472 break;
1473 default:
1476 break;
1479 if ( pDoc->CreateDdeLink( aApplication, aTopic, aItem, nMod ) )
1481 const ::rtl::OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) );
1482 xLink.set( GetObjectByName_Impl( aName ) );
1487 if ( !xLink.is() )
1489 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1490 "ScDDELinksObj::addDDELink: cannot add DDE link!" ) ),
1491 uno::Reference< uno::XInterface >() );
1494 return xLink;
1497 // ============================================================================
1499 ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
1500 mpTable(pTable),
1501 mnIndex(nIndex)
1505 ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
1509 void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue)
1510 throw (IllegalArgumentException, RuntimeException)
1512 ScUnoGuard aGuard;
1513 if (nRow < 0 || nCol < 0)
1514 throw IllegalArgumentException();
1516 ScExternalRefCache::TokenRef pToken;
1517 double fVal = 0.0;
1518 OUString aVal;
1519 if (rValue >>= fVal)
1520 pToken.reset(new FormulaDoubleToken(fVal));
1521 else if (rValue >>= aVal)
1522 pToken.reset(new FormulaStringToken(aVal));
1523 else
1524 // unidentified value type.
1525 return;
1527 mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken);
1530 Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow)
1531 throw (IllegalArgumentException, RuntimeException)
1533 ScUnoGuard aGuard;
1534 if (nRow < 0 || nCol < 0)
1535 throw IllegalArgumentException();
1537 FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get();
1538 if (!pToken)
1539 throw IllegalArgumentException();
1541 Any aValue;
1542 switch (pToken->GetType())
1544 case svDouble:
1546 double fVal = pToken->GetDouble();
1547 aValue <<= fVal;
1549 break;
1550 case svString:
1552 OUString aVal = pToken->GetString();
1553 aValue <<= aVal;
1555 break;
1556 default:
1557 throw IllegalArgumentException();
1559 return aValue;
1562 Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows()
1563 throw (RuntimeException)
1565 ScUnoGuard aGuard;
1566 vector<SCROW> aRows;
1567 mpTable->getAllRows(aRows);
1568 size_t nSize = aRows.size();
1569 Sequence<sal_Int32> aRowsSeq(nSize);
1570 for (size_t i = 0; i < nSize; ++i)
1571 aRowsSeq[i] = aRows[i];
1573 return aRowsSeq;
1576 Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow)
1577 throw (IllegalArgumentException, RuntimeException)
1579 ScUnoGuard aGuard;
1580 if (nRow < 0)
1581 throw IllegalArgumentException();
1583 vector<SCCOL> aCols;
1584 mpTable->getAllCols(static_cast<SCROW>(nRow), aCols);
1585 size_t nSize = aCols.size();
1586 Sequence<sal_Int32> aColsSeq(nSize);
1587 for (size_t i = 0; i < nSize; ++i)
1588 aColsSeq[i] = aCols[i];
1590 return aColsSeq;
1593 sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
1594 throw (RuntimeException)
1596 return static_cast< sal_Int32 >( mnIndex );
1599 // ============================================================================
1601 ScExternalDocLinkObj::ScExternalDocLinkObj(ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
1602 mpRefMgr(pRefMgr), mnFileId(nFileId)
1606 ScExternalDocLinkObj::~ScExternalDocLinkObj()
1610 Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache(
1611 const OUString& aSheetName )
1612 throw (RuntimeException)
1614 ScUnoGuard aGuard;
1615 size_t nIndex = 0;
1616 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
1617 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1618 return aSheetCache;
1621 Any SAL_CALL ScExternalDocLinkObj::getByName(const::rtl::OUString &aName)
1622 throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
1624 ScUnoGuard aGuard;
1625 size_t nIndex = 0;
1626 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex);
1627 if (!pTable)
1628 throw container::NoSuchElementException();
1630 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1632 Any aAny;
1633 aAny <<= aSheetCache;
1634 return aAny;
1637 Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
1638 throw (RuntimeException)
1640 ScUnoGuard aGuard;
1641 vector<String> aTabNames;
1642 mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
1643 size_t n = aTabNames.size();
1644 Sequence<OUString> aSeq(n);
1645 for (size_t i = 0; i < n; ++i)
1646 aSeq[i] = aTabNames[i];
1647 return aSeq;
1650 sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
1651 throw (RuntimeException)
1653 ScUnoGuard aGuard;
1654 return static_cast<sal_Bool>(mpRefMgr->hasCacheTable(mnFileId, aName));
1657 sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
1658 throw (RuntimeException)
1660 ScUnoGuard aGuard;
1661 return static_cast<sal_Int32>(mpRefMgr->getCacheTableCount(mnFileId));
1664 Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nIndex)
1665 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
1667 ScUnoGuard aGuard;
1668 size_t nTabCount = mpRefMgr->getCacheTableCount(mnFileId);
1669 if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(nTabCount))
1670 throw lang::IndexOutOfBoundsException();
1672 ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, static_cast<size_t>(nIndex));
1673 if (!pTable)
1674 throw lang::IndexOutOfBoundsException();
1676 Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
1678 Any aAny;
1679 aAny <<= aSheetCache;
1680 return aAny;
1683 Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration()
1684 throw (RuntimeException)
1686 ScUnoGuard aGuard;
1687 Reference< container::XEnumeration > aRef(
1688 new ScIndexEnumeration(this, OUString::createFromAscii(
1689 "com.sun.star.sheet.ExternalDocLink")));
1690 return aRef;
1693 uno::Type SAL_CALL ScExternalDocLinkObj::getElementType()
1694 throw (RuntimeException)
1696 ScUnoGuard aGuard;
1697 return getCppuType(static_cast<Reference<sheet::XExternalDocLink>*>(0));
1700 sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
1701 throw (RuntimeException)
1703 ScUnoGuard aGuard;
1704 return static_cast<sal_Bool>(mpRefMgr->getCacheTableCount(mnFileId) > 0);
1707 sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
1708 throw (RuntimeException)
1710 return static_cast<sal_Int32>(mnFileId);
1713 // ============================================================================
1715 ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
1716 mpDocShell(pDocShell),
1717 mpRefMgr(pDocShell->GetDocument()->GetExternalRefManager())
1721 ScExternalDocLinksObj::~ScExternalDocLinksObj()
1725 Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink(
1726 const OUString& aDocName )
1727 throw (RuntimeException)
1729 ScUnoGuard aGuard;
1730 sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocName);
1731 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1732 return aDocLink;
1735 Any SAL_CALL ScExternalDocLinksObj::getByName(const::rtl::OUString &aName)
1736 throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
1738 ScUnoGuard aGuard;
1739 if (!mpRefMgr->hasExternalFile(aName))
1740 throw container::NoSuchElementException();
1742 sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aName);
1743 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1745 Any aAny;
1746 aAny <<= aDocLink;
1747 return aAny;
1750 Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames()
1751 throw (RuntimeException)
1753 ScUnoGuard aGuard;
1754 sal_uInt16 n = mpRefMgr->getExternalFileCount();
1755 Sequence<OUString> aSeq(n);
1756 for (sal_uInt16 i = 0; i < n; ++i)
1758 const String* pName = mpRefMgr->getExternalFileName(i);
1759 aSeq[i] = pName ? *pName : EMPTY_STRING;
1762 return aSeq;
1765 sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName)
1766 throw (RuntimeException)
1768 ScUnoGuard aGuard;
1769 return mpRefMgr->hasExternalFile(aName);
1772 sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount()
1773 throw (RuntimeException)
1775 ScUnoGuard aGuard;
1776 return mpRefMgr->getExternalFileCount();
1779 Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex)
1780 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
1782 ScUnoGuard aGuard;
1783 if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min())
1784 throw lang::IndexOutOfBoundsException();
1786 sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex);
1788 if (!mpRefMgr->hasExternalFile(nFileId))
1789 throw lang::IndexOutOfBoundsException();
1791 Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
1792 Any aAny;
1793 aAny <<= aDocLink;
1794 return aAny;
1797 Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration()
1798 throw (RuntimeException)
1800 ScUnoGuard aGuard;
1801 Reference< container::XEnumeration > aRef(
1802 new ScIndexEnumeration(this, OUString::createFromAscii(
1803 "com.sun.star.sheet.ExternalDocLinks")));
1804 return aRef;
1807 uno::Type SAL_CALL ScExternalDocLinksObj::getElementType()
1808 throw (RuntimeException)
1810 ScUnoGuard aGuard;
1811 return getCppuType(static_cast<Reference<sheet::XExternalDocLinks>*>(0));
1814 sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements()
1815 throw (RuntimeException)
1817 ScUnoGuard aGuard;
1818 return mpRefMgr->getExternalFileCount() > 0;