From c3eefbd9e45598ba06f5741e8ac913ba3c469d09 Mon Sep 17 00:00:00 2001 From: Tamás Zolnai Date: Fri, 22 Sep 2017 15:49:12 +0200 Subject: tdf#112501: Pivot table: popupbuttons are placed on wrong cells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...imported from XLS Reviewed-on: https://gerrit.libreoffice.org/42508 Tested-by: Jenkins Reviewed-by: Tamás Zolnai (cherry picked from commit 0098bee792c3e208ea4f6ef1c676958d3f4cd207) Change-Id: I45bc4a0182e6a62471bc02ac1bca31f9735e6566 Reviewed-on: https://gerrit.libreoffice.org/42647 Reviewed-by: Andras Timar Tested-by: Andras Timar --- sc/inc/dpoutputgeometry.hxx | 2 + sc/qa/unit/data/xls/tdf112501.xls | Bin 0 -> 28160 bytes sc/qa/unit/subsequent_filters-test.cxx | 69 +++++++++++++++++++++++++++++++ sc/source/core/data/dpoutputgeometry.cxx | 13 +++++- sc/source/filter/excel/read.cxx | 1 + sc/source/filter/excel/xipivot.cxx | 14 ++++++- sc/source/filter/excel/xlpivot.cxx | 18 ++++++++ sc/source/filter/inc/xipivot.hxx | 6 +++ sc/source/filter/inc/xlpivot.hxx | 12 ++++++ 9 files changed, 133 insertions(+), 2 deletions(-) create mode 100755 sc/qa/unit/data/xls/tdf112501.xls (limited to 'sc') diff --git a/sc/inc/dpoutputgeometry.hxx b/sc/inc/dpoutputgeometry.hxx index f4896fc1c3ec..872b57dd1e70 100644 --- a/sc/inc/dpoutputgeometry.hxx +++ b/sc/inc/dpoutputgeometry.hxx @@ -43,6 +43,7 @@ public: void setDataFieldCount(sal_uInt32 nCount); void setDataLayoutType(FieldType eType); void setHeaderLayout(bool bHeaderLayout); + void setCompactMode(bool bCompactMode); void getColumnFieldPositions(::std::vector& rAddrs) const; void getRowFieldPositions(::std::vector& rAddrs) const; @@ -64,6 +65,7 @@ private: FieldType meDataLayoutType; bool mbShowFilter; bool mbHeaderLayout; + bool mbCompactMode; // MSO only setting }; #endif diff --git a/sc/qa/unit/data/xls/tdf112501.xls b/sc/qa/unit/data/xls/tdf112501.xls new file mode 100755 index 000000000000..2002be6cff29 Binary files /dev/null and b/sc/qa/unit/data/xls/tdf112501.xls differ diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index b53803c4e425..2a1819b35c08 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -242,6 +242,7 @@ public: void testTdf100709XLSX(); void testTdf97598XLSX(); void testTdf111974XLSM(); + void testTdf112501(); CPPUNIT_TEST_SUITE(ScFiltersTest); CPPUNIT_TEST(testBooleanFormatXLSX); @@ -361,6 +362,7 @@ public: CPPUNIT_TEST(testTdf100709XLSX); CPPUNIT_TEST(testTdf97598XLSX); CPPUNIT_TEST(testTdf111974XLSM); + CPPUNIT_TEST(testTdf112501); CPPUNIT_TEST_SUITE_END(); @@ -3891,6 +3893,73 @@ void ScFiltersTest::testTdf97598XLSX() } +void ScFiltersTest::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(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(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(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(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(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(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(rPoolItem); + CPPUNIT_ASSERT(rMergeFlag.GetValue() & ScMF::ButtonPopup); + } + } +} + + ScFiltersTest::ScFiltersTest() : ScBootstrapFixture( "sc/qa/unit/data" ) { diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx index 23138d2fe7af..61d0633eafcd 100644 --- a/sc/source/core/data/dpoutputgeometry.cxx +++ b/sc/source/core/data/dpoutputgeometry.cxx @@ -32,7 +32,8 @@ ScDPOutputGeometry::ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilte mnDataFields(0), meDataLayoutType(None), mbShowFilter(bShowFilter), - mbHeaderLayout (false) + mbHeaderLayout (false), + mbCompactMode (false) { } @@ -70,6 +71,11 @@ void ScDPOutputGeometry::setHeaderLayout(bool bHeaderLayout) mbHeaderLayout = bHeaderLayout; } +void ScDPOutputGeometry::setCompactMode(bool bCompactMode) +{ + mbCompactMode = bCompactMode; +} + void ScDPOutputGeometry::getColumnFieldPositions(vector& rAddrs) const { sal_uInt32 nColumnFields, nRowFields; @@ -96,6 +102,8 @@ void ScDPOutputGeometry::getColumnFieldPositions(vector& rAddrs) cons SCROW nRow = nCurRow; SCTAB nTab = maOutRange.aStart.Tab(); SCCOL nColStart = static_cast(maOutRange.aStart.Col() + nRowFields); + if(mbCompactMode) + nColStart = static_cast(maOutRange.aStart.Col() + 1); // We have only one row in compact mode SCCOL nColEnd = nColStart + static_cast(nColumnFields-1); for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) @@ -120,6 +128,9 @@ void ScDPOutputGeometry::getRowFieldPositions(vector& rAddrs) const SCCOL nColStart = maOutRange.aStart.Col(); SCCOL nColEnd = nColStart + static_cast(nRowFields-1); + if(mbCompactMode) + nColEnd = nColStart; // We have only one row in compact mode + for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) aAddrs.push_back(ScAddress(nCol, nRow, nTab)); rAddrs.swap(aAddrs); diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 70fc840974df..54946b2b5e67 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -1240,6 +1240,7 @@ FltError ImportExcel8::Read() case EXC_ID_SXEX: rPTableMgr.ReadSxex( maStrm ); break; case EXC_ID_SHEETEXT: rTabViewSett.ReadTabBgColor( maStrm, rPal ); break; case EXC_ID_SXVIEWEX9: rPTableMgr.ReadSxViewEx9( maStrm ); break; + case EXC_ID_SXADDL: rPTableMgr.ReadSxAddl( maStrm ); break; } } break; diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index 960d10690b23..abeeba02afdf 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1399,6 +1399,11 @@ void XclImpPivotTable::ReadSxViewEx9( XclImpStream& rStrm ) rStrm >> maPTViewEx9Info; } +void XclImpPivotTable::ReadSxAddl( XclImpStream& rStrm ) +{ + rStrm >> maPTAddlInfo; +} + void XclImpPivotTable::Convert() { if( !mxPCache || !mxPCache->IsValid() ) @@ -1517,6 +1522,7 @@ void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveD mpDPObj->SetHeaderLayout( maPTInfo.mnFirstHeadRow - 2 == static_cast(aGeometry.getRowFieldHeaderRow()) ); } aGeometry.setHeaderLayout(mpDPObj->GetHeaderLayout()); + aGeometry.setCompactMode(maPTAddlInfo.mbCompactMode); ScDocument& rDoc = GetDoc(); @@ -1558,7 +1564,7 @@ void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveD aGeometry.getRowFieldPositions(aFieldBtns); rSaveData.GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aFieldDims); - if (aFieldBtns.size() == aFieldDims.size()) + if ((aFieldBtns.size() == aFieldDims.size()) || (maPTAddlInfo.mbCompactMode && aFieldBtns.size() == 1)) { itr = aFieldBtns.begin(); itrEnd = aFieldBtns.end(); @@ -1705,6 +1711,12 @@ void XclImpPivotTableManager::ReadSxViewEx9( XclImpStream& rStrm ) maPTables.back()->ReadSxViewEx9( rStrm ); } +void XclImpPivotTableManager::ReadSxAddl( XclImpStream& rStrm ) +{ + if( !maPTables.empty() ) + maPTables.back()->ReadSxAddl( rStrm ); +} + void XclImpPivotTableManager::ReadPivotCaches( XclImpStream& rStrm ) { for( XclImpPivotCacheVec::iterator aIt = maPCaches.begin(), aEnd = maPCaches.end(); aIt != aEnd; ++aIt ) diff --git a/sc/source/filter/excel/xlpivot.cxx b/sc/source/filter/excel/xlpivot.cxx index 690129ee0827..a911996530de 100644 --- a/sc/source/filter/excel/xlpivot.cxx +++ b/sc/source/filter/excel/xlpivot.cxx @@ -1021,4 +1021,22 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo ) << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN); } +XclPTAddl::XclPTAddl() : + mbCompactMode(false) +{ +} + +XclImpStream& operator>>(XclImpStream& rStrm, XclPTAddl& rInfo) +{ + rStrm.Ignore(4); + sal_uInt8 sxc = rStrm.ReaduInt8(); + sal_uInt8 sxd = rStrm.ReaduInt8(); + if(sxc == 0x00 && sxd == 0x19) // SxcView / sxdVer12Info + { + sal_uInt32 nFlags = rStrm.ReaduInt32(); + rInfo.mbCompactMode = ((nFlags & 0x00000008) != 0); + } + return rStrm; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/inc/xipivot.hxx b/sc/source/filter/inc/xipivot.hxx index 898726adf46f..15f38ea408e2 100644 --- a/sc/source/filter/inc/xipivot.hxx +++ b/sc/source/filter/inc/xipivot.hxx @@ -332,6 +332,9 @@ public: * autoformat. */ void ReadSxViewEx9( XclImpStream& rStrm ); + /** Reads an SXADDL record that specifies additional info for pivot table. */ + void ReadSxAddl( XclImpStream& rStrm ); + /** Inserts the pivot table into the Calc document. */ void Convert(); @@ -348,6 +351,7 @@ private: XclPTInfo maPTInfo; /// General info about the pivot table (SXVIEW record). XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record). XclPTViewEx9Info maPTViewEx9Info; /// (SXVIEWEX9 record) + XclPTAddl maPTAddlInfo; XclImpPTFieldVec maFields; /// Vector containing all fields. XclImpPTFieldRef mxCurrField; /// Current field for importing additional info. ScfStringVec maVisFieldNames; /// Vector containing all visible field names. @@ -408,6 +412,8 @@ public: /** Reads an SXVIEWEX9 record that specifies the pivot tables * autoformat. */ void ReadSxViewEx9( XclImpStream& rStrm ); + /** Reads an SXADDL record that specifies additional info for pivot table. */ + void ReadSxAddl( XclImpStream& rStrm ); /** Reads all used pivot caches and creates additional sheets for external data sources. */ void ReadPivotCaches( XclImpStream& rStrm ); diff --git a/sc/source/filter/inc/xlpivot.hxx b/sc/source/filter/inc/xlpivot.hxx index 56976aef1bcc..4b74651df881 100644 --- a/sc/source/filter/inc/xlpivot.hxx +++ b/sc/source/filter/inc/xlpivot.hxx @@ -363,6 +363,9 @@ const sal_uInt16 EXC_SXFDBTYPE_DEFAULT = 0x0000; // (0x0810) SXVIEWEX9 --------------------------------------------------------- const sal_uInt16 EXC_ID_SXVIEWEX9 = 0x0810; +// (0x0864) SXADDL ("Pivot Table Additional Info") ---------------------------- +const sal_uInt16 EXC_ID_SXADDL = 0x0864; + // Pivot cache /** Represents a data item of any type in a pivot cache. Supposed as base class for import and export. */ @@ -760,6 +763,15 @@ struct XclPTViewEx9Info XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo ); XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo ); +/** Additional pivot table settings (SXADDL record). */ +struct XclPTAddl +{ + bool mbCompactMode; + explicit XclPTAddl(); +}; + +XclImpStream& operator>>(XclImpStream& rStrm, XclPTAddl& rInfo); + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3