summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-01-06 23:45:46 -0500
committerEike Rathke <erack@redhat.com>2014-01-08 12:52:53 +0000
commit83eb0b64980b405bc94ed19f3bcb60860f86e7d4 (patch)
tree16dc6907ccb674d1e7eadd446f91df2e106f5c80 /sc
parente8ac85752a2e07ceacb3b2f3e4eab3bc35a45c3d (diff)
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@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/dpresfilter.hxx12
-rw-r--r--sc/source/core/data/dpobject.cxx4
-rw-r--r--sc/source/core/data/dpresfilter.cxx44
-rw-r--r--sc/source/core/data/dptabsrc.cxx28
4 files changed, 79 insertions, 9 deletions
diff --git a/sc/inc/dpresfilter.hxx b/sc/inc/dpresfilter.hxx
index be84b8c83c2d..bc7ffc1f62b3 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 653bc0c3e4fd..3d9f5af641fb 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 968be6b424e7..41b2d7eb396d 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 96fe330ea7ce..08df85db78d3 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)