summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2023-12-30 18:08:56 +0600
committerMike Kaganski <mike.kaganski@collabora.com>2023-12-30 14:43:38 +0100
commit7e5a345897e633083ce0194a34c4faac54d28371 (patch)
tree196c4ca2bd92c5ec6378c67f25b59589a533494e /sc
parent020444ed98d7a31403787238cd753e112a6a56fb (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.hxx37
-rw-r--r--sc/inc/table.hxx35
-rw-r--r--sc/source/core/data/column.cxx84
-rw-r--r--sc/source/core/data/table2.cxx68
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