sc/inc/dpresfilter.hxx | 12 ++++++ sc/inc/dputil.hxx | 2 - sc/source/core/data/dpdimsave.cxx | 4 +- sc/source/core/data/dpgroup.cxx | 2 - sc/source/core/data/dpobject.cxx | 17 +++++--- sc/source/core/data/dpresfilter.cxx | 69 ++++++++++++++++++++++++++++++++---- sc/source/core/data/dptabsrc.cxx | 28 ++++++++++---- sc/source/core/data/dputil.cxx | 13 ++++-- 8 files changed, 119 insertions(+), 28 deletions(-)
New commits: commit 5428ccf34d212c2d38b159cfa0902dfba3e0f15a Author: Kohei Yoshida <[email protected]> Date: Tue Jan 7 22:13:07 2014 -0500 fdo#72774: Generate correct group items for the year group. This changes bring it back to the same algorithm used in 3.5. Change-Id: I16855cef1de133a1f886baa823d5b0d2b148e781 (cherry picked from commit c2e88a32314012afb799e321ec1d658f99f71781) diff --git a/sc/inc/dputil.hxx b/sc/inc/dputil.hxx index e4ed831..9568e95 100644 --- a/sc/inc/dputil.hxx +++ b/sc/inc/dputil.hxx @@ -45,7 +45,7 @@ public: SvNumberFormatter* pFormatter); static sal_Int32 getDatePartValue( - double fValue, const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, + double fValue, const ScDPNumGroupInfo* pInfo, sal_Int32 nDatePart, SvNumberFormatter* pFormatter); static OUString getDisplayedMeasureName(const OUString& rName, ScSubTotalFunc eFunc); diff --git a/sc/source/core/data/dpdimsave.cxx b/sc/source/core/data/dpdimsave.cxx index 16f68b8..2db4023 100644 --- a/sc/source/core/data/dpdimsave.cxx +++ b/sc/source/core/data/dpdimsave.cxx @@ -338,8 +338,8 @@ void fillDateGroupDimension( { case sheet::DataPilotFieldGroupBy::YEARS: nStart = ScDPUtil::getDatePartValue( - fSourceMin, rDateInfo, sheet::DataPilotFieldGroupBy::YEARS, pFormatter); - nEnd = ScDPUtil::getDatePartValue(fSourceMax, rDateInfo, sheet::DataPilotFieldGroupBy::YEARS, pFormatter); + fSourceMin, NULL, sheet::DataPilotFieldGroupBy::YEARS, pFormatter); + nEnd = ScDPUtil::getDatePartValue(fSourceMax, NULL, sheet::DataPilotFieldGroupBy::YEARS, pFormatter); break; case sheet::DataPilotFieldGroupBy::QUARTERS: nStart = 1; nEnd = 4; break; case sheet::DataPilotFieldGroupBy::MONTHS: nStart = 1; nEnd = 12; break; diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx index 1e8059a..6a9f824 100644 --- a/sc/source/core/data/dpgroup.cxx +++ b/sc/source/core/data/dpgroup.cxx @@ -911,7 +911,7 @@ void ScDPGroupTableData::FillGroupValues(vector<SCROW>& rItems, const vector<lon { SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); sal_Int32 nPartValue = ScDPUtil::getDatePartValue( - pData->GetValue(), *pNumInfo, nDatePart, pFormatter); + pData->GetValue(), pNumInfo, nDatePart, pFormatter); ScDPItemData aItem(nDatePart, nPartValue); rItems[i] = pCache->GetIdByItemData(nColumn, aItem); diff --git a/sc/source/core/data/dputil.cxx b/sc/source/core/data/dputil.cxx index e34bc79..558e189 100644 --- a/sc/source/core/data/dputil.cxx +++ b/sc/source/core/data/dputil.cxx @@ -294,16 +294,19 @@ OUString ScDPUtil::getNumGroupName( } sal_Int32 ScDPUtil::getDatePartValue( - double fValue, const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, + double fValue, const ScDPNumGroupInfo* pInfo, sal_Int32 nDatePart, SvNumberFormatter* pFormatter) { // Start and end are inclusive // (End date without a time value is included, with a time value it's not) - if (fValue < rInfo.mfStart && !rtl::math::approxEqual(fValue, rInfo.mfStart)) - return ScDPItemData::DateFirst; - if (fValue > rInfo.mfEnd && !rtl::math::approxEqual(fValue, rInfo.mfEnd)) - return ScDPItemData::DateLast; + if (pInfo) + { + if (fValue < pInfo->mfStart && !rtl::math::approxEqual(fValue, pInfo->mfStart)) + return ScDPItemData::DateFirst; + if (fValue > pInfo->mfEnd && !rtl::math::approxEqual(fValue, pInfo->mfEnd)) + return ScDPItemData::DateLast; + } sal_Int32 nResult = 0; commit ee5c8db96bf353b158461e4ca516f338b5086d2f Author: Kohei Yoshida <[email protected]> Date: Tue Jan 7 16:36:55 2014 -0500 fdo#72774: Ensure that all the group fields are in cache upon file load. This resolves the originally reported issue in that bug (in Comment 1). Change-Id: I6fb85cff1eafb78d784605aa08e7d992a1ac36e0 (cherry picked from commit 256e4ccba8a331f2d30c6b5da9dca70206deadae) diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index f9344aa..3ade4cf 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -2858,6 +2858,9 @@ const ScDPCache* ScDPCollection::SheetCaches::getCache(const ScRange& rRange, co return NULL; } + if (pDimData) + pDimData->WriteToCache(*itCache->second); + return itCache->second; } commit 365e32d373fba0a6f1fc3e9b1647c756130a4b8a Author: Kohei Yoshida <[email protected]> Date: Tue Jan 7 00:48:10 2014 -0500 fdo#72645: Case-insensitive string comparison in GETPIVOTDATA. Change-Id: Ibdb2b7ab2bae03875a3462816e860f58d9076457 diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 3d9f5af..f9344aa 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -1321,24 +1321,24 @@ namespace { class FindByName : std::unary_function<const ScDPSaveDimension*, bool> { - OUString maName; + OUString maName; // must be all uppercase. public: FindByName(const OUString& rName) : maName(rName) {} bool operator() (const ScDPSaveDimension* pDim) const { // Layout name takes precedence. const OUString* pLayoutName = pDim->GetLayoutName(); - if (pLayoutName && *pLayoutName == maName) + if (pLayoutName && ScGlobal::pCharClass->uppercase(*pLayoutName) == maName) return true; sheet::GeneralFunction eGenFunc = static_cast<sheet::GeneralFunction>(pDim->GetFunction()); ScSubTotalFunc eFunc = ScDPUtil::toSubTotalFunc(eGenFunc); OUString aSrcName = ScDPUtil::getSourceDimensionName(pDim->GetName()); OUString aFuncName = ScDPUtil::getDisplayedMeasureName(aSrcName, eFunc); - if (maName == aFuncName) + if (maName == ScGlobal::pCharClass->uppercase(aFuncName)) return true; - return maName == aSrcName; + return maName == ScGlobal::pCharClass->uppercase(aSrcName); } }; @@ -1382,7 +1382,9 @@ double ScDPObject::GetPivotData(const OUString& rDataFieldName, std::vector<shee return fRet; std::vector<const ScDPSaveDimension*>::iterator it = std::find_if( - aDataDims.begin(), aDataDims.end(), FindByName(rDataFieldName)); + aDataDims.begin(), aDataDims.end(), + FindByName(ScGlobal::pCharClass->uppercase(rDataFieldName))); + if (it == aDataDims.end()) return fRet; diff --git a/sc/source/core/data/dpresfilter.cxx b/sc/source/core/data/dpresfilter.cxx index 41b2d7e..d4895b8 100644 --- a/sc/source/core/data/dpresfilter.cxx +++ b/sc/source/core/data/dpresfilter.cxx @@ -10,6 +10,7 @@ #include "dpresfilter.hxx" #include "global.hxx" +#include <unotools/charclass.hxx> #include <rtl/math.hxx> #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> @@ -113,12 +114,13 @@ void ScDPResultTree::add( // See if this dimension exists. DimensionsType& rDims = pMemNode->maChildDimensions; - DimensionsType::iterator itDim = rDims.find(filter.maDimName); + OUString aUpperName = ScGlobal::pCharClass->uppercase(filter.maDimName); + DimensionsType::iterator itDim = rDims.find(aUpperName); if (itDim == rDims.end()) { // New dimenison. Insert it. std::pair<DimensionsType::iterator, bool> r = - rDims.insert(DimensionsType::value_type(filter.maDimName, new DimensionNode(pMemNode))); + rDims.insert(DimensionsType::value_type(aUpperName, new DimensionNode(pMemNode))); if (!r.second) // Insertion failed! @@ -132,13 +134,14 @@ void ScDPResultTree::add( // Now, see if this dimension member exists. DimensionNode* pDim = itDim->second; MembersType& rMembers = pDim->maChildMembers; - MembersType::iterator itMem = rMembers.find(filter.maValue); + aUpperName = ScGlobal::pCharClass->uppercase(filter.maValue); + MembersType::iterator itMem = rMembers.find(aUpperName); if (itMem == rMembers.end()) { // New member. Insert it. std::pair<MembersType::iterator, bool> r = rMembers.insert( - MembersType::value_type(filter.maValue, new MemberNode(pDim))); + MembersType::value_type(aUpperName, new MemberNode(pDim))); if (!r.second) // Insertion failed! @@ -153,7 +156,10 @@ void ScDPResultTree::add( if (pDimName && pMemName) { - NamePairType aNames(*pDimName, *pMemName); + NamePairType aNames( + ScGlobal::pCharClass->uppercase(*pDimName), + ScGlobal::pCharClass->uppercase(*pMemName)); + LeafValuesType::iterator it = maLeafValues.find(aNames); if (it == maLeafValues.end()) { @@ -197,13 +203,17 @@ const ScDPResultTree::ValuesType* ScDPResultTree::getResults( const MemberNode* pMember = mpRoot; for (; p != pEnd; ++p) { - DimensionsType::const_iterator itDim = pMember->maChildDimensions.find(p->FieldName); + DimensionsType::const_iterator itDim = pMember->maChildDimensions.find( + ScGlobal::pCharClass->uppercase(p->FieldName)); + if (itDim == pMember->maChildDimensions.end()) // Specified dimension not found. return NULL; const DimensionNode* pDim = itDim->second; - MembersType::const_iterator itMem = pDim->maChildMembers.find(p->MatchValue); + MembersType::const_iterator itMem = pDim->maChildMembers.find( + ScGlobal::pCharClass->uppercase(p->MatchValue)); + if (itMem == pDim->maChildMembers.end()) // Specified member not found. return NULL; @@ -216,7 +226,10 @@ const ScDPResultTree::ValuesType* ScDPResultTree::getResults( double ScDPResultTree::getLeafResult(const com::sun::star::sheet::DataPilotFieldFilter& rFilter) const { - NamePairType aPair(rFilter.FieldName, rFilter.MatchValue); + NamePairType aPair( + ScGlobal::pCharClass->uppercase(rFilter.FieldName), + ScGlobal::pCharClass->uppercase(rFilter.MatchValue)); + LeafValuesType::const_iterator it = maLeafValues.find(aPair); if (it != maLeafValues.end()) // Found! commit 3521016b2820b36d1447b4dd33604707a08b091d Author: Kohei Yoshida <[email protected]> Date: Mon Jan 6 23:45:46 2014 -0500 fdo#72645: Allow GETPIVOTDATA to get result from leaf node of result tree. Change-Id: I0fc1fd069440ed6fee378fc2dfd2ed761afbdeab diff --git a/sc/inc/dpresfilter.hxx b/sc/inc/dpresfilter.hxx index be84b8c..bc7ffc1 100644 --- a/sc/inc/dpresfilter.hxx +++ b/sc/inc/dpresfilter.hxx @@ -15,6 +15,7 @@ #include <map> #include <vector> #include <boost/noncopyable.hpp> +#include <boost/unordered_map.hpp> namespace com { namespace sun { namespace star { namespace sheet { @@ -85,6 +86,15 @@ private: #endif }; + typedef std::pair<OUString, OUString> NamePairType; + + struct NamePairHash + { + size_t operator() (const NamePairType& rPair) const; + }; + typedef boost::unordered_map<NamePairType, double, NamePairHash> LeafValuesType; + LeafValuesType maLeafValues; + OUString maPrimaryDimName; MemberNode* mpRoot; @@ -115,6 +125,8 @@ public: const com::sun::star::uno::Sequence< com::sun::star::sheet::DataPilotFieldFilter>& rFilters) const; + double getLeafResult(const com::sun::star::sheet::DataPilotFieldFilter& rFilter) const; + #if DEBUG_PIVOT_TABLE void dump() const; #endif diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 653bc0c..3d9f5af 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -1328,8 +1328,8 @@ public: { // Layout name takes precedence. const OUString* pLayoutName = pDim->GetLayoutName(); - if (pLayoutName) - return *pLayoutName == maName; + if (pLayoutName && *pLayoutName == maName) + return true; sheet::GeneralFunction eGenFunc = static_cast<sheet::GeneralFunction>(pDim->GetFunction()); ScSubTotalFunc eFunc = ScDPUtil::toSubTotalFunc(eGenFunc); diff --git a/sc/source/core/data/dpresfilter.cxx b/sc/source/core/data/dpresfilter.cxx index 968be6b..41b2d7e 100644 --- a/sc/source/core/data/dpresfilter.cxx +++ b/sc/source/core/data/dpresfilter.cxx @@ -10,6 +10,8 @@ #include "dpresfilter.hxx" #include "global.hxx" +#include <rtl/math.hxx> + #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> using namespace com::sun::star; @@ -21,6 +23,12 @@ ScDPResultFilter::ScDPResultFilter(const OUString& rDimName, bool bDataLayout) : ScDPResultFilterContext::ScDPResultFilterContext() : mnCol(0), mnRow(0) {} +size_t ScDPResultTree::NamePairHash::operator() (const NamePairType& rPair) const +{ + OUStringHash aHash; + return aHash(rPair.first) + aHash(rPair.second); +} + ScDPResultTree::DimensionNode::DimensionNode(const MemberNode* pParent) : mpParent(pParent) {} @@ -89,6 +97,8 @@ void ScDPResultTree::add( { // TODO: I'll work on the col / row to value node mapping later. + const OUString* pDimName = NULL; + const OUString* pMemName = NULL; MemberNode* pMemNode = mpRoot; std::vector<ScDPResultFilter>::const_iterator itFilter = rFilters.begin(), itFilterEnd = rFilters.end(); @@ -117,6 +127,8 @@ void ScDPResultTree::add( itDim = r.first; } + pDimName = &itDim->first; + // Now, see if this dimension member exists. DimensionNode* pDim = itDim->second; MembersType& rMembers = pDim->maChildMembers; @@ -135,9 +147,26 @@ void ScDPResultTree::add( itMem = r.first; } + pMemName = &itMem->first; pMemNode = itMem->second; } + if (pDimName && pMemName) + { + NamePairType aNames(*pDimName, *pMemName); + LeafValuesType::iterator it = maLeafValues.find(aNames); + if (it == maLeafValues.end()) + { + // This name pair doesn't exist. Associate a new value for it. + maLeafValues.insert(LeafValuesType::value_type(aNames, fVal)); + } + else + { + // This name pair already exists. Set the value to NaN. + rtl::math::setNan(&it->second); + } + } + pMemNode->maValues.push_back(fVal); } @@ -145,6 +174,7 @@ void ScDPResultTree::swap(ScDPResultTree& rOther) { std::swap(maPrimaryDimName, rOther.maPrimaryDimName); std::swap(mpRoot, rOther.mpRoot); + maLeafValues.swap(rOther.maLeafValues); } bool ScDPResultTree::empty() const @@ -184,6 +214,20 @@ const ScDPResultTree::ValuesType* ScDPResultTree::getResults( return &pMember->maValues; } +double ScDPResultTree::getLeafResult(const com::sun::star::sheet::DataPilotFieldFilter& rFilter) const +{ + NamePairType aPair(rFilter.FieldName, rFilter.MatchValue); + LeafValuesType::const_iterator it = maLeafValues.find(aPair); + if (it != maLeafValues.end()) + // Found! + return it->second; + + // Not found. Return an NaN. + double fNan; + rtl::math::setNan(&fNan); + return fNan; +} + #if DEBUG_PIVOT_TABLE void ScDPResultTree::dump() const { diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx index 96fe330..08df85d 100644 --- a/sc/source/core/data/dptabsrc.cxx +++ b/sc/source/core/data/dptabsrc.cxx @@ -423,15 +423,29 @@ uno::Sequence<double> ScDPSource::getFilteredResults( // Get result values from the tree. const ScDPResultTree::ValuesType* pVals = maResFilterSet.getResults(aFilters); - if (!pVals) - return uno::Sequence<double>(); + if (pVals) + { + size_t n = pVals->size(); + uno::Sequence<double> aRet(n); + for (size_t i = 0; i < n; ++i) + aRet[i] = (*pVals)[i]; - size_t n = pVals->size(); - uno::Sequence<double> aRet(n); - for (size_t i = 0; i < n; ++i) - aRet[i] = (*pVals)[i]; + return aRet; + } - return aRet; + if (aFilters.getLength() == 1) + { + // Try to get result from the leaf nodes. + double fVal = maResFilterSet.getLeafResult(aFilters[0]); + if (!rtl::math::isNan(fVal)) + { + uno::Sequence<double> aRet(1); + aRet[0] = fVal; + return aRet; + } + } + + return uno::Sequence<double>(); } void SAL_CALL ScDPSource::refresh() throw(uno::RuntimeException) _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
