[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/inc sc/qa sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Thu Mar 14 09:15:38 PDT 2013
sc/inc/column.hxx | 2
sc/inc/columniterator.hxx | 11 +++
sc/inc/document.hxx | 2
sc/inc/table.hxx | 2
sc/qa/unit/ucalc.cxx | 79 +++++++++++++++++++++
sc/source/core/data/columniterator.cxx | 119 ++++++++++++++++++---------------
sc/source/core/data/document.cxx | 9 ++
7 files changed, 171 insertions(+), 53 deletions(-)
New commits:
commit c6eb99af79b498fb201610502dfe23b46067ba8a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Thu Mar 14 12:14:40 2013 -0400
Unit test for the new column-based text width storage, via new iterator.
Change-Id: Ibf1e254e34df98ad5c46a46252168787b07d161c
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 93ae44f..114a39b 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -97,7 +97,6 @@ class ScColumn
ScAttrArray* pAttrArray;
ScDocument* pDocument;
-friend class ScColumnTextWidthIterator;
friend class ScDocument; // for FillInfo
friend class ScDocumentIterator;
friend class ScValueIterator;
@@ -109,6 +108,7 @@ friend class ScMarkedDataIter;
friend class ScCellIterator;
friend class ScHorizontalCellIterator;
friend class ScHorizontalAttrIterator;
+friend class ScColumnTextWidthIterator;
ScColumn(const ScColumn&); // disabled
ScColumn& operator= (const ScColumn&); // disabled
diff --git a/sc/inc/columniterator.hxx b/sc/inc/columniterator.hxx
index a70567c56..7bd645d 100644
--- a/sc/inc/columniterator.hxx
+++ b/sc/inc/columniterator.hxx
@@ -31,6 +31,16 @@ class ScColumnTextWidthIterator : boost::noncopyable
public:
ScColumnTextWidthIterator(ScColumn& rCol, SCROW nStartRow, SCROW nEndRow);
+ /**
+ * @param rDoc document instance.
+ * @param rStartPos position of the first cell from which to start
+ * iteration. Note that the caller must ensure that this
+ * position is valid; the constructor does not check its
+ * validity.
+ * @param nEndRow end row position.
+ */
+ ScColumnTextWidthIterator(ScDocument& rDoc, const ScAddress& rStartPos, SCROW nEndRow);
+
void next();
bool hasCell() const;
SCROW getPos() const;
@@ -38,6 +48,7 @@ public:
void setValue(sal_uInt16 nVal);
private:
+ void init(SCROW nStartRow, SCROW nEndRow);
void getDataIterators(size_t nOffsetInBlock);
void checkEndRow();
};
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 2f59ef1..541ec05 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -214,6 +214,7 @@ friend class ScDocAttrIterator;
friend class ScAttrRectIterator;
friend class ScDocShell;
friend class ScDocRowHeightUpdater;
+friend class ScColumnTextWidthIterator;
typedef ::std::vector<ScTable*> TableContainer;
private:
@@ -1844,6 +1845,7 @@ public:
void RemoveSubTotalCell(ScFormulaCell* pCell);
void SetSubTotalCellsDirty(const ScRange& rDirtyRange);
+ sal_uInt16 GetTextWidth( const ScAddress& rPos ) const;
void SetTextWidth( const ScAddress& rPos, sal_uInt16 nWidth );
private: // CLOOK-Impl-methods
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 8786ccf..3e4d1eb 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -187,7 +187,7 @@ friend class ScHorizontalCellIterator;
friend class ScHorizontalAttrIterator;
friend class ScDocAttrIterator;
friend class ScAttrRectIterator;
-
+friend class ScColumnTextWidthIterator;
public:
ScTable( ScDocument* pDoc, SCTAB nNewTab, const rtl::OUString& rNewName,
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 232a501..57b00f4 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -65,6 +65,7 @@
#include "dpfilteredcache.hxx"
#include "calcconfig.hxx"
#include "interpre.hxx"
+#include "columniterator.hxx"
#include "formula/IFunctionDescription.hxx"
@@ -262,6 +263,7 @@ public:
void testDeleteRow();
void testDeleteCol();
void testAnchoredRotatedShape();
+ void testCellTextWidth();
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testCollator);
@@ -323,6 +325,7 @@ public:
CPPUNIT_TEST(testDeleteRow);
CPPUNIT_TEST(testDeleteCol);
CPPUNIT_TEST(testAnchoredRotatedShape);
+ CPPUNIT_TEST(testCellTextWidth);
CPPUNIT_TEST_SUITE_END();
private:
@@ -6025,6 +6028,82 @@ void Test::testAnchoredRotatedShape()
m_pDoc->DeleteTab(0);
}
+void Test::testCellTextWidth()
+{
+ m_pDoc->InsertTab(0, "Test");
+
+ ScAddress aTopCell(0, 0, 0);
+
+ // Sheet is empty.
+ boost::scoped_ptr<ScColumnTextWidthIterator> pIter(new ScColumnTextWidthIterator(*m_pDoc, aTopCell, MAXROW));
+ CPPUNIT_ASSERT_MESSAGE("Column should have no text widths stored.", !pIter->hasCell());
+
+ // Sheet only has one cell.
+ m_pDoc->SetString(0, 0, 0, "Only one cell");
+ pIter.reset(new ScColumnTextWidthIterator(*m_pDoc, aTopCell, MAXROW));
+ CPPUNIT_ASSERT_MESSAGE("Column should have a cell.", pIter->hasCell());
+ CPPUNIT_ASSERT_EQUAL(0, pIter->getPos());
+
+ // Setting a text width here should commit it to the column.
+ sal_uInt16 nTestVal = 432;
+ pIter->setValue(nTestVal);
+ CPPUNIT_ASSERT_EQUAL(nTestVal, m_pDoc->GetTextWidth(aTopCell));
+
+ // Set values to row 2 through 6.
+ for (SCROW i = 2; i <= 6; ++i)
+ m_pDoc->SetString(0, i, 0, "foo");
+
+ // Set values to row 10 through 18.
+ for (SCROW i = 10; i <= 18; ++i)
+ m_pDoc->SetString(0, i, 0, "foo");
+
+ {
+ // Full range.
+ pIter.reset(new ScColumnTextWidthIterator(*m_pDoc, aTopCell, MAXROW));
+ SCROW aRows[] = { 0, 2, 3, 4, 5, 6, 10, 11, 12, 13, 14, 15, 16, 17, 18 };
+ size_t n = SAL_N_ELEMENTS(aRows);
+ for (size_t i = 0; i < n; ++i, pIter->next())
+ {
+ CPPUNIT_ASSERT_MESSAGE("Cell expected, but not there.", pIter->hasCell());
+ CPPUNIT_ASSERT_EQUAL(aRows[i], pIter->getPos());
+ }
+ CPPUNIT_ASSERT_MESSAGE("Iterator should have ended.", !pIter->hasCell());
+ }
+
+ {
+ // Specify start and end rows (6 - 16)
+ ScAddress aStart = aTopCell;
+ aStart.SetRow(6);
+ pIter.reset(new ScColumnTextWidthIterator(*m_pDoc, aStart, 16));
+ SCROW aRows[] = { 6, 10, 11, 12, 13, 14, 15, 16 };
+ size_t n = SAL_N_ELEMENTS(aRows);
+ for (size_t i = 0; i < n; ++i, pIter->next())
+ {
+ CPPUNIT_ASSERT_MESSAGE("Cell expected, but not there.", pIter->hasCell());
+ CPPUNIT_ASSERT_EQUAL(aRows[i], pIter->getPos());
+ }
+ CPPUNIT_ASSERT_MESSAGE("Iterator should have ended.", !pIter->hasCell());
+ }
+
+ // Clear from row 3 to row 17. After this, we should only have cells at rows 0, 2 and 18.
+ clearRange(m_pDoc, ScRange(0, 3, 0, 0, 17, 0));
+
+ {
+ // Full range again.
+ pIter.reset(new ScColumnTextWidthIterator(*m_pDoc, aTopCell, MAXROW));
+ SCROW aRows[] = { 0, 2, 18 };
+ size_t n = SAL_N_ELEMENTS(aRows);
+ for (size_t i = 0; i < n; ++i, pIter->next())
+ {
+ CPPUNIT_ASSERT_MESSAGE("Cell expected, but not there.", pIter->hasCell());
+ CPPUNIT_ASSERT_EQUAL(aRows[i], pIter->getPos());
+ }
+ CPPUNIT_ASSERT_MESSAGE("Iterator should have ended.", !pIter->hasCell());
+ }
+
+ m_pDoc->DeleteTab(0);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
}
diff --git a/sc/source/core/data/columniterator.cxx b/sc/source/core/data/columniterator.cxx
index 31298bc..24b8c05 100644
--- a/sc/source/core/data/columniterator.cxx
+++ b/sc/source/core/data/columniterator.cxx
@@ -9,6 +9,8 @@
#include "columniterator.hxx"
#include "column.hxx"
+#include "document.hxx"
+#include "table.hxx"
ScColumnTextWidthIterator::ScColumnTextWidthIterator(ScColumn& rCol, SCROW nStartRow, SCROW nEndRow) :
mrTextWidths(rCol.maTextWidths),
@@ -17,58 +19,17 @@ ScColumnTextWidthIterator::ScColumnTextWidthIterator(ScColumn& rCol, SCROW nStar
miBlockCur(mrTextWidths.begin()),
miBlockEnd(mrTextWidths.end())
{
- if (!ValidRow(nStartRow) || !ValidRow(nEndRow))
- miBlockCur = miBlockEnd;
-
- size_t nStart = static_cast<size_t>(nStartRow);
-
- // Locate the start row position.
- size_t nBlockStart = 0, nBlockEnd = 0;
- for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
- {
- nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
- if (nBlockStart <= nStart && nStart < nBlockEnd)
- {
- // Initial block is found!
- break;
- }
- }
-
- if (miBlockCur == miBlockEnd)
- // Initial block not found for whatever reason... Bail out.
- return;
-
- // Locate the initial row position within this block.
- if (miBlockCur->type == mdds::mtv::element_type_ushort)
- {
- // This block stores text widths for non-empty cells.
- size_t nOffsetInBlock = nStart - nBlockStart;
- mnCurPos = nStart;
- getDataIterators(nOffsetInBlock);
- checkEndRow();
- return;
- }
-
- // Current block is not of ushort type. Skip to the next block.
- nBlockStart = nBlockEnd;
- ++miBlockCur;
-
- // Look for the first ushort block.
- for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
- {
- nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
- if (miBlockCur->type != mdds::mtv::element_type_ushort)
- continue;
-
- // Found!
- mnCurPos = nBlockStart;
- getDataIterators(0);
- checkEndRow();
- return;
- }
+ init(nStartRow, nEndRow);
+}
- // Not found.
- OSL_ASSERT(miBlockCur == miBlockEnd);
+ScColumnTextWidthIterator::ScColumnTextWidthIterator(ScDocument& rDoc, const ScAddress& rStartPos, SCROW nEndRow) :
+ mrTextWidths(rDoc.maTabs[rStartPos.Tab()]->aCol[rStartPos.Col()].maTextWidths),
+ mnEnd(static_cast<size_t>(nEndRow)),
+ mnCurPos(0),
+ miBlockCur(mrTextWidths.begin()),
+ miBlockEnd(mrTextWidths.end())
+{
+ init(rStartPos.Row(), nEndRow);
}
void ScColumnTextWidthIterator::next()
@@ -125,6 +86,62 @@ void ScColumnTextWidthIterator::setValue(sal_uInt16 nVal)
*miDataCur = nVal;
}
+void ScColumnTextWidthIterator::init(SCROW nStartRow, SCROW nEndRow)
+{
+ if (!ValidRow(nStartRow) || !ValidRow(nEndRow))
+ miBlockCur = miBlockEnd;
+
+ size_t nStart = static_cast<size_t>(nStartRow);
+
+ // Locate the start row position.
+ size_t nBlockStart = 0, nBlockEnd = 0;
+ for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
+ {
+ nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
+ if (nBlockStart <= nStart && nStart < nBlockEnd)
+ {
+ // Initial block is found!
+ break;
+ }
+ }
+
+ if (miBlockCur == miBlockEnd)
+ // Initial block not found for whatever reason... Bail out.
+ return;
+
+ // Locate the initial row position within this block.
+ if (miBlockCur->type == mdds::mtv::element_type_ushort)
+ {
+ // This block stores text widths for non-empty cells.
+ size_t nOffsetInBlock = nStart - nBlockStart;
+ mnCurPos = nStart;
+ getDataIterators(nOffsetInBlock);
+ checkEndRow();
+ return;
+ }
+
+ // Current block is not of ushort type. Skip to the next block.
+ nBlockStart = nBlockEnd;
+ ++miBlockCur;
+
+ // Look for the first ushort block.
+ for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
+ {
+ nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
+ if (miBlockCur->type != mdds::mtv::element_type_ushort)
+ continue;
+
+ // Found!
+ mnCurPos = nBlockStart;
+ getDataIterators(0);
+ checkEndRow();
+ return;
+ }
+
+ // Not found.
+ OSL_ASSERT(miBlockCur == miBlockEnd);
+}
+
void ScColumnTextWidthIterator::getDataIterators(size_t nOffsetInBlock)
{
OSL_ENSURE(miBlockCur != miBlockEnd, "block is at end position");
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index acce598..a73cd60 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5695,6 +5695,15 @@ void ScDocument::SetSubTotalCellsDirty(const ScRange& rDirtyRange)
maSubTotalCells.swap(aNewSet); // update the list.
}
+sal_uInt16 ScDocument::GetTextWidth( const ScAddress& rPos ) const
+{
+ SCTAB nTab = rPos.Tab();
+ if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
+ return maTabs[nTab]->GetTextWidth(rPos.Col(), rPos.Row());
+
+ return 0;
+}
+
void ScDocument::SetTextWidth( const ScAddress& rPos, sal_uInt16 nWidth )
{
SCTAB nTab = rPos.Tab();
More information about the Libreoffice-commits
mailing list