[Libreoffice-commits] core.git: Branch 'libreoffice-4-1' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Jan 8 04:53:17 PST 2014


 sc/inc/dpresfilter.hxx              |   12 +++++++++
 sc/source/core/data/dpobject.cxx    |    4 +--
 sc/source/core/data/dpresfilter.cxx |   44 ++++++++++++++++++++++++++++++++++++
 sc/source/core/data/dptabsrc.cxx    |   28 +++++++++++++++++-----
 4 files changed, 79 insertions(+), 9 deletions(-)

New commits:
commit 83eb0b64980b405bc94ed19f3bcb60860f86e7d4
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
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
    Reviewed-on: https://gerrit.libreoffice.org/7284
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>

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)


More information about the Libreoffice-commits mailing list