summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--offapi/UnoApi_offapi.mk1
-rw-r--r--offapi/com/sun/star/sheet/DataPilotFieldFilter.idl14
-rw-r--r--offapi/com/sun/star/sheet/DataPilotSourceMembers.idl4
-rw-r--r--offapi/com/sun/star/sheet/XMembersAccess.idl56
-rw-r--r--offapi/com/sun/star/sheet/XMembersSupplier.idl5
-rw-r--r--sc/inc/dapiuno.hxx3
-rw-r--r--sc/inc/dpcache.hxx12
-rw-r--r--sc/inc/dpobject.hxx5
-rw-r--r--sc/inc/dpresfilter.hxx7
-rw-r--r--sc/inc/dptabdat.hxx2
-rw-r--r--sc/inc/dptabres.hxx2
-rw-r--r--sc/inc/dptabsrc.hxx14
-rw-r--r--sc/source/core/data/dpcache.cxx70
-rw-r--r--sc/source/core/data/dpobject.cxx143
-rw-r--r--sc/source/core/data/dpoutput.cxx6
-rw-r--r--sc/source/core/data/dpresfilter.cxx56
-rw-r--r--sc/source/core/data/dpsave.cxx6
-rw-r--r--sc/source/core/data/dptabdat.cxx4
-rw-r--r--sc/source/core/data/dptabres.cxx18
-rw-r--r--sc/source/core/data/dptabsrc.cxx60
-rw-r--r--sc/source/core/tool/interpr2.cxx20
-rw-r--r--sc/source/filter/excel/xepivot.cxx2
-rw-r--r--sc/source/ui/unoobj/dapiuno.cxx6
23 files changed, 406 insertions, 110 deletions
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index ad793bdf6c93..abaeea50a17a 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 66ca9764f3aa..c41cf395f6da 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 d928a8114516..4e113ca33247 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 000000000000..98494cee5868
--- /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 00172207b868..1fd13bf383cf 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 b4b8d6e26837..d58e53d586a4 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 28442ef89552..304f1b59007f 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 5876bd930dbc..ad56ed2c7291 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 dcf643203936..82c2862229df 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 53ff87fdc996..fe9a52ce83e9 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 900fa3e03121..827171d32eda 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 e3ea1d3479e8..03039dfbfca5 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 661944e09e49..655a46093a37 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 531ab8176a0b..1d3b3471d050 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 d62739effd55..6b32a8478202 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 f66e7f116766..033762abcda0 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 1e356e950a81..06bf39b96caa 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 181cf150ea97..8061f2535596 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 136a5b69779c..af5ad122efd8 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 ce48a82446cb..c92c4e212a86 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 4a51f956be73..f82756543a27 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 546064c9be51..e496dc224518 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 32f43a3784c1..a28f0c970212 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;