summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/formulacell.hxx5
-rw-r--r--sc/inc/sharedformula.hxx2
-rw-r--r--sc/qa/unit/filters-test.cxx4
-rw-r--r--sc/source/core/data/column3.cxx4
-rw-r--r--sc/source/core/data/formulacell.cxx23
-rw-r--r--sc/source/core/tool/sharedformula.cxx26
-rw-r--r--sc/source/filter/excel/excform.cxx2
-rw-r--r--sc/source/filter/excel/impop.cxx1
-rw-r--r--sc/source/filter/excel/namebuff.cxx5
-rw-r--r--sc/source/filter/oox/formulabuffer.cxx2
10 files changed, 36 insertions, 38 deletions
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index c151e06a80c2..a6200c9ca0e8 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -48,6 +48,7 @@ class DynamicKernel;
}
+class ScFormulaCell;
class ScProgress;
class ScTokenArray;
struct ScSimilarFormulaDelta;
@@ -58,7 +59,7 @@ struct SC_DLLPUBLIC ScFormulaCellGroup : boost::noncopyable
ScTokenArray* mpCode;
sc::opencl::DynamicKernel* mpDynamicKernel;
- SCROW mnStart; // Start offset of that cell
+ ScFormulaCell *mpTopCell;
SCROW mnLength; // How many of these do we have ?
short mnFormatType;
bool mbInvariant:1;
@@ -347,7 +348,7 @@ public:
/**
* Turn a non-grouped cell into the top of a grouped cell.
*/
- ScFormulaCellGroupRef CreateCellGroup( SCROW nStart, SCROW nLen, bool bInvariant );
+ ScFormulaCellGroupRef CreateCellGroup( SCROW nLen, bool bInvariant );
ScFormulaCellGroupRef GetCellGroup();
void SetCellGroup( const ScFormulaCellGroupRef &xRef );
diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx
index 11493e6468b4..571d73c5e2e4 100644
--- a/sc/inc/sharedformula.hxx
+++ b/sc/inc/sharedformula.hxx
@@ -48,7 +48,7 @@ public:
}
// Create a new group.
- xGroup = pPrev->CreateCellGroup(pPrev->aPos.Row(), 2, eState == ScFormulaCell::EqualInvariant);
+ xGroup = pPrev->CreateCellGroup(2, eState == ScFormulaCell::EqualInvariant);
pCur->SetCellGroup(xGroup);
}
}
diff --git a/sc/qa/unit/filters-test.cxx b/sc/qa/unit/filters-test.cxx
index ce5f4b462e07..d12ea6098687 100644
--- a/sc/qa/unit/filters-test.cxx
+++ b/sc/qa/unit/filters-test.cxx
@@ -364,7 +364,7 @@ void ScFiltersTest::testSharedFormulaXLS()
CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pCell);
ScFormulaCellGroupRef xGroup = pCell->GetCellGroup();
CPPUNIT_ASSERT_MESSAGE("This cell should be a part of a cell group.", xGroup);
- CPPUNIT_ASSERT_MESSAGE("Incorrect group geometry.", xGroup->mnStart == 1 && xGroup->mnLength == 18);
+ CPPUNIT_ASSERT_MESSAGE("Incorrect group geometry.", xGroup->mpTopCell->aPos.Row() == 1 && xGroup->mnLength == 18);
xDocSh->DoClose();
}
@@ -387,7 +387,7 @@ void ScFiltersTest::testSharedFormulaXLSX()
CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pCell);
ScFormulaCellGroupRef xGroup = pCell->GetCellGroup();
CPPUNIT_ASSERT_MESSAGE("This cell should be a part of a cell group.", xGroup);
- CPPUNIT_ASSERT_MESSAGE("Incorrect group geometry.", xGroup->mnStart == 1 && xGroup->mnLength == 18);
+ CPPUNIT_ASSERT_MESSAGE("Incorrect group geometry.", xGroup->mpTopCell->aPos.Row() == 1 && xGroup->mnLength == 18);
xDocSh->DoClose();
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index a40093546169..141240f029b0 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2786,14 +2786,14 @@ public:
nRow += xCurGrp->mnLength;
std::advance(it, xCurGrp->mnLength);
pPrev->SetCellGroup(xCurGrp);
- --xCurGrp->mnStart;
+ --xCurGrp->mpTopCell = pPrev;
++xCurGrp->mnLength;
xPrevGrp = xCurGrp;
}
else
{
// Both previous and current cells are regular cells.
- xPrevGrp = pPrev->CreateCellGroup(nRow - 1, 2, eCompState == ScFormulaCell::EqualInvariant);
+ xPrevGrp = pPrev->CreateCellGroup(2, eCompState == ScFormulaCell::EqualInvariant);
pCur->SetCellGroup(xPrevGrp);
++nRow;
++it;
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 036005c289b6..3ab19a666476 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -407,7 +407,7 @@ ScFormulaCellGroup::ScFormulaCellGroup() :
mnRefCount(0),
mpCode(NULL),
mpDynamicKernel(NULL),
- mnStart(0),
+ mpTopCell(NULL),
mnLength(0),
mnFormatType(NUMBERFORMAT_NUMBER),
mbInvariant(false),
@@ -2321,12 +2321,6 @@ bool ScFormulaCell::UpdatePosOnShift( const sc::RefUpdateContext& rCxt )
// This formula cell itself is being shifted during cell range
// insertion or deletion. Update its position.
-
- if (mxGroup && (mxGroup->mnStart+mxGroup->mnLength-1) == aPos.Row())
- // For a shared formula cell, update its group start position only
- // when it's the last cell of the group.
- mxGroup->mnStart += rCxt.mnRowDelta;
-
aPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
return true;
@@ -2751,7 +2745,7 @@ bool ScFormulaCell::UpdateReference(
if (pDocument->IsClipOrUndo())
return false;
- if (mxGroup && mxGroup->mnStart != aPos.Row())
+ if (mxGroup && mxGroup->mpTopCell != this)
{
// This is not a top cell of a formula group. Don't update references.
@@ -3314,14 +3308,14 @@ ScFormulaCell* ScFormulaCell::GetNextTrack() const { return
void ScFormulaCell::SetPreviousTrack( ScFormulaCell* pF ) { pPreviousTrack = pF; }
void ScFormulaCell::SetNextTrack( ScFormulaCell* pF ) { pNextTrack = pF; }
-ScFormulaCellGroupRef ScFormulaCell::CreateCellGroup( SCROW nStart, SCROW nLen, bool bInvariant )
+ScFormulaCellGroupRef ScFormulaCell::CreateCellGroup( SCROW nLen, bool bInvariant )
{
if (mxGroup)
// You can't create a new group if the cell is already a part of a group.
return ScFormulaCellGroupRef();
mxGroup.reset(new ScFormulaCellGroup);
- mxGroup->mnStart = nStart;
+ mxGroup->mpTopCell = this;
mxGroup->mbInvariant = bInvariant;
mxGroup->mnLength = nLen;
mxGroup->mpCode = pCode; // Move this to the shared location.
@@ -3697,8 +3691,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
return InterpretInvariantFormulaGroup();
ScTokenArray aCode;
- ScAddress aTopPos = aPos;
- aTopPos.SetRow(mxGroup->mnStart);
+ ScAddress aTopPos = mxGroup->mpTopCell->aPos;
GroupTokenConverter aConverter(aCode, *pDocument, *this, aTopPos);
if (!aConverter.convert(*pCode))
{
@@ -3776,7 +3769,7 @@ bool ScFormulaCell::InterpretInvariantFormulaGroup()
for ( sal_Int32 i = 0; i < mxGroup->mnLength; i++ )
{
ScAddress aTmpPos = aPos;
- aTmpPos.SetRow(mxGroup->mnStart + i);
+ aTmpPos.SetRow(mxGroup->mpTopCell->aPos.Row() + i);
ScFormulaCell* pCell = pDocument->GetFormulaCell(aTmpPos);
assert( pCell != NULL );
@@ -4014,12 +4007,12 @@ bool ScFormulaCell::IsSharedTop() const
if (!mxGroup)
return false;
- return mxGroup->mnStart == aPos.Row();
+ return mxGroup->mpTopCell == this;
}
SCROW ScFormulaCell::GetSharedTopRow() const
{
- return mxGroup ? mxGroup->mnStart : -1;
+ return mxGroup ? mxGroup->mpTopCell->aPos.Row() : -1;
}
SCROW ScFormulaCell::GetSharedLength() const
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index 6583ac901e13..20eef831a956 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -38,18 +38,18 @@ void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type
ScFormulaCellGroupRef xGroup = rTop.GetCellGroup();
- SCROW nLength2 = xGroup->mnStart + xGroup->mnLength - nRow;
+ SCROW nLength2 = xGroup->mpTopCell->aPos.Row() + xGroup->mnLength - nRow;
ScFormulaCellGroupRef xGroup2;
if (nLength2 > 1)
{
xGroup2.reset(new ScFormulaCellGroup);
xGroup2->mbInvariant = xGroup->mbInvariant;
- xGroup2->mnStart = nRow;
+ xGroup2->mpTopCell = &rTop;
xGroup2->mnLength = nLength2;
xGroup2->mpCode = xGroup->mpCode->Clone();
}
- xGroup->mnLength = nRow - xGroup->mnStart;
+ xGroup->mnLength = nRow - xGroup->mpTopCell->aPos.Row();
if (xGroup->mnLength == 1)
{
// The top group consists of only one cell. Ungroup this.
@@ -60,7 +60,7 @@ void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type
// Apply the lower group object to the lower cells.
#if DEBUG_COLUMN_STORAGE
- if (xGroup2->mnStart + xGroup2->mnLength > aPos.first->position + aPos.first->size)
+ if (xGroup2->mpTopCell->aPos.Row() + xGroup2->mnLength > aPos.first->position + aPos.first->size)
{
cerr << "ScColumn::SplitFormulaCellGroup: Shared formula region goes beyond the formula block. Not good." << endl;
cerr.flush();
@@ -111,8 +111,6 @@ void SharedFormulaUtil::joinFormulaCells(const CellStoreType::position_type& rPo
if (eState == ScFormulaCell::NotEqual)
return;
- SCROW nRow = rPos.first->position + rPos.second;
-
// Formula tokens equal those of the previous formula cell.
ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
@@ -147,13 +145,13 @@ void SharedFormulaUtil::joinFormulaCells(const CellStoreType::position_type& rPo
{
// cell 1 is not shared, but cell 2 is already shared.
rCell1.SetCellGroup(xGroup2);
- xGroup2->mnStart = nRow;
+ xGroup2->mpTopCell = &rCell1;
++xGroup2->mnLength;
}
else
{
// neither cells are shared.
- xGroup1 = rCell1.CreateCellGroup(nRow, 2, eState == ScFormulaCell::EqualInvariant);
+ xGroup1 = rCell1.CreateCellGroup(2, eState == ScFormulaCell::EqualInvariant);
rCell2.SetCellGroup(xGroup1);
}
}
@@ -207,8 +205,9 @@ void SharedFormulaUtil::unshareFormulaCell(const CellStoreType::position_type& a
else
{
// Move the top cell to the next formula cell down.
+ ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
--xGroup->mnLength;
- ++xGroup->mnStart;
+ xGroup->mpTopCell = &rNext;
}
}
else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1)
@@ -239,8 +238,8 @@ void SharedFormulaUtil::unshareFormulaCell(const CellStoreType::position_type& a
{
// 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.
+ SCROW nEndRow = xGroup->mpTopCell->aPos.Row() + xGroup->mnLength - 1;
+ xGroup->mnLength = rCell.aPos.Row() - xGroup->mpTopCell->aPos.Row(); // Shorten the top group.
if (xGroup->mnLength == 1)
{
// Make the top cell non-shared.
@@ -261,12 +260,13 @@ void SharedFormulaUtil::unshareFormulaCell(const CellStoreType::position_type& a
{
ScFormulaCellGroupRef xGroup2;
xGroup2.reset(new ScFormulaCellGroup);
- xGroup2->mnStart = rCell.aPos.Row() + 1;
+ ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
+ xGroup2->mpTopCell = &rNext;
xGroup2->mnLength = nLength2;
xGroup2->mbInvariant = xGroup->mbInvariant;
xGroup2->mpCode = xGroup->mpCode->Clone();
#if DEBUG_COLUMN_STORAGE
- if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
+ if (xGroup2->mpTopCell->aPos.Row() + xGroup2->mnLength > it->position + it->size)
{
cerr << "ScColumn::UnshareFormulaCell: Shared formula region goes beyond the formula block. Not good." << endl;
cerr.flush();
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 5ce657eb01fd..06e14b2fac39 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -135,7 +135,7 @@ void ImportExcel::Formula(
ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, xGroup);
rDoc.getDoc().EnsureTable(aScPos.Tab());
rDoc.setFormulaCell(aScPos, pCell);
- xGroup->mnLength = aScPos.Row() - xGroup->mnStart + 1;
+ xGroup->mnLength = aScPos.Row() - xGroup->mpTopCell->aPos.Row() + 1;
pCell->SetNeedNumberFormat(false);
if (!rtl::math::isNan(fCurVal))
pCell->SetResultDouble(fCurVal);
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index 507a90482766..bda23cb20574 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -889,6 +889,7 @@ void ImportExcel::Shrfmla( void )
xGroup->compileCode(rDoc.getDoc(), aPos, formula::FormulaGrammar::GRAM_DEFAULT);
ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, xGroup);
+ xGroup->mpTopCell = pCell;
rDoc.getDoc().EnsureTable(aPos.Tab());
rDoc.setFormulaCell(aPos, pCell);
pCell->SetNeedNumberFormat(false);
diff --git a/sc/source/filter/excel/namebuff.cxx b/sc/source/filter/excel/namebuff.cxx
index 43a1adb175e0..1456c89a7c99 100644
--- a/sc/source/filter/excel/namebuff.cxx
+++ b/sc/source/filter/excel/namebuff.cxx
@@ -86,7 +86,10 @@ void SharedFormulaBuffer::Store( const ScRange& rRange, const ScTokenArray& rArr
aPos.SetCol(i);
ScFormulaCellGroupRef xNewGroup(new ScFormulaCellGroup);
- xNewGroup->mnStart = rRange.aStart.Row();
+ // We have no ScFormulaCell yet to point mpTopCell to!?
+ // Let's hope that the only called of this in ImportExcel::Shrfmla()
+ // fixes that up properly.
+ xNewGroup->mpTopCell = NULL;
xNewGroup->mnLength = 1;
xNewGroup->setCode(rArray);
maFormulaGroups.insert(FormulaGroupsType::value_type(aPos, xNewGroup));
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 4303b41a0b88..ca48ecab3914 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -198,7 +198,7 @@ void applyCellFormulas(
ScFormulaCellGroupRef xGroup = rPrev.GetCellGroup();
if (!xGroup)
// Last cell is not grouped yet. Start a new group.
- xGroup = rPrev.CreateCellGroup(p->mnRow, 1, false);
+ xGroup = rPrev.CreateCellGroup(p->mnRow, false);
++xGroup->mnLength;