[Libreoffice-commits] core.git: offapi/com offapi/UnoApi_offapi.mk sc/inc sc/source

Eike Rathke erack at redhat.com
Mon Jun 6 20:22:34 UTC 2016


 offapi/UnoApi_offapi.mk                              |    1 
 offapi/com/sun/star/sheet/DataPilotFieldFilter.idl   |   14 +
 offapi/com/sun/star/sheet/DataPilotSourceMembers.idl |    4 
 offapi/com/sun/star/sheet/XMembersAccess.idl         |   56 +++++++
 offapi/com/sun/star/sheet/XMembersSupplier.idl       |    5 
 sc/inc/dapiuno.hxx                                   |    3 
 sc/inc/dpcache.hxx                                   |   12 +
 sc/inc/dpobject.hxx                                  |    5 
 sc/inc/dpresfilter.hxx                               |    7 
 sc/inc/dptabdat.hxx                                  |    2 
 sc/inc/dptabres.hxx                                  |    2 
 sc/inc/dptabsrc.hxx                                  |   14 +
 sc/source/core/data/dpcache.cxx                      |   70 ++++++++-
 sc/source/core/data/dpobject.cxx                     |  143 ++++++++++++++++---
 sc/source/core/data/dpoutput.cxx                     |    6 
 sc/source/core/data/dpresfilter.cxx                  |   56 +++++--
 sc/source/core/data/dpsave.cxx                       |    6 
 sc/source/core/data/dptabdat.cxx                     |    4 
 sc/source/core/data/dptabres.cxx                     |   18 +-
 sc/source/core/data/dptabsrc.cxx                     |   60 +++++--
 sc/source/core/tool/interpr2.cxx                     |   20 ++
 sc/source/filter/excel/xepivot.cxx                   |    2 
 sc/source/ui/unoobj/dapiuno.cxx                      |    6 
 23 files changed, 406 insertions(+), 110 deletions(-)

New commits:
commit f88f6bcfce233c336c9025d466c5c2fb0b671de3
Author: Eike Rathke <erack at redhat.com>
Date:   Mon Jun 6 19:29:18 2016 +0200

    Resolves: tdf#35247 introduce a locale independent numeric field filter
    
    ... that tries to match a locale independent query string.
    
    Going via string queries is likely only necessary for the ugly
    alternative "fieldname[member]" syntax, if it is actually unnecessary
    for the field1,item1,... syntax needs to be evaluated and if so a
    distinct GetPivotData() function evaluating numeric contraints as well
    could be introduced.
    
    Change-Id: I2c1fc81c1022b0bba5eef8d86c0c815bb6e31f2d
    Reviewed-on: https://gerrit.libreoffice.org/25975
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>

diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index ad793bd..abaeea5 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -3501,6 +3501,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/sheet,\
 	XLabelRange \
 	XLabelRanges \
 	XLevelsSupplier \
+	XMembersAccess \
 	XMembersSupplier \
 	XMultiFormulaTokens \
 	XMultipleOperation \
diff --git a/offapi/com/sun/star/sheet/DataPilotFieldFilter.idl b/offapi/com/sun/star/sheet/DataPilotFieldFilter.idl
index 66ca976..c41cf39 100644
--- a/offapi/com/sun/star/sheet/DataPilotFieldFilter.idl
+++ b/offapi/com/sun/star/sheet/DataPilotFieldFilter.idl
@@ -29,7 +29,19 @@ struct DataPilotFieldFilter
     /** Field name. */
     string FieldName;
 
-    /** String value that needs to match against. */
+    /** String value that needs to match against, locale dependent.
+
+        <p> This is the value as name/label as also displayed in the
+        filter popup dialog, maybe formatted by user applied number
+        formats. </p>
+     */
+    string MatchValueName;
+
+    /** String value that needs to match against, locale independent.
+
+        <p> This is the underlying value formatted in a standardized
+        way, for example ISO 8601 YYYY-MM-DD for dates.
+     */
     string MatchValue;
 };
 
diff --git a/offapi/com/sun/star/sheet/DataPilotSourceMembers.idl b/offapi/com/sun/star/sheet/DataPilotSourceMembers.idl
index d928a811..4e113ca 100644
--- a/offapi/com/sun/star/sheet/DataPilotSourceMembers.idl
+++ b/offapi/com/sun/star/sheet/DataPilotSourceMembers.idl
@@ -20,7 +20,7 @@
 #ifndef __com_sun_star_sheet_DataPilotSourceMembers_idl__
 #define __com_sun_star_sheet_DataPilotSourceMembers_idl__
 
-#include <com/sun/star/container/XNameAccess.idl>
+#include <com/sun/star/sheet/XMembersAccess.idl>
 
 
 module com {  module sun {  module star {  module sheet {
@@ -38,7 +38,7 @@ service DataPilotSourceMembers
 
         @see com::sun::star::sheet::DataPilotSourceMember
      */
-    interface com::sun::star::container::XNameAccess;
+    interface com::sun::star::sheet::XMembersAccess;
 
 };
 
diff --git a/offapi/com/sun/star/sheet/XMembersAccess.idl b/offapi/com/sun/star/sheet/XMembersAccess.idl
new file mode 100644
index 0000000..98494ce
--- /dev/null
+++ b/offapi/com/sun/star/sheet/XMembersAccess.idl
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __com_sun_star_container_XMembersAccess_idl__
+#define __com_sun_star_container_XMembersAccess_idl__
+
+#include <com/sun/star/container/XNameAccess.idl>
+
+
+module com {  module sun {  module star {  module sheet {
+
+
+/** is used to access named members in a data pilot source
+    level collection.
+
+    @see com::sun::star::sheet::DataPilotSourceMember
+ */
+interface XMembersAccess: com::sun::star::container::XNameAccess
+{
+
+    /** returns names of data pilot members in a locale independent
+        notation.
+
+        <p> Specifically date values are represented in an ISO 8601
+        YYYY-MM-DD notation and date+time as YYYY-MM-DD HH:MM:SS,
+        whereas the strings returned by
+        com::sun::star::container::XNameAccess::getElementNames() may
+        represent these in a locale dependent or user formatted notation
+        such as MM/DD/YY or DD.MM.YYYY or other. </p>
+
+        <p> The names returned by this function can NOT be used in calls
+        to com::sun::star::container::XNameAccess::getByName(). However,
+        the order returned in two immediately consecutive calls to
+        getElementNames() and getLocaleIndependentElementNames() maps to
+        the same elements in order. </p>
+
+        @returns
+            a sequence of all element names in this container.
+
+     */
+    sequence<string> getLocaleIndependentElementNames();
+
+};
+
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/sheet/XMembersSupplier.idl b/offapi/com/sun/star/sheet/XMembersSupplier.idl
index 0017220..1fd13bf 100644
--- a/offapi/com/sun/star/sheet/XMembersSupplier.idl
+++ b/offapi/com/sun/star/sheet/XMembersSupplier.idl
@@ -20,8 +20,7 @@
 #ifndef __com_sun_star_sheet_XMembersSupplier_idl__
 #define __com_sun_star_sheet_XMembersSupplier_idl__
 
-#include <com/sun/star/uno/XInterface.idl>
-#include <com/sun/star/container/XNameAccess.idl>
+#include <com/sun/star/sheet/XMembersAccess.idl>
 
 
 module com {  module sun {  module star {  module sheet {
@@ -40,7 +39,7 @@ interface XMembersSupplier: com::sun::star::uno::XInterface
 
         @see com::sun::star::sheet::DataPilotSourceMembers
      */
-    com::sun::star::container::XNameAccess getMembers();
+    com::sun::star::sheet::XMembersAccess getMembers();
 
 };
 
diff --git a/sc/inc/dapiuno.hxx b/sc/inc/dapiuno.hxx
index b4b8d6e..d58e53d 100644
--- a/sc/inc/dapiuno.hxx
+++ b/sc/inc/dapiuno.hxx
@@ -398,8 +398,7 @@ protected:
     /** Returns the number of members for the field described by maFieldId. */
     sal_Int32           GetMemberCount() const;
     /** Returns the collection of members for the field described by maFieldId. */
-    css::uno::Reference< css::container::XNameAccess >
-                        GetMembers() const;
+    css::uno::Reference< css::sheet::XMembersAccess > GetMembers() const;
 
     ScDocShell* GetDocShell() const;
 protected:
diff --git a/sc/inc/dpcache.hxx b/sc/inc/dpcache.hxx
index 28442ef..304f1b5 100644
--- a/sc/inc/dpcache.hxx
+++ b/sc/inc/dpcache.hxx
@@ -80,7 +80,7 @@ public:
          */
         IndexArrayType maData;
 
-        sal_uLong mnNumFormat;
+        sal_uInt32 mnNumFormat;
 
         Field();
         Field(const Field&) = delete;
@@ -133,7 +133,13 @@ public:
     const ScDPObjectSet& GetAllReferences() const;
 
     SCROW GetIdByItemData(long nDim, const ScDPItemData& rItem) const;
-    OUString GetFormattedString(long nDim, const ScDPItemData& rItem) const;
+
+    static sal_uInt32 GetLocaleIndependentFormat( SvNumberFormatter& rFormatter, sal_uInt32 nNumFormat );
+    static OUString GetLocaleIndependentFormattedNumberString( double fValue );
+    static OUString GetLocaleIndependentFormattedString( double fValue, SvNumberFormatter& rFormatter, sal_uInt32 nNumFormat );
+    OUString GetFormattedString(long nDim, const ScDPItemData& rItem, bool bLocaleIndependent) const;
+    SvNumberFormatter* GetNumberFormatter() const;
+
     long AppendGroupField();
     void ResetGroupItems(long nDim, const ScDPNumGroupInfo& rNumInfo, sal_Int32 nGroupType);
     SCROW SetGroupItem(long nDim, const ScDPItemData& rData);
@@ -152,7 +158,7 @@ public:
     sal_Int32 GetGroupType(long nDim) const;
 
     SCCOL GetDimensionIndex(const OUString& sName) const;
-    sal_uLong GetNumberFormat( long nDim ) const;
+    sal_uInt32 GetNumberFormat( long nDim ) const;
     bool  IsDateDimension( long nDim ) const ;
     long GetDimMemberCount(long nDim) const;
     static SCROW GetOrder( long nDim, SCROW nIndex );
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 5876bd9..ad56ed2 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -46,6 +46,7 @@ namespace com { namespace sun { namespace star {
     }
 
     namespace sheet {
+        class XMembersAccess;
         struct DataPilotTablePositionData;
         struct DataPilotTableHeaderData;
         struct DataPilotFieldFilter;
@@ -202,8 +203,8 @@ public:
 
     sal_Int32           GetUsedHierarchy( sal_Int32 nDim );
 
-    bool                GetMembersNA( sal_Int32 nDim, css::uno::Reference< css::container::XNameAccess >& xMembers );
-    bool                GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, css::uno::Reference< css::container::XNameAccess >& xMembers );
+    bool                GetMembersNA( sal_Int32 nDim, css::uno::Reference< css::sheet::XMembersAccess >& xMembers );
+    bool                GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, css::uno::Reference< css::sheet::XMembersAccess >& xMembers );
 
     bool                GetMemberNames( sal_Int32 nDim, css::uno::Sequence< OUString >& rNames );
     bool                GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector<ScDPLabelData::Member>& rMembers );
diff --git a/sc/inc/dpresfilter.hxx b/sc/inc/dpresfilter.hxx
index dcf6432..82c2862 100644
--- a/sc/inc/dpresfilter.hxx
+++ b/sc/inc/dpresfilter.hxx
@@ -12,6 +12,7 @@
 
 #include "dpitemdata.hxx"
 
+#include <memory>
 #include <map>
 #include <vector>
 #include <unordered_map>
@@ -23,6 +24,7 @@ namespace com { namespace sun { namespace star { namespace sheet {
 struct ScDPResultFilter
 {
     OUString maDimName;
+    OUString maValueName;
     OUString maValue;
 
     bool mbHasValue:1;
@@ -54,12 +56,13 @@ private:
 
     struct MemberNode;
     struct DimensionNode;
-    typedef std::map<OUString, MemberNode*> MembersType;
+    typedef std::map<OUString, std::shared_ptr<MemberNode> > MembersType;
     typedef std::map<OUString, DimensionNode*> DimensionsType;
 
     struct DimensionNode
     {
-        MembersType maChildMembers;
+        MembersType maChildMembersValueNames;
+        MembersType maChildMembersValues;
 
         DimensionNode();
         DimensionNode(const DimensionNode&) = delete;
diff --git a/sc/inc/dptabdat.hxx b/sc/inc/dptabdat.hxx
index 53ff87f..fe9a52c 100644
--- a/sc/inc/dptabdat.hxx
+++ b/sc/inc/dptabdat.hxx
@@ -99,7 +99,7 @@ public:
     ScDPTableData(ScDocument* pDoc);
     virtual     ~ScDPTableData();
 
-    OUString GetFormattedString(long nDim, const ScDPItemData& rItem) const;
+    OUString GetFormattedString(long nDim, const ScDPItemData& rItem, bool bLocaleIndependent) const;
 
     long        GetDatePart( long nDateVal, long nHierarchy, long nLevel );
 
diff --git a/sc/inc/dptabres.hxx b/sc/inc/dptabres.hxx
index 900fa3e..827171d 100644
--- a/sc/inc/dptabres.hxx
+++ b/sc/inc/dptabres.hxx
@@ -366,7 +366,7 @@ public:
                                         ScDPInitState& rInitState);
     void CheckShowEmpty( bool bShow = false );
     OUString GetName() const;
-    OUString GetDisplayName() const;
+    OUString GetDisplayName( bool bLocaleIndependent ) const;
 
     void                FillItemData( ScDPItemData& rData ) const;
     bool IsValid() const;
diff --git a/sc/inc/dptabsrc.hxx b/sc/inc/dptabsrc.hxx
index e3ea1d3..03039df 100644
--- a/sc/inc/dptabsrc.hxx
+++ b/sc/inc/dptabsrc.hxx
@@ -564,7 +564,7 @@ public:
                                 throw(css::uno::RuntimeException, std::exception) override;
 
                             // XMembersSupplier
-    virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL
+    virtual css::uno::Reference< css::sheet::XMembersAccess > SAL_CALL
                             getMembers() throw(css::uno::RuntimeException, std::exception) override;
 
                             // XDataPilotMemberResults
@@ -657,7 +657,7 @@ public:
 typedef std::unordered_map< OUString, sal_Int32, OUStringHash > ScDPMembersHashMap;
 
 class ScDPMembers : public cppu::WeakImplHelper<
-                            css::container::XNameAccess,
+                            css::sheet::XMembersAccess,
                             css::lang::XServiceInfo >
 {
 private:
@@ -674,6 +674,10 @@ public:
                             ScDPMembers( ScDPSource* pSrc, long nD, long nH, long nL );
     virtual                 ~ScDPMembers();
 
+                            // XMembersAccess
+    virtual css::uno::Sequence< OUString > SAL_CALL getLocaleIndependentElementNames()
+                                throw(css::uno::RuntimeException, std::exception) override;
+
                             // XNameAccess
     virtual css::uno::Any SAL_CALL getByName( const OUString& aName )
                                 throw(css::container::NoSuchElementException,
@@ -705,6 +709,10 @@ public:
     sal_Int32               GetIndexFromName( const OUString& rName ) const;     // <0 if not found
     const ScDPItemData*     GetSrcItemDataByIndex(  SCROW nIndex);
     SCROW                   GetSrcItemsCount();
+
+private:
+    css::uno::Sequence< OUString > getElementNames( bool bLocaleIndependent ) const
+                                throw(css::uno::RuntimeException, std::exception);
 };
 
 class ScDPMember : public cppu::WeakImplHelper<
@@ -731,7 +739,7 @@ public:
     ScDPMember(const ScDPMember&) = delete;
     ScDPMember& operator=(const ScDPMember&) = delete;
 
-    OUString GetNameStr() const;
+    OUString GetNameStr( bool bLocaleIndependent ) const;
     void                    FillItemData( ScDPItemData& rData ) const;
     const ScDPItemData*  GetItemData() const;
     SCROW GetItemDataId() const { return mnDataId; }
diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx
index 661944e..655a460 100644
--- a/sc/source/core/data/dpcache.cxx
+++ b/sc/source/core/data/dpcache.cxx
@@ -122,7 +122,7 @@ OUString createLabelString(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab)
 
 void initFromCell(
     ScDPCache& rCache, ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
-    ScDPItemData& rData, sal_uLong& rNumFormat)
+    ScDPItemData& rData, sal_uInt32& rNumFormat)
 {
     OUString aDocStr = pDoc->GetString(nCol, nRow, nTab);
     rNumFormat = 0;
@@ -348,7 +348,7 @@ void ScDPCache::InitFromDoc(ScDocument* pDoc, const ScRange& rRange)
         for (SCROW i = 0, n = nEndRow-nStartRow; i < n; ++i)
         {
             SCROW nRow = i + nOffset;
-            sal_uLong nNumFormat = 0;
+            sal_uInt32 nNumFormat = 0;
             initFromCell(*this, pDoc, nCol, nRow, nDocTab, aData, nNumFormat);
             aBuckets.push_back(Bucket(aData, i));
 
@@ -861,7 +861,7 @@ const ScDPCache::ScDPItemDataVec& ScDPCache::GetDimMemberValues(SCCOL nDim) cons
     return maFields.at(nDim)->maItems;
 }
 
-sal_uLong ScDPCache::GetNumberFormat( long nDim ) const
+sal_uInt32 ScDPCache::GetNumberFormat( long nDim ) const
 {
     if ( nDim >= mnColumnCount )
         return 0;
@@ -975,7 +975,50 @@ SCROW ScDPCache::GetIdByItemData(long nDim, const ScDPItemData& rItem) const
     return -1;
 }
 
-OUString ScDPCache::GetFormattedString(long nDim, const ScDPItemData& rItem) const
+// static
+sal_uInt32 ScDPCache::GetLocaleIndependentFormat( SvNumberFormatter& rFormatter, sal_uInt32 nNumFormat )
+{
+    // For a date or date+time format use ISO format so it works across locales
+    // and can be matched against string based item queries. For time use 24h
+    // format. All others use General format, no currency, percent, ...
+    // Use en-US locale for all.
+    switch (rFormatter.GetType( nNumFormat))
+    {
+        case css::util::NumberFormat::DATE:
+            return rFormatter.GetFormatIndex( NF_DATE_ISO_YYYYMMDD, LANGUAGE_ENGLISH_US);
+        break;
+        case css::util::NumberFormat::TIME:
+            return rFormatter.GetFormatIndex( NF_TIME_HHMMSS, LANGUAGE_ENGLISH_US);
+        break;
+        case css::util::NumberFormat::DATETIME:
+            return rFormatter.GetFormatIndex( NF_DATETIME_ISO_YYYYMMDD_HHMMSS, LANGUAGE_ENGLISH_US);
+        break;
+        default:
+            return rFormatter.GetFormatIndex( NF_NUMBER_STANDARD, LANGUAGE_ENGLISH_US);
+    }
+}
+
+// static
+OUString ScDPCache::GetLocaleIndependentFormattedNumberString( double fValue )
+{
+    return rtl::math::doubleToUString( fValue, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
+}
+
+// static
+OUString ScDPCache::GetLocaleIndependentFormattedString( double fValue,
+        SvNumberFormatter& rFormatter, sal_uInt32 nNumFormat )
+{
+    nNumFormat = GetLocaleIndependentFormat( rFormatter, nNumFormat);
+    if ((nNumFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
+        return GetLocaleIndependentFormattedNumberString( fValue);
+
+    OUString aStr;
+    Color* pColor = nullptr;
+    rFormatter.GetOutputString( fValue, nNumFormat, aStr, &pColor);
+    return aStr;
+}
+
+OUString ScDPCache::GetFormattedString(long nDim, const ScDPItemData& rItem, bool bLocaleIndependent) const
 {
     if (nDim < 0)
         return rItem.GetString();
@@ -984,15 +1027,21 @@ OUString ScDPCache::GetFormattedString(long nDim, const ScDPItemData& rItem) con
     if (eType == ScDPItemData::Value)
     {
         // Format value using the stored number format.
-        sal_uLong nNumFormat = GetNumberFormat(nDim);
         SvNumberFormatter* pFormatter = mpDoc->GetFormatTable();
         if (pFormatter)
         {
-            Color* pColor = nullptr;
+            sal_uInt32 nNumFormat = GetNumberFormat(nDim);
+            if (bLocaleIndependent)
+                return GetLocaleIndependentFormattedString( rItem.GetValue(), *pFormatter, nNumFormat);
+
             OUString aStr;
+            Color* pColor = nullptr;
             pFormatter->GetOutputString(rItem.GetValue(), nNumFormat, aStr, &pColor);
             return aStr;
         }
+
+        // Last resort..
+        return GetLocaleIndependentFormattedNumberString( rItem.GetValue());
     }
 
     if (eType == ScDPItemData::GroupValue)
@@ -1023,6 +1072,11 @@ OUString ScDPCache::GetFormattedString(long nDim, const ScDPItemData& rItem) con
     return rItem.GetString();
 }
 
+SvNumberFormatter* ScDPCache::GetNumberFormatter() const
+{
+    return mpDoc->GetFormatTable();
+}
+
 long ScDPCache::AppendGroupField()
 {
     maGroupFields.push_back(o3tl::make_unique<GroupItems>());
@@ -1182,14 +1236,14 @@ std::ostream& operator<< (::std::ostream& os, const OUString& str)
 void dumpItems(const ScDPCache& rCache, long nDim, const ScDPCache::ScDPItemDataVec& rItems, size_t nOffset)
 {
     for (size_t i = 0; i < rItems.size(); ++i)
-        cout << "      " << (i+nOffset) << ": " << rCache.GetFormattedString(nDim, rItems[i]) << endl;
+        cout << "      " << (i+nOffset) << ": " << rCache.GetFormattedString(nDim, rItems[i], false) << endl;
 }
 
 void dumpSourceData(const ScDPCache& rCache, long nDim, const ScDPCache::ScDPItemDataVec& rItems, const ScDPCache::IndexArrayType& rArray)
 {
     ScDPCache::IndexArrayType::const_iterator it = rArray.begin(), itEnd = rArray.end();
     for (; it != itEnd; ++it)
-        cout << "      '" << rCache.GetFormattedString(nDim, rItems[*it]) << "'" << endl;
+        cout << "      '" << rCache.GetFormattedString(nDim, rItems[*it], false) << "'" << endl;
 }
 
 const char* getGroupTypeName(sal_Int32 nType)
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 531ab81..1d3b347 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -1028,7 +1028,7 @@ bool ScDPObject::GetMemberNames( sal_Int32 nDim, Sequence<OUString>& rNames )
 
 bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector<ScDPLabelData::Member>& rMembers )
 {
-    Reference< container::XNameAccess > xMembersNA;
+    Reference< sheet::XMembersAccess > xMembersNA;
     if (!GetMembersNA( nDim, nHier, xMembersNA ))
         return false;
 
@@ -1561,20 +1561,18 @@ bool parseFunction( const OUString& rList, sal_Int32 nStartPos, sal_Int32& rEndP
     return bFound;
 }
 
-bool isAtStart(
-    const OUString& rList, const OUString& rSearch, sal_Int32& rMatched,
-    bool bAllowBracket, sheet::GeneralFunction* pFunc )
+bool extractAtStart( const OUString& rList, sal_Int32& rMatched, bool bAllowBracket, sheet::GeneralFunction* pFunc,
+        OUString& rDequoted )
 {
     sal_Int32 nMatchList = 0;
-    sal_Int32 nMatchSearch = 0;
     sal_Unicode cFirst = rList[0];
+    bool bParsed = false;
     if ( cFirst == '\'' || cFirst == '[' )
     {
         // quoted string or string in brackets must match completely
 
         OUString aDequoted;
         sal_Int32 nQuoteEnd = 0;
-        bool bParsed = false;
 
         if ( cFirst == '\'' )
             bParsed = dequote( rList, 0, nQuoteEnd, aDequoted );
@@ -1635,9 +1633,51 @@ bool isAtStart(
             }
         }
 
-        if ( bParsed && ScGlobal::GetpTransliteration()->isEqual( aDequoted, rSearch ) )
+        if ( bParsed )
         {
             nMatchList = nQuoteEnd;             // match count in the list string, including quotes
+            rDequoted = aDequoted;
+        }
+    }
+
+    if (bParsed)
+    {
+        // look for following space or end of string
+
+        bool bValid = false;
+        if ( sal::static_int_cast<sal_Int32>(nMatchList) >= rList.getLength() )
+            bValid = true;
+        else
+        {
+            sal_Unicode cNext = rList[nMatchList];
+            if ( cNext == ' ' || ( bAllowBracket && cNext == '[' ) )
+                bValid = true;
+        }
+
+        if ( bValid )
+        {
+            rMatched = nMatchList;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool isAtStart(
+    const OUString& rList, const OUString& rSearch, sal_Int32& rMatched,
+    bool bAllowBracket, sheet::GeneralFunction* pFunc )
+{
+    sal_Int32 nMatchList = 0;
+    sal_Int32 nMatchSearch = 0;
+    sal_Unicode cFirst = rList[0];
+    if ( cFirst == '\'' || cFirst == '[' )
+    {
+        OUString aDequoted;
+        bool bParsed = extractAtStart( rList, rMatched, bAllowBracket, pFunc, aDequoted);
+        if ( bParsed && ScGlobal::GetpTransliteration()->isEqual( aDequoted, rSearch ) )
+        {
+            nMatchList = rMatched;             // match count in the list string, including quotes
             nMatchSearch = rSearch.getLength();
         }
     }
@@ -1686,6 +1726,7 @@ bool ScDPObject::ParseFilters(
     std::vector<OUString> aDataNames;     // data fields (source name)
     std::vector<OUString> aGivenNames;    // data fields (compound name)
     std::vector<OUString> aFieldNames;    // column/row/data fields
+    std::vector< uno::Sequence<OUString> > aFieldValueNames;
     std::vector< uno::Sequence<OUString> > aFieldValues;
 
     // get all the field and item names
@@ -1739,13 +1780,17 @@ bool ScDPObject::ParseFilters(
                         uno::Reference<sheet::XMembersSupplier> xLevSupp( xLevel, uno::UNO_QUERY );
                         if ( xLevNam.is() && xLevSupp.is() )
                         {
-                            uno::Reference<container::XNameAccess> xMembers = xLevSupp->getMembers();
+                            uno::Reference<sheet::XMembersAccess> xMembers = xLevSupp->getMembers();
 
                             OUString aFieldName( xLevNam->getName() );
-                            uno::Sequence<OUString> aMemberNames( xMembers->getElementNames() );
+                            // getElementNames() and getLocaleIndependentElementNames()
+                            // must be consecutive calls to obtain strings in matching order.
+                            uno::Sequence<OUString> aMemberValueNames( xMembers->getElementNames() );
+                            uno::Sequence<OUString> aMemberValues( xMembers->getLocaleIndependentElementNames() );
 
                             aFieldNames.push_back( aFieldName );
-                            aFieldValues.push_back( aMemberNames );
+                            aFieldValueNames.push_back( aMemberValueNames );
+                            aFieldValues.push_back( aMemberValues );
                         }
                     }
                 }
@@ -1757,7 +1802,8 @@ bool ScDPObject::ParseFilters(
 
     SCSIZE nDataFields = aDataNames.size();
     SCSIZE nFieldCount = aFieldNames.size();
-    OSL_ENSURE( aGivenNames.size() == nDataFields && aFieldValues.size() == nFieldCount, "wrong count" );
+    OSL_ENSURE( aGivenNames.size() == nDataFields && aFieldValueNames.size() == nFieldCount &&
+            aFieldValues.size() == nFieldCount, "wrong count" );
 
     bool bError = false;
     bool bHasData = false;
@@ -1823,29 +1869,87 @@ bool ScDPObject::ParseFilters(
             bool bItemFound = false;
             sal_Int32 nMatched = 0;
             OUString aFoundName;
+            OUString aFoundValueName;
             OUString aFoundValue;
             sheet::GeneralFunction eFunc = sheet::GeneralFunction_NONE;
             sheet::GeneralFunction eFoundFunc = sheet::GeneralFunction_NONE;
 
+            OUString aQueryValueName;
+            const bool bHasQuery = extractAtStart( aRemaining, nMatched, false, &eFunc, aQueryValueName);
+
+            OUString aQueryValue = aQueryValueName;
+            if (mpTableData)
+            {
+                SvNumberFormatter* pFormatter = mpTableData->GetCacheTable().getCache().GetNumberFormatter();
+                if (pFormatter)
+                {
+                    // Parse possible number from aQueryValueName and format
+                    // locale independent as aQueryValue.
+                    sal_uInt32 nNumFormat;
+                    double fValue;
+                    if (pFormatter->IsNumberFormat( aQueryValueName, nNumFormat, fValue))
+                        aQueryValue = ScDPCache::GetLocaleIndependentFormattedString( fValue, *pFormatter, nNumFormat);
+                }
+            }
+
             for ( SCSIZE nField=0; nField<nFieldCount; nField++ )
             {
                 // If a field name is given, look in that field only, otherwise in all fields.
                 // aSpecField is initialized from aFieldNames array, so exact comparison can be used.
                 if ( !bHasFieldName || aFieldNames[nField] == aSpecField )
                 {
-                    const uno::Sequence<OUString>& rItems = aFieldValues[nField];
-                    sal_Int32 nItemCount = rItems.getLength();
-                    const OUString* pItemArr = rItems.getConstArray();
+                    const uno::Sequence<OUString>& rItemNames = aFieldValueNames[nField];
+                    const uno::Sequence<OUString>& rItemValues = aFieldValues[nField];
+                    sal_Int32 nItemCount = rItemNames.getLength();
+                    assert(nItemCount == rItemValues.getLength());
+                    const OUString* pItemNamesArr = rItemNames.getConstArray();
+                    const OUString* pItemValuesArr = rItemValues.getConstArray();
                     for ( sal_Int32 nItem=0; nItem<nItemCount; nItem++ )
                     {
-                        if ( isAtStart( aRemaining, pItemArr[nItem], nMatched, false, &eFunc ) )
+                        bool bThisItemFound;
+                        if (bHasQuery)
+                        {
+                            // First check given value name against both.
+                            bThisItemFound = ScGlobal::GetpTransliteration()->isEqual(
+                                    aQueryValueName, pItemNamesArr[nItem]);
+                            if (!bThisItemFound && pItemValuesArr[nItem] != pItemNamesArr[nItem])
+                                bThisItemFound = ScGlobal::GetpTransliteration()->isEqual(
+                                        aQueryValueName, pItemValuesArr[nItem]);
+                            if (!bThisItemFound && aQueryValueName != aQueryValue)
+                            {
+                                // Second check locale independent value
+                                // against both.
+                                /* TODO: or check only value string against
+                                 * value string, not against the value name? */
+                                bThisItemFound = ScGlobal::GetpTransliteration()->isEqual(
+                                        aQueryValue, pItemNamesArr[nItem]);
+                                if (!bThisItemFound && pItemValuesArr[nItem] != pItemNamesArr[nItem])
+                                    bThisItemFound = ScGlobal::GetpTransliteration()->isEqual(
+                                            aQueryValue, pItemValuesArr[nItem]);
+                            }
+                        }
+                        else
+                        {
+                            bThisItemFound = isAtStart( aRemaining, pItemNamesArr[nItem], nMatched, false, &eFunc );
+                            if (!bThisItemFound && pItemValuesArr[nItem] != pItemNamesArr[nItem])
+                                bThisItemFound = isAtStart( aRemaining, pItemValuesArr[nItem], nMatched, false, &eFunc );
+                            /* TODO: this checks only the given value name,
+                             * check also locale independent value. But we'd
+                             * have to do that in each iteration of the loop
+                             * inside isAtStart() since a query could not be
+                             * extracted and a match could be on the passed
+                             * item value name string or item value string
+                             * starting at aRemaining. */
+                        }
+                        if (bThisItemFound)
                         {
                             if ( bItemFound )
                                 bError = true;      // duplicate (also across fields)
                             else
                             {
                                 aFoundName = aFieldNames[nField];
-                                aFoundValue = pItemArr[nItem];
+                                aFoundValueName = pItemNamesArr[nItem];
+                                aFoundValue = pItemValuesArr[nItem];
                                 eFoundFunc = eFunc;
                                 bItemFound = true;
                                 bUsed = true;
@@ -1859,6 +1963,7 @@ bool ScDPObject::ParseFilters(
             {
                 sheet::DataPilotFieldFilter aField;
                 aField.FieldName = aFoundName;
+                aField.MatchValueName = aFoundValueName;
                 aField.MatchValue = aFoundValue;
                 rFilters.push_back(aField);
                 rFilterFuncs.push_back(eFoundFunc);
@@ -1945,7 +2050,7 @@ void ScDPObject::ToggleDetails(const DataPilotTableHeaderData& rElemDesc, ScDPOb
     OSL_ENSURE( xLevel.is(), "level not found" );
     if ( !xLevel.is() ) return;
 
-    uno::Reference<container::XNameAccess> xMembers;
+    uno::Reference<sheet::XMembersAccess> xMembers;
     uno::Reference<sheet::XMembersSupplier> xMbrSupp( xLevel, uno::UNO_QUERY );
     if ( xMbrSupp.is() )
         xMembers = xMbrSupp->getMembers();
@@ -2426,12 +2531,12 @@ sal_Int32 ScDPObject::GetUsedHierarchy( sal_Int32 nDim )
     return nHier;
 }
 
-bool ScDPObject::GetMembersNA( sal_Int32 nDim, uno::Reference< container::XNameAccess >& xMembers )
+bool ScDPObject::GetMembersNA( sal_Int32 nDim, uno::Reference< sheet::XMembersAccess >& xMembers )
 {
     return GetMembersNA( nDim, GetUsedHierarchy( nDim ), xMembers );
 }
 
-bool ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< container::XNameAccess >& xMembers )
+bool ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< sheet::XMembersAccess >& xMembers )
 {
     bool bRet = false;
     uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx
index d62739e..6b32a84 100644
--- a/sc/source/core/data/dpoutput.cxx
+++ b/sc/source/core/data/dpoutput.cxx
@@ -471,7 +471,7 @@ uno::Sequence<sheet::MemberResult> getVisiblePageMembersAsResults( const uno::Re
     if (!xMSupplier.is())
         return uno::Sequence<sheet::MemberResult>();
 
-    uno::Reference<container::XNameAccess> xNA = xMSupplier->getMembers();
+    uno::Reference<sheet::XMembersAccess> xNA = xMSupplier->getMembers();
     if (!xNA.is())
         return uno::Sequence<sheet::MemberResult>();
 
@@ -1486,7 +1486,7 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
         while ( nItem > 0 && (pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
             --nItem;
 
-        filter.MatchValue = pArray[nItem].Name;
+        filter.MatchValueName = pArray[nItem].Name;
         rFilters.push_back(filter);
     }
 
@@ -1510,7 +1510,7 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
         while ( nItem > 0 && (pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
             --nItem;
 
-        filter.MatchValue = pArray[nItem].Name;
+        filter.MatchValueName = pArray[nItem].Name;
         rFilters.push_back(filter);
     }
 
diff --git a/sc/source/core/data/dpresfilter.cxx b/sc/source/core/data/dpresfilter.cxx
index f66e7f1..033762a 100644
--- a/sc/source/core/data/dpresfilter.cxx
+++ b/sc/source/core/data/dpresfilter.cxx
@@ -34,16 +34,13 @@ ScDPResultTree::DimensionNode::DimensionNode() {}
 
 ScDPResultTree::DimensionNode::~DimensionNode()
 {
-    MembersType::iterator it = maChildMembers.begin(), itEnd = maChildMembers.end();
-    for (; it != itEnd; ++it)
-        delete it->second;
 }
 
 #if DEBUG_PIVOT_TABLE
 void ScDPResultTree::DimensionNode::dump(int nLevel) const
 {
     string aIndent(nLevel*2, ' ');
-    MembersType::const_iterator it = maChildMembers.begin(), itEnd = maChildMembers.end();
+    MembersType::const_iterator it = maChildMembersValueNames.begin(), itEnd = maChildMembersValueNames.end();
     for (; it != itEnd; ++it)
     {
         cout << aIndent << "member: ";
@@ -131,25 +128,42 @@ void ScDPResultTree::add(
 
         // Now, see if this dimension member exists.
         DimensionNode* pDim = itDim->second;
-        MembersType& rMembers = pDim->maChildMembers;
-        aUpperName = ScGlobal::pCharClass->uppercase(filter.maValue);
-        MembersType::iterator itMem = rMembers.find(aUpperName);
-        if (itMem == rMembers.end())
+        MembersType& rMembersValueNames = pDim->maChildMembersValueNames;
+        aUpperName = ScGlobal::pCharClass->uppercase(filter.maValueName);
+        MembersType::iterator itMem = rMembersValueNames.find(aUpperName);
+        if (itMem == rMembersValueNames.end())
         {
             // New member.  Insert it.
+            std::shared_ptr<MemberNode> pNode( new MemberNode);
             std::pair<MembersType::iterator, bool> r =
-                rMembers.insert(
-                    MembersType::value_type(aUpperName, new MemberNode));
+                rMembersValueNames.insert( MembersType::value_type(aUpperName, pNode));
 
             if (!r.second)
                 // Insertion failed!
                 return;
 
             itMem = r.first;
+
+            // If the locale independent value string isn't any different it
+            // makes no sense to add it to the separate mapping.
+            if (!filter.maValue.isEmpty() && filter.maValue != filter.maValueName)
+            {
+                MembersType& rMembersValues = pDim->maChildMembersValues;
+                aUpperName = ScGlobal::pCharClass->uppercase(filter.maValue);
+                MembersType::iterator itMemVal = rMembersValues.find(aUpperName);
+                if (itMemVal == rMembersValues.end())
+                {
+                    // New member.  Insert it.
+                    std::pair<MembersType::iterator, bool> it =
+                        rMembersValues.insert( MembersType::value_type(aUpperName, pNode));
+                    // If insertion failed do not bail out anymore.
+                    SAL_WARN_IF( !it.second, "sc.core", "ScDPResultTree::add - rMembersValues.insert failed");
+                }
+            }
         }
 
         pMemName = &itMem->first;
-        pMemNode = itMem->second;
+        pMemNode = itMem->second.get();
     }
 
     if (pDimName && pMemName)
@@ -209,14 +223,20 @@ const ScDPResultTree::ValuesType* ScDPResultTree::getResults(
             return nullptr;
 
         const DimensionNode* pDim = itDim->second;
-        MembersType::const_iterator itMem = pDim->maChildMembers.find(
-            ScGlobal::pCharClass->uppercase(p->MatchValue));
+        MembersType::const_iterator itMem( pDim->maChildMembersValueNames.find(
+                    ScGlobal::pCharClass->uppercase( p->MatchValueName)));
 
-        if (itMem == pDim->maChildMembers.end())
-            // Specified member not found.
-            return nullptr;
+        if (itMem == pDim->maChildMembersValueNames.end())
+        {
+            // Specified member name not found, try locale independent value.
+            itMem = pDim->maChildMembersValues.find( ScGlobal::pCharClass->uppercase( p->MatchValue));
+
+            if (itMem == pDim->maChildMembersValues.end())
+                // Specified member not found.
+                return nullptr;
+        }
 
-        pMember = itMem->second;
+        pMember = itMem->second.get();
     }
 
     return &pMember->maValues;
@@ -226,7 +246,7 @@ double ScDPResultTree::getLeafResult(const css::sheet::DataPilotFieldFilter& rFi
 {
     NamePairType aPair(
         ScGlobal::pCharClass->uppercase(rFilter.FieldName),
-        ScGlobal::pCharClass->uppercase(rFilter.MatchValue));
+        ScGlobal::pCharClass->uppercase(rFilter.MatchValueName));
 
     LeafValuesType::const_iterator it = maLeafValues.find(aPair);
     if (it != maLeafValues.end())
diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx
index 1e356e9..06bf39b 100644
--- a/sc/source/core/data/dpsave.cxx
+++ b/sc/source/core/data/dpsave.cxx
@@ -662,7 +662,7 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
                 uno::Reference<sheet::XMembersSupplier> xMembSupp( xLevel, uno::UNO_QUERY );
                 if ( xMembSupp.is() )
                 {
-                    uno::Reference<container::XNameAccess> xMembers = xMembSupp->getMembers();
+                    uno::Reference<sheet::XMembersAccess> xMembers = xMembSupp->getMembers();
                     if ( xMembers.is() )
                     {
                         sal_Int32 nPosition = -1; // set position only in manual mode
@@ -1362,7 +1362,7 @@ void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
         for (size_t j = 0; j < nMemberCount; ++j)
         {
             const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] );
-            OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData);
+            OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData, false);
             if (iter->GetExistingMemberByName(aMemName))
                 // this member instance already exists. nothing to do.
                 continue;
@@ -1407,7 +1407,7 @@ void ScDPSaveData::SyncAllDimensionMembers(ScDPTableData* pData)
         for (size_t j = 0; j < nMemberCount; ++j)
         {
             const ScDPItemData* pMemberData = pData->GetMemberById(nDimIndex, rMembers[j]);
-            OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData);
+            OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData, false);
             aMemNames.insert(aMemName);
         }
 
diff --git a/sc/source/core/data/dptabdat.cxx b/sc/source/core/data/dptabdat.cxx
index 181cf15..8061f25 100644
--- a/sc/source/core/data/dptabdat.cxx
+++ b/sc/source/core/data/dptabdat.cxx
@@ -55,10 +55,10 @@ ScDPTableData::~ScDPTableData()
 {
 }
 
-OUString ScDPTableData::GetFormattedString(long nDim, const ScDPItemData& rItem) const
+OUString ScDPTableData::GetFormattedString(long nDim, const ScDPItemData& rItem, bool bLocaleIndependent) const
 {
     const ScDPCache& rCache = GetCacheTable().getCache();
-    return rCache.GetFormattedString(nDim, rItem);
+    return rCache.GetFormattedString(nDim, rItem, bLocaleIndependent);
 }
 
 long ScDPTableData::GetDatePart( long nDateVal, long nHierarchy, long nLevel )
diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx
index 136a5b6..af5ad12 100644
--- a/sc/source/core/data/dptabres.cxx
+++ b/sc/source/core/data/dptabres.cxx
@@ -110,9 +110,10 @@ public:
         mrFilters.push_back(ScDPResultFilter(rName, bDataLayout));
     }
 
-    void pushDimValue(const OUString& rValue)
+    void pushDimValue(const OUString& rValueName, const OUString& rValue)
     {
         ScDPResultFilter& rFilter = mrFilters.back();
+        rFilter.maValueName = rValueName;
         rFilter.maValue = rValue;
         rFilter.mbHasValue = true;
     }
@@ -953,12 +954,12 @@ OUString ScDPResultMember::GetName() const
 {
   const ScDPMember* pMemberDesc = GetDPMember();
     if (pMemberDesc)
-        return pMemberDesc->GetNameStr();
+        return pMemberDesc->GetNameStr( false );
     else
         return ScGlobal::GetRscString(STR_PIVOT_TOTAL);         // root member
 }
 
-OUString ScDPResultMember::GetDisplayName() const
+OUString ScDPResultMember::GetDisplayName( bool bLocaleIndependent ) const
 {
     const ScDPMember* pDPMember = GetDPMember();
     if (!pDPMember)
@@ -969,7 +970,7 @@ OUString ScDPResultMember::GetDisplayName() const
     if (aParentDimData.mpParentDim)
     {
         long nDim = aParentDimData.mpParentDim->GetDimension();
-        return pResultData->GetSource().GetData()->GetFormattedString(nDim, aItem);
+        return pResultData->GetSource().GetData()->GetFormattedString(nDim, aItem, bLocaleIndependent);
     }
 
     return aItem.GetString();
@@ -1324,7 +1325,7 @@ void ScDPResultMember::FillMemberResults(
         if (aParentDimData.mpParentDim)
         {
             long nDim = aParentDimData.mpParentDim->GetDimension();
-            aName = pResultData->GetSource().GetData()->GetFormattedString(nDim, aItemData);
+            aName = pResultData->GetSource().GetData()->GetFormattedString(nDim, aItemData, false);
         }
         else
         {
@@ -1332,7 +1333,7 @@ void ScDPResultMember::FillMemberResults(
             const ScDPMember* pMem = GetDPMember();
             if (pMem)
                 nDim = pMem->GetDim();
-            aName = pResultData->GetSource().GetData()->GetFormattedString(nDim, aItemData);
+            aName = pResultData->GetSource().GetData()->GetFormattedString(nDim, aItemData, false);
         }
 
         ScDPItemData::Type eType = aItemData.GetType();
@@ -1511,9 +1512,8 @@ void ScDPResultMember::FillDataResults(
     if (pDPMember)
     {
         // Root result has no corresponding DP member. Only take the non-root results.
-        OUString aMemStr = GetDisplayName();
         pFilterStack.reset(new FilterStack(rFilterCxt.maFilters));
-        pFilterStack->pushDimValue(aMemStr);
+        pFilterStack->pushDimValue( GetDisplayName( false), GetDisplayName( true));
     }
 
     //  IsVisible() test is in ScDPResultDimension::FillDataResults
@@ -2017,7 +2017,7 @@ void ScDPDataMember::FillDataRow(
         // since its immediate parent result member is linked to the same
         // dimension member.
         pFilterStack.reset(new FilterStack(rFilterCxt.maFilters));
-        pFilterStack->pushDimValue(pResultMember->GetDisplayName());
+        pFilterStack->pushDimValue( pResultMember->GetDisplayName( false), pResultMember->GetDisplayName( true));
     }
 
     OSL_ENSURE( pRefMember == pResultMember || !pResultMember, "bla" );
diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx
index ce48a82..c92c4e2 100644
--- a/sc/source/core/data/dptabsrc.cxx
+++ b/sc/source/core/data/dptabsrc.cxx
@@ -465,7 +465,7 @@ Sequence< Sequence<Any> > SAL_CALL ScDPSource::getDrillDownData(const Sequence<s
                 ScDPDimension* pDim = GetDimensionsObject()->getByIndex( nCol );
                 ScDPMembers* pMembers = pDim->GetHierarchiesObject()->getByIndex(0)->
                                         GetLevelsObject()->getByIndex(0)->GetMembersObject();
-                sal_Int32 nIndex = pMembers->GetIndexFromName( rFilter.MatchValue );
+                sal_Int32 nIndex = pMembers->GetIndexFromName( rFilter.MatchValueName );
                 if ( nIndex >= 0 )
                 {
                     ScDPItemData aItem;
@@ -1458,7 +1458,7 @@ const ScDPItemData& ScDPDimension::GetSelectedData()
             for (long i=0; i<nCount && !pSelectedData; i++)
             {
                 ScDPMember* pMember = pMembers->getByIndex(i);
-                if (aSelectedPage.equals(pMember->GetNameStr()))
+                if (aSelectedPage.equals(pMember->GetNameStr( false)))
                 {
                     pSelectedData = new ScDPItemData();
                     pMember->FillItemData( *pSelectedData );
@@ -2074,7 +2074,7 @@ ScDPMembers* ScDPLevel::GetMembersObject()
     return mxMembers.get();
 }
 
-uno::Reference<container::XNameAccess> SAL_CALL ScDPLevel::getMembers() throw(uno::RuntimeException, std::exception)
+uno::Reference<sheet::XMembersAccess> SAL_CALL ScDPLevel::getMembers() throw(uno::RuntimeException, std::exception)
 {
     return GetMembersObject();
 }
@@ -2366,22 +2366,7 @@ uno::Any SAL_CALL ScDPMembers::getByName( const OUString& aName )
 
 uno::Sequence<OUString> SAL_CALL ScDPMembers::getElementNames() throw(uno::RuntimeException, std::exception)
 {
-    // Return list of names in sorted order,
-    // so it's displayed in that order in the field options dialog.
-    // Sorting is done at the level object (parent of this).
-
-    ScDPLevel* pLevel = pSource->GetDimensionsObject()->getByIndex(nDim)->
-        GetHierarchiesObject()->getByIndex(nHier)->GetLevelsObject()->getByIndex(nLev);
-    pLevel->EvaluateSortOrder();
-    const std::vector<sal_Int32>& rGlobalOrder = pLevel->GetGlobalOrder();
-    bool bSort = !rGlobalOrder.empty();
-
-    long nCount = getCount();
-    uno::Sequence<OUString> aSeq(nCount);
-    OUString* pArr = aSeq.getArray();
-    for (long i=0; i<nCount; i++)
-        pArr[i] = getByIndex(bSort ? rGlobalOrder[i] : i)->getName();
-    return aSeq;
+    return getElementNames( false );
 }
 
 sal_Bool SAL_CALL ScDPMembers::hasByName( const OUString& aName ) throw(uno::RuntimeException, std::exception)
@@ -2401,6 +2386,37 @@ sal_Bool SAL_CALL ScDPMembers::hasElements() throw(uno::RuntimeException, std::e
 
 // end of XNameAccess implementation
 
+// XMembersAccess implementation
+
+uno::Sequence<OUString> SAL_CALL ScDPMembers::getLocaleIndependentElementNames()
+        throw(uno::RuntimeException, std::exception)
+{
+    return getElementNames( true );
+}
+
+// end of XMembersAccess implementation
+
+uno::Sequence<OUString> ScDPMembers::getElementNames( bool bLocaleIndependent ) const
+        throw(uno::RuntimeException, std::exception)
+{
+    // Return list of names in sorted order,
+    // so it's displayed in that order in the field options dialog.
+    // Sorting is done at the level object (parent of this).
+
+    ScDPLevel* pLevel = pSource->GetDimensionsObject()->getByIndex(nDim)->
+        GetHierarchiesObject()->getByIndex(nHier)->GetLevelsObject()->getByIndex(nLev);
+    pLevel->EvaluateSortOrder();
+    const std::vector<sal_Int32>& rGlobalOrder = pLevel->GetGlobalOrder();
+    bool bSort = !rGlobalOrder.empty();
+
+    long nCount = getCount();
+    uno::Sequence<OUString> aSeq(nCount);
+    OUString* pArr = aSeq.getArray();
+    for (long i=0; i<nCount; i++)
+        pArr[i] = getByIndex(bSort ? rGlobalOrder[i] : i)->GetNameStr( bLocaleIndependent);
+    return aSeq;
+}
+
 long ScDPMembers::getMinMembers() const
 {
     // used in lcl_CountMinMembers
@@ -2594,17 +2610,17 @@ const OUString* ScDPMember::GetLayoutName() const
     return mpLayoutName.get();
 }
 
-OUString ScDPMember::GetNameStr() const
+OUString ScDPMember::GetNameStr( bool bLocaleIndependent ) const
 {
     const ScDPItemData* pData = GetItemData();
     if (pData)
-        return pSource->GetData()->GetFormattedString(nDim, *pData);
+        return pSource->GetData()->GetFormattedString(nDim, *pData, bLocaleIndependent);
     return OUString();
 }
 
 OUString SAL_CALL ScDPMember::getName() throw(uno::RuntimeException, std::exception)
 {
-    return GetNameStr();
+    return GetNameStr( false );
 }
 
 void SAL_CALL ScDPMember::setName( const OUString& /* rNewName */ ) throw(uno::RuntimeException, std::exception)
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index 4a51f95..f827565 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -46,6 +46,7 @@
 #include "tokenarray.hxx"
 #include "globalnames.hxx"
 #include "stlsheet.hxx"
+#include "dpcache.hxx"
 
 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
 
@@ -3306,8 +3307,23 @@ void ScInterpreter::ScGetPivotData()
         sal_uInt16 i = nFilterCount;
         while (i-- > 0)
         {
-            //TODO: should allow numeric constraint values
-            aFilters[i].MatchValue = GetString().getString();
+            /* TODO: should allow numeric constraint values. */
+
+            /* TODO: also, in case of numeric the entire filter match should
+             * not be on a (even if locale independent) formatted string down
+             * below in pDPObj->GetPivotData(). */
+
+            aFilters[i].MatchValueName = GetString().getString();
+
+            // Parse possible number from MatchValueName and format
+            // locale independent as MatchValue.
+            sal_uInt32 nNumFormat;
+            double fValue;
+            if (pFormatter->IsNumberFormat( aFilters[i].MatchValueName, nNumFormat, fValue))
+                aFilters[i].MatchValue = ScDPCache::GetLocaleIndependentFormattedString( fValue, *pFormatter, nNumFormat);
+            else
+                aFilters[i].MatchValue = aFilters[i].MatchValueName;
+
             aFilters[i].FieldName = GetString().getString();
         }
 
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx
index 546064c..e496dc2 100644
--- a/sc/source/filter/excel/xepivot.cxx
+++ b/sc/source/filter/excel/xepivot.cxx
@@ -530,7 +530,7 @@ void XclExpPCField::InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScD
             const ScDPItemData* pData = aDPData.GetMemberById(nDim, nMemberId);
             if ( pData )
             {
-                OUString aStr = pCache->GetFormattedString(nDim, *pData);
+                OUString aStr = pCache->GetFormattedString(nDim, *pData, false);
                 InsertGroupItem(new XclExpPCItem(aStr));
             }
         }
diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx
index 32f43a3..a28f0c9 100644
--- a/sc/source/ui/unoobj/dapiuno.cxx
+++ b/sc/source/ui/unoobj/dapiuno.cxx
@@ -1512,9 +1512,9 @@ sal_Int32 ScDataPilotChildObjBase::GetMemberCount() const
     return nRet;
 }
 
-Reference< XNameAccess > ScDataPilotChildObjBase::GetMembers() const
+Reference< XMembersAccess > ScDataPilotChildObjBase::GetMembers() const
 {
-    Reference< XNameAccess > xMembersNA;
+    Reference< XMembersAccess > xMembersNA;
     if( ScDPObject* pDPObj = GetDPObject() )
         pDPObj->GetMembersNA( lcl_GetObjectIndex( pDPObj, maFieldId ), xMembersNA );
     return xMembersNA;
@@ -2617,7 +2617,7 @@ Reference< XDataPilotField > SAL_CALL ScDataPilotFieldObj::createNameGroup( cons
         //! localized prefix string
         OUString aGroupName = pGroupDimension->CreateGroupName( "Group" );
         ScDPSaveGroupItem aGroup( aGroupName );
-        Reference< XNameAccess > xMembers = GetMembers();
+        Reference< XMembersAccess > xMembers = GetMembers();
         if (!xMembers.is())
         {
             delete pNewGroupDim;


More information about the Libreoffice-commits mailing list