diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2022-03-04 14:18:02 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2022-03-23 09:09:07 +0100 |
commit | ffbd9053b85b6b22b2401ac20ef0244acd55f244 (patch) | |
tree | 664c21ca1ae2158c7233b1b1ed1539aeaa3d7f2e /sc | |
parent | c4077e840ba8983076ef77927b7b47ddb88e44aa (diff) |
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.lunak@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/markmulti.hxx | 3 | ||||
-rw-r--r-- | sc/qa/unit/uicalc/uicalc.cxx | 41 | ||||
-rw-r--r-- | sc/source/core/data/markmulti.cxx | 19 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 43 |
4 files changed, 99 insertions, 7 deletions
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 beaf837bf1a4..7a92f711cb13 100644 --- a/sc/qa/unit/uicalc/uicalc.cxx +++ b/sc/qa/unit/uicalc/uicalc.cxx @@ -1964,6 +1964,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 02775bc548e4..64739bc896b7 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2807,13 +2807,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, @@ -3084,8 +3094,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 ) |