blob: de59d7a831f803d603bc39d9ceea64914abc6869 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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, const String& rScopeName) :
pDocShell( pDocSh ),
aName( rNm ),
aScopeName(rScopeName)
{
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;
SCTAB nameScope = MAXTABCOUNT;
if ( aScopeName != EMPTY_STRING )
{
pDocShell->GetDocument()->GetTable( aScopeName, nameScope );
}
if (pNames->SearchName( aName, nPos, nameScope ))
{
pRet = (*pNames)[nPos];
pRet->ValidateTabRefs(); // adjust relative tab refs to valid tables
}
}
}
return pRet;
}
// sheet::XNamedRange
void ScNamedRangeObj::Modify_Impl( const String* pNewRangeName, const ScTokenArray* pNewTokens, const String* pNewContent,
const ScAddress* pNewPos, const sal_uInt16* pNewType,
const formula::FormulaGrammar::Grammar eGrammar, const String* pNewScopeName )
{
if (pDocShell)
{
ScDocument* pDoc = pDocShell->GetDocument();
ScRangeName* pNames = pDoc->GetRangeName();
if (pNames)
{
sal_uInt16 nPos = 0;
SCTAB nameScope = MAXTABCOUNT;
if (aScopeName != EMPTY_STRING )
pDoc->GetTable(aScopeName, nameScope);
if (pNames->SearchName( aName, nPos, nameScope ))
{
SCTAB newNameScope = MAXTABCOUNT;
if (pNewScopeName && *pNewScopeName != EMPTY_STRING && !pDoc->GetTable(*pNewScopeName, newNameScope))
return;
//added for namerange renew
else if (!pNewScopeName || *pNewScopeName == EMPTY_STRING )
newNameScope = nameScope;
//end of add
ScRangeData* pOld = (*pNames)[nPos];
String aInsName(pOld->GetName());
if (pNewRangeName)
aInsName = *pNewRangeName;
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() );
pNew->SetRangeScope(newNameScope);
const bool bSupportUndo(!pDoc->IsImportingXML());
if ( bSupportUndo )
{
ScRangeName* pNewRanges = new ScRangeName( *pNames );
pNewRanges->AtFree( nPos );
if ( pNewRanges->Insert(pNew) )
{
ScDocFunc aFunc(*pDocShell);
aFunc.SetNewRangeNames( pNewRanges, sal_True );
aName = aInsName; //! broadcast?
aScopeName = pNewScopeName ? *pNewScopeName : aScopeName;
}
else
{
delete pNew; //! uno::Exception/Fehler oder so
delete pNewRanges;
}
}
else
{
pNames->AtFree( nPos );
if ( pNames->Insert(pNew) )
{
ScDocFunc aFunc(*pDocShell);
aFunc.SetNewRangeNames( pNames, sal_True );
aName = aInsName; //! broadcast?
aScopeName = pNewScopeName ? *pNewScopeName : aScopeName;
}
else
{
delete pNew; //! uno::Exception/Fehler oder so
}
}
}
}
}
}
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::getScopeName() throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
return aScopeName;
}
void SAL_CALL ScNamedRangeObj::setScopeAndRangeName( const rtl::OUString& aNewScopeName, const rtl::OUString& aNewRangeName )
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
//! Formeln anpassen ?????
String aNewRangeStr(aNewRangeName);
String aNewScopeStr(aNewScopeName);
// GRAM_PODF_A1 for API compatibility.
Modify_Impl( &aNewRangeStr, NULL, NULL, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1, aNewScopeName.getLength() == 0 ? NULL : &aNewScopeStr);
if ( aScopeName != aNewScopeStr || aName != aNewRangeStr ) // 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->IsValidReference( 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(), pData->GetScopeSheetName() );
++nPos;
}
}
}
}
return NULL;
}
ScNamedRangeObj* ScNamedRangesObj::GetObjectByName_Impl(const rtl::OUString& aName)
{
if ( pDocShell && hasByName(aName) )
return new ScNamedRangeObj( pDocShell, String(aName) );
return NULL;
}
ScNamedRangeObj* ScNamedRangesObj::GetObjectByScopeName_Impl(const ::rtl::OUString& aScopeName, const ::rtl::OUString& aRangeName)
{
if ( pDocShell && hasByScopeName(aScopeName, aRangeName) )
return new ScNamedRangeObj( pDocShell, String(aRangeName),String(aScopeName) );
return NULL;
}
void ScNamedRangesObj::ImplAddNewByScopeAndName(SCTAB aScope, const ::rtl::OUString& aRangeName, const ::rtl::OUString& aContent,
const ::com::sun::star::table::CellAddress& aPosition, sal_Int32 nUnoType) throw(uno::RuntimeException)
{
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();
sal_uInt16 nIndex = 0;
String aNameStr(aRangeName);
String aContStr(aContent);
if (pNames && !pNames->SearchName(aNameStr, nIndex,aScope))
{
// GRAM_PODF_A1 for API compatibility.
ScRangeData* pNew = new ScRangeData( pDoc, aNameStr, aContStr,
aPos, nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );//GRAM_ODFF,//
pNew->SetRangeScope(aScope);
const bool bSupportUndo(!pDoc->IsImportingXML());
if ( bSupportUndo )
{
ScRangeName* pNewRanges = new ScRangeName( *pNames );
if ( pNewRanges->Insert(pNew) )
{
ScDocFunc aFunc(*pDocShell);
aFunc.SetNewRangeNames( pNewRanges, sal_True );
bDone = true;
}
else
{
delete pNew;
delete pNewRanges;
}
}
else
{
if ( pNames->Insert(pNew) )
{
ScDocFunc aFunc(*pDocShell);
aFunc.SetNewRangeNames( pNames, sal_True );
bDone = true;
}
else
{
delete pNew;
}
}
}
}
if (!bDone)
throw uno::RuntimeException(); // no other exceptions specified
}
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;
ImplAddNewByScopeAndName(MAXTABCOUNT, aName, aContent, aPosition, nUnoType);
}
void SAL_CALL ScNamedRangesObj::addNewByScopeName( const rtl::OUString& aScopeName,const rtl::OUString& aRangeName,
const rtl::OUString& aContent, const table::CellAddress& aPosition,
sal_Int32 nUnoType ) throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
SCTAB scope = MAXTABCOUNT;
if (aScopeName.getLength() != 0 && pDocShell &&
!pDocShell->GetDocument()->GetTable( String(aScopeName), scope ) )
throw uno::RuntimeException();
ImplAddNewByScopeAndName(scope, aRangeName, aContent, aPosition, nUnoType);
}
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 ScNamedRangesObj::ImplRemoveByScopeAndName(SCTAB aScope, const ::rtl::OUString& aRangeName)
throw(uno::RuntimeException)
{
bool bDone = false;
if (pDocShell)
{
ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
if (pNames)
{
sal_uInt16 nPos = 0;
if (pNames->SearchName( String(aRangeName), nPos, aScope ))
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::removeByName( const rtl::OUString& aName )
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
ImplRemoveByScopeAndName(MAXTABCOUNT, aName);
}
void SAL_CALL ScNamedRangesObj::removeByScopeName( const ::rtl::OUString& aScopeName, const ::rtl::OUString& aRangeName )
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
SCTAB scope = MAXTABCOUNT;
if (aScopeName.getLength() != 0 && pDocShell &&
!pDocShell->GetDocument()->GetTable( String(aScopeName), scope ))
throw uno::RuntimeException();
ImplRemoveByScopeAndName(scope, aRangeName);
}
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::XNamedRange2 > 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::XNamedRange2 >*)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::XNamedRange2 > xRange(GetObjectByName_Impl(aName));
if ( xRange.is() )
return uno::makeAny(xRange);
else
throw container::NoSuchElementException();
// return uno::Any();
}
uno::Any SAL_CALL ScNamedRangesObj::getByScopeName( const rtl::OUString& aScopeName, const rtl::OUString& aRangeName )
throw(container::NoSuchElementException,
lang::WrappedTargetException, uno::RuntimeException)
{
ScUnoGuard aGuard;
uno::Reference< sheet::XNamedRange2 > xRange(GetObjectByScopeName_Impl(aScopeName, aRangeName));
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);
}
uno::Sequence< sheet::RangeScopeName > SAL_CALL ScNamedRangesObj::getElementScopeNames()
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
if (pDocShell)
{
ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
if (pNames)
{
long nVisCount = getCount(); // Namen mit lcl_UserVisibleName
uno::Sequence<sheet::RangeScopeName> aSeq(nVisCount);
sheet::RangeScopeName * 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].RangeName = pData->GetName();
pAry[nVisPos++].ScopeName = pData->GetScopeSheetName();
}
}
// DBG_ASSERT(nVisPos == nVisCount, "huch, verzaehlt?");
return aSeq;
}
}
return uno::Sequence< sheet::RangeScopeName >(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;
}
sal_Bool SAL_CALL ScNamedRangesObj::hasByScopeName( const ::rtl::OUString& aScopeName, const ::rtl::OUString& aRangeName)
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
if (pDocShell)
{
SCTAB scope = MAXTABCOUNT;
if (aScopeName.getLength() != 0 && !pDocShell->GetDocument()->GetTable( String(aScopeName), scope ) )
return sal_False;
ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
if (pNames)
{
sal_uInt16 nPos = 0;
if (pNames->SearchName( String(aRangeName), nPos, scope ))
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( sal_True ); // CreateFormulaString
}
/** called from the XActionLockable interface methods on final unlock */
void ScNamedRangesObj::unlock()
{
pDocShell->GetDocument()->CompileNameFormula( sal_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;
sal_Bool bDone = sal_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 = sal_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 );
}
//------------------------------------------------------------------------