[Libreoffice-commits] core.git: Branch 'feature/calc-group-interpreter' - 9 commits - sc/inc sc/qa sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Mon Aug 12 14:45:56 PDT 2013
sc/inc/formulacell.hxx | 3 +
sc/inc/sharedformula.hxx | 14 +++++
sc/inc/tokenarray.hxx | 3 +
sc/qa/unit/ucalc.cxx | 6 +-
sc/source/core/data/column.cxx | 62 +++++++++++++++++++++++--
sc/source/core/data/formulacell.cxx | 58 +++++++++++++++++++-----
sc/source/core/tool/sharedformula.cxx | 65 +++++++++++++++++++++-----
sc/source/core/tool/token.cxx | 82 ++++++++++++++++++++++++++++++++++
sc/source/filter/excel/xetable.cxx | 39 ++++++++--------
sc/source/filter/excel/xlformula.cxx | 7 --
sc/source/filter/inc/xetable.hxx | 3 -
sc/source/filter/inc/xlformula.hxx | 8 ---
12 files changed, 281 insertions(+), 69 deletions(-)
New commits:
commit 05effa857e3b03ac894c8a44cd8129374da8c9a7
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Aug 12 17:46:45 2013 -0400
Re-enable these tests. They pass now.
Change-Id: I408f42a849e7635ef53d4b8c142a0d90ac37bb05
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index d65be47..675e0dba 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -297,7 +297,7 @@ public:
CPPUNIT_TEST(testHorizontalIterator);
CPPUNIT_TEST(testFormulaDepTracking);
CPPUNIT_TEST(testFormulaDepTracking2);
-// CPPUNIT_TEST(testCellBroadcaster);
+ CPPUNIT_TEST(testCellBroadcaster);
CPPUNIT_TEST(testFuncParam);
CPPUNIT_TEST(testNamedRange);
CPPUNIT_TEST(testCSV);
@@ -341,8 +341,8 @@ public:
CPPUNIT_TEST(testSetBackgroundColor);
CPPUNIT_TEST(testRenameTable);
CPPUNIT_TEST(testAutoFill);
-// CPPUNIT_TEST(testCopyPasteFormulas);
-// CPPUNIT_TEST(testCopyPasteFormulasExternalDoc);
+ CPPUNIT_TEST(testCopyPasteFormulas);
+ CPPUNIT_TEST(testCopyPasteFormulasExternalDoc);
CPPUNIT_TEST(testFindAreaPosVertical);
CPPUNIT_TEST(testFindAreaPosColRight);
CPPUNIT_TEST(testSort);
commit 56f048dbee4603adce5af80d2896a2d10cd2524b
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Aug 12 17:23:30 2013 -0400
This is clearly a bug. Let's fix it.
Change-Id: I83aa2c108e7d8561d28d76b69a8763a15a20a2bd
diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx
index 0b49751..11493e646 100644
--- a/sc/inc/sharedformula.hxx
+++ b/sc/inc/sharedformula.hxx
@@ -34,7 +34,7 @@ public:
for (++it; it != itEnd; ++it, pPrev = pCur)
{
pCur = *it;
- ScFormulaCell::CompareState eState = pPrev->CompareByTokenArray(*pPrev);
+ ScFormulaCell::CompareState eState = pCur->CompareByTokenArray(*pPrev);
if (eState == ScFormulaCell::NotEqual)
continue;
commit 05271f9a742e6c40540ae6db1211d9ceb95a57e6
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Aug 12 16:42:53 2013 -0400
Ungroup a cell when the group length becomes 1.
Change-Id: Ic656d4837ab1fc5feb4b19765ae427371dfdfe10
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index 07d9029..6583ac9 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -38,13 +38,25 @@ void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type
ScFormulaCellGroupRef xGroup = rTop.GetCellGroup();
- ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
- xGroup2->mbInvariant = xGroup->mbInvariant;
- xGroup2->mnStart = nRow;
- xGroup2->mnLength = xGroup->mnStart + xGroup->mnLength - nRow;
- xGroup2->mpCode = xGroup->mpCode->Clone();
+ SCROW nLength2 = xGroup->mnStart + xGroup->mnLength - nRow;
+ ScFormulaCellGroupRef xGroup2;
+ if (nLength2 > 1)
+ {
+ xGroup2.reset(new ScFormulaCellGroup);
+ xGroup2->mbInvariant = xGroup->mbInvariant;
+ xGroup2->mnStart = nRow;
+ xGroup2->mnLength = nLength2;
+ xGroup2->mpCode = xGroup->mpCode->Clone();
+ }
xGroup->mnLength = nRow - xGroup->mnStart;
+ if (xGroup->mnLength == 1)
+ {
+ // The top group consists of only one cell. Ungroup this.
+ ScFormulaCellGroupRef xNone;
+ ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
+ rPrev.SetCellGroup(xNone);
+ }
// Apply the lower group object to the lower cells.
#if DEBUG_COLUMN_STORAGE
@@ -56,7 +68,7 @@ void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type
}
#endif
sc::formula_block::iterator itEnd = it;
- std::advance(itEnd, xGroup2->mnLength);
+ std::advance(itEnd, nLength2);
for (; it != itEnd; ++it)
{
ScFormulaCell& rCell = **it;
commit 7ad68e3e8d97de37ca347deb50db379c252236e1
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Aug 12 16:28:29 2013 -0400
Fix indentation.
Change-Id: I2caebb42d92bf81e3ba8809a47f833a9379e769d
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index 9299e33..07d9029 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -48,12 +48,12 @@ 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)
- {
- cerr << "ScColumn::SplitFormulaCellGroup: Shared formula region goes beyond the formula block. Not good." << endl;
- cerr.flush();
- abort();
- }
+ 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);
commit 3f06d624d8505b86a88a96b7eaa9910604aab9a7
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Aug 12 15:48:50 2013 -0400
We still need to update cell positions for non-top cells.
Change-Id: If967247ed5d916535e7b52af14b00090b7c9d0d2
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 6a1bbb0..c8e7f35 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -112,6 +112,8 @@ private:
};
void InterpretTail( ScInterpretTailParameter );
+ bool UpdatePosOnShift( const sc::RefUpdateContext& rCxt );
+
/**
* Update reference in response to cell insertion or deletion.
*/
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 102de63..76582a0 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2128,6 +2128,29 @@ bool ScFormulaCell::HasColRowName() const
return (pCode->GetNextColRowName() != NULL);
}
+bool ScFormulaCell::UpdatePosOnShift( const sc::RefUpdateContext& rCxt )
+{
+ if (rCxt.meMode != URM_INSDEL)
+ // Just in case...
+ return false;
+
+ if (!rCxt.mnColDelta && !rCxt.mnRowDelta && !rCxt.mnTabDelta)
+ // No movement.
+ return false;
+
+ if (!rCxt.maRange.In(aPos))
+ return false;
+
+ // This formula cell itself is being shifted during cell range
+ // insertion or deletion. Update its position.
+ if (mxGroup && mxGroup->mnStart == aPos.Row())
+ mxGroup->mnStart += rCxt.mnRowDelta;
+
+ aPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+
+ return true;
+}
+
namespace {
/**
@@ -2245,17 +2268,7 @@ bool ScFormulaCell::UpdateReferenceOnShift(
if ( pUndoCellPos )
aUndoPos = *pUndoCellPos;
ScAddress aOldPos( aPos );
-
- if (rCxt.maRange.In(aPos))
- {
- // This formula cell itself is being shifted during cell range
- // insertion or deletion. Update its position.
- aPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
- if (mxGroup && mxGroup->mnStart == aOldPos.Row())
- mxGroup->mnStart += rCxt.mnRowDelta;
-
- bCellStateChanged = aPos != aOldPos;
- }
+ bCellStateChanged = UpdatePosOnShift(rCxt);
// Check presence of any references or column row names.
pCode->Reset();
@@ -2554,8 +2567,19 @@ bool ScFormulaCell::UpdateReference(
return false;
if (mxGroup && mxGroup->mnStart != aPos.Row())
- // Update only the top cell in case the cell is part of a formula group.
+ {
+ // This is not a top cell of a formula group. Don't update references.
+
+ switch (rCxt.meMode)
+ {
+ case URM_INSDEL:
+ return UpdatePosOnShift(rCxt);
+ break;
+ default:
+ ;
+ }
return false;
+ }
switch (rCxt.meMode)
{
commit 4625f6f699dfcc41b8e7ce2b86aedc1429eb4cf1
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Aug 12 15:23:28 2013 -0400
Do the splitting of formula groups.
Change-Id: I5a8661895b558b67abc19cdc39de9eb027bc1c34
diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx
index 9423384..0b49751 100644
--- a/sc/inc/sharedformula.hxx
+++ b/sc/inc/sharedformula.hxx
@@ -63,7 +63,15 @@ public:
*/
static void splitFormulaCellGroup(const CellStoreType::position_type& aPos);
- static void splitFormulaCellGroups(CellStoreType& rCells, const std::vector<SCROW>& rBounds);
+ /**
+ * Split existing shared formula ranges at specified row positions.
+ *
+ * @param rCells cell storage container
+ * @param rBounds row positions at which to split existing shared formula
+ * ranges. Note that this method will directly modify this
+ * parameter to sort and remove duplicates.
+ */
+ static void splitFormulaCellGroups(CellStoreType& rCells, std::vector<SCROW>& rBounds);
/**
* See if two specified adjacent formula cells can be merged, and if they
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 3cacf7c..25e2f84 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2364,6 +2364,10 @@ bool ScColumn::UpdateReference( const sc::RefUpdateContext& rCxt, ScDocument* pU
if (rCxt.meMode == URM_COPY)
return UpdateReferenceOnCopy(rCxt, pUndoDoc);
+ if (IsEmptyData())
+ // Cells in this column are all empty.
+ return false;
+
std::vector<SCROW> aBounds;
bool bThisColShifted = (rCxt.maRange.aStart.Tab() <= nTab && nTab <= rCxt.maRange.aEnd.Tab() &&
@@ -2387,11 +2391,6 @@ bool ScColumn::UpdateReference( const sc::RefUpdateContext& rCxt, ScDocument* pU
UpdateRefGroupBoundChecker aBoundChecker(rCxt, aBounds);
std::for_each(maCells.begin(), maCells.end(), aBoundChecker);
- // Sort and remove duplicates.
- std::sort(aBounds.begin(), aBounds.end());
- std::vector<SCROW>::iterator it = std::unique(aBounds.begin(), aBounds.end());
- aBounds.erase(it, aBounds.end());
-
// Do the actual splitting.
sc::SharedFormulaUtil::splitFormulaCellGroups(maCells, aBounds);
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index d9f3a25..9299e33 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -64,9 +64,33 @@ void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type
}
}
-void SharedFormulaUtil::splitFormulaCellGroups(CellStoreType& rCells, const std::vector<SCROW>& rBounds)
+void SharedFormulaUtil::splitFormulaCellGroups(CellStoreType& rCells, std::vector<SCROW>& rBounds)
{
- // TODO: Implement this.
+ if (rBounds.empty())
+ return;
+
+ // Sort and remove duplicates.
+ std::sort(rBounds.begin(), rBounds.end());
+ std::vector<SCROW>::iterator it = std::unique(rBounds.begin(), rBounds.end());
+ rBounds.erase(it, rBounds.end());
+
+ it = rBounds.begin();
+ SCROW nRow = *it;
+ CellStoreType::position_type aPos = rCells.position(nRow);
+ if (aPos.first == rCells.end())
+ return;
+
+ splitFormulaCellGroup(aPos);
+ std::vector<SCROW>::iterator itEnd = rBounds.end();
+ for (++it; it != itEnd; ++it)
+ {
+ nRow = *it;
+ aPos = rCells.position(aPos.first, nRow);
+ if (aPos.first == rCells.end())
+ return;
+
+ splitFormulaCellGroup(aPos);
+ }
}
void SharedFormulaUtil::joinFormulaCells(const CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 6cd491c..701e235 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2981,7 +2981,7 @@ void checkBounds(
SCROW nOffset = rCxt.maRange.aStart.Row() - aAbs.aStart.Row();
rBounds.push_back(rPos.Row()+nOffset);
// Ditto.
- nOffset = rCxt.maRange.aEnd.Row() - aAbs.aStart.Row();
+ nOffset = rCxt.maRange.aEnd.Row() + 1 - aAbs.aStart.Row();
rBounds.push_back(rPos.Row()+nOffset);
}
commit 9d27add20779382192d3530178c9d0ca365c56c9
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Sat Aug 10 23:31:38 2013 -0400
Collect all boundaries at which to split the formula group.
Change-Id: Ic78d7a06991b983e625b161f11fbbabce02334f3
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 2a2b61c..6a1bbb0 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -352,6 +352,7 @@ public:
bool IsShared() const;
bool IsSharedInvariant() const;
+ bool IsSharedTop() const;
SCROW GetSharedTopRow() const;
SCROW GetSharedLength() const;
ScTokenArray* GetSharedCode();
diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx
index 232c4bc..9423384 100644
--- a/sc/inc/sharedformula.hxx
+++ b/sc/inc/sharedformula.hxx
@@ -13,6 +13,8 @@
#include "formulacell.hxx"
#include "mtvelements.hxx"
+#include <vector>
+
namespace sc {
class SharedFormulaUtil
@@ -61,6 +63,8 @@ public:
*/
static void splitFormulaCellGroup(const CellStoreType::position_type& aPos);
+ static void splitFormulaCellGroups(CellStoreType& rCells, const std::vector<SCROW>& rBounds);
+
/**
* See if two specified adjacent formula cells can be merged, and if they
* can, merge them into the same group.
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index 09a9798..00f192d 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -166,6 +166,9 @@ public:
sc::RefUpdateResult AdjustReferenceOnMovedTab( sc::RefUpdateMoveTabContext& rCxt, const ScAddress& rOldPos );
+ void CheckRelativeReferenceBounds(
+ const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const;
+
#if DEBUG_FORMULA_COMPILER
void Dump() const;
#endif
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index ba9b35e..3cacf7c 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2295,6 +2295,46 @@ public:
bool isUpdated() const { return mbUpdated; }
};
+class UpdateRefGroupBoundChecker : std::unary_function<sc::CellStoreType::value_type, void>
+{
+ const sc::RefUpdateContext& mrCxt;
+ std::vector<SCROW>& mrBounds;
+public:
+ UpdateRefGroupBoundChecker(const sc::RefUpdateContext& rCxt, std::vector<SCROW>& rBounds) :
+ mrCxt(rCxt), mrBounds(rBounds) {}
+
+ void operator() (const sc::CellStoreType::value_type& node)
+ {
+ if (node.type != sc::element_type_formula)
+ return;
+
+ sc::formula_block::const_iterator it = sc::formula_block::begin(*node.data);
+ sc::formula_block::const_iterator itEnd = sc::formula_block::end(*node.data);
+
+ // Only pick shared formula cells that are the top cells of their
+ // respective shared ranges.
+ for (; it != itEnd; ++it)
+ {
+ const ScFormulaCell& rCell = **it;
+ if (!rCell.IsShared())
+ continue;
+
+ if (rCell.IsSharedTop())
+ {
+ // Check its tokens and record its reference boundaries.
+ const ScTokenArray& rCode = *rCell.GetCode();
+ rCode.CheckRelativeReferenceBounds(
+ mrCxt, rCell.aPos, rCell.GetSharedLength(), mrBounds);
+
+ // Move to the last cell in the group, to get incremented to
+ // the next cell in the next iteration.
+ size_t nOffsetToLast = rCell.GetSharedLength() - 1;
+ std::advance(it, nOffsetToLast);
+ }
+ }
+ }
+};
+
}
bool ScColumn::UpdateReferenceOnCopy( const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc )
@@ -2324,6 +2364,8 @@ bool ScColumn::UpdateReference( const sc::RefUpdateContext& rCxt, ScDocument* pU
if (rCxt.meMode == URM_COPY)
return UpdateReferenceOnCopy(rCxt, pUndoDoc);
+ std::vector<SCROW> aBounds;
+
bool bThisColShifted = (rCxt.maRange.aStart.Tab() <= nTab && nTab <= rCxt.maRange.aEnd.Tab() &&
rCxt.maRange.aStart.Col() <= nCol && nCol <= rCxt.maRange.aEnd.Col());
if (bThisColShifted)
@@ -2333,17 +2375,26 @@ bool ScColumn::UpdateReference( const sc::RefUpdateContext& rCxt, ScDocument* pU
SCROW nSplitPos = rCxt.maRange.aStart.Row();
if (ValidRow(nSplitPos))
{
- sc::CellStoreType::position_type aPos = maCells.position(nSplitPos);
- sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
+ aBounds.push_back(nSplitPos);
nSplitPos = rCxt.maRange.aEnd.Row() + 1;
if (ValidRow(nSplitPos))
- {
- aPos = maCells.position(aPos.first, nSplitPos);
- sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
- }
+ aBounds.push_back(nSplitPos);
}
}
+ // Check the row positions at which the group must be split per relative
+ // references.
+ UpdateRefGroupBoundChecker aBoundChecker(rCxt, aBounds);
+ std::for_each(maCells.begin(), maCells.end(), aBoundChecker);
+
+ // Sort and remove duplicates.
+ std::sort(aBounds.begin(), aBounds.end());
+ std::vector<SCROW>::iterator it = std::unique(aBounds.begin(), aBounds.end());
+ aBounds.erase(it, aBounds.end());
+
+ // Do the actual splitting.
+ sc::SharedFormulaUtil::splitFormulaCellGroups(maCells, aBounds);
+
UpdateRefOnNonCopy aHandler(nCol, nTab, rCxt, pUndoDoc);
sc::ProcessFormula(maCells, aHandler);
return aHandler.isUpdated();
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 962b2dc..102de63 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3774,6 +3774,14 @@ bool ScFormulaCell::IsSharedInvariant() const
return mxGroup ? mxGroup->mbInvariant : false;
}
+bool ScFormulaCell::IsSharedTop() const
+{
+ if (!mxGroup)
+ return false;
+
+ return mxGroup->mnStart == aPos.Row();
+}
+
SCROW ScFormulaCell::GetSharedTopRow() const
{
return mxGroup ? mxGroup->mnStart : -1;
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index 3e77934..d9f3a25 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -64,6 +64,11 @@ void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type
}
}
+void SharedFormulaUtil::splitFormulaCellGroups(CellStoreType& rCells, const std::vector<SCROW>& rBounds)
+{
+ // TODO: Implement this.
+}
+
void SharedFormulaUtil::joinFormulaCells(const CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
{
ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index d231007..6cd491c 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2934,6 +2934,88 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMovedTab( sc::RefUpdateMoveTa
return aRes;
}
+namespace {
+
+void checkBounds(
+ const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen,
+ const ScSingleRefData& rRef, std::vector<SCROW>& rBounds)
+{
+ if (!rRef.IsRowRel())
+ return;
+
+ ScRange aAbs(rRef.toAbs(rPos));
+ aAbs.aEnd.IncRow(nGroupLen-1);
+ if (!rCxt.maRange.Intersects(aAbs))
+ return;
+
+ // Get the boundary row positions.
+ if (aAbs.aEnd.Row() < rCxt.maRange.aStart.Row())
+ // No intersections.
+ return;
+
+ if (aAbs.aEnd.Row() <= rCxt.maRange.aEnd.Row())
+ {
+ // +-+ <---- top
+ // | |
+ // +--+-+--+ <---- boundary row position
+ // | | | |
+ // | +-+ |
+ // +-------+
+
+ // Add offset from the reference top to the cell position.
+ SCROW nOffset = rCxt.maRange.aStart.Row() - aAbs.aStart.Row();
+ rBounds.push_back(rPos.Row()+nOffset);
+ return;
+ }
+
+ // +-+ <---- top
+ // | |
+ // +--+-+--+ <---- boundary row position
+ // | | | |
+ // | | | |
+ // +--+-+--+ <---- boundary row position
+ // | |
+ // +-+
+
+ // Add offset from the reference top to the cell position.
+ SCROW nOffset = rCxt.maRange.aStart.Row() - aAbs.aStart.Row();
+ rBounds.push_back(rPos.Row()+nOffset);
+ // Ditto.
+ nOffset = rCxt.maRange.aEnd.Row() - aAbs.aStart.Row();
+ rBounds.push_back(rPos.Row()+nOffset);
+}
+
+}
+
+void ScTokenArray::CheckRelativeReferenceBounds(
+ const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const
+{
+ FormulaToken** p = pCode;
+ FormulaToken** pEnd = p + static_cast<size_t>(nLen);
+ for (; p != pEnd; ++p)
+ {
+ switch ((*p)->GetType())
+ {
+ case svSingleRef:
+ {
+ ScToken* pToken = static_cast<ScToken*>(*p);
+ checkBounds(rCxt, rPos, nGroupLen, pToken->GetSingleRef(), rBounds);
+ }
+ break;
+ case svDoubleRef:
+ {
+ ScToken* pToken = static_cast<ScToken*>(*p);
+ const ScComplexRefData& rRef = pToken->GetDoubleRef();
+ checkBounds(rCxt, rPos, nGroupLen, rRef.Ref1, rBounds);
+ checkBounds(rCxt, rPos, nGroupLen, rRef.Ref2, rBounds);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+}
+
#if DEBUG_FORMULA_COMPILER
void ScTokenArray::Dump() const
{
commit 9531c75056cf24cd2c15408dccf5318cf44b4499
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri Aug 9 16:41:22 2013 -0400
If the formula cell is grouped, update reference only on the top cell.
Change-Id: I5e2e9db621a61deba39a46962e0ca877235d7c90
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index f755c98..962b2dc 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2553,6 +2553,10 @@ bool ScFormulaCell::UpdateReference(
if (pDocument->IsClipOrUndo())
return false;
+ if (mxGroup && mxGroup->mnStart != aPos.Row())
+ // Update only the top cell in case the cell is part of a formula group.
+ return false;
+
switch (rCxt.meMode)
{
case URM_INSDEL:
commit 2ce9380ad1cac8b3cb741dabcf11e91c4ff37d75
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri Aug 9 12:09:44 2013 -0400
Export shared formulas to xls, from the new shared formula in the core.
Turns out we don't export shared formulas to xlsx, so no work is needed
there.
Change-Id: I85604f3b80c95c5b6179bbdac41e758c5de7854a
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index b436a3d..b13c5bb 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -207,28 +207,29 @@ XclExpShrfmlaBuffer::XclExpShrfmlaBuffer( const XclExpRoot& rRoot ) :
}
XclExpShrfmlaRef XclExpShrfmlaBuffer::CreateOrExtendShrfmla(
- const ScTokenArray& rScTokArr, const ScAddress& rScPos )
+ const ScFormulaCell& rScCell, const ScAddress& rScPos )
{
XclExpShrfmlaRef xRec;
- if( const ScTokenArray* pShrdScTokArr = XclTokenArrayHelper::GetSharedFormula( GetRoot(), rScTokArr ) )
+ const ScTokenArray* pShrdScTokArr = rScCell.GetSharedCode();
+ if (!pShrdScTokArr)
+ // This formula cell is not shared formula cell.
+ return xRec;
+
+ XclExpShrfmlaMap::iterator aIt = maRecMap.find( pShrdScTokArr );
+ if( aIt == maRecMap.end() )
{
- XclExpShrfmlaMap::iterator aIt = maRecMap.find( pShrdScTokArr );
- if( aIt == maRecMap.end() )
- {
- // create a new record
- XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_SHARED, *pShrdScTokArr, &rScPos );
- xRec.reset( new XclExpShrfmla( xTokArr, rScPos ) );
- maRecMap[ pShrdScTokArr ] = xRec;
- }
- else
- {
- // extend existing record
- OSL_ENSURE( aIt->second, "XclExpShrfmlaBuffer::CreateOrExtendShrfmla - missing record" );
- xRec = aIt->second;
- xRec->ExtendRange( rScPos );
- }
+ // create a new record
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_SHARED, *pShrdScTokArr, &rScPos );
+ xRec.reset( new XclExpShrfmla( xTokArr, rScPos ) );
+ maRecMap[ pShrdScTokArr ] = xRec;
+ }
+ else
+ {
+ // extend existing record
+ OSL_ENSURE( aIt->second, "XclExpShrfmlaBuffer::CreateOrExtendShrfmla - missing record" );
+ xRec = aIt->second;
+ xRec->ExtendRange( rScPos );
}
- return xRec;
}
// Multiple operations ========================================================
@@ -851,7 +852,7 @@ XclExpFormulaCell::XclExpFormulaCell(
// no matrix found - try to create shared formula
if( !mxAddRec )
- mxAddRec = rShrfmlaBfr.CreateOrExtendShrfmla( rScTokArr, aScPos );
+ mxAddRec = rShrfmlaBfr.CreateOrExtendShrfmla(mrScFmlaCell, aScPos);
// no shared formula found - create a simple cell formula
if( !mxAddRec )
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
index 356a348..a04ebfd 100644
--- a/sc/source/filter/excel/xlformula.cxx
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -759,13 +759,6 @@ void XclTokenArrayHelper::ConvertStringToList( ScTokenArray& rScTokArr, sal_Unic
}
}
-// shared formulas ------------------------------------------------------------
-
-const ScTokenArray* XclTokenArrayHelper::GetSharedFormula( const XclRoot& /*rRoot*/, const ScTokenArray& /*rScTokArr*/ )
-{
- return NULL;
-}
-
// multiple operations --------------------------------------------------------
namespace {
diff --git a/sc/source/filter/inc/xetable.hxx b/sc/source/filter/inc/xetable.hxx
index 533d2ec..0e47052 100644
--- a/sc/source/filter/inc/xetable.hxx
+++ b/sc/source/filter/inc/xetable.hxx
@@ -189,8 +189,7 @@ public:
function updates its cell range to include the passed cell position,
if there is a SHRFMLA record for the passed token array; otherwise
this function creates and returns a new SHRFMLA record. */
- XclExpShrfmlaRef CreateOrExtendShrfmla(
- const ScTokenArray& rScTokArr, const ScAddress& rScPos );
+ XclExpShrfmlaRef CreateOrExtendShrfmla( const ScFormulaCell& rScCell, const ScAddress& rScPos );
private:
typedef ::std::map< const ScTokenArray*, XclExpShrfmlaRef > XclExpShrfmlaMap;
diff --git a/sc/source/filter/inc/xlformula.hxx b/sc/source/filter/inc/xlformula.hxx
index fdf395e..0a90e08 100644
--- a/sc/source/filter/inc/xlformula.hxx
+++ b/sc/source/filter/inc/xlformula.hxx
@@ -523,14 +523,6 @@ public:
@param bTrimLeadingSpaces true = remove leading spaces from each token. */
static void ConvertStringToList( ScTokenArray& rScTokArr, sal_Unicode cStringSep, bool bTrimLeadingSpaces );
- // shared formulas --------------------------------------------------------
-
- /** Tries to extract the definition of a shared formula from the passed token array.
- @descr Shared formulas are stored as hidden defined names in Calc. This
- function looks if the passed token array consists of the reference to
- such a hidden defined name and returns its definition on success. */
- static const ScTokenArray* GetSharedFormula( const XclRoot& rRoot, const ScTokenArray& rScTokArr );
-
// multiple operations ----------------------------------------------------
/** Parses the passed formula and tries to extract references of a multiple operation.
More information about the Libreoffice-commits
mailing list