kbrown / rpms / libreoffice

Forked from rpms/libreoffice 2 years ago
Clone

Blame SOURCES/0040-fdo-69984-Handle-duplicate-field-names-correctly.patch

f0633d
From 2ea5c1b6dd1d8fda41c1c1fdc3cf994c4f9e5895 Mon Sep 17 00:00:00 2001
f0633d
From: Kohei Yoshida <kohei.yoshida@collabora.com>
f0633d
Date: Thu, 5 Dec 2013 15:37:10 -0500
f0633d
Subject: [PATCH 040/109] fdo#69984: Handle duplicate field names correctly.
f0633d
f0633d
Duplicate field names are represented in two ways: 1) 'Name' vs 'Name*' in
f0633d
the UNO part of the pivot engine, and 2) Name,0 vs Name,1 which are a pair
f0633d
of textural name and a numeric duplicate index in the non-UNO part of the
f0633d
engine.  But some parts lost this duplicate index information and/or confused
f0633d
the 2 ways of representation.  Hopefully this change will sort things out.
f0633d
f0633d
(cherry picked from commit 7e491281d2ba71490fa22cce1e43ba91f60395e3)
f0633d
f0633d
Conflicts:
f0633d
	sc/inc/pivot.hxx
f0633d
f0633d
Change-Id: I03ae7b6c011c31ace454679837542d6d0909ecaa
f0633d
Reviewed-on: https://gerrit.libreoffice.org/6944
f0633d
Reviewed-by: Eike Rathke <erack@redhat.com>
f0633d
Tested-by: Eike Rathke <erack@redhat.com>
f0633d
---
f0633d
 sc/inc/dputil.hxx                |  8 +++++++-
f0633d
 sc/inc/pivot.hxx                 | 26 ++++++++++++++------------
f0633d
 sc/source/core/data/dpobject.cxx |  6 ++++++
f0633d
 sc/source/core/data/dputil.cxx   | 21 +++++++++++++++++++++
f0633d
 sc/source/core/data/pivot2.cxx   |  7 ++++---
f0633d
 sc/source/ui/dbgui/pvfundlg.cxx  | 34 +++++++++++++++++++++++-----------
f0633d
 sc/source/ui/dbgui/pvlaydlg.cxx  |  7 +++++--
f0633d
 sc/source/ui/inc/pvfundlg.hxx    |  4 ++--
f0633d
 8 files changed, 82 insertions(+), 31 deletions(-)
f0633d
f0633d
diff --git a/sc/inc/dputil.hxx b/sc/inc/dputil.hxx
f0633d
index 294ca97..e4ed831 100644
f0633d
--- a/sc/inc/dputil.hxx
f0633d
+++ b/sc/inc/dputil.hxx
f0633d
@@ -26,7 +26,13 @@ public:
f0633d
 
f0633d
     SC_DLLPUBLIC static OUString getSourceDimensionName(const OUString& rName);
f0633d
 
f0633d
-    static OUString createDuplicateDimensionName(const OUString& rOriginal, size_t nDupCount);
f0633d
+    /**
f0633d
+     * Get a duplicate index in case the dimension is a duplicate.  It returns
f0633d
+     * 0 in case it's an original dimension.
f0633d
+     */
f0633d
+    sal_uInt8 static getDuplicateIndex(const OUString& rName);
f0633d
+
f0633d
+    SC_DLLPUBLIC static OUString createDuplicateDimensionName(const OUString& rOriginal, size_t nDupCount);
f0633d
 
f0633d
     static OUString getDateGroupName(
f0633d
         sal_Int32 nDatePart, sal_Int32 nValue, SvNumberFormatter* pFormatter,
f0633d
diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx
f0633d
index 85e19e0..a1e063f 100644
f0633d
--- a/sc/inc/pivot.hxx
f0633d
+++ b/sc/inc/pivot.hxx
f0633d
@@ -52,13 +52,14 @@
f0633d
 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
f0633d
 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
f0633d
 
f0633d
-
f0633d
-struct ScDPName
f0633d
+struct SC_DLLPUBLIC ScDPName
f0633d
 {
f0633d
-    OUString     maName;         /// Original name of the dimension.
f0633d
-    OUString     maLayoutName;   /// Layout name (display name)
f0633d
+    OUString     maName;         ///< Original name of the dimension.
f0633d
+    OUString     maLayoutName;   ///< Layout name (display name)
f0633d
+    sal_uInt8 mnDupCount;
f0633d
 
f0633d
-    explicit ScDPName(const OUString& rName, const OUString& rLayoutName);
f0633d
+    ScDPName();
f0633d
+    explicit ScDPName(const OUString& rName, const OUString& rLayoutName, sal_uInt8 nDupCount);
f0633d
 };
f0633d
 
f0633d
 // ============================================================================
f0633d
@@ -68,13 +69,14 @@ struct ScDPLabelData
f0633d
     OUString       maName;         /// Original name of the dimension.
f0633d
     OUString       maLayoutName;   /// Layout name (display name)
f0633d
     OUString       maSubtotalName;
f0633d
-    SCCOL               mnCol;          /// 0-based field index (not the source column index)
f0633d
-    long                mnOriginalDim;  /// original dimension index (>= 0 for duplicated dimension)
f0633d
-    sal_uInt16          mnFuncMask;     /// Page/Column/Row subtotal function.
f0633d
-    sal_Int32           mnUsedHier;     /// Used hierarchy.
f0633d
-    sal_Int32           mnFlags;        /// Flags from the DataPilotSource dimension
f0633d
-    bool                mbShowAll:1;    /// true = Show all (also empty) results.
f0633d
-    bool                mbIsValue:1;    /// true = Sum or count in data field.
f0633d
+    SCCOL               mnCol;          ///< 0-based field index (not the source column index)
f0633d
+    long                mnOriginalDim;  ///< original dimension index (>= 0 for duplicated dimension)
f0633d
+    sal_uInt16          mnFuncMask;     ///< Page/Column/Row subtotal function.
f0633d
+    sal_Int32           mnUsedHier;     ///< Used hierarchy.
f0633d
+    sal_Int32           mnFlags;        ///< Flags from the DataPilotSource dimension
f0633d
+    sal_uInt8           mnDupCount;
f0633d
+    bool                mbShowAll:1;    ///< true = Show all (also empty) results.
f0633d
+    bool                mbIsValue:1;    ///< true = Sum or count in data field.
f0633d
     bool                mbDataLayout:1;
f0633d
 
f0633d
     struct Member
f0633d
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
f0633d
index fba73d6..3a45a34 100644
f0633d
--- a/sc/source/core/data/dpobject.cxx
f0633d
+++ b/sc/source/core/data/dpobject.cxx
f0633d
@@ -2278,10 +2278,16 @@ bool ScDPObject::FillLabelDataForDimension(
f0633d
         xDimProp, OUString(SC_UNO_DP_FIELD_SUBTOTALNAME), OUString());
f0633d
 
f0633d
     bool bIsValue = true;                               //! check
f0633d
+
f0633d
+    // Name from the UNO dimension object may have trailing '*'s in which
f0633d
+    // case it's a duplicate dimension. Convert that to a duplicate index.
f0633d
+
f0633d
+    sal_uInt8 nDupCount = ScDPUtil::getDuplicateIndex(aFieldName);
f0633d
     aFieldName = ScDPUtil::getSourceDimensionName(aFieldName);
f0633d
 
f0633d
     rLabelData.maName = aFieldName;
f0633d
     rLabelData.mnCol = static_cast<SCCOL>(nDim);
f0633d
+    rLabelData.mnDupCount = nDupCount;
f0633d
     rLabelData.mbDataLayout = bData;
f0633d
     rLabelData.mbIsValue = bIsValue;
f0633d
 
f0633d
diff --git a/sc/source/core/data/dputil.cxx b/sc/source/core/data/dputil.cxx
f0633d
index d1fc655..e34bc79 100644
f0633d
--- a/sc/source/core/data/dputil.cxx
f0633d
+++ b/sc/source/core/data/dputil.cxx
f0633d
@@ -68,6 +68,27 @@ OUString ScDPUtil::getSourceDimensionName(const OUString& rName)
f0633d
     return comphelper::string::stripEnd(rName, '*');
f0633d
 }
f0633d
 
f0633d
+sal_uInt8 ScDPUtil::getDuplicateIndex(const OUString& rName)
f0633d
+{
f0633d
+    // Count all trailing '*'s.
f0633d
+
f0633d
+    sal_Int32 n = rName.getLength();
f0633d
+    if (!n)
f0633d
+        return 0;
f0633d
+
f0633d
+    sal_uInt8 nDupCount = 0;
f0633d
+    const sal_Unicode* p = rName.getStr();
f0633d
+    const sal_Unicode* pStart = p;
f0633d
+    p += n-1; // Set it to the last char.
f0633d
+    for (; p != pStart; --p, ++nDupCount)
f0633d
+    {
f0633d
+        if (*p != '*')
f0633d
+            break;
f0633d
+    }
f0633d
+
f0633d
+    return nDupCount;
f0633d
+}
f0633d
+
f0633d
 OUString ScDPUtil::createDuplicateDimensionName(const OUString& rOriginal, size_t nDupCount)
f0633d
 {
f0633d
     if (!nDupCount)
f0633d
diff --git a/sc/source/core/data/pivot2.cxx b/sc/source/core/data/pivot2.cxx
f0633d
index e8aed77..9460632 100644
f0633d
--- a/sc/source/core/data/pivot2.cxx
f0633d
+++ b/sc/source/core/data/pivot2.cxx
f0633d
@@ -58,10 +58,10 @@ bool equals(const DataPilotFieldReference& left, const DataPilotFieldReference&
f0633d
 
f0633d
 }
f0633d
 
f0633d
-// ============================================================================
f0633d
+ScDPName::ScDPName() : mnDupCount(0) {}
f0633d
 
f0633d
-ScDPName::ScDPName(const OUString& rName, const OUString& rLayoutName) :
f0633d
-    maName(rName), maLayoutName(rLayoutName) {}
f0633d
+ScDPName::ScDPName(const OUString& rName, const OUString& rLayoutName, sal_uInt8 nDupCount) :
f0633d
+    maName(rName), maLayoutName(rLayoutName), mnDupCount(nDupCount) {}
f0633d
 
f0633d
 // ============================================================================
f0633d
 
f0633d
@@ -85,6 +85,7 @@ ScDPLabelData::ScDPLabelData() :
f0633d
     mnFuncMask(PIVOT_FUNC_NONE),
f0633d
     mnUsedHier(0),
f0633d
     mnFlags(0),
f0633d
+    mnDupCount(0),
f0633d
     mbShowAll(false),
f0633d
     mbIsValue(false),
f0633d
     mbDataLayout(false)
f0633d
diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx
f0633d
index f9e468b..af369f4 100644
f0633d
--- a/sc/source/ui/dbgui/pvfundlg.cxx
f0633d
+++ b/sc/source/ui/dbgui/pvfundlg.cxx
f0633d
@@ -35,6 +35,7 @@
f0633d
 #include "dpsave.hxx"
f0633d
 #include "pvfundlg.hrc"
f0633d
 #include "globstr.hrc"
f0633d
+#include "dputil.hxx"
f0633d
 
f0633d
 #include <vector>
f0633d
 
f0633d
@@ -574,8 +575,13 @@ void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const
f0633d
     else
f0633d
         rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::DATA;
f0633d
 
f0633d
-    rLabelData.maSortInfo.Field = GetFieldName(maLbSortBy.GetSelectEntry());
f0633d
-    rLabelData.maSortInfo.IsAscending = maRbSortAsc.IsChecked();
f0633d
+    ScDPName aFieldName = GetFieldName(maLbSortBy.GetSelectEntry());
f0633d
+    if (!aFieldName.maName.isEmpty())
f0633d
+    {
f0633d
+        rLabelData.maSortInfo.Field =
f0633d
+            ScDPUtil::createDuplicateDimensionName(aFieldName.maName, aFieldName.mnDupCount);
f0633d
+        rLabelData.maSortInfo.IsAscending = maRbSortAsc.IsChecked();
f0633d
+    }
f0633d
 
f0633d
     // *** LAYOUT MODE ***
f0633d
 
f0633d
@@ -584,10 +590,15 @@ void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const
f0633d
 
f0633d
     // *** AUTO SHOW ***
f0633d
 
f0633d
-    rLabelData.maShowInfo.IsEnabled = maCbShow.IsChecked();
f0633d
-    rLabelData.maShowInfo.ShowItemsMode = maLbShowFromWrp.GetControlValue();
f0633d
-    rLabelData.maShowInfo.ItemCount = sal::static_int_cast<sal_Int32>( maNfShow.GetValue() );
f0633d
-    rLabelData.maShowInfo.DataField = GetFieldName(maLbShowUsing.GetSelectEntry());
f0633d
+    aFieldName = GetFieldName(maLbShowUsing.GetSelectEntry());
f0633d
+    if (!aFieldName.maName.isEmpty())
f0633d
+    {
f0633d
+        rLabelData.maShowInfo.IsEnabled = maCbShow.IsChecked();
f0633d
+        rLabelData.maShowInfo.ShowItemsMode = maLbShowFromWrp.GetControlValue();
f0633d
+        rLabelData.maShowInfo.ItemCount = sal::static_int_cast<sal_Int32>( maNfShow.GetValue() );
f0633d
+        rLabelData.maShowInfo.DataField =
f0633d
+            ScDPUtil::createDuplicateDimensionName(aFieldName.maName, aFieldName.mnDupCount);
f0633d
+    }
f0633d
 
f0633d
     // *** HIDDEN ITEMS ***
f0633d
 
f0633d
@@ -613,7 +624,7 @@ void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayou
f0633d
     for( ScDPNameVec::const_iterator aIt = rDataFields.begin(), aEnd = rDataFields.end(); aIt != aEnd; ++aIt )
f0633d
     {
f0633d
         // Cache names for later lookup.
f0633d
-        maDataFieldNameMap.insert(NameMapType::value_type(aIt->maLayoutName, aIt->maName));
f0633d
+        maDataFieldNameMap.insert(NameMapType::value_type(aIt->maLayoutName, *aIt));
f0633d
 
f0633d
         maLbSortBy.InsertEntry( aIt->maLayoutName );
f0633d
         maLbShowUsing.InsertEntry( aIt->maLayoutName );  // for AutoShow
f0633d
@@ -714,10 +725,10 @@ void ScDPSubtotalOptDlg::InitHideListBox()
f0633d
     maLbHide.Enable( bEnable );
f0633d
 }
f0633d
 
f0633d
-const OUString& ScDPSubtotalOptDlg::GetFieldName(const OUString& rLayoutName) const
f0633d
+ScDPName ScDPSubtotalOptDlg::GetFieldName(const OUString& rLayoutName) const
f0633d
 {
f0633d
     NameMapType::const_iterator itr = maDataFieldNameMap.find(rLayoutName);
f0633d
-    return itr == maDataFieldNameMap.end() ? rLayoutName : itr->second;
f0633d
+    return itr == maDataFieldNameMap.end() ? ScDPName() : itr->second;
f0633d
 }
f0633d
 
f0633d
 sal_uInt16 ScDPSubtotalOptDlg::FindListBoxEntry(
f0633d
@@ -728,8 +739,9 @@ sal_uInt16 ScDPSubtotalOptDlg::FindListBoxEntry(
f0633d
     while (nPos < rLBox.GetEntryCount())
f0633d
     {
f0633d
         // translate the displayed field name back to its original field name.
f0633d
-        const OUString& rName = GetFieldName(rLBox.GetEntry(nPos));
f0633d
-        if (rName.equals(rEntry))
f0633d
+        ScDPName aName = GetFieldName(rLBox.GetEntry(nPos));
f0633d
+        OUString aUnoName = ScDPUtil::createDuplicateDimensionName(aName.maName, aName.mnDupCount);
f0633d
+        if (aUnoName.equals(rEntry))
f0633d
         {
f0633d
             bFound = true;
f0633d
             break;
f0633d
diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx
f0633d
index 79178c9..b682845 100644
f0633d
--- a/sc/source/ui/dbgui/pvlaydlg.cxx
f0633d
+++ b/sc/source/ui/dbgui/pvlaydlg.cxx
f0633d
@@ -60,6 +60,7 @@
f0633d
 #include "dpsave.hxx"
f0633d
 #include "dpshttab.hxx"
f0633d
 #include "scmod.hxx"
f0633d
+#include "dputil.hxx"
f0633d
 
f0633d
 #include "sc.hrc"
f0633d
 #include "scabstdlg.hxx"
f0633d
@@ -783,7 +784,7 @@ void ScPivotLayoutDlg::NotifyDoubleClick( ScPivotFieldType eType, size_t nFieldI
f0633d
                     OUString aFuncStr = GetFuncString(nMask);
f0633d
                     aLayoutName = aFuncStr + pDFData->maName;
f0633d
                 }
f0633d
-                aDataFieldNames.push_back(ScDPName(pDFData->maName, aLayoutName));
f0633d
+                aDataFieldNames.push_back(ScDPName(pDFData->maName, aLayoutName, pDFData->mnDupCount));
f0633d
             }
f0633d
 
f0633d
             bool bLayout = (eType == PIVOTFIELDTYPE_ROW) &&
f0633d
@@ -1588,7 +1589,9 @@ IMPL_LINK_NOARG(ScPivotLayoutDlg, OkHdl)
f0633d
 
f0633d
     for( ScDPLabelDataVector::const_iterator aIt = maLabelData.begin(), aEnd = maLabelData.end(); aIt != aEnd; ++aIt )
f0633d
     {
f0633d
-        ScDPSaveDimension* pDim = aSaveData.GetExistingDimensionByName(aIt->maName);
f0633d
+        // "UNO" name may have trailing '*'s which signifies duplicate index.
f0633d
+        OUString aUnoName = ScDPUtil::createDuplicateDimensionName(aIt->maName, aIt->mnDupCount);
f0633d
+        ScDPSaveDimension* pDim = aSaveData.GetExistingDimensionByName(aUnoName);
f0633d
 
f0633d
         if (!pDim)
f0633d
             continue;
f0633d
diff --git a/sc/source/ui/inc/pvfundlg.hxx b/sc/source/ui/inc/pvfundlg.hxx
f0633d
index c02cb5c..6ad269d 100644
f0633d
--- a/sc/source/ui/inc/pvfundlg.hxx
f0633d
+++ b/sc/source/ui/inc/pvfundlg.hxx
f0633d
@@ -162,7 +162,7 @@ private:
f0633d
     void                Init( const ScDPNameVec& rDataFields, bool bEnableLayout );
f0633d
     void                InitHideListBox();
f0633d
 
f0633d
-    const OUString& GetFieldName(const OUString& rLayoutName) const;
f0633d
+    ScDPName GetFieldName(const OUString& rLayoutName) const;
f0633d
 
f0633d
     /** Searches for a listbox entry, starts search at specified position. */
f0633d
     sal_uInt16 FindListBoxEntry( const ListBox& rLBox, const String& rEntry, sal_uInt16 nStartPos ) const;
f0633d
@@ -203,7 +203,7 @@ private:
f0633d
     ScDPObject&         mrDPObj;            /// The DataPilot object (for member names).
f0633d
     ScDPLabelData       maLabelData;        /// Cache for members data.
f0633d
 
f0633d
-    typedef ::boost::unordered_map< OUString, OUString, OUStringHash > NameMapType;
f0633d
+    typedef ::boost::unordered_map<OUString, ScDPName, OUStringHash> NameMapType;
f0633d
     NameMapType maDataFieldNameMap; /// Cache for displayed name to field name mapping.
f0633d
 };
f0633d
 
f0633d
-- 
f0633d
1.8.4.2
f0633d