Kaydet (Commit) 7282014e authored tarafından Noel Grandin's avatar Noel Grandin Kaydeden (comit) Mike Kaganski

tdf#50916 Makes numbers of columns dynamic.

With this commit we are making numbers of columns
dynamic, but the number of maximum supported
columns will be the same (1024).
Such approach will allow us to check issues
(eg. performance, LO format etc.), and improve it.

Increasing number of maximum columns, will be done
in separate commit.

Change-Id: Ibac4101e9ffc05e3548eca1c198f6319ac7ff9aa
Reviewed-on: https://gerrit.libreoffice.org/44802
Tested-by: Jenkins
Reviewed-by: 's avatarBartosz Kosiorek <gang65@poczta.onet.pl>
üst df30a451
......@@ -67,6 +67,7 @@ const SCSIZE SCSIZE_MAX = ::std::numeric_limits<SCSIZE>::max();
// Count values
const SCROW MAXROWCOUNT = MAXROWCOUNT_DEFINE;
const SCCOL MAXCOLCOUNT = MAXCOLCOUNT_DEFINE;
const SCCOL INITIALCOLCOUNT = 64;
/// limiting to 10000 for now, problem with 32 bit builds for now
const SCTAB MAXTABCOUNT = 10000;
const SCCOLROW MAXCOLROWCOUNT = MAXROWCOUNT;
......
......@@ -28,10 +28,9 @@
class ScColContainer
{
public:
typedef std::vector<std::unique_ptr<ScColumn>> ScColumnVector;
ScColumnVector aCols;
public:
ScColContainer( const size_t nSize );
~ScColContainer() COVERITY_NOEXCEPT_FALSE;
......@@ -73,6 +72,9 @@ public:
ScColumnVector::const_iterator begin() const { return aCols.begin(); }
ScColumnVector::const_iterator end() const { return aCols.end(); }
private:
ScColumnVector aCols;
};
......
......@@ -370,7 +370,7 @@ class ScDocAttrIterator // all attribute areas
private:
ScDocument* pDoc;
SCTAB nTab;
SCCOL const nEndCol;
SCCOL nEndCol;
SCROW const nStartRow;
SCROW const nEndRow;
SCCOL nCol;
......@@ -391,7 +391,7 @@ class ScAttrRectIterator // all attribute areas, including areas stre
private:
ScDocument* pDoc;
SCTAB nTab;
SCCOL const nEndCol;
SCCOL nEndCol;
SCROW const nStartRow;
SCROW const nEndRow;
SCCOL nIterStartCol;
......@@ -423,7 +423,7 @@ class ScHorizontalCellIterator // walk through all non empty cells in an ar
ScDocument* pDoc;
SCTAB mnTab;
SCCOL const nStartCol;
SCCOL const nEndCol;
SCCOL nEndCol;
SCROW const nStartRow;
SCROW const nEndRow;
SCCOL mnCol;
......@@ -482,7 +482,7 @@ private:
SCTAB nTab;
SCCOL const nStartCol;
SCROW const nStartRow;
SCCOL const nEndCol;
SCCOL nEndCol;
SCROW const nEndRow;
std::unique_ptr<SCROW[]> pNextEnd;
......
......@@ -786,6 +786,8 @@ public:
ScRangePairListRef& GetColNameRangesRef() { return xColNameRanges; }
ScRangePairListRef& GetRowNameRangesRef() { return xRowNameRanges; }
SC_DLLPUBLIC SCCOL ClampToAllocatedColumns(SCTAB nTab, SCCOL nCol) const;
SC_DLLPUBLIC ScDBCollection* GetDBCollection() const { return pDBCollection.get();}
void SetDBCollection( std::unique_ptr<ScDBCollection> pNewDBCollection,
bool bRemoveAutoFilter = false );
......
......@@ -20,6 +20,7 @@
#ifndef INCLUDED_SC_INC_TABLE_HXX
#define INCLUDED_SC_INC_TABLE_HXX
#include <algorithm>
#include <vector>
#include <tools/gen.hxx>
#include <tools/color.hxx>
......@@ -151,7 +152,7 @@ class ScTable
private:
typedef ::std::vector< ScRange > ScRangeVec;
ScColContainer aCol;
mutable ScColContainer aCol;
OUString aName;
OUString aCodeName;
......@@ -273,14 +274,14 @@ public:
ScOutlineTable* GetOutlineTable() { return pOutlineTable.get(); }
ScColumn& CreateColumnIfNotExists( const SCCOL nScCol )
ScColumn& CreateColumnIfNotExists( const SCCOL nScCol ) const
{
if ( nScCol >= aCol.size() )
CreateColumnIfNotExistsImpl(nScCol);
return aCol[nScCol];
}
// out-of-line the cold part of the function
void CreateColumnIfNotExistsImpl( const SCCOL nScCol );
void CreateColumnIfNotExistsImpl( const SCCOL nScCol ) const;
sal_uLong GetCellCount() const;
sal_uLong GetWeightedCount() const;
sal_uLong GetWeightedCount(SCROW nStartRow, SCROW nEndRow) const;
......@@ -443,9 +444,11 @@ public:
CellType GetCellType( const ScAddress& rPos ) const
{
return ValidColRow(rPos.Col(),rPos.Row()) ?
aCol[rPos.Col()].GetCellType( rPos.Row() ) :
CELLTYPE_NONE;
if (!ValidColRow(rPos.Col(),rPos.Row()))
return CELLTYPE_NONE;
if (rPos.Col() >= aCol.size())
return CELLTYPE_NONE;
return aCol[rPos.Col()].GetCellType( rPos.Row() );
}
CellType GetCellType( SCCOL nCol, SCROW nRow ) const;
ScRefCellValue GetCellValue( SCCOL nCol, SCROW nRow ) const;
......@@ -1072,6 +1075,8 @@ public:
static void UpdateSearchItemAddressForReplace( const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow );
ScColumnsRange GetColumnsRange(SCCOL begin, SCCOL end) const;
SCCOL ClampToAllocatedColumns(SCCOL nCol) const { return std::min(nCol, static_cast<SCCOL>(aCol.size() - 1)); }
SCCOL GetAllocatedColumnsCount() const { return aCol.size(); }
private:
......
......@@ -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;
......
......@@ -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(
......
......@@ -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: */
......@@ -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 )
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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 ) );
......
This diff is collapsed.
......@@ -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))
......
......@@ -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));
......
......@@ -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 )
......
......@@ -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)
......
......@@ -340,7 +340,7 @@ void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
if ( bSortByRows )
{
OUString aFieldName;
SCCOL nMaxCol = aSortData.nCol2;
SCCOL nMaxCol = pDoc->ClampToAllocatedColumns(nTab, aSortData.nCol2);
SCCOL col;
for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS; col++ )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment