summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-03-18 14:19:52 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-03-19 13:40:22 -0400
commit6433ab29afa4d19000c14bdc0b64c0062972427e (patch)
treefb70ea164f36e9935ed05a682e4a1f6b1893a268 /sc
parent6000c8d15510b77a02d517afb81e3d2e164b318c (diff)
Implement (partially?) and test formula token array hash function.
For now, we don't factor in any differences in reference tokens in the generated hash values. Change-Id: Ie9836228eaad9c74edd884c3e8c4b273979760fd
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/document.hxx4
-rw-r--r--sc/inc/table.hxx2
-rw-r--r--sc/qa/unit/ucalc.cxx52
-rw-r--r--sc/source/core/data/column2.cxx18
-rw-r--r--sc/source/core/data/document.cxx13
-rw-r--r--sc/source/core/data/table1.cxx8
7 files changed, 99 insertions, 0 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 4ec4f294182d..8147c063b122 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -408,6 +408,8 @@ public:
sal_uInt8 GetScriptType( SCROW nRow ) const;
void SetScriptType( SCROW nRow, sal_uInt8 nType );
+ size_t GetFormulaHash( SCROW nRow ) const;
+
private:
ScBaseCell* CloneCell(SCSIZE nIndex, sal_uInt16 nFlags, ScDocument& rDestDoc, const ScAddress& rDestPos) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 4dc0602da26d..7d23b89a7b27 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -750,6 +750,8 @@ public:
SC_DLLPUBLIC bool SetString(
SCCOL nCol, SCROW nRow, SCTAB nTab, const rtl::OUString& rString,
ScSetStringParam* pParam = NULL );
+ bool SetString( const ScAddress& rPos, const OUString& rString, ScSetStringParam* pParam = NULL );
+
SC_DLLPUBLIC void SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal );
void SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const sal_uInt16 nError);
@@ -1852,6 +1854,8 @@ public:
sal_uInt8 GetScriptType( const ScAddress& rPos ) const;
void SetScriptType( const ScAddress& rPos, sal_uInt8 nType );
+ size_t GetFormulaHash( const ScAddress& rPos ) const;
+
private: // CLOOK-Impl-methods
/**
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 6a0b07880fd4..2e8b697f6a8e 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -796,6 +796,8 @@ public:
sal_uInt8 GetScriptType( SCCOL nCol, SCROW nRow ) const;
void SetScriptType( SCCOL nCol, SCROW nRow, sal_uInt8 nType );
+ size_t GetFormulaHash( SCCOL nCol, SCROW nRow ) const;
+
private:
void FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd,
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index ec9465228ee5..4d93eb1e24be 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -116,6 +116,7 @@ public:
void testCollator();
void testRangeList();
void testInput();
+ void testFormulaGrouping();
void testCellFunctions();
void testCopyToDocument();
/**
@@ -269,6 +270,7 @@ public:
CPPUNIT_TEST(testCollator);
CPPUNIT_TEST(testRangeList);
CPPUNIT_TEST(testInput);
+ CPPUNIT_TEST(testFormulaGrouping);
CPPUNIT_TEST(testCellFunctions);
CPPUNIT_TEST(testCopyToDocument);
CPPUNIT_TEST(testSheetsFunc);
@@ -1188,6 +1190,56 @@ void testFuncINDIRECT(ScDocument* pDoc)
}
}
+void Test::testFormulaGrouping()
+{
+ m_pDoc->InsertTab(0, "Test");
+
+ ScAddress aPos1(0,0,0), aPos2(1,0,0);
+
+ // simplest cases.
+ m_pDoc->SetString(aPos1, "=1");
+ size_t nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
+ m_pDoc->SetString(aPos2, "=2");
+ size_t nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
+ CPPUNIT_ASSERT_MESSAGE("These hashes should differ.", nHashVal1 != nHashVal2);
+
+ // different cell functions.
+ aPos1.IncRow();
+ aPos2.IncRow();
+ m_pDoc->SetString(aPos1, "=SUM(1,2,3,4,5)");
+ m_pDoc->SetString(aPos2, "=AVERAGE(1,2,3,4,5)");
+ nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
+ nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
+ CPPUNIT_ASSERT_MESSAGE("These hashes should differ.", nHashVal1 != nHashVal2);
+
+ // same relative references.
+ aPos1.IncRow();
+ aPos2.IncRow();
+ m_pDoc->SetString(aPos1, "=A2*3");
+ m_pDoc->SetString(aPos2, "=B2*3");
+ nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
+ nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
+ CPPUNIT_ASSERT_MESSAGE("These hashes should be equal.", nHashVal1 == nHashVal2);
+
+ m_pDoc->SetString(aPos2, "=B2*4"); // Change the constant.
+ nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
+ CPPUNIT_ASSERT_MESSAGE("These hashes should differ.", nHashVal1 != nHashVal2);
+
+ m_pDoc->SetString(aPos1, "=A2*4"); // Change the constant again to make it "equal".
+ nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
+ CPPUNIT_ASSERT_MESSAGE("These hashes should be equal.", nHashVal1 == nHashVal2);
+
+ aPos1.IncRow();
+ aPos2.IncRow();
+ m_pDoc->SetString(aPos1, "=3*4*5");
+ m_pDoc->SetString(aPos2, "=3*4*\"foo\"");
+ nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
+ nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
+ CPPUNIT_ASSERT_MESSAGE("These hashes should differ.", nHashVal1 != nHashVal2);
+
+ m_pDoc->DeleteTab(0);
+}
+
void Test::testCellFunctions()
{
OUString aTabName("foo");
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 330154226f14..ea4be5ba4c90 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1525,6 +1525,24 @@ void ScColumn::SetScriptType( SCROW nRow, sal_uInt8 nType )
maScriptTypes.set<unsigned short>(nRow, nType);
}
+size_t ScColumn::GetFormulaHash( SCROW nRow ) const
+{
+ if (!ValidRow(nRow))
+ return 0;
+
+ SCSIZE nIndex;
+ if (!Search(nRow, nIndex))
+ // cell not found.
+ return 0;
+
+ const ScBaseCell* pCell = maItems[nIndex].pCell;
+ if (pCell->GetCellType() != CELLTYPE_FORMULA)
+ // Not a formula cell.
+ return 0;
+
+ return static_cast<const ScFormulaCell*>(pCell)->GetHash();
+}
+
void ScColumn::FindDataAreaPos(SCROW& rRow, bool bDown) const
{
// check if we are in a data area
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 3a1247ad2cb8..1f237d13b0c7 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1552,6 +1552,14 @@ bool ScDocument::HasPartOfMerged( const ScRange& rRange )
return bPart;
}
+size_t ScDocument::GetFormulaHash( const ScAddress& rPos ) const
+{
+ SCTAB nTab = rPos.Tab();
+ if (!ValidTab(nTab) || static_cast<size_t>(nTab) >= maTabs.size() || !maTabs[nTab])
+ return 0;
+
+ return maTabs[nTab]->GetFormulaHash(rPos.Col(), rPos.Row());
+}
bool ScDocument::CanFitBlock( const ScRange& rOld, const ScRange& rNew )
{
@@ -2939,6 +2947,11 @@ bool ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString&
return false;
}
+bool ScDocument::SetString(
+ const ScAddress& rPos, const OUString& rString, ScSetStringParam* pParam )
+{
+ return SetString(rPos.Col(), rPos.Row(), rPos.Tab(), rString, pParam);
+}
void ScDocument::SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal )
{
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index fd5026f22593..ee90ae4c4c63 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2096,6 +2096,14 @@ void ScTable::SetScriptType( SCCOL nCol, SCROW nRow, sal_uInt8 nType )
aCol[nCol].SetScriptType(nRow, nType);
}
+size_t ScTable::GetFormulaHash( SCCOL nCol, SCROW nRow ) const
+{
+ if (!ValidCol(nCol))
+ return 0;
+
+ return aCol[nCol].GetFormulaHash(nRow);
+}
+
void ScTable::DeleteConditionalFormat( sal_uLong nIndex )
{
mpCondFormatList->erase(nIndex);