[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/inc sc/qa sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Wed Jun 26 18:49:08 PDT 2013
sc/inc/column.hxx | 7 +++++
sc/qa/unit/ucalc.cxx | 31 ++++++++++++++++++++++
sc/source/core/data/column.cxx | 10 +------
sc/source/core/data/column3.cxx | 56 +++++++++++++++++++++++++++++++++++++---
4 files changed, 93 insertions(+), 11 deletions(-)
New commits:
commit a6f996db16bc6a84d28dde7aef15a23536f8f0b2
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 5354a07..c0dea00 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -469,6 +469,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 3918cd2..de330f5 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 ff152ff..16d4ada 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.
More information about the Libreoffice-commits
mailing list