diff options
Diffstat (limited to 'sc/source/ui/unoobj/nameuno.cxx')
-rw-r--r-- | sc/source/ui/unoobj/nameuno.cxx | 1134 |
1 files changed, 1134 insertions, 0 deletions
diff --git a/sc/source/ui/unoobj/nameuno.cxx b/sc/source/ui/unoobj/nameuno.cxx new file mode 100644 index 000000000000..ab8576949b75 --- /dev/null +++ b/sc/source/ui/unoobj/nameuno.cxx @@ -0,0 +1,1134 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: nameuno.cxx,v $ + * $Revision: 1.21.132.2 $ + * + * 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 <com/sun/star/sheet/NamedRangeFlag.hpp> +#include <com/sun/star/awt/XBitmap.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +using namespace ::com::sun::star; + + +#include "nameuno.hxx" +#include "miscuno.hxx" +#include "cellsuno.hxx" +#include "convuno.hxx" +#include "targuno.hxx" +#include "tokenuno.hxx" +#include "tokenarray.hxx" +#include "docsh.hxx" +#include "docfunc.hxx" +#include "rangenam.hxx" +//CHINA001 #include "namecrea.hxx" // NAME_TOP etc. +#include "unoguard.hxx" +#include "unonames.hxx" + +#include "scui_def.hxx" //CHINA001 + +//------------------------------------------------------------------------ + +const SfxItemPropertyMapEntry* lcl_GetNamedRangeMap() +{ + static SfxItemPropertyMapEntry aNamedRangeMap_Impl[] = + { + {MAP_CHAR_LEN(SC_UNO_LINKDISPBIT), 0, &getCppuType((uno::Reference<awt::XBitmap>*)0), beans::PropertyAttribute::READONLY, 0 }, + {MAP_CHAR_LEN(SC_UNO_LINKDISPNAME), 0, &getCppuType((rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 }, + {MAP_CHAR_LEN(SC_UNONAME_TOKENINDEX), 0, &getCppuType((sal_Int32*)0), beans::PropertyAttribute::READONLY, 0 }, + {MAP_CHAR_LEN(SC_UNONAME_ISSHAREDFMLA), 0, &getBooleanCppuType(), 0, 0 }, + {0,0,0,0,0,0} + }; + return aNamedRangeMap_Impl; +} + +//------------------------------------------------------------------------ + +#define SCNAMEDRANGEOBJ_SERVICE "com.sun.star.sheet.NamedRange" + +SC_SIMPLE_SERVICE_INFO( ScLabelRangeObj, "ScLabelRangeObj", "com.sun.star.sheet.LabelRange" ) +SC_SIMPLE_SERVICE_INFO( ScLabelRangesObj, "ScLabelRangesObj", "com.sun.star.sheet.LabelRanges" ) +SC_SIMPLE_SERVICE_INFO( ScNamedRangesObj, "ScNamedRangesObj", "com.sun.star.sheet.NamedRanges" ) + +//------------------------------------------------------------------------ + +sal_Bool lcl_UserVisibleName( const ScRangeData* pData ) +{ + //! als Methode an ScRangeData + + return ( pData && !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) ); +} + +//------------------------------------------------------------------------ + +ScNamedRangeObj::ScNamedRangeObj(ScDocShell* pDocSh, const String& rNm) : + pDocShell( pDocSh ), + aName( rNm ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScNamedRangeObj::~ScNamedRangeObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScNamedRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + // Ref-Update interessiert nicht + + if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + pDocShell = NULL; // ungueltig geworden +} + +// Hilfsfuntionen + +ScRangeData* ScNamedRangeObj::GetRangeData_Impl() +{ + ScRangeData* pRet = NULL; + if (pDocShell) + { + ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); + if (pNames) + { + sal_uInt16 nPos = 0; + if (pNames->SearchName( aName, nPos )) + { + pRet = (*pNames)[nPos]; + pRet->ValidateTabRefs(); // adjust relative tab refs to valid tables + } + } + } + return pRet; +} + +// sheet::XNamedRange + +void ScNamedRangeObj::Modify_Impl( const String* pNewName, const ScTokenArray* pNewTokens, const String* pNewContent, + const ScAddress* pNewPos, const sal_uInt16* pNewType, + const formula::FormulaGrammar::Grammar eGrammar ) +{ + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + ScRangeName* pNames = pDoc->GetRangeName(); + if (pNames) + { + sal_uInt16 nPos = 0; + if (pNames->SearchName( aName, nPos )) + { + ScRangeName* pNewRanges = new ScRangeName( *pNames ); + ScRangeData* pOld = (*pNames)[nPos]; + + String aInsName(pOld->GetName()); + if (pNewName) + aInsName = *pNewName; + String aContent; // Content string based => + pOld->GetSymbol( aContent, eGrammar); // no problems with changed positions and such. + if (pNewContent) + aContent = *pNewContent; + ScAddress aPos(pOld->GetPos()); + if (pNewPos) + aPos = *pNewPos; + sal_uInt16 nType = pOld->GetType(); + if (pNewType) + nType = *pNewType; + + ScRangeData* pNew = NULL; + if ( pNewTokens ) + pNew = new ScRangeData( pDoc, aInsName, *pNewTokens, aPos, nType ); + else + pNew = new ScRangeData( pDoc, aInsName, aContent, aPos, nType, eGrammar ); + pNew->SetIndex( pOld->GetIndex() ); + + pNewRanges->AtFree( nPos ); + if ( pNewRanges->Insert(pNew) ) + { + ScDocFunc aFunc(*pDocShell); + aFunc.SetNewRangeNames( pNewRanges, sal_True ); + + aName = aInsName; //! broadcast? + } + else + { + delete pNew; //! uno::Exception/Fehler oder so + delete pNewRanges; + } + } + } + } +} + + +rtl::OUString SAL_CALL ScNamedRangeObj::getName() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return aName; +} + +void SAL_CALL ScNamedRangeObj::setName( const rtl::OUString& aNewName ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + //! Formeln anpassen ????? + + String aNewStr(aNewName); + // GRAM_PODF_A1 for API compatibility. + Modify_Impl( &aNewStr, NULL, NULL, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 ); + + if ( aName != aNewStr ) // some error occured... + throw uno::RuntimeException(); // no other exceptions specified +} + +rtl::OUString SAL_CALL ScNamedRangeObj::getContent() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + String aContent; + ScRangeData* pData = GetRangeData_Impl(); + if (pData) + // GRAM_PODF_A1 for API compatibility. + pData->GetSymbol( aContent,formula::FormulaGrammar::GRAM_PODF_A1); + return aContent; +} + +void SAL_CALL ScNamedRangeObj::setContent( const rtl::OUString& aContent ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + String aContStr(aContent); + // GRAM_PODF_A1 for API compatibility. + Modify_Impl( NULL, NULL, &aContStr, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 ); +} + +void ScNamedRangeObj::SetContentWithGrammar( const ::rtl::OUString& aContent, + const formula::FormulaGrammar::Grammar eGrammar ) + throw(::com::sun::star::uno::RuntimeException) +{ + String aContStr(aContent); + Modify_Impl( NULL, NULL, &aContStr, NULL, NULL, eGrammar ); +} + +table::CellAddress SAL_CALL ScNamedRangeObj::getReferencePosition() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScAddress aPos; + ScRangeData* pData = GetRangeData_Impl(); + if (pData) + aPos = pData->GetPos(); + table::CellAddress aAddress; + aAddress.Column = aPos.Col(); + aAddress.Row = aPos.Row(); + aAddress.Sheet = aPos.Tab(); + if (pDocShell) + { + SCTAB nDocTabs = pDocShell->GetDocument()->GetTableCount(); + if ( aAddress.Sheet >= nDocTabs && nDocTabs > 0 ) + { + // Even after ValidateTabRefs, the position can be invalid if + // the content points to preceding tables. The resulting string + // is invalid in any case, so the position is just shifted. + aAddress.Sheet = nDocTabs - 1; + } + } + return aAddress; +} + +void SAL_CALL ScNamedRangeObj::setReferencePosition( const table::CellAddress& aReferencePosition ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScAddress aPos( (SCCOL)aReferencePosition.Column, (SCROW)aReferencePosition.Row, aReferencePosition.Sheet ); + // GRAM_PODF_A1 for API compatibility. + Modify_Impl( NULL, NULL, NULL, &aPos, NULL,formula::FormulaGrammar::GRAM_PODF_A1 ); +} + +sal_Int32 SAL_CALL ScNamedRangeObj::getType() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nType=0; + ScRangeData* pData = GetRangeData_Impl(); + if (pData) + { + // do not return internal RT_* flags + // see property 'IsSharedFormula' for RT_SHARED + if ( pData->HasType(RT_CRITERIA) ) nType |= sheet::NamedRangeFlag::FILTER_CRITERIA; + if ( pData->HasType(RT_PRINTAREA) ) nType |= sheet::NamedRangeFlag::PRINT_AREA; + if ( pData->HasType(RT_COLHEADER) ) nType |= sheet::NamedRangeFlag::COLUMN_HEADER; + if ( pData->HasType(RT_ROWHEADER) ) nType |= sheet::NamedRangeFlag::ROW_HEADER; + } + return nType; +} + +void SAL_CALL ScNamedRangeObj::setType( sal_Int32 nUnoType ) throw(uno::RuntimeException) +{ + // see property 'IsSharedFormula' for RT_SHARED + ScUnoGuard aGuard; + sal_uInt16 nNewType = RT_NAME; + if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA; + if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA; + if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER; + if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER; + + // GRAM_PODF_A1 for API compatibility. + Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 ); +} + +// XFormulaTokens + +uno::Sequence<sheet::FormulaToken> SAL_CALL ScNamedRangeObj::getTokens() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Sequence<sheet::FormulaToken> aSequence; + ScRangeData* pData = GetRangeData_Impl(); + if (pData && pDocShell) + { + ScTokenArray* pTokenArray = pData->GetCode(); + if ( pTokenArray ) + (void)ScTokenConversion::ConvertToTokenSequence( *pDocShell->GetDocument(), aSequence, *pTokenArray ); + } + return aSequence; +} + +void SAL_CALL ScNamedRangeObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if( pDocShell ) + { + ScTokenArray aTokenArray; + (void)ScTokenConversion::ConvertToTokenArray( *pDocShell->GetDocument(), aTokenArray, rTokens ); + // GRAM_PODF_A1 for API compatibility. + Modify_Impl( NULL, &aTokenArray, NULL, NULL, NULL, formula::FormulaGrammar::GRAM_PODF_A1 ); + } +} + + +// XCellRangeSource + +uno::Reference<table::XCellRange> SAL_CALL ScNamedRangeObj::getReferredCells() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScRange aRange; + ScRangeData* pData = GetRangeData_Impl(); + if ( pData && pData->IsReference( aRange ) ) + { + //! static Funktion um ScCellObj/ScCellRangeObj zu erzeugen am ScCellRangeObj ??? + + if ( aRange.aStart == aRange.aEnd ) + return new ScCellObj( pDocShell, aRange.aStart ); + else + return new ScCellRangeObj( pDocShell, aRange ); + } + return NULL; +} + +// beans::XPropertySet + +uno::Reference<beans::XPropertySetInfo> SAL_CALL ScNamedRangeObj::getPropertySetInfo() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetNamedRangeMap() )); + return aRef; +} + +void SAL_CALL ScNamedRangeObj::setPropertyValue( + const rtl::OUString& rPropertyName, const uno::Any& aValue ) + throw(beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, + uno::RuntimeException) +{ + ScUnoGuard aGuard; + if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) ) + { + bool bIsShared = false; + if( aValue >>= bIsShared ) + { + sal_uInt16 nNewType = bIsShared ? RT_SHARED : RT_NAME; + Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 ); + } + } +} + +uno::Any SAL_CALL ScNamedRangeObj::getPropertyValue( const rtl::OUString& rPropertyName ) + throw(beans::UnknownPropertyException, lang::WrappedTargetException, + uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Any aRet; + if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPBIT ) ) + { + // no target bitmaps for individual entries (would be all equal) + // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_RANGENAME ); + } + else if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPNAME ) ) + aRet <<= rtl::OUString( aName ); + else if ( rPropertyName.equalsAscii( SC_UNONAME_TOKENINDEX ) ) + { + // get index for use in formula tokens (read-only) + ScRangeData* pData = GetRangeData_Impl(); + if (pData) + aRet <<= static_cast<sal_Int32>(pData->GetIndex()); + } + else if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) ) + { + if( ScRangeData* pData = GetRangeData_Impl() ) + aRet <<= static_cast< bool >( pData->HasType( RT_SHARED ) ); + } + return aRet; +} + +SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangeObj ) + +// lang::XServiceInfo + +rtl::OUString SAL_CALL ScNamedRangeObj::getImplementationName() throw(uno::RuntimeException) +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScNamedRangeObj" ) ); +} + +sal_Bool SAL_CALL ScNamedRangeObj::supportsService( const rtl::OUString& rServiceName ) + throw(uno::RuntimeException) +{ + return rServiceName.equalsAscii( SCNAMEDRANGEOBJ_SERVICE ) || + rServiceName.equalsAscii( SCLINKTARGET_SERVICE ); +} + +uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangeObj::getSupportedServiceNames() + throw(uno::RuntimeException) +{ + uno::Sequence<rtl::OUString> aRet(2); + aRet[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCNAMEDRANGEOBJ_SERVICE ) ); + aRet[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCLINKTARGET_SERVICE ) ); + return aRet; +} + + +// XUnoTunnel + +sal_Int64 SAL_CALL ScNamedRangeObj::getSomething( + const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException) +{ + if ( rId.getLength() == 16 && + 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), + rId.getConstArray(), 16 ) ) + { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); + } + return 0; +} + +// static +const uno::Sequence<sal_Int8>& ScNamedRangeObj::getUnoTunnelId() +{ + static uno::Sequence<sal_Int8> * pSeq = 0; + if( !pSeq ) + { + osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); + if( !pSeq ) + { + static uno::Sequence< sal_Int8 > aSeq( 16 ); + rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); + pSeq = &aSeq; + } + } + return *pSeq; +} + +// static +ScNamedRangeObj* ScNamedRangeObj::getImplementation( const uno::Reference<uno::XInterface> xObj ) +{ + ScNamedRangeObj* pRet = NULL; + uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY ); + if (xUT.is()) + pRet = reinterpret_cast<ScNamedRangeObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId()))); + return pRet; +} + +//------------------------------------------------------------------------ + +ScNamedRangesObj::ScNamedRangesObj(ScDocShell* pDocSh) : + pDocShell( pDocSh ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScNamedRangesObj::~ScNamedRangesObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScNamedRangesObj::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 + } +} + +// sheet::XNamedRanges + +ScNamedRangeObj* ScNamedRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex) +{ + if (pDocShell) + { + ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); + if (pNames) + { + sal_uInt16 nCount = pNames->GetCount(); + sal_uInt16 nPos = 0; + for (sal_uInt16 i=0; i<nCount; i++) + { + ScRangeData* pData = (*pNames)[i]; + if (lcl_UserVisibleName(pData)) // interne weglassen + { + if ( nPos == nIndex ) + return new ScNamedRangeObj( pDocShell, pData->GetName() ); + ++nPos; + } + } + } + } + return NULL; +} + +ScNamedRangeObj* ScNamedRangesObj::GetObjectByName_Impl(const rtl::OUString& aName) +{ + if ( pDocShell && hasByName(aName) ) + return new ScNamedRangeObj( pDocShell, String(aName) ); + return NULL; +} + +void SAL_CALL ScNamedRangesObj::addNewByName( const rtl::OUString& aName, + const rtl::OUString& aContent, const table::CellAddress& aPosition, + sal_Int32 nUnoType ) throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + String aNameStr(aName); + String aContStr(aContent); + ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, aPosition.Sheet ); + + sal_uInt16 nNewType = RT_NAME; + if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA; + if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA; + if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER; + if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER; + + BOOL bDone = FALSE; + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + ScRangeName* pNames = pDoc->GetRangeName(); + USHORT nIndex = 0; + if (pNames && !pNames->SearchName(aNameStr, nIndex)) + { + ScRangeName* pNewRanges = new ScRangeName( *pNames ); + // GRAM_PODF_A1 for API compatibility. + ScRangeData* pNew = new ScRangeData( pDoc, aNameStr, aContStr, + aPos, nNewType,formula::FormulaGrammar::GRAM_PODF_A1 ); + if ( pNewRanges->Insert(pNew) ) + { + ScDocFunc aFunc(*pDocShell); + aFunc.SetNewRangeNames( pNewRanges, sal_True ); + bDone = TRUE; + } + else + { + delete pNew; + delete pNewRanges; + } + } + } + + if (!bDone) + throw uno::RuntimeException(); // no other exceptions specified +} + +void SAL_CALL ScNamedRangesObj::addNewFromTitles( const table::CellRangeAddress& aSource, + sheet::Border aBorder ) throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + //! das darf kein enum sein, weil mehrere Bits gesetzt sein koennen !!! + + sal_Bool bTop = ( aBorder == sheet::Border_TOP ); + sal_Bool bLeft = ( aBorder == sheet::Border_LEFT ); + sal_Bool bBottom = ( aBorder == sheet::Border_BOTTOM ); + sal_Bool bRight = ( aBorder == sheet::Border_RIGHT ); + + ScRange aRange; + ScUnoConversion::FillScRange( aRange, aSource ); + + sal_uInt16 nFlags = 0; + if (bTop) nFlags |= NAME_TOP; + if (bLeft) nFlags |= NAME_LEFT; + if (bBottom) nFlags |= NAME_BOTTOM; + if (bRight) nFlags |= NAME_RIGHT; + + if (nFlags) + { + ScDocFunc aFunc(*pDocShell); + aFunc.CreateNames( aRange, nFlags, sal_True ); + } +} + +void SAL_CALL ScNamedRangesObj::removeByName( const rtl::OUString& aName ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + BOOL bDone = FALSE; + if (pDocShell) + { + ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); + if (pNames) + { + String aString(aName); + sal_uInt16 nPos = 0; + if (pNames->SearchName( aString, nPos )) + if ( lcl_UserVisibleName((*pNames)[nPos]) ) + { + ScRangeName* pNewRanges = new ScRangeName(*pNames); + pNewRanges->AtFree(nPos); + ScDocFunc aFunc(*pDocShell); + aFunc.SetNewRangeNames( pNewRanges, sal_True ); + bDone = TRUE; + } + } + } + + if (!bDone) + throw uno::RuntimeException(); // no other exceptions specified +} + +void SAL_CALL ScNamedRangesObj::outputList( const table::CellAddress& aOutputPosition ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScAddress aPos( (SCCOL)aOutputPosition.Column, (SCROW)aOutputPosition.Row, aOutputPosition.Sheet ); + if (pDocShell) + { + ScDocFunc aFunc(*pDocShell); + aFunc.InsertNameList( aPos, sal_True ); + } +} + +// container::XEnumerationAccess + +uno::Reference<container::XEnumeration> SAL_CALL ScNamedRangesObj::createEnumeration() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.NamedRangesEnumeration"))); +} + +// container::XIndexAccess + +sal_Int32 SAL_CALL ScNamedRangesObj::getCount() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + long nRet = 0; + if (pDocShell) + { + ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); + if (pNames) + { + sal_uInt16 nCount = pNames->GetCount(); + for (sal_uInt16 i=0; i<nCount; i++) + if (lcl_UserVisibleName( (*pNames)[i] )) // interne weglassen + ++nRet; + } + } + return nRet; +} + +uno::Any SAL_CALL ScNamedRangesObj::getByIndex( sal_Int32 nIndex ) + throw(lang::IndexOutOfBoundsException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference< sheet::XNamedRange > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex)); + if ( xRange.is() ) + return uno::makeAny(xRange); + else + throw lang::IndexOutOfBoundsException(); +// return uno::Any(); +} + +uno::Type SAL_CALL ScNamedRangesObj::getElementType() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return ::getCppuType((const uno::Reference< sheet::XNamedRange >*)0); // muss zu getByIndex passen +} + +sal_Bool SAL_CALL ScNamedRangesObj::hasElements() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return ( getCount() != 0 ); +} + +uno::Any SAL_CALL ScNamedRangesObj::getByName( const rtl::OUString& aName ) + throw(container::NoSuchElementException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference< sheet::XNamedRange > xRange(GetObjectByName_Impl(aName)); + if ( xRange.is() ) + return uno::makeAny(xRange); + else + throw container::NoSuchElementException(); +// return uno::Any(); +} + +uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangesObj::getElementNames() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDocShell) + { + ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); + if (pNames) + { + long nVisCount = getCount(); // Namen mit lcl_UserVisibleName + uno::Sequence<rtl::OUString> aSeq(nVisCount); + rtl::OUString* pAry = aSeq.getArray(); + + sal_uInt16 nCount = pNames->GetCount(); + sal_uInt16 nVisPos = 0; + for (sal_uInt16 i=0; i<nCount; i++) + { + ScRangeData* pData = (*pNames)[i]; + if ( lcl_UserVisibleName(pData) ) + pAry[nVisPos++] = pData->GetName(); + } +// DBG_ASSERT(nVisPos == nVisCount, "huch, verzaehlt?"); + return aSeq; + } + } + return uno::Sequence<rtl::OUString>(0); +} + +sal_Bool SAL_CALL ScNamedRangesObj::hasByName( const rtl::OUString& aName ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDocShell) + { + ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); + if (pNames) + { + sal_uInt16 nPos = 0; + if (pNames->SearchName( String(aName), nPos )) + if ( lcl_UserVisibleName((*pNames)[nPos]) ) + return sal_True; + } + } + return sal_False; +} + +/** called from the XActionLockable interface methods on initial locking */ +void ScNamedRangesObj::lock() +{ + pDocShell->GetDocument()->CompileNameFormula( TRUE ); // CreateFormulaString +} + +/** called from the XActionLockable interface methods on final unlock */ +void ScNamedRangesObj::unlock() +{ + pDocShell->GetDocument()->CompileNameFormula( FALSE ); // CompileFormulaString +} + +// document::XActionLockable + +sal_Bool ScNamedRangesObj::isActionLocked() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return pDocShell->GetDocument()->GetNamedRangesLockCount() != 0; +} + +void ScNamedRangesObj::addActionLock() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScDocument* pDoc = pDocShell->GetDocument(); + sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount(); + ++nLockCount; + if ( nLockCount == 1 ) + { + lock(); + } + pDoc->SetNamedRangesLockCount( nLockCount ); +} + +void ScNamedRangesObj::removeActionLock() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScDocument* pDoc = pDocShell->GetDocument(); + sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount(); + if ( nLockCount > 0 ) + { + --nLockCount; + if ( nLockCount == 0 ) + { + unlock(); + } + pDoc->SetNamedRangesLockCount( nLockCount ); + } +} + +void ScNamedRangesObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if ( nLock >= 0 ) + { + ScDocument* pDoc = pDocShell->GetDocument(); + sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount(); + if ( nLock == 0 && nLockCount > 0 ) + { + unlock(); + } + if ( nLock > 0 && nLockCount == 0 ) + { + lock(); + } + pDoc->SetNamedRangesLockCount( nLock ); + } +} + +sal_Int16 ScNamedRangesObj::resetActionLocks() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScDocument* pDoc = pDocShell->GetDocument(); + sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount(); + if ( nLockCount > 0 ) + { + unlock(); + } + pDoc->SetNamedRangesLockCount( 0 ); + return nLockCount; +} + +//------------------------------------------------------------------------ + +ScLabelRangeObj::ScLabelRangeObj(ScDocShell* pDocSh, sal_Bool bCol, const ScRange& rR) : + pDocShell( pDocSh ), + bColumn( bCol ), + aRange( rR ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScLabelRangeObj::~ScLabelRangeObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScLabelRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + //! Ref-Update !!! + + if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + pDocShell = NULL; // ungueltig geworden +} + +// Hilfsfuntionen + +ScRangePair* ScLabelRangeObj::GetData_Impl() +{ + ScRangePair* pRet = NULL; + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); + if (pList) + pRet = pList->Find( aRange ); + } + return pRet; +} + +void ScLabelRangeObj::Modify_Impl( const ScRange* pLabel, const ScRange* pData ) +{ + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); + if (pOldList) + { + ScRangePairListRef xNewList(pOldList->Clone()); + ScRangePair* pEntry = xNewList->Find( aRange ); + if (pEntry) + { + xNewList->Remove( pEntry ); // nur aus der Liste entfernt, nicht geloescht + + if ( pLabel ) + pEntry->GetRange(0) = *pLabel; + if ( pData ) + pEntry->GetRange(1) = *pData; + + xNewList->Join( *pEntry ); + delete pEntry; + + if (bColumn) + pDoc->GetColNameRangesRef() = xNewList; + else + pDoc->GetRowNameRangesRef() = xNewList; + + pDoc->CompileColRowNameFormula(); + pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID ); + pDocShell->SetDocumentModified(); + + //! Undo ?!?! (hier und aus Dialog) + + if ( pLabel ) + aRange = *pLabel; // Objekt anpassen, um Range wiederzufinden + } + } + } +} + +// sheet::XLabelRange + +table::CellRangeAddress SAL_CALL ScLabelRangeObj::getLabelArea() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + table::CellRangeAddress aRet; + ScRangePair* pData = GetData_Impl(); + if (pData) + ScUnoConversion::FillApiRange( aRet, pData->GetRange(0) ); + return aRet; +} + +void SAL_CALL ScLabelRangeObj::setLabelArea( const table::CellRangeAddress& aLabelArea ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScRange aLabelRange; + ScUnoConversion::FillScRange( aLabelRange, aLabelArea ); + Modify_Impl( &aLabelRange, NULL ); +} + +table::CellRangeAddress SAL_CALL ScLabelRangeObj::getDataArea() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + table::CellRangeAddress aRet; + ScRangePair* pData = GetData_Impl(); + if (pData) + ScUnoConversion::FillApiRange( aRet, pData->GetRange(1) ); + return aRet; +} + +void SAL_CALL ScLabelRangeObj::setDataArea( const table::CellRangeAddress& aDataArea ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScRange aDataRange; + ScUnoConversion::FillScRange( aDataRange, aDataArea ); + Modify_Impl( NULL, &aDataRange ); +} + +//------------------------------------------------------------------------ + +ScLabelRangesObj::ScLabelRangesObj(ScDocShell* pDocSh, sal_Bool bCol) : + pDocShell( pDocSh ), + bColumn( bCol ) +{ + pDocShell->GetDocument()->AddUnoObject(*this); +} + +ScLabelRangesObj::~ScLabelRangesObj() +{ + if (pDocShell) + pDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScLabelRangesObj::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 + } +} + +// sheet::XLabelRanges + +ScLabelRangeObj* ScLabelRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex) +{ + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); + if ( pList && nIndex < pList->Count() ) + { + ScRangePair* pData = pList->GetObject(nIndex); + if (pData) + return new ScLabelRangeObj( pDocShell, bColumn, pData->GetRange(0) ); + } + } + return NULL; +} + +void SAL_CALL ScLabelRangesObj::addNew( const table::CellRangeAddress& aLabelArea, + const table::CellRangeAddress& aDataArea ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); + if (pOldList) + { + ScRangePairListRef xNewList(pOldList->Clone()); + + ScRange aLabelRange; + ScRange aDataRange; + ScUnoConversion::FillScRange( aLabelRange, aLabelArea ); + ScUnoConversion::FillScRange( aDataRange, aDataArea ); + xNewList->Join( ScRangePair( aLabelRange, aDataRange ) ); + + if (bColumn) + pDoc->GetColNameRangesRef() = xNewList; + else + pDoc->GetRowNameRangesRef() = xNewList; + + pDoc->CompileColRowNameFormula(); + pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID ); + pDocShell->SetDocumentModified(); + + //! Undo ?!?! (hier und aus Dialog) + } + } +} + +void SAL_CALL ScLabelRangesObj::removeByIndex( sal_Int32 nIndex ) + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + BOOL bDone = FALSE; + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); + + if ( pOldList && nIndex >= 0 && nIndex < (sal_Int32)pOldList->Count() ) + { + ScRangePairListRef xNewList(pOldList->Clone()); + + ScRangePair* pEntry = xNewList->GetObject( nIndex ); + if (pEntry) + { + xNewList->Remove( pEntry ); + delete pEntry; + + if (bColumn) + pDoc->GetColNameRangesRef() = xNewList; + else + pDoc->GetRowNameRangesRef() = xNewList; + + pDoc->CompileColRowNameFormula(); + pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID ); + pDocShell->SetDocumentModified(); + bDone = TRUE; + + //! Undo ?!?! (hier und aus Dialog) + } + } + } + if (!bDone) + throw uno::RuntimeException(); // no other exceptions specified +} + +// container::XEnumerationAccess + +uno::Reference<container::XEnumeration> SAL_CALL ScLabelRangesObj::createEnumeration() + throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.LabelRangesEnumeration"))); +} + +// container::XIndexAccess + +sal_Int32 SAL_CALL ScLabelRangesObj::getCount() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); + if (pList) + return pList->Count(); + } + return 0; +} + +uno::Any SAL_CALL ScLabelRangesObj::getByIndex( sal_Int32 nIndex ) + throw(lang::IndexOutOfBoundsException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Reference< sheet::XLabelRange > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex)); + if ( xRange.is() ) + return uno::makeAny(xRange); + else + throw lang::IndexOutOfBoundsException(); +// return uno::Any(); +} + +uno::Type SAL_CALL ScLabelRangesObj::getElementType() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return ::getCppuType((const uno::Reference< sheet::XLabelRange >*)0); // muss zu getByIndex passen + +} + +sal_Bool SAL_CALL ScLabelRangesObj::hasElements() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return ( getCount() != 0 ); +} + +//------------------------------------------------------------------------ + + + |