/************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include #include #include #include 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*)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 SAL_CALL ScNamedRangeObj::getTokens() throw(uno::RuntimeException) { ScUnoGuard aGuard; uno::Sequence 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& 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 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 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(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 SAL_CALL ScNamedRangeObj::getSupportedServiceNames() throw(uno::RuntimeException) { uno::Sequence 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& rId ) throw(uno::RuntimeException) { if ( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) { return sal::static_int_cast(reinterpret_cast(this)); } return 0; } // static const uno::Sequence& ScNamedRangeObj::getUnoTunnelId() { static uno::Sequence * 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 xObj ) { ScNamedRangeObj* pRet = NULL; uno::Reference xUT( xObj, uno::UNO_QUERY ); if (xUT.is()) pRet = reinterpret_cast(sal::static_int_cast(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; iGetName() ); ++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 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 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 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 aSeq(nVisCount); rtl::OUString* pAry = aSeq.getArray(); sal_uInt16 nCount = pNames->GetCount(); sal_uInt16 nVisPos = 0; for (sal_uInt16 i=0; iGetName(); } // DBG_ASSERT(nVisPos == nVisCount, "huch, verzaehlt?"); return aSeq; } } return uno::Sequence(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 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 ); } //------------------------------------------------------------------------