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>
This commit is contained in:
Luboš Luňák
2022-03-04 16:41:58 +01:00
parent 4015c18130
commit 3db91487e5
4 changed files with 99 additions and 7 deletions
+3
View File
@@ -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;
+41
View File
@@ -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: */
+19
View File
@@ -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() )
+36 -7
View File
@@ -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 )