sc/inc/markmulti.hxx | 3 ++ sc/qa/unit/uicalc/uicalc.cxx | 41 ++++++++++++++++++++++++++++++++++++ sc/source/core/data/markmulti.cxx | 19 ++++++++++++++++ sc/source/core/data/table2.cxx | 43 +++++++++++++++++++++++++++++++------- 4 files changed, 99 insertions(+), 7 deletions(-)
New commits: commit 3db91487e57277f75d64d95d06d4ddcc29f1c4e0 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Fri Mar 4 14:18:02 2022 +0100 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Fri Mar 4 16:41:58 2022 +0100 set properly attributes for cells in unallocated Calc columns ScTable::ApplySelectionCache() was setting attributes only for allocated columns, so e.g. selecting a whole column and making it bold didn't actually set all of it bold. Make sure it set it for all columns, and make use of the default attribute for unallocated columns to avoid allocating columns just to set them the same attribute. Change-Id: Ie9886317d7a91c6a43951af69b717f9ba32a1c9e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130984 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/sc/inc/markmulti.hxx b/sc/inc/markmulti.hxx index bb028e14a7a8..9861342dc49b 100644 --- a/sc/inc/markmulti.hxx +++ b/sc/inc/markmulti.hxx @@ -52,6 +52,9 @@ public: bool IsAllMarked( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const; bool HasEqualRowsMarked( SCCOL nCol1, SCCOL nCol2 ) const; SCROW GetNextMarked( SCCOL nCol, SCROW nRow, bool bUp ) const; + // Returns the first column of the range [column,nLastCol] for which + // all those columns have equal marks. Value returned is not less than nMinCol. + SCCOL GetStartOfEqualColumns( SCCOL nLastCol, SCCOL nMinCol = 0 ) const; void SetMarkArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow, bool bMark ); void Set( ScRangeList const & ); bool IsRowMarked( SCROW nRow ) const; diff --git a/sc/qa/unit/uicalc/uicalc.cxx b/sc/qa/unit/uicalc/uicalc.cxx index 0861d04fc4a6..00f966e2685d 100644 --- a/sc/qa/unit/uicalc/uicalc.cxx +++ b/sc/qa/unit/uicalc/uicalc.cxx @@ -2273,6 +2273,47 @@ CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testTdf126926) CPPUNIT_ASSERT(pDBs->empty()); } +CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testUnallocatedColumnsAttributes) +{ + mxComponent = loadFromDesktop("private:factory/scalc"); + ScModelObj* pModelObj = dynamic_cast<ScModelObj*>(mxComponent.get()); + CPPUNIT_ASSERT(pModelObj); + ScDocument* pDoc = pModelObj->GetDocument(); + CPPUNIT_ASSERT(pDoc); + + // If this check fails, this entire test needs adjusting. + CPPUNIT_ASSERT_EQUAL(SCCOL(64), pDoc->GetAllocatedColumnsCount(0)); + + // Except for first 10 cells make the entire first row bold. + goToCell("K1:" + pDoc->MaxColAsString() + "1"); + dispatchCommand(mxComponent, ".uno:Bold", {}); + + // That shouldn't need allocating more columns, just changing the default attribute. + CPPUNIT_ASSERT_EQUAL(SCCOL(64), pDoc->GetAllocatedColumnsCount(0)); + vcl::Font aFont; + pDoc->GetPattern(pDoc->MaxCol(), 0, 0)->GetFont(aFont, SC_AUTOCOL_RAW); + CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight()); + + goToCell("A2:CV2"); // first 100 cells in row 2 + dispatchCommand(mxComponent, ".uno:Bold", {}); + // These need to be explicitly allocated. + CPPUNIT_ASSERT_EQUAL(SCCOL(100), pDoc->GetAllocatedColumnsCount(0)); + pDoc->GetPattern(99, 1, 0)->GetFont(aFont, SC_AUTOCOL_RAW); + CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight()); + pDoc->GetPattern(100, 1, 0)->GetFont(aFont, SC_AUTOCOL_RAW); + CPPUNIT_ASSERT_EQUAL_MESSAGE("font should not be bold", WEIGHT_NORMAL, aFont.GetWeight()); + + goToCell("CW3:" + pDoc->MaxColAsString() + "3"); // All but first 100 cells in row 3. + dispatchCommand(mxComponent, ".uno:Bold", {}); + // First 100 columns need to be allocated to not be bold, the rest should be handled + // by the default attribute. + CPPUNIT_ASSERT_EQUAL(SCCOL(100), pDoc->GetAllocatedColumnsCount(0)); + pDoc->GetPattern(99, 2, 0)->GetFont(aFont, SC_AUTOCOL_RAW); + CPPUNIT_ASSERT_EQUAL_MESSAGE("font should not be bold", WEIGHT_NORMAL, aFont.GetWeight()); + pDoc->GetPattern(100, 2, 0)->GetFont(aFont, SC_AUTOCOL_RAW); + CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/markmulti.cxx b/sc/source/core/data/markmulti.cxx index dc0ebc528b06..3f1d4cbf0e6a 100644 --- a/sc/source/core/data/markmulti.cxx +++ b/sc/source/core/data/markmulti.cxx @@ -152,6 +152,25 @@ bool ScMultiSel::HasEqualRowsMarked( SCCOL nCol1, SCCOL nCol2 ) const return true; } +SCCOL ScMultiSel::GetStartOfEqualColumns( SCCOL nLastCol, SCCOL nMinCol ) const +{ + if( nMinCol > nLastCol ) + return nMinCol; + if( nLastCol >= static_cast<SCCOL>(aMultiSelContainer.size())) + { + if( nMinCol >= static_cast<SCCOL>(aMultiSelContainer.size())) + return nMinCol; + SCCOL nCol = static_cast<SCCOL>(aMultiSelContainer.size()) - 1; + while( nCol >= nMinCol && aMultiSelContainer[nCol] == aRowSel ) + --nCol; + return nCol + 1; + } + SCCOL nCol = nLastCol - 1; + while( nCol >= nMinCol && aMultiSelContainer[nCol] == aMultiSelContainer[nLastCol] ) + --nCol; + return nCol + 1; +} + SCROW ScMultiSel::GetNextMarked( SCCOL nCol, SCROW nRow, bool bUp ) const { if ( nCol >= static_cast<SCCOL>(aMultiSelContainer.size()) || !aMultiSelContainer[nCol].HasMarks() ) diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index b65d1651e56d..a9862090a5cc 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2799,13 +2799,23 @@ void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, const ScPatternAttr& rAttr, ScEditDataArray* pDataArray, bool* const pIsChanged ) { - if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow)) + if (!ValidColRow(nStartCol, nStartRow) || !ValidColRow(nEndCol, nEndRow)) + return; + PutInOrder(nStartCol, nEndCol); + PutInOrder(nStartRow, nEndRow); + SCCOL maxCol = nEndCol; + if( nEndCol == GetDoc().MaxCol()) { - PutInOrder(nStartCol, nEndCol); - PutInOrder(nStartRow, nEndRow); - for (SCCOL i = nStartCol; i <= nEndCol; i++) - CreateColumnIfNotExists(i).ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray, pIsChanged); + // For the same unallocated columns until the end we can change just the default. + maxCol = std::max( nStartCol, aCol.size()) - 1; + if( maxCol >= 0 ) + CreateColumnIfNotExists(maxCol); // Allocate needed different columns before changing the default. + const SfxItemSet* pSet = &rAttr.GetItemSet(); + SfxItemPoolCache aCache( GetDoc().GetPool(), pSet ); + aDefaultColAttrArray.ApplyCacheArea(nStartRow, nEndRow, &aCache, pDataArray, pIsChanged ); } + for (SCCOL i = nStartCol; i <= maxCol; i++) + CreateColumnIfNotExists(i).ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray, pIsChanged); } void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange, @@ -3076,8 +3086,27 @@ void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr ) void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged ) { - for (SCCOL i=0; i < aCol.size(); i++) - aCol[i].ApplySelectionCache( pCache, rMark, pDataArray, pIsChanged ); + if(!rMark.GetTableSelect(nTab)) + return; + assert( rMark.IsMultiMarked() ); + SCCOL maxCol; + if( rMark.GetMultiMarkArea().aEnd.Col() == GetDoc().MaxCol()) + { + // For the same unallocated columns until the end we can change just the default. + maxCol = rMark.GetMultiSelData().GetStartOfEqualColumns( GetDoc().MaxCol(), aCol.size()) - 1; + if( maxCol >= 0 ) + CreateColumnIfNotExists(maxCol); // Allocate needed different columns before changing the default. + ScMultiSelIter aMultiIter( rMark.GetMultiSelData(), GetDoc().MaxCol() ); + SCROW nTop = 0; + SCROW nBottom = 0; + while (aMultiIter.Next( nTop, nBottom )) + aDefaultColAttrArray.ApplyCacheArea( nTop, nBottom, pCache, pDataArray, pIsChanged ); + } + else // need to allocate all columns affected + maxCol = rMark.GetMultiMarkArea().aEnd.Col(); + + for (SCCOL i=0; i <= maxCol; i++) + CreateColumnIfNotExists(i).ApplySelectionCache( pCache, rMark, pDataArray, pIsChanged ); } void ScTable::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark )