diff options
Diffstat (limited to 'sc/source/core')
-rw-r--r-- | sc/source/core/data/columnspanset.cxx | 16 | ||||
-rw-r--r-- | sc/source/core/data/dociter.cxx | 19 | ||||
-rw-r--r-- | sc/source/core/data/documen3.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/data/documen8.cxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 9 | ||||
-rw-r--r-- | sc/source/core/data/fillinfo.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/table1.cxx | 44 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 79 | ||||
-rw-r--r-- | sc/source/core/data/table3.cxx | 7 | ||||
-rw-r--r-- | sc/source/core/data/table4.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/table5.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/data/table7.cxx | 10 |
12 files changed, 123 insertions, 78 deletions
diff --git a/sc/source/core/data/columnspanset.cxx b/sc/source/core/data/columnspanset.cxx index 1098ce30447e..89805a7824df 100644 --- a/sc/source/core/data/columnspanset.cxx +++ b/sc/source/core/data/columnspanset.cxx @@ -131,6 +131,7 @@ void ColumnSpanSet::scan( if (!pTab) return; + nCol2 = pTab->ClampToAllocatedColumns(nCol2); for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) { ColumnType& rCol = getColumn(nTab, nCol); @@ -181,7 +182,7 @@ void ColumnSpanSet::executeColumnAction(ScDocument& rDoc, ColumnAction& ac) cons continue; const TableType& rTab = *maTables[nTab]; - for (size_t nCol = 0; nCol < rTab.size(); ++nCol) + for (SCCOL nCol = 0; nCol < static_cast<SCCOL>(rTab.size()); ++nCol) { if (!rTab[nCol]) continue; @@ -190,7 +191,7 @@ void ColumnSpanSet::executeColumnAction(ScDocument& rDoc, ColumnAction& ac) cons if (!pTab) continue; - if (!ValidCol(nCol)) + if (!ValidCol(nCol) || nCol >= pTab->GetAllocatedColumnsCount()) { // End the loop. nCol = rTab.size(); @@ -357,12 +358,13 @@ void RangeColumnSpanSet::executeColumnAction(ScDocument& rDoc, sc::ColumnSpanSet { for (SCTAB nTab = range.aStart.Tab(); nTab <= range.aEnd.Tab(); ++nTab) { - for (SCCOL nCol = range.aStart.Col(); nCol <= range.aEnd.Col(); ++nCol) - { - ScTable* pTab = rDoc.FetchTable(nTab); - if (!pTab) - continue; + ScTable* pTab = rDoc.FetchTable(nTab); + if (!pTab) + continue; + SCCOL nEndCol = pTab->ClampToAllocatedColumns(range.aEnd.Col()); + for (SCCOL nCol = range.aStart.Col(); nCol <= nEndCol; ++nCol) + { if (!ValidCol(nCol)) break; diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index 6cd02b5c4a6e..174ff54c43e8 100644 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -166,7 +166,7 @@ bool ScValueIterator::GetThis(double& rValue, FormulaError& rErr) do { ++mnCol; - if (mnCol > maEndPos.Col()) + if (mnCol > maEndPos.Col() || mnCol >= pDoc->maTabs[mnTab]->GetAllocatedColumnsCount()) { mnCol = maStartPos.Col(); ++mnTab; @@ -829,6 +829,7 @@ ScCellIterator::ScCellIterator( ScDocument* pDoc, const ScRange& rRange, Subtota maEndPos(rRange.aEnd), mnSubTotalFlags(nSubTotalFlags) { + maEndPos.SetCol( pDoc->ClampToAllocatedColumns(maStartPos.Tab(), maEndPos.Col()) ); init(); } @@ -1922,7 +1923,9 @@ ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB if (mnTab >= pDoc->GetTableCount()) OSL_FAIL("try to access index out of bounds, FIX IT"); - maColPositions.reserve( nCol2-nCol1+1 ); + nEndCol = pDoc->maTabs[mnTab]->ClampToAllocatedColumns(nEndCol); + + maColPositions.reserve( nEndCol-nStartCol+1 ); SetTab( mnTab ); } @@ -2233,6 +2236,8 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB OSL_FAIL("try to access index out of bounds, FIX IT"); OSL_ENSURE( pDoc->maTabs[nTab], "Table does not exist" ); + nEndCol = pDoc->maTabs[nTab]->ClampToAllocatedColumns(nEndCol); + nRow = nStartRow; nCol = nStartCol; bRowEmpty = false; @@ -2482,8 +2487,12 @@ ScDocAttrIterator::ScDocAttrIterator(ScDocument* pDocument, SCTAB nTable, nEndRow( nRow2 ), nCol( nCol1 ) { - if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab] ) + if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab] + && nCol < pDoc->maTabs[nTab]->GetAllocatedColumnsCount()) + { + nEndCol = pDoc->maTabs[nTab]->ClampToAllocatedColumns(nEndCol); pColIter = pDoc->maTabs[nTab]->aCol[nCol].CreateAttrIterator( nStartRow, nEndRow ); + } } ScDocAttrIterator::~ScDocAttrIterator() @@ -2610,8 +2619,10 @@ ScAttrRectIterator::ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable, nIterStartCol( nCol1 ), nIterEndCol( nCol1 ) { - if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab] ) + if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab] + && nCol1 < pDoc->maTabs[nTab]->GetAllocatedColumnsCount()) { + nEndCol = pDoc->maTabs[nTab]->ClampToAllocatedColumns(nEndCol); pColIter = pDoc->maTabs[nTab]->aCol[nIterStartCol].CreateAttrIterator( nStartRow, nEndRow ); while ( nIterEndCol < nEndCol && pDoc->maTabs[nTab]->aCol[nIterEndCol].IsAllAttrEqual( diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index a0c0bcd0f040..75f1cdab071a 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -2098,4 +2098,9 @@ void ScDocument::SetSortParam( const ScSortParam& rParam, SCTAB nTab ) mSheetSortParams[ nTab ] = rParam; } +SCCOL ScDocument::ClampToAllocatedColumns(SCTAB nTab, SCCOL nCol) const +{ + return maTabs[nTab]->ClampToAllocatedColumns(nCol); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx index c90353bc207b..af0100f6dde4 100644 --- a/sc/source/core/data/documen8.cxx +++ b/sc/source/core/data/documen8.cxx @@ -578,6 +578,7 @@ bool ScDocument::IdleCalcTextWidth() // true = try next again sal_uInt16 nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE); Fraction aZoomFract(nZoom, 100); + aScope.setCol(pTab->ClampToAllocatedColumns(aScope.Col())); // Start at specified cell position (nCol, nRow, nTab). ScColumn* pCol = &pTab->aCol[aScope.Col()]; std::unique_ptr<ScColumnTextWidthIterator> pColIter(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW)); @@ -646,6 +647,8 @@ bool ScDocument::IdleCalcTextWidth() // true = try next again bNewTab = true; } + aScope.setCol(pTab->ClampToAllocatedColumns(aScope.Col())); + if ( nRestart < 2 ) { if ( bNewTab ) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 7538690cf625..a3df4639e94b 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -4720,7 +4720,8 @@ void ScDocument::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, S const SfxPoolItem* ScDocument::GetAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich ) const { - if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] ) + if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && + nCol < maTabs[nTab]->GetAllocatedColumnsCount()) { const SfxPoolItem* pTemp = maTabs[nTab]->GetAttr( nCol, nRow, nWhich ); if (pTemp) @@ -6511,7 +6512,8 @@ ScPostIt* ScDocument::GetNote(const ScAddress& rPos) ScPostIt* ScDocument::GetNote(SCCOL nCol, SCROW nRow, SCTAB nTab) { - if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size())) + if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && + nCol < maTabs[nTab]->GetAllocatedColumnsCount()) return maTabs[nTab]->aCol[nCol].GetCellNote(nRow); else return nullptr; @@ -6542,6 +6544,9 @@ bool ScDocument::HasNote(SCCOL nCol, SCROW nRow, SCTAB nTab) const if (!pTab) return false; + if (nCol >= pTab->GetAllocatedColumnsCount()) + return false; + const ScPostIt* pNote = pTab->aCol[nCol].GetCellNote(nRow); return pNote != nullptr; } diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx index ecdcfd6deb64..6c170200e8be 100644 --- a/sc/source/core/data/fillinfo.cxx +++ b/sc/source/core/data/fillinfo.cxx @@ -442,7 +442,7 @@ void ScDocument::FillInfo( { SCCOL nX = (nArrCol>0) ? nArrCol-1 : MAXCOL+1; // negative -> invalid - if ( ValidCol(nX) ) + if ( ValidCol(nX) && nX < maTabs[nTab]->GetAllocatedColumnsCount() ) { // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes // will disturb the output diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 6fb453807604..d964642bd498 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -237,7 +237,7 @@ bool SetOptimalHeightsToRows( ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName, bool bColInfo, bool bRowInfo ) : - aCol( MAXCOLCOUNT ), + aCol( INITIALCOLCOUNT ), aName( rNewName ), aCodeName( rNewName ), nLinkRefreshDelay( 0 ), @@ -1705,7 +1705,7 @@ void ScTable::UpdateReference( mpRangeName->UpdateReference(rCxt, nTab); for ( ; i<=iMax; i++) - bUpdated |= aCol[i].UpdateReference(rCxt, pUndoDoc); + bUpdated |= CreateColumnIfNotExists(i).UpdateReference(rCxt, pUndoDoc); if ( bIncludeDraw ) UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos ); @@ -2434,11 +2434,12 @@ void ScTable::FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, { size_t nMatCol = 0; for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nMatCol) - aCol[nCol].FillMatrix(rMat, nMatCol, nRow1, nRow2, pPool); + CreateColumnIfNotExists(nCol).FillMatrix(rMat, nMatCol, nRow1, nRow2, pPool); } void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) { + nCol2 = ClampToAllocatedColumns(nCol2); for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) aCol[nCol].InterpretDirtyCells(nRow1, nRow2); } @@ -2509,32 +2510,33 @@ const ScConditionalFormatList* ScTable::GetCondFormList() const ScColumnsRange ScTable::GetColumnsRange(SCCOL nColBegin, SCCOL nColEnd) const { - // Because the range is inclusive, some code will pass nColEnd<nColBegin to - // indicate an empty range. Ensure that we create only valid iterators for - // the range, limit columns to bounds. - SCCOL nEffBegin, nEffEnd; - if (nColBegin <= nColEnd) + ScColContainer::ScColumnVector::const_iterator beginIter; + ScColContainer::ScColumnVector::const_iterator endIter; + + // because the range is inclusive, some code will pass nColEnd<nColBegin to indicate an empty range + if (nColEnd < nColBegin) { - if (nColBegin < 0) - nEffBegin = 0; - else - nEffBegin = std::min<SCCOL>( nColBegin, aCol.size()); - if (nColEnd < 0) - nEffEnd = 0; - else - nEffEnd = std::min<SCCOL>( nColEnd + 1, aCol.size()); + beginIter = aCol.end(); + endIter = aCol.end(); + } + else if (nColBegin >= aCol.size()) + { + beginIter = aCol.end(); + endIter = aCol.end(); } else { - // Any empty will do. - nEffBegin = nEffEnd = 0; + // clamp end of range to available columns + if (nColEnd >= aCol.size()) + nColEnd = aCol.size() - 1; + beginIter = aCol.begin() + nColBegin; + endIter = aCol.begin() + nColEnd + 1; } - return ScColumnsRange( ScColumnsRange::Iterator( aCol.begin() + nEffBegin), - ScColumnsRange::Iterator( aCol.begin() + nEffEnd)); + return ScColumnsRange(ScColumnsRange::Iterator(beginIter), ScColumnsRange::Iterator(endIter)); } // out-of-line the cold part of the CreateColumnIfNotExists function -void ScTable::CreateColumnIfNotExistsImpl( const SCCOL nScCol ) +void ScTable::CreateColumnIfNotExistsImpl( const SCCOL nScCol ) const { const SCCOL aOldColSize = aCol.size(); aCol.resize( static_cast< size_t >( nScCol + 1 ) ); diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index bc2293f3bd9c..a74fc3a9a289 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -136,7 +136,7 @@ bool ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SC bTest = pOutlineTable->TestInsertRow(nSize); for (SCCOL i=nStartCol; (i<=nEndCol) && bTest; i++) - bTest = aCol[i].TestInsertRow(nStartRow, nSize); + bTest = CreateColumnIfNotExists(i).TestInsertRow(nStartRow, nSize); return bTest; } @@ -487,10 +487,10 @@ void ScTable::CopyToClip( if (!pTable->mpRangeName && mpRangeName) pTable->mpRangeName.reset( new ScRangeName(*mpRangeName) ); - SCCOL i; + nCol2 = ClampToAllocatedColumns(nCol2); - for ( i = nCol1; i <= nCol2; i++) - aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->aCol[i]); // notes are handled at column level + for ( SCCOL i = nCol1; i <= nCol2; i++) + aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->CreateColumnIfNotExists(i)); // notes are handled at column level // copy widths/heights, and only "hidden", "filtered" and "manual" flags // also for all preceding columns/rows, to have valid positions for drawing objects @@ -515,7 +515,7 @@ void ScTable::CopyToClip( // If necessary replace formulas with values if ( IsProtected() ) - for (i = nCol1; i <= nCol2; i++) + for (SCCOL i = nCol1; i <= nCol2; i++) pTable->aCol[i].RemoveProtected(nRow1, nRow2); pTable->mpCondFormatList.reset(new ScConditionalFormatList(pTable->pDocument, *mpCondFormatList)); @@ -665,7 +665,7 @@ bool ScTable::InitColumnBlockPosition( sc::ColumnBlockPosition& rBlockPos, SCCOL if (!ValidCol(nCol)) return false; - aCol[nCol].InitBlockPosition(rBlockPos); + CreateColumnIfNotExists(nCol).InitBlockPosition(rBlockPos); return true; } @@ -681,7 +681,10 @@ void ScTable::CopyFromClip( if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2)) { for ( SCCOL i = nCol1; i <= nCol2; i++) + { + pTable->CreateColumnIfNotExists(i - nDx); aCol[i].CopyFromClip(rCxt, nRow1, nRow2, nDy, pTable->aCol[i - nDx]); // notes are handles at column level + } if (rCxt.getInsertFlag() & InsertDeleteFlags::ATTRIB) { @@ -1043,7 +1046,7 @@ ScColumn* ScTable::FetchColumn( SCCOL nCol ) if (!ValidCol(nCol)) return nullptr; - return &aCol[nCol]; + return &CreateColumnIfNotExists(nCol); } const ScColumn* ScTable::FetchColumn( SCCOL nCol ) const @@ -1124,9 +1127,9 @@ void ScTable::CopyToTable( { InsertDeleteFlags nTempFlags( nFlags & ~InsertDeleteFlags( InsertDeleteFlags::NOTE | InsertDeleteFlags::ADDNOTES)); - for (SCCOL i = nCol1; i <= nCol2; i++) + for (SCCOL i = nCol1; i <= ClampToAllocatedColumns(nCol2); i++) aCol[i].CopyToColumn(rCxt, nRow1, nRow2, bIsUndoDoc ? nFlags : nTempFlags, bMarked, - pDestTab->aCol[i], pMarkData, bAsLink, bGlobalNamesToLocal); + pDestTab->CreateColumnIfNotExists(i), pMarkData, bAsLink, bGlobalNamesToLocal); } if (!bColRowFlags) // Column widths/Row heights/Flags @@ -1253,9 +1256,10 @@ void ScTable::CopyCaptionsToTable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2)) return; + nCol2 = ClampToAllocatedColumns(nCol2); for (SCCOL i = nCol1; i <= nCol2; i++) { - aCol[i].CopyCellNotesToDocument(nRow1, nRow2, pDestTab->aCol[i], bCloneCaption); + aCol[i].CopyCellNotesToDocument(nRow1, nRow2, pDestTab->CreateColumnIfNotExists(i), bCloneCaption); pDestTab->aCol[i].UpdateNoteCaptions(nRow1, nRow2); } } @@ -1298,6 +1302,8 @@ void ScTable::UndoToTable( void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const { + pPosTab->CreateColumnIfNotExists(aCol.size()-1); + pDestTab->CreateColumnIfNotExists(aCol.size()-1); for (SCCOL i=0; i < aCol.size(); i++) aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] ); } @@ -1317,14 +1323,16 @@ void ScTable::CopyScenarioTo( ScTable* pDestTab ) const OSL_ENSURE( bScenario, "bScenario == FALSE" ); for (SCCOL i=0; i < aCol.size(); i++) - aCol[i].CopyScenarioTo( pDestTab->aCol[i] ); + aCol[i].CopyScenarioTo( pDestTab->CreateColumnIfNotExists(i) ); } void ScTable::CopyScenarioFrom( const ScTable* pSrcTab ) { OSL_ENSURE( bScenario, "bScenario == FALSE" ); - for (SCCOL i=0; i < aCol.size(); i++) + SCCOL nEndCol = pSrcTab->aCol.size(); + CreateColumnIfNotExists(nEndCol); + for (SCCOL i=0; i < nEndCol; i++) aCol[i].CopyScenarioFrom( pSrcTab->aCol[i] ); } @@ -1411,7 +1419,7 @@ bool ScTable::SetEditText( SCCOL nCol, SCROW nRow, std::unique_ptr<EditTextObjec return false; } - aCol[nCol].SetEditText(nRow, std::move(pEditText)); + CreateColumnIfNotExists(nCol).SetEditText(nRow, std::move(pEditText)); return true; } @@ -1472,7 +1480,7 @@ void ScTable::SetFormula( if (!ValidColRow(nCol, nRow)) return; - aCol[nCol].SetFormula(nRow, rFormula, eGram); + CreateColumnIfNotExists(nCol).SetFormula(nRow, rFormula, eGram); } ScFormulaCell* ScTable::SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell ) @@ -1516,7 +1524,7 @@ void ScTable::SetRawString( SCCOL nCol, SCROW nRow, const svl::SharedString& rSt void ScTable::GetString( SCCOL nCol, SCROW nRow, OUString& rString, const ScInterpreterContext* pContext ) const { - if (ValidColRow(nCol,nRow)) + if (ValidColRow(nCol,nRow) && nCol < GetAllocatedColumnsCount()) aCol[nCol].GetString( nRow, rString, pContext ); else rString.clear(); @@ -1581,8 +1589,7 @@ ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, SCROW nRow ) { if (!ValidColRow(nCol, nRow)) return nullptr; - - return aCol[nCol].GetFormulaCell(nRow); + return CreateColumnIfNotExists(nCol).GetFormulaCell(nRow); } std::unique_ptr<ScPostIt> ScTable::ReleaseNote( SCCOL nCol, SCROW nRow ) @@ -1793,6 +1800,7 @@ void ScTable::SetDirty( const ScRange& rRange, ScColumn::BroadcastMode eMode ) bool bOldAutoCalc = pDocument->GetAutoCalc(); pDocument->SetAutoCalc( false ); // avoid multiple recalculations SCCOL nCol2 = rRange.aEnd.Col(); + nCol2 = ClampToAllocatedColumns(nCol2); for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++) aCol[i].SetDirty(rRange.aStart.Row(), rRange.aEnd.Row(), eMode); pDocument->SetAutoCalc( bOldAutoCalc ); @@ -1913,7 +1921,7 @@ void ScTable::ResetChanged( const ScRange& rRange ) { SCCOL nStartCol = rRange.aStart.Col(); SCROW nStartRow = rRange.aStart.Row(); - SCCOL nEndCol = rRange.aEnd.Col(); + SCCOL nEndCol = ClampToAllocatedColumns(rRange.aEnd.Col()); SCROW nEndRow = rRange.aEnd.Row(); for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++) @@ -1964,7 +1972,7 @@ void ScTable::SetNumberFormat( SCCOL nCol, SCROW nRow, sal_uInt32 nNumberFormat const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const { if (ValidColRow(nCol,nRow)) - return aCol[nCol].GetPattern( nRow ); + return CreateColumnIfNotExists(nCol).GetPattern( nRow ); else { OSL_FAIL("wrong column or row"); @@ -1974,7 +1982,8 @@ const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const { - if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow) ) + if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow) + && nCol < GetAllocatedColumnsCount()) return aCol[nCol].GetMostUsedPattern( nStartRow, nEndRow ); else return nullptr; @@ -2052,6 +2061,7 @@ bool ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, OSL_FAIL("ScTable::IsBlockEmpty: invalid column number"); return false; } + nCol2 = ClampToAllocatedColumns(nCol2); bool bEmpty = true; for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++) { @@ -2300,7 +2310,8 @@ bool ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const for (sc::ColRowSpan & aSpan : aSpans) { - for ( SCCOLROW j=aSpan.mnStart; j<=aSpan.mnEnd; j++ ) + SCCOL nEndCol = ClampToAllocatedColumns(aSpan.mnEnd); + for ( SCCOLROW j=aSpan.mnStart; j<=nEndCol; j++ ) { if ( aCol[j].HasSelectionMatrixFragment(rMark) ) return true; @@ -2319,6 +2330,8 @@ bool ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, *pOnlyNotBecauseOfMatrix = false; return false; } + nCol1 = ClampToAllocatedColumns(nCol1); + nCol2 = ClampToAllocatedColumns(nCol2); bool bIsEditable = true; if ( nLockCount ) @@ -2495,7 +2508,8 @@ void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkDa for (const sc::ColRowSpan & rSpan : aSpans) { - for (SCCOLROW i = rSpan.mnStart; i <= rSpan.mnEnd; ++i) + SCCOL nEnd = ClampToAllocatedColumns(rSpan.mnEnd); + for (SCCOLROW i = rSpan.mnStart; i <= nEnd; ++i) { aCol[i].MergeSelectionPattern( rState, rMark, bDeep ); } @@ -2505,6 +2519,7 @@ void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkDa void ScTable::MergePatternArea( ScMergePatternState& rState, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bDeep ) const { + nCol2 = ClampToAllocatedColumns(nCol2); for (SCCOL i=nCol1; i<=nCol2; i++) aCol[i].MergePatternArea( rState, nRow1, nRow2, bDeep ); } @@ -2550,7 +2565,7 @@ void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, PutInOrder(nStartCol, nEndCol); PutInOrder(nStartRow, nEndRow); for (SCCOL i = nStartCol; i <= nEndCol; i++) - aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray, pIsChanged); + CreateColumnIfNotExists(i).ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray, pIsChanged); } } @@ -2576,7 +2591,7 @@ void ScTable::AddCondFormatData( const ScRangeList& rRangeList, sal_uInt32 nInde SCROW nRowEnd = rRange.aEnd.Row(); for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) { - aCol[nCol].AddCondFormat(nRowStart, nRowEnd, nIndex); + CreateColumnIfNotExists(nCol).AddCondFormat(nRowStart, nRowEnd, nIndex); } } } @@ -2588,7 +2603,7 @@ void ScTable::RemoveCondFormatData( const ScRangeList& rRangeList, sal_uInt32 nI { const ScRange & rRange = rRangeList[i]; SCCOL nColStart = rRange.aStart.Col(); - SCCOL nColEnd = rRange.aEnd.Col(); + SCCOL nColEnd = ClampToAllocatedColumns(rRange.aEnd.Col()); SCROW nRowStart = rRange.aStart.Row(); SCROW nRowEnd = rRange.aEnd.Row(); for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) @@ -2698,7 +2713,7 @@ const ScStyleSheet* ScTable::GetAreaStyle( bool& rFound, SCCOL nCol1, SCROW nRow const ScStyleSheet* pStyle = nullptr; const ScStyleSheet* pNewStyle; - + nCol2 = ClampToAllocatedColumns(nCol2); for (SCCOL i=nCol1; i<=nCol2 && bEqual; i++) { pNewStyle = aCol[i].GetAreaStyle(bColFound, nRow1, nRow2); @@ -2761,17 +2776,19 @@ bool ScTable::ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW bool bChanged = false; if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow)) for (SCCOL i = nStartCol; i <= nEndCol; i++) - bChanged |= aCol[i].ApplyFlags(nStartRow, nEndRow, nFlags); + bChanged |= CreateColumnIfNotExists(i).ApplyFlags(nStartRow, nEndRow, nFlags); return bChanged; } bool ScTable::RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScMF nFlags ) { + if (!ValidColRow(nStartCol, nStartRow) || !ValidColRow(nEndCol, nEndRow)) + return false; bool bChanged = false; - if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow)) - for (SCCOL i = nStartCol; i <= nEndCol; i++) - bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags); + nEndCol = ClampToAllocatedColumns(nEndCol); + for (SCCOL i = nStartCol; i <= nEndCol; i++) + bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags); return bChanged; } @@ -2784,7 +2801,7 @@ void ScTable::SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr ) void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr ) { if (ValidColRow(nCol,nRow)) - aCol[nCol].ApplyAttr( nRow, rAttr ); + CreateColumnIfNotExists(nCol).ApplyAttr( nRow, rAttr ); } void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 4e9f074470ae..819bfa6f87db 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -17,7 +17,6 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include <rtl/math.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/random.hxx> #include <unotools/textsearch.hxx> @@ -1825,7 +1824,7 @@ bool ScTable::TestRemoveSubTotals( const ScSubTotalParam& rParam ) { SCCOL nStartCol = rParam.nCol1; SCROW nStartRow = rParam.nRow1 + 1; // Header - SCCOL nEndCol = rParam.nCol2; + SCCOL nEndCol = ClampToAllocatedColumns(rParam.nCol2); SCROW nEndRow = rParam.nRow2; for (SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol) @@ -1859,7 +1858,7 @@ void ScTable::RemoveSubTotals( ScSubTotalParam& rParam ) { SCCOL nStartCol = rParam.nCol1; SCROW nStartRow = rParam.nRow1 + 1; // Header - SCCOL nEndCol = rParam.nCol2; + SCCOL nEndCol = ClampToAllocatedColumns(rParam.nCol2); SCROW nEndRow = rParam.nRow2; // will change RemoveSubTotalsHandler aFunc; @@ -3541,7 +3540,7 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData, const ScMarkData& aMarkArea.aEnd.SetCol(MAXCOL); } const SCCOL nStartCol = aMarkArea.aStart.Col(); - const SCCOL nEndCol = aMarkArea.aEnd.Col(); + const SCCOL nEndCol = ClampToAllocatedColumns(aMarkArea.aEnd.Col()); for (SCCOL nCol = nStartCol; nCol <= nEndCol && !rData.getError(); ++nCol) { if (mpColFlags && ColHidden(nCol)) diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx index 91201f0efbe7..41754592410c 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -1638,6 +1638,8 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, { rInner = nISource; + CreateColumnIfNotExists(nCol); + // Source cell value. We need to clone the value since it may be inserted repeatedly. ScCellValue aSrcCell = aCol[nCol].GetCellValue(static_cast<SCROW>(nRow)); diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx index 4d3c99f86899..5a50a7cfcdcc 100644 --- a/sc/source/core/data/table5.cxx +++ b/sc/source/core/data/table5.cxx @@ -1082,7 +1082,7 @@ void ScTable::StartListening( const ScAddress& rAddress, SvtListener* pListener if (!ValidCol(rAddress.Col())) return; - aCol[rAddress.Col()].StartListening( *pListener, rAddress.Row() ); + CreateColumnIfNotExists(rAddress.Col()).StartListening( *pListener, rAddress.Row() ); } void ScTable::EndListening( const ScAddress& rAddress, SvtListener* pListener ) @@ -1090,7 +1090,8 @@ void ScTable::EndListening( const ScAddress& rAddress, SvtListener* pListener ) if (!ValidCol(rAddress.Col())) return; - aCol[rAddress.Col()].EndListening( *pListener, rAddress.Row() ); + if (rAddress.Col() < aCol.size()) + aCol[rAddress.Col()].EndListening( *pListener, rAddress.Row() ); } void ScTable::StartListening( sc::StartListeningContext& rCxt, const ScAddress& rAddress, SvtListener& rListener ) diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx index 30f869a58733..e0ed0c96bce6 100644 --- a/sc/source/core/data/table7.cxx +++ b/sc/source/core/data/table7.cxx @@ -21,7 +21,7 @@ bool ScTable::IsMerged( SCCOL nCol, SCROW nRow ) const { - if (!ValidCol(nCol)) + if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount() ) return false; return aCol[nCol].IsMerged(nRow); @@ -128,7 +128,7 @@ void ScTable::CopyOneCellFromClip( SCCOL nColOffset = nCol - nCol1; nColOffset = nColOffset % nSrcColSize; assert(nColOffset >= 0); - aCol[nCol].CopyOneCellFromClip(rCxt, nRow1, nRow2, nColOffset); + CreateColumnIfNotExists(nCol).CopyOneCellFromClip(rCxt, nRow1, nRow2, nColOffset); if (rCxt.getInsertFlag() & InsertDeleteFlags::ATTRIB) { @@ -318,9 +318,7 @@ void ScTable::EndListeningIntersectedGroups( if (nCol2 < nCol1 || !IsColValid(nCol1) || !ValidCol(nCol2)) return; - const SCCOL nMaxCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 ); - - for (SCCOL nCol = nCol1; nCol <= nMaxCol2; ++nCol) + for (SCCOL nCol : GetColumnsRange(nCol1, nCol2)) aCol[nCol].EndListeningIntersectedGroups(rCxt, nRow1, nRow2, pGroupPos); } @@ -345,7 +343,7 @@ bool ScTable::IsEditActionAllowed( { if (!IsProtected()) { - SCCOL nCol1 = 0, nCol2 = MAXCOL; + SCCOL nCol1 = 0, nCol2 = aCol.size() - 1; SCROW nRow1 = 0, nRow2 = MAXROW; switch (eAction) |