diff options
author | Deena Francis <deena.francis@gmail.com> | 2015-02-16 22:28:52 +0530 |
---|---|---|
committer | Kohei Yoshida <libreoffice@kohei.us> | 2015-03-12 01:18:06 +0000 |
commit | 7b355da6853af6678c4ba22710d157cf8a6d43eb (patch) | |
tree | f4776c6b9db2582c4fd52538814d2fcc38f34eb5 | |
parent | 33434f47ac44f5cb4612a11b1c28c4582976cb25 (diff) |
Enhancement tdf#87972 : Cannot repeat items labels on a pivot table
Change-Id: I44b2521ea548b51a1b3e9b42cfa64c5f50d7798a
Reviewed-on: https://gerrit.libreoffice.org/14504
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Kohei Yoshida <libreoffice@kohei.us>
Tested-by: Kohei Yoshida <libreoffice@kohei.us>
-rw-r--r-- | include/xmloff/xmltoken.hxx | 1 | ||||
-rw-r--r-- | sc/inc/dapiuno.hxx | 2 | ||||
-rw-r--r-- | sc/inc/dpsave.hxx | 5 | ||||
-rw-r--r-- | sc/inc/dptabsrc.hxx | 2 | ||||
-rw-r--r-- | sc/inc/pivot.hxx | 1 | ||||
-rw-r--r-- | sc/inc/unonames.hxx | 2 | ||||
-rw-r--r-- | sc/qa/unit/ucalc.hxx | 6 | ||||
-rw-r--r-- | sc/qa/unit/ucalc_pivottable.cxx | 173 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/dpsave.cxx | 11 | ||||
-rw-r--r-- | sc/source/core/data/dptabres.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/data/dptabsrc.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/pivot2.cxx | 3 | ||||
-rw-r--r-- | sc/source/filter/xml/XMLExportDataPilot.cxx | 5 | ||||
-rw-r--r-- | sc/source/filter/xml/xmldpimp.cxx | 5 | ||||
-rw-r--r-- | sc/source/filter/xml/xmldpimp.hxx | 1 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.cxx | 1 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.hxx | 3 | ||||
-rw-r--r-- | sc/source/ui/dbgui/PivotLayoutDialog.cxx | 1 | ||||
-rw-r--r-- | sc/source/ui/dbgui/pvfundlg.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/inc/pvfundlg.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/unoobj/dapiuno.cxx | 25 | ||||
-rw-r--r-- | sc/uiconfig/scalc/ui/datafieldoptionsdialog.ui | 16 | ||||
-rw-r--r-- | xmloff/source/core/xmltoken.cxx | 1 |
24 files changed, 244 insertions, 50 deletions
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 1fb984f81b38..ef40853db536 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -2637,6 +2637,7 @@ namespace xmloff { namespace token { XML_DEFAULT_OUTLINE_LEVEL, XML_SHOW_DETAILS, XML_SHOW_EMPTY, + XML_REPEAT_ITEM_LABELS, XML_ITERATIVE, XML_uX, XML_NP_DLG, diff --git a/sc/inc/dapiuno.hxx b/sc/inc/dapiuno.hxx index f0347676608c..6bedada3aaf0 100644 --- a/sc/inc/dapiuno.hxx +++ b/sc/inc/dapiuno.hxx @@ -586,6 +586,8 @@ public: void setSortInfo(const com::sun::star::sheet::DataPilotFieldSortInfo* pInfo); bool getShowEmpty() const; void setShowEmpty(bool bShow); + bool getRepeatItemLabels() const; + void setRepeatItemLabels(bool bShow); bool hasGroupInfo(); com::sun::star::sheet::DataPilotFieldGroupInfo getGroupInfo(); diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx index c9bf960bfb8b..9b2136b0222c 100644 --- a/sc/inc/dpsave.hxx +++ b/sc/inc/dpsave.hxx @@ -106,6 +106,7 @@ private: sal_uInt16 nFunction; // enum GeneralFunction, for data dimensions long nUsedHierarchy; sal_uInt16 nShowEmptyMode; //! at level + bool bRepeatItemLabels; //! at level bool bSubTotalDefault; //! at level long nSubTotalCount; sal_uInt16* pSubTotalFuncs; // enum GeneralFunction @@ -162,6 +163,10 @@ public: bool GetShowEmpty() const { return bool(nShowEmptyMode); } + void SetRepeatItemLabels(bool bSet); + bool GetRepeatItemLabels() const + { return bRepeatItemLabels; } + void SetFunction(sal_uInt16 nNew); // enum GeneralFunction sal_uInt16 GetFunction() const { return nFunction; } diff --git a/sc/inc/dptabsrc.hxx b/sc/inc/dptabsrc.hxx index 016e7090663d..c07a242a0208 100644 --- a/sc/inc/dptabsrc.hxx +++ b/sc/inc/dptabsrc.hxx @@ -564,6 +564,7 @@ private: long nAutoMeasure; // measure (index of data dimension) for AutoShow bool bShowEmpty:1; bool bEnableLayout:1; // enabled only for row fields, not for the innermost one + bool bRepeatItemLabels:1; public: ScDPLevel( ScDPSource* pSrc, long nD, long nH, long nL ); @@ -635,6 +636,7 @@ public: com::sun::star::uno::Sequence<com::sun::star::sheet::GeneralFunction> getSubTotals() const; bool getShowEmpty() const { return bShowEmpty;} + bool getRepeatItemLabels() const { return bRepeatItemLabels; } const ::com::sun::star::sheet::DataPilotFieldSortInfo& GetSortInfo() const { return aSortInfo; } const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo& GetAutoShow() const { return aAutoShowInfo; } diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index 3fdabb29eb80..35e6e6081338 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -75,6 +75,7 @@ struct ScDPLabelData bool mbShowAll:1; ///< true = Show all (also empty) results. bool mbIsValue:1; ///< true = Sum or count in data field. bool mbDataLayout:1; + bool mbRepeatItemLabels:1; struct Member { diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx index f21ed9e06587..f02297ec84cf 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -261,6 +261,7 @@ #define SC_UNONAME_ISGROUP "IsGroupField" #define SC_UNONAME_GROUPINFO "GroupInfo" #define SC_UNONAME_SHOWEMPTY "ShowEmpty" +#define SC_UNONAME_REPEATITEMLABELS "RepeatItemLabels" // data pilot item #define SC_UNONAME_SHOWDETAIL "ShowDetail" @@ -577,6 +578,7 @@ #define SC_UNO_DP_FILTER "Filter" #define SC_UNO_DP_SUBTOTAL "SubTotals" #define SC_UNO_DP_SHOWEMPTY "ShowEmpty" +#define SC_UNO_DP_REPEATITEMLABELS "RepeatItemLabels" #define SC_UNO_DP_ISVISIBLE "IsVisible" #define SC_UNO_DP_SHOWDETAILS "ShowDetails" #define SC_UNO_DP_IGNOREEMPTY "IgnoreEmptyRows" diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index 66d281752a45..a60e478bf770 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -290,6 +290,11 @@ public: */ void testPivotTableDocFunc(); + /** + * Test pivot table per-field repeat item labels functionality + */ + void testPivotTableRepeatItemLabels(); + void testCellCopy(); void testSheetCopy(); void testSheetMove(); @@ -530,6 +535,7 @@ public: CPPUNIT_TEST(testPivotTableNumStability); CPPUNIT_TEST(testPivotTableFieldReference); CPPUNIT_TEST(testPivotTableDocFunc); + CPPUNIT_TEST(testPivotTableRepeatItemLabels); CPPUNIT_TEST(testCellCopy); CPPUNIT_TEST(testSheetCopy); CPPUNIT_TEST(testSheetMove); diff --git a/sc/qa/unit/ucalc_pivottable.cxx b/sc/qa/unit/ucalc_pivottable.cxx index 2e31241268b7..07b04ca96c59 100644 --- a/sc/qa/unit/ucalc_pivottable.cxx +++ b/sc/qa/unit/ucalc_pivottable.cxx @@ -38,6 +38,7 @@ struct DPFieldDef * default function (SUM) is used. */ int eFunc; + bool bRepeatItemLabels; }; template<size_t _Size> @@ -133,6 +134,7 @@ ScDPObject* createDPFromSourceDesc( aShowInfo.ShowItemsMode = 0; aShowInfo.ItemCount = 0; pDim->SetAutoShowInfo(&aShowInfo); + pDim->SetRepeatItemLabels(aFields[i].bRepeatItemLabels); } } @@ -189,9 +191,9 @@ void Test::testPivotTable() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Group", sheet::DataPilotFieldOrientation_COLUMN, 0 }, - { "Score", sheet::DataPilotFieldOrientation_DATA, 0 } + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Group", sheet::DataPilotFieldOrientation_COLUMN, 0, false }, + { "Score", sheet::DataPilotFieldOrientation_DATA, 0, false } }; // Raw data @@ -373,9 +375,9 @@ void Test::testPivotTableLabels() // Dimension definition DPFieldDef aFields[] = { - { "Software", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Version", sheet::DataPilotFieldOrientation_COLUMN, 0 }, - { "1.2.3", sheet::DataPilotFieldOrientation_DATA, 0 } + { "Software", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Version", sheet::DataPilotFieldOrientation_COLUMN, 0, false }, + { "1.2.3", sheet::DataPilotFieldOrientation_DATA, 0, false } }; // Raw data @@ -429,9 +431,9 @@ void Test::testPivotTableDateLabels() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Date", sheet::DataPilotFieldOrientation_COLUMN, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, 0 } + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Date", sheet::DataPilotFieldOrientation_COLUMN, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, 0, false } }; // Raw data @@ -505,11 +507,11 @@ void Test::testPivotTableFilters() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_HIDDEN, 0 }, - { "Group1", sheet::DataPilotFieldOrientation_HIDDEN, 0 }, - { "Group2", sheet::DataPilotFieldOrientation_PAGE, 0 }, - { "Val1", sheet::DataPilotFieldOrientation_DATA, 0 }, - { "Val2", sheet::DataPilotFieldOrientation_DATA, 0 } + { "Name", sheet::DataPilotFieldOrientation_HIDDEN, 0, false }, + { "Group1", sheet::DataPilotFieldOrientation_HIDDEN, 0, false }, + { "Group2", sheet::DataPilotFieldOrientation_PAGE, 0, false }, + { "Val1", sheet::DataPilotFieldOrientation_DATA, 0, false }, + { "Val2", sheet::DataPilotFieldOrientation_DATA, 0, false } }; // Raw data @@ -658,9 +660,9 @@ void Test::testPivotTableNamedSource() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Group", sheet::DataPilotFieldOrientation_COLUMN, 0 }, - { "Score", sheet::DataPilotFieldOrientation_DATA, 0 } + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Group", sheet::DataPilotFieldOrientation_COLUMN, 0, false }, + { "Score", sheet::DataPilotFieldOrientation_DATA, 0, false } }; // Raw data @@ -958,9 +960,9 @@ void Test::testPivotTableDuplicateDataFields() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_COUNT } + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_COUNT, false } }; ScAddress aPos(2,2,0); @@ -1052,8 +1054,8 @@ void Test::testPivotTableNormalGrouping() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; ScAddress aPos(1,1,0); @@ -1214,8 +1216,8 @@ void Test::testPivotTableNumberGrouping() // Dimension definition DPFieldDef aFields[] = { - { "Order", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Score", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Order", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Score", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; ScAddress aPos(1,1,0); @@ -1299,8 +1301,8 @@ void Test::testPivotTableDateGrouping() // Dimension definition DPFieldDef aFields[] = { - { "Date", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Date", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; ScAddress aPos(1,1,0); @@ -1469,8 +1471,8 @@ void Test::testPivotTableEmptyRows() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; ScAddress aPos(1,1,0); @@ -1582,8 +1584,8 @@ void Test::testPivotTableTextNumber() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; // Insert raw data such that the first column values are entered as text. @@ -1684,8 +1686,8 @@ void Test::testPivotTableCaseInsensitiveStrings() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; ScAddress aPos(1,1,0); @@ -1760,8 +1762,8 @@ void Test::testPivotTableNumStability() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Total", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Total", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; m_pDoc->InsertTab(0, OUString("Data")); @@ -1847,8 +1849,8 @@ void Test::testPivotTableFieldReference() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; ScAddress aPos(1,1,0); @@ -2017,8 +2019,8 @@ void Test::testPivotTableDocFunc() // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; ScAddress aPos(1,1,0); @@ -2093,8 +2095,8 @@ void Test::testFuncGETPIVOTDATA() { // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; pDPObj = createDPFromRange(m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false); @@ -2156,9 +2158,9 @@ void Test::testFuncGETPIVOTDATA() { // Dimension definition DPFieldDef aFields[] = { - { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_COUNT }, + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_COUNT, false }, }; pDPObj = createDPFromRange(m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false); @@ -2250,9 +2252,9 @@ void Test::testFuncGETPIVOTDATALeafAccess() // Dimension definition DPFieldDef aFields[] = { - { "Type", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Member", sheet::DataPilotFieldOrientation_ROW, 0 }, - { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + { "Type", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Member", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Value", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM, false }, }; // Create pivot table at A1 on 2nd sheet. @@ -2321,4 +2323,83 @@ void Test::testFuncGETPIVOTDATALeafAccess() m_pDoc->DeleteTab(0); } +void Test::testPivotTableRepeatItemLabels() +{ + m_pDoc->InsertTab(0, OUString("Data")); + m_pDoc->InsertTab(1, OUString("Table")); + + // Dimension definition + DPFieldDef aFields[] = { + { "Name", sheet::DataPilotFieldOrientation_ROW, 0, true }, + { "Country", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Year", sheet::DataPilotFieldOrientation_ROW, 0, false }, + { "Score", sheet::DataPilotFieldOrientation_DATA, 0, false } + }; + + // Raw data + const char* aData[][4] = { + { "Andy", "US", "1999", "30" }, + { "Andy", "US", "2002", "20" }, + { "Andy", "US", "2010", "45" }, + { "David", "GB", "1998", "12" }, + { "Edward", "NO", "2000", "8" }, + { "Frank", "FR", "2009", "15" }, + { "Frank", "FR", "2008", "45" }, + { "Frank", "FR", "2007", "45" }, + }; + + size_t nFieldCount = SAL_N_ELEMENTS(aFields); + size_t nDataCount = SAL_N_ELEMENTS(aData); + + ScRange aSrcRange = insertDPSourceData(m_pDoc, aFields, nFieldCount, aData, nDataCount); + SCROW nRow1 = aSrcRange.aStart.Row(), nRow2 = aSrcRange.aEnd.Row(); + SCCOL nCol1 = aSrcRange.aStart.Col(), nCol2 = aSrcRange.aEnd.Col(); + + ScDPObject* pDPObj = createDPFromRange( + m_pDoc, ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0), aFields, nFieldCount, false); + + ScDPCollection* pDPs = m_pDoc->GetDPCollection(); + bool bSuccess = pDPs->InsertNewTable(pDPObj); + CPPUNIT_ASSERT_MESSAGE("failed to insert a new datapilot object into document", bSuccess); + CPPUNIT_ASSERT_MESSAGE("there should be only one data pilot table.", + pDPs->GetCount() == 1); + pDPObj->SetName(pDPs->CreateNewName()); + + bool bOverflow = false; + ScRange aOutRange = pDPObj->GetNewOutputRange(bOverflow); + CPPUNIT_ASSERT_MESSAGE("Table overflow!?", !bOverflow); + + pDPObj->Output(aOutRange.aStart); + aOutRange = pDPObj->GetOutRange(); + { + // Expected output table content. 0 = empty cell + const char* aOutputCheck[][4] = { + { "Name", "Country", "Year", "Sum - Score" }, + { "Andy", "US", "1999", "30" }, + { "Andy", 0, "2002", "20" }, + { "Andy", 0, "2010", "45" }, + { "David", "GB", "1998", "12" }, + { "Edward", "NO", "2000", "8" }, + { "Frank", "FR", "2007", "45" }, + { "Frank", 0, "2008", "45" }, + { "Frank", 0, "2009", "15" }, + { "Total Result", 0, 0, "220" } + }; + + bSuccess = checkDPTableOutput<4>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output"); + CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess); + } + + CPPUNIT_ASSERT_MESSAGE("There should be only one data cache.", pDPs->GetSheetCaches().size() == 1); + + pDPs->FreeTable(pDPObj); + CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0)); + CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.", + pDPs->GetSheetCaches().size(), static_cast<size_t>(0)); + + m_pDoc->DeleteTab(1); + m_pDoc->DeleteTab(0); +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 5e9fd6893839..09bacb77e07b 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -2275,6 +2275,9 @@ static void lcl_FillLabelData( ScDPLabelData& rData, const uno::Reference< beans rData.mbShowAll = ScUnoHelpFunctions::GetBoolProperty( xLevProp, OUString(SC_UNO_DP_SHOWEMPTY)); + rData.mbRepeatItemLabels = ScUnoHelpFunctions::GetBoolProperty( + xLevProp, OUString(SC_UNO_DP_REPEATITEMLABELS)); + try { xLevProp->getPropertyValue( OUString( SC_UNO_DP_SORTING ) ) diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index 0fb2b3dad592..7819edd062fd 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -199,6 +199,7 @@ ScDPSaveDimension::ScDPSaveDimension(const OUString& rName, bool bDataLayout) : nFunction( sheet::GeneralFunction_AUTO ), nUsedHierarchy( -1 ), nShowEmptyMode( SC_DPSAVEMODE_DONTKNOW ), + bRepeatItemLabels( false ), bSubTotalDefault( true ), nSubTotalCount( 0 ), pSubTotalFuncs( NULL ), @@ -219,6 +220,7 @@ ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) : nFunction( r.nFunction ), nUsedHierarchy( r.nUsedHierarchy ), nShowEmptyMode( r.nShowEmptyMode ), + bRepeatItemLabels( r.bRepeatItemLabels ), bSubTotalDefault( r.bSubTotalDefault ), nSubTotalCount( r.nSubTotalCount ), pSubTotalFuncs( NULL ) @@ -279,6 +281,7 @@ bool ScDPSaveDimension::operator== ( const ScDPSaveDimension& r ) const nFunction != r.nFunction || nUsedHierarchy != r.nUsedHierarchy || nShowEmptyMode != r.nShowEmptyMode || + bRepeatItemLabels!= r.bRepeatItemLabels|| bSubTotalDefault != r.bSubTotalDefault || nSubTotalCount != r.nSubTotalCount ) return false; @@ -395,6 +398,11 @@ void ScDPSaveDimension::SetShowEmpty(bool bSet) nShowEmptyMode = sal_uInt16(bSet); } +void ScDPSaveDimension::SetRepeatItemLabels(bool bSet) +{ + bRepeatItemLabels = bSet; +} + void ScDPSaveDimension::SetFunction(sal_uInt16 nNew) { nFunction = nNew; @@ -626,6 +634,9 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD lcl_SetBoolProperty( xLevProp, OUString(SC_UNO_DP_SHOWEMPTY), (bool)nShowEmptyMode ); + lcl_SetBoolProperty( xLevProp, + OUString(SC_UNO_DP_REPEATITEMLABELS), bRepeatItemLabels ); + if ( pSortInfo ) ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_SORTING, *pSortInfo); diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx index cd78a5d2c5b8..0aeeb3551d7e 100644 --- a/sc/source/core/data/dptabres.cxx +++ b/sc/source/core/data/dptabres.cxx @@ -1368,6 +1368,7 @@ void ScDPResultMember::FillMemberResults( else pArray[rPos].Flags &= ~sheet::MemberResultFlags::NUMERIC; + const ScDPLevel* pParentLevel = GetParentLevel(); if ( nSize && !bRoot ) // root is overwritten by first dimension { pArray[rPos].Name = aName; @@ -1377,9 +1378,20 @@ void ScDPResultMember::FillMemberResults( // set "continue" flag (removed for subtotals later) for (long i=1; i<nSize; i++) pArray[rPos+i].Flags |= sheet::MemberResultFlags::CONTINUE; + if ( pParentLevel && pParentLevel->getRepeatItemLabels() ) + { + long nSizeNonEmpty = nSize; + if ( pParentLevel->IsAddEmpty() ) + --nSizeNonEmpty; + for (long i=1; i<nSizeNonEmpty; i++) + { + pArray[rPos+i].Name = aName; + pArray[rPos+i].Caption = aCaption; + pArray[rPos+i].Flags |= sheet::MemberResultFlags::HASMEMBER; + } + } } - const ScDPLevel* pParentLevel = GetParentLevel(); long nExtraSpace = 0; if ( pParentLevel && pParentLevel->IsAddEmpty() ) ++nExtraSpace; diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx index f5a57b942602..58e7d70d8f2e 100644 --- a/sc/source/core/data/dptabsrc.cxx +++ b/sc/source/core/data/dptabsrc.cxx @@ -2015,7 +2015,8 @@ ScDPLevel::ScDPLevel( ScDPSource* pSrc, long nD, long nH, long nL ) : nSortMeasure( 0 ), nAutoMeasure( 0 ), bShowEmpty( false ), - bEnableLayout( false ) + bEnableLayout( false ), + bRepeatItemLabels( false ) { //TODO: hold pSource // aSubTotals is empty @@ -2201,6 +2202,7 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPLevel::getPropertySetInfo() { OUString(SC_UNO_DP_AUTOSHOW), 0, cppu::UnoType<sheet::DataPilotFieldAutoShowInfo>::get(), 0, 0 }, { OUString(SC_UNO_DP_LAYOUT), 0, cppu::UnoType<sheet::DataPilotFieldLayoutInfo>::get(), 0, 0 }, { OUString(SC_UNO_DP_SHOWEMPTY), 0, getBooleanCppuType(), 0, 0 }, + { OUString(SC_UNO_DP_REPEATITEMLABELS), 0, getBooleanCppuType(), 0, 0 }, { OUString(SC_UNO_DP_SORTING), 0, cppu::UnoType<sheet::DataPilotFieldSortInfo>::get(), 0, 0 }, { OUString(SC_UNO_DP_SUBTOTAL), 0, getCppuType((uno::Sequence<sheet::GeneralFunction>*)0), 0, 0 }, { OUString(), 0, css::uno::Type(), 0, 0 } @@ -2217,6 +2219,8 @@ void SAL_CALL ScDPLevel::setPropertyValue( const OUString& aPropertyName, const { if ( aPropertyName == SC_UNO_DP_SHOWEMPTY ) bShowEmpty = lcl_GetBoolFromAny(aValue); + else if ( aPropertyName == SC_UNO_DP_REPEATITEMLABELS ) + bRepeatItemLabels = lcl_GetBoolFromAny(aValue); else if ( aPropertyName == SC_UNO_DP_SUBTOTAL ) aValue >>= aSubTotals; else if ( aPropertyName == SC_UNO_DP_SORTING ) @@ -2238,6 +2242,8 @@ uno::Any SAL_CALL ScDPLevel::getPropertyValue( const OUString& aPropertyName ) uno::Any aRet; if ( aPropertyName == SC_UNO_DP_SHOWEMPTY ) lcl_SetBoolInAny(aRet, bShowEmpty); + if ( aPropertyName == SC_UNO_DP_REPEATITEMLABELS ) + lcl_SetBoolInAny(aRet, bRepeatItemLabels); else if ( aPropertyName == SC_UNO_DP_SUBTOTAL ) { uno::Sequence<sheet::GeneralFunction> aSeq = getSubTotals(); //TODO: avoid extra copy? diff --git a/sc/source/core/data/pivot2.cxx b/sc/source/core/data/pivot2.cxx index 93f327e9947b..d0ae6ccc2205 100644 --- a/sc/source/core/data/pivot2.cxx +++ b/sc/source/core/data/pivot2.cxx @@ -92,7 +92,8 @@ ScDPLabelData::ScDPLabelData() : mnDupCount(0), mbShowAll(false), mbIsValue(false), - mbDataLayout(false) + mbDataLayout(false), + mbRepeatItemLabels(false) {} OUString ScDPLabelData::getDisplayName() const diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index 8946070603af..e175408e3c8b 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -493,6 +493,11 @@ void ScXMLExportDataPilot::WriteLevels(ScDPSaveDimension* pDim) ::sax::Converter::convertBool(sBuffer, pDim->GetShowEmpty()); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, sBuffer.makeStringAndClear()); } + { + OUStringBuffer sBuffer; + ::sax::Converter::convertBool(sBuffer, pDim->GetRepeatItemLabels()); + rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_REPEAT_ITEM_LABELS, sBuffer.makeStringAndClear()); + } SvXMLElementExport aElemDPL(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_LEVEL, true, true); WriteSubTotals(pDim); diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index ac19a32775f9..ca44604f464f 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -1264,6 +1264,11 @@ ScXMLDataPilotLevelContext::ScXMLDataPilotLevelContext( ScXMLImport& rImport, pDataPilotField->SetShowEmpty(IsXMLToken(sValue, XML_TRUE)); } break; + case XML_TOK_DATA_PILOT_LEVEL_ATTR_REPEAT_ITEM_LABELS : + { + pDataPilotField->SetRepeatItemLabels(IsXMLToken(sValue, XML_TRUE)); + } + break; } } } diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx index 626a0538324c..ff006f3245c4 100644 --- a/sc/source/filter/xml/xmldpimp.hxx +++ b/sc/source/filter/xml/xmldpimp.hxx @@ -361,6 +361,7 @@ public: virtual void EndElement() SAL_OVERRIDE; void SetShowEmpty(const bool bValue) { if (pDim) pDim->SetShowEmpty(bValue); } + void SetRepeatItemLabels(const bool bSet) { if (pDim) pDim->SetRepeatItemLabels(bSet); } void SetSubTotals(const sal_uInt16* pFunctions, const sal_Int16 nCount) { if(pDim) pDim->SetSubTotals(nCount, pFunctions); } void AddMember(ScDPSaveMember* pMember); void SetSubTotalName(const OUString& rName); diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx index 2e589023258e..8930c363376f 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -1714,6 +1714,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotLevelAttrTokenMap() static const SvXMLTokenMapEntry aDataPilotLevelAttrTokenMap[] = { { XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY }, + { XML_NAMESPACE_CALC_EXT, XML_REPEAT_ITEM_LABELS, XML_TOK_DATA_PILOT_LEVEL_ATTR_REPEAT_ITEM_LABELS }, XML_TOKEN_MAP_END }; diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx index 5ceeb72b5d2b..09adfacf0666 100644 --- a/sc/source/filter/xml/xmlimprt.hxx +++ b/sc/source/filter/xml/xmlimprt.hxx @@ -650,7 +650,8 @@ enum ScXMLDataPilotFieldElemTokens enum ScXMLDataPilotLevelAttrTokens { - XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY + XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY, + XML_TOK_DATA_PILOT_LEVEL_ATTR_REPEAT_ITEM_LABELS }; enum ScXMLDataPilotLevelElemTokens diff --git a/sc/source/ui/dbgui/PivotLayoutDialog.cxx b/sc/source/ui/dbgui/PivotLayoutDialog.cxx index b5d2c658e352..c8087b39920f 100644 --- a/sc/source/ui/dbgui/PivotLayoutDialog.cxx +++ b/sc/source/ui/dbgui/PivotLayoutDialog.cxx @@ -538,6 +538,7 @@ void ScPivotLayoutDialog::ApplyLabelData(ScDPSaveData& rSaveData) pSaveDimensions->SetUsedHierarchy(pLabelData.mnUsedHier); pSaveDimensions->SetShowEmpty(pLabelData.mbShowAll); + pSaveDimensions->SetRepeatItemLabels(pLabelData.mbRepeatItemLabels); pSaveDimensions->SetSortInfo(&pLabelData.maSortInfo); pSaveDimensions->SetLayoutInfo(&pLabelData.maLayoutInfo); pSaveDimensions->SetAutoShowInfo(&pLabelData.maShowInfo); diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index 8f5c24bd15e9..3f55a4be76d9 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -452,6 +452,7 @@ void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const rLabelData.maSortInfo = maLabelData.maSortInfo; rLabelData.maLayoutInfo = maLabelData.maLayoutInfo; rLabelData.maShowInfo = maLabelData.maShowInfo; + rLabelData.mbRepeatItemLabels = maLabelData.mbRepeatItemLabels; } void ScDPSubtotalDlg::Init( const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData ) @@ -524,6 +525,7 @@ ScDPSubtotalOptDlg::ScDPSubtotalOptDlg( vcl::Window* pParent, ScDPObject& rDPObj get(m_pLayoutFrame, "layoutframe"); get(m_pLbLayout, "layout"); get(m_pCbLayoutEmpty, "emptyline"); + get(m_pCbRepeatItemLabels, "repeatitemlabels"); get(m_pCbShow, "show"); get(m_pNfShow, "items"); get(m_pFtShow, "showft"); @@ -566,6 +568,7 @@ void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const rLabelData.maLayoutInfo.LayoutMode = m_xLbLayoutWrp->GetControlValue(); rLabelData.maLayoutInfo.AddEmptyLines = m_pCbLayoutEmpty->IsChecked(); + rLabelData.mbRepeatItemLabels = m_pCbRepeatItemLabels->IsChecked(); // *** AUTO SHOW *** @@ -648,6 +651,7 @@ void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayou m_xLbLayoutWrp->SetControlValue( maLabelData.maLayoutInfo.LayoutMode ); m_pCbLayoutEmpty->Check( maLabelData.maLayoutInfo.AddEmptyLines ); + m_pCbRepeatItemLabels->Check( maLabelData.mbRepeatItemLabels ); // *** AUTO SHOW *** diff --git a/sc/source/ui/inc/pvfundlg.hxx b/sc/source/ui/inc/pvfundlg.hxx index 8a0fc1b750e0..4718e5e5e026 100644 --- a/sc/source/ui/inc/pvfundlg.hxx +++ b/sc/source/ui/inc/pvfundlg.hxx @@ -160,6 +160,7 @@ private: VclContainer* m_pLayoutFrame; ListBox* m_pLbLayout; CheckBox* m_pCbLayoutEmpty; + CheckBox* m_pCbRepeatItemLabels; CheckBox* m_pCbShow; NumericField* m_pNfShow; FixedText* m_pFtShow; diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index abdec8b54a49..83637c56a6db 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -125,6 +125,7 @@ const SfxItemPropertyMapEntry* lcl_GetDataPilotFieldMap() {OUString(SC_UNONAME_REFERENCE), 0, cppu::UnoType<DataPilotFieldReference>::get(), MAYBEVOID, 0 }, {OUString(SC_UNONAME_SELPAGE), 0, cppu::UnoType<OUString>::get(), 0, 0 }, {OUString(SC_UNONAME_SHOWEMPTY), 0, getBooleanCppuType(), 0, 0 }, + {OUString(SC_UNONAME_REPEATITEMLABELS), 0, getBooleanCppuType(), 0, 0 }, {OUString(SC_UNONAME_SORTINFO), 0, cppu::UnoType<DataPilotFieldSortInfo>::get(), MAYBEVOID, 0 }, {OUString(SC_UNONAME_SUBTOTALS), 0, getCppuType((Sequence<GeneralFunction>*)0), 0, 0 }, {OUString(SC_UNONAME_USESELPAGE), 0, getBooleanCppuType(), 0, 0 }, @@ -1955,6 +1956,10 @@ void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyNa { setShowEmpty(cppu::any2bool(aValue)); } + else if ( aNameString == SC_UNONAME_REPEATITEMLABELS ) + { + setRepeatItemLabels(cppu::any2bool(aValue)); + } } Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyName ) @@ -2015,6 +2020,8 @@ Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyNam } else if ( aNameString == SC_UNONAME_SHOWEMPTY ) aRet <<= getShowEmpty(); + else if ( aNameString == SC_UNONAME_REPEATITEMLABELS ) + aRet <<= getRepeatItemLabels(); return aRet; } @@ -2334,6 +2341,24 @@ void ScDataPilotFieldObj::setShowEmpty( bool bShow ) } } +bool ScDataPilotFieldObj::getRepeatItemLabels() const +{ + SolarMutexGuard aGuard; + ScDPSaveDimension* pDim = GetDPDimension(); + return pDim && pDim->GetRepeatItemLabels(); +} + +void ScDataPilotFieldObj::setRepeatItemLabels( bool bShow ) +{ + SolarMutexGuard aGuard; + ScDPObject* pDPObj = 0; + if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) ) + { + pDim->SetRepeatItemLabels( bShow ); + SetDPObject( pDPObj ); + } +} + bool ScDataPilotFieldObj::hasGroupInfo() { SolarMutexGuard aGuard; diff --git a/sc/uiconfig/scalc/ui/datafieldoptionsdialog.ui b/sc/uiconfig/scalc/ui/datafieldoptionsdialog.ui index 9cf3040e8361..26f7b8fea307 100644 --- a/sc/uiconfig/scalc/ui/datafieldoptionsdialog.ui +++ b/sc/uiconfig/scalc/ui/datafieldoptionsdialog.ui @@ -209,6 +209,22 @@ <property name="row_spacing">6</property> <property name="column_spacing">12</property> <child> + <object class="GtkCheckButton" id="repeatitemlabels"> + <property name="label" translatable="yes">_Repeat item labels</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">2</property> + </packing> + </child> + <child> <object class="GtkCheckButton" id="emptyline"> <property name="label" translatable="yes">_Empty line after each item</property> <property name="visible">True</property> diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 91d20c5afa96..e651e1bb8315 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -2641,6 +2641,7 @@ namespace xmloff { namespace token { TOKEN( "default-outline-level", XML_DEFAULT_OUTLINE_LEVEL ), TOKEN( "show-details", XML_SHOW_DETAILS ), TOKEN( "show-empty", XML_SHOW_EMPTY ), + TOKEN( "repeat-item-labels", XML_REPEAT_ITEM_LABELS ), TOKEN( "iterative", XML_ITERATIVE ), TOKEN( "X", XML_uX ), |