1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <o3tl/safeint.hxx>
21 #include <svl/hint.hxx>
23 #include <vcl/svapp.hxx>
24 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
25 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
26 #include <com/sun/star/awt/XBitmap.hpp>
27 #include <com/sun/star/beans/PropertyAttribute.hpp>
29 #include <comphelper/servicehelper.hxx>
30 #include <cppuhelper/supportsservice.hxx>
31 #include <unotools/charclass.hxx>
33 #include <nameuno.hxx>
34 #include <miscuno.hxx>
35 #include <cellsuno.hxx>
36 #include <convuno.hxx>
37 #include <targuno.hxx>
38 #include <tokenuno.hxx>
39 #include <tokenarray.hxx>
41 #include <docfunc.hxx>
42 #include <rangenam.hxx>
43 #include <unonames.hxx>
45 #include <scui_def.hxx>
47 using namespace ::com::sun::star
;
48 using ::com::sun::star::uno::Reference
;
49 using ::com::sun::star::uno::Any
;
51 static std::span
<const SfxItemPropertyMapEntry
> lcl_GetNamedRangeMap()
53 static const SfxItemPropertyMapEntry aNamedRangeMap_Impl
[] =
55 { SC_UNO_LINKDISPBIT
, 0, cppu::UnoType
<awt::XBitmap
>::get(), beans::PropertyAttribute::READONLY
, 0 },
56 { SC_UNO_LINKDISPNAME
, 0, cppu::UnoType
<OUString
>::get(), beans::PropertyAttribute::READONLY
, 0 },
57 { SC_UNONAME_TOKENINDEX
, 0, cppu::UnoType
<sal_Int32
>::get(), beans::PropertyAttribute::READONLY
, 0 },
58 { SC_UNONAME_ISSHAREDFMLA
, 0, cppu::UnoType
<bool>::get(), 0, 0 },
60 return aNamedRangeMap_Impl
;
63 static std::span
<const SfxItemPropertyMapEntry
> lcl_GetNamedRangesMap()
65 static const SfxItemPropertyMapEntry aNamedRangesMap_Impl
[] =
67 { SC_UNO_MODIFY_BROADCAST
, 0, cppu::UnoType
<bool>::get(), 0, 0 },
69 return aNamedRangesMap_Impl
;
72 constexpr OUString SCNAMEDRANGEOBJ_SERVICE
= u
"com.sun.star.sheet.NamedRange"_ustr
;
74 SC_SIMPLE_SERVICE_INFO( ScLabelRangeObj
, u
"ScLabelRangeObj"_ustr
, u
"com.sun.star.sheet.LabelRange"_ustr
)
75 SC_SIMPLE_SERVICE_INFO( ScLabelRangesObj
, u
"ScLabelRangesObj"_ustr
, u
"com.sun.star.sheet.LabelRanges"_ustr
)
76 SC_SIMPLE_SERVICE_INFO( ScNamedRangesObj
, u
"ScNamedRangesObj"_ustr
, u
"com.sun.star.sheet.NamedRanges"_ustr
)
78 // Database named ranges are not considered by getCount, hasByName, removeByName and getElementNames
79 // Note that hidden named ranges are considered by these methods
80 static bool lcl_UserVisibleName(const ScRangeData
& rData
)
82 //! as method to ScRangeData
83 return !rData
.HasType(ScRangeData::Type::Database
);
86 ScNamedRangeObj::ScNamedRangeObj( rtl::Reference
< ScNamedRangesObj
> xParent
, ScDocShell
* pDocSh
, OUString aNm
, Reference
<container::XNamed
> const & xSheet
):
87 mxParent(std::move(xParent
)),
89 aName(std::move( aNm
)),
92 pDocShell
->GetDocument().AddUnoObject(*this);
95 ScNamedRangeObj::~ScNamedRangeObj()
100 pDocShell
->GetDocument().RemoveUnoObject(*this);
103 void ScNamedRangeObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
105 // reference update is of no interest
107 if ( rHint
.GetId() == SfxHintId::Dying
)
108 pDocShell
= nullptr; // became invalid
113 ScRangeData
* ScNamedRangeObj::GetRangeData_Impl()
115 ScRangeData
* pRet
= nullptr;
119 SCTAB nTab
= GetTab_Impl();
121 pNames
= pDocShell
->GetDocument().GetRangeName(nTab
);
123 pNames
= pDocShell
->GetDocument().GetRangeName();
126 pRet
= pNames
->findByUpperName(ScGlobal::getCharClass().uppercase(aName
));
128 pRet
->ValidateTabRefs(); // adjust relative tab refs to valid tables
134 SCTAB
ScNamedRangeObj::GetTab_Impl()
140 ScDocument
& rDoc
= pDocShell
->GetDocument();
142 OUString sName
= mxSheet
->getName();
143 bool bFound
= rDoc
.GetTable(sName
, nTab
);
144 assert(bFound
); (void)bFound
; // fouled up?
148 return -1;//global range name
151 // sheet::XNamedRange
153 void ScNamedRangeObj::Modify_Impl( const OUString
* pNewName
, const ScTokenArray
* pNewTokens
, const OUString
* pNewContent
,
154 const ScAddress
* pNewPos
, const ScRangeData::Type
* pNewType
,
155 const formula::FormulaGrammar::Grammar eGrammar
)
160 ScDocument
& rDoc
= pDocShell
->GetDocument();
162 SCTAB nTab
= GetTab_Impl();
164 pNames
= rDoc
.GetRangeName(nTab
);
166 pNames
= rDoc
.GetRangeName();
170 const ScRangeData
* pOld
= pNames
->findByUpperName(ScGlobal::getCharClass().uppercase(aName
));
174 std::unique_ptr
<ScRangeName
> pNewRanges(new ScRangeName(*pNames
));
176 OUString aInsName
= pOld
->GetName();
178 aInsName
= *pNewName
;
180 // Content string based => no problems with changed positions and such.
181 OUString aContent
= pOld
->GetSymbol(eGrammar
);
183 aContent
= *pNewContent
;
185 ScAddress aPos
= pOld
->GetPos();
189 ScRangeData::Type nType
= pOld
->GetType();
193 ScRangeData
* pNew
= nullptr;
195 pNew
= new ScRangeData( rDoc
, aInsName
, *pNewTokens
, aPos
, nType
);
197 pNew
= new ScRangeData( rDoc
, aInsName
, aContent
, aPos
, nType
, eGrammar
);
199 pNew
->SetIndex( pOld
->GetIndex() );
201 pNewRanges
->erase(*pOld
);
202 if (pNewRanges
->insert(pNew
))
204 pDocShell
->GetDocFunc().SetNewRangeNames(std::move(pNewRanges
), mxParent
->IsModifyAndBroadcast(), nTab
);
206 aName
= aInsName
; //! broadcast?
210 pNew
= nullptr; //! uno::Exception/Error or something
214 OUString SAL_CALL
ScNamedRangeObj::getName()
216 SolarMutexGuard aGuard
;
220 void SAL_CALL
ScNamedRangeObj::setName( const OUString
& aNewName
)
222 SolarMutexGuard aGuard
;
223 //! adapt formulas ?????
225 OUString
aNewStr(aNewName
);
226 // GRAM_API for API compatibility.
227 Modify_Impl( &aNewStr
, nullptr, nullptr, nullptr, nullptr,formula::FormulaGrammar::GRAM_API
);
229 if ( aName
!= aNewStr
) // some error occurred...
230 throw uno::RuntimeException(); // no other exceptions specified
233 OUString SAL_CALL
ScNamedRangeObj::getContent()
235 SolarMutexGuard aGuard
;
237 ScRangeData
* pData
= GetRangeData_Impl();
239 // GRAM_API for API compatibility.
240 aContent
= pData
->GetSymbol(formula::FormulaGrammar::GRAM_API
);
244 void SAL_CALL
ScNamedRangeObj::setContent( const OUString
& aContent
)
246 SolarMutexGuard aGuard
;
247 OUString
aContStr(aContent
);
248 // GRAM_API for API compatibility.
249 Modify_Impl( nullptr, nullptr, &aContStr
, nullptr, nullptr,formula::FormulaGrammar::GRAM_API
);
252 table::CellAddress SAL_CALL
ScNamedRangeObj::getReferencePosition()
254 SolarMutexGuard aGuard
;
256 ScRangeData
* pData
= GetRangeData_Impl();
258 aPos
= pData
->GetPos();
259 table::CellAddress aAddress
;
260 aAddress
.Column
= aPos
.Col();
261 aAddress
.Row
= aPos
.Row();
262 aAddress
.Sheet
= aPos
.Tab();
265 SCTAB nDocTabs
= pDocShell
->GetDocument().GetTableCount();
266 if ( aAddress
.Sheet
>= nDocTabs
&& nDocTabs
> 0 )
268 // Even after ValidateTabRefs, the position can be invalid if
269 // the content points to preceding tables. The resulting string
270 // is invalid in any case, so the position is just shifted.
271 aAddress
.Sheet
= nDocTabs
- 1;
277 void SAL_CALL
ScNamedRangeObj::setReferencePosition( const table::CellAddress
& aReferencePosition
)
279 SolarMutexGuard aGuard
;
280 ScAddress
aPos( static_cast<SCCOL
>(aReferencePosition
.Column
), static_cast<SCROW
>(aReferencePosition
.Row
), aReferencePosition
.Sheet
);
281 // GRAM_API for API compatibility.
282 Modify_Impl( nullptr, nullptr, nullptr, &aPos
, nullptr,formula::FormulaGrammar::GRAM_API
);
285 sal_Int32 SAL_CALL
ScNamedRangeObj::getType()
287 SolarMutexGuard aGuard
;
289 ScRangeData
* pData
= GetRangeData_Impl();
292 // do not return internal ScRangeData::Type flags
293 if ( pData
->HasType(ScRangeData::Type::Criteria
) ) nType
|= sheet::NamedRangeFlag::FILTER_CRITERIA
;
294 if ( pData
->HasType(ScRangeData::Type::PrintArea
) ) nType
|= sheet::NamedRangeFlag::PRINT_AREA
;
295 if ( pData
->HasType(ScRangeData::Type::ColHeader
) ) nType
|= sheet::NamedRangeFlag::COLUMN_HEADER
;
296 if ( pData
->HasType(ScRangeData::Type::RowHeader
) ) nType
|= sheet::NamedRangeFlag::ROW_HEADER
;
297 if ( pData
->HasType(ScRangeData::Type::Hidden
) ) nType
|= sheet::NamedRangeFlag::HIDDEN
;
302 void SAL_CALL
ScNamedRangeObj::setType( sal_Int32 nUnoType
)
304 SolarMutexGuard aGuard
;
305 ScRangeData::Type nNewType
= ScRangeData::Type::Name
;
306 if ( nUnoType
& sheet::NamedRangeFlag::FILTER_CRITERIA
) nNewType
|= ScRangeData::Type::Criteria
;
307 if ( nUnoType
& sheet::NamedRangeFlag::PRINT_AREA
) nNewType
|= ScRangeData::Type::PrintArea
;
308 if ( nUnoType
& sheet::NamedRangeFlag::COLUMN_HEADER
) nNewType
|= ScRangeData::Type::ColHeader
;
309 if ( nUnoType
& sheet::NamedRangeFlag::ROW_HEADER
) nNewType
|= ScRangeData::Type::RowHeader
;
310 if ( nUnoType
& sheet::NamedRangeFlag::HIDDEN
) nNewType
|= ScRangeData::Type::Hidden
;
312 // GRAM_API for API compatibility.
313 Modify_Impl( nullptr, nullptr, nullptr, nullptr, &nNewType
,formula::FormulaGrammar::GRAM_API
);
318 uno::Sequence
<sheet::FormulaToken
> SAL_CALL
ScNamedRangeObj::getTokens()
320 SolarMutexGuard aGuard
;
321 uno::Sequence
<sheet::FormulaToken
> aSequence
;
322 ScRangeData
* pData
= GetRangeData_Impl();
323 if (pData
&& pDocShell
)
325 ScTokenArray
* pTokenArray
= pData
->GetCode();
327 ScTokenConversion::ConvertToTokenSequence( pDocShell
->GetDocument(), aSequence
, *pTokenArray
);
332 void SAL_CALL
ScNamedRangeObj::setTokens( const uno::Sequence
<sheet::FormulaToken
>& rTokens
)
334 SolarMutexGuard aGuard
;
337 ScTokenArray
aTokenArray(pDocShell
->GetDocument());
338 (void)ScTokenConversion::ConvertToTokenArray( pDocShell
->GetDocument(), aTokenArray
, rTokens
);
339 // GRAM_API for API compatibility.
340 Modify_Impl( nullptr, &aTokenArray
, nullptr, nullptr, nullptr, formula::FormulaGrammar::GRAM_API
);
346 uno::Reference
<table::XCellRange
> SAL_CALL
ScNamedRangeObj::getReferredCells()
348 SolarMutexGuard aGuard
;
350 ScRangeData
* pData
= GetRangeData_Impl();
351 if ( pData
&& pData
->IsValidReference( aRange
) )
353 //! static function to create ScCellObj/ScCellRangeObj at ScCellRangeObj ???
355 if ( aRange
.aStart
== aRange
.aEnd
)
356 return new ScCellObj( pDocShell
, aRange
.aStart
);
358 return new ScCellRangeObj( pDocShell
, aRange
);
363 // beans::XPropertySet
365 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScNamedRangeObj::getPropertySetInfo()
367 static uno::Reference
< beans::XPropertySetInfo
> aRef(new SfxItemPropertySetInfo( lcl_GetNamedRangeMap() ));
371 void SAL_CALL
ScNamedRangeObj::setPropertyValue(
372 const OUString
& rPropertyName
, const uno::Any
& /*aValue*/ )
374 if ( rPropertyName
== SC_UNONAME_ISSHAREDFMLA
)
380 uno::Any SAL_CALL
ScNamedRangeObj::getPropertyValue( const OUString
& rPropertyName
)
382 SolarMutexGuard aGuard
;
384 if ( rPropertyName
== SC_UNO_LINKDISPBIT
)
386 // no target bitmaps for individual entries (would be all equal)
387 // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_RANGENAME );
389 else if ( rPropertyName
== SC_UNO_LINKDISPNAME
)
391 else if ( rPropertyName
== SC_UNONAME_TOKENINDEX
)
393 // get index for use in formula tokens (read-only)
394 ScRangeData
* pData
= GetRangeData_Impl();
396 aRet
<<= static_cast<sal_Int32
>(pData
->GetIndex());
398 else if ( rPropertyName
== SC_UNONAME_ISSHAREDFMLA
)
400 if (GetRangeData_Impl())
406 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangeObj
)
408 // lang::XServiceInfo
410 OUString SAL_CALL
ScNamedRangeObj::getImplementationName()
412 return u
"ScNamedRangeObj"_ustr
;
415 sal_Bool SAL_CALL
ScNamedRangeObj::supportsService( const OUString
& rServiceName
)
417 return cppu::supportsService(this, rServiceName
);
420 uno::Sequence
<OUString
> SAL_CALL
ScNamedRangeObj::getSupportedServiceNames()
422 return {SCNAMEDRANGEOBJ_SERVICE
, SCLINKTARGET_SERVICE
};
425 ScNamedRangesObj::ScNamedRangesObj(ScDocShell
* pDocSh
) :
426 mbModifyAndBroadcast(true),
429 pDocShell
->GetDocument().AddUnoObject(*this);
432 ScNamedRangesObj::~ScNamedRangesObj()
437 pDocShell
->GetDocument().RemoveUnoObject(*this);
440 void ScNamedRangesObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
442 // reference update is of no interest
444 if ( rHint
.GetId() == SfxHintId::Dying
)
446 pDocShell
= nullptr; // became invalid
450 // sheet::XNamedRanges
452 void SAL_CALL
ScNamedRangesObj::addNewByName( const OUString
& aName
,
453 const OUString
& aContent
, const table::CellAddress
& aPosition
,
456 SolarMutexGuard aGuard
;
457 ScAddress
aPos( static_cast<SCCOL
>(aPosition
.Column
), static_cast<SCROW
>(aPosition
.Row
), aPosition
.Sheet
);
459 ScRangeData::Type nNewType
= ScRangeData::Type::Name
;
460 if ( nUnoType
& sheet::NamedRangeFlag::FILTER_CRITERIA
) nNewType
|= ScRangeData::Type::Criteria
;
461 if ( nUnoType
& sheet::NamedRangeFlag::PRINT_AREA
) nNewType
|= ScRangeData::Type::PrintArea
;
462 if ( nUnoType
& sheet::NamedRangeFlag::COLUMN_HEADER
) nNewType
|= ScRangeData::Type::ColHeader
;
463 if ( nUnoType
& sheet::NamedRangeFlag::ROW_HEADER
) nNewType
|= ScRangeData::Type::RowHeader
;
464 if ( nUnoType
& sheet::NamedRangeFlag::HIDDEN
) nNewType
|= ScRangeData::Type::Hidden
;
469 ScDocument
& rDoc
= pDocShell
->GetDocument();
470 // tdf#119457 - check for a valid range name and cell reference
471 switch (ScRangeData::IsNameValid(aName
, rDoc
))
473 case ScRangeData::IsNameValidType::NAME_INVALID_CELL_REF
:
474 throw uno::RuntimeException(
475 u
"Invalid name. Reference to a cell, or a range of cells not allowed"_ustr
,
478 case ScRangeData::IsNameValidType::NAME_INVALID_BAD_STRING
:
479 throw uno::RuntimeException(
480 u
"Invalid name. Start with a letter, use only letters, numbers and underscore"_ustr
,
483 case ScRangeData::IsNameValidType::NAME_VALID
:
484 if (ScRangeName
* pNames
= GetRangeName_Impl();
486 && !pNames
->findByUpperName(ScGlobal::getCharClass().uppercase(aName
)))
488 std::unique_ptr
<ScRangeName
> pNewRanges(new ScRangeName( *pNames
));
489 // GRAM_API for API compatibility.
490 ScRangeData
* pNew
= new ScRangeData( rDoc
, aName
, aContent
,
491 aPos
, nNewType
,formula::FormulaGrammar::GRAM_API
);
492 if ( pNewRanges
->insert(pNew
) )
494 pDocShell
->GetDocFunc().SetNewRangeNames(std::move(pNewRanges
), mbModifyAndBroadcast
, GetTab_Impl());
506 throw uno::RuntimeException(); // no other exceptions specified
509 void SAL_CALL
ScNamedRangesObj::addNewFromTitles( const table::CellRangeAddress
& aSource
,
510 sheet::Border aBorder
)
512 SolarMutexGuard aGuard
;
513 //! this cannot be an enum, because multiple bits can be set !!!
515 bool bTop
= ( aBorder
== sheet::Border_TOP
);
516 bool bLeft
= ( aBorder
== sheet::Border_LEFT
);
517 bool bBottom
= ( aBorder
== sheet::Border_BOTTOM
);
518 bool bRight
= ( aBorder
== sheet::Border_RIGHT
);
521 ScUnoConversion::FillScRange( aRange
, aSource
);
523 CreateNameFlags nFlags
= CreateNameFlags::NONE
;
524 if (bTop
) nFlags
|= CreateNameFlags::Top
;
525 if (bLeft
) nFlags
|= CreateNameFlags::Left
;
526 if (bBottom
) nFlags
|= CreateNameFlags::Bottom
;
527 if (bRight
) nFlags
|= CreateNameFlags::Right
;
529 if (nFlags
!= CreateNameFlags::NONE
)
530 pDocShell
->GetDocFunc().CreateNames( aRange
, nFlags
, true, GetTab_Impl() );
533 void SAL_CALL
ScNamedRangesObj::removeByName( const OUString
& aName
)
535 SolarMutexGuard aGuard
;
539 ScRangeName
* pNames
= GetRangeName_Impl();
542 const ScRangeData
* pData
= pNames
->findByUpperName(ScGlobal::getCharClass().uppercase(aName
));
543 if (pData
&& lcl_UserVisibleName(*pData
))
545 std::unique_ptr
<ScRangeName
> pNewRanges(new ScRangeName(*pNames
));
546 pNewRanges
->erase(*pData
);
547 pDocShell
->GetDocFunc().SetNewRangeNames( std::move(pNewRanges
), mbModifyAndBroadcast
, GetTab_Impl());
554 throw uno::RuntimeException(); // no other exceptions specified
557 void SAL_CALL
ScNamedRangesObj::outputList( const table::CellAddress
& aOutputPosition
)
559 SolarMutexGuard aGuard
;
560 ScAddress
aPos( static_cast<SCCOL
>(aOutputPosition
.Column
), static_cast<SCROW
>(aOutputPosition
.Row
), aOutputPosition
.Sheet
);
562 pDocShell
->GetDocFunc().InsertNameList( aPos
, true );
565 // container::XEnumerationAccess
567 uno::Reference
<container::XEnumeration
> SAL_CALL
ScNamedRangesObj::createEnumeration()
569 SolarMutexGuard aGuard
;
570 return new ScIndexEnumeration(this, u
"com.sun.star.sheet.NamedRangesEnumeration"_ustr
);
573 // container::XIndexAccess
575 sal_Int32 SAL_CALL
ScNamedRangesObj::getCount()
577 SolarMutexGuard aGuard
;
578 tools::Long nRet
= 0;
581 ScRangeName
* pNames
= GetRangeName_Impl();
584 for (const auto& rName
: *pNames
)
585 if (lcl_UserVisibleName(*rName
.second
))
592 uno::Any SAL_CALL
ScNamedRangesObj::getByIndex( sal_Int32 nIndex
)
594 SolarMutexGuard aGuard
;
595 uno::Reference
< sheet::XNamedRange
> xRange(GetObjectByIndex_Impl(static_cast<sal_uInt16
>(nIndex
)));
597 throw lang::IndexOutOfBoundsException();
599 return uno::Any(xRange
);
602 uno::Type SAL_CALL
ScNamedRangesObj::getElementType()
604 return cppu::UnoType
<sheet::XNamedRange
>::get(); // must be suitable for getByIndex
607 sal_Bool SAL_CALL
ScNamedRangesObj::hasElements()
609 SolarMutexGuard aGuard
;
610 return ( getCount() != 0 );
613 Reference
<beans::XPropertySetInfo
> SAL_CALL
ScNamedRangesObj::getPropertySetInfo()
615 static Reference
<beans::XPropertySetInfo
> aRef(
616 new SfxItemPropertySetInfo(lcl_GetNamedRangesMap()));
620 void SAL_CALL
ScNamedRangesObj::setPropertyValue(
621 const OUString
& rPropertyName
, const uno::Any
& aValue
)
623 if ( rPropertyName
== SC_UNO_MODIFY_BROADCAST
)
625 aValue
>>= mbModifyAndBroadcast
;
629 Any SAL_CALL
ScNamedRangesObj::getPropertyValue( const OUString
& rPropertyName
)
632 if ( rPropertyName
== SC_UNO_MODIFY_BROADCAST
)
634 aRet
<<= mbModifyAndBroadcast
;
640 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangesObj
)
642 uno::Any SAL_CALL
ScNamedRangesObj::getByName( const OUString
& aName
)
644 SolarMutexGuard aGuard
;
645 uno::Reference
< sheet::XNamedRange
> xRange(GetObjectByName_Impl(aName
));
647 throw container::NoSuchElementException();
649 return uno::Any(xRange
);
652 uno::Sequence
<OUString
> SAL_CALL
ScNamedRangesObj::getElementNames()
654 SolarMutexGuard aGuard
;
657 ScRangeName
* pNames
= GetRangeName_Impl();
660 tools::Long nVisCount
= getCount(); // names with lcl_UserVisibleName
661 uno::Sequence
<OUString
> aSeq(nVisCount
);
662 OUString
* pAry
= aSeq
.getArray();
663 sal_uInt16 nVisPos
= 0;
664 for (const auto& rName
: *pNames
)
666 if (lcl_UserVisibleName(*rName
.second
))
667 pAry
[nVisPos
++] = rName
.second
->GetName();
675 sal_Bool SAL_CALL
ScNamedRangesObj::hasByName( const OUString
& aName
)
677 SolarMutexGuard aGuard
;
680 ScRangeName
* pNames
= GetRangeName_Impl();
683 const ScRangeData
* pData
= pNames
->findByUpperName(ScGlobal::getCharClass().uppercase(aName
));
684 if (pData
&& lcl_UserVisibleName(*pData
))
691 /** called from the XActionLockable interface methods on initial locking */
692 void ScNamedRangesObj::lock()
694 pDocShell
->GetDocument().PreprocessRangeNameUpdate();
697 /** called from the XActionLockable interface methods on final unlock */
698 void ScNamedRangesObj::unlock()
700 pDocShell
->GetDocument().CompileHybridFormula();
703 // document::XActionLockable
705 sal_Bool
ScNamedRangesObj::isActionLocked()
707 SolarMutexGuard aGuard
;
708 return pDocShell
->GetDocument().GetNamedRangesLockCount() != 0;
711 void ScNamedRangesObj::addActionLock()
713 SolarMutexGuard aGuard
;
714 ScDocument
& rDoc
= pDocShell
->GetDocument();
715 sal_Int16 nLockCount
= rDoc
.GetNamedRangesLockCount();
717 if ( nLockCount
== 1 )
721 rDoc
.SetNamedRangesLockCount( nLockCount
);
724 void ScNamedRangesObj::removeActionLock()
726 SolarMutexGuard aGuard
;
727 ScDocument
& rDoc
= pDocShell
->GetDocument();
728 sal_Int16 nLockCount
= rDoc
.GetNamedRangesLockCount();
729 if ( nLockCount
> 0 )
732 if ( nLockCount
== 0 )
736 rDoc
.SetNamedRangesLockCount( nLockCount
);
740 void ScNamedRangesObj::setActionLocks( sal_Int16 nLock
)
742 SolarMutexGuard aGuard
;
746 ScDocument
& rDoc
= pDocShell
->GetDocument();
747 sal_Int16 nLockCount
= rDoc
.GetNamedRangesLockCount();
748 if ( nLock
== 0 && nLockCount
> 0 )
752 if ( nLock
> 0 && nLockCount
== 0 )
756 rDoc
.SetNamedRangesLockCount( nLock
);
759 sal_Int16
ScNamedRangesObj::resetActionLocks()
761 SolarMutexGuard aGuard
;
762 ScDocument
& rDoc
= pDocShell
->GetDocument();
763 sal_Int16 nLockCount
= rDoc
.GetNamedRangesLockCount();
764 if ( nLockCount
> 0 )
768 rDoc
.SetNamedRangesLockCount( 0 );
772 ScGlobalNamedRangesObj::ScGlobalNamedRangesObj(ScDocShell
* pDocSh
)
773 : ScNamedRangesObj(pDocSh
)
778 ScGlobalNamedRangesObj::~ScGlobalNamedRangesObj()
783 rtl::Reference
<ScNamedRangeObj
> ScGlobalNamedRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex
)
788 ScRangeName
* pNames
= pDocShell
->GetDocument().GetRangeName();
793 for (const auto& rName
: *pNames
)
795 if (lcl_UserVisibleName(*rName
.second
))
798 return new ScNamedRangeObj(this, pDocShell
, rName
.second
->GetName());
805 rtl::Reference
<ScNamedRangeObj
> ScGlobalNamedRangesObj::GetObjectByName_Impl(const OUString
& aName
)
807 if ( pDocShell
&& hasByName(aName
) )
808 return new ScNamedRangeObj(this, pDocShell
, aName
);
812 ScRangeName
* ScGlobalNamedRangesObj::GetRangeName_Impl()
814 return pDocShell
->GetDocument().GetRangeName();
817 SCTAB
ScGlobalNamedRangesObj::GetTab_Impl()
822 ScLocalNamedRangesObj::ScLocalNamedRangesObj( ScDocShell
* pDocSh
, uno::Reference
<container::XNamed
> xSheet
)
823 : ScNamedRangesObj(pDocSh
),
824 mxSheet(std::move(xSheet
))
829 ScLocalNamedRangesObj::~ScLocalNamedRangesObj()
834 rtl::Reference
<ScNamedRangeObj
> ScLocalNamedRangesObj::GetObjectByName_Impl(const OUString
& aName
)
836 if ( pDocShell
&& hasByName( aName
) )
837 return new ScNamedRangeObj( this, pDocShell
, aName
, mxSheet
);
842 rtl::Reference
<ScNamedRangeObj
> ScLocalNamedRangesObj::GetObjectByIndex_Impl( sal_uInt16 nIndex
)
847 OUString aName
= mxSheet
->getName();
848 ScDocument
& rDoc
= pDocShell
->GetDocument();
850 if (!rDoc
.GetTable(aName
, nTab
))
853 ScRangeName
* pNames
= rDoc
.GetRangeName( nTab
);
858 for (const auto& rName
: *pNames
)
860 if (lcl_UserVisibleName(*rName
.second
))
863 return new ScNamedRangeObj(this, pDocShell
, rName
.second
->GetName(), mxSheet
);
870 ScRangeName
* ScLocalNamedRangesObj::GetRangeName_Impl()
872 SCTAB nTab
= GetTab_Impl();
873 return pDocShell
->GetDocument().GetRangeName( nTab
);
876 SCTAB
ScLocalNamedRangesObj::GetTab_Impl()
879 (void)pDocShell
->GetDocument().GetTable(mxSheet
->getName(), nTab
);
883 ScLabelRangeObj::ScLabelRangeObj(ScDocShell
* pDocSh
, bool bCol
, const ScRange
& rR
) :
888 pDocShell
->GetDocument().AddUnoObject(*this);
891 ScLabelRangeObj::~ScLabelRangeObj()
896 pDocShell
->GetDocument().RemoveUnoObject(*this);
899 void ScLabelRangeObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
903 if ( rHint
.GetId() == SfxHintId::Dying
)
904 pDocShell
= nullptr; // became invalid
909 ScRangePair
* ScLabelRangeObj::GetData_Impl()
911 ScRangePair
* pRet
= nullptr;
914 ScDocument
& rDoc
= pDocShell
->GetDocument();
915 ScRangePairList
* pList
= bColumn
? rDoc
.GetColNameRanges() : rDoc
.GetRowNameRanges();
917 pRet
= pList
->Find( aRange
);
922 void ScLabelRangeObj::Modify_Impl( const ScRange
* pLabel
, const ScRange
* pData
)
927 ScDocument
& rDoc
= pDocShell
->GetDocument();
928 ScRangePairList
* pOldList
= bColumn
? rDoc
.GetColNameRanges() : rDoc
.GetRowNameRanges();
932 ScRangePairListRef
xNewList(pOldList
->Clone());
933 ScRangePair
* pEntry
= xNewList
->Find( aRange
);
938 pEntry
->GetRange(0) = *pLabel
;
940 pEntry
->GetRange(1) = *pData
;
942 xNewList
->Join( *pEntry
, true );
945 rDoc
.GetColNameRangesRef() = std::move(xNewList
);
947 rDoc
.GetRowNameRangesRef() = std::move(xNewList
);
949 rDoc
.CompileColRowNameFormula();
950 pDocShell
->PostPaint( 0,0,0, rDoc
.MaxCol(),rDoc
.MaxRow(),MAXTAB
, PaintPartFlags::Grid
);
951 pDocShell
->SetDocumentModified();
953 //! Undo ?!?! (here and from dialog)
956 aRange
= *pLabel
; // adapt object to find range again
959 // sheet::XLabelRange
961 table::CellRangeAddress SAL_CALL
ScLabelRangeObj::getLabelArea()
963 SolarMutexGuard aGuard
;
964 table::CellRangeAddress aRet
;
965 ScRangePair
* pData
= GetData_Impl();
967 ScUnoConversion::FillApiRange( aRet
, pData
->GetRange(0) );
971 void SAL_CALL
ScLabelRangeObj::setLabelArea( const table::CellRangeAddress
& aLabelArea
)
973 SolarMutexGuard aGuard
;
975 ScUnoConversion::FillScRange( aLabelRange
, aLabelArea
);
976 Modify_Impl( &aLabelRange
, nullptr );
979 table::CellRangeAddress SAL_CALL
ScLabelRangeObj::getDataArea()
981 SolarMutexGuard aGuard
;
982 table::CellRangeAddress aRet
;
983 ScRangePair
* pData
= GetData_Impl();
985 ScUnoConversion::FillApiRange( aRet
, pData
->GetRange(1) );
989 void SAL_CALL
ScLabelRangeObj::setDataArea( const table::CellRangeAddress
& aDataArea
)
991 SolarMutexGuard aGuard
;
993 ScUnoConversion::FillScRange( aDataRange
, aDataArea
);
994 Modify_Impl( nullptr, &aDataRange
);
997 ScLabelRangesObj::ScLabelRangesObj(ScDocShell
* pDocSh
, bool bCol
) :
1001 pDocShell
->GetDocument().AddUnoObject(*this);
1004 ScLabelRangesObj::~ScLabelRangesObj()
1009 pDocShell
->GetDocument().RemoveUnoObject(*this);
1012 void ScLabelRangesObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1014 // reference update is of no interest
1016 if ( rHint
.GetId() == SfxHintId::Dying
)
1018 pDocShell
= nullptr; // became invalid
1022 // sheet::XLabelRanges
1024 rtl::Reference
<ScLabelRangeObj
> ScLabelRangesObj::GetObjectByIndex_Impl(size_t nIndex
)
1028 ScDocument
& rDoc
= pDocShell
->GetDocument();
1029 ScRangePairList
* pList
= bColumn
? rDoc
.GetColNameRanges() : rDoc
.GetRowNameRanges();
1030 if ( pList
&& nIndex
< pList
->size() )
1032 ScRangePair
& rData
= (*pList
)[nIndex
];
1033 return new ScLabelRangeObj( pDocShell
, bColumn
, rData
.GetRange(0) );
1039 void SAL_CALL
ScLabelRangesObj::addNew( const table::CellRangeAddress
& aLabelArea
,
1040 const table::CellRangeAddress
& aDataArea
)
1042 SolarMutexGuard aGuard
;
1046 ScDocument
& rDoc
= pDocShell
->GetDocument();
1047 ScRangePairList
* pOldList
= bColumn
? rDoc
.GetColNameRanges() : rDoc
.GetRowNameRanges();
1051 ScRangePairListRef
xNewList(pOldList
->Clone());
1053 ScRange aLabelRange
;
1055 ScUnoConversion::FillScRange( aLabelRange
, aLabelArea
);
1056 ScUnoConversion::FillScRange( aDataRange
, aDataArea
);
1057 xNewList
->Join( ScRangePair( aLabelRange
, aDataRange
) );
1060 rDoc
.GetColNameRangesRef() = std::move(xNewList
);
1062 rDoc
.GetRowNameRangesRef() = std::move(xNewList
);
1064 rDoc
.CompileColRowNameFormula();
1065 pDocShell
->PostPaint( 0,0,0, rDoc
.MaxCol(),rDoc
.MaxRow(),MAXTAB
, PaintPartFlags::Grid
);
1066 pDocShell
->SetDocumentModified();
1068 //! Undo ?!?! (here and from dialog)
1071 void SAL_CALL
ScLabelRangesObj::removeByIndex( sal_Int32 nIndex
)
1073 SolarMutexGuard aGuard
;
1077 ScDocument
& rDoc
= pDocShell
->GetDocument();
1078 ScRangePairList
* pOldList
= bColumn
? rDoc
.GetColNameRanges() : rDoc
.GetRowNameRanges();
1080 if ( pOldList
&& nIndex
>= 0 && o3tl::make_unsigned(nIndex
) < pOldList
->size() )
1082 ScRangePairListRef
xNewList(pOldList
->Clone());
1084 xNewList
->Remove( nIndex
);
1087 rDoc
.GetColNameRangesRef() = std::move(xNewList
);
1089 rDoc
.GetRowNameRangesRef() = std::move(xNewList
);
1091 rDoc
.CompileColRowNameFormula();
1092 pDocShell
->PostPaint( 0,0,0, rDoc
.MaxCol(),rDoc
.MaxRow(),MAXTAB
, PaintPartFlags::Grid
);
1093 pDocShell
->SetDocumentModified();
1096 //! Undo ?!?! (here and from dialog)
1100 throw uno::RuntimeException(); // no other exceptions specified
1103 // container::XEnumerationAccess
1105 uno::Reference
<container::XEnumeration
> SAL_CALL
ScLabelRangesObj::createEnumeration()
1107 SolarMutexGuard aGuard
;
1108 return new ScIndexEnumeration(this, u
"com.sun.star.sheet.LabelRangesEnumeration"_ustr
);
1111 // container::XIndexAccess
1113 sal_Int32 SAL_CALL
ScLabelRangesObj::getCount()
1115 SolarMutexGuard aGuard
;
1118 ScDocument
& rDoc
= pDocShell
->GetDocument();
1119 ScRangePairList
* pList
= bColumn
? rDoc
.GetColNameRanges() : rDoc
.GetRowNameRanges();
1121 return pList
->size();
1126 uno::Any SAL_CALL
ScLabelRangesObj::getByIndex( sal_Int32 nIndex
)
1128 SolarMutexGuard aGuard
;
1129 uno::Reference
< sheet::XLabelRange
> xRange(GetObjectByIndex_Impl(static_cast<sal_uInt16
>(nIndex
)));
1131 throw lang::IndexOutOfBoundsException();
1133 return uno::Any(xRange
);
1136 uno::Type SAL_CALL
ScLabelRangesObj::getElementType()
1138 return cppu::UnoType
<sheet::XLabelRange
>::get(); // must be suitable for getByIndex
1141 sal_Bool SAL_CALL
ScLabelRangesObj::hasElements()
1143 SolarMutexGuard aGuard
;
1144 return ( getCount() != 0 );
1147 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */