Kaydet (Commit) 2c92a92e authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Prevent crash during on-line spell checking.

The new ScHorizontalCellIterator internally uses iterators for each
column to track positions. This means that, if a cell value in the iteration
range chnages while the iteration is on-going, those internal iterators
get invalidated. Allow the client code to rehash the iterators when modifying
a cell content during iteration.

Having said that, it's best not to modify cells during iteration.

Change-Id: Ida453d4f883e1fbcbab4eb0401e37fea8c0b901d
üst cf021519
...@@ -441,6 +441,13 @@ public: ...@@ -441,6 +441,13 @@ public:
/// Set a(nother) sheet and (re)init. /// Set a(nother) sheet and (re)init.
void SetTab( SCTAB nTab ); void SetTab( SCTAB nTab );
/**
* When modifying a cell while still in iteration, call this to re-fetch
* the column iterators used internally because the old iterators have
* been invalidated.
*/
void RehashCol( SCCOL nCol );
private: private:
void Advance(); void Advance();
}; };
......
...@@ -1681,7 +1681,7 @@ ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB ...@@ -1681,7 +1681,7 @@ ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB
nEndRow( nRow2 ), nEndRow( nRow2 ),
mnCol( nCol1 ), mnCol( nCol1 ),
mnRow( nRow1 ), mnRow( nRow1 ),
bMore( true ) bMore(false)
{ {
if (mnTab >= pDoc->GetTableCount()) if (mnTab >= pDoc->GetTableCount())
OSL_FAIL("try to access index out of bounds, FIX IT"); OSL_FAIL("try to access index out of bounds, FIX IT");
...@@ -1700,24 +1700,42 @@ ScHorizontalCellIterator::~ScHorizontalCellIterator() ...@@ -1700,24 +1700,42 @@ ScHorizontalCellIterator::~ScHorizontalCellIterator()
void ScHorizontalCellIterator::SetTab( SCTAB nTabP ) void ScHorizontalCellIterator::SetTab( SCTAB nTabP )
{ {
bMore = false;
mnTab = nTabP; mnTab = nTabP;
mnRow = nStartRow; mnRow = nStartRow;
mnCol = nStartCol; mnCol = nStartCol;
bMore = true;
// Set the start position in each column. // Set the start position in each column.
for (SCCOL i = nStartCol; i <= nEndCol; ++i) for (SCCOL i = nStartCol; i <= nEndCol; ++i)
{ {
ScColumn* pCol = &pDoc->maTabs[mnTab]->aCol[i]; ScColumn* pCol = &pDoc->maTabs[mnTab]->aCol[i];
maColPositions[i-nStartCol].maPos = pCol->maCells.position(nStartRow).first; ColParam& rParam = maColPositions[i-nStartCol];
maColPositions[i-nStartCol].maEnd = pCol->maCells.end(); rParam.maPos = pCol->maCells.position(nStartRow).first;
rParam.maEnd = pCol->maCells.end();
if (rParam.maPos != rParam.maEnd)
bMore = true;
} }
if (maColPositions[0].maPos->type == sc::element_type_empty) if (!bMore)
return;
ColParam& rParam = maColPositions[0];
if (rParam.maPos == rParam.maEnd || rParam.maPos->type == sc::element_type_empty)
// Skip to the first non-empty cell. // Skip to the first non-empty cell.
Advance(); Advance();
} }
void ScHorizontalCellIterator::RehashCol( SCCOL nCol )
{
if (nCol < nStartCol || nEndCol < nCol)
return;
ColParam& rParam = maColPositions[nCol-nStartCol];
ScColumn& rCol = pDoc->maTabs[mnTab]->aCol[nCol];
rParam.maPos = rCol.maCells.position(mnRow).first;
rParam.maEnd = rCol.maCells.end();
}
ScRefCellValue* ScHorizontalCellIterator::GetNext( SCCOL& rCol, SCROW& rRow ) ScRefCellValue* ScHorizontalCellIterator::GetNext( SCCOL& rCol, SCROW& rRow )
{ {
if (!bMore) if (!bMore)
......
...@@ -827,12 +827,14 @@ bool ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe ...@@ -827,12 +827,14 @@ bool ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe
{ {
// The cell will take ownership of pNewData. // The cell will take ownership of pNewData.
SetEditText(ScAddress(nCol,nRow,nTab), pEngine->CreateTextObject()); SetEditText(ScAddress(nCol,nRow,nTab), pEngine->CreateTextObject());
aIter.RehashCol(nCol);
} }
else else
{ {
ScSetStringParam aParam; ScSetStringParam aParam;
aParam.setTextInput(); aParam.setTextInput();
SetString(ScAddress(nCol,nRow,nTab), pEngine->GetText(), &aParam); SetString(ScAddress(nCol,nRow,nTab), pEngine->GetText(), &aParam);
aIter.RehashCol(nCol);
} }
// Paint // Paint
......
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