summaryrefslogtreecommitdiffstats
path: root/sc/qa
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-11-25 00:02:21 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-11-25 10:00:14 -0500
commit0dae7466fff1e742543ef7512b7dd22472c75624 (patch)
treec9f146abd01a7cabd81944fd794c133cdecadca3 /sc/qa
parentall these ids and their associated resources were unnecessary (diff)
downloadcore-0dae7466fff1e742543ef7512b7dd22472c75624.tar.gz
core-0dae7466fff1e742543ef7512b7dd22472c75624.zip
Adjust ref undo to ensure group area listeners are used.
When undoing row deletion (and possibly other similar undo's). And write test for it. Change-Id: I04b4fd9932f4236f124dcd25967355c6055dec33
Diffstat (limited to 'sc/qa')
-rw-r--r--sc/qa/unit/ucalc.hxx25
-rw-r--r--sc/qa/unit/ucalc_sharedformula.cxx101
2 files changed, 124 insertions, 2 deletions
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 7cad0ad9d299..e20b069895ea 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -12,6 +12,7 @@
#include "helper/qahelper.hxx"
#include "document.hxx"
+#include <stringutil.hxx>
struct TestImpl;
class ScUndoPaste;
@@ -55,9 +56,16 @@ public:
static void setCalcAsShown(ScDocument* pDoc, bool bCalcAsShown);
+
template<size_t _Size>
- static ScRange insertRangeData(ScDocument* pDoc, const ScAddress& rPos, const char* aData[][_Size], size_t nRowCount)
+ static ScRange insertRangeData(
+ ScDocument* pDoc, const ScAddress& rPos, const char* aData[][_Size], size_t nRowCount,
+ bool bGroupListening = false )
{
+ // TODO : Ideally bGroupListening should be always true for all tests.
+ // Eventually we want to drop this parameter once all tests pass with
+ // group listening turned on.
+
ScRange aRange(rPos);
aRange.aEnd.SetCol(rPos.Col()+_Size-1);
aRange.aEnd.SetRow(rPos.Row()+nRowCount-1);
@@ -73,10 +81,21 @@ public:
SCCOL nCol = i + rPos.Col();
SCROW nRow = j + rPos.Row();
- pDoc->SetString(nCol, nRow, rPos.Tab(), OUString(aData[j][i], strlen(aData[j][i]), RTL_TEXTENCODING_UTF8));
+ OUString aStr(aData[j][i], strlen(aData[j][i]), RTL_TEXTENCODING_UTF8);
+ if (bGroupListening)
+ {
+ ScSetStringParam aParam; // Leave default.
+ aParam.meStartListening = sc::NoListening;
+ pDoc->SetString(nCol, nRow, rPos.Tab(), aStr, &aParam);
+ }
+ else
+ pDoc->SetString(nCol, nRow, rPos.Tab(), aStr, NULL);
}
}
+ if (bGroupListening)
+ pDoc->StartAllListeners(aRange);
+
printRange(pDoc, aRange, "Range data content");
return aRange;
}
@@ -300,6 +319,7 @@ public:
void testSharedFormulasRefUpdateMove();
void testSharedFormulasRefUpdateMove2();
void testSharedFormulasRefUpdateRange();
+ void testSharedFormulasRefUpdateRangeDeleteRow();
void testSharedFormulasRefUpdateExternal();
void testSharedFormulasInsertRow();
void testSharedFormulasDeleteRows();
@@ -529,6 +549,7 @@ public:
CPPUNIT_TEST(testSharedFormulasRefUpdateMove);
CPPUNIT_TEST(testSharedFormulasRefUpdateMove2);
CPPUNIT_TEST(testSharedFormulasRefUpdateRange);
+ CPPUNIT_TEST(testSharedFormulasRefUpdateRangeDeleteRow);
CPPUNIT_TEST(testSharedFormulasRefUpdateExternal);
CPPUNIT_TEST(testSharedFormulasInsertRow);
CPPUNIT_TEST(testSharedFormulasDeleteRows);
diff --git a/sc/qa/unit/ucalc_sharedformula.cxx b/sc/qa/unit/ucalc_sharedformula.cxx
index 16d55771f9d7..811612379163 100644
--- a/sc/qa/unit/ucalc_sharedformula.cxx
+++ b/sc/qa/unit/ucalc_sharedformula.cxx
@@ -21,6 +21,7 @@
#include <tokenstringcontext.hxx>
#include <globalnames.hxx>
#include <dbdata.hxx>
+#include <bcaslot.hxx>
#include <svl/sharedstring.hxx>
@@ -580,6 +581,106 @@ void Test::testSharedFormulasRefUpdateRange()
m_pDoc->DeleteTab(0);
}
+void Test::testSharedFormulasRefUpdateRangeDeleteRow()
+{
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calc.
+ m_pDoc->InsertTab(0, "Formula");
+
+ ScRange aWholeArea(0, 0, 0, 100, 100, 0); // Large enough for all references used in the test.
+
+ const char* aData[][3] = {
+ { "1", "2", "=SUM(A1:B1)" },
+ { "3", "4", "=SUM(A2:B2)" },
+ { 0, 0, 0 },
+ { "5", "6", "=SUM(A4:B4)" },
+ { "7", "8", "=SUM(A5:B5)" }
+ };
+
+ insertRangeData(m_pDoc, ScAddress(0,0,0), aData, SAL_N_ELEMENTS(aData), true);
+
+ // Check initial formula values.
+ CPPUNIT_ASSERT_EQUAL( 3.0, m_pDoc->GetValue(ScAddress(2,0,0)));
+ CPPUNIT_ASSERT_EQUAL( 7.0, m_pDoc->GetValue(ScAddress(2,1,0)));
+ CPPUNIT_ASSERT_EQUAL(11.0, m_pDoc->GetValue(ScAddress(2,3,0)));
+ CPPUNIT_ASSERT_EQUAL(15.0, m_pDoc->GetValue(ScAddress(2,4,0)));
+
+ // Check the area listener status.
+ ScBroadcastAreaSlotMachine* pBASM = m_pDoc->GetBASM();
+ CPPUNIT_ASSERT(pBASM);
+ std::vector<sc::AreaListener> aListeners = pBASM->GetAllListeners(aWholeArea, sc::AreaInside);
+ std::sort(aListeners.begin(), aListeners.end(), sc::AreaListener::SortByArea());
+
+ CPPUNIT_ASSERT_MESSAGE("There should only be 2 area listeners.", aListeners.size() == 2);
+ // First one should be group-listening on A1:B2.
+ CPPUNIT_ASSERT_MESSAGE("This listener should be listening on A1:B2.", aListeners[0].maArea == ScRange(0,0,0,1,1,0));
+ CPPUNIT_ASSERT_MESSAGE("This listener should be group-listening.", aListeners[0].mbGroupListening);
+ // Second one should be group-listening on A4:B5.
+ CPPUNIT_ASSERT_MESSAGE("This listener should be listening on A1:B2.", aListeners[0].maArea == ScRange(0,0,0,1,1,0));
+ CPPUNIT_ASSERT_MESSAGE("This listener should be group-listening.", aListeners[0].mbGroupListening);
+
+ // Make sure that C1:C2 and C4:C5 are formula groups.
+ const ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(2,0,0));
+ CPPUNIT_ASSERT(pFC);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(0), pFC->GetSharedTopRow());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2,3,0));
+ CPPUNIT_ASSERT(pFC);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(3), pFC->GetSharedTopRow());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+
+ // Delete row 3. This will merge the two formula groups.
+ ScDocFunc& rFunc = getDocShell().GetDocFunc();
+ ScMarkData aMark;
+ aMark.SelectOneTable(0);
+ rFunc.DeleteCells(ScRange(0,2,0,MAXCOL,2,0), &aMark, DEL_DELROWS, true, true);
+
+ // Make sure C1:C4 belong to the same group.
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2,0,0));
+ CPPUNIT_ASSERT(pFC);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(0), pFC->GetSharedTopRow());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
+
+ // We should only have one listener group-listening on A1:B4.
+ aListeners = pBASM->GetAllListeners(aWholeArea, sc::AreaInside);
+ CPPUNIT_ASSERT_MESSAGE("There should only be 1 area listener.", aListeners.size() == 1);
+ CPPUNIT_ASSERT_MESSAGE("This listener should be listening on A1:B4.", aListeners[0].maArea == ScRange(0,0,0,1,3,0));
+ CPPUNIT_ASSERT_MESSAGE("This listener should be group-listening.", aListeners[0].mbGroupListening);
+
+ // Change the value of B4 and make sure the value of C4 changes.
+ rFunc.SetValueCell(ScAddress(1,3,0), 100.0, false);
+ CPPUNIT_ASSERT_EQUAL(107.0, m_pDoc->GetValue(ScAddress(2,3,0)));
+
+ SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager();
+ CPPUNIT_ASSERT(pUndoMgr);
+
+ // Undo the value change in B4, and make sure C4 follows.
+ pUndoMgr->Undo();
+ CPPUNIT_ASSERT_EQUAL(15.0, m_pDoc->GetValue(ScAddress(2,3,0)));
+
+ // Undo the deletion of row 3.
+ pUndoMgr->Undo();
+
+ // Check the values of formula cells again.
+ CPPUNIT_ASSERT_EQUAL( 3.0, m_pDoc->GetValue(ScAddress(2,0,0)));
+ CPPUNIT_ASSERT_EQUAL( 7.0, m_pDoc->GetValue(ScAddress(2,1,0)));
+ CPPUNIT_ASSERT_EQUAL(11.0, m_pDoc->GetValue(ScAddress(2,3,0)));
+ CPPUNIT_ASSERT_EQUAL(15.0, m_pDoc->GetValue(ScAddress(2,4,0)));
+
+ aListeners = pBASM->GetAllListeners(aWholeArea, sc::AreaInside);
+ std::sort(aListeners.begin(), aListeners.end(), sc::AreaListener::SortByArea());
+
+ CPPUNIT_ASSERT_MESSAGE("There should only be 2 area listeners.", aListeners.size() == 2);
+ // First one should be group-listening on A1:B2.
+ CPPUNIT_ASSERT_MESSAGE("This listener should be listening on A1:B2.", aListeners[0].maArea == ScRange(0,0,0,1,1,0));
+ CPPUNIT_ASSERT_MESSAGE("This listener should be group-listening.", aListeners[0].mbGroupListening);
+ // Second one should be group-listening on A4:B5.
+ CPPUNIT_ASSERT_MESSAGE("This listener should be listening on A1:B2.", aListeners[0].maArea == ScRange(0,0,0,1,1,0));
+ CPPUNIT_ASSERT_MESSAGE("This listener should be group-listening.", aListeners[0].mbGroupListening);
+
+ m_pDoc->DeleteTab(0);
+}
+
void Test::testSharedFormulasRefUpdateExternal()
{
sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calc.