1147 lines
34 KiB
C++
1147 lines
34 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* 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 .
|
|
*/
|
|
|
|
#include <o3tl/safeint.hxx>
|
|
#include <svl/hint.hxx>
|
|
#include <utility>
|
|
#include <vcl/svapp.hxx>
|
|
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
|
|
#include <com/sun/star/sheet/NamedRangeFlag.hpp>
|
|
#include <com/sun/star/awt/XBitmap.hpp>
|
|
#include <com/sun/star/beans/PropertyAttribute.hpp>
|
|
|
|
#include <comphelper/servicehelper.hxx>
|
|
#include <cppuhelper/supportsservice.hxx>
|
|
#include <unotools/charclass.hxx>
|
|
|
|
#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>
|
|
#include <unonames.hxx>
|
|
|
|
#include <scui_def.hxx>
|
|
|
|
using namespace ::com::sun::star;
|
|
using ::com::sun::star::uno::Reference;
|
|
using ::com::sun::star::uno::Any;
|
|
|
|
static std::span<const SfxItemPropertyMapEntry> lcl_GetNamedRangeMap()
|
|
{
|
|
static const SfxItemPropertyMapEntry aNamedRangeMap_Impl[] =
|
|
{
|
|
{ SC_UNO_LINKDISPBIT, 0, cppu::UnoType<awt::XBitmap>::get(), beans::PropertyAttribute::READONLY, 0 },
|
|
{ SC_UNO_LINKDISPNAME, 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0 },
|
|
{ SC_UNONAME_TOKENINDEX, 0, cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 },
|
|
{ SC_UNONAME_ISSHAREDFMLA, 0, cppu::UnoType<bool>::get(), 0, 0 },
|
|
};
|
|
return aNamedRangeMap_Impl;
|
|
}
|
|
|
|
static std::span<const SfxItemPropertyMapEntry> lcl_GetNamedRangesMap()
|
|
{
|
|
static const SfxItemPropertyMapEntry aNamedRangesMap_Impl[] =
|
|
{
|
|
{ SC_UNO_MODIFY_BROADCAST, 0, cppu::UnoType<bool>::get(), 0, 0 },
|
|
};
|
|
return aNamedRangesMap_Impl;
|
|
}
|
|
|
|
constexpr OUString SCNAMEDRANGEOBJ_SERVICE = u"com.sun.star.sheet.NamedRange"_ustr;
|
|
|
|
SC_SIMPLE_SERVICE_INFO( ScLabelRangeObj, u"ScLabelRangeObj"_ustr, u"com.sun.star.sheet.LabelRange"_ustr )
|
|
SC_SIMPLE_SERVICE_INFO( ScLabelRangesObj, u"ScLabelRangesObj"_ustr, u"com.sun.star.sheet.LabelRanges"_ustr )
|
|
SC_SIMPLE_SERVICE_INFO( ScNamedRangesObj, u"ScNamedRangesObj"_ustr, u"com.sun.star.sheet.NamedRanges"_ustr )
|
|
|
|
// Database named ranges are not considered by getCount, hasByName, removeByName and getElementNames
|
|
// Note that hidden named ranges are considered by these methods
|
|
static bool lcl_UserVisibleName(const ScRangeData& rData)
|
|
{
|
|
//! as method to ScRangeData
|
|
return !rData.HasType(ScRangeData::Type::Database);
|
|
}
|
|
|
|
ScNamedRangeObj::ScNamedRangeObj( rtl::Reference< ScNamedRangesObj > xParent, ScDocShell* pDocSh, OUString aNm, Reference<container::XNamed> const & xSheet):
|
|
mxParent(std::move(xParent)),
|
|
pDocShell( pDocSh ),
|
|
aName(std::move( aNm )),
|
|
mxSheet( xSheet )
|
|
{
|
|
pDocShell->GetDocument().AddUnoObject(*this);
|
|
}
|
|
|
|
ScNamedRangeObj::~ScNamedRangeObj()
|
|
{
|
|
SolarMutexGuard g;
|
|
|
|
if (pDocShell)
|
|
pDocShell->GetDocument().RemoveUnoObject(*this);
|
|
}
|
|
|
|
void ScNamedRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
|
|
{
|
|
// reference update is of no interest
|
|
|
|
if ( rHint.GetId() == SfxHintId::Dying )
|
|
pDocShell = nullptr; // became invalid
|
|
}
|
|
|
|
// Helper functions
|
|
|
|
ScRangeData* ScNamedRangeObj::GetRangeData_Impl()
|
|
{
|
|
ScRangeData* pRet = nullptr;
|
|
if (pDocShell)
|
|
{
|
|
ScRangeName* pNames;
|
|
SCTAB nTab = GetTab_Impl();
|
|
if (nTab >= 0)
|
|
pNames = pDocShell->GetDocument().GetRangeName(nTab);
|
|
else
|
|
pNames = pDocShell->GetDocument().GetRangeName();
|
|
if (pNames)
|
|
{
|
|
pRet = pNames->findByUpperName(ScGlobal::getCharClass().uppercase(aName));
|
|
if (pRet)
|
|
pRet->ValidateTabRefs(); // adjust relative tab refs to valid tables
|
|
}
|
|
}
|
|
return pRet;
|
|
}
|
|
|
|
SCTAB ScNamedRangeObj::GetTab_Impl()
|
|
{
|
|
if (mxSheet.is())
|
|
{
|
|
if (!pDocShell)
|
|
return -2;
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
SCTAB nTab;
|
|
OUString sName = mxSheet->getName();
|
|
bool bFound = rDoc.GetTable(sName, nTab);
|
|
assert(bFound); (void)bFound; // fouled up?
|
|
return nTab;
|
|
}
|
|
else
|
|
return -1;//global range name
|
|
}
|
|
|
|
// sheet::XNamedRange
|
|
|
|
void ScNamedRangeObj::Modify_Impl( const OUString* pNewName, const ScTokenArray* pNewTokens, const OUString* pNewContent,
|
|
const ScAddress* pNewPos, const ScRangeData::Type* pNewType,
|
|
const formula::FormulaGrammar::Grammar eGrammar )
|
|
{
|
|
if (!pDocShell)
|
|
return;
|
|
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
ScRangeName* pNames;
|
|
SCTAB nTab = GetTab_Impl();
|
|
if (nTab >= 0)
|
|
pNames = rDoc.GetRangeName(nTab);
|
|
else
|
|
pNames = rDoc.GetRangeName();
|
|
if (!pNames)
|
|
return;
|
|
|
|
const ScRangeData* pOld = pNames->findByUpperName(ScGlobal::getCharClass().uppercase(aName));
|
|
if (!pOld)
|
|
return;
|
|
|
|
std::unique_ptr<ScRangeName> pNewRanges(new ScRangeName(*pNames));
|
|
|
|
OUString aInsName = pOld->GetName();
|
|
if (pNewName)
|
|
aInsName = *pNewName;
|
|
|
|
// Content string based => no problems with changed positions and such.
|
|
OUString aContent = pOld->GetSymbol(eGrammar);
|
|
if (pNewContent)
|
|
aContent = *pNewContent;
|
|
|
|
ScAddress aPos = pOld->GetPos();
|
|
if (pNewPos)
|
|
aPos = *pNewPos;
|
|
|
|
ScRangeData::Type nType = pOld->GetType();
|
|
if (pNewType)
|
|
nType = *pNewType;
|
|
|
|
ScRangeData* pNew = nullptr;
|
|
if (pNewTokens)
|
|
pNew = new ScRangeData( rDoc, aInsName, *pNewTokens, aPos, nType );
|
|
else
|
|
pNew = new ScRangeData( rDoc, aInsName, aContent, aPos, nType, eGrammar );
|
|
|
|
pNew->SetIndex( pOld->GetIndex() );
|
|
|
|
pNewRanges->erase(*pOld);
|
|
if (pNewRanges->insert(pNew))
|
|
{
|
|
pDocShell->GetDocFunc().SetNewRangeNames(std::move(pNewRanges), mxParent->IsModifyAndBroadcast(), nTab);
|
|
|
|
aName = aInsName; //! broadcast?
|
|
}
|
|
else
|
|
{
|
|
pNew = nullptr; //! uno::Exception/Error or something
|
|
}
|
|
}
|
|
|
|
OUString SAL_CALL ScNamedRangeObj::getName()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
return aName;
|
|
}
|
|
|
|
void SAL_CALL ScNamedRangeObj::setName( const OUString& aNewName )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
//! adapt formulas ?????
|
|
|
|
OUString aNewStr(aNewName);
|
|
// GRAM_API for API compatibility.
|
|
Modify_Impl( &aNewStr, nullptr, nullptr, nullptr, nullptr,formula::FormulaGrammar::GRAM_API );
|
|
|
|
if ( aName != aNewStr ) // some error occurred...
|
|
throw uno::RuntimeException(); // no other exceptions specified
|
|
}
|
|
|
|
OUString SAL_CALL ScNamedRangeObj::getContent()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
OUString aContent;
|
|
ScRangeData* pData = GetRangeData_Impl();
|
|
if (pData)
|
|
// GRAM_API for API compatibility.
|
|
aContent = pData->GetSymbol(formula::FormulaGrammar::GRAM_API);
|
|
return aContent;
|
|
}
|
|
|
|
void SAL_CALL ScNamedRangeObj::setContent( const OUString& aContent )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
OUString aContStr(aContent);
|
|
// GRAM_API for API compatibility.
|
|
Modify_Impl( nullptr, nullptr, &aContStr, nullptr, nullptr,formula::FormulaGrammar::GRAM_API );
|
|
}
|
|
|
|
table::CellAddress SAL_CALL ScNamedRangeObj::getReferencePosition()
|
|
{
|
|
SolarMutexGuard 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 )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScAddress aPos( static_cast<SCCOL>(aReferencePosition.Column), static_cast<SCROW>(aReferencePosition.Row), aReferencePosition.Sheet );
|
|
// GRAM_API for API compatibility.
|
|
Modify_Impl( nullptr, nullptr, nullptr, &aPos, nullptr,formula::FormulaGrammar::GRAM_API );
|
|
}
|
|
|
|
sal_Int32 SAL_CALL ScNamedRangeObj::getType()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
sal_Int32 nType=0;
|
|
ScRangeData* pData = GetRangeData_Impl();
|
|
if (pData)
|
|
{
|
|
// do not return internal ScRangeData::Type flags
|
|
if ( pData->HasType(ScRangeData::Type::Criteria) ) nType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
|
|
if ( pData->HasType(ScRangeData::Type::PrintArea) ) nType |= sheet::NamedRangeFlag::PRINT_AREA;
|
|
if ( pData->HasType(ScRangeData::Type::ColHeader) ) nType |= sheet::NamedRangeFlag::COLUMN_HEADER;
|
|
if ( pData->HasType(ScRangeData::Type::RowHeader) ) nType |= sheet::NamedRangeFlag::ROW_HEADER;
|
|
if ( pData->HasType(ScRangeData::Type::Hidden) ) nType |= sheet::NamedRangeFlag::HIDDEN;
|
|
}
|
|
return nType;
|
|
}
|
|
|
|
void SAL_CALL ScNamedRangeObj::setType( sal_Int32 nUnoType )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScRangeData::Type nNewType = ScRangeData::Type::Name;
|
|
if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= ScRangeData::Type::Criteria;
|
|
if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= ScRangeData::Type::PrintArea;
|
|
if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= ScRangeData::Type::ColHeader;
|
|
if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= ScRangeData::Type::RowHeader;
|
|
if ( nUnoType & sheet::NamedRangeFlag::HIDDEN ) nNewType |= ScRangeData::Type::Hidden;
|
|
|
|
// GRAM_API for API compatibility.
|
|
Modify_Impl( nullptr, nullptr, nullptr, nullptr, &nNewType,formula::FormulaGrammar::GRAM_API );
|
|
}
|
|
|
|
// XFormulaTokens
|
|
|
|
uno::Sequence<sheet::FormulaToken> SAL_CALL ScNamedRangeObj::getTokens()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
uno::Sequence<sheet::FormulaToken> aSequence;
|
|
ScRangeData* pData = GetRangeData_Impl();
|
|
if (pData && pDocShell)
|
|
{
|
|
ScTokenArray* pTokenArray = pData->GetCode();
|
|
if ( pTokenArray )
|
|
ScTokenConversion::ConvertToTokenSequence( pDocShell->GetDocument(), aSequence, *pTokenArray );
|
|
}
|
|
return aSequence;
|
|
}
|
|
|
|
void SAL_CALL ScNamedRangeObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if( pDocShell )
|
|
{
|
|
ScTokenArray aTokenArray(pDocShell->GetDocument());
|
|
(void)ScTokenConversion::ConvertToTokenArray( pDocShell->GetDocument(), aTokenArray, rTokens );
|
|
// GRAM_API for API compatibility.
|
|
Modify_Impl( nullptr, &aTokenArray, nullptr, nullptr, nullptr, formula::FormulaGrammar::GRAM_API );
|
|
}
|
|
}
|
|
|
|
// XCellRangeSource
|
|
|
|
uno::Reference<table::XCellRange> SAL_CALL ScNamedRangeObj::getReferredCells()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScRange aRange;
|
|
ScRangeData* pData = GetRangeData_Impl();
|
|
if ( pData && pData->IsValidReference( aRange ) )
|
|
{
|
|
//! static function to create ScCellObj/ScCellRangeObj at ScCellRangeObj ???
|
|
|
|
if ( aRange.aStart == aRange.aEnd )
|
|
return new ScCellObj( pDocShell, aRange.aStart );
|
|
else
|
|
return new ScCellRangeObj( pDocShell, aRange );
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
// beans::XPropertySet
|
|
|
|
uno::Reference<beans::XPropertySetInfo> SAL_CALL ScNamedRangeObj::getPropertySetInfo()
|
|
{
|
|
static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetNamedRangeMap() ));
|
|
return aRef;
|
|
}
|
|
|
|
void SAL_CALL ScNamedRangeObj::setPropertyValue(
|
|
const OUString& rPropertyName, const uno::Any& /*aValue*/ )
|
|
{
|
|
if ( rPropertyName == SC_UNONAME_ISSHAREDFMLA )
|
|
{
|
|
// Ignore this.
|
|
}
|
|
}
|
|
|
|
uno::Any SAL_CALL ScNamedRangeObj::getPropertyValue( const OUString& rPropertyName )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
uno::Any aRet;
|
|
if ( rPropertyName == SC_UNO_LINKDISPBIT )
|
|
{
|
|
// no target bitmaps for individual entries (would be all equal)
|
|
// ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_RANGENAME );
|
|
}
|
|
else if ( rPropertyName == SC_UNO_LINKDISPNAME )
|
|
aRet <<= aName;
|
|
else if ( rPropertyName == 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 == SC_UNONAME_ISSHAREDFMLA )
|
|
{
|
|
if (GetRangeData_Impl())
|
|
aRet <<= false;
|
|
}
|
|
return aRet;
|
|
}
|
|
|
|
SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangeObj )
|
|
|
|
// lang::XServiceInfo
|
|
|
|
OUString SAL_CALL ScNamedRangeObj::getImplementationName()
|
|
{
|
|
return u"ScNamedRangeObj"_ustr;
|
|
}
|
|
|
|
sal_Bool SAL_CALL ScNamedRangeObj::supportsService( const OUString& rServiceName )
|
|
{
|
|
return cppu::supportsService(this, rServiceName);
|
|
}
|
|
|
|
uno::Sequence<OUString> SAL_CALL ScNamedRangeObj::getSupportedServiceNames()
|
|
{
|
|
return {SCNAMEDRANGEOBJ_SERVICE, SCLINKTARGET_SERVICE};
|
|
}
|
|
|
|
ScNamedRangesObj::ScNamedRangesObj(ScDocShell* pDocSh) :
|
|
mbModifyAndBroadcast(true),
|
|
pDocShell( pDocSh )
|
|
{
|
|
pDocShell->GetDocument().AddUnoObject(*this);
|
|
}
|
|
|
|
ScNamedRangesObj::~ScNamedRangesObj()
|
|
{
|
|
SolarMutexGuard g;
|
|
|
|
if (pDocShell)
|
|
pDocShell->GetDocument().RemoveUnoObject(*this);
|
|
}
|
|
|
|
void ScNamedRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
|
|
{
|
|
// reference update is of no interest
|
|
|
|
if ( rHint.GetId() == SfxHintId::Dying )
|
|
{
|
|
pDocShell = nullptr; // became invalid
|
|
}
|
|
}
|
|
|
|
// sheet::XNamedRanges
|
|
|
|
void SAL_CALL ScNamedRangesObj::addNewByName( const OUString& aName,
|
|
const OUString& aContent, const table::CellAddress& aPosition,
|
|
sal_Int32 nUnoType )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), aPosition.Sheet );
|
|
|
|
ScRangeData::Type nNewType = ScRangeData::Type::Name;
|
|
if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= ScRangeData::Type::Criteria;
|
|
if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= ScRangeData::Type::PrintArea;
|
|
if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= ScRangeData::Type::ColHeader;
|
|
if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= ScRangeData::Type::RowHeader;
|
|
if ( nUnoType & sheet::NamedRangeFlag::HIDDEN ) nNewType |= ScRangeData::Type::Hidden;
|
|
|
|
bool bDone = false;
|
|
if (pDocShell)
|
|
{
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
// tdf#119457 - check for a valid range name and cell reference
|
|
switch (ScRangeData::IsNameValid(aName, rDoc))
|
|
{
|
|
case ScRangeData::IsNameValidType::NAME_INVALID_CELL_REF:
|
|
throw uno::RuntimeException(
|
|
u"Invalid name. Reference to a cell, or a range of cells not allowed"_ustr,
|
|
getXWeak());
|
|
break;
|
|
case ScRangeData::IsNameValidType::NAME_INVALID_BAD_STRING:
|
|
throw uno::RuntimeException(
|
|
u"Invalid name. Start with a letter, use only letters, numbers and underscore"_ustr,
|
|
getXWeak());
|
|
break;
|
|
case ScRangeData::IsNameValidType::NAME_VALID:
|
|
if (ScRangeName* pNames = GetRangeName_Impl();
|
|
pNames
|
|
&& !pNames->findByUpperName(ScGlobal::getCharClass().uppercase(aName)))
|
|
{
|
|
std::unique_ptr<ScRangeName> pNewRanges(new ScRangeName( *pNames ));
|
|
// GRAM_API for API compatibility.
|
|
ScRangeData* pNew = new ScRangeData( rDoc, aName, aContent,
|
|
aPos, nNewType,formula::FormulaGrammar::GRAM_API );
|
|
if ( pNewRanges->insert(pNew) )
|
|
{
|
|
pDocShell->GetDocFunc().SetNewRangeNames(std::move(pNewRanges), mbModifyAndBroadcast, GetTab_Impl());
|
|
bDone = true;
|
|
}
|
|
else
|
|
{
|
|
pNew = nullptr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bDone)
|
|
throw uno::RuntimeException(); // no other exceptions specified
|
|
}
|
|
|
|
void SAL_CALL ScNamedRangesObj::addNewFromTitles( const table::CellRangeAddress& aSource,
|
|
sheet::Border aBorder )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
//! this cannot be an enum, because multiple bits can be set !!!
|
|
|
|
bool bTop = ( aBorder == sheet::Border_TOP );
|
|
bool bLeft = ( aBorder == sheet::Border_LEFT );
|
|
bool bBottom = ( aBorder == sheet::Border_BOTTOM );
|
|
bool bRight = ( aBorder == sheet::Border_RIGHT );
|
|
|
|
ScRange aRange;
|
|
ScUnoConversion::FillScRange( aRange, aSource );
|
|
|
|
CreateNameFlags nFlags = CreateNameFlags::NONE;
|
|
if (bTop) nFlags |= CreateNameFlags::Top;
|
|
if (bLeft) nFlags |= CreateNameFlags::Left;
|
|
if (bBottom) nFlags |= CreateNameFlags::Bottom;
|
|
if (bRight) nFlags |= CreateNameFlags::Right;
|
|
|
|
if (nFlags != CreateNameFlags::NONE)
|
|
pDocShell->GetDocFunc().CreateNames( aRange, nFlags, true, GetTab_Impl() );
|
|
}
|
|
|
|
void SAL_CALL ScNamedRangesObj::removeByName( const OUString& aName )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
bool bDone = false;
|
|
if (pDocShell)
|
|
{
|
|
ScRangeName* pNames = GetRangeName_Impl();
|
|
if (pNames)
|
|
{
|
|
const ScRangeData* pData = pNames->findByUpperName(ScGlobal::getCharClass().uppercase(aName));
|
|
if (pData && lcl_UserVisibleName(*pData))
|
|
{
|
|
std::unique_ptr<ScRangeName> pNewRanges(new ScRangeName(*pNames));
|
|
pNewRanges->erase(*pData);
|
|
pDocShell->GetDocFunc().SetNewRangeNames( std::move(pNewRanges), mbModifyAndBroadcast, GetTab_Impl());
|
|
bDone = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bDone)
|
|
throw uno::RuntimeException(); // no other exceptions specified
|
|
}
|
|
|
|
void SAL_CALL ScNamedRangesObj::outputList( const table::CellAddress& aOutputPosition )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScAddress aPos( static_cast<SCCOL>(aOutputPosition.Column), static_cast<SCROW>(aOutputPosition.Row), aOutputPosition.Sheet );
|
|
if (pDocShell)
|
|
pDocShell->GetDocFunc().InsertNameList( aPos, true );
|
|
}
|
|
|
|
// container::XEnumerationAccess
|
|
|
|
uno::Reference<container::XEnumeration> SAL_CALL ScNamedRangesObj::createEnumeration()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
return new ScIndexEnumeration(this, u"com.sun.star.sheet.NamedRangesEnumeration"_ustr);
|
|
}
|
|
|
|
// container::XIndexAccess
|
|
|
|
sal_Int32 SAL_CALL ScNamedRangesObj::getCount()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
tools::Long nRet = 0;
|
|
if (pDocShell)
|
|
{
|
|
ScRangeName* pNames = GetRangeName_Impl();
|
|
if (pNames)
|
|
{
|
|
for (const auto& rName : *pNames)
|
|
if (lcl_UserVisibleName(*rName.second))
|
|
++nRet;
|
|
}
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
uno::Any SAL_CALL ScNamedRangesObj::getByIndex( sal_Int32 nIndex )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
uno::Reference< sheet::XNamedRange > xRange(GetObjectByIndex_Impl(static_cast<sal_uInt16>(nIndex)));
|
|
if ( !xRange.is() )
|
|
throw lang::IndexOutOfBoundsException();
|
|
|
|
return uno::Any(xRange);
|
|
}
|
|
|
|
uno::Type SAL_CALL ScNamedRangesObj::getElementType()
|
|
{
|
|
return cppu::UnoType<sheet::XNamedRange>::get(); // must be suitable for getByIndex
|
|
}
|
|
|
|
sal_Bool SAL_CALL ScNamedRangesObj::hasElements()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
return ( getCount() != 0 );
|
|
}
|
|
|
|
Reference<beans::XPropertySetInfo> SAL_CALL ScNamedRangesObj::getPropertySetInfo()
|
|
{
|
|
static Reference<beans::XPropertySetInfo> aRef(
|
|
new SfxItemPropertySetInfo(lcl_GetNamedRangesMap()));
|
|
return aRef;
|
|
}
|
|
|
|
void SAL_CALL ScNamedRangesObj::setPropertyValue(
|
|
const OUString& rPropertyName, const uno::Any& aValue )
|
|
{
|
|
if ( rPropertyName == SC_UNO_MODIFY_BROADCAST )
|
|
{
|
|
aValue >>= mbModifyAndBroadcast;
|
|
}
|
|
}
|
|
|
|
Any SAL_CALL ScNamedRangesObj::getPropertyValue( const OUString& rPropertyName )
|
|
{
|
|
Any aRet;
|
|
if ( rPropertyName == SC_UNO_MODIFY_BROADCAST )
|
|
{
|
|
aRet <<= mbModifyAndBroadcast;
|
|
}
|
|
|
|
return aRet;
|
|
}
|
|
|
|
SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangesObj )
|
|
|
|
uno::Any SAL_CALL ScNamedRangesObj::getByName( const OUString& aName )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
uno::Reference< sheet::XNamedRange > xRange(GetObjectByName_Impl(aName));
|
|
if ( !xRange.is() )
|
|
throw container::NoSuchElementException();
|
|
|
|
return uno::Any(xRange);
|
|
}
|
|
|
|
uno::Sequence<OUString> SAL_CALL ScNamedRangesObj::getElementNames()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if (pDocShell)
|
|
{
|
|
ScRangeName* pNames = GetRangeName_Impl();
|
|
if (pNames)
|
|
{
|
|
tools::Long nVisCount = getCount(); // names with lcl_UserVisibleName
|
|
uno::Sequence<OUString> aSeq(nVisCount);
|
|
OUString* pAry = aSeq.getArray();
|
|
sal_uInt16 nVisPos = 0;
|
|
for (const auto& rName : *pNames)
|
|
{
|
|
if (lcl_UserVisibleName(*rName.second))
|
|
pAry[nVisPos++] = rName.second->GetName();
|
|
}
|
|
return aSeq;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
sal_Bool SAL_CALL ScNamedRangesObj::hasByName( const OUString& aName )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if (pDocShell)
|
|
{
|
|
ScRangeName* pNames = GetRangeName_Impl();
|
|
if (pNames)
|
|
{
|
|
const ScRangeData* pData = pNames->findByUpperName(ScGlobal::getCharClass().uppercase(aName));
|
|
if (pData && lcl_UserVisibleName(*pData))
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/** called from the XActionLockable interface methods on initial locking */
|
|
void ScNamedRangesObj::lock()
|
|
{
|
|
pDocShell->GetDocument().PreprocessRangeNameUpdate();
|
|
}
|
|
|
|
/** called from the XActionLockable interface methods on final unlock */
|
|
void ScNamedRangesObj::unlock()
|
|
{
|
|
pDocShell->GetDocument().CompileHybridFormula();
|
|
}
|
|
|
|
// document::XActionLockable
|
|
|
|
sal_Bool ScNamedRangesObj::isActionLocked()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
return pDocShell->GetDocument().GetNamedRangesLockCount() != 0;
|
|
}
|
|
|
|
void ScNamedRangesObj::addActionLock()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
sal_Int16 nLockCount = rDoc.GetNamedRangesLockCount();
|
|
++nLockCount;
|
|
if ( nLockCount == 1 )
|
|
{
|
|
lock();
|
|
}
|
|
rDoc.SetNamedRangesLockCount( nLockCount );
|
|
}
|
|
|
|
void ScNamedRangesObj::removeActionLock()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
sal_Int16 nLockCount = rDoc.GetNamedRangesLockCount();
|
|
if ( nLockCount > 0 )
|
|
{
|
|
--nLockCount;
|
|
if ( nLockCount == 0 )
|
|
{
|
|
unlock();
|
|
}
|
|
rDoc.SetNamedRangesLockCount( nLockCount );
|
|
}
|
|
}
|
|
|
|
void ScNamedRangesObj::setActionLocks( sal_Int16 nLock )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if ( nLock < 0 )
|
|
return;
|
|
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
sal_Int16 nLockCount = rDoc.GetNamedRangesLockCount();
|
|
if ( nLock == 0 && nLockCount > 0 )
|
|
{
|
|
unlock();
|
|
}
|
|
if ( nLock > 0 && nLockCount == 0 )
|
|
{
|
|
lock();
|
|
}
|
|
rDoc.SetNamedRangesLockCount( nLock );
|
|
}
|
|
|
|
sal_Int16 ScNamedRangesObj::resetActionLocks()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
sal_Int16 nLockCount = rDoc.GetNamedRangesLockCount();
|
|
if ( nLockCount > 0 )
|
|
{
|
|
unlock();
|
|
}
|
|
rDoc.SetNamedRangesLockCount( 0 );
|
|
return nLockCount;
|
|
}
|
|
|
|
ScGlobalNamedRangesObj::ScGlobalNamedRangesObj(ScDocShell* pDocSh)
|
|
: ScNamedRangesObj(pDocSh)
|
|
{
|
|
|
|
}
|
|
|
|
ScGlobalNamedRangesObj::~ScGlobalNamedRangesObj()
|
|
{
|
|
|
|
}
|
|
|
|
rtl::Reference<ScNamedRangeObj> ScGlobalNamedRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
|
|
{
|
|
if (!pDocShell)
|
|
return nullptr;
|
|
|
|
ScRangeName* pNames = pDocShell->GetDocument().GetRangeName();
|
|
if (!pNames)
|
|
return nullptr;
|
|
|
|
sal_uInt16 nPos = 0;
|
|
for (const auto& rName : *pNames)
|
|
{
|
|
if (lcl_UserVisibleName(*rName.second))
|
|
{
|
|
if (nPos == nIndex)
|
|
return new ScNamedRangeObj(this, pDocShell, rName.second->GetName());
|
|
}
|
|
++nPos;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
rtl::Reference<ScNamedRangeObj> ScGlobalNamedRangesObj::GetObjectByName_Impl(const OUString& aName)
|
|
{
|
|
if ( pDocShell && hasByName(aName) )
|
|
return new ScNamedRangeObj(this, pDocShell, aName);
|
|
return nullptr;
|
|
}
|
|
|
|
ScRangeName* ScGlobalNamedRangesObj::GetRangeName_Impl()
|
|
{
|
|
return pDocShell->GetDocument().GetRangeName();
|
|
}
|
|
|
|
SCTAB ScGlobalNamedRangesObj::GetTab_Impl()
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
ScLocalNamedRangesObj::ScLocalNamedRangesObj( ScDocShell* pDocSh, uno::Reference<container::XNamed> xSheet )
|
|
: ScNamedRangesObj(pDocSh),
|
|
mxSheet(std::move(xSheet))
|
|
{
|
|
|
|
}
|
|
|
|
ScLocalNamedRangesObj::~ScLocalNamedRangesObj()
|
|
{
|
|
|
|
}
|
|
|
|
rtl::Reference<ScNamedRangeObj> ScLocalNamedRangesObj::GetObjectByName_Impl(const OUString& aName)
|
|
{
|
|
if ( pDocShell && hasByName( aName ) )
|
|
return new ScNamedRangeObj( this, pDocShell, aName, mxSheet);
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
rtl::Reference<ScNamedRangeObj> ScLocalNamedRangesObj::GetObjectByIndex_Impl( sal_uInt16 nIndex )
|
|
{
|
|
if (!pDocShell)
|
|
return nullptr;
|
|
|
|
OUString aName = mxSheet->getName();
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
SCTAB nTab;
|
|
if (!rDoc.GetTable(aName, nTab))
|
|
return nullptr;
|
|
|
|
ScRangeName* pNames = rDoc.GetRangeName( nTab );
|
|
if (!pNames)
|
|
return nullptr;
|
|
|
|
sal_uInt16 nPos = 0;
|
|
for (const auto& rName : *pNames)
|
|
{
|
|
if (lcl_UserVisibleName(*rName.second))
|
|
{
|
|
if (nPos == nIndex)
|
|
return new ScNamedRangeObj(this, pDocShell, rName.second->GetName(), mxSheet);
|
|
}
|
|
++nPos;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
ScRangeName* ScLocalNamedRangesObj::GetRangeName_Impl()
|
|
{
|
|
SCTAB nTab = GetTab_Impl();
|
|
return pDocShell->GetDocument().GetRangeName( nTab );
|
|
}
|
|
|
|
SCTAB ScLocalNamedRangesObj::GetTab_Impl()
|
|
{
|
|
SCTAB nTab;
|
|
(void)pDocShell->GetDocument().GetTable(mxSheet->getName(), nTab);
|
|
return nTab;
|
|
}
|
|
|
|
ScLabelRangeObj::ScLabelRangeObj(ScDocShell* pDocSh, bool bCol, const ScRange& rR) :
|
|
pDocShell( pDocSh ),
|
|
bColumn( bCol ),
|
|
aRange( rR )
|
|
{
|
|
pDocShell->GetDocument().AddUnoObject(*this);
|
|
}
|
|
|
|
ScLabelRangeObj::~ScLabelRangeObj()
|
|
{
|
|
SolarMutexGuard g;
|
|
|
|
if (pDocShell)
|
|
pDocShell->GetDocument().RemoveUnoObject(*this);
|
|
}
|
|
|
|
void ScLabelRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
|
|
{
|
|
//! Ref-Update !!!
|
|
|
|
if ( rHint.GetId() == SfxHintId::Dying )
|
|
pDocShell = nullptr; // became invalid
|
|
}
|
|
|
|
// Helper functions
|
|
|
|
ScRangePair* ScLabelRangeObj::GetData_Impl()
|
|
{
|
|
ScRangePair* pRet = nullptr;
|
|
if (pDocShell)
|
|
{
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
ScRangePairList* pList = bColumn ? rDoc.GetColNameRanges() : rDoc.GetRowNameRanges();
|
|
if (pList)
|
|
pRet = pList->Find( aRange );
|
|
}
|
|
return pRet;
|
|
}
|
|
|
|
void ScLabelRangeObj::Modify_Impl( const ScRange* pLabel, const ScRange* pData )
|
|
{
|
|
if (!pDocShell)
|
|
return;
|
|
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
ScRangePairList* pOldList = bColumn ? rDoc.GetColNameRanges() : rDoc.GetRowNameRanges();
|
|
if (!pOldList)
|
|
return;
|
|
|
|
ScRangePairListRef xNewList(pOldList->Clone());
|
|
ScRangePair* pEntry = xNewList->Find( aRange );
|
|
if (!pEntry)
|
|
return;
|
|
|
|
if ( pLabel )
|
|
pEntry->GetRange(0) = *pLabel;
|
|
if ( pData )
|
|
pEntry->GetRange(1) = *pData;
|
|
|
|
xNewList->Join( *pEntry, true );
|
|
|
|
if (bColumn)
|
|
rDoc.GetColNameRangesRef() = std::move(xNewList);
|
|
else
|
|
rDoc.GetRowNameRangesRef() = std::move(xNewList);
|
|
|
|
rDoc.CompileColRowNameFormula();
|
|
pDocShell->PostPaint( 0,0,0, rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB, PaintPartFlags::Grid );
|
|
pDocShell->SetDocumentModified();
|
|
|
|
//! Undo ?!?! (here and from dialog)
|
|
|
|
if ( pLabel )
|
|
aRange = *pLabel; // adapt object to find range again
|
|
}
|
|
|
|
// sheet::XLabelRange
|
|
|
|
table::CellRangeAddress SAL_CALL ScLabelRangeObj::getLabelArea()
|
|
{
|
|
SolarMutexGuard 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 )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScRange aLabelRange;
|
|
ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
|
|
Modify_Impl( &aLabelRange, nullptr );
|
|
}
|
|
|
|
table::CellRangeAddress SAL_CALL ScLabelRangeObj::getDataArea()
|
|
{
|
|
SolarMutexGuard 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 )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScRange aDataRange;
|
|
ScUnoConversion::FillScRange( aDataRange, aDataArea );
|
|
Modify_Impl( nullptr, &aDataRange );
|
|
}
|
|
|
|
ScLabelRangesObj::ScLabelRangesObj(ScDocShell* pDocSh, bool bCol) :
|
|
pDocShell( pDocSh ),
|
|
bColumn( bCol )
|
|
{
|
|
pDocShell->GetDocument().AddUnoObject(*this);
|
|
}
|
|
|
|
ScLabelRangesObj::~ScLabelRangesObj()
|
|
{
|
|
SolarMutexGuard g;
|
|
|
|
if (pDocShell)
|
|
pDocShell->GetDocument().RemoveUnoObject(*this);
|
|
}
|
|
|
|
void ScLabelRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
|
|
{
|
|
// reference update is of no interest
|
|
|
|
if ( rHint.GetId() == SfxHintId::Dying )
|
|
{
|
|
pDocShell = nullptr; // became invalid
|
|
}
|
|
}
|
|
|
|
// sheet::XLabelRanges
|
|
|
|
rtl::Reference<ScLabelRangeObj> ScLabelRangesObj::GetObjectByIndex_Impl(size_t nIndex)
|
|
{
|
|
if (pDocShell)
|
|
{
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
ScRangePairList* pList = bColumn ? rDoc.GetColNameRanges() : rDoc.GetRowNameRanges();
|
|
if ( pList && nIndex < pList->size() )
|
|
{
|
|
ScRangePair & rData = (*pList)[nIndex];
|
|
return new ScLabelRangeObj( pDocShell, bColumn, rData.GetRange(0) );
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void SAL_CALL ScLabelRangesObj::addNew( const table::CellRangeAddress& aLabelArea,
|
|
const table::CellRangeAddress& aDataArea )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if (!pDocShell)
|
|
return;
|
|
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
ScRangePairList* pOldList = bColumn ? rDoc.GetColNameRanges() : rDoc.GetRowNameRanges();
|
|
if (!pOldList)
|
|
return;
|
|
|
|
ScRangePairListRef xNewList(pOldList->Clone());
|
|
|
|
ScRange aLabelRange;
|
|
ScRange aDataRange;
|
|
ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
|
|
ScUnoConversion::FillScRange( aDataRange, aDataArea );
|
|
xNewList->Join( ScRangePair( aLabelRange, aDataRange ) );
|
|
|
|
if (bColumn)
|
|
rDoc.GetColNameRangesRef() = std::move(xNewList);
|
|
else
|
|
rDoc.GetRowNameRangesRef() = std::move(xNewList);
|
|
|
|
rDoc.CompileColRowNameFormula();
|
|
pDocShell->PostPaint( 0,0,0, rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB, PaintPartFlags::Grid );
|
|
pDocShell->SetDocumentModified();
|
|
|
|
//! Undo ?!?! (here and from dialog)
|
|
}
|
|
|
|
void SAL_CALL ScLabelRangesObj::removeByIndex( sal_Int32 nIndex )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
bool bDone = false;
|
|
if (pDocShell)
|
|
{
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
ScRangePairList* pOldList = bColumn ? rDoc.GetColNameRanges() : rDoc.GetRowNameRanges();
|
|
|
|
if ( pOldList && nIndex >= 0 && o3tl::make_unsigned(nIndex) < pOldList->size() )
|
|
{
|
|
ScRangePairListRef xNewList(pOldList->Clone());
|
|
|
|
xNewList->Remove( nIndex );
|
|
|
|
if (bColumn)
|
|
rDoc.GetColNameRangesRef() = std::move(xNewList);
|
|
else
|
|
rDoc.GetRowNameRangesRef() = std::move(xNewList);
|
|
|
|
rDoc.CompileColRowNameFormula();
|
|
pDocShell->PostPaint( 0,0,0, rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB, PaintPartFlags::Grid );
|
|
pDocShell->SetDocumentModified();
|
|
bDone = true;
|
|
|
|
//! Undo ?!?! (here and from dialog)
|
|
}
|
|
}
|
|
if (!bDone)
|
|
throw uno::RuntimeException(); // no other exceptions specified
|
|
}
|
|
|
|
// container::XEnumerationAccess
|
|
|
|
uno::Reference<container::XEnumeration> SAL_CALL ScLabelRangesObj::createEnumeration()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
return new ScIndexEnumeration(this, u"com.sun.star.sheet.LabelRangesEnumeration"_ustr);
|
|
}
|
|
|
|
// container::XIndexAccess
|
|
|
|
sal_Int32 SAL_CALL ScLabelRangesObj::getCount()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if (pDocShell)
|
|
{
|
|
ScDocument& rDoc = pDocShell->GetDocument();
|
|
ScRangePairList* pList = bColumn ? rDoc.GetColNameRanges() : rDoc.GetRowNameRanges();
|
|
if (pList)
|
|
return pList->size();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uno::Any SAL_CALL ScLabelRangesObj::getByIndex( sal_Int32 nIndex )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
uno::Reference< sheet::XLabelRange > xRange(GetObjectByIndex_Impl(static_cast<sal_uInt16>(nIndex)));
|
|
if ( !xRange.is() )
|
|
throw lang::IndexOutOfBoundsException();
|
|
|
|
return uno::Any(xRange);
|
|
}
|
|
|
|
uno::Type SAL_CALL ScLabelRangesObj::getElementType()
|
|
{
|
|
return cppu::UnoType<sheet::XLabelRange>::get(); // must be suitable for getByIndex
|
|
}
|
|
|
|
sal_Bool SAL_CALL ScLabelRangesObj::hasElements()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
return ( getCount() != 0 );
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|