diff options
author | Tamás Zolnai <tamas.zolnai@collabora.com> | 2017-09-21 06:48:09 +0200 |
---|---|---|
committer | Tamás Zolnai <tamas.zolnai@collabora.com> | 2017-09-21 21:21:33 +0200 |
commit | 0098bee792c3e208ea4f6ef1c676958d3f4cd207 (patch) | |
tree | 5904499baf80f7c05ef671e42fd44ad24332a4bb | |
parent | 29bb6d45dd0f8adef0612bea99b3df6de7a6e82b (diff) |
tdf#112501: Pivot table: popupbuttons are placed on wrong cells
...imported from XLS
Change-Id: I45bc4a0182e6a62471bc02ac1bca31f9735e6566
Reviewed-on: https://gerrit.libreoffice.org/42508
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com>
-rw-r--r-- | sc/inc/dpoutputgeometry.hxx | 2 | ||||
-rwxr-xr-x | sc/qa/unit/data/xls/tdf112501.xls | bin | 0 -> 28160 bytes | |||
-rw-r--r-- | sc/qa/unit/subsequent_filters-test.cxx | 69 | ||||
-rw-r--r-- | sc/source/core/data/dpoutputgeometry.cxx | 13 | ||||
-rw-r--r-- | sc/source/filter/excel/read.cxx | 1 | ||||
-rw-r--r-- | sc/source/filter/excel/xipivot.cxx | 14 | ||||
-rw-r--r-- | sc/source/filter/excel/xlpivot.cxx | 18 | ||||
-rw-r--r-- | sc/source/filter/inc/xipivot.hxx | 6 | ||||
-rw-r--r-- | sc/source/filter/inc/xlpivot.hxx | 12 |
9 files changed, 133 insertions, 2 deletions
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<ScAddress>& rAddrs) const; void getRowFieldPositions(::std::vector<ScAddress>& 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 Binary files differnew file mode 100755 index 000000000000..2002be6cff29 --- /dev/null +++ b/sc/qa/unit/data/xls/tdf112501.xls diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index b982c782eda9..459a85d4377b 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -246,6 +246,7 @@ public: void testPageScalingXLSX(); void testActiveXCheckboxXLSX(); + void testTdf112501(); #ifdef UNX void testUnicodeFileNameGnumeric(); #endif @@ -376,6 +377,7 @@ public: CPPUNIT_TEST(testPageScalingXLSX); CPPUNIT_TEST(testActiveXCheckboxXLSX); + CPPUNIT_TEST(testTdf112501); #ifdef UNX CPPUNIT_TEST(testUnicodeFileNameGnumeric); #endif @@ -4048,6 +4050,73 @@ void ScFiltersTest::testActiveXCheckboxXLSX() xDocSh->DoClose(); } +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<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); + } + } +} + + ScFiltersTest::ScFiltersTest() : ScBootstrapFixture( "sc/qa/unit/data" ) { diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx index 16011cf31243..8d3ec1c09589 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<ScAddress>& rAddrs) const { sal_uInt32 nColumnFields, nRowFields; @@ -96,6 +102,8 @@ void ScDPOutputGeometry::getColumnFieldPositions(vector<ScAddress>& rAddrs) cons SCROW nRow = nCurRow; SCTAB nTab = maOutRange.aStart.Tab(); SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + nRowFields); + if(mbCompactMode) + nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + 1); // We have only one row in compact mode SCCOL nColEnd = nColStart + static_cast<SCCOL>(nColumnFields-1); for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) @@ -120,6 +128,9 @@ void ScDPOutputGeometry::getRowFieldPositions(vector<ScAddress>& rAddrs) const SCCOL nColStart = maOutRange.aStart.Col(); SCCOL nColEnd = nColStart + static_cast<SCCOL>(nRowFields-1); + if(mbCompactMode) + nColEnd = nColStart; // We have only one row in compact mode + for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) aAddrs.emplace_back(nCol, nRow, nTab); rAddrs.swap(aAddrs); diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 18b89773b9e7..2dc1d485af1b 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -1235,6 +1235,7 @@ ErrCode 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 b756f273aca5..aee3afb72dca 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1396,6 +1396,11 @@ void XclImpPivotTable::ReadSxViewEx9( XclImpStream& rStrm ) rStrm >> maPTViewEx9Info; } +void XclImpPivotTable::ReadSxAddl( XclImpStream& rStrm ) +{ + rStrm >> maPTAddlInfo; +} + void XclImpPivotTable::Convert() { if( !mxPCache || !mxPCache->IsValid() ) @@ -1514,6 +1519,7 @@ void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveD mpDPObj->SetHeaderLayout( maPTInfo.mnFirstHeadRow - 2 == static_cast<sal_uInt16>(aGeometry.getRowFieldHeaderRow()) ); } aGeometry.setHeaderLayout(mpDPObj->GetHeaderLayout()); + aGeometry.setCompactMode(maPTAddlInfo.mbCompactMode); ScDocument& rDoc = GetDoc(); @@ -1555,7 +1561,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(); @@ -1702,6 +1708,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( const 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 7cba10f7dd36..378f3c96104c 100644 --- a/sc/source/filter/excel/xlpivot.cxx +++ b/sc/source/filter/excel/xlpivot.cxx @@ -1019,4 +1019,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 93425806f69d..fedfd4e28704 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( const XclImpStream& rStrm ); diff --git a/sc/source/filter/inc/xlpivot.hxx b/sc/source/filter/inc/xlpivot.hxx index e85143c6e0dd..597b15c58768 100644 --- a/sc/source/filter/inc/xlpivot.hxx +++ b/sc/source/filter/inc/xlpivot.hxx @@ -364,6 +364,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. */ @@ -761,6 +764,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: */ |