[Libreoffice-commits] core.git: include/xmloff sc/inc sc/qa sc/source sc/uiconfig xmloff/source

Deena Francis deena.francis at gmail.com
Wed Mar 11 18:18:32 PDT 2015


 include/xmloff/xmltoken.hxx                    |    1 
 sc/inc/dapiuno.hxx                             |    2 
 sc/inc/dpsave.hxx                              |    5 
 sc/inc/dptabsrc.hxx                            |    2 
 sc/inc/pivot.hxx                               |    1 
 sc/inc/unonames.hxx                            |    2 
 sc/qa/unit/ucalc.hxx                           |    6 
 sc/qa/unit/ucalc_pivottable.cxx                |  173 ++++++++++++++++++-------
 sc/source/core/data/dpobject.cxx               |    3 
 sc/source/core/data/dpsave.cxx                 |   11 +
 sc/source/core/data/dptabres.cxx               |   14 +-
 sc/source/core/data/dptabsrc.cxx               |    8 +
 sc/source/core/data/pivot2.cxx                 |    3 
 sc/source/filter/xml/XMLExportDataPilot.cxx    |    5 
 sc/source/filter/xml/xmldpimp.cxx              |    5 
 sc/source/filter/xml/xmldpimp.hxx              |    1 
 sc/source/filter/xml/xmlimprt.cxx              |    1 
 sc/source/filter/xml/xmlimprt.hxx              |    3 
 sc/source/ui/dbgui/PivotLayoutDialog.cxx       |    1 
 sc/source/ui/dbgui/pvfundlg.cxx                |    4 
 sc/source/ui/inc/pvfundlg.hxx                  |    1 
 sc/source/ui/unoobj/dapiuno.cxx                |   25 +++
 sc/uiconfig/scalc/ui/datafieldoptionsdialog.ui |   16 ++
 xmloff/source/core/xmltoken.cxx                |    1 
 24 files changed, 244 insertions(+), 50 deletions(-)

New commits:
commit 7b355da6853af6678c4ba22710d157cf8a6d43eb
Author: Deena Francis <deena.francis at gmail.com>
Date:   Mon Feb 16 22:28:52 2015 +0530

    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 at libreoffice.org>
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
    Tested-by: Kohei Yoshida <libreoffice at kohei.us>

diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 1fb984f..ef40853 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 f034767..6bedada 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 c9bf960..9b2136b 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 016e709..c07a242 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 3fdabb2..35e6e60 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 f21ed9e0..f02297e 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 66d2817..a60e478 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 2e31241..07b04ca 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 5e9fd68..09bacb7 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 0fb2b3d..7819edd 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 cd78a5d..0aeeb35 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 f5a57b9..58e7d70 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 93f327e..d0ae6cc 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 8946070..e175408 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 ac19a327..ca44604 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 626a053..ff006f3 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 2e58902..8930c36 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 5ceeb72..09adfac 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 b5d2c65..c8087b3 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 8f5c24b..3f55a4b 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 8a0fc1b..4718e5e 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 abdec8b..83637c5 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 9cf3040..26f7b8f 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 91d20c5..e651e1b 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 ),


More information about the Libreoffice-commits mailing list