[Libreoffice-commits] core.git: sc/CppunitTest_sc_pivottable_filters_test.mk sc/Module_sc.mk sc/qa
Tamás Zolnai
tamas.zolnai at collabora.com
Mon Nov 13 13:33:06 UTC 2017
sc/CppunitTest_sc_pivottable_filters_test.mk | 120 +
sc/Module_sc.mk | 1
sc/qa/unit/pivottable_filters_test.cxx | 2167 +++++++++++++++++++++++++++
sc/qa/unit/subsequent_export-test.cxx | 1491 ------------------
sc/qa/unit/subsequent_filters-test.cxx | 574 -------
5 files changed, 2288 insertions(+), 2065 deletions(-)
New commits:
commit 610d909dac1c68286dc12ed5dc1206affefe6774
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date: Mon Nov 13 12:19:46 2017 +0100
Move pivot table tests to a separate test suit
Change-Id: Ic0797a988b7135927a53ca9f16c8bc30d24feef5
Reviewed-on: https://gerrit.libreoffice.org/44673
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
diff --git a/sc/CppunitTest_sc_pivottable_filters_test.mk b/sc/CppunitTest_sc_pivottable_filters_test.mk
new file mode 100755
index 000000000000..139ed85f3b24
--- /dev/null
+++ b/sc/CppunitTest_sc_pivottable_filters_test.mk
@@ -0,0 +1,120 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,sc_pivottable_filters_test))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sc_pivottable_filters_test, \
+ sc/qa/unit/pivottable_filters_test \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,sc_pivottable_filters_test, \
+ boost_headers \
+ mdds_headers \
+ libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sc_pivottable_filters_test, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ editeng \
+ for \
+ forui \
+ i18nlangtag \
+ msfilter \
+ oox \
+ sal \
+ salhelper \
+ sax \
+ sc \
+ scqahelper \
+ sfx \
+ sot \
+ svl \
+ svt \
+ svx \
+ svxcore \
+ test \
+ tk \
+ tl \
+ ucbhelper \
+ unotest \
+ utl \
+ vcl \
+ xo \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sc_pivottable_filters_test,\
+ -I$(SRCDIR)/sc/source/ui/inc \
+ -I$(SRCDIR)/sc/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,sc_pivottable_filters_test))
+
+$(eval $(call gb_CppunitTest_use_ure,sc_pivottable_filters_test))
+$(eval $(call gb_CppunitTest_use_vcl,sc_pivottable_filters_test))
+
+$(eval $(call gb_CppunitTest_use_components,sc_pivottable_filters_test,\
+ chart2/source/chartcore \
+ chart2/source/controller/chartcontroller \
+ comphelper/util/comphelp \
+ configmgr/source/configmgr \
+ dbaccess/util/dba \
+ embeddedobj/util/embobj \
+ eventattacher/source/evtatt \
+ filter/source/config/cache/filterconfig1 \
+ forms/util/frm \
+ framework/util/fwk \
+ i18npool/source/search/i18nsearch \
+ i18npool/util/i18npool \
+ linguistic/source/lng \
+ oox/util/oox \
+ package/source/xstor/xstor \
+ package/util/package2 \
+ sax/source/expatwrap/expwrap \
+ scaddins/source/analysis/analysis \
+ scaddins/source/datefunc/date \
+ sc/util/sc \
+ sc/util/scfilt \
+ sfx2/util/sfx \
+ sot/util/sot \
+ svl/util/svl \
+ svtools/util/svt \
+ toolkit/util/tk \
+ ucb/source/core/ucb1 \
+ ucb/source/ucp/file/ucpfile1 \
+ ucb/source/ucp/tdoc/ucptdoc1 \
+ unotools/util/utl \
+ unoxml/source/rdf/unordf \
+ unoxml/source/service/unoxml \
+ uui/util/uui \
+ xmloff/util/xo \
+ xmlsecurity/util/xmlsecurity \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_CppunitTest_use_components,sc_pivottable_filters_test,\
+ xmlsecurity/util/xsec_xmlsec.windows \
+))
+else
+$(eval $(call gb_CppunitTest_use_components,sc_pivottable_filters_test,\
+ xmlsecurity/util/xsec_xmlsec \
+))
+endif
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sc_pivottable_filters_test,\
+ officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sc_pivottable_filters_test))
+
+# vim: set noet sw=4 ts=4:
\ No newline at end of file
diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk
index c55aeeb46a24..732717d5db5e 100644
--- a/sc/Module_sc.mk
+++ b/sc/Module_sc.mk
@@ -62,6 +62,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sc, \
CppunitTest_sc_subsequent_export_test \
CppunitTest_sc_html_export_test \
CppunitTest_sc_copypaste \
+ CppunitTest_sc_pivottable_filters_test \
))
# Various function tests fail in 32-bit linux_x86 build due to dreaded floating
diff --git a/sc/qa/unit/pivottable_filters_test.cxx b/sc/qa/unit/pivottable_filters_test.cxx
new file mode 100755
index 000000000000..167b68f0d773
--- /dev/null
+++ b/sc/qa/unit/pivottable_filters_test.cxx
@@ -0,0 +1,2167 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+#include <osl/file.hxx>
+#include <config_features.h>
+
+#include "helper/qahelper.hxx"
+#include "helper/xpath.hxx"
+#include "helper/shared_test_impl.hxx"
+
+#include <patattr.hxx>
+#include <docpool.hxx>
+#include <scitems.hxx>
+#include <document.hxx>
+#include <generalfunction.hxx>
+#include <dpcache.hxx>
+#include <dpobject.hxx>
+#include <dpsave.hxx>
+#include <dputil.hxx>
+#include <attrib.hxx>
+#include <dpshttab.hxx>
+#include <globstr.hrc>
+
+#include <test/xmltesttools.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+class ScPivotTableFiltersTest : public ScBootstrapFixture, public XmlTestTools
+{
+protected:
+ virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) override;
+public:
+ ScPivotTableFiltersTest();
+
+ virtual void setUp() override;
+ virtual void tearDown() override;
+
+ // Import
+ void testPivotTableBasicODS();
+ void testPivotTableNamedRangeSourceODS();
+ void testPivotTableSharedCacheGroupODS();
+ void testGetPivotDataXLS();
+ void testPivotTableSharedGroupXLSX();
+ void testPivotTableSharedDateGroupXLSX();
+ void testPivotTableSharedNestedDateGroupXLSX();
+ void testPivotTableSharedNumGroupXLSX();
+ void testPivotTableNoColumnsLayout();
+ void testTdf112501();
+
+ // Export
+ void testPivotTableExportXLSX();
+ void testPivotCacheExportXLSX();
+ void testPivotTableXLSX();
+ void testPivotTableTwoDataFieldsXLSX();
+ void testPivotTableMedianODS();
+ void testPivotTableRowHeaderXLS();
+ void testPivotTableDoubleFieldFilter();
+ void testPivotTableStringFieldFilter();
+ void testPivotTableDateFieldFilter();
+ void testPivotTableBoolFieldFilter();
+ void testPivotTableRowColPageFieldFilter();
+ void testPivotTableEmptyItem();
+ void testPivotTablePageFieldFilter();
+ void testPivotTableFirstHeaderRowXLSX();
+ void testPivotTableDoubleFieldFilterXLSX();
+ void testPivotTableStringFieldFilterXLSX();
+ void testPivotTableDateFieldFilterXLSX();
+ void testPivotTableBoolFieldFilterXLSX();
+ void testPivotTableRowColPageFieldFilterXLSX();
+ void testPivotTableErrorItemFilterXLSX();
+ void testPivotTableOutlineModeXLSX();
+ void testPivotTableDuplicatedMemberFilterXLSX();
+ void testPivotTableTabularModeXLSX();
+ void testTdf112106();
+
+ CPPUNIT_TEST_SUITE(ScPivotTableFiltersTest);
+
+ CPPUNIT_TEST(testPivotTableBasicODS);
+ CPPUNIT_TEST(testPivotTableNamedRangeSourceODS);
+ CPPUNIT_TEST(testPivotTableSharedCacheGroupODS);
+ CPPUNIT_TEST(testGetPivotDataXLS);
+ CPPUNIT_TEST(testPivotTableSharedGroupXLSX);
+ CPPUNIT_TEST(testPivotTableSharedDateGroupXLSX);
+ CPPUNIT_TEST(testPivotTableSharedNestedDateGroupXLSX);
+ CPPUNIT_TEST(testPivotTableSharedNumGroupXLSX);
+ CPPUNIT_TEST(testPivotTableNoColumnsLayout);
+ CPPUNIT_TEST(testTdf112501);
+
+ CPPUNIT_TEST(testPivotTableExportXLSX);
+ CPPUNIT_TEST(testPivotCacheExportXLSX);
+ CPPUNIT_TEST(testPivotTableXLSX);
+ CPPUNIT_TEST(testPivotTableTwoDataFieldsXLSX);
+ CPPUNIT_TEST(testPivotTableMedianODS);
+ CPPUNIT_TEST(testPivotTableRowHeaderXLS);
+ CPPUNIT_TEST(testPivotTableDoubleFieldFilter);
+ CPPUNIT_TEST(testPivotTableStringFieldFilter);
+ CPPUNIT_TEST(testPivotTableDateFieldFilter);
+ CPPUNIT_TEST(testPivotTableBoolFieldFilter);
+ CPPUNIT_TEST(testPivotTableRowColPageFieldFilter);
+ CPPUNIT_TEST(testPivotTableEmptyItem);
+ CPPUNIT_TEST(testPivotTablePageFieldFilter);
+ CPPUNIT_TEST(testPivotTableFirstHeaderRowXLSX);
+ CPPUNIT_TEST(testPivotTableDoubleFieldFilterXLSX);
+ CPPUNIT_TEST(testPivotTableStringFieldFilterXLSX);
+ CPPUNIT_TEST(testPivotTableDateFieldFilterXLSX);
+ CPPUNIT_TEST(testPivotTableBoolFieldFilterXLSX);
+ CPPUNIT_TEST(testPivotTableRowColPageFieldFilterXLSX);
+ CPPUNIT_TEST(testPivotTableErrorItemFilterXLSX);
+ CPPUNIT_TEST(testPivotTableOutlineModeXLSX);
+ CPPUNIT_TEST(testPivotTableDuplicatedMemberFilterXLSX);
+ CPPUNIT_TEST(testPivotTableTabularModeXLSX);
+ CPPUNIT_TEST(testTdf112106);
+
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ uno::Reference<uno::XInterface> m_xCalcComponent;
+};
+
+
+ScPivotTableFiltersTest::ScPivotTableFiltersTest()
+ : ScBootstrapFixture("sc/qa/unit/data")
+{
+}
+
+void ScPivotTableFiltersTest::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
+ // which is a private symbol to us, gets called
+ m_xCalcComponent =
+ getMultiServiceFactory()->createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
+ CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
+}
+
+void ScPivotTableFiltersTest::tearDown()
+{
+ uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
+ test::BootstrapFixture::tearDown();
+}
+
+void ScPivotTableFiltersTest::registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx)
+{
+ struct { xmlChar* pPrefix; xmlChar* pURI; } aNamespaces[] =
+ {
+ { BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main") },
+ { BAD_CAST("x"), BAD_CAST("http://schemas.openxmlformats.org/spreadsheetml/2006/main") },
+ { BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml") },
+ { BAD_CAST("c"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart") },
+ { BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main") },
+ { BAD_CAST("mc"), BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006") },
+ { BAD_CAST("wps"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape") },
+ { BAD_CAST("wpg"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup") },
+ { BAD_CAST("wp"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing") },
+ { BAD_CAST("office"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0") },
+ { BAD_CAST("table"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:table:1.0") },
+ { BAD_CAST("text"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:text:1.0") },
+ { BAD_CAST("style"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:style:1.0") },
+ { BAD_CAST("draw"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:drawing:1.0") },
+ { BAD_CAST("xlink"), BAD_CAST("http://www.w3c.org/1999/xlink") },
+ { BAD_CAST("xdr"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing") },
+ { BAD_CAST("x"), BAD_CAST("http://schemas.openxmlformats.org/spreadsheetml/2006/main") },
+ { BAD_CAST("r"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/relationships") },
+ { BAD_CAST("number"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0") }
+ };
+ for(size_t i = 0; i < SAL_N_ELEMENTS(aNamespaces); ++i)
+ {
+ xmlXPathRegisterNs(pXmlXPathCtx, aNamespaces[i].pPrefix, aNamespaces[i].pURI );
+ }
+}
+
+namespace {
+
+class FindDimByName
+{
+ OUString maName;
+public:
+ explicit FindDimByName(const OUString& rName) : maName(rName) {}
+
+ bool operator() (const ScDPSaveDimension* p) const
+ {
+ return p && p->GetName() == maName;
+ }
+};
+
+bool hasDimension(const std::vector<const ScDPSaveDimension*>& rDims, const OUString& aName)
+{
+ return std::any_of(rDims.begin(), rDims.end(), FindDimByName(aName));
+}
+
+}
+
+void ScPivotTableFiltersTest::testPivotTableBasicODS()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table-basic.", FORMAT_ODS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load pivot-table-basic.ods", xDocSh.is());
+
+ ScDocument& rDoc = xDocSh->GetDocument();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "There should be exactly two sheets.", sal_Int16(2),
+ rDoc.GetTableCount());
+
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_MESSAGE("Failed to get a live ScDPCollection instance.", pDPs);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "There should be exactly one pivot table instance.", size_t(1),
+ pDPs->GetCount());
+
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
+ const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT_MESSAGE("Failed to get ScDPSaveData instance.", pSaveData);
+ std::vector<const ScDPSaveDimension*> aDims;
+
+ // Row fields
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aDims);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ ("There should be exactly 3 row fields (2 normal dimensions and 1"
+ " layout dimension)."),
+ std::vector<ScDPSaveDimension const *>::size_type(3), aDims.size());
+ CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Row1"));
+ CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Row2"));
+ const ScDPSaveDimension* pDataLayout = pSaveData->GetExistingDataLayoutDimension();
+ CPPUNIT_ASSERT_MESSAGE("There should be a data layout field as a row field.",
+ pDataLayout && pDataLayout->GetOrientation() == sheet::DataPilotFieldOrientation_ROW);
+
+ // Column fields
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aDims);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "There should be exactly 2 column fields.",
+ std::vector<ScDPSaveDimension const *>::size_type(2), aDims.size());
+ CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Col1"));
+ CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Col2"));
+
+ // Page fields
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_PAGE, aDims);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "There should be exactly 2 page fields.",
+ std::vector<ScDPSaveDimension const *>::size_type(2), aDims.size());
+ CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Page1"));
+ CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Page2"));
+
+ // Check the data field.
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA, aDims);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "There should be exactly 1 data field.",
+ std::vector<ScDPSaveDimension const *>::size_type(1), aDims.size());
+ const ScDPSaveDimension* pDim = aDims.back();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Function for the data field should be COUNT.",
+ sal_uInt16(ScGeneralFunction::COUNT), sal_uInt16(pDim->GetFunction()));
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableNamedRangeSourceODS()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table-named-range-source.", FORMAT_ODS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load pivot-table-named-range-source.ods", xDocSh.is());
+
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDPs->GetCount());
+
+ ScDPObject* pDP = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDP);
+
+ // Make sure this pivot table is based on a named range source.
+ const ScSheetSourceDesc* pDesc = pDP->GetSheetDesc();
+ CPPUNIT_ASSERT(pDesc);
+ CPPUNIT_ASSERT_EQUAL(OUString("MyRange"), pDesc->GetRangeName());
+
+ css::sheet::DataPilotFieldOrientation nOrient;
+ long nDim = pDP->GetHeaderDim(ScAddress(0,1,1), nOrient);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to detect header dimension.", long(0), nDim);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("This dimension should be a page dimension.",
+ sheet::DataPilotFieldOrientation_PAGE, nOrient);
+
+ xDocSh->DoClose();
+}
+
+namespace {
+
+bool checkVisiblePageFieldMember( const ScDPSaveDimension::MemberList& rMembers, const OUString& rVisibleMember )
+{
+ ScDPSaveDimension::MemberList::const_iterator it = rMembers.begin(), itEnd = rMembers.end();
+ bool bFound = false;
+ for (; it != itEnd; ++it)
+ {
+ const ScDPSaveMember* pMem = *it;
+ if (pMem->GetName() == rVisibleMember)
+ {
+ bFound = true;
+ if (!pMem->GetIsVisible())
+ // This member is supposed to be visible. Fail.
+ return false;
+ }
+ else
+ {
+ if (pMem->GetIsVisible())
+ // This member is supposed to be hidden. Not good.
+ return false;
+ }
+ }
+
+ return bFound;
+}
+
+}
+
+void ScPivotTableFiltersTest::testPivotTableSharedCacheGroupODS()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table-shared-cache-with-group.", FORMAT_ODS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // Make sure that page field's visibility settings are loaded correctly.
+
+ ScDPObject* pDPObj = rDoc.GetDPAtCursor(0, 0, 1); // A1 on 2nd sheet
+ CPPUNIT_ASSERT_MESSAGE("There should be a pivot table here.", pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT_MESSAGE("Save data is expected.", pSaveData);
+ ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName("Project Name");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get page field named 'Project Name'.", pDim);
+ const ScDPSaveDimension::MemberList* pMembers = &pDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(14), pMembers->size());
+ CPPUNIT_ASSERT_MESSAGE("Incorrect member visibility.", checkVisiblePageFieldMember(*pMembers, "APL-01-1"));
+
+ pDPObj = rDoc.GetDPAtCursor(0, 1, 2); // A2 on 3rd sheet
+ CPPUNIT_ASSERT_MESSAGE("There should be a pivot table here.", pDPObj);
+ pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT_MESSAGE("Save data is expected.", pSaveData);
+ pDim = pSaveData->GetExistingDimensionByName("Project Name");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get page field named 'Project Name'.", pDim);
+ pMembers = &pDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(14), pMembers->size());
+ CPPUNIT_ASSERT_MESSAGE("Incorrect member visibility.", checkVisiblePageFieldMember(*pMembers, "VEN-01-1"));
+
+ // These two pivot tables share the same data range. We should only have
+ // one pivot cache.
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ ScDPCollection::SheetCaches& rSheetCaches = pDPs->GetSheetCaches();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
+
+ // Make sure that the cache contains all group field data upon load.
+ const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
+ CPPUNIT_ASSERT_MESSAGE("Failed to get the pivot source description instance.", pDesc);
+ const ScDPCache* pCache = rSheetCaches.getExistingCache(pDesc->GetSourceRange());
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache should exist for this range.", pCache);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(9), pCache->GetFieldCount());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pCache->GetGroupFieldCount());
+
+ SCCOL nDim = pCache->GetDimensionIndex("StartDate");
+ CPPUNIT_ASSERT_MESSAGE("Dimension 'StartDate' doesn't exist in the cache.", nDim >= 0);
+ sal_Int32 nGrpType = pCache->GetGroupType(nDim);
+ CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldGroupBy::DAYS, nGrpType);
+ const ScDPNumGroupInfo* pInfo = pCache->GetNumGroupInfo(nDim);
+ CPPUNIT_ASSERT_MESSAGE("Number group info doesn't exist in cache for 'StartDate'.", pInfo);
+
+ // We should have two additional group fields and one should be years and
+ // the other should be month. The order is not guaranteed.
+
+ bool bHasYears = false;
+ bool bHasMonths = false;
+ std::vector<SCROW> aMemberIds;
+
+ for (long nGrpDim = 9; nGrpDim <= 10; ++nGrpDim)
+ {
+ nGrpType = pCache->GetGroupType(nGrpDim);
+ switch (nGrpType)
+ {
+ case sheet::DataPilotFieldGroupBy::MONTHS:
+ {
+ bHasMonths = true;
+ aMemberIds.clear();
+ pCache->GetGroupDimMemberIds(nGrpDim, aMemberIds);
+
+ // There should be a total of 14 items for the month group: 12
+ // months plus the start and end value items.
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(14), aMemberIds.size());
+
+ std::vector<sal_Int32> aGrpValues;
+ for (size_t i = 0, n = aMemberIds.size(); i < n; ++i)
+ {
+ const ScDPItemData* pItem = pCache->GetItemDataById(nGrpDim, aMemberIds[i]);
+ CPPUNIT_ASSERT_MESSAGE("Failed to get pivot item.", pItem);
+ CPPUNIT_ASSERT_EQUAL(ScDPItemData::GroupValue, pItem->GetType());
+ ScDPItemData::GroupValueAttr aGrpVal = pItem->GetGroupValue();
+ CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldGroupBy::MONTHS, aGrpVal.mnGroupType);
+ aGrpValues.push_back(aGrpVal.mnValue);
+ }
+
+ std::sort(aGrpValues.begin(), aGrpValues.end());
+ std::vector<sal_Int32> aChecks;
+ aChecks.push_back(ScDPItemData::DateFirst);
+ for (sal_Int32 i = 1; i <= 12; ++i)
+ aChecks.push_back(i); // January through December.
+ aChecks.push_back(ScDPItemData::DateLast);
+ CPPUNIT_ASSERT_MESSAGE("Unexpected group values for the month group.", bool(aGrpValues == aChecks));
+ }
+ break;
+ case sheet::DataPilotFieldGroupBy::YEARS:
+ {
+ bHasYears = true;
+ aMemberIds.clear();
+ pCache->GetGroupDimMemberIds(nGrpDim, aMemberIds);
+
+ // There should be a total of 4 items and they should be 2012,
+ // 2013 and the start and end value items.
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), aMemberIds.size());
+
+ std::vector<sal_Int32> aGrpValues;
+ for (size_t i = 0, n = aMemberIds.size(); i < n; ++i)
+ {
+ const ScDPItemData* pItem = pCache->GetItemDataById(nGrpDim, aMemberIds[i]);
+ CPPUNIT_ASSERT_MESSAGE("Failed to get pivot item.", pItem);
+ CPPUNIT_ASSERT_EQUAL(ScDPItemData::GroupValue, pItem->GetType());
+ ScDPItemData::GroupValueAttr aGrpVal = pItem->GetGroupValue();
+ CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldGroupBy::YEARS, aGrpVal.mnGroupType);
+ aGrpValues.push_back(aGrpVal.mnValue);
+ }
+
+ std::sort(aGrpValues.begin(), aGrpValues.end());
+ std::vector<sal_Int32> aChecks;
+ aChecks.push_back(ScDPItemData::DateFirst);
+ aChecks.push_back(2012);
+ aChecks.push_back(2013);
+ aChecks.push_back(ScDPItemData::DateLast);
+ CPPUNIT_ASSERT_MESSAGE("Unexpected group values for the year group.", bool(aGrpValues == aChecks));
+ }
+ break;
+ default:
+ ;
+ }
+ }
+
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache doesn't have an additional year group.", bHasYears);
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache doesn't have an additional month group.", bHasMonths);
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testGetPivotDataXLS()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-getpivotdata.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ rDoc.CalcAll();
+
+ // Check GETPIVOTDATA results in E3:E20. Expected results are given in
+ // F3:F20.
+
+ for (SCROW nRow = 2; nRow <= 19; ++nRow)
+ CPPUNIT_ASSERT_EQUAL(rDoc.GetValue(ScAddress(4,nRow,1)), rDoc.GetValue(ScAddress(5,nRow,1)));
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableSharedGroupXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table/shared-group-field.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // Check whether right group names are imported for both tables
+ // First table
+ CPPUNIT_ASSERT_EQUAL(OUString("a2"), rDoc.GetString(ScAddress(0,1,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport1"), rDoc.GetString(ScAddress(0,2,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport2"), rDoc.GetString(ScAddress(0,3,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport3"), rDoc.GetString(ScAddress(0,4,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("16"), rDoc.GetString(ScAddress(0,5,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("17"), rDoc.GetString(ScAddress(0,6,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("18"), rDoc.GetString(ScAddress(0,7,0)));
+
+ // Second table
+ CPPUNIT_ASSERT_EQUAL(OUString("a2"), rDoc.GetString(ScAddress(0,11,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport1"), rDoc.GetString(ScAddress(0,12,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport2"), rDoc.GetString(ScAddress(0,13,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport3"), rDoc.GetString(ScAddress(0,14,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("16"), rDoc.GetString(ScAddress(0,15,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("17"), rDoc.GetString(ScAddress(0,16,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("18"), rDoc.GetString(ScAddress(0,17,0)));
+
+ // There should be exactly 2 pivot tables and 1 cache.
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ ScDPCollection::SheetCaches& rSheetCaches = pDPs->GetSheetCaches();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
+
+ const ScDPCache* pCache = rSheetCaches.getExistingCache(ScRange(0,0,1,13,18,1));
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache is expected for A1:N19 on the second sheet.", pCache);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(14), pCache->GetFieldCount());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pCache->GetGroupFieldCount());
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableSharedDateGroupXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table/shared-dategroup.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // Check whether right date labels are imported for both tables
+ // First table
+ CPPUNIT_ASSERT_EQUAL(OUString("a"), rDoc.GetString(ScAddress(0,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(0,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(0,5,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(0,6,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(0,7,1)));
+ // TODO: check why this fails with 2005
+ // CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(0,8,1)));
+
+ // Second table
+ CPPUNIT_ASSERT_EQUAL(OUString("a"), rDoc.GetString(ScAddress(5,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(5,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(5,5,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(5,6,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(5,7,1)));
+ // TODO: check why this fails with 2005
+ // CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(5,8,1)));
+
+ // There should be exactly 2 pivot tables and 1 cache.
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ ScDPCollection::SheetCaches& rSheetCaches = pDPs->GetSheetCaches();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
+
+ const ScDPCache* pCache = rSheetCaches.getExistingCache(ScRange(0,0,0,9,24,0));
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache is expected for A1:J25 on the first sheet.", pCache);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(10), pCache->GetFieldCount());
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableSharedNestedDateGroupXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table/shared-nested-dategroup.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // Check whether right date groups are imported for both tables
+ // First table
+ CPPUNIT_ASSERT_EQUAL(OUString("Years"), rDoc.GetString(ScAddress(0,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(0,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(0,11,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(0,18,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(0,21,1)));
+ // TODO: check why this fails with the empty string
+ //CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(0,32,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Quarters"), rDoc.GetString(ScAddress(1,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("a"), rDoc.GetString(ScAddress(2,3,1)));
+
+ // Second table
+ CPPUNIT_ASSERT_EQUAL(OUString("Years"), rDoc.GetString(ScAddress(6,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(6,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(6,11,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(6,18,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(6,21,1)));
+ // TODO: check why this fails with the empty string
+ //CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(6,31,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Quarters"), rDoc.GetString(ScAddress(7,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("a"), rDoc.GetString(ScAddress(8,3,1)));
+
+ // There should be exactly 2 pivot tables and 1 cache.
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ ScDPCollection::SheetCaches& rSheetCaches = pDPs->GetSheetCaches();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
+
+ const ScDPCache* pCache = rSheetCaches.getExistingCache(ScRange(0,0,0,9,24,0));
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache is expected for A1:J25 on the first sheet.", pCache);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(10), pCache->GetFieldCount());
+ // Two new group field is created
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pCache->GetGroupFieldCount());
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableSharedNumGroupXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table/shared-numgroup.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // Check whether right number groups are imported for both tables
+ // First table
+ CPPUNIT_ASSERT_EQUAL(OUString("f"), rDoc.GetString(ScAddress(0,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("32674-47673"), rDoc.GetString(ScAddress(0,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("47674-62673"), rDoc.GetString(ScAddress(0,5,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("62674-77673"), rDoc.GetString(ScAddress(0,6,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("77674-92673"), rDoc.GetString(ScAddress(0,7,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("92674-107673"), rDoc.GetString(ScAddress(0,8,1)));
+
+ // Second table
+ CPPUNIT_ASSERT_EQUAL(OUString("f"), rDoc.GetString(ScAddress(5,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("32674-47673"), rDoc.GetString(ScAddress(5,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("47674-62673"), rDoc.GetString(ScAddress(5,5,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("62674-77673"), rDoc.GetString(ScAddress(5,6,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("77674-92673"), rDoc.GetString(ScAddress(5,7,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("92674-107673"), rDoc.GetString(ScAddress(5,8,1)));
+
+ // There should be exactly 2 pivot tables and 1 cache.
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ ScDPCollection::SheetCaches& rSheetCaches = pDPs->GetSheetCaches();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
+
+ const ScDPCache* pCache = rSheetCaches.getExistingCache(ScRange(0,0,0,9,24,0));
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache is expected for A1:J25 on the first sheet.", pCache);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(10), pCache->GetFieldCount());
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableNoColumnsLayout()
+{
+ // tdf#113268 - Pivot table: Missing popup button after opening a pivot table from ODS
+ ScDocShellRef xDocSh = loadDoc("pivottable_no_columns_layout.", FORMAT_ODS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // There should be exactly 2 pivot tables
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ // Check first pivot table's popup button (headerlayout flag)
+ {
+ const ScPatternAttr* pPattern = rDoc.GetPattern(0, 1, 1);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+
+ // Check second pivot table's popup button
+ {
+ const ScPatternAttr* pPattern = rDoc.GetPattern(3, 0, 1);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+}
+
+void ScPivotTableFiltersTest::testTdf112501()
+{
+ ScDocShellRef xDocSh = loadDoc("tdf112501.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // There should be exactly 2 pivot tables
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ // Check first pivot table popup buttons (compact)
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
+ // Check whether we have the buttons at the right buttons
+ // Row button
+ {
+ const ScPatternAttr* pPattern = rDoc.GetPattern(0, 3, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+ // Column button
+ {
+ const ScPatternAttr* pPattern = rDoc.GetPattern(1, 2, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+ // Check also C3 to make sure column button is not placed there
+ {
+ const ScPatternAttr* pPattern = rDoc.GetPattern(2, 2, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(!(rMergeFlag.GetValue() & ScMF::ButtonPopup));
+ }
+ }
+
+ // Check first pivot table popup buttons (not compact)
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[1];
+ CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
+ // Check whether we have the buttons at the right buttons
+ // Two row buttons
+ {
+ const ScPatternAttr* pPattern = rDoc.GetPattern(7, 3, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+ {
+ const ScPatternAttr* pPattern = rDoc.GetPattern(8, 3, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+ // Column button
+ {
+ const ScPatternAttr* pPattern = rDoc.GetPattern(9, 2, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+ }
+}
+
+void ScPivotTableFiltersTest::testPivotTableExportXLSX()
+{
+ // tdf#89139: pivot table definition needs to list items, including hidden
+
+ ScDocShellRef xShell = loadDoc("tdf89139_pivot_table.", FORMAT_XLSX);
+ CPPUNIT_ASSERT(xShell.is());
+
+ std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
+ xmlDocPtr pTable = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotTables/pivotTable1.xml");
+ CPPUNIT_ASSERT(pTable);
+
+ assertXPath(pTable, "/x:pivotTableDefinition/x:pivotFields/x:pivotField[3]/x:items", "count", "4");
+ assertXPath(pTable, "/x:pivotTableDefinition/x:pivotFields/x:pivotField[3]/x:items/x:item", 4);
+ assertXPath(pTable, "/x:pivotTableDefinition/x:pivotFields/x:pivotField[3]/x:items/x:item[3]", "h", "1");
+}
+
+void ScPivotTableFiltersTest::testPivotCacheExportXLSX()
+{
+ // tdf#89139 FILESAVE xlsx pivot table corrupted after save with LO and re-open with MS Office
+ // MS Excel is very sensitive for proper values of fields:
+ // containsMixedTypes, containsSemiMixedTypes, containsInteger, containsBlank
+ // If it is not properly set, then Excel is not opening spreadsheet properly.
+ // This test case ensures, that such values are properly set according to documentation:
+ // https://technet.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.shareditems.aspx
+
+ ScDocShellRef xShell = loadDoc("pivot-table/with-strings-integers-and-dates.", FORMAT_XLSX);
+ CPPUNIT_ASSERT(xShell.is());
+
+ std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
+ xmlDocPtr pCacheDef = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotCache/pivotCacheDefinition1.xml");
+ CPPUNIT_ASSERT(pCacheDef);
+
+ assertXPath(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField", 6);
+
+ // Four strings and one empty field
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]", "name", "mixed strings and empty");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "containsBlank", "1");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "containsMixedTypes");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "containsSemiMixedTypes");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "containsNonDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "containsDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "containsString");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "minDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "maxDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "containsNumber");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "containsInteger");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "minValue");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "maxValue");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[1]/x:sharedItems", "count", "5");
+
+ // Two integers and one empty field
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]", "name", "mixed empty fields and integers");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "containsBlank", "1");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "containsMixedTypes");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "containsSemiMixedTypes");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "containsNonDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "containsDate");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "containsString", "0");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "minDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "maxDate");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "containsNumber", "1");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "containsInteger", "1");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "minValue", "111");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "maxValue", "222");
+ // We list items on round-trip, Excel not, but Excel accepts that; We need list all items, because we are using it as reference in pivotCacheRecords1.xml
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[2]/x:sharedItems", "count", "3");
+
+ // Five integers
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]", "name", "all fields are integers");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "containsBlank");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "containsMixedTypes");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "containsSemiMixedTypes", "0");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "containsNonDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "containsDate");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "containsString", "0");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "minDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "maxDate");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "containsNumber", "1");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "containsInteger", "1");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "minValue", "1111");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "maxValue", "5555");
+ // We list items on round-trip, Excel not, but Excel accepts that; We need list all items, because we are using it as reference in pivotCacheRecords1.xml
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[3]/x:sharedItems", "count", "5");
+
+ // Three integers and one string
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]", "name", "mixed strings and integers");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "containsBlank");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "containsMixedTypes", "1");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "containsSemiMixedTypes");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "containsNonDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "containsDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "containsString");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "minDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "maxDate");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "containsNumber", "1");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "containsInteger", "1");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "minValue", "1234");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "maxValue", "5678");
+ // We list items on round-trip, Excel not, but Excel accepts that; We need list all items, because we are using it as reference in pivotCacheRecords1.xml
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[4]/x:sharedItems", "count", "4");
+
+ // Four dates without blanks
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]", "name", "date and time with duplicated entries");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "containsBlank");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "containsMixedTypes");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "containsSemiMixedTypes","0");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "containsNonDate","0");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "containsDate", "1");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "containsString", "0");
+ //TODO Date generator in tests are one day higher, than during standard xlsx export. It should be: minDate="1899-12-31T00:00:00" maxDate="2009-07-06T10:53:02"
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "minDate", "1900-01-01T00:00:00");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "maxDate", "2009-07-07T10:53:02");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "containsNumber");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "containsInteger");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "minValue");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "maxValue");
+ // We list items on round-trip, Excel not, but Excel accepts that; We need list all items, because we are using it as reference in pivotCacheRecords1.xml
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[5]/x:sharedItems", "count", "4");
+
+ // Only blanks
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]", "name", "blank");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "containsBlank", "1");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "containsMixedTypes");
+ // Despite what documentation says, in case there's only blank values in field (no strings), containsSemiMixedTypes is true (default - not written)
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "containsSemiMixedTypes");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "containsDate");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "containsString", "0");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "minDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "maxDate");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "containsNumber");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "containsInteger");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "minValue");
+ assertXPathNoAttribute(pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "maxValue");
+ assertXPath (pCacheDef, "/x:pivotCacheDefinition/x:cacheFields/x:cacheField[6]/x:sharedItems", "count", "1");
+}
+
+void ScPivotTableFiltersTest::testPivotTableXLSX()
+{
+ struct
+ {
+ bool check( const ScDocument& rDoc )
+ {
+ if (!rDoc.HasPivotTable())
+ {
+ cerr << "The document should have pivot table." << endl;
+ return false;
+ }
+
+ const ScDPCollection* pDPs = rDoc.GetDPCollection();
+ if (!pDPs)
+ {
+ cerr << "Pivot table container should exist." << endl;
+ return false;
+ }
+
+ ScRange aSrcRange(0,0,0,9,2,0); // A1:J3 on Sheet1.
+ const ScDPCache* pCache = pDPs->GetSheetCaches().getExistingCache(aSrcRange);
+ if (!pCache)
+ {
+ cerr << "The document should have a pivot cache for A1:J3 on Sheet1." << endl;
+ return false;
+ }
+
+ // Cache should have fields from F1 through F10.
+
+ const char* pNames[] = {
+ "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"
+ };
+
+ size_t nCount = pCache->GetFieldCount();
+ if (nCount != SAL_N_ELEMENTS(pNames))
+ {
+ cout << "Incorrect number of fields in pivot cache." << endl;
+ return false;
+ }
+
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ OUString aCacheName = pCache->GetDimensionName(i);
+ if (aCacheName != OUString::createFromAscii(pNames[i]))
+ {
+ cerr << "Field " << i << " has label '" << aCacheName << "' but expected '" << pNames[i] << "'" << endl;
+ return false;
+ }
+ }
+
+ const ScDPObject* pDPObj = rDoc.GetDPAtCursor(0,10,0); // A11
+ if (!pDPObj)
+ {
+ cerr << "A pivot table should exist over A11." << endl;
+ return false;
+ }
+
+ // Output range should be A8:D15.
+ ScRange aOutRange = pDPObj->GetOutRange();
+ if (ScRange(0,7,0,3,14,0) != aOutRange)
+ {
+ cerr << "Incorrect output range." << endl;
+ return false;
+ }
+
+ // Row field - F1
+ // Column field - F4
+ // Page fields - F7 and F6
+ // Data field - F10
+
+ const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ if (!pSaveData)
+ {
+ cerr << "Save data should exist in each pivot table object." << endl;
+ return false;
+ }
+
+ std::vector<const ScDPSaveDimension*> aDims;
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aDims);
+ if (aDims.size() != 1 || aDims[0]->GetName() != "F1")
+ {
+ cerr << "Pivot table should have one row field labeld 'F1'" << endl;
+ return false;
+ }
+
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aDims);
+ if (aDims.size() != 1 || aDims[0]->GetName() != "F4")
+ {
+ cerr << "Pivot table should have one column field labeld 'F4'" << endl;
+ return false;
+ }
+
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_PAGE, aDims);
+ if (aDims.size() != 2 || aDims[0]->GetName() != "F7" || aDims[1]->GetName() != "F6")
+ {
+ cerr << "Pivot table should have two page fields labeld 'F7' and 'F6' in this order." << endl;
+ return false;
+ }
+
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA, aDims);
+ if (aDims.size() != 1 || aDims[0]->GetName() != "F10")
+ {
+ cerr << "Pivot table should have one data field labeld 'F10'" << endl;
+ return false;
+ }
+
+ const ScDPSaveDimension* pDim = aDims[0];
+ if (pDim->GetFunction() != ScGeneralFunction::SUM)
+ {
+ cerr << "Data field should have SUM function." << endl;
+ return false;
+ }
+
+ return true;
+ }
+
+ } aTest;
+
+ ScDocShellRef xDocSh = loadDoc("pivot-table/many-fields-in-cache.", FORMAT_XLSX);
+ CPPUNIT_ASSERT(xDocSh.is());
+ ScDocument* pDoc = &xDocSh->GetDocument();
+
+ // Initial check.
+ bool bCheck = aTest.check(*pDoc);
+ CPPUNIT_ASSERT_MESSAGE("Initial check failed.", bCheck);
+
+ ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLSX);
+ xDocSh->DoClose();
+ CPPUNIT_ASSERT(xDocSh2.is());
+ pDoc = &xDocSh2->GetDocument();
+
+ // Reload check.
+ bCheck = aTest.check(*pDoc);
+ CPPUNIT_ASSERT_MESSAGE("Reload check failed.", bCheck);
+
+ xDocSh2->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableTwoDataFieldsXLSX()
+{
+ struct
+ {
+ bool check( const ScDocument& rDoc )
+ {
+ if (!rDoc.HasPivotTable())
+ {
+ cerr << "The document should have pivot table." << endl;
+ return false;
+ }
+
+ const ScDPCollection* pDPs = rDoc.GetDPCollection();
+ if (!pDPs)
+ {
+ cerr << "Pivot table container should exist." << endl;
+ return false;
+ }
+
+ ScRange aSrcRange(1,1,1,2,8,1); // B2:C9 on the 2nd sheet.
+ const ScDPCache* pCache = pDPs->GetSheetCaches().getExistingCache(aSrcRange);
+ if (!pCache)
+ {
+ cerr << "The document should have a pivot cache for B2:C9 on 'Src'." << endl;
+ return false;
+ }
+
+ const char* pNames[] = { "Name", "Value" };
+ (void) pNames;
+
+ size_t nCount = pCache->GetFieldCount();
+ if (nCount != SAL_N_ELEMENTS(pNames))
+ {
+ cout << "Incorrect number of fields in pivot cache." << endl;
+ return false;
+ }
+
+ const ScDPObject* pDPObj = rDoc.GetDPAtCursor(0,2,0); // A3
+ if (!pDPObj)
+ {
+ cerr << "A pivot table should exist over A3." << endl;
+ return false;
+ }
+
+ // Output range should be A3:C12.
+ ScRange aOutRange = pDPObj->GetOutRange();
+ if (ScRange(0,2,0,2,11,0) != aOutRange)
+ {
+ cerr << "Incorrect output range." << endl;
+ return false;
+ }
+
+ const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ if (!pSaveData)
+ {
+ cerr << "Save data should exist in each pivot table object." << endl;
+ return false;
+ }
+
+ std::vector<const ScDPSaveDimension*> aDims;
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aDims);
+ if (aDims.size() != 1 || aDims[0]->GetName() != "Name")
+ {
+ cerr << "Pivot table should have one row field labeld 'Name'" << endl;
+ return false;
+ }
+
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA, aDims);
+ if (aDims.size() != 2 ||
+ ScDPUtil::getSourceDimensionName(aDims[0]->GetName()) != "Value" ||
+ ScDPUtil::getSourceDimensionName(aDims[1]->GetName()) != "Value")
+ {
+ cerr << "Pivot table should have two duplicated data fields both of which are named 'Value'." << endl;
+ return false;
+ }
+
+ if (aDims[0]->GetFunction() != ScGeneralFunction::SUM)
+ {
+ cerr << "First data field should be SUM." << endl;
+ return false;
+ }
+
+ if (aDims[1]->GetFunction() != ScGeneralFunction::COUNT)
+ {
+ cerr << "First data field should be COUNT." << endl;
+ return false;
+ }
+
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aDims);
+ if (aDims.size() != 1 || !aDims[0]->IsDataLayout())
+ {
+ cerr << "Pivot table should have one column field which is a data layout field." << endl;
+ return false;
+ }
+
+ return true;
+ }
+
+ } aTest;
+
+ ScDocShellRef xDocSh = loadDoc("pivot-table/two-data-fields.", FORMAT_XLSX);
+ CPPUNIT_ASSERT(xDocSh.is());
+ ScDocument* pDoc = &xDocSh->GetDocument();
+
+ // Initial check.
+ bool bCheck = aTest.check(*pDoc);
+ CPPUNIT_ASSERT_MESSAGE("Initial check failed.", bCheck);
+
+ ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLSX);
+ xDocSh->DoClose();
+ CPPUNIT_ASSERT(xDocSh2.is());
+ pDoc = &xDocSh2->GetDocument();
+
+ // Reload check.
+ bCheck = aTest.check(*pDoc);
+ CPPUNIT_ASSERT_MESSAGE("Reload check failed.", bCheck);
+
+ xDocSh2->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableMedianODS()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table-median.", FORMAT_ODS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load test document.", xDocSh.is());
+
+ // Export the document and import again for a check
+ ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_ODS);
+ xDocSh->DoClose();
+
+ // Check sheet
+ ScDocument& rDoc = xDocSh2->GetDocument();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be exactly one sheet.", sal_Int16(1), rDoc.GetTableCount());
+
+ // Check pivot table
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_MESSAGE("Failed to get a live ScDPCollection instance.", pDPs);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be one pivot table instance.", size_t(1), pDPs->GetCount());
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT_MESSAGE("Failed to get pivot table object.", pDPObj);
+ const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT_MESSAGE("Failed to get ScDPSaveData instance.", pSaveData);
+
+ // Check the data field function.
+ std::vector<const ScDPSaveDimension*> aDims;
+ pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA, aDims);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "There should be exactly 1 data field.",
+ std::vector<ScDPSaveDimension const *>::size_type(1), aDims.size());
+
+ const ScDPSaveDimension* pDim = aDims.back();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Function for the data field should be MEDIAN.",
+ sal_uInt16(ScGeneralFunction::MEDIAN), sal_uInt16(pDim->GetFunction()));
+
+ xDocSh2->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableRowHeaderXLS()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot_row_header.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // There should be exactly 2 pivot tables
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ // First table has extra row header
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
+ CPPUNIT_ASSERT(pDPObj->GetHeaderLayout());
+ // Check whether the row header has the right popupbutton flag
+ const ScPatternAttr* pPattern = rDoc.GetPattern(3, 3, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+
+ // Second table has no extra row header
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[1];
+ CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
+ CPPUNIT_ASSERT(!pDPObj->GetHeaderLayout());
+ // Check whether the row header has the right popupbutton flag
+ const ScPatternAttr* pPattern = rDoc.GetPattern(0, 2, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+
+ // Check also after a reload
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+
+ // There should be exactly 2 pivot tables
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ // First table has extra row header
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
+ CPPUNIT_ASSERT(pDPObj->GetHeaderLayout());
+ // Check whether the row header has the right popupbutton flag
+ const ScPatternAttr* pPattern = rLoadedDoc.GetPattern(3, 3, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+
+ // Second table has no extra row header
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[1];
+ CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
+ CPPUNIT_ASSERT(!pDPObj->GetHeaderLayout());
+ // Check whether the row header has the right popupbutton flag
+ const ScPatternAttr* pPattern = rLoadedDoc.GetPattern(0, 2, 0);
+ const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup);
+ }
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableDoubleFieldFilter()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_double_field_filter.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pDPs->GetCount());
+
+ // Field with general formatting
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[2];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Double field1");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "1"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "3"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ // Number formatting
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[1];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Double field2");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "1.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "3.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ }
+
+ // With thousand separator
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Double field3");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "10,000.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "20,000.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "30,000.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableStringFieldFilter()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_string_field_filter.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Country");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(2), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("United Kingdom");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("United States");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+
+ xDocSh->DoClose();
+}
+
+
+void ScPivotTableFiltersTest::testPivotTableDateFieldFilter()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_date_field_filter.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Date");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "2016. január 6."
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2016. január 7."
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2016. január 8."
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ }
+
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Date2");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "2016-01-06"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2016-01-07"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2016-01-08"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ }
+
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Date3");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "2016. 1. 6. 0:00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2016. 1. 7. 0:00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2016. 1. 8. 0:00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableBoolFieldFilter()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_bool_field_filter.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Bool field");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(2), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("0");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("1");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableRowColPageFieldFilter()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_rowcolpage_field_filter.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+
+ // Row field
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Order ID");
+ CPPUNIT_ASSERT(pSaveDim);
+ CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldOrientation_ROW, pSaveDim->GetOrientation());
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("1");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("2");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("3");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ }
+
+ // Column field
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Double2 field");
+ CPPUNIT_ASSERT(pSaveDim);
+ CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldOrientation_COLUMN, pSaveDim->GetOrientation());
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("2");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("3");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("4");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ }
+
+ // Page field
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Double3 field");
+ CPPUNIT_ASSERT(pSaveDim);
+ CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldOrientation_PAGE, pSaveDim->GetOrientation());
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("5");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("6");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("7");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ // Hidden field
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Double4 field");
+ CPPUNIT_ASSERT(pSaveDim);
+ CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldOrientation_HIDDEN, pSaveDim->GetOrientation());
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("8");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("9");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("10");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableEmptyItem()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_empty_item.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Category");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("Fruit");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("Vegetables");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTablePageFieldFilter()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_page_field_filter.", FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+
+ // Only one item is selected (an empty item)
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Product");
+ CPPUNIT_ASSERT(pSaveDim);
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("Banana");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("Carrots");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ // More items are selected, but not all
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Category");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("Vegetables");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("Fruit");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ // All items are selected
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Order ID");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("1");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("2");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("3");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ // Only one item is selected (a non-empty item)
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Country");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("United States");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("United Kingdom");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ }
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableFirstHeaderRowXLSX()
+{
+ // tdf#112733: We have different tables here, but have the same value as firstHeaderRow
+ // The documentation is not clear about what firstHeaderRow actually means, but MS Excel works on this way
+ ScDocShellRef xShell = loadDoc("pivot_table_first_header_row.", FORMAT_XLSX);
+ CPPUNIT_ASSERT(xShell.is());
+
+ std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
+ xmlDocPtr pTable = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotTables/pivotTable1.xml");
+ CPPUNIT_ASSERT(pTable);
+ assertXPath(pTable, "/x:pivotTableDefinition/x:location", "firstHeaderRow", "1");
+
+ pTable = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotTables/pivotTable2.xml");
+ CPPUNIT_ASSERT(pTable);
+ assertXPath(pTable, "/x:pivotTableDefinition/x:location", "firstHeaderRow", "1");
+
+ pTable = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotTables/pivotTable3.xml");
+ CPPUNIT_ASSERT(pTable);
+ assertXPath(pTable, "/x:pivotTableDefinition/x:location", "firstHeaderRow", "1");
+}
+
+void ScPivotTableFiltersTest::testPivotTableDoubleFieldFilterXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_double_field_filter.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pDPs->GetCount());
+
+ // Field with general formatting
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Double field1");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "1"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "3"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ // Number formatting
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[1];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Double field2");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "1.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "3.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ }
+
+ // With thousand separator
+ {
+ const ScDPObject* pDPObj = &(*pDPs)[2];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Double field3");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "10,000.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "20,000.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "30,000.00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableStringFieldFilterXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_string_field_filter.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Country");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(2), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("United Kingdom");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("United States");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+
+ xDocSh->DoClose();
+}
+
+
+void ScPivotTableFiltersTest::testPivotTableDateFieldFilterXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_date_field_filter.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Date");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ //CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "2016. január 7."
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2016. január 8."
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ }
+
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Date2");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "2016-01-07"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2016-01-08"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ }
+
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Date3");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ auto aIter = rMembers.begin();
+ ScDPSaveMember* pMember = *aIter; // "2016. 1. 7. 0:00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ ++aIter;
+ pMember = *aIter; // "2016. 1. 8. 0:00"
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ }
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableBoolFieldFilterXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_bool_field_filter.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Bool field");
+ CPPUNIT_ASSERT(pSaveDim);
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(2), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("0");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && !pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("1");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+
+ xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableRowColPageFieldFilterXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivottable_rowcolpage_field_filter.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+ // Reload and check filtering of row dimensions
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+ ScDocument& rLoadedDoc = xDocSh->GetDocument();
+ pDPs = rLoadedDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+
+ // Row field
+ {
+ ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName("Order ID");
+ CPPUNIT_ASSERT(pSaveDim);
+ CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldOrientation_ROW, pSaveDim->GetOrientation());
+
+ const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), rMembers.size());
+ ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("1");
+ CPPUNIT_ASSERT(pMember);
+ CPPUNIT_ASSERT(pMember->HasIsVisible() && pMember->GetIsVisible());
+ pMember = pSaveDim->GetExistingMemberByName("2");
+ CPPUNIT_ASSERT(pMember);
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list