From cfc9cef1e26e98153eb93229a9c18a674a3ebf11 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 6 Dec 2013 10:43:38 -0500 Subject: [PATCH 043/109] fdo#69518: Correctly handle the old constraint syntax. We apparently support this syntax for ODF-backward compatibility. To fix this, I resurrected ScDPObject::ParseFilters() which was removed as unused, adjusted it for the String->OUString change, and changed the filter data structure to the UNO one rather than using the old one we no longer use elsewhere. (cherry picked from commit 1d85c8df2fb9cb25fc524485339ae9f11e8da676) Conflicts: sc/inc/dpobject.hxx sc/source/core/data/dpobject.cxx sc/source/core/tool/interpr2.cxx Change-Id: If52b38aaa1e8b208fb0ef9d92a6e853decdf43e3 Reviewed-on: https://gerrit.libreoffice.org/6962 Reviewed-by: Eike Rathke Tested-by: Eike Rathke --- sc/inc/dpobject.hxx | 8 +- sc/inc/dpoutput.hxx | 21 ----- sc/source/core/data/dpobject.cxx | 163 ++++++++++++++++++++------------------- sc/source/core/tool/interpr2.cxx | 15 ++++ 4 files changed, 103 insertions(+), 104 deletions(-) diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 735b033..8505a53 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -183,9 +183,11 @@ public: const OUString& rDataFieldName, std::vector& rFilters); - bool ParseFilters( ScDPGetPivotDataField& rTarget, - std::vector< ScDPGetPivotDataField >& rFilters, - const OUString& rFilterList ); + bool ParseFilters( + OUString& rDataFieldName, + std::vector& rFilters, + std::vector& rFilterFuncs, + const OUString& rFilterList ); void GetMemberResultNames(ScDPUniqueStringSet& rNames, long nDimension); diff --git a/sc/inc/dpoutput.hxx b/sc/inc/dpoutput.hxx index 293d937..7b38c7e 100644 --- a/sc/inc/dpoutput.hxx +++ b/sc/inc/dpoutput.hxx @@ -41,29 +41,8 @@ namespace com { namespace sun { namespace star { namespace sheet { class Rectangle; class ScDocument; - struct ScDPOutLevelData; - -struct ScDPGetPivotDataField -{ - OUString maFieldName; - com::sun::star::sheet::GeneralFunction meFunction; - - bool mbValIsStr; - OUString maValStr; - double mnValNum; - - ScDPGetPivotDataField() : - meFunction( com::sun::star::sheet::GeneralFunction_NONE ), - mbValIsStr( false ), - mnValNum( 0.0 ) - { - } -}; - - - class ScDPOutput { private: diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 3a45a34..677ccd5 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -1400,25 +1400,27 @@ void ScDPObject::GetMemberResultNames(ScDPUniqueStringSet& rNames, long nDimensi pOutput->GetMemberResultNames(rNames, nDimension); // used only with table data -> level not needed } -static bool lcl_Dequote( const String& rSource, xub_StrLen nStartPos, xub_StrLen& rEndPos, String& rResult ) +namespace { + +bool dequote( const OUString& rSource, sal_Int32 nStartPos, sal_Int32& rEndPos, OUString& rResult ) { // nStartPos has to point to opening quote bool bRet = false; const sal_Unicode cQuote = '\''; - if ( rSource.GetChar(nStartPos) == cQuote ) + if (rSource[nStartPos] == cQuote) { OUStringBuffer aBuffer; - xub_StrLen nPos = nStartPos + 1; - const xub_StrLen nLen = rSource.Len(); + sal_Int32 nPos = nStartPos + 1; + const sal_Int32 nLen = rSource.getLength(); while ( nPos < nLen ) { - const sal_Unicode cNext = rSource.GetChar(nPos); + const sal_Unicode cNext = rSource[nPos]; if ( cNext == cQuote ) { - if ( nPos+1 < nLen && rSource.GetChar(nPos+1) == cQuote ) + if (nPos+1 < nLen && rSource[nPos+1] == cQuote) { // double quote is used for an embedded quote aBuffer.append( cNext ); // append one quote @@ -1449,7 +1451,7 @@ struct ScGetPivotDataFunctionEntry sheet::GeneralFunction eFunc; }; -static bool lcl_ParseFunction( const String& rList, xub_StrLen nStartPos, xub_StrLen& rEndPos, sheet::GeneralFunction& rFunc ) +bool parseFunction( const OUString& rList, sal_Int32 nStartPos, sal_Int32& rEndPos, sheet::GeneralFunction& rFunc ) { static const ScGetPivotDataFunctionEntry aFunctions[] = { @@ -1471,22 +1473,22 @@ static bool lcl_ParseFunction( const String& rList, xub_StrLen nStartPos, xub_St { "StdDevp", sheet::GeneralFunction_STDEVP } }; - const xub_StrLen nListLen = rList.Len(); - while ( nStartPos < nListLen && rList.GetChar(nStartPos) == ' ' ) + const sal_Int32 nListLen = rList.getLength(); + while (nStartPos < nListLen && rList[nStartPos] == ' ') ++nStartPos; bool bParsed = false; bool bFound = false; - String aFuncStr; - xub_StrLen nFuncEnd = 0; - if ( nStartPos < nListLen && rList.GetChar(nStartPos) == '\'' ) - bParsed = lcl_Dequote( rList, nStartPos, nFuncEnd, aFuncStr ); + OUString aFuncStr; + sal_Int32 nFuncEnd = 0; + if (nStartPos < nListLen && rList[nStartPos] == '\'') + bParsed = dequote( rList, nStartPos, nFuncEnd, aFuncStr ); else { - nFuncEnd = rList.Search( static_cast(']'), nStartPos ); - if ( nFuncEnd != STRING_NOTFOUND ) + nFuncEnd = rList.indexOf(']', nStartPos); + if (nFuncEnd >= 0) { - aFuncStr = rList.Copy( nStartPos, nFuncEnd - nStartPos ); + aFuncStr = rList.copy(nStartPos, nFuncEnd - nStartPos); bParsed = true; } } @@ -1498,12 +1500,12 @@ static bool lcl_ParseFunction( const String& rList, xub_StrLen nStartPos, xub_St const sal_Int32 nFuncCount = sizeof(aFunctions) / sizeof(aFunctions[0]); for ( sal_Int32 nFunc=0; nFunc(']'), nStartPos ); - if ( nClosePos != STRING_NOTFOUND ) + sal_Int32 nClosePos = rList.indexOf(']', nStartPos); + if (nClosePos >= 0) { - xub_StrLen nNameEnd = nClosePos; - xub_StrLen nSemiPos = rList.Search( static_cast(';'), nStartPos ); - if ( nSemiPos != STRING_NOTFOUND && nSemiPos < nClosePos && pFunc ) + sal_Int32 nNameEnd = nClosePos; + sal_Int32 nSemiPos = rList.indexOf(';', nStartPos); + if (nSemiPos >= 0 && nSemiPos < nClosePos && pFunc) { - xub_StrLen nFuncEnd = 0; - if ( lcl_ParseFunction( rList, nSemiPos + 1, nFuncEnd, *pFunc ) ) + sal_Int32 nFuncEnd = 0; + if (parseFunction(rList, nSemiPos+1, nFuncEnd, *pFunc)) nNameEnd = nSemiPos; } - aDequoted = rList.Copy( nStartPos, nNameEnd - nStartPos ); + aDequoted = rList.copy(nStartPos, nNameEnd - nStartPos); // spaces before the closing bracket or semicolon aDequoted = comphelper::string::stripEnd(aDequoted, ' '); nQuoteEnd = nClosePos + 1; @@ -1589,26 +1592,26 @@ static bool lcl_IsAtStart( const String& rList, const String& rSearch, sal_Int32 if ( bParsed && ScGlobal::GetpTransliteration()->isEqual( aDequoted, rSearch ) ) { nMatchList = nQuoteEnd; // match count in the list string, including quotes - nMatchSearch = rSearch.Len(); + nMatchSearch = rSearch.getLength(); } } else { // otherwise look for search string at the start of rList - ScGlobal::GetpTransliteration()->equals( rList, 0, rList.Len(), nMatchList, - rSearch, 0, rSearch.Len(), nMatchSearch ); + ScGlobal::GetpTransliteration()->equals( + rList, 0, rList.getLength(), nMatchList, rSearch, 0, rSearch.getLength(), nMatchSearch); } - if ( nMatchSearch == rSearch.Len() ) + if (nMatchSearch == rSearch.getLength()) { // search string is at start of rList - look for following space or end of string bool bValid = false; - if ( sal::static_int_cast(nMatchList) >= rList.Len() ) + if ( sal::static_int_cast(nMatchList) >= rList.getLength() ) bValid = true; else { - sal_Unicode cNext = rList.GetChar(sal::static_int_cast(nMatchList)); + sal_Unicode cNext = rList[nMatchList]; if ( cNext == ' ' || ( bAllowBracket && cNext == '[' ) ) bValid = true; } @@ -1623,17 +1626,20 @@ static bool lcl_IsAtStart( const String& rList, const String& rSearch, sal_Int32 return false; } -bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget, - std::vector< ScDPGetPivotDataField >& rFilters, - const OUString& rFilterList ) +} // anonymous namespace + +bool ScDPObject::ParseFilters( + OUString& rDataFieldName, + std::vector& rFilters, + std::vector& rFilterFuncs, const OUString& rFilterList ) { // parse the string rFilterList into parameters for GetPivotData CreateObjects(); // create xSource if not already done - std::vector aDataNames; // data fields (source name) - std::vector aGivenNames; // data fields (compound name) - std::vector aFieldNames; // column/row/data fields + std::vector aDataNames; // data fields (source name) + std::vector aGivenNames; // data fields (compound name) + std::vector aFieldNames; // column/row/data fields std::vector< uno::Sequence > aFieldValues; // @@ -1691,7 +1697,7 @@ bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget, { uno::Reference xMembers = xLevSupp->getMembers(); - String aFieldName( xLevNam->getName() ); + OUString aFieldName( xLevNam->getName() ); uno::Sequence aMemberNames( xMembers->getElementNames() ); aFieldNames.push_back( aFieldName ); @@ -1713,8 +1719,8 @@ bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget, bool bError = false; bool bHasData = false; - String aRemaining(comphelper::string::strip(rFilterList, ' ')); - while ( aRemaining.Len() && !bError ) + OUString aRemaining(comphelper::string::strip(rFilterList, ' ')); + while (!aRemaining.isEmpty() && !bError) { bool bUsed = false; @@ -1722,17 +1728,17 @@ bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget, for ( SCSIZE nDataPos=0; nDataPos(nMatched) ); + rDataFieldName = aFound; + aRemaining = aRemaining.copy(nMatched); bHasData = true; bUsed = true; } @@ -1740,21 +1746,21 @@ bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget, // look for field name - String aSpecField; + OUString aSpecField; bool bHasFieldName = false; if ( !bUsed ) { sal_Int32 nMatched = 0; for ( SCSIZE nField=0; nField(nMatched) ); + aRemaining = aRemaining.copy(nMatched); aRemaining = comphelper::string::stripStart(aRemaining, ' '); // field name has to be followed by item name in brackets - if ( aRemaining.GetChar(0) == '[' ) + if (!aRemaining.isEmpty() && aRemaining[0] == '[') { bHasFieldName = true; // bUsed remains false - still need the item @@ -1774,8 +1780,8 @@ bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget, { bool bItemFound = false; sal_Int32 nMatched = 0; - String aFoundName; - String aFoundValue; + OUString aFoundName; + OUString aFoundValue; sheet::GeneralFunction eFunc = sheet::GeneralFunction_NONE; sheet::GeneralFunction eFoundFunc = sheet::GeneralFunction_NONE; @@ -1790,7 +1796,7 @@ bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget, const OUString* pItemArr = rItems.getConstArray(); for ( sal_Int32 nItem=0; nItem(nMatched) ); + sheet::DataPilotFieldFilter aField; + aField.FieldName = aFoundName; + aField.MatchValue = aFoundValue; + rFilters.push_back(aField); + rFilterFuncs.push_back(eFoundFunc); + aRemaining = aRemaining.copy(nMatched); } } @@ -1831,7 +1834,7 @@ bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget, if ( !bError && !bHasData && aDataNames.size() == 1 ) { // if there's only one data field, its name need not be specified - rTarget.maFieldName = aDataNames[0]; + rDataFieldName = aDataNames[0]; bHasData = true; } diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index 7cc59de..a0f270d 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -3005,6 +3005,21 @@ void ScInterpreter::ScGetPivotData() return; } + if (bOldSyntax) + { + OUString aFilterStr = aDataFieldName; + std::vector aFilterFuncs; + if (!pDPObj->ParseFilters(aDataFieldName, aFilters, aFilterFuncs, aFilterStr)) + { + PushError(errNoRef); + return; + } + + // TODO : For now, we ignore filter functions since we couldn't find a + // live example of how they are supposed to be used. We'll support + // this again once we come across a real-world example. + } + double fVal = pDPObj->GetPivotData(aDataFieldName, aFilters); if (rtl::math::isNan(fVal)) { -- 1.8.4.2