[Libreoffice-commits] core.git: 33 commits - sc/inc sc/Library_sc.mk sc/qa sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Thu Jun 27 13:22:36 PDT 2013
sc/Library_sc.mk | 1
sc/inc/cellclonehandler.hxx | 68 ---
sc/inc/column.hxx | 89 +++-
sc/inc/document.hxx | 12
sc/inc/formulacell.hxx | 17
sc/inc/formularesult.hxx | 2
sc/inc/table.hxx | 6
sc/inc/validat.hxx | 1
sc/qa/unit/ucalc.cxx | 180 ++++++++
sc/source/core/data/cellclonehandler.cxx | 116 -----
sc/source/core/data/column.cxx | 687 +++++++++++++++++++------------
sc/source/core/data/column2.cxx | 204 +++++++++
sc/source/core/data/column3.cxx | 388 ++++++++++++-----
sc/source/core/data/dociter.cxx | 22
sc/source/core/data/documen8.cxx | 28 +
sc/source/core/data/document.cxx | 18
sc/source/core/data/formulacell.cxx | 438 ++++++++++---------
sc/source/core/data/table1.cxx | 29 +
sc/source/core/inc/interpre.hxx | 1
sc/source/core/tool/compiler.cxx | 249 ++++-------
sc/source/core/tool/formularesult.cxx | 45 +-
sc/source/core/tool/interpr5.cxx | 125 -----
sc/source/filter/xml/xmlexprt.cxx | 13
sc/source/ui/app/transobj.cxx | 4
sc/source/ui/view/tabview4.cxx | 11
25 files changed, 1647 insertions(+), 1107 deletions(-)
New commits:
commit 7ae43cdd7f3e21656541db63d3b657160f1a4fac
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Thu Jun 27 15:38:34 2013 -0400
Turn off column debug and remove warnings.
Change-Id: Ic7dd79c1e420e87dcaff4126d60763ff8cbe9344
diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index 2c58997..0ebf8be 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -15,7 +15,7 @@
#include "svl/broadcast.hxx"
#include "editeng/editobj.hxx"
-#define DEBUG_COLUMN_STORAGE 1
+#define DEBUG_COLUMN_STORAGE 0
#if DEBUG_COLUMN_STORAGE
#ifdef NDEBUG
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 7205672..3704c6d 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1532,15 +1532,15 @@ void ScColumn::RegroupFormulaCells()
{
}
-void ScColumn::RegroupFormulaCells( SCROW nRow )
+void ScColumn::RegroupFormulaCells( SCROW /*nRow*/ )
{
}
-void ScColumn::RegroupFormulaCells( SCROW nRow1, SCROW nRow2 )
+void ScColumn::RegroupFormulaCells( SCROW /*nRow1*/, SCROW /*nRow2*/ )
{
}
-void ScColumn::FormulaCellsUndecided( SCROW nRow1, SCROW nRow2 )
+void ScColumn::FormulaCellsUndecided( SCROW /*nRow1*/, SCROW /*nRow2*/ )
{
}
commit d6824709d29505e79a86c85c2b127c5e3f6ff416
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Thu Jun 27 15:12:10 2013 -0400
Rename a variable to something more meaningful.
Change-Id: I860e5301e3fec3f06f318b28787f71b63dbaf0ab
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 5d471c4..2ade13b 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2100,7 +2100,7 @@ bool ScFormulaCell::UpdateReference(
if (pUndoDoc)
pOldCode.reset(pCode->Clone());
- ScRangeData* pRangeData = NULL;
+ ScRangeData* pSharedCode = NULL;
bool bValChanged = false;
bool bRangeModified = false; // any range, not only shared formula
bool bRefSizeChanged = false;
@@ -2110,7 +2110,7 @@ bool ScFormulaCell::UpdateReference(
// Update cell or range references.
ScCompiler aComp(pDocument, aPos, *pCode);
aComp.SetGrammar(pDocument->GetGrammar());
- pRangeData = aComp.UpdateReference(eUpdateRefMode, aOldPos, rRange,
+ pSharedCode = aComp.UpdateReference(eUpdateRefMode, aOldPos, rRange,
nDx, nDy, nDz,
bValChanged, bRefSizeChanged);
bRangeModified = aComp.HasModifiedRange();
@@ -2215,7 +2215,7 @@ bool ScFormulaCell::UpdateReference(
bHasRelName = HasRelNameReference();
// Reference changed and new listening needed?
// Except in Insert/Delete without specialties.
- bNewListening = (bRangeModified || pRangeData || bColRowNameCompile
+ bNewListening = (bRangeModified || pSharedCode || bColRowNameCompile
|| (bValChanged && (eUpdateRefMode != URM_INSDEL ||
bInDeleteUndo || bRefSizeChanged)) ||
(bHasRelName && eUpdateRefMode != URM_COPY))
@@ -2231,14 +2231,14 @@ bool ScFormulaCell::UpdateReference(
bool bNeedDirty = false;
// NeedDirty for changes except for Copy and Move/Insert without RelNames
- if ( bRangeModified || pRangeData || bColRowNameCompile ||
+ if ( bRangeModified || pSharedCode || bColRowNameCompile ||
(bValChanged && eUpdateRefMode != URM_COPY &&
(eUpdateRefMode != URM_MOVE || bHasRelName) &&
(!bIsInsert || bHasRelName || bInDeleteUndo ||
bRefSizeChanged)) || bOnRefMove)
bNeedDirty = true;
- if (pUndoDoc && (bValChanged || pRangeData || bOnRefMove))
+ 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
@@ -2258,13 +2258,13 @@ bool ScFormulaCell::UpdateReference(
bValChanged = false;
- if ( pRangeData )
+ if ( pSharedCode )
{ // Replace shared formula with own formula
pDocument->RemoveFromFormulaTree( this ); // update formula count
delete pCode;
- pCode = pRangeData->GetCode()->Clone();
+ pCode = pSharedCode->GetCode()->Clone();
// #i18937# #i110008# call MoveRelWrap, but with the old position
- ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
+ ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pSharedCode->GetMaxCol(), pSharedCode->GetMaxRow());
ScCompiler aComp2(pDocument, aPos, *pCode);
aComp2.SetGrammar(pDocument->GetGrammar());
aComp2.UpdateSharedFormulaReference( eUpdateRefMode, aOldPos, rRange,
@@ -2297,7 +2297,7 @@ bool ScFormulaCell::UpdateReference(
}
}
- if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
+ if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pSharedCode) )
{ // Cut off references, invalid or similar?
sc::AutoCalcSwitch(*pDocument, false);
SetDirty();
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index db84612..bdce061 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4222,25 +4222,25 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
}
}
// Check for SharedFormulas.
- ScRangeData* pRangeData = NULL;
+ ScRangeData* pSharedCode = NULL;
pArr->Reset();
- for( FormulaToken* j = pArr->GetNextName(); j && !pRangeData;
+ for( FormulaToken* j = pArr->GetNextName(); j && !pSharedCode;
j = pArr->GetNextName() )
{
if( j->GetOpCode() == ocName )
{
ScRangeData* pName = GetRangeData( *j);
if (pName && pName->HasType(RT_SHARED))
- pRangeData = pName;
+ pSharedCode = pName;
}
}
// Check SharedFormulas for wraps.
- if (pRangeData)
+ if (pSharedCode)
{
- ScRangeData* pName = pRangeData;
- pRangeData = NULL;
+ ScRangeData* pName = pSharedCode;
+ pSharedCode = NULL;
pArr->Reset();
- for( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()); t && !pRangeData;
+ for( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()); t && !pSharedCode;
t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) )
{
bool bRelName = (t->GetType() == svSingleRef ?
@@ -4257,16 +4257,16 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
// wrapped it. Replace SharedFormula.
if (!bValid)
{
- pRangeData = pName;
+ pSharedCode = pName;
rChanged = true;
}
}
}
}
- return pRangeData;
+ return pSharedCode;
}
- ScRangeData* pRangeData = NULL;
+ ScRangeData* pSharedCode = NULL;
ScToken* t;
pArr->Reset();
while( (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL )
@@ -4276,7 +4276,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
ScRangeData* pName = GetRangeData( *t);
if (pName && pName->HasType(RT_SHAREDMOD))
{
- pRangeData = pName; // maybe need a replacement of shared with own code
+ pSharedCode = pName; // maybe need a replacement of shared with own code
rChanged = true;
}
}
@@ -4373,7 +4373,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
}
}
- return pRangeData;
+ return pSharedCode;
}
bool ScCompiler::UpdateNameReference(UpdateRefMode eUpdateRefMode,
commit ff5d891b480a0bb3b6cee950d9ea41387fd16392
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Thu Jun 27 14:57:32 2013 -0400
Some attempt to clean ScFormulaCell::UpdateReference() a bit.
This method is still a monster, however...
Change-Id: I4aaa2d20c8ae6132a75c7c92c0a1b58882d8a261
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index b724d02..1f9b960 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -176,11 +176,10 @@ public:
bool HasRelNameReference() const;
bool HasColRowName() const;
- bool UpdateReference(UpdateRefMode eUpdateRefMode,
- const ScRange& r,
- SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
- ScDocument* pUndoDoc = NULL,
- const ScAddress* pUndoCellPos = NULL );
+ bool UpdateReference(
+ UpdateRefMode eUpdateRefMode, const ScRange& rRange,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz, ScDocument* pUndoDoc = NULL,
+ const ScAddress* pUndoCellPos = NULL );
void TransposeReference();
void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index a3ab73d..5d471c4 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -46,8 +46,10 @@
#include "formulagroup.hxx"
#include "listenercontext.hxx"
#include "types.hxx"
+#include "scopetools.hxx"
#include <boost/bind.hpp>
+#include <boost/scoped_ptr.hpp>
using namespace formula;
@@ -2039,15 +2041,14 @@ bool ScFormulaCell::HasColRowName() const
return (pCode->GetNextColRowName() != NULL);
}
-bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
- const ScRange& r,
- SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
- ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
+bool ScFormulaCell::UpdateReference(
+ UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
{
bool bCellStateChanged = false;
- SCCOL nCol1 = r.aStart.Col();
- SCROW nRow1 = r.aStart.Row();
+ SCCOL nCol1 = rRange.aStart.Col();
+ SCROW nRow1 = rRange.aStart.Row();
SCCOL nCol = aPos.Col();
SCROW nRow = aPos.Row();
SCTAB nTab = aPos.Tab();
@@ -2055,15 +2056,21 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
if ( pUndoCellPos )
aUndoPos = *pUndoCellPos;
ScAddress aOldPos( aPos );
- bool bIsInsert = (eUpdateRefMode == URM_INSDEL &&
- nDx >= 0 && nDy >= 0 && nDz >= 0);
- if (eUpdateRefMode == URM_INSDEL && r.In( aPos ))
+ bool bIsInsert = (eUpdateRefMode == URM_INSDEL && nDx >= 0 && nDy >= 0 && nDz >= 0);
+
+ if (eUpdateRefMode == URM_INSDEL && rRange.In(aPos))
{
+ // This formula cell itself is being shifted during cell range
+ // insertion or deletion. Update its position.
aPos.Move(nDx, nDy, nDz);
bCellStateChanged = aPos != aOldPos;
}
- else if ( r.In( aPos ) )
+ else 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 );
}
@@ -2072,6 +2079,7 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
bool bOnRefMove = false;
if ( !pDocument->IsClipOrUndo() )
{
+ // Check presence of any references or column row names.
pCode->Reset();
bHasRefs = (pCode->GetNextReferenceRPN() != NULL);
if ( !bHasRefs || eUpdateRefMode == URM_COPY )
@@ -2082,218 +2090,219 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
}
bOnRefMove = pCode->IsRecalcModeOnRefMove();
}
- if( bHasRefs || bOnRefMove )
+
+ 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* pRangeData = NULL;
+ bool bValChanged = false;
+ bool bRangeModified = false; // any range, not only shared formula
+ bool bRefSizeChanged = false;
+
+ if (bHasRefs)
{
- ScTokenArray* pOld = pUndoDoc ? pCode->Clone() : NULL;
- ScRangeData* pRangeData;
- bool bValChanged = false;
- bool bRangeModified = false; // any range, not only shared formula
- bool bRefSizeChanged = false;
- if ( bHasRefs )
- {
- ScCompiler aComp(pDocument, aPos, *pCode);
- aComp.SetGrammar(pDocument->GetGrammar());
- pRangeData = aComp.UpdateReference(eUpdateRefMode, aOldPos, r,
- nDx, nDy, nDz,
- bValChanged, bRefSizeChanged);
- bRangeModified = aComp.HasModifiedRange();
- }
- else
- {
- bValChanged = false;
- pRangeData = NULL;
- bRangeModified = false;
- bRefSizeChanged = false;
- }
+ // Update cell or range references.
+ ScCompiler aComp(pDocument, aPos, *pCode);
+ aComp.SetGrammar(pDocument->GetGrammar());
+ pRangeData = aComp.UpdateReference(eUpdateRefMode, aOldPos, rRange,
+ nDx, nDy, nDz,
+ bValChanged, bRefSizeChanged);
+ bRangeModified = aComp.HasModifiedRange();
+ }
+
+ bCellStateChanged |= bValChanged;
- bCellStateChanged |= bValChanged;
+ if (bOnRefMove)
+ // Cell may reference itself, e.g. ocColumn, ocRow without parameter
+ bOnRefMove = (bValChanged || (aPos != aOldPos));
- if ( bOnRefMove )
- bOnRefMove = (bValChanged || (aPos != aOldPos));
- // Cell may reference itself, e.g. ocColumn, ocRow without parameter
+ bool bColRowNameCompile = false;
+ bool bHasRelName = false;
+ bool bNewListening = false;
+ bool bInDeleteUndo = false;
- bool bColRowNameCompile, bHasRelName, bNewListening, bInDeleteUndo;
- if ( bHasRefs )
+ if (bHasRefs)
+ {
+ // 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 )
{
- // 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 )
{
- 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
- rRef.CalcAbsIfRel( aPos );
- ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
- ScRangePair* pR = pColList->Find( aAdr );
- if ( pR )
- { // defined
- if ( pR->GetRange(1).aStart.Row() == nRow1 )
- bColRowNameCompile = true;
- }
- else
- { // on the fly
- if ( rRef.nRow + 1 == nRow1 )
- bColRowNameCompile = true;
- }
+ ScSingleRefData& rRef = t->GetSingleRef();
+ if ( nDy > 0 && rRef.IsColRel() )
+ { // ColName
+ rRef.CalcAbsIfRel( aPos );
+ ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
+ ScRangePair* pR = pColList->Find( aAdr );
+ if ( pR )
+ { // defined
+ if ( pR->GetRange(1).aStart.Row() == nRow1 )
+ bColRowNameCompile = true;
}
- if ( nDx > 0 && rRef.IsRowRel() )
- { // RowName
- rRef.CalcAbsIfRel( aPos );
- ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
- ScRangePair* pR = pRowList->Find( aAdr );
- if ( pR )
- { // defined
- if ( pR->GetRange(1).aStart.Col() == nCol1 )
- bColRowNameCompile = true;
- }
- else
- { // on the fly
- if ( rRef.nCol + 1 == nCol1 )
- bColRowNameCompile = true;
- }
+ else
+ { // on the fly
+ if ( rRef.nRow + 1 == nRow1 )
+ bColRowNameCompile = true;
+ }
+ }
+ if ( nDx > 0 && rRef.IsRowRel() )
+ { // RowName
+ rRef.CalcAbsIfRel( aPos );
+ ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
+ ScRangePair* pR = pRowList->Find( aAdr );
+ if ( pR )
+ { // defined
+ if ( pR->GetRange(1).aStart.Col() == nCol1 )
+ bColRowNameCompile = true;
+ }
+ else
+ { // on the fly
+ if ( rRef.nCol + 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 )
+ }
+ 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 )
{
- 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();
+ rRef.CalcAbsIfRel( aPos );
+ if ( rRef.Valid() )
{
- ScSingleRefData& rRef = t->GetSingleRef();
- rRef.CalcAbsIfRel( aPos );
- if ( rRef.Valid() )
- {
- ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
- if ( r.In( aAdr ) )
- bColRowNameCompile = true;
- }
- t = static_cast<ScToken*>(pCode->GetNextColRowName());
+ ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
+ if ( rRange.In( aAdr ) )
+ bColRowNameCompile = true;
}
+ t = static_cast<ScToken*>(pCode->GetNextColRowName());
}
}
- else if ( eUpdateRefMode == URM_COPY && bHasColRowNames && bValChanged )
- {
- bColRowNameCompile = true;
- }
- ScChangeTrack* pChangeTrack = pDocument->GetChangeTrack();
- if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
- bInDeleteUndo = true;
- else
- bInDeleteUndo = false;
- // RelNameRefs are always moved
- bHasRelName = HasRelNameReference();
- // Reference changed and new listening needed?
- // Except in Insert/Delete without specialties.
- bNewListening = (bRangeModified || pRangeData || bColRowNameCompile
- || (bValChanged && (eUpdateRefMode != URM_INSDEL ||
- bInDeleteUndo || bRefSizeChanged)) ||
- (bHasRelName && eUpdateRefMode != URM_COPY))
- // #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() && r.In(aPos));
- if ( bNewListening )
- EndListeningTo( pDocument, pOld, aOldPos );
}
- else
+ else if ( eUpdateRefMode == URM_COPY && bHasColRowNames && bValChanged )
{
- bColRowNameCompile = bHasRelName = bNewListening = bInDeleteUndo =
- false;
+ bColRowNameCompile = true;
}
- bool bNeedDirty = false;
- // NeedDirty for changes except for Copy and Move/Insert without RelNames
- if ( bRangeModified || pRangeData || bColRowNameCompile ||
- (bValChanged && eUpdateRefMode != URM_COPY &&
- (eUpdateRefMode != URM_MOVE || bHasRelName) &&
- (!bIsInsert || bHasRelName || bInDeleteUndo ||
- bRefSizeChanged)) || bOnRefMove)
- bNeedDirty = true;
- else
- bNeedDirty = false;
- if (pUndoDoc && (bValChanged || pRangeData || 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).
+ ScChangeTrack* pChangeTrack = pDocument->GetChangeTrack();
+ bInDeleteUndo = (pChangeTrack && pChangeTrack->IsInDeleteUndo());
- // 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,
- pOld, eTempGrammar, cMatrixFlag );
- pFCell->aResult.SetToken( NULL); // to recognize it as changed later (Cut/Paste!)
- pUndoDoc->SetFormulaCell(aUndoPos, pFCell);
- }
- }
- bValChanged = false;
- if ( pRangeData )
- { // Replace shared formula with own formula
- pDocument->RemoveFromFormulaTree( this ); // update formula count
- delete pCode;
- pCode = pRangeData->GetCode()->Clone();
- // #i18937# #i110008# call MoveRelWrap, but with the old position
- ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
- ScCompiler aComp2(pDocument, aPos, *pCode);
- aComp2.SetGrammar(pDocument->GetGrammar());
- aComp2.UpdateSharedFormulaReference( eUpdateRefMode, aOldPos, r,
- nDx, nDy, nDz );
- bValChanged = true;
- bNeedDirty = true;
- }
- if ( ( bCompile = (bCompile || bValChanged || bRangeModified || bColRowNameCompile) ) != 0 )
+ // RelNameRefs are always moved
+ bHasRelName = HasRelNameReference();
+ // Reference changed and new listening needed?
+ // Except in Insert/Delete without specialties.
+ bNewListening = (bRangeModified || pRangeData || bColRowNameCompile
+ || (bValChanged && (eUpdateRefMode != URM_INSDEL ||
+ bInDeleteUndo || bRefSizeChanged)) ||
+ (bHasRelName && eUpdateRefMode != URM_COPY))
+ // #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));
+
+ if ( bNewListening )
+ EndListeningTo(pDocument, pOldCode.get(), aOldPos);
+ }
+
+ bool bNeedDirty = false;
+ // NeedDirty for changes except for Copy and Move/Insert without RelNames
+ if ( bRangeModified || pRangeData || bColRowNameCompile ||
+ (bValChanged && eUpdateRefMode != URM_COPY &&
+ (eUpdateRefMode != URM_MOVE || bHasRelName) &&
+ (!bIsInsert || bHasRelName || bInDeleteUndo ||
+ bRefSizeChanged)) || bOnRefMove)
+ bNeedDirty = true;
+
+ if (pUndoDoc && (bValChanged || pRangeData || 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 )
{
- CompileTokenArray( bNewListening ); // no Listening
- bNeedDirty = true;
+ 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);
}
- if ( !bInDeleteUndo )
- { // In ChangeTrack Delete-Reject listeners are established in
- // InsertCol/InsertRow
- if ( bNewListening )
+ }
+
+ bValChanged = false;
+
+ if ( pRangeData )
+ { // Replace shared formula with own formula
+ pDocument->RemoveFromFormulaTree( this ); // update formula count
+ delete pCode;
+ pCode = pRangeData->GetCode()->Clone();
+ // #i18937# #i110008# call MoveRelWrap, but with the old position
+ ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
+ ScCompiler aComp2(pDocument, aPos, *pCode);
+ aComp2.SetGrammar(pDocument->GetGrammar());
+ aComp2.UpdateSharedFormulaReference( eUpdateRefMode, 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 )
+ {
+ if ( eUpdateRefMode == URM_INSDEL )
{
- 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 );
+ // 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 );
}
- if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
- { // Cut off references, invalid or similar?
- bool bOldAutoCalc = pDocument->GetAutoCalc();
- // No Interpret in SubMinimalRecalc because of eventual wrong reference
- pDocument->SetAutoCalc( false );
- SetDirty();
- pDocument->SetAutoCalc( bOldAutoCalc );
- }
+ }
- delete pOld;
+ if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
+ { // Cut off references, invalid or similar?
+ sc::AutoCalcSwitch(*pDocument, false);
+ SetDirty();
}
+
return bCellStateChanged;
}
commit b5e8b51f8643eb7576335ca01d7bffa2462e62f5
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Thu Jun 27 14:03:27 2013 -0400
Reduce indentation to a sane level.
Change-Id: I2940ca21f8cee0d780e58cfcda50705be61568d9
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index ca8be5e..db84612 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4265,126 +4265,115 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
}
return pRangeData;
}
- else
+
+ ScRangeData* pRangeData = NULL;
+ ScToken* t;
+ pArr->Reset();
+ while( (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL )
{
- ScRangeData* pRangeData = NULL;
- ScToken* t;
- pArr->Reset();
- while( (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL )
+ if( t->GetOpCode() == ocName )
{
- if( t->GetOpCode() == ocName )
+ ScRangeData* pName = GetRangeData( *t);
+ if (pName && pName->HasType(RT_SHAREDMOD))
{
- ScRangeData* pName = GetRangeData( *t);
- if (pName && pName->HasType(RT_SHAREDMOD))
- {
- pRangeData = pName; // maybe need a replacement of shared with own code
- rChanged = true;
- }
- }
- else if( t->GetType() != svIndex ) // it may be a DB area!!!
- {
- t->CalcAbsIfRel( rOldPos );
- switch (t->GetType())
- {
- case svExternalSingleRef:
- case svExternalDoubleRef:
- // External references never change their positioning
- // nor point to parts that will be removed or expanded.
- // In fact, calling ScRefUpdate::Update() for URM_MOVE
- // may have negative side effects. Simply adapt
- // relative references to the new position.
- t->CalcRelFromAbs( aPos);
- break;
- case svSingleRef:
- {
- if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
- aPos, r, nDx, nDy, nDz,
- SingleDoubleRefModifier(
- t->GetSingleRef()).Ref())
- != UR_NOTHING)
- rChanged = true;
- }
- break;
- default:
- {
- ScComplexRefData& rRef = t->GetDoubleRef();
- SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
- SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
- SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
- if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
- aPos, r, nDx, nDy, nDz,
- t->GetDoubleRef()) != UR_NOTHING)
- {
- rChanged = true;
- if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
- rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
- rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
- rRefSizeChanged = true;
- }
- }
- }
+ pRangeData = pName; // maybe need a replacement of shared with own code
+ rChanged = true;
}
}
- pArr->Reset();
- while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
+ else if( t->GetType() != svIndex ) // it may be a DB area!!!
{
- if ( t->GetRef() != 1 )
+ t->CalcAbsIfRel( rOldPos );
+ switch (t->GetType())
{
- }
- else
- { // if nRefCnt>1 it's already updated in token code
- if ( t->GetType() == svSingleRef )
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ // External references never change their positioning
+ // nor point to parts that will be removed or expanded.
+ // In fact, calling ScRefUpdate::Update() for URM_MOVE
+ // may have negative side effects. Simply adapt
+ // relative references to the new position.
+ t->CalcRelFromAbs( aPos);
+ break;
+ case svSingleRef:
{
- ScSingleRefData& rRef = t->GetSingleRef();
- SingleDoubleRefModifier aMod( rRef );
- if ( rRef.IsRelName() )
- {
- ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, aMod.Ref() );
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ aPos, r, nDx, nDy, nDz,
+ SingleDoubleRefModifier(
+ t->GetSingleRef()).Ref())
+ != UR_NOTHING)
rChanged = true;
- }
- else
- {
- aMod.Ref().CalcAbsIfRel( rOldPos );
- if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
- r, nDx, nDy, nDz, aMod.Ref() )
- != UR_NOTHING
- )
- rChanged = true;
- }
}
- else
+ break;
+ default:
{
ScComplexRefData& rRef = t->GetDoubleRef();
SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
- if ( rRef.Ref1.IsRelName() || rRef.Ref2.IsRelName() )
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ aPos, r, nDx, nDy, nDz,
+ t->GetDoubleRef()) != UR_NOTHING)
{
- ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, rRef );
rChanged = true;
- }
- else
- {
- if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
- r, nDx, nDy, nDz, rRef )
- != UR_NOTHING
- )
- {
- rChanged = true;
- if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
- rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
- rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
- {
- rRefSizeChanged = true;
- }
- }
+ if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
+ rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
+ rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
+ rRefSizeChanged = true;
}
}
}
}
+ }
+ pArr->Reset();
+ while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
+ {
+ if (t->GetRef() != 1)
+ continue;
- return pRangeData;
+ if ( t->GetType() == svSingleRef )
+ {
+ ScSingleRefData& rRef = t->GetSingleRef();
+ SingleDoubleRefModifier aMod( rRef );
+ if ( rRef.IsRelName() )
+ {
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, aMod.Ref() );
+ rChanged = true;
+ }
+ else
+ {
+ aMod.Ref().CalcAbsIfRel( rOldPos );
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
+ r, nDx, nDy, nDz, aMod.Ref() )
+ != UR_NOTHING
+ )
+ rChanged = true;
+ }
+ }
+ else
+ {
+ ScComplexRefData& rRef = t->GetDoubleRef();
+ SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
+ SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
+ SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
+ if ( rRef.Ref1.IsRelName() || rRef.Ref2.IsRelName() )
+ {
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, rRef );
+ rChanged = true;
+ }
+ else if (ScRefUpdate::Update(pDoc, eUpdateRefMode, aPos, r, nDx, nDy, nDz, rRef) != UR_NOTHING)
+ {
+ rChanged = true;
+ if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
+ rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
+ rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
+ {
+ rRefSizeChanged = true;
+ }
+ }
+ }
}
+
+ return pRangeData;
}
bool ScCompiler::UpdateNameReference(UpdateRefMode eUpdateRefMode,
commit c8ed4d86bbdde79ea28c59742eac702f9622d57a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Thu Jun 27 13:52:50 2013 -0400
Remove this old attempt of shared formula code.
We'll devise a brand-new solution for this.
Change-Id: Ib4e04b3ce0b5d1ab511aecfab35f81e43dd4edf9
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 81cd26d..a3ab73d 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2055,7 +2055,6 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
if ( pUndoCellPos )
aUndoPos = *pUndoCellPos;
ScAddress aOldPos( aPos );
-// bool bPosChanged = false; // if this cell was moved
bool bIsInsert = (eUpdateRefMode == URM_INSDEL &&
nDx >= 0 && nDy >= 0 && nDz >= 0);
if (eUpdateRefMode == URM_INSDEL && r.In( aPos ))
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index d0ef4ad..ca8be5e 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4267,14 +4267,6 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
}
else
{
-/*
- * Set SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE to 1 if we wanted to preserve as
- * many shared formulas as possible instead of replacing them with direct code.
- * Note that this may produce shared formula usage Excel doesn't understand,
- * which would have to be adapted for in the export filter. Advisable as a long
- * term goal, since it could decrease memory footprint.
- */
-#define SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE 0
ScRangeData* pRangeData = NULL;
ScToken* t;
pArr->Reset();
@@ -4286,9 +4278,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
if (pName && pName->HasType(RT_SHAREDMOD))
{
pRangeData = pName; // maybe need a replacement of shared with own code
-#if ! SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
rChanged = true;
-#endif
}
}
else if( t->GetType() != svIndex ) // it may be a DB area!!!
@@ -4335,24 +4325,11 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
}
}
}
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
- bool bEasyShared, bPosInRange;
- if ( !pRangeData )
- bEasyShared = bPosInRange = false;
- else
- {
- bEasyShared = true;
- bPosInRange = r.In( eUpdateRefMode == URM_MOVE ? aPos : rOldPos );
- }
-#endif
pArr->Reset();
while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
{
if ( t->GetRef() != 1 )
{
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
- bEasyShared = false;
-#endif
}
else
{ // if nRefCnt>1 it's already updated in token code
@@ -4374,15 +4351,6 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
)
rChanged = true;
}
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
- if ( bEasyShared )
- {
- const ScSingleRefData& rSRD = aMod.Ref().Ref1;
- ScAddress aRef( rSRD.nCol, rSRD.nRow, rSRD.nTab );
- if ( r.In( aRef ) != bPosInRange )
- bEasyShared = false;
- }
-#endif
}
else
{
@@ -4408,35 +4376,13 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
{
rRefSizeChanged = true;
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
- bEasyShared = false;
-#endif
}
}
}
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
- if ( bEasyShared )
- {
- ScRange aRef( rRef.Ref1.nCol, rRef.Ref1.nRow,
- rRef.Ref1.nTab, rRef.Ref2.nCol, rRef.Ref2.nRow,
- rRef.Ref2.nTab );
- if ( r.In( aRef ) != bPosInRange )
- bEasyShared = false;
- }
-#endif
}
}
}
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
- if ( pRangeData )
- {
- if ( bEasyShared )
- pRangeData = 0;
- else
- rChanged = true;
- }
-#endif
-#undef SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+
return pRangeData;
}
}
commit d14e48591f2ede07626bfa8adde403d762a28d18
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Thu Jun 27 11:44:22 2013 -0400
A little more detail in the method documentation.
Change-Id: I0f25a8e660ff98d89965ff3428873dec43dbeda1
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index d38762a..b119d3d 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -312,11 +312,15 @@ public:
* Update reference addresses in formula cell in response to mass cell
* movement.
*
- * @param eUpdateRefMode update mode - insert/delete, copy, move,
- * reorder...
- * @param rRange range of cells that are about to be moved or copied.
- * (TODO: find out what this range means for the reorder
- * mode).
+ * @param eUpdateRefMode update mode - insert/delete, copy, or move. The
+ * reorder mode (which corresponds with the
+ * reordering of sheets) is not used with this
+ * method.
+ *
+ * @param rRange range of cells that are about to be moved for
+ * insert/delete/move modes. For copy mode, it's the
+ * destination range of cells that are about to be copied.
+ *
* @param nDx moved by how many cells in the column direction.
* @param nDy moved by how many cells in the row direction.
* @param nDz moved by how many sheets in the sheet direction.
commit bac886b75f3ce94178ba1751fc85cd4f2c5a9d0f
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Thu Jun 27 11:29:46 2013 -0400
ScColumn::UpdateReference to take ScRange as a parameter.
To reduce the number of parameters by 5. Also add *some* description
of this method esp what the range means when updating formula references.
Change-Id: Iccde58d6ecde6f0c09c111cf9b4f551ce392effb
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1c04e5d..d38762a 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -308,10 +308,27 @@ public:
void ResetChanged( SCROW nStartRow, SCROW nEndRow );
- 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 );
+ /**
+ * Update reference addresses in formula cell in response to mass cell
+ * movement.
+ *
+ * @param eUpdateRefMode update mode - insert/delete, copy, move,
+ * reorder...
+ * @param rRange range of cells that are about to be moved or copied.
+ * (TODO: find out what this range means for the reorder
+ * mode).
+ * @param nDx moved by how many cells in the column direction.
+ * @param nDy moved by how many cells in the row direction.
+ * @param nDz moved by how many sheets in the sheet direction.
+ * @param pUndoDoc undo document instance.
+ *
+ * @return true if reference of at least one formula cell has been
+ * updated, false otherwise.
+ */
+ bool UpdateReference(
+ UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScDocument* pUndoDoc = NULL );
+
void UpdateInsertTab(SCTAB nInsPos, SCTAB nNewSheets = 1);
void UpdateInsertTabOnlyCells(SCTAB nInsPos, SCTAB nNewSheets = 1);
void UpdateDeleteTab(SCTAB nDelPos, bool bIsMove, ScColumn* pRefUndo = NULL, SCTAB nSheets = 1);
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 8c53a69..9f75ad8 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1992,9 +1992,8 @@ void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
// UpdateUsed not needed, already done in TestCopyScenario (obsolete comment ?)
SCsTAB nDz = nTab - rSrcCol.nTab;
- UpdateReference(URM_COPY, nCol, nStart, nTab,
- nCol, nEnd, nTab,
- 0, 0, nDz, NULL);
+ UpdateReference(
+ URM_COPY, ScRange(nCol, nStart, nTab, nCol, nEnd, nTab), 0, 0, nDz, NULL);
UpdateCompile();
}
@@ -2023,9 +2022,9 @@ void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const
// UpdateUsed not needed, is already done in TestCopyScenario (obsolete comment ?)
SCsTAB nDz = rDestCol.nTab - nTab;
- rDestCol.UpdateReference(URM_COPY, rDestCol.nCol, nStart, rDestCol.nTab,
- rDestCol.nCol, nEnd, rDestCol.nTab,
- 0, 0, nDz, NULL);
+ rDestCol.UpdateReference(
+ URM_COPY, ScRange(rDestCol.nCol, nStart, rDestCol.nTab, rDestCol.nCol, nEnd, rDestCol.nTab),
+ 0, 0, nDz, NULL);
rDestCol.UpdateCompile();
}
@@ -2221,21 +2220,19 @@ public:
}
-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 ScColumn::UpdateReference(
+ UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScDocument* pUndoDoc )
{
- ScRange aRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
-
if (eUpdateRefMode == URM_COPY)
{
- UpdateRefOnCopy aHandler(aRange, nDx, nDy, nDz, pUndoDoc);
- FormulaCellsUndecided(nRow1, nRow2);
- sc::ProcessBlock(maCells.begin(), maCells, aHandler, nRow1, nRow2);
+ UpdateRefOnCopy aHandler(rRange, nDx, nDy, nDz, pUndoDoc);
+ FormulaCellsUndecided(rRange.aStart.Row(), rRange.aEnd.Row());
+ sc::ProcessBlock(maCells.begin(), maCells, aHandler, rRange.aStart.Row(), rRange.aEnd.Row());
return aHandler.isUpdated();
}
- UpdateRefOnNonCopy aHandler(nCol, nTab, aRange, nDx, nDy, nDz, eUpdateRefMode, pUndoDoc);
+ UpdateRefOnNonCopy aHandler(nCol, nTab, rRange, nDx, nDy, nDz, eUpdateRefMode, pUndoDoc);
FormulaCellsUndecided(0, MAXROW);
sc::ProcessFormula(maCells, aHandler);
return aHandler.isUpdated();
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index be6f4ae..2d90fa9 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -1463,16 +1463,14 @@ void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
iMax = MAXCOL;
}
+ ScRange aRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+
// Named expressions need to be updated before formulas acessing them.
if (mpRangeName)
- {
- ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );;
mpRangeName->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, true );
- }
for ( ; i<=iMax; i++)
- bUpdated |= aCol[i].UpdateReference(
- eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, pUndoDoc );
+ bUpdated |= aCol[i].UpdateReference(eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc);
if ( bIncludeDraw )
UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
commit cfc732b858befd0f9102cb0161e9afde424dcecf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jun 26 23:06:02 2013 -0400
No need to increment formula row positions in InsertRow().
UpdateReference() which gets called before InsertRow() moves the formula
positions.
Change-Id: I6d00607a1a1b4463f69bb58610f6ba41871e4475
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 36c3628..c66f3c0 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -237,6 +237,7 @@ public:
void testUpdateReference();
void testSearchCells();
void testSharedFormulas();
+ void testFormulaPosition();
/**
* Make sure the sheet streams are invalidated properly.
@@ -354,6 +355,7 @@ public:
CPPUNIT_TEST(testUpdateReference);
CPPUNIT_TEST(testSearchCells);
CPPUNIT_TEST(testSharedFormulas);
+ CPPUNIT_TEST(testFormulaPosition);
CPPUNIT_TEST(testJumpToPrecedentsDependents);
CPPUNIT_TEST(testSetBackgroundColor);
CPPUNIT_TEST(testRenameTable);
@@ -6405,6 +6407,76 @@ void Test::testSharedFormulas()
namespace {
+bool checkFormulaPosition(ScDocument& rDoc, const ScAddress& rPos)
+{
+ OUString aStr;
+ rPos.Format(aStr, SCA_VALID);
+ const ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
+ if (!pFC)
+ {
+ cerr << "Formula cell expected at " << aStr << " but not found." << endl;
+ return false;
+ }
+
+ if (pFC->aPos != rPos)
+ {
+ OUString aStr2;
+ pFC->aPos.Format(aStr2, SCA_VALID);
+ cerr << "Formula cell at " << aStr << " has incorrect position of " << aStr2 << endl;
+ return false;
+ }
+
+ return true;
+}
+
+void checkFormulaPositions(ScDocument& rDoc, const ScAddress& rPos, const SCROW* pRows, size_t nRowCount)
+{
+ ScAddress aPos = rPos;
+ for (size_t i = 0; i < nRowCount; ++i)
+ {
+ SCROW nRow = pRows[i];
+ aPos.SetRow(nRow);
+
+ if (!checkFormulaPosition(rDoc, aPos))
+ {
+ OUString aStr;
+ aPos.Format(aStr, SCA_VALID);
+ std::ostringstream os;
+ os << "Formula cell position failed at " << aStr;
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+ }
+}
+
+}
+
+void Test::testFormulaPosition()
+{
+ m_pDoc->InsertTab(0, "Test");
+
+ ScAddress aPos(0,0,0); // A1
+ m_pDoc->SetString(aPos, "=ROW()");
+ aPos.IncRow(); // A2
+ m_pDoc->SetString(aPos, "=ROW()");
+ aPos.SetRow(3); // A4;
+ m_pDoc->SetString(aPos, "=ROW()");
+
+ {
+ SCROW aRows[] = { 0, 1, 3 };
+ checkFormulaPositions(*m_pDoc, aPos, aRows, SAL_N_ELEMENTS(aRows));
+ }
+
+ m_pDoc->InsertRow(0,0,0,0,1,5); // Insert 5 rows at A2.
+ {
+ SCROW aRows[] = { 0, 6, 8 };
+ checkFormulaPositions(*m_pDoc, aPos, aRows, SAL_N_ELEMENTS(aRows));
+ }
+
+ m_pDoc->DeleteTab(0);
+}
+
+namespace {
+
bool hasRange(const std::vector<ScTokenRef>& rRefTokens, const ScRange& rRange)
{
std::vector<ScTokenRef>::const_iterator it = rRefTokens.begin(), itEnd = rRefTokens.end();
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 39bfd2f..8c53a69 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1233,43 +1233,9 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
maCellTextAttrs.insert_empty(nStartRow, nSize);
maCellTextAttrs.resize(MAXROWCOUNT);
- sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
- sc::CellStoreType::iterator it = maCells.insert_empty(aPos.first, nStartRow, nSize);
+ maCells.insert_empty(nStartRow, nSize);
maCells.resize(MAXROWCOUNT);
- sc::AutoCalcSwitch aSwitch(*pDocument, false);
-
- // Get the position of the first affected cell.
- aPos = maCells.position(it, nStartRow+nSize);
- it = aPos.first;
-
- // Update the positions of all affected formula cells.
- if (it->type == sc::element_type_formula)
- {
- sc::formula_block::iterator itf = sc::formula_block::begin(*it->data);
- sc::formula_block::iterator itfEnd = sc::formula_block::end(*it->data);
- std::advance(itf, aPos.second);
- for (; itf != itfEnd; ++itf)
- {
- ScFormulaCell& rCell = **itf;
- rCell.aPos.IncRow(nSize);
- }
- }
-
- for (++it; it != maCells.end(); ++it)
- {
- if (it->type != sc::element_type_formula)
- continue;
-
- sc::formula_block::iterator itf = sc::formula_block::begin(*it->data);
- sc::formula_block::iterator itfEnd = sc::formula_block::end(*it->data);
- for (; itf != itfEnd; ++itf)
- {
- ScFormulaCell* pCell = *itf;
- pCell->aPos.IncRow(nSize);
- }
- }
-
CellStorageModified();
// We *probably* don't need to broadcast here since the parent call seems
commit b5a195e65cd5de06e17e5a7aeb69024f8f8761c9
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jun 26 21:50:38 2013 -0400
More on shared formula cell handling.
Change-Id: Ifb0feff8c7016e3cadfa219ea6421852112ca189
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 78011ad..1c04e5d 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -476,6 +476,13 @@ public:
void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
/**
+ * Split existing shared formula range at specified position. The cell at
+ * specified position becomes the top cell of the lower shared formula
+ * range after this call.
+ */
+ void SplitFormulaCellGroup( const sc::CellStoreType::position_type& aPos ) const;
+
+ /**
* Regroup formula cells for the entire column.
*/
void RegroupFormulaCells();
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 5286965..36c3628 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6369,6 +6369,37 @@ void Test::testSharedFormulas()
CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow());
CPPUNIT_ASSERT_EQUAL(4, pFC->GetSharedLength());
+ // Extend B13:B16 to B13:B20.
+ aPos.SetRow(16); // B17
+ m_pDoc->SetString(aPos, "=A17*2");
+ aPos.IncRow();
+ m_pDoc->SetString(aPos, "=A18*2");
+ aPos.IncRow();
+ m_pDoc->SetString(aPos, "=A19*2");
+ aPos.IncRow();
+ m_pDoc->SetString(aPos, "=A20*2");
+ pFC = m_pDoc->GetFormulaCell(aPos);
+ CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
+ CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow());
+ CPPUNIT_ASSERT_EQUAL(8, pFC->GetSharedLength());
+
+#if 0
+ // Insert empty rows at B16 to split B13:B20 into B13:B15 and B21:B25.
+ m_pDoc->InsertRow(1, 0, 1, 0, 15, 5);
+
+ aPos.SetRow(12); // B13
+ pFC = m_pDoc->GetFormulaCell(aPos);
+ CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
+ CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow());
+ CPPUNIT_ASSERT_EQUAL(3, pFC->GetSharedLength());
+
+ aPos.SetRow(23); // B24
+ pFC = m_pDoc->GetFormulaCell(aPos);
+ CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
+ CPPUNIT_ASSERT_EQUAL(20, pFC->GetSharedTopRow());
+ CPPUNIT_ASSERT_EQUAL(5, pFC->GetSharedLength());
+#endif
+
m_pDoc->DeleteTab(0);
}
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 1e08708..39bfd2f 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1233,10 +1233,7 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
maCellTextAttrs.insert_empty(nStartRow, nSize);
maCellTextAttrs.resize(MAXROWCOUNT);
- // Check if this insertion will split an existing formula block.
sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
- bool bSplitFormulaBlock = aPos.second != 0;
-
sc::CellStoreType::iterator it = maCells.insert_empty(aPos.first, nStartRow, nSize);
maCells.resize(MAXROWCOUNT);
@@ -1254,8 +1251,8 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
std::advance(itf, aPos.second);
for (; itf != itfEnd; ++itf)
{
- ScFormulaCell* pCell = *itf;
- pCell->aPos.IncRow(nSize);
+ ScFormulaCell& rCell = **itf;
+ rCell.aPos.IncRow(nSize);
}
}
@@ -1273,9 +1270,6 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
}
}
- if (bSplitFormulaBlock)
- RegroupFormulaCells(nStartRow, nStartRow+nSize-1);
-
CellStorageModified();
// We *probably* don't need to broadcast here since the parent call seems
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index bfb5590..ee200f5 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -429,7 +429,7 @@ void ScColumn::UnshareFormulaCell(
#if DEBUG_COLUMN_STORAGE
if (aPos.second+1 >= aPos.first->size)
{
- cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl;
+ cerr << "ScColumn::UnshareFormulaCell: There is no next formula cell but there should be!" << endl;
cerr.flush();
abort();
}
@@ -454,7 +454,7 @@ void ScColumn::UnshareFormulaCell(
#if DEBUG_COLUMN_STORAGE
if (aPos.second == 0)
{
- cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl;
+ cerr << "ScColumn::UnshareFormulaCell: There is no previous formula cell but there should be!" << endl;
cerr.flush();
abort();
}
@@ -482,7 +482,7 @@ void ScColumn::UnshareFormulaCell(
#if DEBUG_COLUMN_STORAGE
if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
{
- cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl;
+ cerr << "ScColumn::UnshareFormulaCell: Shared formula region goes beyond the formula block. Not good." << endl;
cerr.flush();
abort();
}
@@ -501,6 +501,56 @@ void ScColumn::UnshareFormulaCell(
rCell.SetCellGroup(xNone);
}
+void ScColumn::SplitFormulaCellGroup( const sc::CellStoreType::position_type& aPos ) const
+{
+ SCROW nRow = aPos.first->position + aPos.second;
+
+ if (aPos.first->type != sc::element_type_formula)
+ // Not a formula cell block.
+ return;
+
+ if (aPos.second == 0)
+ // Split position coincides with the block border. Nothing to do.
+ return;
+
+ sc::formula_block::iterator it = sc::formula_block::begin(*aPos.first->data);
+ std::advance(it, aPos.second);
+ ScFormulaCell& rTop = **it;
+ if (!rTop.IsShared())
+ // Not a shared formula.
+ return;
+
+ if (nRow == rTop.GetSharedTopRow())
+ // Already the top cell of a shared group.
+ return;
+
+ ScFormulaCellGroupRef xGroup = rTop.GetCellGroup();
+
+ ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
+ xGroup2->mbInvariant = xGroup->mbInvariant;
+ xGroup2->mnStart = nRow;
+ xGroup2->mnLength = xGroup->mnStart + xGroup->mnLength - nRow;
+
+ xGroup->mnLength = nRow - xGroup->mnStart;
+
+ // Apply the lower group object to the lower cells.
+#if DEBUG_COLUMN_STORAGE
+ if (xGroup2->mnStart + xGroup2->mnLength > aPos.first->position + aPos.first->size)
+ {
+ cerr << "ScColumn::SplitFormulaCellGroup: Shared formula region goes beyond the formula block. Not good." << endl;
+ cerr.flush();
+ abort();
+ }
+#endif
+ sc::formula_block::iterator itEnd = it;
+ std::advance(itEnd, xGroup2->mnLength);
+ for (; it != itEnd; ++it)
+ {
+ ScFormulaCell& rCell = **it;
+ rCell.SetCellGroup(xGroup2);
+ }
+}
+
sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
{
// See if we are overwriting an existing formula cell.
commit ab030f75deafad4aab33ac47bfb36dd252e3515e
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jun 26 19:16:45 2013 -0400
Handle formula cells in SwapCell().
Change-Id: I9ddc69793e70bd399b93ce472a38060b1a946ff9
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index e29a8a6..1e08708 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1129,26 +1129,43 @@ void updateRefInFormulaCell( ScFormulaCell& rCell, SCCOL nCol, SCTAB nTab, SCCOL
void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
{
- ScFormulaCell* pCell1 = maCells.get<ScFormulaCell*>(nRow);
- ScFormulaCell* pCell2 = rCol.maCells.get<ScFormulaCell*>(nRow);
- if (pCell1)
- updateRefInFormulaCell(*pCell1, rCol.nCol, nTab, rCol.nCol - nCol);
+ sc::CellStoreType::position_type aPos1 = maCells.position(nRow);
+ sc::CellStoreType::position_type aPos2 = rCol.maCells.position(nRow);
- if (pCell2)
- updateRefInFormulaCell(*pCell2, nCol, nTab, nCol - rCol.nCol);
+ if (aPos1.first->type == sc::element_type_formula)
+ {
+ ScFormulaCell& rCell = *sc::formula_block::at(*aPos1.first->data, aPos1.second);
+ updateRefInFormulaCell(rCell, rCol.nCol, nTab, rCol.nCol - nCol);
+ UnshareFormulaCell(aPos1, rCell);
+ }
+
+ if (aPos2.first->type == sc::element_type_formula)
+ {
+ ScFormulaCell& rCell = *sc::formula_block::at(*aPos2.first->data, aPos2.second);
+ updateRefInFormulaCell(rCell, nCol, nTab, nCol - rCol.nCol);
+ UnshareFormulaCell(aPos2, rCell);
+ }
maCells.swap(nRow, nRow, rCol.maCells, nRow);
maCellTextAttrs.swap(nRow, nRow, rCol.maCellTextAttrs, nRow);
- CellStorageModified();
- rCol.CellStorageModified();
+ aPos1 = maCells.position(nRow);
+ aPos2 = rCol.maCells.position(nRow);
- if (pCell1 || pCell2)
+ if (aPos1.first->type == sc::element_type_formula)
{
- // At least one of the two cells is a formula cell. Regroup them.
- RegroupFormulaCells(nRow);
- rCol.RegroupFormulaCells(nRow);
+ ScFormulaCell& rCell = *sc::formula_block::at(*aPos1.first->data, aPos1.second);
+ JoinNewFormulaCell(aPos1, rCell);
}
+
+ if (aPos2.first->type == sc::element_type_formula)
+ {
+ ScFormulaCell& rCell = *sc::formula_block::at(*aPos2.first->data, aPos2.second);
+ rCol.JoinNewFormulaCell(aPos2, rCell);
+ }
+
+ CellStorageModified();
+ rCol.CellStorageModified();
}
commit a8153482ad4f918f3501aed34c3131e970592575
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jun 26 18:59:57 2013 -0400
Proper handling of formula cells in SwapRow().
Change-Id: Id295160b69cc5cb40cd9e0403928dac8b0e58807
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index a9aae2c..78011ad 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -147,8 +147,7 @@ public:
const sc::CellTextAttrStoreType& GetCellAttrStore() const { return maCellTextAttrs; }
ScRefCellValue GetCellValue( SCROW nRow ) const;
- ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const;
- ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const;
+ ScRefCellValue GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const;
void Delete( SCROW nRow );
void FreeAll();
@@ -468,6 +467,12 @@ public:
void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+ /**
+ * Detouch a formula cell that's about to be deleted, or removed from
+ * document storage (if that ever happens).
+ */
+ void DetouchFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+
void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
/**
@@ -497,6 +502,7 @@ private:
sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow );
sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow );
void ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell );
+ void ActivateNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell );
void BroadcastNewCell( SCROW nRow );
bool UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow );
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 9bf8dac..e29a8a6 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -763,17 +763,7 @@ ScRefCellValue ScColumn::GetCellValue( SCROW nRow ) const
return GetCellValue(aPos.first, aPos.second);
}
-ScRefCellValue ScColumn::GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const
-{
- std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(itPos, nRow);
- itPos = aPos.first;
- if (aPos.first == maCells.end())
- return ScRefCellValue();
-
- return GetCellValue(itPos, aPos.second);
-}
-
-ScRefCellValue ScColumn::GetCellValue( sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const
+ScRefCellValue ScColumn::GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const
{
ScRefCellValue aVal; // Defaults to empty cell.
switch (itPos->type)
@@ -820,8 +810,6 @@ ScFormulaCell* cloneFormulaCell(ScDocument* pDoc, const ScAddress& rNewPos, ScFo
void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
{
- typedef std::pair<sc::CellStoreType::iterator,size_t> CellPosType;
-
if (nRow1 == nRow2)
// Nothing to swap.
return;
@@ -832,11 +820,11 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
// Broadcasters (if exist) should NOT be swapped.
- CellPosType aPos1 = maCells.position(nRow1);
+ sc::CellStoreType::position_type aPos1 = maCells.position(nRow1);
if (aPos1.first == maCells.end())
return;
- CellPosType aPos2 = maCells.position(aPos1.first, nRow2);
+ sc::CellStoreType::position_type aPos2 = maCells.position(aPos1.first, nRow2);
if (aPos2.first == maCells.end())
return;
@@ -881,13 +869,15 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
// TODO: Find out a way to adjust references without cloning new instances.
boost::scoped_ptr<ScFormulaCell> pOld1(*itf1);
boost::scoped_ptr<ScFormulaCell> pOld2(*itf2);
+ DetouchFormulaCell(aPos1, **itf1);
+ DetouchFormulaCell(aPos2, **itf2);
ScFormulaCell* pNew1 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *pOld2);
ScFormulaCell* pNew2 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *pOld1);
*itf1 = pNew1;
*itf2 = pNew2;
- RegroupFormulaCells(nRow1);
- RegroupFormulaCells(nRow2);
+ ActivateNewFormulaCell(aPos1, *pNew1);
+ ActivateNewFormulaCell(aPos2, *pNew2);
}
break;
default:
@@ -902,10 +892,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
// The two cells are of different types.
- sc::CellStoreType::const_iterator cit = it1;
- ScRefCellValue aCell1 = GetCellValue(cit, nRow1);
- cit = it2;
- ScRefCellValue aCell2 = GetCellValue(cit, nRow2);
+ ScRefCellValue aCell1 = GetCellValue(aPos1.first, aPos1.second);
+ ScRefCellValue aCell2 = GetCellValue(aPos2.first, aPos2.second);
+
+ // Make sure to put cells in row 1 first then row 2!
if (aCell1.meType == CELLTYPE_NONE)
{
@@ -929,11 +919,12 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
break;
case CELLTYPE_FORMULA:
{
+ // cell 1 is empty and cell 2 is a formula cell.
ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
+ DetouchFormulaCell(aPos2, *aCell2.mpFormula);
it1 = maCells.set(it1, nRow1, pNew);
maCells.set_empty(it1, nRow2, nRow2); // original formula cell gets deleted.
-
- RegroupFormulaCells(nRow2);
+ ActivateNewFormulaCell(it1, nRow1, *pNew);
}
break;
default:
@@ -972,12 +963,12 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
break;
case CELLTYPE_FORMULA:
{
+ // cell 1 is a formula cell and cell 2 is empty.
ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula);
+ DetouchFormulaCell(aPos1, *aCell1.mpFormula);
it1 = maCells.set_empty(it1, nRow1, nRow1); // original formula cell is gone.
- maCells.set(it1, nRow2, pNew);
-
- RegroupFormulaCells(nRow1);
- RegroupFormulaCells(nRow2);
+ it1 = maCells.set(it1, nRow2, pNew);
+ ActivateNewFormulaCell(it1, nRow2, *pNew);
}
break;
default:
@@ -1009,8 +1000,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
break;
case CELLTYPE_FORMULA:
{
+ DetouchFormulaCell(aPos2, *aCell2.mpFormula);
ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
it1 = maCells.set(it1, nRow1, pNew);
+ ActivateNewFormulaCell(it1, nRow1, *pNew);
// The old formula cell will get overwritten below.
}
break;
@@ -1040,8 +1033,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
case CELLTYPE_FORMULA:
{
// cell 1 - string, cell 2 - formula
+ DetouchFormulaCell(aPos2, *aCell2.mpFormula);
ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
it1 = maCells.set(it1, nRow1, pNew);
+ ActivateNewFormulaCell(it1, nRow1, *pNew);
// Old formula cell will get overwritten below.
}
break;
@@ -1067,8 +1062,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
break;
case CELLTYPE_FORMULA:
{
+ DetouchFormulaCell(aPos2, *aCell2.mpFormula);
ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
it1 = maCells.set(it1, nRow1, pNew);
+ ActivateNewFormulaCell(it1, nRow1, *pNew);
// Old formula cell will get overwritten below.
}
break;
@@ -1081,6 +1078,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
break;
case CELLTYPE_FORMULA:
{
+ // cell 1 is a formula cell and cell 2 is not.
+ DetouchFormulaCell(aPos1, *aCell1.mpFormula);
ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula);
switch (aCell2.meType)
{
@@ -1101,7 +1100,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
;
}
- maCells.set(it1, nRow2, pNew);
+ it1 = maCells.set(it1, nRow2, pNew);
+ ActivateNewFormulaCell(it1, nRow2, *pNew);
}
break;
default:
@@ -1109,8 +1109,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
}
SwapCellTextAttrs(nRow1, nRow2);
- RegroupFormulaCells(nRow1);
- RegroupFormulaCells(nRow2);
CellStorageModified();
BroadcastCells(aRows);
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index b106ed6..bfb5590 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -398,6 +398,17 @@ void ScColumn::JoinNewFormulaCell(
}
}
+void ScColumn::DetouchFormulaCell(
+ const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
+{
+ if (!pDocument->IsClipOrUndo())
+ // Have the dying formula cell stop listening.
+ rCell.EndListeningTo(pDocument);
+
+ if (rCell.IsShared())
+ UnshareFormulaCell(aPos, rCell);
+}
+
void ScColumn::UnshareFormulaCell(
const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
{
@@ -498,12 +509,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
if (itRet->type == sc::element_type_formula)
{
ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aPos.second);
- if (!pDocument->IsClipOrUndo())
- // Have the dying formula cell stop listening.
- rCell.EndListeningTo(pDocument);
-
- if (rCell.IsShared())
- UnshareFormulaCell(aPos, rCell);
+ DetouchFormulaCell(aPos, rCell);
}
return itRet;
@@ -512,9 +518,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
void ScColumn::ActivateNewFormulaCell(
const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell )
{
- // See if this new formula cell can join an existing shared formula group.
- sc::CellStoreType::position_type aPos = maCells.position(itPos, nRow);
+ ActivateNewFormulaCell(maCells.position(itPos, nRow), rCell);
+}
+void ScColumn::ActivateNewFormulaCell(
+ const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell )
+{
+ // See if this new formula cell can join an existing shared formula group.
JoinNewFormulaCell(aPos, rCell);
// When we insert from the Clipboard we still have wrong (old) References!
commit 85ce60d4c43d35b9673ed22f4a4adaa4928349be
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jun 26 18:06:04 2013 -0400
Make this a member method too.
Change-Id: Ib1b16ce5a7a36560b04d4d57b585fdcf2a2b294d
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index d691e49..a9aae2c 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -466,6 +466,8 @@ public:
void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
+ void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+
void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
/**
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index b9d1309..b106ed6 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -327,6 +327,77 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
return GetPositionToInsert(maCells.begin(), nRow);
}
+namespace {
+
+void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
+{
+ ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
+ if (eState == ScFormulaCell::NotEqual)
+ return;
+
+ // Formula tokens equal those of the previous formula cell.
+ ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
+ ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
+ if (xGroup1)
+ {
+ if (xGroup2)
+ {
+ // Both cell1 and cell2 are shared. Merge them together.
+ xGroup1->mnLength += xGroup2->mnLength;
+ rCell2.SetCellGroup(xGroup1);
+ }
+ else
+ {
+ // cell1 is shared but cell2 is not.
+ rCell2.SetCellGroup(xGroup1);
+ ++xGroup1->mnLength;
+ }
+ }
+ else
+ {
+ if (xGroup2)
+ {
+ // cell1 is not shared, but cell2 is already shared.
+ rCell1.SetCellGroup(xGroup2);
+ xGroup2->mnStart = nRow;
+ ++xGroup2->mnLength;
+ }
+ else
+ {
+ // neither cells are shared.
+ xGroup1.reset(new ScFormulaCellGroup);
+ xGroup1->mnStart = nRow;
+ xGroup1->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
+ xGroup1->mnLength = 2;
+
+ rCell1.SetCellGroup(xGroup1);
+ rCell2.SetCellGroup(xGroup1);
+ }
+ }
+}
+
+}
+
+void ScColumn::JoinNewFormulaCell(
+ const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
+{
+ SCROW nRow = aPos.first->position + aPos.second;
+
+ // Check the previous row position for possible grouping.
+ if (aPos.first->type == sc::element_type_formula && aPos.second > 0)
+ {
+ ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
+ joinFormulaCells(nRow-1, rPrev, rCell);
+ }
+
+ // Check the next row position for possible grouping.
+ if (aPos.first->type == sc::element_type_formula && aPos.second+1 < aPos.first->size)
+ {
+ ScFormulaCell& rNext = *sc::formula_block::at(*aPos.first->data, aPos.second+1);
+ joinFormulaCells(nRow, rCell, rNext);
+ }
+}
+
void ScColumn::UnshareFormulaCell(
const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
{
@@ -438,76 +509,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
return itRet;
}
-namespace {
-
-void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
-{
- ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
- if (eState == ScFormulaCell::NotEqual)
- return;
-
- // Formula tokens equal those of the previous formula cell.
- ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
- ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
- if (xGroup1)
- {
- if (xGroup2)
- {
- // Both cell1 and cell2 are shared. Merge them together.
- xGroup1->mnLength += xGroup2->mnLength;
- rCell2.SetCellGroup(xGroup1);
- }
- else
- {
- // cell1 is shared but cell2 is not.
- rCell2.SetCellGroup(xGroup1);
- ++xGroup1->mnLength;
- }
- }
- else
- {
- if (xGroup2)
- {
- // cell1 is not shared, but cell2 is already shared.
- rCell1.SetCellGroup(xGroup2);
- xGroup2->mnStart = nRow;
- ++xGroup2->mnLength;
- }
- else
- {
- // neither cells are shared.
- xGroup1.reset(new ScFormulaCellGroup);
- xGroup1->mnStart = nRow;
- xGroup1->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
- xGroup1->mnLength = 2;
-
- rCell1.SetCellGroup(xGroup1);
- rCell2.SetCellGroup(xGroup1);
- }
- }
-}
-
-}
-
void ScColumn::ActivateNewFormulaCell(
const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell )
{
// See if this new formula cell can join an existing shared formula group.
sc::CellStoreType::position_type aPos = maCells.position(itPos, nRow);
- // Check the previous row position for possible grouping.
- if (aPos.first->type == sc::element_type_formula && aPos.second > 0)
- {
- ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
- joinFormulaCells(nRow-1, rPrev, rCell);
- }
-
- // Check the next row position for possible grouping.
- if (aPos.first->type == sc::element_type_formula && aPos.second+1 < aPos.first->size)
- {
- ScFormulaCell& rNext = *sc::formula_block::at(*aPos.first->data, aPos.second+1);
- joinFormulaCells(nRow, rCell, rNext);
- }
+ JoinNewFormulaCell(aPos, rCell);
// When we insert from the Clipboard we still have wrong (old) References!
// First they are rewired in CopyBlockFromClip via UpdateReference and the
commit a37a2c3b28b51abf1c54c49efd03329f8b3cc1ae
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jun 26 17:57:34 2013 -0400
Make this a member method of ScColumn.
Change-Id: I5d0a573d277338ddef60fdd58bfb1f5ba7fc695e
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 44946c4..d691e49 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -466,6 +466,8 @@ public:
void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
+ void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+
/**
* Regroup formula cells for the entire column.
*/
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 216b318..b9d1309 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -327,13 +327,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
return GetPositionToInsert(maCells.begin(), nRow);
}
-namespace {
-
-/**
- * Re-group a shared formula cell that's being overwritten.
- */
-void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell)
+void ScColumn::UnshareFormulaCell(
+ const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
{
+ if (!rCell.IsShared())
+ return;
+
+ ScFormulaCellGroupRef xNone;
sc::CellStoreType::iterator it = aPos.first;
// This formula cell is shared. Adjust the shared group.
@@ -352,7 +352,6 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor
abort();
}
#endif
- ScFormulaCellGroupRef xNone;
ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
rNext.SetCellGroup(xNone);
}
@@ -378,7 +377,6 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor
abort();
}
#endif
- ScFormulaCellGroupRef xNone;
ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1);
rPrev.SetCellGroup(xNone);
}
@@ -417,8 +415,8 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor
rCell2.SetCellGroup(xGroup2);
}
}
-}
+ rCell.SetCellGroup(xNone);
}
sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
@@ -434,7 +432,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
rCell.EndListeningTo(pDocument);
if (rCell.IsShared())
- adjustSharedFormulaCell(aPos, rCell);
+ UnshareFormulaCell(aPos, rCell);
}
return itRet;
commit 2b300a9e90f40f8b890d6de522aa1ea8e7c0d74a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jun 26 17:43:18 2013 -0400
We don't need this formula group vector.
Change-Id: I96f3b19a5bb0d761b7abd943df6a2e48cfcbf9bd
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 322d7a6..44946c4 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -110,8 +110,6 @@ class ScColumn
SCCOL nCol;
SCTAB nTab;
- std::vector<ScFormulaCellGroupRef> maFnGroups;
-
ScAttrArray* pAttrArray;
ScDocument* pDocument;
bool mbDirtyGroups; /// formula groups are dirty.
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 6cb19db..216b318 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2713,11 +2713,9 @@ public:
class GroupFormulaCells
{
- std::vector<ScFormulaCellGroupRef>& mrFnGroups;
ScFormulaCellGroupRef mxNone;
public:
- GroupFormulaCells(std::vector<ScFormulaCellGroupRef>& rFnGroups) : mrFnGroups(rFnGroups) {}
void operator() (sc::CellStoreType::value_type& node)
{
@@ -2755,8 +2753,6 @@ public:
xGroup->mbInvariant = (eCompState == ScFormulaCell::EqualInvariant);
xGroup->mnLength = 2;
- mrFnGroups.push_back(xGroup);
-
pCur->SetCellGroup(xGroup);
pPrev->SetCellGroup(xGroup);
}
@@ -2783,10 +2779,9 @@ void ScColumn::RebuildFormulaGroups()
ScFormulaCellGroupRef xNone;
CellGroupSetter aFunc(xNone);
sc::ProcessFormula(maCells, aFunc);
- maFnGroups.clear();
// re-build formula groups.
- std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells(maFnGroups));
+ std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells());
mbDirtyGroups = false;
}
commit 58d309f141621840047d5ee587a0adc8017289bf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jun 26 17:37:23 2013 -0400
Extract this code block into an own function.
Change-Id: I6abe520ad6392e4f9163434b73f3b3ab88a71297
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index cc422bc..6cb19db 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -327,103 +327,115 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
return GetPositionToInsert(maCells.begin(), nRow);
}
-sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
+namespace {
+
+/**
+ * Re-group a shared formula cell that's being overwritten.
+ */
+void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell)
{
- // See if we are overwriting an existing formula cell.
- sc::CellStoreType::position_type aRet = maCells.position(it, nRow);
- sc::CellStoreType::iterator itRet = aRet.first;
- if (itRet->type == sc::element_type_formula)
- {
- ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aRet.second);
- if (!pDocument->IsClipOrUndo())
- // Have the dying formula cell stop listening.
- rCell.EndListeningTo(pDocument);
+ sc::CellStoreType::iterator it = aPos.first;
- if (rCell.IsShared())
+ // This formula cell is shared. Adjust the shared group.
+ if (rCell.aPos.Row() == rCell.GetSharedTopRow())
+ {
+ // Top of the shared range.
+ ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
+ if (xGroup->mnLength == 2)
{
- // This formula cell is shared. Adjust the shared group.
- if (rCell.aPos.Row() == rCell.GetSharedTopRow())
- {
- // Top of the shared range.
- ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
- if (xGroup->mnLength == 2)
- {
- // Group consists only only two cells. Mark the second one non-shared.
+ // Group consists only only two cells. Mark the second one non-shared.
#if DEBUG_COLUMN_STORAGE
- if (aRet.second+1 >= aRet.first->size)
- {
- cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl;
- cerr.flush();
- abort();
- }
-#endif
- ScFormulaCellGroupRef xNone;
- ScFormulaCell& rNext = *sc::formula_block::at(*itRet->data, aRet.second+1);
- rNext.SetCellGroup(xNone);
- }
- else
- {
- // Move the top cell to the next formula cell down.
- --xGroup->mnLength;
- ++xGroup->mnStart;
- }
- }
- else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1)
+ if (aPos.second+1 >= aPos.first->size)
{
- // Bottom of the shared range.
- ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
- if (xGroup->mnLength == 2)
- {
- // Mark the top cell non-shared.
-#if DEBUG_COLUMN_STORAGE
- if (aRet.second == 0)
- {
- cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl;
- cerr.flush();
- abort();
- }
-#endif
- ScFormulaCellGroupRef xNone;
- ScFormulaCell& rPrev = *sc::formula_block::at(*itRet->data, aRet.second-1);
- rPrev.SetCellGroup(xNone);
- }
- else
- {
- // Just shortern the shared range length by one.
- --xGroup->mnLength;
- }
+ cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl;
+ cerr.flush();
+ abort();
}
- else
+#endif
+ ScFormulaCellGroupRef xNone;
+ ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
+ rNext.SetCellGroup(xNone);
+ }
+ else
+ {
+ // Move the top cell to the next formula cell down.
+ --xGroup->mnLength;
+ ++xGroup->mnStart;
+ }
+ }
+ else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1)
+ {
+ // Bottom of the shared range.
+ ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
+ if (xGroup->mnLength == 2)
+ {
+ // Mark the top cell non-shared.
+#if DEBUG_COLUMN_STORAGE
+ if (aPos.second == 0)
{
- // In the middle of the shared range. Split it into two groups.
- ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
- SCROW nEndRow = xGroup->mnStart + xGroup->mnLength - 1;
- xGroup->mnLength = rCell.aPos.Row() - xGroup->mnStart; // Shorten the top group.
-
- ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
- xGroup2->mnStart = rCell.aPos.Row() + 1;
- xGroup2->mnLength = nEndRow - rCell.aPos.Row();
- xGroup2->mbInvariant = xGroup->mbInvariant;
+ cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl;
+ cerr.flush();
+ abort();
+ }
+#endif
+ ScFormulaCellGroupRef xNone;
+ ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1);
+ rPrev.SetCellGroup(xNone);
+ }
+ else
+ {
+ // Just shortern the shared range length by one.
+ --xGroup->mnLength;
+ }
+ }
+ else
+ {
+ // In the middle of the shared range. Split it into two groups.
+ ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
+ SCROW nEndRow = xGroup->mnStart + xGroup->mnLength - 1;
+ xGroup->mnLength = rCell.aPos.Row() - xGroup->mnStart; // Shorten the top group.
+
+ ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
+ xGroup2->mnStart = rCell.aPos.Row() + 1;
+ xGroup2->mnLength = nEndRow - rCell.aPos.Row();
+ xGroup2->mbInvariant = xGroup->mbInvariant;
#if DEBUG_COLUMN_STORAGE
- if (xGroup2->mnStart + xGroup2->mnLength > itRet->position + itRet->size)
- {
- cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl;
- cerr.flush();
- abort();
- }
+ if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
+ {
+ cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl;
+ cerr.flush();
+ abort();
+ }
#endif
- sc::formula_block::iterator itCell = sc::formula_block::begin(*itRet->data);
- std::advance(itCell, aRet.second+1);
- sc::formula_block::iterator itCellEnd = itCell;
- std::advance(itCellEnd, xGroup2->mnLength);
- for (; itCell != itCellEnd; ++itCell)
- {
- ScFormulaCell& rCell2 = **itCell;
- rCell2.SetCellGroup(xGroup2);
- }
- }
+ sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data);
+ std::advance(itCell, aPos.second+1);
+ sc::formula_block::iterator itCellEnd = itCell;
+ std::advance(itCellEnd, xGroup2->mnLength);
+ for (; itCell != itCellEnd; ++itCell)
+ {
+ ScFormulaCell& rCell2 = **itCell;
+ rCell2.SetCellGroup(xGroup2);
}
}
+}
+
+}
+
+sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
+{
+ // See if we are overwriting an existing formula cell.
+ sc::CellStoreType::position_type aPos = maCells.position(it, nRow);
+ sc::CellStoreType::iterator itRet = aPos.first;
+ if (itRet->type == sc::element_type_formula)
+ {
+ ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aPos.second);
+ if (!pDocument->IsClipOrUndo())
+ // Have the dying formula cell stop listening.
+ rCell.EndListeningTo(pDocument);
+
+ if (rCell.IsShared())
+ adjustSharedFormulaCell(aPos, rCell);
+ }
return itRet;
}
commit 13822d7a7a9c30248f4f58d4768a6b2acddade2e
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jun 26 15:56:46 2013 -0400
Don't forget to transfer this too when splitting group.
Change-Id: I3337504f6b95f273106e809da90d089cd76d8bdb
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index c66e9d5e..cc422bc 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -403,6 +403,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
xGroup2->mnStart = rCell.aPos.Row() + 1;
xGroup2->mnLength = nEndRow - rCell.aPos.Row();
+ xGroup2->mbInvariant = xGroup->mbInvariant;
#if DEBUG_COLUMN_STORAGE
if (xGroup2->mnStart + xGroup2->mnLength > itRet->position + itRet->size)
{
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list