Kaydet (Commit) d828577b authored tarafından Mike Kaganski's avatar Mike Kaganski

tdf#89139: list all items in pivot table definition, incl. hidden

Change-Id: I14ce935185a6e0e3739fcf01fdefa031d814e821
Reviewed-on: https://gerrit.libreoffice.org/41509Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMike Kaganski <mike.kaganski@collabora.com>
üst 3c49b28f
...@@ -115,6 +115,7 @@ public: ...@@ -115,6 +115,7 @@ public:
void testCellNoteExportXLS(); void testCellNoteExportXLS();
void testFormatExportODS(); void testFormatExportODS();
void testPivotTableExportXLSX();
void testPivotExportXLSX(); void testPivotExportXLSX();
void testCommentExportXLSX(); void testCommentExportXLSX();
#if HAVE_MORE_FONTS #if HAVE_MORE_FONTS
...@@ -227,6 +228,7 @@ public: ...@@ -227,6 +228,7 @@ public:
CPPUNIT_TEST(testCellNoteExportXLS); CPPUNIT_TEST(testCellNoteExportXLS);
CPPUNIT_TEST(testFormatExportODS); CPPUNIT_TEST(testFormatExportODS);
CPPUNIT_TEST(testPivotTableExportXLSX);
CPPUNIT_TEST(testPivotExportXLSX); CPPUNIT_TEST(testPivotExportXLSX);
CPPUNIT_TEST(testCommentExportXLSX); CPPUNIT_TEST(testCommentExportXLSX);
#if HAVE_MORE_FONTS #if HAVE_MORE_FONTS
...@@ -563,6 +565,22 @@ void ScExportTest::testFormatExportODS() ...@@ -563,6 +565,22 @@ void ScExportTest::testFormatExportODS()
xDocSh->DoClose(); xDocSh->DoClose();
} }
void ScExportTest::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 ScExportTest::testPivotExportXLSX() void ScExportTest::testPivotExportXLSX()
{ {
// tdf#89139 FILESAVE xlsx pivot table corrupted after save with LO and re-open with MS Office // tdf#89139 FILESAVE xlsx pivot table corrupted after save with LO and re-open with MS Office
......
...@@ -701,24 +701,35 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP ...@@ -701,24 +701,35 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
} }
// Dump field items. // Dump field items.
css::uno::Sequence<OUString> aMemberNames; std::vector<ScDPLabelData::Member> aMembers;
{ {
// We need to get the members in actual order, getting which requires non-const reference here // We need to get the members in actual order, getting which requires non-const reference here
auto& dpo = const_cast<ScDPObject&>(rDPObj); auto& dpo = const_cast<ScDPObject&>(rDPObj);
dpo.GetMemberNames(i, aMemberNames); dpo.GetMembers(i, dpo.GetUsedHierarchy(i), aMembers);
} }
const ScDPCache::ScDPItemDataVec& rCacheFieldItems = rCache.GetDimMemberValues(i); const ScDPCache::ScDPItemDataVec& rCacheFieldItems = rCache.GetDimMemberValues(i);
std::vector<size_t> aMemberSequence; const auto iCacheFieldItems_begin = rCacheFieldItems.begin(), iCacheFieldItems_end = rCacheFieldItems.end();
for (const OUString& sMemberName : aMemberNames) // The pair contains the member index in cache and if it is hidden
std::vector< std::pair<size_t, bool> > aMemberSequence;
std::set<size_t> aUsedCachePositions;
for (const auto & rMember : aMembers)
{ {
auto it = std::find_if(rCacheFieldItems.begin(), rCacheFieldItems.end(), auto it = std::find_if(iCacheFieldItems_begin, iCacheFieldItems_end,
[&sMemberName](const ScDPItemData& arg) -> bool { return arg.GetString() == sMemberName; }); [&rMember](const ScDPItemData& arg) -> bool { return arg.GetString() == rMember.maName; });
if (it != rCacheFieldItems.end()) if (it != iCacheFieldItems_end)
{ {
aMemberSequence.push_back(it - rCacheFieldItems.begin()); size_t nCachePos = it - iCacheFieldItems_begin;
aMemberSequence.push_back(std::make_pair(nCachePos, !rMember.mbVisible));
aUsedCachePositions.insert(nCachePos);
} }
} }
// Now add all remaining cache items as hidden
for (size_t nItem = 0; nItem < rCacheFieldItems.size(); ++nItem)
{
if (aUsedCachePositions.find(nItem) == aUsedCachePositions.end())
aMemberSequence.push_back(std::make_pair(nItem, true));
}
auto pAttList = sax_fastparser::FastSerializerHelper::createAttrList(); auto pAttList = sax_fastparser::FastSerializerHelper::createAttrList();
pAttList->add(XML_axis, toOOXMLAxisType(eOrient)); pAttList->add(XML_axis, toOOXMLAxisType(eOrient));
...@@ -726,14 +737,20 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP ...@@ -726,14 +737,20 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
long nSubTotalCount = pDim->GetSubTotalsCount(); long nSubTotalCount = pDim->GetSubTotalsCount();
std::vector<OString> aSubtotalSequence; std::vector<OString> aSubtotalSequence;
bool bHasDefaultSubtotal = false;
for (long nSubTotal = 0; nSubTotal < nSubTotalCount; ++nSubTotal) for (long nSubTotal = 0; nSubTotal < nSubTotalCount; ++nSubTotal)
{ {
ScGeneralFunction eFunc = pDim->GetSubTotalFunc(nSubTotal); ScGeneralFunction eFunc = pDim->GetSubTotalFunc(nSubTotal);
aSubtotalSequence.push_back(GetSubtotalFuncName(eFunc)); aSubtotalSequence.push_back(GetSubtotalFuncName(eFunc));
sal_Int32 nAttToken = GetSubtotalAttrToken(eFunc); sal_Int32 nAttToken = GetSubtotalAttrToken(eFunc);
if (!pAttList->hasAttribute(nAttToken)) if (nAttToken == XML_defaultSubtotal)
bHasDefaultSubtotal = true;
else if (!pAttList->hasAttribute(nAttToken))
pAttList->add(nAttToken, ToPsz10(true)); pAttList->add(nAttToken, ToPsz10(true));
} }
// XML_defaultSubtotal is true by default; only write it if it's false
if (!bHasDefaultSubtotal)
pAttList->add(XML_defaultSubtotal, ToPsz10(false));
sax_fastparser::XFastAttributeListRef xAttributeList(pAttList); sax_fastparser::XFastAttributeListRef xAttributeList(pAttList);
pPivotStrm->startElement(XML_pivotField, xAttributeList); pPivotStrm->startElement(XML_pivotField, xAttributeList);
...@@ -742,11 +759,14 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP ...@@ -742,11 +759,14 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
XML_count, OString::number(static_cast<long>(aMemberSequence.size() + aSubtotalSequence.size())), XML_count, OString::number(static_cast<long>(aMemberSequence.size() + aSubtotalSequence.size())),
FSEND); FSEND);
for (size_t nMember : aMemberSequence) for (const auto & nMember : aMemberSequence)
{ {
pPivotStrm->singleElement(XML_item, auto pItemAttList = sax_fastparser::FastSerializerHelper::createAttrList();
XML_x, OString::number(static_cast<long>(nMember)), if (nMember.second)
FSEND); pItemAttList->add(XML_h, ToPsz10(true));
pItemAttList->add(XML_x, OString::number(static_cast<long>(nMember.first)));
sax_fastparser::XFastAttributeListRef xItemAttributeList(pItemAttList);
pPivotStrm->singleElement(XML_item, xItemAttributeList);
} }
for (const OString& sSubtotal : aSubtotalSequence) for (const OString& sSubtotal : aSubtotalSequence)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment