[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/CppunitTest_sc_ucalc.mk sc/qa

Kohei Yoshida kohei.yoshida at gmail.com
Thu Jul 11 09:30:22 PDT 2013


 sc/CppunitTest_sc_ucalc.mk      |    1 
 sc/qa/unit/ucalc.cxx            | 2441 ++--------------------------------------
 sc/qa/unit/ucalc.hxx            |   28 
 sc/qa/unit/ucalc_pivottable.cxx | 2079 ++++++++++++++++++++++++++++++++++
 4 files changed, 2284 insertions(+), 2265 deletions(-)

New commits:
commit a5bb800fa85706897b64dca1f47215f2fa3f4a4a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Jul 11 12:27:38 2013 -0400

    Move pivot table tests into a separate source file.
    
    Change-Id: Ie32999007bbeaff4076195c68f2537ba0da6148b

diff --git a/sc/CppunitTest_sc_ucalc.mk b/sc/CppunitTest_sc_ucalc.mk
index 15e1b61..623639b 100644
--- a/sc/CppunitTest_sc_ucalc.mk
+++ b/sc/CppunitTest_sc_ucalc.mk
@@ -13,6 +13,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,sc_ucalc))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sc_ucalc, \
     sc/qa/unit/ucalc \
+    sc/qa/unit/ucalc_pivottable \
     sc/qa/unit/ucalc_sharedformula \
 ))
 
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 06c5b83..6d2d0fc 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -15,7 +15,6 @@
 
 #include "scdll.hxx"
 #include "formulacell.hxx"
-#include "document.hxx"
 #include "stringutil.hxx"
 #include "scmatrix.hxx"
 #include "drwlayer.hxx"
@@ -39,12 +38,6 @@
 #include "funcdesc.hxx"
 #include "externalrefmgr.hxx"
 
-#include "dpshttab.hxx"
-#include "dpobject.hxx"
-#include "dpsave.hxx"
-#include "dpdimsave.hxx"
-#include "dpcache.hxx"
-#include "dpfilteredcache.hxx"
 #include "calcconfig.hxx"
 #include "interpre.hxx"
 #include "columniterator.hxx"
@@ -55,6 +48,7 @@
 #include "scopetools.hxx"
 #include "dociter.hxx"
 #include "docsh.hxx"
+#include "queryparam.hxx"
 
 #include "formula/IFunctionDescription.hxx"
 
@@ -69,13 +63,6 @@
 
 #include <sfx2/docfile.hxx>
 
-#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
-#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
-#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
-#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
-#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
-#include <com/sun/star/sheet/GeneralFunction.hpp>
-
 #include <iostream>
 #include <sstream>
 #include <vector>
@@ -98,48 +85,6 @@ FormulaGrammarSwitch::~FormulaGrammarSwitch()
     mpDoc->SetGrammar(meOldGrammar);
 }
 
-void printRange(ScDocument* pDoc, const ScRange& rRange, const char* pCaption)
-{
-    SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
-    SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
-    SheetPrinter printer(nRow2 - nRow1 + 1, nCol2 - nCol1 + 1);
-    for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
-    {
-        for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
-        {
-            OUString aVal = pDoc->GetString(nCol, nRow, rRange.aStart.Tab());
-            printer.set(nRow-nRow1, nCol-nCol1, aVal);
-        }
-    }
-    printer.print(pCaption);
-}
-
-template<size_t _Size>
-ScRange insertRangeData(ScDocument* pDoc, const ScAddress& rPos, const char* aData[][_Size], size_t nRowCount)
-{
-    ScRange aRange(rPos);
-    aRange.aEnd.SetCol(rPos.Col()+_Size-1);
-    aRange.aEnd.SetRow(rPos.Row()+nRowCount-1);
-
-    Test::clearRange(pDoc, aRange);
-
-    for (size_t i = 0; i < _Size; ++i)
-    {
-        for (size_t j = 0; j < nRowCount; ++j)
-        {
-            if (!aData[j][i])
-                continue;
-
-            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));
-        }
-    }
-
-    printRange(pDoc, aRange, "Range data content");
-    return aRange;
-}
-
 class MeasureTimeSwitch
 {
     double& mrDiff;
@@ -1027,7 +972,7 @@ void runTestMATCH(ScDocument* pDoc, const char* aData[_DataSize], StrStrCheck aC
     }
 
     pDoc->CalcAll();
-    printRange(pDoc, ScRange(0, 0, 0, 2, _FormulaSize-1, 0), "MATCH");
+    Test::printRange(pDoc, ScRange(0, 0, 0, 2, _FormulaSize-1, 0), "MATCH");
 
     // verify the results.
     for (size_t i = 0; i < _FormulaSize; ++i)
@@ -1505,7 +1450,7 @@ template<size_t _Size>
 bool checkHorizontalIterator(ScDocument* pDoc, const char* pData[][_Size], size_t nDataCount, const HoriIterCheck* pChecks, size_t nCheckCount)
 {
     ScAddress aPos(0,0,0);
-    insertRangeData(pDoc, aPos, pData, nDataCount);
+    Test::insertRangeData(pDoc, aPos, pData, nDataCount);
     ScHorizontalCellIterator aIter(pDoc, 0, 0, 0, 1, nDataCount-1);
 
     SCCOL nCol;
@@ -2112,2249 +2057,199 @@ void Test::testCSV()
                 (aStr, aTests[i].eSep == English ? '.' : ',',
                  aTests[i].eSep == English ? ',' : '.',
                  nValue);
-        CPPUNIT_ASSERT_MESSAGE ("CSV numeric detection failure", bResult == aTests[i].bResult);
-        CPPUNIT_ASSERT_MESSAGE ("CSV numeric value failure", nValue == aTests[i].nValue);
-    }
-}
-
-template<typename Evaluator>
-void checkMatrixElements(const ScMatrix& rMat)
-{
-    SCSIZE nC, nR;
-    rMat.GetDimensions(nC, nR);
-    Evaluator aEval;
-    for (SCSIZE i = 0; i < nC; ++i)
-    {
-        for (SCSIZE j = 0; j < nR; ++j)
-        {
-            aEval(i, j, rMat.Get(i, j));
-        }
-    }
-}
-
-struct AllZeroMatrix
-{
-    void operator() (SCSIZE /*nCol*/, SCSIZE /*nRow*/, const ScMatrixValue& rVal) const
-    {
-        CPPUNIT_ASSERT_MESSAGE("element is not of numeric type", rVal.nType == SC_MATVAL_VALUE);
-        CPPUNIT_ASSERT_MESSAGE("element value must be zero", rVal.fVal == 0.0);
-    }
-};
-
-struct PartiallyFilledZeroMatrix
-{
-    void operator() (SCSIZE nCol, SCSIZE nRow, const ScMatrixValue& rVal) const
-    {
-        CPPUNIT_ASSERT_MESSAGE("element is not of numeric type", rVal.nType == SC_MATVAL_VALUE);
-        if (1 <= nCol && nCol <= 2 && 2 <= nRow && nRow <= 8)
-        {
-            CPPUNIT_ASSERT_MESSAGE("element value must be 3.0", rVal.fVal == 3.0);
-        }
-        else
-        {
-            CPPUNIT_ASSERT_MESSAGE("element value must be zero", rVal.fVal == 0.0);
-        }
-    }
-};
-
-struct AllEmptyMatrix
-{
-    void operator() (SCSIZE /*nCol*/, SCSIZE /*nRow*/, const ScMatrixValue& rVal) const
-    {
-        CPPUNIT_ASSERT_MESSAGE("element is not of empty type", rVal.nType == SC_MATVAL_EMPTY);
-        CPPUNIT_ASSERT_MESSAGE("value of \"empty\" element is expected to be zero", rVal.fVal == 0.0);
-    }
-};
-
-struct PartiallyFilledEmptyMatrix
-{
-    void operator() (SCSIZE nCol, SCSIZE nRow, const ScMatrixValue& rVal) const
-    {
-        if (nCol == 1 && nRow == 1)
-        {
-            CPPUNIT_ASSERT_MESSAGE("element is not of boolean type", rVal.nType == SC_MATVAL_BOOLEAN);
-            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.fVal == 1.0);
-        }
-        else if (nCol == 4 && nRow == 5)
-        {
-            CPPUNIT_ASSERT_MESSAGE("element is not of value type", rVal.nType == SC_MATVAL_VALUE);
-            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.fVal == -12.5);
-        }
-        else if (nCol == 8 && nRow == 2)
-        {
-            CPPUNIT_ASSERT_MESSAGE("element is not of value type", rVal.nType == SC_MATVAL_STRING);
-            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.aStr == "Test");
-        }
-        else if (nCol == 8 && nRow == 11)
-        {
-            CPPUNIT_ASSERT_MESSAGE("element is not of empty path type", rVal.nType == SC_MATVAL_EMPTYPATH);
-            CPPUNIT_ASSERT_MESSAGE("value of \"empty\" element is expected to be zero", rVal.fVal == 0.0);
-        }
-        else
-        {
-            CPPUNIT_ASSERT_MESSAGE("element is not of empty type", rVal.nType == SC_MATVAL_EMPTY);
-            CPPUNIT_ASSERT_MESSAGE("value of \"empty\" element is expected to be zero", rVal.fVal == 0.0);
-        }
-    }
-};
-
-void Test::testMatrix()
-{
-    ScMatrixRef pMat;
-
-    // First, test the zero matrix type.
-    pMat = new ScMatrix(0, 0, 0.0);
-    SCSIZE nC, nR;
-    pMat->GetDimensions(nC, nR);
-    CPPUNIT_ASSERT_MESSAGE("matrix is not empty", nC == 0 && nR == 0);
-    pMat->Resize(4, 10, 0.0);
-    pMat->GetDimensions(nC, nR);
-    CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 4 && nR == 10);
-    CPPUNIT_ASSERT_MESSAGE("both 'and' and 'or' should evaluate to false",
-                           !pMat->And() && !pMat->Or());
-
-    // Resizing into a larger matrix should fill the void space with zeros.
-    checkMatrixElements<AllZeroMatrix>(*pMat);
-
-    pMat->FillDouble(3.0, 1, 2, 2, 8);
-    checkMatrixElements<PartiallyFilledZeroMatrix>(*pMat);
-    CPPUNIT_ASSERT_MESSAGE("matrix is expected to be numeric", pMat->IsNumeric());
-    CPPUNIT_ASSERT_MESSAGE("partially non-zero matrix should evaluate false on 'and' and true on 'or",
-                           !pMat->And() && pMat->Or());
-    pMat->FillDouble(5.0, 0, 0, nC-1, nR-1);
-    CPPUNIT_ASSERT_MESSAGE("fully non-zero matrix should evaluate true both on 'and' and 'or",
-                           pMat->And() && pMat->Or());
-
-    // Test the AND and OR evaluations.
-    pMat = new ScMatrix(2, 2, 0.0);
-
-    // Only some of the elements are non-zero.
-    pMat->PutBoolean(true, 0, 0);
-    pMat->PutDouble(1.0, 1, 1);
-    CPPUNIT_ASSERT_MESSAGE("incorrect OR result", pMat->Or());
-    CPPUNIT_ASSERT_MESSAGE("incorrect AND result", !pMat->And());
-
-    // All of the elements are non-zero.
-    pMat->PutBoolean(true, 0, 1);
-    pMat->PutDouble(2.3, 1, 0);
-    CPPUNIT_ASSERT_MESSAGE("incorrect OR result", pMat->Or());
-    CPPUNIT_ASSERT_MESSAGE("incorrect AND result", pMat->And());
-
-    // Now test the emtpy matrix type.
-    pMat = new ScMatrix(10, 20);
-    pMat->GetDimensions(nC, nR);
-    CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 10 && nR == 20);
-    checkMatrixElements<AllEmptyMatrix>(*pMat);
-
-    pMat->PutBoolean(true, 1, 1);
-    pMat->PutDouble(-12.5, 4, 5);
-    OUString aStr("Test");
-    pMat->PutString(aStr, 8, 2);
-    pMat->PutEmptyPath(8, 11);
-    checkMatrixElements<PartiallyFilledEmptyMatrix>(*pMat);
-
-    // Test resizing.
-    pMat = new ScMatrix(0, 0);
-    pMat->Resize(2, 2, 1.5);
-    pMat->PutEmpty(1, 1);
-
-    CPPUNIT_ASSERT_EQUAL(1.5, pMat->GetDouble(0, 0));
-    CPPUNIT_ASSERT_EQUAL(1.5, pMat->GetDouble(0, 1));
-    CPPUNIT_ASSERT_EQUAL(1.5, pMat->GetDouble(1, 0));
-    CPPUNIT_ASSERT_MESSAGE("PutEmpty() call failed.", pMat->IsEmpty(1, 1));
-
-    // Max and min values.
-    pMat = new ScMatrix(2, 2, 0.0);
-    pMat->PutDouble(-10, 0, 0);
-    pMat->PutDouble(-12, 0, 1);
-    pMat->PutDouble(-8, 1, 0);
-    pMat->PutDouble(-25, 1, 1);
-    CPPUNIT_ASSERT_EQUAL(-25.0, pMat->GetMinValue(false));
-    CPPUNIT_ASSERT_EQUAL(-8.0, pMat->GetMaxValue(false));
-    pMat->PutString("Test", 0, 0);
-    CPPUNIT_ASSERT_EQUAL(0.0, pMat->GetMaxValue(true)); // text as zero.
-    CPPUNIT_ASSERT_EQUAL(-8.0, pMat->GetMaxValue(false)); // ignore text.
-    pMat->PutBoolean(true, 0, 0);
-    CPPUNIT_ASSERT_EQUAL(1.0, pMat->GetMaxValue(false));
-    pMat = new ScMatrix(2, 2, 10.0);
-    pMat->PutBoolean(false, 0, 0);
-    pMat->PutDouble(12.5, 1, 1);
-    CPPUNIT_ASSERT_EQUAL(0.0, pMat->GetMinValue(false));
-    CPPUNIT_ASSERT_EQUAL(12.5, pMat->GetMaxValue(false));
-}
-
-void Test::testEnterMixedMatrix()
-{
-    m_pDoc->InsertTab(0, "foo");
-
-    // Insert the source values in A1:B2.
-    m_pDoc->SetString(0, 0, 0, "A");
-    m_pDoc->SetString(1, 0, 0, "B");
-    double val = 1.0;
-    m_pDoc->SetValue(0, 1, 0, val);
-    val = 2.0;
-    m_pDoc->SetValue(1, 1, 0, val);
-
-    // Create a matrix range in A4:B5 referencing A1:B2.
-    ScMarkData aMark;
-    aMark.SelectOneTable(0);
-    m_pDoc->InsertMatrixFormula(0, 3, 1, 4, aMark, "=A1:B2", NULL);
-
-    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(0,0,0), m_pDoc->GetString(0,3,0));
-    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(1,0,0), m_pDoc->GetString(1,3,0));
-    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(0,1,0), m_pDoc->GetValue(0,4,0));
-    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(1,1,0), m_pDoc->GetValue(1,4,0));
-
-    m_pDoc->DeleteTab(0);
-}
-
-namespace {
-
-struct DPFieldDef
-{
-    const char* pName;
-    sheet::DataPilotFieldOrientation eOrient;
-
-    /**
-     * Function for data field.  It's used only for data field.  When 0, the
-     * default function (SUM) is used.
-     */
-    int eFunc;
-};
-
-template<size_t _Size>
-ScRange insertDPSourceData(ScDocument* pDoc, DPFieldDef aFields[], size_t nFieldCount, const char* aData[][_Size], size_t nDataCount)
-{
-    // Insert field names in row 0.
-    for (size_t i = 0; i < nFieldCount; ++i)
-        pDoc->SetString(static_cast<SCCOL>(i), 0, 0, OUString(aFields[i].pName, strlen(aFields[i].pName), RTL_TEXTENCODING_UTF8));
-
-    // Insert data into row 1 and downward.
-    for (size_t i = 0; i < nDataCount; ++i)
-    {
-        SCROW nRow = static_cast<SCROW>(i) + 1;
-        for (size_t j = 0; j < nFieldCount; ++j)
-        {
-            SCCOL nCol = static_cast<SCCOL>(j);
-            pDoc->SetString(
-                nCol, nRow, 0, OUString(aData[i][j], strlen(aData[i][j]), RTL_TEXTENCODING_UTF8));
-        }
-    }
-
-    SCROW nRow1 = 0, nRow2 = 0;
-    SCCOL nCol1 = 0, nCol2 = 0;
-    pDoc->GetDataArea(0, nCol1, nRow1, nCol2, nRow2, true, false);
-    CPPUNIT_ASSERT_MESSAGE("Data is expected to start from (col=0,row=0).", nCol1 == 0 && nRow1 == 0);
-    CPPUNIT_ASSERT_MESSAGE("Unexpected data range.",
-                           nCol2 == static_cast<SCCOL>(nFieldCount - 1) && nRow2 == static_cast<SCROW>(nDataCount));
-
-    ScRange aSrcRange(nCol1, nRow1, 0, nCol2, nRow2, 0);
-    printRange(pDoc, aSrcRange, "Data sheet content");
-    return aSrcRange;
-}
-
-template<size_t _Size>
-bool checkDPTableOutput(ScDocument* pDoc, const ScRange& aOutRange, const char* aOutputCheck[][_Size], const char* pCaption)
-{
-    bool bResult = true;
-    const ScAddress& s = aOutRange.aStart;
-    const ScAddress& e = aOutRange.aEnd;
-    SheetPrinter printer(e.Row() - s.Row() + 1, e.Col() - s.Col() + 1);
-    SCROW nOutRowSize = e.Row() - s.Row() + 1;
-    SCCOL nOutColSize = e.Col() - s.Col() + 1;
-    for (SCROW nRow = 0; nRow < nOutRowSize; ++nRow)
-    {
-        for (SCCOL nCol = 0; nCol < nOutColSize; ++nCol)
-        {
-            OUString aVal = pDoc->GetString(nCol + s.Col(), nRow + s.Row(), s.Tab());
-            printer.set(nRow, nCol, aVal);
-            const char* p = aOutputCheck[nRow][nCol];
-            if (p)
-            {
-                OUString aCheckVal = OUString::createFromAscii(p);
-                bool bEqual = aCheckVal.equals(aVal);
-                if (!bEqual)
-                {
-                    cout << "Expected: " << aCheckVal << "  Actual: " << aVal << endl;
-                    bResult = false;
-                }
-            }
-            else if (!aVal.isEmpty())
-            {
-                cout << "Empty cell expected" << endl;
-                bResult = false;
-            }
-        }
-    }
-    printer.print(pCaption);
-    return bResult;
-}
-
-ScDPObject* createDPFromSourceDesc(
-    ScDocument* pDoc, const ScSheetSourceDesc& rDesc, DPFieldDef aFields[], size_t nFieldCount,
-    bool bFilterButton)
-{
-    ScDPObject* pDPObj = new ScDPObject(pDoc);
-    pDPObj->SetSheetDesc(rDesc);
-    pDPObj->SetOutRange(ScAddress(0, 0, 1));
-
-    ScDPSaveData aSaveData;
-    // Set data pilot table output options.
-    aSaveData.SetIgnoreEmptyRows(false);
-    aSaveData.SetRepeatIfEmpty(false);
-    aSaveData.SetColumnGrand(true);
-    aSaveData.SetRowGrand(true);
-    aSaveData.SetFilterButton(bFilterButton);
-    aSaveData.SetDrillDown(true);
-
-    // Check the sanity of the source range.
-    const ScRange& rSrcRange = rDesc.GetSourceRange();
-    SCROW nRow1 = rSrcRange.aStart.Row();
-    SCROW nRow2 = rSrcRange.aEnd.Row();
-    CPPUNIT_ASSERT_MESSAGE("source range contains no data!", nRow2 - nRow1 > 1);
-
-    // Set the dimension information.
-    for (size_t i = 0; i < nFieldCount; ++i)
-    {
-        OUString aDimName = OUString::createFromAscii(aFields[i].pName);
-        ScDPSaveDimension* pDim = aSaveData.GetNewDimensionByName(aDimName);
-        pDim->SetOrientation(static_cast<sal_uInt16>(aFields[i].eOrient));
-        pDim->SetUsedHierarchy(0);
-
-        if (aFields[i].eOrient == sheet::DataPilotFieldOrientation_DATA)
-        {
-            sheet::GeneralFunction eFunc = sheet::GeneralFunction_SUM;
-            if (aFields[i].eFunc)
-                eFunc = static_cast<sheet::GeneralFunction>(aFields[i].eFunc);
-
-            pDim->SetFunction(eFunc);
-            pDim->SetReferenceValue(NULL);
-        }
-        else
-        {
-            sheet::DataPilotFieldSortInfo aSortInfo;
-            aSortInfo.IsAscending = true;
-            aSortInfo.Mode = 2;
-            pDim->SetSortInfo(&aSortInfo);
-
-            sheet::DataPilotFieldLayoutInfo aLayInfo;
-            aLayInfo.LayoutMode = 0;
-            aLayInfo.AddEmptyLines = false;
-            pDim->SetLayoutInfo(&aLayInfo);
-            sheet::DataPilotFieldAutoShowInfo aShowInfo;
-            aShowInfo.IsEnabled = false;
-            aShowInfo.ShowItemsMode = 0;
-            aShowInfo.ItemCount = 0;
-            pDim->SetAutoShowInfo(&aShowInfo);
-        }
-    }
-
-    // Don't forget the data layout dimension.
-    ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension();
-    pDim->SetOrientation(sheet::DataPilotFieldOrientation_ROW);
-    pDim->SetShowEmpty(true);
-
-    pDPObj->SetSaveData(aSaveData);
-    pDPObj->InvalidateData();
-
-    return pDPObj;
-}
-
-ScDPObject* createDPFromRange(
-    ScDocument* pDoc, const ScRange& rRange, DPFieldDef aFields[], size_t nFieldCount,
-    bool bFilterButton)
-{
-    ScSheetSourceDesc aSheetDesc(pDoc);
-    aSheetDesc.SetSourceRange(rRange);
-    return createDPFromSourceDesc(pDoc, aSheetDesc, aFields, nFieldCount, bFilterButton);
-}
-
-ScRange refresh(ScDPObject* pDPObj)
-{
-    bool bOverFlow = false;
-    ScRange aOutRange = pDPObj->GetNewOutputRange(bOverFlow);
-    CPPUNIT_ASSERT_MESSAGE("Table overflow!?", !bOverFlow);
-
-    pDPObj->Output(aOutRange.aStart);
-    aOutRange = pDPObj->GetOutRange();
-    return aOutRange;
-}
-
-ScRange refreshGroups(ScDPCollection* pDPs, ScDPObject* pDPObj)
-{
-    // We need to first create group data in the cache, then the group data in
-    // the object.
-    std::set<ScDPObject*> aRefs;
-    bool bSuccess = pDPs->ReloadGroupsInCache(pDPObj, aRefs);
-    CPPUNIT_ASSERT_MESSAGE("Failed to reload group data in cache.", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("There should be only one table linked to this cache.", aRefs.size() == 1);
-    pDPObj->ReloadGroupTableData();
-
-    return refresh(pDPObj);
-}
-
-}
-
-void Test::testPivotTable()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name",  sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Group", sheet::DataPilotFieldOrientation_COLUMN, 0 },
-        { "Score", sheet::DataPilotFieldOrientation_DATA, 0 }
-    };
-
-    // Raw data
-    const char* aData[][3] = {
-        { "Andy",    "A", "30" },
-        { "Bruce",   "A", "20" },
-        { "Charlie", "B", "45" },
-        { "David",   "B", "12" },
-        { "Edward",  "C",  "8" },
-        { "Frank",   "C", "15" },
-    };
-
-    size_t nFieldCount = SAL_N_ELEMENTS(aFields);
-    size_t nDataCount = SAL_N_ELEMENTS(aData);
-
-    ScRange aSrcRange = insertDPSourceData(m_pDoc, aFields, nFieldCount, aData, nDataCount);
-    SCROW nRow1 = aSrcRange.aStart.Row(), nRow2 = aSrcRange.aEnd.Row();
-    SCCOL nCol1 = aSrcRange.aStart.Col(), nCol2 = aSrcRange.aEnd.Col();
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0), aFields, nFieldCount, false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new datapilot object into document", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    bool bOverFlow = false;
-    ScRange aOutRange = pDPObj->GetNewOutputRange(bOverFlow);
-    CPPUNIT_ASSERT_MESSAGE("Table overflow!?", !bOverFlow);
-
-    pDPObj->Output(aOutRange.aStart);
-    aOutRange = pDPObj->GetOutRange();
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][5] = {
-            { "Sum - Score", "Group", 0, 0, 0 },
-            { "Name", "A", "B", "C", "Total Result" },
-            { "Andy", "30", 0, 0, "30" },
-            { "Bruce", "20", 0, 0, "20" },
-            { "Charlie", 0, "45", 0, "45" },
-            { "David", 0, "12", 0, "12" },
-            { "Edward", 0, 0, "8", "8" },
-            { "Frank", 0, 0, "15", "15" },
-            { "Total Result", "50", "57", "23", "130" }
-        };
-
-        bSuccess = checkDPTableOutput<5>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-    CPPUNIT_ASSERT_MESSAGE("There should be only one data cache.", pDPs->GetSheetCaches().size() == 1);
-
-    // Update the cell values.
-    double aData2[] = { 100, 200, 300, 400, 500, 600 };
-    for (size_t i = 0; i < SAL_N_ELEMENTS(aData2); ++i)
-    {
-        SCROW nRow = i + 1;
-        m_pDoc->SetValue(2, nRow, 0, aData2[i]);
-    }
-
-    printRange(m_pDoc, ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0), "Data sheet content (modified)");
-
-    // Now, create a copy of the datapilot object for the updated table, but
-    // don't reload the cache which should force the copy to use the old data
-    // from the cache.
-    ScDPObject* pDPObj2 = new ScDPObject(*pDPObj);
-    pDPs->InsertNewTable(pDPObj2);
-
-    aOutRange = pDPObj2->GetOutRange();
-    pDPObj2->ClearTableData();
-    pDPObj2->Output(aOutRange.aStart);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][5] = {
-            { "Sum - Score", "Group", 0, 0, 0 },
-            { "Name", "A", "B", "C", "Total Result" },
-            { "Andy", "30", 0, 0, "30" },
-            { "Bruce", "20", 0, 0, "20" },
-            { "Charlie", 0, "45", 0, "45" },
-            { "David", 0, "12", 0, "12" },
-            { "Edward", 0, 0, "8", "8" },
-            { "Frank", 0, 0, "15", "15" },
-            { "Total Result", "50", "57", "23", "130" }
-        };
-
-        bSuccess = checkDPTableOutput<5>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output (from old cache)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    CPPUNIT_ASSERT_MESSAGE("There should be only one data cache.", pDPs->GetSheetCaches().size() == 1);
-
-    // Free the first datapilot object after the 2nd one gets reloaded, to
-    // prevent the data cache from being deleted before the reload.
-    pDPs->FreeTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("There should be only one data cache.", pDPs->GetSheetCaches().size() == 1);
-
-    // This time clear the cache to refresh the data from the source range.
-    CPPUNIT_ASSERT_MESSAGE("This datapilot should be based on sheet data.", pDPObj2->IsSheetData());
-    std::set<ScDPObject*> aRefs;
-    sal_uLong nErrId = pDPs->ReloadCache(pDPObj2, aRefs);
-    CPPUNIT_ASSERT_MESSAGE("Cache reload failed.", nErrId == 0);
-    CPPUNIT_ASSERT_MESSAGE("Reloading a cache shouldn't remove any cache.",
-                           pDPs->GetSheetCaches().size() == 1);
-
-    pDPObj2->ClearTableData();
-    pDPObj2->Output(aOutRange.aStart);
-
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][5] = {
-            { "Sum - Score", "Group", 0, 0, 0 },
-            { "Name", "A", "B", "C", "Total Result" },
-            { "Andy", "100", 0, 0, "100" },
-            { "Bruce", "200", 0, 0, "200" },
-            { "Charlie", 0, "300", 0, "300" },
-            { "David", 0, "400", 0, "400" },
-            { "Edward", 0, 0, "500", "500" },
-            { "Frank", 0, 0, "600", "600" },
-            { "Total Result", "300", "700", "1100", "2100" }
-        };
-
-        bSuccess = checkDPTableOutput<5>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output (refreshed)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    CPPUNIT_ASSERT_MESSAGE("Cache should be here.", pDPs->GetSheetCaches().hasCache(aSrcRange));
-
-    // Swap the two sheets.
-    m_pDoc->MoveTab(1, 0);
-    CPPUNIT_ASSERT_MESSAGE("Swapping the sheets shouldn't remove the cache.",
-                           pDPs->GetSheetCaches().size() == 1);
-    CPPUNIT_ASSERT_MESSAGE("Cache should have moved.", !pDPs->GetSheetCaches().hasCache(aSrcRange));
-    aSrcRange.aStart.SetTab(1);
-    aSrcRange.aEnd.SetTab(1);
-    CPPUNIT_ASSERT_MESSAGE("Cache should be here.", pDPs->GetSheetCaches().hasCache(aSrcRange));
-
-    pDPs->FreeTable(pDPObj2);
-    CPPUNIT_ASSERT_MESSAGE("There shouldn't be any data pilot table stored with the document.",
-                           pDPs->GetCount() == 0);
-
-    CPPUNIT_ASSERT_MESSAGE("There shouldn't be any more data cache.",
-                           pDPs->GetSheetCaches().size() == 0);
-
-    // Insert a brand new pivot table object once again, but this time, don't
-    // create the output to avoid creating a data cache.
-    m_pDoc->DeleteTab(1);
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    pDPObj = createDPFromRange(
-        m_pDoc, ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0), aFields, nFieldCount, false);
-    bSuccess = pDPs->InsertNewTable(pDPObj);
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new datapilot object into document", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-    CPPUNIT_ASSERT_MESSAGE("Data cache shouldn't exist yet before creating the table output.",
-                           pDPs->GetSheetCaches().size() == 0);
-
-    // Now, "refresh" the table.  This should still return a reference to self
-    // even with the absence of data cache.
-    aRefs.clear();
-    pDPs->ReloadCache(pDPObj, aRefs);
-    CPPUNIT_ASSERT_MESSAGE("It should return the same object as a reference.",
-                           aRefs.size() == 1 && *aRefs.begin() == pDPObj);
-
-    pDPs->FreeTable(pDPObj);
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableLabels()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Software", sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Version",  sheet::DataPilotFieldOrientation_COLUMN, 0 },
-        { "1.2.3",    sheet::DataPilotFieldOrientation_DATA, 0 }
-    };
-
-    // Raw data
-    const char* aData[][3] = {
-        { "LibreOffice", "3.3.0", "30" },
-        { "LibreOffice", "3.3.1", "20" },
-        { "LibreOffice", "3.4.0", "45" },
-    };
-
-    size_t nFieldCount = SAL_N_ELEMENTS(aFields);
-    size_t nDataCount = SAL_N_ELEMENTS(aData);
-
-    ScRange aSrcRange = insertDPSourceData(m_pDoc, aFields, nFieldCount, aData, nDataCount);
-    SCROW nRow1 = aSrcRange.aStart.Row(), nRow2 = aSrcRange.aEnd.Row();
-    SCCOL nCol1 = aSrcRange.aStart.Col(), nCol2 = aSrcRange.aEnd.Col();
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0), aFields, nFieldCount, false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new datapilot object into document", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][5] = {
-            { "Sum - 1.2.3", "Version", 0, 0, 0 },
-            { "Software", "3.3.0", "3.3.1", "3.4.0", "Total Result" },
-            { "LibreOffice", "30", "20", "45", "95" },
-            { "Total Result", "30", "20", "45", "95" }
-        };
-
-        bSuccess = checkDPTableOutput<5>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    pDPs->FreeTable(pDPObj);
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableDateLabels()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name",  sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Date",  sheet::DataPilotFieldOrientation_COLUMN, 0 },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, 0 }
-    };
-
-    // Raw data
-    const char* aData[][3] = {
-        { "Zena",   "2011-1-1", "30" },
-        { "Yodel",  "2011-1-2", "20" },
-        { "Xavior", "2011-1-3", "45" }
-    };
-
-    size_t nFieldCount = SAL_N_ELEMENTS(aFields);
-    size_t nDataCount = SAL_N_ELEMENTS(aData);
-
-    ScRange aSrcRange = insertDPSourceData(m_pDoc, aFields, nFieldCount, aData, nDataCount);
-    SCROW nRow1 = aSrcRange.aStart.Row(), nRow2 = aSrcRange.aEnd.Row();
-    SCCOL nCol1 = aSrcRange.aStart.Col(), nCol2 = aSrcRange.aEnd.Col();
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0), aFields, nFieldCount, false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new datapilot object into document", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][5] = {
-            { "Sum - Value", "Date", 0, 0, 0 },
-            { "Name", "2011-01-01", "2011-01-02", "2011-01-03", "Total Result" },
-            { "Xavior",  0, 0, "45", "45" },
-            { "Yodel",  0, "20", 0, "20" },
-            { "Zena",  "30", 0, 0, "30" },
-            { "Total Result", "30", "20", "45", "95" }
-        };
-
-        bSuccess = checkDPTableOutput<5>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    {
-        const char* aChecks[] = {
-            "2011-01-01", "2011-01-02", "2011-01-03"
-        };
-
-        // Make sure those cells that contain dates are numeric.
-        SCROW nRow = aOutRange.aStart.Row() + 1;
-        nCol1 = aOutRange.aStart.Col() + 1;
-        nCol2 = nCol1 + 2;
-        for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
-        {
-            OUString aVal = m_pDoc->GetString(nCol, nRow, 1);
-            CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected.", aVal.equalsAscii(aChecks[nCol-nCol1]));
-            CPPUNIT_ASSERT_MESSAGE("This cell contains a date value and is supposed to be numeric.",
-                                   m_pDoc->HasValueData(nCol, nRow, 1));
-        }
-    }
-
-    pDPs->FreeTable(pDPObj);
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableFilters()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name",   sheet::DataPilotFieldOrientation_HIDDEN, 0 },
-        { "Group1", sheet::DataPilotFieldOrientation_HIDDEN, 0 },
-        { "Group2", sheet::DataPilotFieldOrientation_PAGE, 0 },
-        { "Val1",   sheet::DataPilotFieldOrientation_DATA, 0 },
-        { "Val2",   sheet::DataPilotFieldOrientation_DATA, 0 }
-    };
-
-    // Raw data
-    const char* aData[][5] = {
-        { "A", "1", "A", "1", "10" },
-        { "B", "1", "A", "1", "10" },
-        { "C", "1", "B", "1", "10" },
-        { "D", "1", "B", "1", "10" },
-        { "E", "2", "A", "1", "10" },
-        { "F", "2", "A", "1", "10" },
-        { "G", "2", "B", "1", "10" },
-        { "H", "2", "B", "1", "10" }
-    };
-
-    size_t nFieldCount = SAL_N_ELEMENTS(aFields);
-    size_t nDataCount = SAL_N_ELEMENTS(aData);
-
-    ScRange aSrcRange = insertDPSourceData(m_pDoc, aFields, nFieldCount, aData, nDataCount);
-    SCROW nRow1 = aSrcRange.aStart.Row(), nRow2 = aSrcRange.aEnd.Row();
-    SCCOL nCol1 = aSrcRange.aStart.Col(), nCol2 = aSrcRange.aEnd.Col();
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0), aFields, nFieldCount, true);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new datapilot object into document", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Filter", 0 },
-            { "Group2", "- all -" },
-            { 0, 0 },
-            { "Data", 0 },
-            { "Sum - Val1", "8" },
-            { "Sum - Val2", "80" }
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output (unfiltered)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
-
-    ScAddress aFormulaAddr = aOutRange.aEnd;
-    aFormulaAddr.IncRow(2);
-    m_pDoc->SetString(aFormulaAddr.Col(), aFormulaAddr.Row(), aFormulaAddr.Tab(),
-                      OUString("=B6"));
-    double fTest = m_pDoc->GetValue(aFormulaAddr);
-    CPPUNIT_ASSERT_MESSAGE("Incorrect formula value that references a cell in the pivot table output.", fTest == 80.0);
-
-    // Set current page of 'Group2' to 'A'.
-    pDPObj->BuildAllDimensionMembers();
-    ScDPSaveData aSaveData(*pDPObj->GetSaveData());
-    ScDPSaveDimension* pPageDim = aSaveData.GetDimensionByName(
-        OUString("Group2"));
-    CPPUNIT_ASSERT_MESSAGE("Dimension not found", pPageDim);
-    OUString aPage("A");
-    pPageDim->SetCurrentPage(&aPage);
-    pDPObj->SetSaveData(aSaveData);
-    aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Filter", 0 },
-            { "Group2", "A" },
-            { 0, 0 },
-            { "Data", 0 },
-            { "Sum - Val1", "4" },
-            { "Sum - Val2", "40" }
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output (filtered by page)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    fTest = m_pDoc->GetValue(aFormulaAddr);
-    CPPUNIT_ASSERT_MESSAGE("Incorrect formula value that references a cell in the pivot table output.", fTest == 40.0);
-
-    // Set query filter.
-    ScSheetSourceDesc aDesc(*pDPObj->GetSheetDesc());
-    ScQueryParam aQueryParam(aDesc.GetQueryParam());
-    CPPUNIT_ASSERT_MESSAGE("There should be at least one query entry.", aQueryParam.GetEntryCount() > 0);
-    ScQueryEntry& rEntry = aQueryParam.GetEntry(0);
-    rEntry.bDoQuery = true;
-    rEntry.nField = 1;  // Group1
-    rEntry.GetQueryItem().mfVal = 1;
-    aDesc.SetQueryParam(aQueryParam);
-    pDPObj->SetSheetDesc(aDesc);
-    aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Filter", 0 },
-            { "Group2", "A" },
-            { 0, 0 },
-            { "Data", 0 },
-            { "Sum - Val1", "2" },
-            { "Sum - Val2", "20" }
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output (filtered by query)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    fTest = m_pDoc->GetValue(aFormulaAddr);
-    CPPUNIT_ASSERT_MESSAGE("Incorrect formula value that references a cell in the pivot table output.", fTest == 20.0);
-
-    // Set the current page of 'Group2' back to '- all -'. The query filter
-    // should still be in effect.
-    pPageDim->SetCurrentPage(NULL); // Remove the page.
-    pDPObj->SetSaveData(aSaveData);
-    aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Filter", 0 },
-            { "Group2", "- all -" },
-            { 0, 0 },
-            { "Data", 0 },
-            { "Sum - Val1", "4" },
-            { "Sum - Val2", "40" }
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output (filtered by page)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_MESSAGE("There shouldn't be any data pilot table stored with the document.",
-                           pDPs->GetCount() == 0);
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableNamedSource()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name",  sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Group", sheet::DataPilotFieldOrientation_COLUMN, 0 },
-        { "Score", sheet::DataPilotFieldOrientation_DATA, 0 }
-    };
-
-    // Raw data
-    const char* aData[][3] = {
-        { "Andy",    "A", "30" },
-        { "Bruce",   "A", "20" },
-        { "Charlie", "B", "45" },
-        { "David",   "B", "12" },
-        { "Edward",  "C",  "8" },
-        { "Frank",   "C", "15" },
-    };
-
-    size_t nFieldCount = SAL_N_ELEMENTS(aFields);
-    size_t nDataCount = SAL_N_ELEMENTS(aData);
-
-    // Insert the raw data.
-    ScRange aSrcRange = insertDPSourceData(m_pDoc, aFields, nFieldCount, aData, nDataCount);
-    OUString aRangeStr;
-    aSrcRange.Format(aRangeStr, SCR_ABS_3D, m_pDoc);
-
-    // Name this range.
-    OUString aRangeName("MyData");
-    ScRangeName* pNames = m_pDoc->GetRangeName();
-    CPPUNIT_ASSERT_MESSAGE("Failed to get global range name container.", pNames);
-    ScRangeData* pName = new ScRangeData(
-        m_pDoc, aRangeName, aRangeStr);
-    bool bSuccess = pNames->insert(pName);
-    CPPUNIT_ASSERT_MESSAGE("Failed to insert a new name.", bSuccess);
-
-    ScSheetSourceDesc aSheetDesc(m_pDoc);
-    aSheetDesc.SetRangeName(aRangeName);
-    ScDPObject* pDPObj = createDPFromSourceDesc(m_pDoc, aSheetDesc, aFields, nFieldCount, false);
-    CPPUNIT_ASSERT_MESSAGE("Failed to create a new pivot table object.", pDPObj);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bSuccess = pDPs->InsertNewTable(pDPObj);
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][5] = {
-            { "Sum - Score", "Group", 0, 0, 0 },
-            { "Name", "A", "B", "C", "Total Result" },
-            { "Andy", "30", 0, 0, "30" },
-            { "Bruce", "20", 0, 0, "20" },
-            { "Charlie", 0, "45", 0, "45" },
-            { "David", 0, "12", 0, "12" },
-            { "Edward", 0, 0, "8", "8" },
-            { "Frank", 0, 0, "15", "15" },
-            { "Total Result", "50", "57", "23", "130" }
-        };
-
-        bSuccess = checkDPTableOutput<5>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    CPPUNIT_ASSERT_MESSAGE("There should be one named range data cache.",
-                           pDPs->GetNameCaches().size() == 1 && pDPs->GetSheetCaches().size() == 0);
-
-    // Move the table with pivot table to the left of the source data sheet.
-    m_pDoc->MoveTab(1, 0);
-    OUString aTabName;
-    m_pDoc->GetName(0, aTabName);
-    CPPUNIT_ASSERT_MESSAGE( "Wrong sheet name.", aTabName == "Table" );
-    CPPUNIT_ASSERT_MESSAGE("Pivot table output is on the wrong sheet!",
-                           pDPObj->GetOutRange().aStart.Tab() == 0);
-
-    CPPUNIT_ASSERT_MESSAGE("Moving the pivot table to another sheet shouldn't have changed the cache state.",
-                           pDPs->GetNameCaches().size() == 1 && pDPs->GetSheetCaches().size() == 0);
-
-    const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
-    CPPUNIT_ASSERT_MESSAGE("Sheet source description doesn't exist.", pDesc);
-    CPPUNIT_ASSERT_MESSAGE("Named source range has been altered unexpectedly!",
-                           pDesc->GetRangeName().equals(aRangeName));
-
-    CPPUNIT_ASSERT_MESSAGE("Cache should exist.", pDPs->GetNameCaches().hasCache(aRangeName));
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_MESSAGE("There should be no more tables.", pDPs->GetCount() == 0);
-    CPPUNIT_ASSERT_MESSAGE("There shouldn't be any more cache stored.",
-                           pDPs->GetNameCaches().size() == 0);
-
-    pNames->clear();
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableCache()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-
-    // Raw data
-    const char* aData[][3] = {
-        { "F1", "F2", "F3" },
-        { "Z",  "A", "30" },
-        { "R",  "A", "20" },
-        { "A",  "B", "45" },
-        { "F",  "B", "12" },
-        { "Y",  "C",  "8" },
-        { "12", "C", "15" },
-    };
-
-    ScAddress aPos(1,1,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
-    CPPUNIT_ASSERT_MESSAGE("failed to insert range data at correct position", aDataRange.aStart == aPos);
-
-    ScDPCache aCache(m_pDoc);
-    aCache.InitFromDoc(m_pDoc, aDataRange);
-    long nDimCount = aCache.GetColumnCount();
-    CPPUNIT_ASSERT_MESSAGE("wrong dimension count.", nDimCount == 3);
-    OUString aDimName = aCache.GetDimensionName(0);
-    CPPUNIT_ASSERT_MESSAGE("wrong dimension name", aDimName.equalsAscii("F1"));
-    aDimName = aCache.GetDimensionName(1);
-    CPPUNIT_ASSERT_MESSAGE("wrong dimension name", aDimName.equalsAscii("F2"));
-    aDimName = aCache.GetDimensionName(2);
-    CPPUNIT_ASSERT_MESSAGE("wrong dimension name", aDimName.equalsAscii("F3"));
-
-    // In each dimension, member ID values also represent their sort order (in
-    // source dimensions only, not in group dimensions). Value items are
-    // sorted before string ones. Also, no duplicate dimension members should
-    // exist.
-
-    // Dimension 0 - a mix of strings and values.
-    long nMemCount = aCache.GetDimMemberCount(0);
-    CPPUNIT_ASSERT_MESSAGE("wrong dimension member count", nMemCount == 6);
-    const ScDPItemData* pItem = aCache.GetItemDataById(0, 0);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::Value &&
-                           pItem->GetValue() == 12);
-    pItem = aCache.GetItemDataById(0, 1);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::String &&
-                           pItem->GetString().equalsAscii("A"));
-    pItem = aCache.GetItemDataById(0, 2);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::String &&
-                           pItem->GetString().equalsAscii("F"));
-    pItem = aCache.GetItemDataById(0, 3);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::String &&
-                           pItem->GetString().equalsAscii("R"));
-    pItem = aCache.GetItemDataById(0, 4);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::String &&
-                           pItem->GetString().equalsAscii("Y"));
-    pItem = aCache.GetItemDataById(0, 5);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::String &&
-                           pItem->GetString().equalsAscii("Z"));
-    pItem = aCache.GetItemDataById(0, 6);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", !pItem);
-
-    // Dimension 1 - duplicate values in source.
-    nMemCount = aCache.GetDimMemberCount(1);
-    CPPUNIT_ASSERT_MESSAGE("wrong dimension member count", nMemCount == 3);
-    pItem = aCache.GetItemDataById(1, 0);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::String &&
-                           pItem->GetString().equalsAscii("A"));
-    pItem = aCache.GetItemDataById(1, 1);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::String &&
-                           pItem->GetString().equalsAscii("B"));
-    pItem = aCache.GetItemDataById(1, 2);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::String &&
-                           pItem->GetString().equalsAscii("C"));
-    pItem = aCache.GetItemDataById(1, 3);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", !pItem);
-
-    // Dimension 2 - values only.
-    nMemCount = aCache.GetDimMemberCount(2);
-    CPPUNIT_ASSERT_MESSAGE("wrong dimension member count", nMemCount == 6);
-    pItem = aCache.GetItemDataById(2, 0);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::Value &&
-                           pItem->GetValue() == 8);
-    pItem = aCache.GetItemDataById(2, 1);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::Value &&
-                           pItem->GetValue() == 12);
-    pItem = aCache.GetItemDataById(2, 2);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::Value &&
-                           pItem->GetValue() == 15);
-    pItem = aCache.GetItemDataById(2, 3);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::Value &&
-                           pItem->GetValue() == 20);
-    pItem = aCache.GetItemDataById(2, 4);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::Value &&
-                           pItem->GetValue() == 30);
-    pItem = aCache.GetItemDataById(2, 5);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", pItem &&
-                           pItem->GetType() == ScDPItemData::Value &&
-                           pItem->GetValue() == 45);
-    pItem = aCache.GetItemDataById(2, 6);
-    CPPUNIT_ASSERT_MESSAGE("wrong item value", !pItem);
-
-    {
-        // Check the integrity of the source data.
-        ScDPItemData aTest;
-        long nDim;
-
-        {
-            // Dimension 0: Z, R, A, F, Y, 12
-            nDim = 0;
-            const char* aChecks[] = { "Z", "R", "A", "F", "Y" };
-            for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
-            {
-                pItem = aCache.GetItemDataById(nDim, aCache.GetItemDataId(nDim, i, false));
-                aTest.SetString(OUString::createFromAscii(aChecks[i]));
-                CPPUNIT_ASSERT_MESSAGE("wrong data value", pItem && *pItem == aTest);
-            }
-
-            pItem = aCache.GetItemDataById(nDim, aCache.GetItemDataId(nDim, 5, false));
-            aTest.SetValue(12);
-            CPPUNIT_ASSERT_MESSAGE("wrong data value", pItem && *pItem == aTest);
-        }
-
-        {
-            // Dimension 1: A, A, B, B, C, C
-            nDim = 1;
-            const char* aChecks[] = { "A", "A", "B", "B", "C", "C" };
-            for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
-            {
-                pItem = aCache.GetItemDataById(nDim, aCache.GetItemDataId(nDim, i, false));
-                aTest.SetString(OUString::createFromAscii(aChecks[i]));
-                CPPUNIT_ASSERT_MESSAGE("wrong data value", pItem && *pItem == aTest);
-            }
-        }
-
-        {
-            // Dimension 2: 30, 20, 45, 12, 8, 15
-            nDim = 2;
-            double aChecks[] = { 30, 20, 45, 12, 8, 15 };
-            for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
-            {
-                pItem = aCache.GetItemDataById(nDim, aCache.GetItemDataId(nDim, i, false));
-                aTest.SetValue(aChecks[i]);
-                CPPUNIT_ASSERT_MESSAGE("wrong data value", pItem && *pItem == aTest);
-            }
-        }
-    }
-
-    // Now, on to testing the filtered cache.
-
-    {
-        // Non-filtered cache - everything should be visible.
-        ScDPFilteredCache aFilteredCache(aCache);
-        aFilteredCache.fillTable();
-
-        sal_Int32 nRows = aFilteredCache.getRowSize();
-        CPPUNIT_ASSERT_MESSAGE("Wrong dimension.", nRows == 6 && aFilteredCache.getColSize() == 3);
-
-        for (sal_Int32 i = 0; i < nRows; ++i)
-        {
-            if (!aFilteredCache.isRowActive(i))
-            {
-                std::ostringstream os;
-                os << "Row " << i << " should be visible but it isn't.";
-                CPPUNIT_ASSERT_MESSAGE(os.str().c_str(), false);
-            }
-        }
-    }
-
-    // TODO : Add test for filtered caches.
-
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableDuplicateDataFields()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Raw data
-    const char* aData[][2] = {
-        { "Name", "Value" },
-        { "A",       "45" },
-        { "A",        "5" },
-        { "A",       "41" },
-        { "A",       "49" },
-        { "A",        "4" },
-        { "B",       "33" },
-        { "B",       "84" },
-        { "B",       "74" },
-        { "B",        "8" },
-        { "B",       "68" }
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name",  sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_COUNT }
-    };
-
-    ScAddress aPos(2,2,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
-    CPPUNIT_ASSERT_MESSAGE("failed to insert range data at correct position", aDataRange.aStart == aPos);
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount(), static_cast<size_t>(1));
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][3] = {
-            { "Name", "Data", 0 },
-            { "A", "Sum - Value", "144" },
-            { 0, "Count - Value", "5" },
-            { "B", "Sum - Value", "267" },
-            { 0, "Count - Value", "5" },
-            { "Total Sum - Value", 0, "411" },
-            { "Total Count - Value", 0, "10" },
-        };
-
-        bSuccess = checkDPTableOutput<3>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    // Move the data layout dimension from row to column.
-    ScDPSaveData* pSaveData = pDPObj->GetSaveData();
-    CPPUNIT_ASSERT_MESSAGE("No save data!?", pSaveData);
-    ScDPSaveDimension* pDataLayout = pSaveData->GetDataLayoutDimension();
-    CPPUNIT_ASSERT_MESSAGE("No data layout dimension.", pDataLayout);
-    pDataLayout->SetOrientation(sheet::DataPilotFieldOrientation_COLUMN);
-    pDPObj->SetSaveData(*pSaveData);
-
-    // Refresh the table output.
-    aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][3] = {
-            { 0, "Data", 0 },
-            { "Name", "Sum - Value", "Count - Value" },
-            { "A", "144", "5" },
-            { "B", "267", "5" },
-            { "Total Result", "411", "10" }
-        };
-
-        bSuccess = checkDPTableOutput<3>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    ScPivotParam aParam;
-    pDPObj->FillLabelData(aParam);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be exactly 4 labels (2 original, 1 data layout, and 1 duplicate dimensions).",
-                           aParam.maLabelArray.size(), static_cast<size_t>(4));
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
-                           pDPs->GetSheetCaches().size(), static_cast<size_t>(0));
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableNormalGrouping()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Raw data
-    const char* aData[][2] = {
-        { "Name", "Value" },
-        { "A", "1" },
-        { "B", "2" },
-        { "C", "3" },
-        { "D", "4" },
-        { "E", "5" },
-        { "F", "6" },
-        { "G", "7" }
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name",  sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-    };
-
-    ScAddress aPos(1,1,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
-    CPPUNIT_ASSERT_MESSAGE("failed to insert range data at correct position", aDataRange.aStart == aPos);
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount(), static_cast<size_t>(1));
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", "1" },
-            { "B", "2" },
-            { "C", "3" },
-            { "D", "4" },
-            { "E", "5" },
-            { "F", "6" },
-            { "G", "7" },
-            { "Total Result", "28" }
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Initial output without grouping");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    ScDPSaveData* pSaveData = pDPObj->GetSaveData();
-    CPPUNIT_ASSERT_MESSAGE("No save data !?", pSaveData);
-    ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData();
-    CPPUNIT_ASSERT_MESSAGE("Failed to create dimension data.", pDimData);
-
-    OUString aGroupPrefix("Group");
-    OUString aBaseDimName("Name");
-    OUString aGroupDimName =
-        pDimData->CreateGroupDimName(aBaseDimName, *pDPObj, false, NULL);
-
-    {
-        // Group A, B and C together.
-        ScDPSaveGroupDimension aGroupDim(aBaseDimName, aGroupDimName);
-        OUString aGroupName = aGroupDim.CreateGroupName(aGroupPrefix);
-        CPPUNIT_ASSERT_MESSAGE("Unexpected group name", aGroupName.equalsAscii("Group1"));
-
-        ScDPSaveGroupItem aGroup(aGroupName);
-        aGroup.AddElement(OUString("A"));
-        aGroup.AddElement(OUString("B"));
-        aGroup.AddElement(OUString("C"));
-        aGroupDim.AddGroupItem(aGroup);
-        pDimData->AddGroupDimension(aGroupDim);
-
-        ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aGroupDimName);
-        pDim->SetOrientation(sheet::DataPilotFieldOrientation_ROW);
-        pSaveData->SetPosition(pDim, 0); // Set it before the base dimension.
-    }
-
-    pDPObj->SetSaveData(*pSaveData);
-    aOutRange = refreshGroups(pDPs, pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][3] = {
-            { "Name2", "Name", 0 },
-            { "D", "D", "4" },
-            { "E", "E", "5" },
-            { "F", "F", "6" },
-            { "G", "G", "7" },
-            { "Group1", "A", "1" },
-            { 0,        "B", "2" },
-            { 0,        "C", "3" },
-            { "Total Result", 0, "28" }
-        };
-
-        bSuccess = checkDPTableOutput<3>(m_pDoc, aOutRange, aOutputCheck, "A, B, C grouped by Group1.");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    pSaveData = pDPObj->GetSaveData();
-    pDimData = pSaveData->GetDimensionData();
-
-    {
-        // Group D, E, F together.
-        ScDPSaveGroupDimension* pGroupDim = pDimData->GetGroupDimAccForBase(aBaseDimName);
-        CPPUNIT_ASSERT_MESSAGE("There should be an existing group dimension.", pGroupDim);
-        OUString aGroupName = pGroupDim->CreateGroupName(aGroupPrefix);
-        CPPUNIT_ASSERT_MESSAGE("Unexpected group name", aGroupName.equalsAscii("Group2"));
-
-        ScDPSaveGroupItem aGroup(aGroupName);
-        aGroup.AddElement(OUString("D"));
-        aGroup.AddElement(OUString("E"));
-        aGroup.AddElement(OUString("F"));
-        pGroupDim->AddGroupItem(aGroup);
-    }
-
-    pDPObj->SetSaveData(*pSaveData);
-    aOutRange = refreshGroups(pDPs, pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][3] = {
-            { "Name2", "Name", 0 },
-            { "G", "G", "7" },
-            { "Group1", "A", "1" },
-            { 0,        "B", "2" },
-            { 0,        "C", "3" },
-            { "Group2", "D", "4" },
-            { 0,        "E", "5" },
-            { 0,        "F", "6" },
-            { "Total Result", 0, "28" }
-        };
-
-        bSuccess = checkDPTableOutput<3>(m_pDoc, aOutRange, aOutputCheck, "D, E, F grouped by Group2.");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
-                           pDPs->GetSheetCaches().size(), static_cast<size_t>(0));
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableNumberGrouping()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Raw data
-    const char* aData[][2] = {
-        { "Order", "Score" },
-        { "43", "171" },
-        { "18", "20"  },
-        { "69", "159" },
-        { "95", "19"  },
-        { "96", "163" },
-        { "46", "70"  },
-        { "22", "36"  },
-        { "81", "49"  },
-        { "54", "61"  },
-        { "39", "62"  },
-        { "86", "17"  },
-        { "34", "0"   },
-        { "30", "25"  },
-        { "24", "103" },
-        { "16", "59"  },
-        { "24", "119" },
-        { "15", "86"  },
-        { "69", "170" }
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Order", sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Score", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-    };
-
-    ScAddress aPos(1,1,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
-    CPPUNIT_ASSERT_MESSAGE("failed to insert range data at correct position", aDataRange.aStart == aPos);
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount(), static_cast<size_t>(1));
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScDPSaveData* pSaveData = pDPObj->GetSaveData();
-    CPPUNIT_ASSERT_MESSAGE("No save data !?", pSaveData);
-    ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData();
-    CPPUNIT_ASSERT_MESSAGE("No dimension data !?", pDimData);
-
-    {
-        ScDPNumGroupInfo aInfo;
-        aInfo.mbEnable = true;
-        aInfo.mbAutoStart = false;
-        aInfo.mbAutoEnd = false;
-        aInfo.mbDateValues = false;
-        aInfo.mbIntegerOnly = true;
-        aInfo.mfStart = 30;
-        aInfo.mfEnd = 60;
-        aInfo.mfStep = 10;
-        ScDPSaveNumGroupDimension aGroup(OUString("Order"), aInfo);
-        pDimData->AddNumGroupDimension(aGroup);
-    }
-
-    pDPObj->SetSaveData(*pSaveData);
-    ScRange aOutRange = refreshGroups(pDPs, pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Order", 0 },
-            { "<30",   "423" },
-            { "30-39", "87"  },
-            { "40-49", "241" },
-            { "50-60", "61"  },
-            { ">60",   "577" },
-            { "Total Result", "1389" }
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Order grouped by numbers");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
-                           pDPs->GetSheetCaches().size(), static_cast<size_t>(0));
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableDateGrouping()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Raw data
-    const char* aData[][2] = {
-        { "Date", "Value" },
-        { "2011-01-01", "1" },
-        { "2011-03-02", "2" },
-        { "2012-01-04", "3" },
-        { "2012-02-23", "4" },
-        { "2012-02-24", "5" },
-        { "2012-03-15", "6" },
-        { "2011-09-03", "7" },
-        { "2012-12-25", "8" }
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Date", sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-    };
-
-    ScAddress aPos(1,1,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
-    CPPUNIT_ASSERT_MESSAGE("failed to insert range data at correct position", aDataRange.aStart == aPos);
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScDPSaveData* pSaveData = pDPObj->GetSaveData();
-    CPPUNIT_ASSERT_MESSAGE("No save data !?", pSaveData);
-    ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData();
-    CPPUNIT_ASSERT_MESSAGE("No dimension data !?", pDimData);
-
-    OUString aBaseDimName("Date");
-
-    ScDPNumGroupInfo aInfo;
-    aInfo.mbEnable = true;
-    aInfo.mbAutoStart = true;
-    aInfo.mbAutoEnd = true;
-    {
-        // Turn the Date dimension into months.  The first of the date
-        // dimensions is always a number-group dimension which replaces the
-        // original dimension.
-        ScDPSaveNumGroupDimension aGroup(aBaseDimName, aInfo, sheet::DataPilotFieldGroupBy::MONTHS);
-        pDimData->AddNumGroupDimension(aGroup);
-    }
-
-    {
-        // Add quarter dimension.  This will be an additional dimension.
-        OUString aGroupDimName =
-            pDimData->CreateDateGroupDimName(
-                sheet::DataPilotFieldGroupBy::QUARTERS, *pDPObj, true, NULL);
-        ScDPSaveGroupDimension aGroupDim(aBaseDimName, aGroupDimName);
-        aGroupDim.SetDateInfo(aInfo, sheet::DataPilotFieldGroupBy::QUARTERS);
-        pDimData->AddGroupDimension(aGroupDim);
-
-        // Set orientation.
-        ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aGroupDimName);
-        pDim->SetOrientation(sheet::DataPilotFieldOrientation_ROW);
-        pSaveData->SetPosition(pDim, 0); // set it to the left end.
-    }
-
-    {
-        // Add year dimension.  This is a new dimension also.
-        OUString aGroupDimName =
-            pDimData->CreateDateGroupDimName(
-                sheet::DataPilotFieldGroupBy::YEARS, *pDPObj, true, NULL);
-        ScDPSaveGroupDimension aGroupDim(aBaseDimName, aGroupDimName);
-        aGroupDim.SetDateInfo(aInfo, sheet::DataPilotFieldGroupBy::YEARS);
-        pDimData->AddGroupDimension(aGroupDim);
-
-        // Set orientation.
-        ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aGroupDimName);
-        pDim->SetOrientation(sheet::DataPilotFieldOrientation_ROW);
-        pSaveData->SetPosition(pDim, 0); // set it to the left end.
-    }
-
-    pDPObj->SetSaveData(*pSaveData);
-    ScRange aOutRange = refreshGroups(pDPs, pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][4] = {
-            { "Years", "Quarters", "Date", 0 },
-            { "2011", "Q1", "Jan", "1" },
-            { 0, 0,         "Mar", "2" },
-            { 0,      "Q3", "Sep", "7" },
-            { "2012", "Q1", "Jan", "3" },
-            { 0, 0,         "Feb", "9" },
-            { 0, 0,         "Mar", "6" },
-            { 0,      "Q4", "Dec", "8" },
-            { "Total Result", 0, 0, "36" },
-        };
-
-        bSuccess = checkDPTableOutput<4>(m_pDoc, aOutRange, aOutputCheck, "Years, quarters and months date groups.");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    {
-        // Let's hide year 2012.
-        pSaveData = pDPObj->GetSaveData();
-        ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(OUString("Years"));
-        CPPUNIT_ASSERT_MESSAGE("Years dimension should exist.", pDim);
-        ScDPSaveMember* pMem = pDim->GetMemberByName(OUString("2012"));
-        CPPUNIT_ASSERT_MESSAGE("Member should exist.", pMem);
-        pMem->SetIsVisible(false);
-    }
-    pDPObj->SetSaveData(*pSaveData);
-    pDPObj->ReloadGroupTableData();
-    pDPObj->InvalidateData();
-
-    aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][4] = {
-            { "Years", "Quarters", "Date", 0 },
-            { "2011", "Q1", "Jan", "1" },
-            { 0, 0,         "Mar", "2" },
-            { 0,      "Q3", "Sep", "7" },
-            { "Total Result", 0, 0, "10" },
-        };
-
-        bSuccess = checkDPTableOutput<4>(m_pDoc, aOutRange, aOutputCheck, "Year 2012 data now hidden");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    // Remove all date grouping. The source dimension "Date" has two
-    // external dimensions ("Years" and "Quarters") and one internal ("Date"
-    // the same name but different hierarchy).  Remove all of them.
-    pSaveData = pDPObj->GetSaveData();
-    pSaveData->RemoveAllGroupDimensions(aBaseDimName);
-    pDPObj->SetSaveData(*pSaveData);
-    pDPObj->ReloadGroupTableData();
-    pDPObj->InvalidateData();
-
-    aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Date", 0 },
-            { "2011-01-01", "1" },
-            { "2011-03-02", "2" },
-            { "2011-09-03", "7" },
-            { "2012-01-04", "3" },
-            { "2012-02-23", "4" },
-            { "2012-02-24", "5" },
-            { "2012-03-15", "6" },
-            { "2012-12-25", "8" },
-            { "Total Result", "36" }
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Remove all date grouping.");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
-                           pDPs->GetSheetCaches().size(), static_cast<size_t>(0));
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableEmptyRows()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Raw data
-    const char* aData[][2] = {
-        { "Name", "Value" },
-        { "A", "1" },
-        { "B", "2" },
-        { "C", "3" },
-        { "D", "4" },
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name", sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-    };
-
-    ScAddress aPos(1,1,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
-    CPPUNIT_ASSERT_MESSAGE("failed to insert range data at correct position", aDataRange.aStart == aPos);
-
-    // Extend the range downward to include some trailing empty rows.
-    aDataRange.aEnd.IncRow(2);
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", "1" },
-            { "B", "2" },
-            { "C", "3" },
-            { "D", "4" },
-            { "(empty)", 0 },
-            { "Total Result", "10" },
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Include empty rows");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    // This time, ignore empty rows.
-    ScDPSaveData* pSaveData = pDPObj->GetSaveData();
-    CPPUNIT_ASSERT_MESSAGE("Save data doesn't exist.", pSaveData);
-    pSaveData->SetIgnoreEmptyRows(true);
-    pDPObj->ClearTableData();
-    aOutRange = refresh(pDPObj);
-
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", "1" },
-            { "B", "2" },
-            { "C", "3" },
-            { "D", "4" },
-            { "Total Result", "10" },
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Ignore empty rows");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    // Modify the source to remove member 'A', then refresh the table.
-    m_pDoc->SetString(1, 2, 0, "B");
-
-    std::set<ScDPObject*> aRefs;
-    sal_uLong nErr = pDPs->ReloadCache(pDPObj, aRefs);
-    CPPUNIT_ASSERT_MESSAGE("Failed to reload cache.", !nErr);
-    CPPUNIT_ASSERT_MESSAGE("There should only be one pivot table linked to this cache.",
-                           aRefs.size() == 1 && *aRefs.begin() == pDPObj);
-
-    pDPObj->ClearTableData();
-    aOutRange = refresh(pDPObj);
-
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "B", "3" },
-            { "C", "3" },
-            { "D", "4" },
-            { "Total Result", "10" },
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Ignore empty rows");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
-                           pDPs->GetSheetCaches().size(), static_cast<size_t>(0));
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testPivotTableTextNumber()
-{
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Raw data
-    const char* aData[][2] = {
-        { "Name", "Value" },
-        { "0001", "1" },
-        { "0002", "2" },
-        { "0003", "3" },
-        { "0004", "4" },
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name", sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-    };
-
-    // Insert raw data such that the first column values are entered as text.
-    size_t nRowCount = SAL_N_ELEMENTS(aData);
-    for (size_t nRow = 0; nRow < nRowCount; ++nRow)
-    {
-        ScSetStringParam aParam;
-        aParam.mbDetectNumberFormat = false;
-        aParam.meSetTextNumFormat = ScSetStringParam::Always;
-        m_pDoc->SetString(0, nRow, 0, OUString::createFromAscii(aData[nRow][0]), &aParam);
-        aParam.meSetTextNumFormat = ScSetStringParam::Never;
-        m_pDoc->SetString(1, nRow, 0, OUString::createFromAscii(aData[nRow][1]), &aParam);
-
-        if (nRow == 0)
-            // Don't check the header row.
-            continue;
-
-        // Check the data rows.
-        CPPUNIT_ASSERT_MESSAGE("This cell is supposed to be text.", m_pDoc->HasStringData(0, nRow, 0));
-        CPPUNIT_ASSERT_MESSAGE("This cell is supposed to be numeric.", m_pDoc->HasValueData(1, nRow, 0));
-    }
-
-    ScRange aDataRange(0, 0, 0, 1, 4, 0);
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "0001", "1" },
-            { "0002", "2" },
-            { "0003", "3" },
-            { "0004", "4" },
-            { "Total Result", "10" },
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Text number field members");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
-                                 pDPs->GetSheetCaches().size(), static_cast<size_t>(0));
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
+        CPPUNIT_ASSERT_MESSAGE ("CSV numeric detection failure", bResult == aTests[i].bResult);
+        CPPUNIT_ASSERT_MESSAGE ("CSV numeric value failure", nValue == aTests[i].nValue);
+    }
 }
 
-void Test::testPivotTableCaseInsensitiveStrings()
+template<typename Evaluator>
+void checkMatrixElements(const ScMatrix& rMat)
 {
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Raw data
-    const char* aData[][2] = {
-        { "Name", "Value" },
-        { "A", "1" },
-        { "a", "2" },
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name", sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-    };
-
-    ScAddress aPos(1,1,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
-    CPPUNIT_ASSERT_MESSAGE("failed to insert range data at correct position", aDataRange.aStart == aPos);
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-
+    SCSIZE nC, nR;
+    rMat.GetDimensions(nC, nR);
+    Evaluator aEval;
+    for (SCSIZE i = 0; i < nC; ++i)
     {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", "3" },
-            { "Total Result", "3" },
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Case insensitive strings");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
+        for (SCSIZE j = 0; j < nR; ++j)
+        {
+            aEval(i, j, rMat.Get(i, j));
+        }
     }
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
-                           pDPs->GetSheetCaches().size(), static_cast<size_t>(0));
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
 }
 
-void Test::testPivotTableNumStability()
+struct AllZeroMatrix
 {
-    FormulaGrammarSwitch aFGSwitch(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1);
-
-    // Raw Data
-    const char* aData[][4] = {
-        { "Name",   "Time Start", "Time End", "Total"          },
-        { "Sam",    "07:48 AM",   "09:00 AM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "09:00 AM",   "10:30 AM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "10:30 AM",   "12:30 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "12:30 PM",   "01:00 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "01:00 PM",   "01:30 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "01:30 PM",   "02:00 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "02:00 PM",   "07:15 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "07:47 AM",   "09:00 AM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "09:00 AM",   "10:00 AM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "10:00 AM",   "11:00 AM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "11:00 AM",   "11:30 AM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "11:30 AM",   "12:45 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "12:45 PM",   "01:15 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "01:15 PM",   "02:30 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "02:30 PM",   "02:45 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "02:45 PM",   "04:30 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "04:30 PM",   "06:00 PM", "=RC[-1]-RC[-2]" },
-        { "Sam",    "06:00 PM",   "07:15 PM", "=RC[-1]-RC[-2]" },
-        { "Mike",   "06:15 AM",   "08:30 AM", "=RC[-1]-RC[-2]" },
-        { "Mike",   "08:30 AM",   "10:03 AM", "=RC[-1]-RC[-2]" },
-        { "Mike",   "10:03 AM",   "12:00 PM", "=RC[-1]-RC[-2]" },
-        { "Dennis", "11:00 AM",   "01:00 PM", "=RC[-1]-RC[-2]" },
-        { "Dennis", "01:00 PM",   "02:00 PM", "=RC[-1]-RC[-2]" }
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name",  sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Total", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-    };
-
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    size_t nRowCount = SAL_N_ELEMENTS(aData);
-    ScAddress aPos(1,1,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, nRowCount);
-
-    // Insert formulas to manually calculate sums for each name.
-    m_pDoc->SetString(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+1, aDataRange.aStart.Tab(), "=SUMIF(R[-23]C:R[-1]C;\"Dennis\";R[-23]C[3]:R[-1]C[3])");
-    m_pDoc->SetString(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+2, aDataRange.aStart.Tab(), "=SUMIF(R[-24]C:R[-2]C;\"Mike\";R[-24]C[3]:R[-2]C[3])");
-    m_pDoc->SetString(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+3, aDataRange.aStart.Tab(), "=SUMIF(R[-25]C:R[-3]C;\"Sam\";R[-25]C[3]:R[-3]C[3])");
-
-    m_pDoc->CalcAll();
-
-    // Get correct sum values.
-    double fDennisTotal = m_pDoc->GetValue(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+1, aDataRange.aStart.Tab());
-    double fMikeTotal = m_pDoc->GetValue(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+2, aDataRange.aStart.Tab());
-    double fSamTotal = m_pDoc->GetValue(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+3, aDataRange.aStart.Tab());
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount(), static_cast<size_t>(1));
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-
-    // Manually check the total value for each name.
-    //
-    // +--------------+----------------+
-    // | Name         |                |
-    // +--------------+----------------+
-    // | Dennis       | <Dennis total> |
-    // +--------------+----------------+
-    // | Mike         | <Miks total>   |
-    // +--------------+----------------+
-    // | Sam          | <Sam total>    |
-    // +--------------+----------------+
-    // | Total Result | ...            |
-    // +--------------+----------------+
-
-    aPos = aOutRange.aStart;
-    aPos.IncCol();
-    aPos.IncRow();
-    double fTest = m_pDoc->GetValue(aPos);
-    CPPUNIT_ASSERT_MESSAGE("Incorrect value for Dennis.", rtl::math::approxEqual(fTest, fDennisTotal));
-    aPos.IncRow();
-    fTest = m_pDoc->GetValue(aPos);
-    CPPUNIT_ASSERT_MESSAGE("Incorrect value for Mike.", rtl::math::approxEqual(fTest, fMikeTotal));
-    aPos.IncRow();
-    fTest = m_pDoc->GetValue(aPos);
-    CPPUNIT_ASSERT_MESSAGE("Incorrect value for Sam.", rtl::math::approxEqual(fTest, fSamTotal));
-
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
-                           pDPs->GetSheetCaches().size(), static_cast<size_t>(0));
-
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
-}
+    void operator() (SCSIZE /*nCol*/, SCSIZE /*nRow*/, const ScMatrixValue& rVal) const
+    {
+        CPPUNIT_ASSERT_MESSAGE("element is not of numeric type", rVal.nType == SC_MATVAL_VALUE);
+        CPPUNIT_ASSERT_MESSAGE("element value must be zero", rVal.fVal == 0.0);
+    }
+};
 
-void Test::testPivotTableFieldReference()
+struct PartiallyFilledZeroMatrix
 {
-    m_pDoc->InsertTab(0, OUString("Data"));
-    m_pDoc->InsertTab(1, OUString("Table"));
-
-    // Raw data
-    const char* aData[][2] = {
-        { "Name", "Value" },
-        { "A", "1" },
-        { "B", "2" },
-        { "C", "4" },
-        { "D", "8" },
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name", sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-    };
-
-    ScAddress aPos(1,1,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
-    CPPUNIT_ASSERT_MESSAGE("failed to insert range data at correct position", aDataRange.aStart == aPos);
-
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    bool bSuccess = pDPs->InsertNewTable(pDPObj);
-
-    CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess);
-    CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.",
-                           pDPs->GetCount() == 1);
-    pDPObj->SetName(pDPs->CreateNewName());
-
-    ScRange aOutRange = refresh(pDPObj);
-
+    void operator() (SCSIZE nCol, SCSIZE nRow, const ScMatrixValue& rVal) const
     {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", "1" },
-            { "B", "2" },
-            { "C", "4" },
-            { "D", "8" },
-            { "Total Result", "15" },
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Field reference (none)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
+        CPPUNIT_ASSERT_MESSAGE("element is not of numeric type", rVal.nType == SC_MATVAL_VALUE);
+        if (1 <= nCol && nCol <= 2 && 2 <= nRow && nRow <= 8)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element value must be 3.0", rVal.fVal == 3.0);
+        }
+        else
+        {
+            CPPUNIT_ASSERT_MESSAGE("element value must be zero", rVal.fVal == 0.0);
+        }
     }
+};
 
-    ScDPSaveData aSaveData = *pDPObj->GetSaveData();
-    sheet::DataPilotFieldReference aFieldRef;
-    aFieldRef.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE;
-    aFieldRef.ReferenceField = "Name";
-    aFieldRef.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::NAMED;
-    aFieldRef.ReferenceItemName = "A";
-    ScDPSaveDimension* pDim = aSaveData.GetDimensionByName("Value");
-    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve dimension 'Value'.", pDim);
-    pDim->SetReferenceValue(&aFieldRef);
-    pDPObj->SetSaveData(aSaveData);
-
-    aOutRange = refresh(pDPObj);
+struct AllEmptyMatrix
+{
+    void operator() (SCSIZE /*nCol*/, SCSIZE /*nRow*/, const ScMatrixValue& rVal) const
     {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", 0 },
-            { "B", "1" },
-            { "C", "3" },
-            { "D", "7" },
-            { "Total Result", 0 },
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Field reference (difference from)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
+        CPPUNIT_ASSERT_MESSAGE("element is not of empty type", rVal.nType == SC_MATVAL_EMPTY);
+        CPPUNIT_ASSERT_MESSAGE("value of \"empty\" element is expected to be zero", rVal.fVal == 0.0);
     }
+};
 
-    aFieldRef.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE;
-    pDim->SetReferenceValue(&aFieldRef);
-    pDPObj->SetSaveData(aSaveData);
-
-    aOutRange = refresh(pDPObj);
+struct PartiallyFilledEmptyMatrix
+{
+    void operator() (SCSIZE nCol, SCSIZE nRow, const ScMatrixValue& rVal) const
     {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", "100.00%" },
-            { "B", "200.00%" },
-            { "C", "400.00%" },
-            { "D", "800.00%" },
-            { "Total Result", 0 },
-        };
-
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Field reference (% of)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
+        if (nCol == 1 && nRow == 1)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of boolean type", rVal.nType == SC_MATVAL_BOOLEAN);
+            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.fVal == 1.0);
+        }
+        else if (nCol == 4 && nRow == 5)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of value type", rVal.nType == SC_MATVAL_VALUE);
+            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.fVal == -12.5);
+        }
+        else if (nCol == 8 && nRow == 2)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of value type", rVal.nType == SC_MATVAL_STRING);
+            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.aStr == "Test");
+        }
+        else if (nCol == 8 && nRow == 11)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of empty path type", rVal.nType == SC_MATVAL_EMPTYPATH);
+            CPPUNIT_ASSERT_MESSAGE("value of \"empty\" element is expected to be zero", rVal.fVal == 0.0);
+        }
+        else
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of empty type", rVal.nType == SC_MATVAL_EMPTY);
+            CPPUNIT_ASSERT_MESSAGE("value of \"empty\" element is expected to be zero", rVal.fVal == 0.0);
+        }
     }
+};
 
-    aFieldRef.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE;
-    pDim->SetReferenceValue(&aFieldRef);
-    pDPObj->SetSaveData(aSaveData);
+void Test::testMatrix()
+{
+    ScMatrixRef pMat;
 
-    aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", 0 },
-            { "B", "100.00%" },
-            { "C", "300.00%" },
-            { "D", "700.00%" },
-            { "Total Result", 0 },
-        };
+    // First, test the zero matrix type.
+    pMat = new ScMatrix(0, 0, 0.0);
+    SCSIZE nC, nR;
+    pMat->GetDimensions(nC, nR);
+    CPPUNIT_ASSERT_MESSAGE("matrix is not empty", nC == 0 && nR == 0);
+    pMat->Resize(4, 10, 0.0);
+    pMat->GetDimensions(nC, nR);
+    CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 4 && nR == 10);
+    CPPUNIT_ASSERT_MESSAGE("both 'and' and 'or' should evaluate to false",
+                           !pMat->And() && !pMat->Or());
 
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Field reference (% difference from)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
+    // Resizing into a larger matrix should fill the void space with zeros.
+    checkMatrixElements<AllZeroMatrix>(*pMat);
 
-    aFieldRef.ReferenceType = sheet::DataPilotFieldReferenceType::RUNNING_TOTAL;
-    pDim->SetReferenceValue(&aFieldRef);
-    pDPObj->SetSaveData(aSaveData);
+    pMat->FillDouble(3.0, 1, 2, 2, 8);
+    checkMatrixElements<PartiallyFilledZeroMatrix>(*pMat);
+    CPPUNIT_ASSERT_MESSAGE("matrix is expected to be numeric", pMat->IsNumeric());
+    CPPUNIT_ASSERT_MESSAGE("partially non-zero matrix should evaluate false on 'and' and true on 'or",
+                           !pMat->And() && pMat->Or());
+    pMat->FillDouble(5.0, 0, 0, nC-1, nR-1);
+    CPPUNIT_ASSERT_MESSAGE("fully non-zero matrix should evaluate true both on 'and' and 'or",
+                           pMat->And() && pMat->Or());
 
-    aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", "1" },
-            { "B", "3" },
-            { "C", "7" },
-            { "D", "15" },
-            { "Total Result", 0 },
-        };
+    // Test the AND and OR evaluations.
+    pMat = new ScMatrix(2, 2, 0.0);
 
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Field reference (Running total)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
+    // Only some of the elements are non-zero.
+    pMat->PutBoolean(true, 0, 0);
+    pMat->PutDouble(1.0, 1, 1);
+    CPPUNIT_ASSERT_MESSAGE("incorrect OR result", pMat->Or());
+    CPPUNIT_ASSERT_MESSAGE("incorrect AND result", !pMat->And());
 
-    aFieldRef.ReferenceType = sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE;
-    pDim->SetReferenceValue(&aFieldRef);
-    pDPObj->SetSaveData(aSaveData);
+    // All of the elements are non-zero.
+    pMat->PutBoolean(true, 0, 1);
+    pMat->PutDouble(2.3, 1, 0);
+    CPPUNIT_ASSERT_MESSAGE("incorrect OR result", pMat->Or());
+    CPPUNIT_ASSERT_MESSAGE("incorrect AND result", pMat->And());
 
-    aOutRange = refresh(pDPObj);
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "A", "6.67%" },
-            { "B", "13.33%" },
-            { "C", "26.67%" },
-            { "D", "53.33%" },
-            { "Total Result", "100.00%" },
-        };
+    // Now test the emtpy matrix type.
+    pMat = new ScMatrix(10, 20);
+    pMat->GetDimensions(nC, nR);
+    CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 10 && nR == 20);
+    checkMatrixElements<AllEmptyMatrix>(*pMat);
 
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Field reference (% of column)");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
+    pMat->PutBoolean(true, 1, 1);
+    pMat->PutDouble(-12.5, 4, 5);
+    OUString aStr("Test");
+    pMat->PutString(aStr, 8, 2);
+    pMat->PutEmptyPath(8, 11);
+    checkMatrixElements<PartiallyFilledEmptyMatrix>(*pMat);
 
-    pDPs->FreeTable(pDPObj);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
-                           pDPs->GetSheetCaches().size(), static_cast<size_t>(0));
+    // Test resizing.
+    pMat = new ScMatrix(0, 0);
+    pMat->Resize(2, 2, 1.5);
+    pMat->PutEmpty(1, 1);
 
-    m_pDoc->DeleteTab(1);
-    m_pDoc->DeleteTab(0);
+    CPPUNIT_ASSERT_EQUAL(1.5, pMat->GetDouble(0, 0));
+    CPPUNIT_ASSERT_EQUAL(1.5, pMat->GetDouble(0, 1));
+    CPPUNIT_ASSERT_EQUAL(1.5, pMat->GetDouble(1, 0));
+    CPPUNIT_ASSERT_MESSAGE("PutEmpty() call failed.", pMat->IsEmpty(1, 1));
+
+    // Max and min values.
+    pMat = new ScMatrix(2, 2, 0.0);
+    pMat->PutDouble(-10, 0, 0);
+    pMat->PutDouble(-12, 0, 1);
+    pMat->PutDouble(-8, 1, 0);
+    pMat->PutDouble(-25, 1, 1);
+    CPPUNIT_ASSERT_EQUAL(-25.0, pMat->GetMinValue(false));
+    CPPUNIT_ASSERT_EQUAL(-8.0, pMat->GetMaxValue(false));
+    pMat->PutString("Test", 0, 0);
+    CPPUNIT_ASSERT_EQUAL(0.0, pMat->GetMaxValue(true)); // text as zero.
+    CPPUNIT_ASSERT_EQUAL(-8.0, pMat->GetMaxValue(false)); // ignore text.
+    pMat->PutBoolean(true, 0, 0);
+    CPPUNIT_ASSERT_EQUAL(1.0, pMat->GetMaxValue(false));
+    pMat = new ScMatrix(2, 2, 10.0);
+    pMat->PutBoolean(false, 0, 0);
+    pMat->PutDouble(12.5, 1, 1);
+    CPPUNIT_ASSERT_EQUAL(0.0, pMat->GetMinValue(false));
+    CPPUNIT_ASSERT_EQUAL(12.5, pMat->GetMaxValue(false));
 }
 
-void Test::testPivotTableDocFunc()
+void Test::testEnterMixedMatrix()
 {
-    m_pDoc->InsertTab(0, "Data");
-    m_pDoc->InsertTab(1, "Table");
-
-    // Raw data
-    const char* aData[][2] = {
-        { "Name",      "Value" },
-        { "Sun",       "1" },
-        { "Oracle",    "2" },
-        { "Red Hat",   "4" },
-        { "SUSE",      "8" },
-        { "Apple",     "16" },
-        { "Microsoft", "32" },
-    };
-
-    // Dimension definition
-    DPFieldDef aFields[] = {
-        { "Name", sheet::DataPilotFieldOrientation_ROW, 0 },
-        { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM },
-    };
-
-    ScAddress aPos(1,1,0);
-    ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
-    CPPUNIT_ASSERT_MESSAGE("failed to insert range data at correct position", aDataRange.aStart == aPos);
+    m_pDoc->InsertTab(0, "foo");
 
-    ScDPObject* pDPObj = createDPFromRange(
-        m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false);
-
-    CPPUNIT_ASSERT_MESSAGE("Failed to create pivot table object.", pDPObj);
-
-    // Craete a new pivot table output.
-    ScDBDocFunc aFunc(getDocShell());
-    bool bSuccess = aFunc.CreatePivotTable(*pDPObj, false, true);
-    CPPUNIT_ASSERT_MESSAGE("Failed to create pivot table output via ScDBDocFunc.", bSuccess);
-    ScDPCollection* pDPs = m_pDoc->GetDPCollection();
-    CPPUNIT_ASSERT_MESSAGE("Failed to get pivot table collection.", pDPs);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
-    pDPObj = (*pDPs)[0];
-    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve pivot table object from the collection", pDPObj);
-    ScRange aOutRange = pDPObj->GetOutRange();
-    {
-        // Expected output table content.  0 = empty cell
-        const char* aOutputCheck[][2] = {
-            { "Name", 0 },
-            { "Apple", "16" },
-            { "Microsoft", "32" },
-            { "Oracle", "2" },
-            { "Red Hat", "4" },
-            { "Sun", "1" },
-            { "SUSE", "8" },
-            { "Total Result", "63" },
-        };
+    // Insert the source values in A1:B2.
+    m_pDoc->SetString(0, 0, 0, "A");
+    m_pDoc->SetString(1, 0, 0, "B");
+    double val = 1.0;
+    m_pDoc->SetValue(0, 1, 0, val);
+    val = 2.0;
+    m_pDoc->SetValue(1, 1, 0, val);
 
-        bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Pivot table created via ScDBDocFunc");
-        CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
-    }
+    // Create a matrix range in A4:B5 referencing A1:B2.
+    ScMarkData aMark;
+    aMark.SelectOneTable(0);
+    m_pDoc->InsertMatrixFormula(0, 3, 1, 4, aMark, "=A1:B2", NULL);
 
-    // Remove this pivot table output. This should also clear the pivot cache
-    // it was referencing.
-    bSuccess = aFunc.RemovePivotTable(*pDPObj, false, true);
-    CPPUNIT_ASSERT_MESSAGE("Failed to remove pivot table output via ScDBDocFunc.", bSuccess);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pDPs->GetCount());
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pDPs->GetSheetCaches().size());
+    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(0,0,0), m_pDoc->GetString(0,3,0));
+    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(1,0,0), m_pDoc->GetString(1,3,0));

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list