diff options
-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 ) |