diff options
-rw-r--r-- | offapi/UnoApi_offapi.mk | 1 | ||||
-rw-r--r-- | offapi/com/sun/star/sheet/DataPilotFieldFilter.idl | 14 | ||||
-rw-r--r-- | offapi/com/sun/star/sheet/DataPilotSourceMembers.idl | 4 | ||||
-rw-r--r-- | offapi/com/sun/star/sheet/XMembersAccess.idl | 56 | ||||
-rw-r--r-- | offapi/com/sun/star/sheet/XMembersSupplier.idl | 5 | ||||
-rw-r--r-- | sc/inc/dapiuno.hxx | 3 | ||||
-rw-r--r-- | sc/inc/dpcache.hxx | 12 | ||||
-rw-r--r-- | sc/inc/dpobject.hxx | 5 | ||||
-rw-r--r-- | sc/inc/dpresfilter.hxx | 7 | ||||
-rw-r--r-- | sc/inc/dptabdat.hxx | 2 | ||||
-rw-r--r-- | sc/inc/dptabres.hxx | 2 | ||||
-rw-r--r-- | sc/inc/dptabsrc.hxx | 14 | ||||
-rw-r--r-- | sc/source/core/data/dpcache.cxx | 70 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 143 | ||||
-rw-r--r-- | sc/source/core/data/dpoutput.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/dpresfilter.cxx | 56 | ||||
-rw-r--r-- | sc/source/core/data/dpsave.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/dptabdat.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/dptabres.cxx | 18 | ||||
-rw-r--r-- | sc/source/core/data/dptabsrc.cxx | 60 | ||||
-rw-r--r-- | sc/source/core/tool/interpr2.cxx | 20 | ||||
-rw-r--r-- | sc/source/filter/excel/xepivot.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/unoobj/dapiuno.cxx | 6 |
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; |