diff options
Diffstat (limited to 'sc/source/ui/unoobj/linkuno.cxx')
-rw-r--r-- | sc/source/ui/unoobj/linkuno.cxx | 1821 |
1 files changed, 1821 insertions, 0 deletions
diff --git a/sc/source/ui/unoobj/linkuno.cxx b/sc/source/ui/unoobj/linkuno.cxx new file mode 100644 index 000000000000..ee6c3ff1988a --- /dev/null +++ b/sc/source/ui/unoobj/linkuno.cxx @@ -0,0 +1,1821 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +#include <svl/smplhint.hxx> +#include <sfx2/linkmgr.hxx> + +#include "linkuno.hxx" +#include "miscuno.hxx" +#include "convuno.hxx" +#include "docsh.hxx" +#include "docfunc.hxx" +#include "collect.hxx" +#include "tablink.hxx" +#include "arealink.hxx" +#include "unoguard.hxx" +#include "hints.hxx" +#include "unonames.hxx" +#include "rangeseq.hxx" +#include "token.hxx" + +#include <vector> +#include <climits> + +using namespace com::sun::star; +using namespace formula; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::uno::RuntimeException; +using ::rtl::OUString; +using ::std::vector; + +//------------------------------------------------------------------------ + +// fuer Sheet- und Area-Links benutzt: +const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap() +{ + static SfxItemPropertyMapEntry aSheetLinkMap_Impl[] = + { + {MAP_CHAR_LEN(SC_UNONAME_FILTER), 0, &getCppuType((rtl::OUString*)0), 0, 0 }, + {MAP_CHAR_LEN(SC_UNONAME_FILTOPT), 0, &getCppuType((rtl::OUString*)0), 0, 0 }, + {MAP_CHAR_LEN(SC_UNONAME_LINKURL), 0, &getCppuType((rtl::OUString*)0), 0, 0 }, + {MAP_CHAR_LEN(SC_UNONAME_REFDELAY), 0, &getCppuType((sal_Int32*)0), 0, 0 }, + {MAP_CHAR_LEN(SC_UNONAME_REFPERIOD), 0, &getCppuType((sal_Int32*)0), 0, 0 }, + {0,0,0,0,0,0} + }; + return aSheetLinkMap_Impl; +} + +//------------------------------------------------------------------------ + +SV_IMPL_PTRARR( XRefreshListenerArr_Impl, XRefreshListenerPtr ); + +SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj, "ScAreaLinkObj", "com.sun.star.sheet.CellAreaLink" ) +SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj, "ScAreaLinksObj", "com.sun.star.sheet.CellAreaLinks" ) +SC_SIMPLE_SERVICE_INFO( ScDDELinkObj, "ScDDELinkObj", "com.sun.star.sheet.DDELink" ) +SC_SIMPLE_SERVICE_INFO( ScDDELinksObj, "ScDDELinksObj", "com.sun.star.sheet.DDELinks" ) +SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj, "ScSheetLinkObj", "com.sun.star.sheet.SheetLink" ) +SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj, "ScSheetLinksObj", "com.sun.star.sheet.SheetLinks" ) + +//------------------------------------------------------------------------ + +ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const String& rName) : + aPropSet( lcl_GetSheetLinkMap() ), + pDocShell( pDocSh ), + aFileName( rName ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScSheetLinkObj::~ScSheetLinkObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + //! notify if links in document are changed + // UpdateRef is not needed here + + if ( rHint.ISA( SfxSimpleHint ) ) + { + if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + pDocShell = NULL; // pointer is invalid + } + else if ( rHint.ISA( ScLinkRefreshedHint ) ) + { + const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint; + if ( rLH.GetLinkType() == SC_LINKREFTYPE_SHEET && rLH.GetUrl() == aFileName ) + Refreshed_Impl(); + } +} + +ScTableLink* ScSheetLinkObj::GetLink_Impl() const +{ + if (pDocShell) + { + sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager(); + sal_uInt16 nCount = pLinkManager->GetLinks().Count(); + for (sal_uInt16 i=0; i<nCount; i++) + { + ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i]; + if (pBase->ISA(ScTableLink)) + { + ScTableLink* pTabLink = (ScTableLink*)pBase; + if ( pTabLink->GetFileName() == aFileName ) + return pTabLink; + } + } + } + return NULL; // nicht gefunden +} + +// XNamed + +rtl::OUString SAL_CALL ScSheetLinkObj::getName() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return getFileName(); // Name ist der Dateiname (URL) +} + +void SAL_CALL ScSheetLinkObj::setName( const rtl::OUString& aName ) throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + setFileName(aName); // Name ist der Dateiname (URL) +} + +// XRefreshable + +void SAL_CALL ScSheetLinkObj::refresh() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScTableLink* pLink = GetLink_Impl(); + if (pLink) + pLink->Refresh( pLink->GetFileName(), pLink->GetFilterName(), NULL, pLink->GetRefreshDelay() ); +} + +void SAL_CALL ScSheetLinkObj::addRefreshListener( + const uno::Reference<util::XRefreshListener >& xListener ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference<util::XRefreshListener>* pObj = + new uno::Reference<util::XRefreshListener>( xListener ); + aRefreshListeners.Insert( pObj, aRefreshListeners.Count() ); + + // hold one additional ref to keep this object alive as long as there are listeners + if ( aRefreshListeners.Count() == 1 ) + acquire(); +} + +void SAL_CALL ScSheetLinkObj::removeRefreshListener( + const uno::Reference<util::XRefreshListener >& xListener ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_uInt16 nCount = aRefreshListeners.Count(); + for ( sal_uInt16 n=nCount; n--; ) + { + uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n]; + if ( *pObj == xListener ) + { + aRefreshListeners.DeleteAndDestroy( n ); + if ( aRefreshListeners.Count() == 0 ) + release(); // release ref for listeners + break; + } + } +} + +void ScSheetLinkObj::Refreshed_Impl() +{ + lang::EventObject aEvent; + aEvent.Source.set((cppu::OWeakObject*)this); + for ( sal_uInt16 n=0; n<aRefreshListeners.Count(); n++ ) + (*aRefreshListeners[n])->refreshed( aEvent ); +} + +void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh ) +{ + ScTableLink* pLink = GetLink_Impl(); + if( pLink ) + pLink->SetRefreshDelay( (sal_uLong) nRefresh ); +} + +// XPropertySet + +uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSheetLinkObj::getPropertySetInfo() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + static uno::Reference<beans::XPropertySetInfo> aRef( + new SfxItemPropertySetInfo( aPropSet.getPropertyMap() )); + return aRef; +} + +void SAL_CALL ScSheetLinkObj::setPropertyValue( + const rtl::OUString& aPropertyName, const uno::Any& aValue ) + throw(beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, + uno::RuntimeException) +{ + ScUnoGuard aGuard; + String aNameString(aPropertyName); + rtl::OUString aValStr; + if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) ) + { + if ( aValue >>= aValStr ) + setFileName( aValStr ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) ) + { + if ( aValue >>= aValStr ) + setFilter( aValStr ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) ) + { + if ( aValue >>= aValStr ) + setFilterOptions( aValStr ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) ) + { + sal_Int32 nRefresh = 0; + if ( aValue >>= nRefresh ) + setRefreshDelay( nRefresh ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) ) + { + sal_Int32 nRefresh = 0; + if ( aValue >>= nRefresh ) + setRefreshDelay( nRefresh ); + } +} + +uno::Any SAL_CALL ScSheetLinkObj::getPropertyValue( const rtl::OUString& aPropertyName ) + throw(beans::UnknownPropertyException, lang::WrappedTargetException, + uno::RuntimeException) +{ + ScUnoGuard aGuard; + String aNameString(aPropertyName); + uno::Any aRet; + if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) ) + aRet <<= getFileName(); + else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) ) + aRet <<= getFilter(); + else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) ) + aRet <<= getFilterOptions(); + else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) ) + aRet <<= getRefreshDelay(); + else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) ) + aRet <<= getRefreshDelay(); + return aRet; +} + +SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj ) + +// internal: + +rtl::OUString ScSheetLinkObj::getFileName(void) const +{ + ScUnoGuard aGuard; + return aFileName; +} + +void ScSheetLinkObj::setFileName(const rtl::OUString& rNewName) +{ + ScUnoGuard aGuard; + ScTableLink* pLink = GetLink_Impl(); + if (pLink) + { + // pLink->Refresh mit neuem Dateinamen bringt sfx2::LinkManager durcheinander + // darum per Hand die Tabellen umsetzen und Link per UpdateLinks neu erzeugen + + String aNewStr(ScGlobal::GetAbsDocName( String(rNewName), pDocShell )); + + // zuerst Tabellen umsetzen + + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + if ( pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab) == aFileName ) // alte Datei + pDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), aNewStr, + pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab), + pDoc->GetLinkTab(nTab), + pDoc->GetLinkRefreshDelay(nTab) ); // nur Datei aendern + + // Links updaten + //! Undo !!! + + pLink = NULL; // wird bei UpdateLinks ungueltig + pDocShell->UpdateLinks(); // alter Link raus, evtl. neuen Link anlegen + + // Daten kopieren + + aFileName = aNewStr; + pLink = GetLink_Impl(); // neuer Link mit neuem Namen + if (pLink) + pLink->Update(); // inkl. Paint & Undo fuer Daten + } +} + +rtl::OUString ScSheetLinkObj::getFilter(void) const +{ + ScUnoGuard aGuard; + rtl::OUString aRet; + ScTableLink* pLink = GetLink_Impl(); + if (pLink) + aRet = pLink->GetFilterName(); + return aRet; +} + +void ScSheetLinkObj::setFilter(const rtl::OUString& Filter) +{ + ScUnoGuard aGuard; + ScTableLink* pLink = GetLink_Impl(); + if (pLink) + { + String aFilterStr(Filter); + pLink->Refresh( aFileName, aFilterStr, NULL, pLink->GetRefreshDelay() ); + } +} + +rtl::OUString ScSheetLinkObj::getFilterOptions(void) const +{ + ScUnoGuard aGuard; + rtl::OUString aRet; + ScTableLink* pLink = GetLink_Impl(); + if (pLink) + aRet = pLink->GetOptions(); + return aRet; +} + +void ScSheetLinkObj::setFilterOptions(const rtl::OUString& FilterOptions) +{ + ScUnoGuard aGuard; + ScTableLink* pLink = GetLink_Impl(); + if (pLink) + { + String aOptStr(FilterOptions); + pLink->Refresh( aFileName, pLink->GetFilterName(), &aOptStr, pLink->GetRefreshDelay() ); + } +} + +sal_Int32 ScSheetLinkObj::getRefreshDelay(void) const +{ + ScUnoGuard aGuard; + sal_Int32 nRet = 0; + ScTableLink* pLink = GetLink_Impl(); + if (pLink) + nRet = (sal_Int32) pLink->GetRefreshDelay(); + return nRet; +} + +void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay) +{ + ScUnoGuard aGuard; + ModifyRefreshDelay_Impl( nRefreshDelay ); +} + +//------------------------------------------------------------------------ + +ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) : + pDocShell( pDocSh ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScSheetLinksObj::~ScSheetLinksObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + // Referenz-Update interessiert hier nicht + + if ( rHint.ISA( SfxSimpleHint ) && + ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + { + pDocShell = NULL; // ungueltig geworden + } +} + +// XSheetLinks + +ScSheetLinkObj* ScSheetLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex) +{ + if (pDocShell) + { + sal_Int32 nCount = 0; + ScStrCollection aNames; // um doppelte wegzulassen + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + if (pDoc->IsLinked(nTab)) + { + String aLinkDoc = pDoc->GetLinkDoc( nTab ); + StrData* pData = new StrData(aLinkDoc); + if (aNames.Insert(pData)) + { + if ( nCount == nIndex ) + return new ScSheetLinkObj( pDocShell, aLinkDoc ); + ++nCount; + } + else + delete pData; + } + } + return NULL; // kein Dokument oder Index zu gross +} + +ScSheetLinkObj* ScSheetLinksObj::GetObjectByName_Impl(const rtl::OUString& aName) +{ + // Name ist der Dateiname + + if (pDocShell) + { + String aNameStr(aName); + + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + if (pDoc->IsLinked(nTab)) + { + //! case-insensitiv ??? + String aLinkDoc = pDoc->GetLinkDoc( nTab ); + if ( aLinkDoc == aNameStr ) + return new ScSheetLinkObj( pDocShell, aNameStr ); + } + } + + return NULL; +} + +// XEnumerationAccess + +uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetLinksEnumeration"))); +} + +// XIndexAccess + +sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nCount = 0; + if (pDocShell) + { + ScStrCollection aNames; // um doppelte wegzulassen + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + if (pDoc->IsLinked(nTab)) + { + String aLinkDoc(pDoc->GetLinkDoc( nTab )); + StrData* pData = new StrData(aLinkDoc); + if (aNames.Insert(pData)) + ++nCount; + else + delete pData; + } + } + return nCount; +} + +uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex ) + throw(lang::IndexOutOfBoundsException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex)); + if (xLink.is()) + return uno::makeAny(xLink); + else + throw lang::IndexOutOfBoundsException(); +// return uno::Any(); +} + +uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return getCppuType((uno::Reference<beans::XPropertySet>*)0); +} + +sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return ( getCount() != 0 ); +} + +uno::Any SAL_CALL ScSheetLinksObj::getByName( const rtl::OUString& aName ) + throw(container::NoSuchElementException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName)); + if (xLink.is()) + return uno::makeAny(xLink); + else + throw container::NoSuchElementException(); +// return uno::Any(); +} + +sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const rtl::OUString& aName ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + // Name ist der Dateiname + + if (pDocShell) + { + String aNameStr(aName); + + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + if (pDoc->IsLinked(nTab)) + { + //! case-insensitiv ??? + String aLinkDoc(pDoc->GetLinkDoc( nTab )); + if ( aLinkDoc == aNameStr ) + return sal_True; + } + } + return sal_False; +} + +uno::Sequence<rtl::OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + // Name ist der Dateiname + + if (pDocShell) + { + ScStrCollection aNames; // um doppelte wegzulassen + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + String aName; + + sal_Int32 nLinkCount = getCount(); + uno::Sequence<rtl::OUString> aSeq(nLinkCount); + rtl::OUString* pAry = aSeq.getArray(); + sal_uInt16 nPos = 0; + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + { + if (pDoc->IsLinked(nTab)) + { + String aLinkDoc(pDoc->GetLinkDoc( nTab )); + StrData* pData = new StrData(aLinkDoc); + if (aNames.Insert(pData)) + pAry[nPos++] = aLinkDoc; + else + delete pData; + } + } + DBG_ASSERT( nPos==nLinkCount, "verzaehlt" ); + return aSeq; + } + return uno::Sequence<rtl::OUString>(); +} + +//------------------------------------------------------------------------ + +ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, sal_uInt16 nPos ) +{ + if (pDocShell) + { + sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager(); + sal_uInt16 nTotalCount = pLinkManager->GetLinks().Count(); + sal_uInt16 nAreaCount = 0; + for (sal_uInt16 i=0; i<nTotalCount; i++) + { + ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i]; + if (pBase->ISA(ScAreaLink)) + { + if ( nAreaCount == nPos ) + return (ScAreaLink*)pBase; + ++nAreaCount; + } + } + } + return NULL; // nicht gefunden +} + +ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, sal_uInt16 nP) : + aPropSet( lcl_GetSheetLinkMap() ), + pDocShell( pDocSh ), + nPos( nP ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScAreaLinkObj::~ScAreaLinkObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + //! notify if links in document are changed + // UpdateRef is not needed here + + if ( rHint.ISA( SfxSimpleHint ) ) + { + if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + pDocShell = NULL; // pointer is invalid + } + else if ( rHint.ISA( ScLinkRefreshedHint ) ) + { + const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint; + if ( rLH.GetLinkType() == SC_LINKREFTYPE_AREA ) + { + // get this link to compare dest position + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); + if ( pLink && pLink->GetDestArea().aStart == rLH.GetDestPos() ) + Refreshed_Impl(); + } + } +} + +// XFileLink + +void ScAreaLinkObj::Modify_Impl( const rtl::OUString* pNewFile, const rtl::OUString* pNewFilter, + const rtl::OUString* pNewOptions, const rtl::OUString* pNewSource, + const table::CellRangeAddress* pNewDest ) +{ + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); + if (pLink) + { + String aFile (pLink->GetFile()); + String aFilter (pLink->GetFilter()); + String aOptions (pLink->GetOptions()); + String aSource (pLink->GetSource()); + ScRange aDest (pLink->GetDestArea()); + sal_uLong nRefresh = pLink->GetRefreshDelay(); + + //! Undo fuer Loeschen + //! Undo zusammenfassen + + sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager(); + pLinkManager->Remove( pLink ); + pLink = NULL; // bei Remove geloescht + + sal_Bool bFitBlock = sal_True; // verschieben, wenn durch Update Groesse geaendert + if (pNewFile) + { + aFile = String( *pNewFile ); + aFile = ScGlobal::GetAbsDocName( aFile, pDocShell ); //! in InsertAreaLink? + } + if (pNewFilter) + aFilter = String( *pNewFilter ); + if (pNewOptions) + aOptions = String( *pNewOptions ); + if (pNewSource) + aSource = String( *pNewSource ); + if (pNewDest) + { + ScUnoConversion::FillScRange( aDest, *pNewDest ); + bFitBlock = sal_False; // neuer Bereich angegeben -> keine Inhalte verschieben + } + + ScDocFunc aFunc(*pDocShell); + aFunc.InsertAreaLink( aFile, aFilter, aOptions, aSource, aDest, nRefresh, bFitBlock, sal_True ); + } +} + +void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh ) +{ + ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos ); + if( pLink ) + pLink->SetRefreshDelay( (sal_uLong) nRefresh ); +} + +// XRefreshable + +void SAL_CALL ScAreaLinkObj::refresh() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); + if (pLink) + pLink->Refresh( pLink->GetFile(), pLink->GetFilter(), pLink->GetSource(), pLink->GetRefreshDelay() ); +} + +void SAL_CALL ScAreaLinkObj::addRefreshListener( + const uno::Reference<util::XRefreshListener >& xListener ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference<util::XRefreshListener>* pObj = + new uno::Reference<util::XRefreshListener>( xListener ); + aRefreshListeners.Insert( pObj, aRefreshListeners.Count() ); + + // hold one additional ref to keep this object alive as long as there are listeners + if ( aRefreshListeners.Count() == 1 ) + acquire(); +} + +void SAL_CALL ScAreaLinkObj::removeRefreshListener( + const uno::Reference<util::XRefreshListener >& xListener ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_uInt16 nCount = aRefreshListeners.Count(); + for ( sal_uInt16 n=nCount; n--; ) + { + uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n]; + if ( *pObj == xListener ) + { + aRefreshListeners.DeleteAndDestroy( n ); + if ( aRefreshListeners.Count() == 0 ) + release(); // release ref for listeners + break; + } + } +} + +void ScAreaLinkObj::Refreshed_Impl() +{ + lang::EventObject aEvent; + aEvent.Source.set((cppu::OWeakObject*)this); + for ( sal_uInt16 n=0; n<aRefreshListeners.Count(); n++ ) + (*aRefreshListeners[n])->refreshed( aEvent ); +} + +// XPropertySet + +uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAreaLinkObj::getPropertySetInfo() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + static uno::Reference<beans::XPropertySetInfo> aRef( + new SfxItemPropertySetInfo( aPropSet.getPropertyMap() )); + return aRef; +} + +void SAL_CALL ScAreaLinkObj::setPropertyValue( + const rtl::OUString& aPropertyName, const uno::Any& aValue ) + throw(beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, + uno::RuntimeException) +{ + ScUnoGuard aGuard; + String aNameString(aPropertyName); + rtl::OUString aValStr; + if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) ) + { + if ( aValue >>= aValStr ) + setFileName( aValStr ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) ) + { + if ( aValue >>= aValStr ) + setFilter( aValStr ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) ) + { + if ( aValue >>= aValStr ) + setFilterOptions( aValStr ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) ) + { + sal_Int32 nRefresh = 0; + if ( aValue >>= nRefresh ) + setRefreshDelay( nRefresh ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) ) + { + sal_Int32 nRefresh = 0; + if ( aValue >>= nRefresh ) + setRefreshDelay( nRefresh ); + } +} + +uno::Any SAL_CALL ScAreaLinkObj::getPropertyValue( const rtl::OUString& aPropertyName ) + throw(beans::UnknownPropertyException, lang::WrappedTargetException, + uno::RuntimeException) +{ + ScUnoGuard aGuard; + String aNameString(aPropertyName); + uno::Any aRet; + if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) ) + aRet <<= getFileName(); + else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) ) + aRet <<= getFilter(); + else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) ) + aRet <<= getFilterOptions(); + else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) ) + aRet <<= getRefreshDelay(); + else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) ) + aRet <<= getRefreshDelay(); + return aRet; +} + +SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj ) + +// internal: + +rtl::OUString ScAreaLinkObj::getFileName(void) const +{ + ScUnoGuard aGuard; + rtl::OUString aRet; + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); + if (pLink) + aRet = pLink->GetFile(); + return aRet; +} + +void ScAreaLinkObj::setFileName(const rtl::OUString& rNewName) +{ + ScUnoGuard aGuard; + Modify_Impl( &rNewName, NULL, NULL, NULL, NULL ); +} + +rtl::OUString ScAreaLinkObj::getFilter(void) const +{ + ScUnoGuard aGuard; + rtl::OUString aRet; + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); + if (pLink) + aRet = pLink->GetFilter(); + return aRet; +} + +void ScAreaLinkObj::setFilter(const rtl::OUString& Filter) +{ + ScUnoGuard aGuard; + Modify_Impl( NULL, &Filter, NULL, NULL, NULL ); +} + +rtl::OUString ScAreaLinkObj::getFilterOptions(void) const +{ + ScUnoGuard aGuard; + rtl::OUString aRet; + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); + if (pLink) + aRet = pLink->GetOptions(); + return aRet; +} + +void ScAreaLinkObj::setFilterOptions(const rtl::OUString& FilterOptions) +{ + ScUnoGuard aGuard; + Modify_Impl( NULL, NULL, &FilterOptions, NULL, NULL ); +} + +sal_Int32 ScAreaLinkObj::getRefreshDelay(void) const +{ + ScUnoGuard aGuard; + sal_Int32 nRet = 0; + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); + if (pLink) + nRet = (sal_Int32) pLink->GetRefreshDelay(); + return nRet; +} + +void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay) +{ + ScUnoGuard aGuard; + ModifyRefreshDelay_Impl( nRefreshDelay ); +} + +// XAreaLink + +rtl::OUString SAL_CALL ScAreaLinkObj::getSourceArea() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + rtl::OUString aRet; + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); + if (pLink) + aRet = pLink->GetSource(); + return aRet; +} + +void SAL_CALL ScAreaLinkObj::setSourceArea( const rtl::OUString& aSourceArea ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + Modify_Impl( NULL, NULL, NULL, &aSourceArea, NULL ); +} + +table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + table::CellRangeAddress aRet; + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); + if (pLink) + ScUnoConversion::FillApiRange( aRet, pLink->GetDestArea() ); + return aRet; +} + +void SAL_CALL ScAreaLinkObj::setDestArea( const table::CellRangeAddress& aDestArea ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea ); +} + +//------------------------------------------------------------------------ + +ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) : + pDocShell( pDocSh ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScAreaLinksObj::~ScAreaLinksObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + // Referenz-Update interessiert hier nicht + + if ( rHint.ISA( SfxSimpleHint ) && + ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + { + pDocShell = NULL; // ungueltig geworden + } +} + +// XAreaLinks + +ScAreaLinkObj* ScAreaLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex) +{ + if ( pDocShell && nIndex >= 0 && nIndex < getCount() ) + return new ScAreaLinkObj( pDocShell, (sal_uInt16)nIndex ); + + return NULL; // nicht gefunden +} + +void SAL_CALL ScAreaLinksObj::insertAtPosition( const table::CellAddress& aDestPos, + const rtl::OUString& aFileName, + const rtl::OUString& aSourceArea, + const rtl::OUString& aFilter, + const rtl::OUString& aFilterOptions ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDocShell) + { + String aFileStr (aFileName); + String aFilterStr (aFilter); + String aOptionStr (aFilterOptions); + String aSourceStr (aSourceArea); + ScAddress aDestAddr( (SCCOL)aDestPos.Column, (SCROW)aDestPos.Row, aDestPos.Sheet ); + + aFileStr = ScGlobal::GetAbsDocName( aFileStr, pDocShell ); //! in InsertAreaLink ??? + + ScDocFunc aFunc(*pDocShell); + aFunc.InsertAreaLink( aFileStr, aFilterStr, aOptionStr, + aSourceStr, ScRange(aDestAddr), + 0, sal_False, sal_True ); // keine Inhalte verschieben + } +} + +void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, (sal_uInt16)nIndex); + if (pLink) + { + //! SetAddUndo oder so + + sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager(); + pLinkManager->Remove( pLink ); + } +} + +// XEnumerationAccess + +uno::Reference<container::XEnumeration> SAL_CALL ScAreaLinksObj::createEnumeration() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.CellAreaLinksEnumeration"))); +} + +// XIndexAccess + +sal_Int32 SAL_CALL ScAreaLinksObj::getCount() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nAreaCount = 0; + if (pDocShell) + { + sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager(); + sal_uInt16 nTotalCount = pLinkManager->GetLinks().Count(); + for (sal_uInt16 i=0; i<nTotalCount; i++) + { + ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i]; + if (pBase->ISA(ScAreaLink)) + ++nAreaCount; + } + } + return nAreaCount; +} + +uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex ) + throw(lang::IndexOutOfBoundsException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference<sheet::XAreaLink> xLink(GetObjectByIndex_Impl(nIndex)); + if (xLink.is()) + return uno::makeAny(xLink); + else + throw lang::IndexOutOfBoundsException(); +// return uno::Any(); +} + +uno::Type SAL_CALL ScAreaLinksObj::getElementType() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return getCppuType((uno::Reference<sheet::XAreaLink>*)0); +} + +sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return ( getCount() != 0 ); +} + +//------------------------------------------------------------------------ + +ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const String& rA, + const String& rT, const String& rI) : + pDocShell( pDocSh ), + aAppl( rA ), + aTopic( rT ), + aItem( rI ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScDDELinkObj::~ScDDELinkObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScDDELinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + //! notify if links in document are changed + // UpdateRef is not needed here + + if ( rHint.ISA( SfxSimpleHint ) ) + { + if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + pDocShell = NULL; // pointer is invalid + } + else if ( rHint.ISA( ScLinkRefreshedHint ) ) + { + const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint; + if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE && + rLH.GetDdeAppl() == aAppl && + rLH.GetDdeTopic() == aTopic && + rLH.GetDdeItem() == aItem ) //! mode is ignored + Refreshed_Impl(); + } +} + +// XNamed + +String lcl_BuildDDEName( const String& rAppl, const String& rTopic, const String& rItem ) +{ + // Appl|Topic!Item (wie Excel) + String aRet = rAppl; + aRet += '|'; + aRet += rTopic; + aRet += '!'; + aRet += rItem; + return aRet; +} + +rtl::OUString SAL_CALL ScDDELinkObj::getName() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return lcl_BuildDDEName( aAppl, aTopic, aItem ); +} + +void SAL_CALL ScDDELinkObj::setName( const rtl::OUString& /* aName */ ) throw(uno::RuntimeException) +{ + // name can't be changed (formulas wouldn't find the link) + throw uno::RuntimeException(); +} + +// XDDELink + +rtl::OUString SAL_CALL ScDDELinkObj::getApplication() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + //! Test, ob Link noch im Dokument enthalten? + + return aAppl; +} + +rtl::OUString SAL_CALL ScDDELinkObj::getTopic() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + //! Test, ob Link noch im Dokument enthalten? + + return aTopic; +} + +rtl::OUString SAL_CALL ScDDELinkObj::getItem() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + //! Test, ob Link noch im Dokument enthalten? + + return aItem; +} + +// XRefreshable + +void SAL_CALL ScDDELinkObj::refresh() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + (void)pDoc->UpdateDdeLink( aAppl, aTopic, aItem ); + //! Fehler abfragen + } +} + +void SAL_CALL ScDDELinkObj::addRefreshListener( + const uno::Reference<util::XRefreshListener >& xListener ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference<util::XRefreshListener>* pObj = + new uno::Reference<util::XRefreshListener>( xListener ); + aRefreshListeners.Insert( pObj, aRefreshListeners.Count() ); + + // hold one additional ref to keep this object alive as long as there are listeners + if ( aRefreshListeners.Count() == 1 ) + acquire(); +} + +void SAL_CALL ScDDELinkObj::removeRefreshListener( + const uno::Reference<util::XRefreshListener >& xListener ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_uInt16 nCount = aRefreshListeners.Count(); + for ( sal_uInt16 n=nCount; n--; ) + { + uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n]; + if ( *pObj == xListener ) + { + aRefreshListeners.DeleteAndDestroy( n ); + if ( aRefreshListeners.Count() == 0 ) + release(); // release ref for listeners + break; + } + } +} + +// XDDELinkResults + +uno::Sequence< uno::Sequence< uno::Any > > ScDDELinkObj::getResults( ) + throw (uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Sequence< uno::Sequence< uno::Any > > aReturn; + bool bSuccess = false; + + if ( pDocShell ) + { + ScDocument* pDoc = pDocShell->GetDocument(); + if ( pDoc ) + { + sal_uInt16 nPos = 0; + if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) ) + { + const ScMatrix* pMatrix = pDoc->GetDdeLinkResultMatrix( nPos ); + if ( pMatrix ) + { + uno::Any aAny; + if ( ScRangeToSequence::FillMixedArray( aAny, pMatrix, true ) ) + { + aAny >>= aReturn; + } + } + bSuccess = true; + } + } + } + + if ( !bSuccess ) + { + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "ScDDELinkObj::getResults: failed to get results!" ) ), + uno::Reference< uno::XInterface >() ); + } + + return aReturn; +} + +void ScDDELinkObj::setResults( const uno::Sequence< uno::Sequence< uno::Any > >& aResults ) + throw (uno::RuntimeException) +{ + ScUnoGuard aGuard; + bool bSuccess = false; + + if ( pDocShell ) + { + ScDocument* pDoc = pDocShell->GetDocument(); + if ( pDoc ) + { + sal_uInt16 nPos = 0; + if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) ) + { + uno::Any aAny; + aAny <<= aResults; + ScMatrixRef xMatrix = ScSequenceToMatrix::CreateMixedMatrix( aAny ); + bSuccess = pDoc->SetDdeLinkResultMatrix( nPos, xMatrix ); + } + } + } + + if ( !bSuccess ) + { + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "ScDDELinkObj::setResults: failed to set results!" ) ), + uno::Reference< uno::XInterface >() ); + } +} + +void ScDDELinkObj::Refreshed_Impl() +{ + lang::EventObject aEvent; + aEvent.Source.set((cppu::OWeakObject*)this); + for ( sal_uInt16 n=0; n<aRefreshListeners.Count(); n++ ) + (*aRefreshListeners[n])->refreshed( aEvent ); +} + +//------------------------------------------------------------------------ + +ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) : + pDocShell( pDocSh ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScDDELinksObj::~ScDDELinksObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + // Referenz-Update interessiert hier nicht + + if ( rHint.ISA( SfxSimpleHint ) && + ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + { + pDocShell = NULL; // ungueltig geworden + } +} + +// XDDELinks + +ScDDELinkObj* ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex) +{ + if (pDocShell) + { + String aAppl, aTopic, aItem; + if ( nIndex <= USHRT_MAX && + pDocShell->GetDocument()->GetDdeLinkData( (sal_uInt16)nIndex, aAppl, aTopic, aItem ) ) + return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem ); + } + return NULL; +} + +ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const rtl::OUString& aName) +{ + if (pDocShell) + { + String aNamStr(aName); + String aAppl, aTopic, aItem; + + ScDocument* pDoc = pDocShell->GetDocument(); + sal_uInt16 nCount = pDoc->GetDdeLinkCount(); + for (sal_uInt16 i=0; i<nCount; i++) + { + pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem ); + if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr ) + return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem ); + } + } + return NULL; +} + +// XEnumerationAccess + +uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DDELinksEnumeration"))); +} + +// XIndexAccess + +sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nAreaCount = 0; + if (pDocShell) + nAreaCount = pDocShell->GetDocument()->GetDdeLinkCount(); + return nAreaCount; +} + +uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex ) + throw(lang::IndexOutOfBoundsException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex)); + if (xLink.is()) + return uno::makeAny(xLink); + else + throw lang::IndexOutOfBoundsException(); +// return uno::Any(); +} + +uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return getCppuType((uno::Reference<sheet::XDDELink>*)0); +} + +sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return ( getCount() != 0 ); +} + +uno::Any SAL_CALL ScDDELinksObj::getByName( const rtl::OUString& aName ) + throw(container::NoSuchElementException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName)); + if (xLink.is()) + return uno::makeAny(xLink); + else + throw container::NoSuchElementException(); +// return uno::Any(); +} + +uno::Sequence<rtl::OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDocShell) + { + String aAppl, aTopic, aItem; + + ScDocument* pDoc = pDocShell->GetDocument(); + sal_uInt16 nCount = pDoc->GetDdeLinkCount(); + uno::Sequence<rtl::OUString> aSeq(nCount); + rtl::OUString* pAry = aSeq.getArray(); + + for (sal_uInt16 i=0; i<nCount; i++) + { + pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem ); + pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem); + } + return aSeq; + } + return uno::Sequence<rtl::OUString>(); +} + +sal_Bool SAL_CALL ScDDELinksObj::hasByName( const rtl::OUString& aName ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDocShell) + { + String aNamStr(aName); + String aAppl, aTopic, aItem; + + ScDocument* pDoc = pDocShell->GetDocument(); + sal_uInt16 nCount = pDoc->GetDdeLinkCount(); + for (sal_uInt16 i=0; i<nCount; i++) + { + pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem ); + if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr ) + return sal_True; + } + } + return sal_False; +} + +// XDDELinks + +uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink( + const ::rtl::OUString& aApplication, const ::rtl::OUString& aTopic, + const ::rtl::OUString& aItem, ::com::sun::star::sheet::DDELinkMode nMode ) + throw (uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference< sheet::XDDELink > xLink; + + if ( pDocShell ) + { + ScDocument* pDoc = pDocShell->GetDocument(); + if ( pDoc ) + { + sal_uInt8 nMod = SC_DDE_DEFAULT; + switch ( nMode ) + { + case sheet::DDELinkMode_DEFAULT: + { + nMod = SC_DDE_DEFAULT; + } + break; + case sheet::DDELinkMode_ENGLISH: + { + nMod = SC_DDE_ENGLISH; + } + break; + case sheet::DDELinkMode_TEXT: + { + nMod = SC_DDE_TEXT; + } + break; + default: + { + } + break; + } + + if ( pDoc->CreateDdeLink( aApplication, aTopic, aItem, nMod ) ) + { + const ::rtl::OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) ); + xLink.set( GetObjectByName_Impl( aName ) ); + } + } + } + + if ( !xLink.is() ) + { + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "ScDDELinksObj::addDDELink: cannot add DDE link!" ) ), + uno::Reference< uno::XInterface >() ); + } + + return xLink; +} + +// ============================================================================ + +ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable, size_t nIndex) : + mpTable(pTable), + mnIndex(nIndex) +{ +} + +ScExternalSheetCacheObj::~ScExternalSheetCacheObj() +{ +} + +void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue) + throw (IllegalArgumentException, RuntimeException) +{ + ScUnoGuard aGuard; + if (nRow < 0 || nCol < 0) + throw IllegalArgumentException(); + + ScExternalRefCache::TokenRef pToken; + double fVal = 0.0; + OUString aVal; + if (rValue >>= fVal) + pToken.reset(new FormulaDoubleToken(fVal)); + else if (rValue >>= aVal) + pToken.reset(new FormulaStringToken(aVal)); + else + // unidentified value type. + return; + + mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken); +} + +Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow) + throw (IllegalArgumentException, RuntimeException) +{ + ScUnoGuard aGuard; + if (nRow < 0 || nCol < 0) + throw IllegalArgumentException(); + + FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get(); + if (!pToken) + throw IllegalArgumentException(); + + Any aValue; + switch (pToken->GetType()) + { + case svDouble: + { + double fVal = pToken->GetDouble(); + aValue <<= fVal; + } + break; + case svString: + { + OUString aVal = pToken->GetString(); + aValue <<= aVal; + } + break; + default: + throw IllegalArgumentException(); + } + return aValue; +} + +Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + vector<SCROW> aRows; + mpTable->getAllRows(aRows); + size_t nSize = aRows.size(); + Sequence<sal_Int32> aRowsSeq(nSize); + for (size_t i = 0; i < nSize; ++i) + aRowsSeq[i] = aRows[i]; + + return aRowsSeq; +} + +Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow) + throw (IllegalArgumentException, RuntimeException) +{ + ScUnoGuard aGuard; + if (nRow < 0) + throw IllegalArgumentException(); + + vector<SCCOL> aCols; + mpTable->getAllCols(static_cast<SCROW>(nRow), aCols); + size_t nSize = aCols.size(); + Sequence<sal_Int32> aColsSeq(nSize); + for (size_t i = 0; i < nSize; ++i) + aColsSeq[i] = aCols[i]; + + return aColsSeq; +} + +sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex() + throw (RuntimeException) +{ + return static_cast< sal_Int32 >( mnIndex ); +} + +// ============================================================================ + +ScExternalDocLinkObj::ScExternalDocLinkObj(ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) : + mpRefMgr(pRefMgr), mnFileId(nFileId) +{ +} + +ScExternalDocLinkObj::~ScExternalDocLinkObj() +{ +} + +Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache( + const OUString& aSheetName, sal_Bool bDynamicCache ) + throw (RuntimeException) +{ + ScUnoGuard aGuard; + size_t nIndex = 0; + ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex); + if (!bDynamicCache) + // Set the whole table cached to prevent access to the source document. + pTable->setWholeTableCached(); + + Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex)); + return aSheetCache; +} + +Any SAL_CALL ScExternalDocLinkObj::getByName(const::rtl::OUString &aName) + throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) +{ + ScUnoGuard aGuard; + size_t nIndex = 0; + ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex); + if (!pTable) + throw container::NoSuchElementException(); + + Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex)); + + Any aAny; + aAny <<= aSheetCache; + return aAny; +} + +Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + vector<String> aTabNames; + mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames); + size_t n = aTabNames.size(); + Sequence<OUString> aSeq(n); + for (size_t i = 0; i < n; ++i) + aSeq[i] = aTabNames[i]; + return aSeq; +} + +sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName) + throw (RuntimeException) +{ + ScUnoGuard aGuard; + return static_cast<sal_Bool>(mpRefMgr->hasCacheTable(mnFileId, aName)); +} + +sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + return static_cast<sal_Int32>(mpRefMgr->getCacheTableCount(mnFileId)); +} + +Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nIndex) + throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException) +{ + ScUnoGuard aGuard; + size_t nTabCount = mpRefMgr->getCacheTableCount(mnFileId); + if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(nTabCount)) + throw lang::IndexOutOfBoundsException(); + + ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, static_cast<size_t>(nIndex)); + if (!pTable) + throw lang::IndexOutOfBoundsException(); + + Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex)); + + Any aAny; + aAny <<= aSheetCache; + return aAny; +} + +Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + Reference< container::XEnumeration > aRef( + new ScIndexEnumeration(this, OUString::createFromAscii( + "com.sun.star.sheet.ExternalDocLink"))); + return aRef; +} + +uno::Type SAL_CALL ScExternalDocLinkObj::getElementType() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + return getCppuType(static_cast<Reference<sheet::XExternalDocLink>*>(0)); +} + +sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + return static_cast<sal_Bool>(mpRefMgr->getCacheTableCount(mnFileId) > 0); +} + +sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex() + throw (RuntimeException) +{ + return static_cast<sal_Int32>(mnFileId); +} + +// ============================================================================ + +ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) : + mpDocShell(pDocShell), + mpRefMgr(pDocShell->GetDocument()->GetExternalRefManager()) +{ +} + +ScExternalDocLinksObj::~ScExternalDocLinksObj() +{ +} + +Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink( + const OUString& aDocName ) + throw (RuntimeException) +{ + ScUnoGuard aGuard; + sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocName); + Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId)); + return aDocLink; +} + +Any SAL_CALL ScExternalDocLinksObj::getByName(const::rtl::OUString &aName) + throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) +{ + ScUnoGuard aGuard; + if (!mpRefMgr->hasExternalFile(aName)) + throw container::NoSuchElementException(); + + sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aName); + Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId)); + + Any aAny; + aAny <<= aDocLink; + return aAny; +} + +Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + sal_uInt16 n = mpRefMgr->getExternalFileCount(); + Sequence<OUString> aSeq(n); + for (sal_uInt16 i = 0; i < n; ++i) + { + const String* pName = mpRefMgr->getExternalFileName(i); + aSeq[i] = pName ? *pName : EMPTY_STRING; + } + + return aSeq; +} + +sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName) + throw (RuntimeException) +{ + ScUnoGuard aGuard; + return mpRefMgr->hasExternalFile(aName); +} + +sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + return mpRefMgr->getExternalFileCount(); +} + +Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex) + throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException) +{ + ScUnoGuard aGuard; + if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min()) + throw lang::IndexOutOfBoundsException(); + + sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex); + + if (!mpRefMgr->hasExternalFile(nFileId)) + throw lang::IndexOutOfBoundsException(); + + Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId)); + Any aAny; + aAny <<= aDocLink; + return aAny; +} + +Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + Reference< container::XEnumeration > aRef( + new ScIndexEnumeration(this, OUString::createFromAscii( + "com.sun.star.sheet.ExternalDocLinks"))); + return aRef; +} + +uno::Type SAL_CALL ScExternalDocLinksObj::getElementType() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + return getCppuType(static_cast<Reference<sheet::XExternalDocLinks>*>(0)); +} + +sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements() + throw (RuntimeException) +{ + ScUnoGuard aGuard; + return mpRefMgr->getExternalFileCount() > 0; +} + |