summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kyoshida@novell.com>2011-03-08 10:55:13 +0100
committerPetr Mladek <pmladek@suse.cz>2011-03-08 10:55:13 +0100
commit1eecd1b23e0501bf8ddb2f48c79640bf6be9703d (patch)
tree5f22968a971a3f3519270e0cc104bfd04394206e
parent65e3078cc47d5ba85039d14a30ebf2933ca9f417 (diff)
Properly invalidate cached sheet XML streams during reference update.
Failure to invalidate sheet streams during reference update caused formula cross referenceing between sheets to totallly get borked. The bug was originally reported in i#116833. Signed off by Petr Mladek <pmladek@suse.cz>
-rw-r--r--sc/inc/cell.hxx2
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/source/core/data/cell2.cxx11
-rw-r--r--sc/source/core/data/column.cxx13
-rw-r--r--sc/source/core/data/table1.cxx8
-rw-r--r--sc/source/core/data/table2.cxx32
6 files changed, 57 insertions, 11 deletions
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index ba480b83cf58..56205c5b8f9a 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -440,7 +440,7 @@ public:
BOOL HasRelNameReference() const;
BOOL HasColRowName() const;
- void UpdateReference(UpdateRefMode eUpdateRefMode,
+ bool UpdateReference(UpdateRefMode eUpdateRefMode,
const ScRange& r,
SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
ScDocument* pUndoDoc = NULL,
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 2600ee149d3f..bf8706267c98 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -286,7 +286,7 @@ public:
void ResetChanged( SCROW nStartRow, SCROW nEndRow );
- void UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ bool UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
ScDocument* pUndoDoc = NULL );
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 4e1823b97b6a..bf57bb10024e 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -829,11 +829,13 @@ BOOL ScFormulaCell::HasColRowName() const
return (pCode->GetNextColRowName() != NULL);
}
-void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
+bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
const ScRange& r,
SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
{
+ bool bCellStateChanged = false;
+
SCCOL nCol1 = r.aStart.Col();
SCROW nRow1 = r.aStart.Row();
SCTAB nTab1 = r.aStart.Tab();
@@ -862,6 +864,7 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
nCol = 0;
else if ( nCol > MAXCOL )
nCol = MAXCOL;
+ bCellStateChanged = aPos.Col() != nCol;
aPos.SetCol( nCol );
// bPosChanged = TRUE;
}
@@ -876,6 +879,7 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
nRow = 0;
else if ( nRow > MAXROW )
nRow = MAXROW;
+ bCellStateChanged = aPos.Row() != nRow;
aPos.SetRow( nRow );
// bPosChanged = TRUE;
}
@@ -891,6 +895,7 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
nTab = 0;
else if ( nTab > nMaxTab )
nTab = nMaxTab;
+ bCellStateChanged = aPos.Tab() != nTab;
aPos.SetTab( nTab );
// bPosChanged = TRUE;
}
@@ -940,6 +945,9 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
bRangeModified = FALSE;
bRefSizeChanged = FALSE;
}
+
+ bCellStateChanged |= bValChanged;
+
if ( bOnRefMove )
bOnRefMove = (bValChanged || (aPos != aOldPos));
// Cell may reference itself, e.g. ocColumn, ocRow without parameter
@@ -1126,6 +1134,7 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
delete pOld;
}
+ return bCellStateChanged;
}
void ScFormulaCell::UpdateInsertTab(SCTAB nTable)
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 27dce7c8f414..6a542539f9d3 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1622,10 +1622,11 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
}
-void ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+bool ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
ScDocument* pUndoDoc )
{
+ bool bUpdated = false;
if (pItems)
{
ScRange aRange( ScAddress( nCol1, nRow1, nTab1 ),
@@ -1637,7 +1638,8 @@ void ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
{
ScFormulaCell* pCell = (ScFormulaCell*) pItems[nIndex].pCell;
if( pCell->GetCellType() == CELLTYPE_FORMULA)
- pCell->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
+ bUpdated |= pCell->UpdateReference(
+ eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
}
}
else
@@ -1658,7 +1660,8 @@ void ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
ScBaseCell* pCell = pItems[i].pCell;
if( pCell->GetCellType() == CELLTYPE_FORMULA)
{
- ((ScFormulaCell*)pCell)->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
+ bUpdated |= ((ScFormulaCell*)pCell)->UpdateReference(
+ eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
if ( nRow != pItems[i].nRow )
Search( nRow, i ); // Listener removed/inserted?
}
@@ -1676,7 +1679,8 @@ void ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
// When deleting rows on several sheets, the formula's position may be updated with the first call,
// so the undo position must be passed from here.
ScAddress aUndoPos( nCol, nRow, nTab );
- ((ScFormulaCell*)pCell)->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc, &aUndoPos );
+ bUpdated |= ((ScFormulaCell*)pCell)->UpdateReference(
+ eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc, &aUndoPos );
if ( nRow != pItems[i].nRow )
Search( nRow, i ); // Listener removed/inserted?
}
@@ -1684,6 +1688,7 @@ void ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
}
}
}
+ return bUpdated;
}
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index d4dd2026a019..1c7eec428f53 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -1288,6 +1288,7 @@ void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
ScDocument* pUndoDoc, BOOL bIncludeDraw, bool bUpdateNoteCaptionPos )
{
+ bool bUpdated = false;
SCCOL i;
SCCOL iMax;
if ( eUpdateRefMode == URM_COPY )
@@ -1301,8 +1302,8 @@ void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
iMax = MAXCOL;
}
for ( ; i<=iMax; i++)
- aCol[i].UpdateReference( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
- nDx, nDy, nDz, pUndoDoc );
+ bUpdated |= aCol[i].UpdateReference(
+ eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, pUndoDoc );
if ( bIncludeDraw )
UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
@@ -1387,6 +1388,9 @@ void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
PAINT_GRID ) );
}
}
+
+ if (bUpdated && IsStreamValid())
+ SetStreamValid(false);
}
void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index bb4fbb0f4d85..afcb88a12cc2 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -179,6 +179,11 @@ void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE
DecRecalcLevel( false );
InvalidatePageBreaks();
+
+ if (IsStreamValid())
+ // TODO: In the future we may want to check if the table has been
+ // really modified before setting the stream invalid.
+ SetStreamValid(false);
}
@@ -224,6 +229,11 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE
DecRecalcLevel();
InvalidatePageBreaks();
+
+ if (IsStreamValid())
+ // TODO: In the future we may want to check if the table has been
+ // really modified before setting the stream invalid.
+ SetStreamValid(false);
}
@@ -311,6 +321,11 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
DecRecalcLevel();
InvalidatePageBreaks();
+
+ if (IsStreamValid())
+ // TODO: In the future we may want to check if the table has been
+ // really modified before setting the stream invalid.
+ SetStreamValid(false);
}
@@ -371,6 +386,11 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
DecRecalcLevel();
InvalidatePageBreaks();
+
+ if (IsStreamValid())
+ // TODO: In the future we may want to check if the table has been
+ // really modified before setting the stream invalid.
+ SetStreamValid(false);
}
@@ -398,9 +418,12 @@ void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USH
aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
}
-
-// DecRecalcLevel();
}
+
+ if (IsStreamValid())
+ // TODO: In the future we may want to check if the table has been
+ // really modified before setting the stream invalid.
+ SetStreamValid(false);
}
@@ -424,6 +447,11 @@ void ScTable::DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark )
SfxItemPoolCache aCache( pPool, &aSet );
ApplySelectionCache( &aCache, rMark );
}
+
+ if (IsStreamValid())
+ // TODO: In the future we may want to check if the table has been
+ // really modified before setting the stream invalid.
+ SetStreamValid(false);
}