diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2023-12-30 18:08:56 +0600 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2023-12-30 14:43:38 +0100 |
commit | 7e5a345897e633083ce0194a34c4faac54d28371 (patch) | |
tree | 196c4ca2bd92c5ec6378c67f25b59589a533494e /sc | |
parent | 020444ed98d7a31403787238cd753e112a6a56fb (diff) |
tdf#158254: generalize and use algorithm to apply with allocation
Commit 17bcf1073bf21088b9845e36fe735622d8f88fd7 (introduce ScColumnData
for ScColumn/ScTable code sharing, 2022-05-05) implemented an algorithm
to only allocate needed amount of columns, and/or apply to default data
when needed. It was done for ApplySelectionCache, ChangeSelectionIndent,
ClearSelectionItems. Yet, many other functions need the same approach.
This change introduces ScTable::ApplyWithAllocation template, which
allows to use this algorithm uniformly to any operation on a selection,
which ultimately applies to ScColumnData. The code in the functions
mentioned above is replaced with its use; and ApplySelectionStyle is
fixed using it.
Change-Id: Ic8890d9980fcb01b61bb111183b355c623f866a2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161441
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/column.hxx | 37 | ||||
-rw-r--r-- | sc/inc/table.hxx | 35 | ||||
-rw-r--r-- | sc/source/core/data/column.cxx | 84 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 68 |
4 files changed, 81 insertions, 143 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 87273f0f83ba..0e07ed8142b0 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -145,8 +145,9 @@ public: const ScPatternAttr* GetPattern( SCROW nRow ) const; const ScPatternAttr* GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const; - SCROW ApplySelectionCache( ScItemPoolCache& rCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged, - SCCOL nCol ); + void ApplySelectionStyle(const ScStyleSheet& rStyle, SCROW nTop, SCROW nBottom); + void ApplySelectionCache(ScItemPoolCache& rCache, SCROW nStartRow, SCROW nEndRow, + ScEditDataArray* pDataArray, bool* pIsChanged); void ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr, ScEditDataArray* pDataArray = nullptr, bool* const pIsChanged = nullptr); @@ -168,12 +169,17 @@ public: bool IsAllAttrEqual( const ScColumnData& rCol, SCROW nStartRow, SCROW nEndRow ) const; - void ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark, SCCOL nCol ); - void ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark, SCCOL nCol ); + void ClearSelectionItems(const sal_uInt16* pWhich, SCROW nStartRow, SCROW nEndRow); + void ChangeSelectionIndent(bool bIncrement, SCROW nStartRow, SCROW nEndRow); bool TestInsertRow( SCSIZE nSize ) const; void InsertRow( SCROW nStartRow, SCSIZE nSize ); void DeleteRow( SCROW nStartRow, SCSIZE nSize ); + + // Applies a function to the selected ranges. + // The function looks like + // ApplyDataFunc(ScColumnData& applyTo, SCROW nTop, SCROW nBottom) + template <typename ApplyDataFunc> void Apply(const ScMarkData&, SCCOL, ApplyDataFunc); }; // Use protected inheritance to prevent publishing some internal ScColumnData @@ -549,7 +555,6 @@ public: const ScPatternAttr& rPattern, SvNumFormatType nNewType ); void ApplyStyle( SCROW nRow, const ScStyleSheet* rStyle ); - void ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark); void ApplySelectionLineStyle( const ScMarkData& rMark, const ::editeng::SvxBorderLine* pLine, bool bColorOnly ); void AddCondFormat(SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex ); @@ -576,12 +581,8 @@ public: void RemoveProtected( SCROW nStartRow, SCROW nEndRow ); - SCROW ApplySelectionCache( ScItemPoolCache& rCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged ); void DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast ); - void ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark ); - void ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark ); - tools::Long GetNeededSize( SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY, const Fraction& rZoomX, const Fraction& rZoomY, @@ -1067,4 +1068,22 @@ inline void ScColumnData::DeleteRow(SCROW nStartRow, SCSIZE nSize) pAttrArray->DeleteRow( nStartRow, nSize ); } +template <typename ApplyDataFunc> +void ScColumnData::Apply(const ScMarkData& rMark, SCCOL nCol, ApplyDataFunc apply) +{ + if (rMark.IsMultiMarked()) + { + ScMultiSelIter aMultiIter(rMark.GetMultiSelData(), nCol); + SCROW nTop, nBottom; + while (aMultiIter.Next(nTop, nBottom)) + apply(*this, nTop, nBottom); + } + else if (rMark.IsMarked()) + { + const ScRange& aRange = rMark.GetMarkArea(); + if (aRange.aStart.Col() <= nCol && nCol <= aRange.aEnd.Col()) + apply(*this, aRange.aStart.Row(), aRange.aEnd.Row()); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 72e78b195986..8f749a273707 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -34,6 +34,7 @@ #include "drwlayer.hxx" #include "SparklineList.hxx" #include "SolverSettings.hxx" +#include "markdata.hxx" #include <algorithm> #include <atomic> @@ -1427,6 +1428,40 @@ private: SCROW mnUBound; }; + // Applies a function to the selected ranges; makes sure to only allocate + // as few columns as needed, and applies the rest to default column data. + // The function looks like + // ApplyDataFunc(ScColumnData& applyTo, SCROW nTop, SCROW nBottom) + template <typename ApplyDataFunc> + void ApplyWithAllocation(const ScMarkData&, ApplyDataFunc); }; +template <typename ApplyDataFunc> +void ScTable::ApplyWithAllocation(const ScMarkData& rMark, ApplyDataFunc apply) +{ + if (!rMark.GetTableSelect(nTab) || !(rMark.IsMultiMarked() || rMark.IsMarked())) + return; + SCCOL lastChangeCol; + if (rMark.GetArea().aEnd.Col() == GetDoc().MaxCol()) + { + // For the same unallocated columns until the end we can change just the default. + lastChangeCol = rMark.GetStartOfEqualColumns(GetDoc().MaxCol(), aCol.size()) - 1; + // Allocate needed different columns before changing the default. + if (lastChangeCol >= 0) + CreateColumnIfNotExists(lastChangeCol); + + aDefaultColData.Apply(rMark, GetDoc().MaxCol(), apply); + } + else // need to allocate all columns affected + { + lastChangeCol = rMark.GetArea().aEnd.Col(); + CreateColumnIfNotExists(lastChangeCol); + } + + // The loop should go not to lastChangeCol, but over all columns, to apply to already allocated + // in the "StartOfEqualColumns" range + for (SCCOL i = 0; i < aCol.size(); i++) + aCol[i].Apply(rMark, i, apply); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 198e56fb7158..59b9b8c78117 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -375,81 +375,23 @@ sal_uInt32 ScColumnData::GetNumberFormat( SCROW nStartRow, SCROW nEndRow ) const return nFormat; } -SCROW ScColumn::ApplySelectionCache( ScItemPoolCache& rCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, - bool* const pIsChanged ) +void ScColumnData::ApplySelectionCache(ScItemPoolCache& rCache, SCROW nStartRow, SCROW nEndRow, + ScEditDataArray* pDataArray, bool* pIsChanged) { - return ScColumnData::ApplySelectionCache( rCache, rMark, pDataArray, pIsChanged, nCol ); + pAttrArray->ApplyCacheArea(nStartRow, nEndRow, rCache, pDataArray, pIsChanged); } -SCROW ScColumnData::ApplySelectionCache( ScItemPoolCache& rCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, - bool* const pIsChanged, SCCOL nCol ) +void ScColumnData::ChangeSelectionIndent(bool bIncrement, SCROW nStartRow, SCROW nEndRow) { - SCROW nTop = 0; - SCROW nBottom = 0; - bool bFound = false; - - if ( rMark.IsMultiMarked() ) - { - ScMultiSelIter aMultiIter( rMark.GetMultiSelData(), nCol ); - while (aMultiIter.Next( nTop, nBottom )) - { - pAttrArray->ApplyCacheArea( nTop, nBottom, rCache, pDataArray, pIsChanged ); - bFound = true; - } - } - - if (!bFound) - return -1; - else if (nTop==0 && nBottom==GetDoc().MaxRow()) - return 0; - else - return nBottom; -} - -void ScColumnData::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark, SCCOL nCol ) -{ - assert(rMark.IsMultiMarked()); - if ( pAttrArray && rMark.IsMultiMarked() ) - { - ScMultiSelIter aMultiIter( rMark.GetMultiSelData(), nCol ); - SCROW nTop; - SCROW nBottom; - while (aMultiIter.Next( nTop, nBottom )) - pAttrArray->ChangeIndent(nTop, nBottom, bIncrement); - } -} - -void ScColumn::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark ) -{ - return ScColumnData::ChangeSelectionIndent( bIncrement, rMark, nCol ); + pAttrArray->ChangeIndent(nStartRow, nEndRow, bIncrement); } -void ScColumnData::ClearSelectionItems( const sal_uInt16* pWhich,const ScMarkData& rMark, SCCOL nCol ) +void ScColumnData::ClearSelectionItems(const sal_uInt16* pWhich, SCROW nStartRow, SCROW nEndRow) { if (!pAttrArray) return; - if (rMark.IsMultiMarked() ) - { - ScMultiSelIter aMultiIter( rMark.GetMultiSelData(), nCol ); - SCROW nTop; - SCROW nBottom; - while (aMultiIter.Next( nTop, nBottom )) - pAttrArray->ClearItems(nTop, nBottom, pWhich); - } - else if (rMark.IsMarked()) - { - const ScRange& aRange = rMark.GetMarkArea(); - if (aRange.aStart.Col() <= nCol && nCol <= aRange.aEnd.Col()) - { - pAttrArray->ClearItems(aRange.aStart.Row(), aRange.aEnd.Row(), pWhich); - } - } -} - -void ScColumn::ClearSelectionItems( const sal_uInt16* pWhich,const ScMarkData& rMark ) -{ - ScColumnData::ClearSelectionItems( pWhich, rMark, nCol ); + pAttrArray->ClearItems(nStartRow, nEndRow, pWhich); } void ScColumn::DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast ) @@ -522,17 +464,9 @@ void ScColumn::ApplyStyle( SCROW nRow, const ScStyleSheet* rStyle ) pAttrArray->SetPattern(nRow, CellAttributeHolder(pNewPattern, true)); } -void ScColumn::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark) +void ScColumnData::ApplySelectionStyle(const ScStyleSheet& rStyle, SCROW nTop, SCROW nBottom) { - SCROW nTop; - SCROW nBottom; - - if ( rMark.IsMultiMarked() ) - { - ScMultiSelIter aMultiIter( rMark.GetMultiSelData(), nCol ); - while (aMultiIter.Next( nTop, nBottom )) - pAttrArray->ApplyStyleArea(nTop, nBottom, rStyle); - } + pAttrArray->ApplyStyleArea(nTop, nBottom, rStyle); } void ScColumn::ApplySelectionLineStyle( const ScMarkData& rMark, diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index b995aec2e7b4..6ce0a1637346 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -3073,8 +3073,8 @@ void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, S void ScTable::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark) { - for (SCCOL i=0; i < aCol.size(); i++) - aCol[i].ApplySelectionStyle( rStyle, rMark ); + ApplyWithAllocation(rMark, [&rStyle](ScColumnData& applyTo, SCROW nTop, SCROW nBottom) + { applyTo.ApplySelectionStyle(rStyle, nTop, nBottom); }); } void ScTable::ApplySelectionLineStyle( const ScMarkData& rMark, @@ -3236,71 +3236,21 @@ void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr ) void ScTable::ApplySelectionCache( ScItemPoolCache& rCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged ) { - if(!rMark.GetTableSelect(nTab)) - return; - SCCOL lastChangeCol; - if( rMark.GetArea().aEnd.Col() == GetDoc().MaxCol()) - { - // For the same unallocated columns until the end we can change just the default. - lastChangeCol = rMark.GetStartOfEqualColumns( GetDoc().MaxCol(), aCol.size()) - 1; - if( lastChangeCol >= 0 ) - CreateColumnIfNotExists(lastChangeCol); // Allocate needed different columns before changing the default. - aDefaultColData.ApplySelectionCache( rCache, rMark, pDataArray, pIsChanged, GetDoc().MaxCol()); - } - else // need to allocate all columns affected - { - lastChangeCol = rMark.GetArea().aEnd.Col(); - CreateColumnIfNotExists(lastChangeCol); - } - - for (SCCOL i=0; i <= lastChangeCol; i++) - aCol[i].ApplySelectionCache( rCache, rMark, pDataArray, pIsChanged ); + ApplyWithAllocation( + rMark, [&rCache, pDataArray, pIsChanged](ScColumnData& applyTo, SCROW nTop, SCROW nBottom) + { applyTo.ApplySelectionCache(rCache, nTop, nBottom, pDataArray, pIsChanged); }); } void ScTable::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark ) { - if(!rMark.GetTableSelect(nTab)) - return; - SCCOL lastChangeCol; - if( rMark.GetArea().aEnd.Col() == GetDoc().MaxCol()) - { - // For the same unallocated columns until the end we can change just the default. - lastChangeCol = rMark.GetStartOfEqualColumns( GetDoc().MaxCol(), aCol.size()) - 1; - if( lastChangeCol >= 0 ) - CreateColumnIfNotExists(lastChangeCol); // Allocate needed different columns before changing the default. - aDefaultColData.ChangeSelectionIndent( bIncrement, rMark, GetDoc().MaxCol()); - } - else - { - lastChangeCol = rMark.GetArea().aEnd.Col(); - CreateColumnIfNotExists(lastChangeCol); - } - - for (SCCOL i=0; i <= lastChangeCol; i++) - aCol[i].ChangeSelectionIndent( bIncrement, rMark ); + ApplyWithAllocation(rMark, [&bIncrement](ScColumnData& applyTo, SCROW nTop, SCROW nBottom) + { applyTo.ChangeSelectionIndent(bIncrement, nTop, nBottom); }); } void ScTable::ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark ) { - if(!rMark.GetTableSelect(nTab)) - return; - SCCOL lastChangeCol; - if( rMark.GetArea().aEnd.Col() == GetDoc().MaxCol()) - { - // For the same unallocated columns until the end we can change just the default. - lastChangeCol = rMark.GetStartOfEqualColumns( GetDoc().MaxCol(), aCol.size()) - 1; - if( lastChangeCol >= 0 ) - CreateColumnIfNotExists(lastChangeCol); // Allocate needed different columns before changing the default. - aDefaultColData.ClearSelectionItems( pWhich, rMark, GetDoc().MaxCol()); - } - else - { - lastChangeCol = rMark.GetArea().aEnd.Col(); - CreateColumnIfNotExists(lastChangeCol); - } - - for (SCCOL i=0; i <= lastChangeCol; i++) - aCol[i].ClearSelectionItems( pWhich, rMark ); + ApplyWithAllocation(rMark, [pWhich](ScColumnData& applyTo, SCROW nTop, SCROW nBottom) + { applyTo.ClearSelectionItems(pWhich, nTop, nBottom); }); } // Column widths / Row heights |