Kaydet (Commit) 0098bee7 authored tarafından Tamás Zolnai's avatar Tamás Zolnai

tdf#112501: Pivot table: popupbuttons are placed on wrong cells

...imported from XLS

Change-Id: I45bc4a0182e6a62471bc02ac1bca31f9735e6566
Reviewed-on: https://gerrit.libreoffice.org/42508Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarTamás Zolnai <tamas.zolnai@collabora.com>
üst 29bb6d45
......@@ -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
......
......@@ -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" )
{
......
......@@ -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);
......
......@@ -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;
......
......@@ -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 )
......
......@@ -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: */
......@@ -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 );
......
......@@ -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: */
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