[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 2 commits - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Wed Jul 17 18:31:01 PDT 2013
sc/inc/formulacell.hxx | 18 +
sc/source/core/data/formulacell.cxx | 550 +++++++++++++++++++++++++++++-------
2 files changed, 462 insertions(+), 106 deletions(-)
New commits:
commit 4efa10aebbbe8da21d3b2214cdabd6acd6079889
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jul 17 21:31:24 2013 -0400
Split this method into 3.
Apparently too many people have tried to cram their needs into this
single function, which ended up making this such a monster full of
temporary hacks.
Change-Id: If8f7676a60f6017767e68252d173ca9e38b89d99
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 7012eb1..7260ea0 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -105,6 +105,24 @@ private:
};
void InterpretTail( ScInterpretTailParameter );
+ /**
+ * Update reference in response to cell insertion or deletion.
+ */
+ bool UpdateReferenceOnShift(
+ const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos );
+
+ /**
+ * Update reference in response to cell move.
+ */
+ bool UpdateReferenceOnMove(
+ const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos );
+
+ /**
+ * Update reference in response to cell copy-n-paste.
+ */
+ bool UpdateReferenceOnCopy(
+ const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos );
+
ScFormulaCell( const ScFormulaCell& );
public:
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index bd9bb6c..aa03600 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2204,25 +2204,24 @@ bool checkCompileColRowName(
}
-bool ScFormulaCell::UpdateReference(
+bool ScFormulaCell::UpdateReferenceOnShift(
const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
{
+ if (rCxt.meMode != URM_INSDEL)
+ // Just in case...
+ return false;
+
bool bCellStateChanged = false;
- UpdateRefMode eUpdateRefMode = rCxt.meMode;
const ScRange& rRange = rCxt.maRange;
SCCOL nDx = rCxt.mnColDelta;
SCROW nDy = rCxt.mnRowDelta;
SCTAB nDz = rCxt.mnTabDelta;
- SCCOL nCol = aPos.Col();
- SCROW nRow = aPos.Row();
- SCTAB nTab = aPos.Tab();
ScAddress aUndoPos( aPos ); // position for undo cell in pUndoDoc
if ( pUndoCellPos )
aUndoPos = *pUndoCellPos;
ScAddress aOldPos( aPos );
- bool bIsInsert = (eUpdateRefMode == URM_INSDEL && nDx >= 0 && nDy >= 0 && nDz >= 0);
- if (eUpdateRefMode == URM_INSDEL && rRange.In(aPos))
+ if (rRange.In(aPos))
{
// This formula cell itself is being shifted during cell range
// insertion or deletion. Update its position.
@@ -2232,7 +2231,169 @@ bool ScFormulaCell::UpdateReference(
bCellStateChanged = aPos != aOldPos;
}
- else if (rRange.In(aPos))
+
+ bool bHasRefs = false;
+ bool bHasColRowNames = false;
+ bool bOnRefMove = false;
+ if ( !pDocument->IsClipOrUndo() )
+ {
+ // Check presence of any references or column row names.
+ pCode->Reset();
+ bHasRefs = (pCode->GetNextReferenceRPN() != NULL);
+ if (!bHasRefs)
+ {
+ pCode->Reset();
+ bHasColRowNames = (pCode->GetNextColRowName() != NULL);
+ bHasRefs = bHasRefs || bHasColRowNames;
+ }
+ bOnRefMove = pCode->IsRecalcModeOnRefMove();
+ }
+
+ if (!bHasRefs && !bOnRefMove)
+ // This formula cell contains no references, nor needs recalculating
+ // on reference update. Bail out.
+ return bCellStateChanged;
+
+ boost::scoped_ptr<ScTokenArray> pOldCode;
+ if (pUndoDoc)
+ pOldCode.reset(pCode->Clone());
+
+ ScRangeData* pSharedCode = NULL;
+ bool bValChanged = false;
+ bool bRangeModified = false; // any range, not only shared formula
+ bool bRefSizeChanged = false;
+
+ if (bHasRefs)
+ {
+ // Update cell or range references.
+ ScCompiler aComp(pDocument, aPos, *pCode);
+ aComp.SetGrammar(pDocument->GetGrammar());
+ pSharedCode = aComp.UpdateReference(URM_INSDEL, aOldPos, rRange,
+ nDx, nDy, nDz,
+ bValChanged, bRefSizeChanged);
+ bRangeModified = aComp.HasModifiedRange();
+ }
+
+ bCellStateChanged |= bValChanged;
+
+ if (bOnRefMove)
+ // Cell may reference itself, e.g. ocColumn, ocRow without parameter
+ bOnRefMove = (bValChanged || (aPos != aOldPos));
+
+ bool bColRowNameCompile = false;
+ bool bHasRelName = false;
+ bool bNewListening = false;
+ bool bInDeleteUndo = false;
+
+ if (bHasRefs)
+ {
+ // Upon Insert ColRowNames have to be recompiled in case the
+ // insertion occurs right in front of the range.
+ if (bHasColRowNames)
+ bColRowNameCompile = checkCompileColRowName(rCxt, *pDocument, *pCode, aOldPos, aPos, bValChanged);
+
+ ScChangeTrack* pChangeTrack = pDocument->GetChangeTrack();
+ bInDeleteUndo = (pChangeTrack && pChangeTrack->IsInDeleteUndo());
+
+ // RelNameRefs are always moved
+ bHasRelName = HasRelNameReference();
+ // Reference changed and new listening needed?
+ // Except in Insert/Delete without specialties.
+ bNewListening = (bRangeModified || pSharedCode || bColRowNameCompile
+ || (bValChanged && (bInDeleteUndo || bRefSizeChanged)) || bHasRelName);
+
+ if ( bNewListening )
+ EndListeningTo(pDocument, pOldCode.get(), aOldPos);
+ }
+
+ bool bNeedDirty = false;
+ // NeedDirty for changes except for Copy and Move/Insert without RelNames
+ if (bRangeModified || pSharedCode || bColRowNameCompile ||
+ (bValChanged && (bHasRelName || bInDeleteUndo || bRefSizeChanged)) || bOnRefMove)
+ bNeedDirty = true;
+
+ if (pUndoDoc && (bValChanged || pSharedCode || bOnRefMove))
+ {
+ // Copy the cell to aUndoPos, which is its current position in the document,
+ // so this works when UpdateReference is called before moving the cells
+ // (InsertCells/DeleteCells - aPos is changed above) as well as when UpdateReference
+ // is called after moving the cells (MoveBlock/PasteFromClip - aOldPos is changed).
+
+ // If there is already a formula cell in the undo document, don't overwrite it,
+ // the first (oldest) is the important cell.
+ if ( pUndoDoc->GetCellType( aUndoPos ) != CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aUndoPos,
+ pOldCode.get(), eTempGrammar, cMatrixFlag );
+ pFCell->aResult.SetToken( NULL); // to recognize it as changed later (Cut/Paste!)
+ pUndoDoc->SetFormulaCell(aUndoPos, pFCell);
+ }
+ }
+
+ bValChanged = false;
+
+ if ( pSharedCode )
+ { // Replace shared formula with own formula
+ pDocument->RemoveFromFormulaTree( this ); // update formula count
+ delete pCode;
+ pCode = pSharedCode->GetCode()->Clone();
+ // #i18937# #i110008# call MoveRelWrap, but with the old position
+ ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pSharedCode->GetMaxCol(), pSharedCode->GetMaxRow());
+ ScCompiler aComp2(pDocument, aPos, *pCode);
+ aComp2.SetGrammar(pDocument->GetGrammar());
+ aComp2.UpdateSharedFormulaReference(URM_INSDEL, aOldPos, rRange, nDx, nDy, nDz);
+ bValChanged = true;
+ bNeedDirty = true;
+ }
+
+ if ( ( bCompile = (bCompile || bValChanged || bRangeModified || bColRowNameCompile) ) != 0 )
+ {
+ CompileTokenArray( bNewListening ); // no Listening
+ bNeedDirty = true;
+ }
+
+ if ( !bInDeleteUndo )
+ { // In ChangeTrack Delete-Reject listeners are established in
+ // InsertCol/InsertRow
+ if ( bNewListening )
+ {
+ // Inserts/Deletes re-establish listeners after all
+ // UpdateReference calls.
+ // All replaced shared formula listeners have to be
+ // established after an Insert or Delete. Do nothing here.
+ SetNeedsListening( true);
+ }
+ }
+
+ if ( bNeedDirty && (!bHasRelName || pSharedCode) )
+ { // Cut off references, invalid or similar?
+ sc::AutoCalcSwitch(*pDocument, false);
+ SetDirty();
+ }
+
+ return bCellStateChanged;
+}
+
+bool ScFormulaCell::UpdateReferenceOnMove(
+ const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
+{
+ if (rCxt.meMode != URM_MOVE)
+ return false;
+
+ bool bCellStateChanged = false;
+ const ScRange& rRange = rCxt.maRange;
+ SCCOL nDx = rCxt.mnColDelta;
+ SCROW nDy = rCxt.mnRowDelta;
+ SCTAB nDz = rCxt.mnTabDelta;
+ SCCOL nCol = aPos.Col();
+ SCROW nRow = aPos.Row();
+ SCTAB nTab = aPos.Tab();
+ ScAddress aUndoPos( aPos ); // position for undo cell in pUndoDoc
+ if ( pUndoCellPos )
+ aUndoPos = *pUndoCellPos;
+ ScAddress aOldPos( aPos );
+
+ if (rRange.In(aPos))
{
// The cell is being moved or copied to a new position. I guess the
// position has been updated prior to this call? Determine
@@ -2249,7 +2410,7 @@ bool ScFormulaCell::UpdateReference(
// Check presence of any references or column row names.
pCode->Reset();
bHasRefs = (pCode->GetNextReferenceRPN() != NULL);
- if ( !bHasRefs || eUpdateRefMode == URM_COPY )
+ if (!bHasRefs)
{
pCode->Reset();
bHasColRowNames = (pCode->GetNextColRowName() != NULL);
@@ -2277,7 +2438,7 @@ bool ScFormulaCell::UpdateReference(
// Update cell or range references.
ScCompiler aComp(pDocument, aPos, *pCode);
aComp.SetGrammar(pDocument->GetGrammar());
- pSharedCode = aComp.UpdateReference(eUpdateRefMode, aOldPos, rRange,
+ pSharedCode = aComp.UpdateReference(URM_MOVE, aOldPos, rRange,
nDx, nDy, nDz,
bValChanged, bRefSizeChanged);
bRangeModified = aComp.HasModifiedRange();
@@ -2309,14 +2470,11 @@ bool ScFormulaCell::UpdateReference(
// Reference changed and new listening needed?
// Except in Insert/Delete without specialties.
bNewListening = (bRangeModified || pSharedCode || bColRowNameCompile
- || (bValChanged && (eUpdateRefMode != URM_INSDEL ||
- bInDeleteUndo || bRefSizeChanged)) ||
- (bHasRelName && eUpdateRefMode != URM_COPY))
+ || bValChanged || bHasRelName)
// #i36299# Don't duplicate action during cut&paste / drag&drop
// on a cell in the range moved, start/end listeners is done
// via ScDocument::DeleteArea() and ScDocument::CopyFromClip().
- && !(eUpdateRefMode == URM_MOVE &&
- pDocument->IsInsertingFromOtherDoc() && rRange.In(aPos));
+ && !(pDocument->IsInsertingFromOtherDoc() && rRange.In(aPos));
if ( bNewListening )
EndListeningTo(pDocument, pOldCode.get(), aOldPos);
@@ -2325,10 +2483,7 @@ bool ScFormulaCell::UpdateReference(
bool bNeedDirty = false;
// NeedDirty for changes except for Copy and Move/Insert without RelNames
if ( bRangeModified || pSharedCode || bColRowNameCompile ||
- (bValChanged && eUpdateRefMode != URM_COPY &&
- (eUpdateRefMode != URM_MOVE || bHasRelName) &&
- (!bIsInsert || bHasRelName || bInDeleteUndo ||
- bRefSizeChanged)) || bOnRefMove)
+ (bValChanged && bHasRelName && (bHasRelName || bInDeleteUndo || bRefSizeChanged)) || bOnRefMove)
bNeedDirty = true;
if (pUndoDoc && (bValChanged || pSharedCode || bOnRefMove))
@@ -2360,7 +2515,7 @@ bool ScFormulaCell::UpdateReference(
ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pSharedCode->GetMaxCol(), pSharedCode->GetMaxRow());
ScCompiler aComp2(pDocument, aPos, *pCode);
aComp2.SetGrammar(pDocument->GetGrammar());
- aComp2.UpdateSharedFormulaReference( eUpdateRefMode, aOldPos, rRange,
+ aComp2.UpdateSharedFormulaReference(URM_MOVE, aOldPos, rRange,
nDx, nDy, nDz );
bValChanged = true;
bNeedDirty = true;
@@ -2377,20 +2532,11 @@ bool ScFormulaCell::UpdateReference(
// InsertCol/InsertRow
if ( bNewListening )
{
- if ( eUpdateRefMode == URM_INSDEL )
- {
- // Inserts/Deletes re-establish listeners after all
- // UpdateReference calls.
- // All replaced shared formula listeners have to be
- // established after an Insert or Delete. Do nothing here.
- SetNeedsListening( true);
- }
- else
- StartListeningTo( pDocument );
+ StartListeningTo( pDocument );
}
}
- if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pSharedCode) )
+ if (bNeedDirty)
{ // Cut off references, invalid or similar?
sc::AutoCalcSwitch(*pDocument, false);
SetDirty();
@@ -2399,6 +2545,184 @@ bool ScFormulaCell::UpdateReference(
return bCellStateChanged;
}
+bool ScFormulaCell::UpdateReferenceOnCopy(
+ const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
+{
+ if (rCxt.meMode != URM_COPY)
+ return false;
+
+ bool bCellStateChanged = false;
+ const ScRange& rRange = rCxt.maRange;
+ SCCOL nDx = rCxt.mnColDelta;
+ SCROW nDy = rCxt.mnRowDelta;
+ SCTAB nDz = rCxt.mnTabDelta;
+ SCCOL nCol = aPos.Col();
+ SCROW nRow = aPos.Row();
+ SCTAB nTab = aPos.Tab();
+ ScAddress aUndoPos( aPos ); // position for undo cell in pUndoDoc
+ if ( pUndoCellPos )
+ aUndoPos = *pUndoCellPos;
+ ScAddress aOldPos( aPos );
+
+ if (rRange.In(aPos))
+ {
+ // The cell is being moved or copied to a new position. I guess the
+ // position has been updated prior to this call? Determine
+ // its original position before the move which will be used to adjust
+ // relative references later.
+ aOldPos.Set( nCol - nDx, nRow - nDy, nTab - nDz );
+ }
+
+ bool bHasRefs = false;
+ bool bHasColRowNames = false;
+ bool bOnRefMove = false;
+ if ( !pDocument->IsClipOrUndo() )
+ {
+ // Check presence of any references or column row names.
+ pCode->Reset();
+ bHasRefs = (pCode->GetNextReferenceRPN() != NULL);
+ pCode->Reset();
+ bHasColRowNames = (pCode->GetNextColRowName() != NULL);
+ bHasRefs = bHasRefs || bHasColRowNames;
+ bOnRefMove = pCode->IsRecalcModeOnRefMove();
+ }
+
+ if (!bHasRefs && !bOnRefMove)
+ // This formula cell contains no references, nor needs recalculating
+ // on reference update. Bail out.
+ return bCellStateChanged;
+
+ boost::scoped_ptr<ScTokenArray> pOldCode;
+ if (pUndoDoc)
+ pOldCode.reset(pCode->Clone());
+
+ ScRangeData* pSharedCode = NULL;
+ bool bValChanged = false;
+ bool bRangeModified = false; // any range, not only shared formula
+ bool bRefSizeChanged = false;
+
+ if (bHasRefs)
+ {
+ // Update cell or range references.
+ ScCompiler aComp(pDocument, aPos, *pCode);
+ aComp.SetGrammar(pDocument->GetGrammar());
+ pSharedCode = aComp.UpdateReference(URM_COPY, aOldPos, rRange,
+ nDx, nDy, nDz,
+ bValChanged, bRefSizeChanged);
+ bRangeModified = aComp.HasModifiedRange();
+ }
+
+ bCellStateChanged |= bValChanged;
+
+ if (bOnRefMove)
+ // Cell may reference itself, e.g. ocColumn, ocRow without parameter
+ bOnRefMove = (bValChanged || (aPos != aOldPos));
+
+ bool bColRowNameCompile = false;
+ bool bHasRelName = false;
+ bool bNewListening = false;
+ bool bInDeleteUndo = false;
+
+ if (bHasRefs)
+ {
+ // Upon Insert ColRowNames have to be recompiled in case the
+ // insertion occurs right in front of the range.
+ if (bHasColRowNames)
+ bColRowNameCompile = checkCompileColRowName(rCxt, *pDocument, *pCode, aOldPos, aPos, bValChanged);
+
+ ScChangeTrack* pChangeTrack = pDocument->GetChangeTrack();
+ bInDeleteUndo = (pChangeTrack && pChangeTrack->IsInDeleteUndo());
+
+ // RelNameRefs are always moved
+ bHasRelName = HasRelNameReference();
+ // Reference changed and new listening needed?
+ // Except in Insert/Delete without specialties.
+ bNewListening =
+ (bRangeModified || pSharedCode || bColRowNameCompile || (bValChanged && (bInDeleteUndo || bRefSizeChanged)));
+
+ if ( bNewListening )
+ EndListeningTo(pDocument, pOldCode.get(), aOldPos);
+ }
+
+ bool bNeedDirty = false;
+ // NeedDirty for changes except for Copy and Move/Insert without RelNames
+ if ( bRangeModified || pSharedCode || bColRowNameCompile || bOnRefMove)
+ bNeedDirty = true;
+
+ if (pUndoDoc && (bValChanged || pSharedCode || bOnRefMove))
+ {
+ // Copy the cell to aUndoPos, which is its current position in the document,
+ // so this works when UpdateReference is called before moving the cells
+ // (InsertCells/DeleteCells - aPos is changed above) as well as when UpdateReference
+ // is called after moving the cells (MoveBlock/PasteFromClip - aOldPos is changed).
+
+ // If there is already a formula cell in the undo document, don't overwrite it,
+ // the first (oldest) is the important cell.
+ if ( pUndoDoc->GetCellType( aUndoPos ) != CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aUndoPos,
+ pOldCode.get(), eTempGrammar, cMatrixFlag );
+ pFCell->aResult.SetToken( NULL); // to recognize it as changed later (Cut/Paste!)
+ pUndoDoc->SetFormulaCell(aUndoPos, pFCell);
+ }
+ }
+
+ bValChanged = false;
+
+ if ( pSharedCode )
+ { // Replace shared formula with own formula
+ pDocument->RemoveFromFormulaTree( this ); // update formula count
+ delete pCode;
+ pCode = pSharedCode->GetCode()->Clone();
+ // #i18937# #i110008# call MoveRelWrap, but with the old position
+ ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pSharedCode->GetMaxCol(), pSharedCode->GetMaxRow());
+ ScCompiler aComp2(pDocument, aPos, *pCode);
+ aComp2.SetGrammar(pDocument->GetGrammar());
+ aComp2.UpdateSharedFormulaReference(URM_COPY, aOldPos, rRange, nDx, nDy, nDz);
+ bValChanged = true;
+ bNeedDirty = true;
+ }
+
+ if ( ( bCompile = (bCompile || bValChanged || bRangeModified || bColRowNameCompile) ) != 0 )
+ {
+ CompileTokenArray( bNewListening ); // no Listening
+ bNeedDirty = true;
+ }
+
+ if ( !bInDeleteUndo )
+ { // In ChangeTrack Delete-Reject listeners are established in
+ // InsertCol/InsertRow
+ if ( bNewListening )
+ StartListeningTo( pDocument );
+ }
+
+ if (bNeedDirty)
+ { // Cut off references, invalid or similar?
+ sc::AutoCalcSwitch(*pDocument, false);
+ SetDirty();
+ }
+
+ return bCellStateChanged;
+}
+
+bool ScFormulaCell::UpdateReference(
+ const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
+{
+ switch (rCxt.meMode)
+ {
+ case URM_INSDEL:
+ return UpdateReferenceOnShift(rCxt, pUndoDoc, pUndoCellPos);
+ case URM_MOVE:
+ return UpdateReferenceOnMove(rCxt, pUndoDoc, pUndoCellPos);
+ case URM_COPY:
+ return UpdateReferenceOnCopy(rCxt, pUndoDoc, pUndoCellPos);
+ default:
+ ;
+ }
+
+ return false;
+}
+
void ScFormulaCell::UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets)
{
bool bPosChanged = ( aPos.Tab() >= nTable ? true : false );
commit b4c5b83ad7036a127607fd8dee51969b79ad7612
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jul 17 18:46:41 2013 -0400
Extract this code into a local function.
Change-Id: I91bb3cdc31d247004e22bef734374e8a80819c3a
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index acb5d46..bd9bb6c 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2117,6 +2117,93 @@ bool ScFormulaCell::HasColRowName() const
return (pCode->GetNextColRowName() != NULL);
}
+namespace {
+
+/**
+ * Check if we need to re-compile column or row names.
+ */
+bool checkCompileColRowName(
+ const sc::RefUpdateContext& rCxt, ScDocument& rDoc, ScTokenArray& rCode,
+ const ScAddress& aOldPos, const ScAddress& aPos, bool bValChanged)
+{
+ switch (rCxt.meMode)
+ {
+ case URM_INSDEL:
+ {
+ if (rCxt.mnColDelta <= 0 && rCxt.mnRowDelta <= 0)
+ return false;
+
+ ScToken* t;
+ ScRangePairList* pColList = rDoc.GetColNameRanges();
+ ScRangePairList* pRowList = rDoc.GetRowNameRanges();
+ rCode.Reset();
+ while ((t = static_cast<ScToken*>(rCode.GetNextColRowName())) != NULL)
+ {
+ ScSingleRefData& rRef = t->GetSingleRef();
+ if (rCxt.mnRowDelta > 0 && rRef.IsColRel())
+ { // ColName
+ ScAddress aAdr = rRef.toAbs(aPos);
+ ScRangePair* pR = pColList->Find( aAdr );
+ if ( pR )
+ { // defined
+ if (pR->GetRange(1).aStart.Row() == rCxt.maRange.aStart.Row())
+ return true;
+ }
+ else
+ { // on the fly
+ if (aAdr.Row() + 1 == rCxt.maRange.aStart.Row())
+ return true;
+ }
+ }
+ if (rCxt.mnColDelta > 0 && rRef.IsRowRel())
+ { // RowName
+ ScAddress aAdr = rRef.toAbs(aPos);
+ ScRangePair* pR = pRowList->Find( aAdr );
+ if ( pR )
+ { // defined
+ if ( pR->GetRange(1).aStart.Col() == rCxt.maRange.aStart.Col())
+ return true;
+ }
+ else
+ { // on the fly
+ if (aAdr.Col() + 1 == rCxt.maRange.aStart.Col())
+ return true;
+ }
+ }
+ }
+ }
+ case URM_MOVE:
+ { // Recomplie for Move/D&D when ColRowName was moved or this Cell
+ // points to one and was moved.
+ bool bMoved = (aPos != aOldPos);
+ if (bMoved)
+ return true;
+
+ rCode.Reset();
+ const ScToken* t = static_cast<const ScToken*>(rCode.GetNextColRowName());
+ for (; t; t = static_cast<const ScToken*>(rCode.GetNextColRowName()))
+ {
+ const ScSingleRefData& rRef = t->GetSingleRef();
+ ScAddress aAbs = rRef.toAbs(aPos);
+ if (ValidAddress(aAbs))
+ {
+ if (rCxt.maRange.In(aAbs))
+ return true;
+ }
+ }
+ }
+ break;
+ case URM_COPY:
+ return bValChanged;
+ default:
+ ;
+ }
+
+ return false;
+}
+
+}
+
bool ScFormulaCell::UpdateReference(
const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
{
@@ -2126,8 +2213,6 @@ bool ScFormulaCell::UpdateReference(
SCCOL nDx = rCxt.mnColDelta;
SCROW nDy = rCxt.mnRowDelta;
SCTAB nDz = rCxt.mnTabDelta;
- SCCOL nCol1 = rRange.aStart.Col();
- SCROW nRow1 = rRange.aStart.Row();
SCCOL nCol = aPos.Col();
SCROW nRow = aPos.Row();
SCTAB nTab = aPos.Tab();
@@ -2213,79 +2298,8 @@ bool ScFormulaCell::UpdateReference(
{
// Upon Insert ColRowNames have to be recompiled in case the
// insertion occurs right in front of the range.
- bColRowNameCompile =
- (eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0));
-
- if ( bColRowNameCompile )
- {
- bColRowNameCompile = false;
- ScToken* t;
- ScRangePairList* pColList = pDocument->GetColNameRanges();
- ScRangePairList* pRowList = pDocument->GetRowNameRanges();
- pCode->Reset();
- while ( !bColRowNameCompile && (t = static_cast<ScToken*>(pCode->GetNextColRowName())) != NULL )
- {
- ScSingleRefData& rRef = t->GetSingleRef();
- if ( nDy > 0 && rRef.IsColRel() )
- { // ColName
- ScAddress aAdr = rRef.toAbs(aPos);
- ScRangePair* pR = pColList->Find( aAdr );
- if ( pR )
- { // defined
- if ( pR->GetRange(1).aStart.Row() == nRow1 )
- bColRowNameCompile = true;
- }
- else
- { // on the fly
- if (aAdr.Row() + 1 == nRow1)
- bColRowNameCompile = true;
- }
- }
- if ( nDx > 0 && rRef.IsRowRel() )
- { // RowName
- ScAddress aAdr = rRef.toAbs(aPos);
- ScRangePair* pR = pRowList->Find( aAdr );
- if ( pR )
- { // defined
- if ( pR->GetRange(1).aStart.Col() == nCol1 )
- bColRowNameCompile = true;
- }
- else
- { // on the fly
- if (aAdr.Col() + 1 == nCol1)
- bColRowNameCompile = true;
- }
- }
- }
- }
- else if ( eUpdateRefMode == URM_MOVE )
- { // Recomplie for Move/D&D when ColRowName was moved or this Cell
- // points to one and was moved.
- bColRowNameCompile = bCompile; // Possibly from Copy ctor
- if ( !bColRowNameCompile )
- {
- bool bMoved = (aPos != aOldPos);
- pCode->Reset();
- ScToken* t = static_cast<ScToken*>(pCode->GetNextColRowName());
- if ( t && bMoved )
- bColRowNameCompile = true;
- while ( t && !bColRowNameCompile )
- {
- ScSingleRefData& rRef = t->GetSingleRef();
- ScAddress aAbs = rRef.toAbs(aPos);
- if (ValidAddress(aAbs))
- {
- if (rRange.In(aAbs))
- bColRowNameCompile = true;
- }
- t = static_cast<ScToken*>(pCode->GetNextColRowName());
- }
- }
- }
- else if ( eUpdateRefMode == URM_COPY && bHasColRowNames && bValChanged )
- {
- bColRowNameCompile = true;
- }
+ if (bHasColRowNames)
+ bColRowNameCompile = checkCompileColRowName(rCxt, *pDocument, *pCode, aOldPos, aPos, bValChanged);
ScChangeTrack* pChangeTrack = pDocument->GetChangeTrack();
bInDeleteUndo = (pChangeTrack && pChangeTrack->IsInDeleteUndo());
More information about the Libreoffice-commits
mailing list