summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/markmulti.hxx3
-rw-r--r--sc/qa/unit/uicalc/uicalc.cxx41
-rw-r--r--sc/source/core/data/markmulti.cxx19
-rw-r--r--sc/source/core/data/table2.cxx43
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 )