LCOV - code coverage report
Current view: top level - sc/source/core/data - dpresfilter.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 93 98 94.9 %
Date: 2015-06-13 12:38:46 Functions: 17 17 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include "dpresfilter.hxx"
      11             : #include "global.hxx"
      12             : 
      13             : #include <unotools/charclass.hxx>
      14             : #include <rtl/math.hxx>
      15             : 
      16             : #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
      17             : 
      18             : using namespace com::sun::star;
      19             : using namespace std;
      20             : 
      21         420 : ScDPResultFilter::ScDPResultFilter(const OUString& rDimName, bool bDataLayout) :
      22         420 :     maDimName(rDimName), mbHasValue(false), mbDataLayout(bDataLayout) {}
      23             : 
      24          91 : ScDPResultFilterContext::ScDPResultFilterContext() :
      25          91 :     mnCol(0), mnRow(0) {}
      26             : 
      27        1857 : size_t ScDPResultTree::NamePairHash::operator() (const NamePairType& rPair) const
      28             : {
      29             :     OUStringHash aHash;
      30        1857 :     return aHash(rPair.first) + aHash(rPair.second);
      31             : }
      32             : 
      33         393 : ScDPResultTree::DimensionNode::DimensionNode(const MemberNode* pParent) :
      34         393 :     mpParent(pParent) {}
      35             : 
      36         766 : ScDPResultTree::DimensionNode::~DimensionNode()
      37             : {
      38         383 :     MembersType::iterator it = maChildMembers.begin(), itEnd = maChildMembers.end();
      39        1743 :     for (; it != itEnd; ++it)
      40        1360 :         delete it->second;
      41         383 : }
      42             : 
      43             : #if DEBUG_PIVOT_TABLE
      44             : void ScDPResultTree::DimensionNode::dump(int nLevel) const
      45             : {
      46             :     string aIndent(nLevel*2, ' ');
      47             :     MembersType::const_iterator it = maChildMembers.begin(), itEnd = maChildMembers.end();
      48             :     for (; it != itEnd; ++it)
      49             :     {
      50             :         cout << aIndent << "member: ";
      51             :         const ScDPItemData& rVal = it->first;
      52             :         if (rVal.IsValue())
      53             :             cout << rVal.GetValue();
      54             :         else
      55             :             cout << rVal.GetString();
      56             :         cout << endl;
      57             : 
      58             :         it->second->dump(nLevel+1);
      59             :     }
      60             : }
      61             : #endif
      62             : 
      63        1609 : ScDPResultTree::MemberNode::MemberNode(const DimensionNode* pParent) :
      64        1609 :     mpParent(pParent) {}
      65             : 
      66        3160 : ScDPResultTree::MemberNode::~MemberNode()
      67             : {
      68        1580 :     DimensionsType::iterator it = maChildDimensions.begin(), itEnd = maChildDimensions.end();
      69        1963 :     for (; it != itEnd; ++it)
      70         383 :         delete it->second;
      71        1580 : }
      72             : 
      73             : #if DEBUG_PIVOT_TABLE
      74             : void ScDPResultTree::MemberNode::dump(int nLevel) const
      75             : {
      76             :     string aIndent(nLevel*2, ' ');
      77             :     ValuesType::const_iterator itVal = maValues.begin(), itValEnd = maValues.end();
      78             :     for (; itVal != itValEnd; ++itVal)
      79             :         cout << aIndent << "value: " << *itVal << endl;
      80             : 
      81             :     DimensionsType::const_iterator it = maChildDimensions.begin(), itEnd = maChildDimensions.end();
      82             :     for (; it != itEnd; ++it)
      83             :     {
      84             :         cout << aIndent << "dimension: " << it->first << endl;
      85             :         it->second->dump(nLevel+1);
      86             :     }
      87             : }
      88             : #endif
      89             : 
      90         213 : ScDPResultTree::ScDPResultTree() : mpRoot(new MemberNode(NULL)) {}
      91         422 : ScDPResultTree::~ScDPResultTree()
      92             : {
      93         211 :     delete mpRoot;
      94         211 : }
      95             : 
      96        1416 : void ScDPResultTree::add(
      97             :     const std::vector<ScDPResultFilter>& rFilters, long /*nCol*/, long /*nRow*/, double fVal)
      98             : {
      99             :     // TODO: I'll work on the col / row to value node mapping later.
     100             : 
     101        1416 :     const OUString* pDimName = NULL;
     102        1416 :     const OUString* pMemName = NULL;
     103        1416 :     MemberNode* pMemNode = mpRoot;
     104             : 
     105        1416 :     std::vector<ScDPResultFilter>::const_iterator itFilter = rFilters.begin(), itFilterEnd = rFilters.end();
     106        3790 :     for (; itFilter != itFilterEnd; ++itFilter)
     107             :     {
     108        2374 :         const ScDPResultFilter& filter = *itFilter;
     109        2374 :         if (filter.mbDataLayout)
     110          54 :             continue;
     111             : 
     112        2320 :         if (maPrimaryDimName.isEmpty())
     113          74 :             maPrimaryDimName = filter.maDimName;
     114             : 
     115             :         // See if this dimension exists.
     116        2320 :         DimensionsType& rDims = pMemNode->maChildDimensions;
     117        2320 :         OUString aUpperName = ScGlobal::pCharClass->uppercase(filter.maDimName);
     118        2320 :         DimensionsType::iterator itDim = rDims.find(aUpperName);
     119        2320 :         if (itDim == rDims.end())
     120             :         {
     121             :             // New dimenison.  Insert it.
     122             :             std::pair<DimensionsType::iterator, bool> r =
     123         393 :                 rDims.insert(DimensionsType::value_type(aUpperName, new DimensionNode(pMemNode)));
     124             : 
     125         393 :             if (!r.second)
     126             :                 // Insertion failed!
     127           0 :                 return;
     128             : 
     129         393 :             itDim = r.first;
     130             :         }
     131             : 
     132        2320 :         pDimName = &itDim->first;
     133             : 
     134             :         // Now, see if this dimension member exists.
     135        2320 :         DimensionNode* pDim = itDim->second;
     136        2320 :         MembersType& rMembers = pDim->maChildMembers;
     137        2320 :         aUpperName = ScGlobal::pCharClass->uppercase(filter.maValue);
     138        2320 :         MembersType::iterator itMem = rMembers.find(aUpperName);
     139        2320 :         if (itMem == rMembers.end())
     140             :         {
     141             :             // New member.  Insert it.
     142             :             std::pair<MembersType::iterator, bool> r =
     143             :                 rMembers.insert(
     144        1387 :                     MembersType::value_type(aUpperName, new MemberNode(pDim)));
     145             : 
     146        1387 :             if (!r.second)
     147             :                 // Insertion failed!
     148           0 :                 return;
     149             : 
     150        1387 :             itMem = r.first;
     151             :         }
     152             : 
     153        2320 :         pMemName = &itMem->first;
     154        2320 :         pMemNode = itMem->second;
     155        2320 :     }
     156             : 
     157        1416 :     if (pDimName && pMemName)
     158             :     {
     159             :         NamePairType aNames(
     160             :             ScGlobal::pCharClass->uppercase(*pDimName),
     161        1317 :             ScGlobal::pCharClass->uppercase(*pMemName));
     162             : 
     163        1317 :         LeafValuesType::iterator it = maLeafValues.find(aNames);
     164        1317 :         if (it == maLeafValues.end())
     165             :         {
     166             :             // This name pair doesn't exist.  Associate a new value for it.
     167         516 :             maLeafValues.insert(LeafValuesType::value_type(aNames, fVal));
     168             :         }
     169             :         else
     170             :         {
     171             :             // This name pair already exists. Set the value to NaN.
     172         801 :             rtl::math::setNan(&it->second);
     173        1317 :         }
     174             :     }
     175             : 
     176        1416 :     pMemNode->maValues.push_back(fVal);
     177             : }
     178             : 
     179          91 : void ScDPResultTree::swap(ScDPResultTree& rOther)
     180             : {
     181          91 :     std::swap(maPrimaryDimName, rOther.maPrimaryDimName);
     182          91 :     std::swap(mpRoot, rOther.mpRoot);
     183          91 :     maLeafValues.swap(rOther.maLeafValues);
     184          91 : }
     185             : 
     186          43 : bool ScDPResultTree::empty() const
     187             : {
     188          43 :     return mpRoot->maChildDimensions.empty();
     189             : }
     190             : 
     191           9 : void ScDPResultTree::clear()
     192             : {
     193           9 :     maPrimaryDimName = EMPTY_OUSTRING;
     194           9 :     delete mpRoot;
     195           9 :     mpRoot = new MemberNode(NULL);
     196           9 : }
     197             : 
     198          43 : const ScDPResultTree::ValuesType* ScDPResultTree::getResults(
     199             :     const uno::Sequence<sheet::DataPilotFieldFilter>& rFilters) const
     200             : {
     201          43 :     const sheet::DataPilotFieldFilter* p = rFilters.getConstArray();
     202          43 :     const sheet::DataPilotFieldFilter* pEnd = p + static_cast<size_t>(rFilters.getLength());
     203          43 :     const MemberNode* pMember = mpRoot;
     204         128 :     for (; p != pEnd; ++p)
     205             :     {
     206             :         DimensionsType::const_iterator itDim = pMember->maChildDimensions.find(
     207          45 :             ScGlobal::pCharClass->uppercase(p->FieldName));
     208             : 
     209          45 :         if (itDim == pMember->maChildDimensions.end())
     210             :             // Specified dimension not found.
     211          48 :             return NULL;
     212             : 
     213          21 :         const DimensionNode* pDim = itDim->second;
     214             :         MembersType::const_iterator itMem = pDim->maChildMembers.find(
     215          21 :             ScGlobal::pCharClass->uppercase(p->MatchValue));
     216             : 
     217          21 :         if (itMem == pDim->maChildMembers.end())
     218             :             // Specified member not found.
     219           0 :             return NULL;
     220             : 
     221          21 :         pMember = itMem->second;
     222             :     }
     223             : 
     224          19 :     return &pMember->maValues;
     225             : }
     226             : 
     227          24 : double ScDPResultTree::getLeafResult(const com::sun::star::sheet::DataPilotFieldFilter& rFilter) const
     228             : {
     229             :     NamePairType aPair(
     230             :         ScGlobal::pCharClass->uppercase(rFilter.FieldName),
     231          24 :         ScGlobal::pCharClass->uppercase(rFilter.MatchValue));
     232             : 
     233          24 :     LeafValuesType::const_iterator it = maLeafValues.find(aPair);
     234          24 :     if (it != maLeafValues.end())
     235             :         // Found!
     236          24 :         return it->second;
     237             : 
     238             :     // Not found.  Return an NaN.
     239             :     double fNan;
     240           0 :     rtl::math::setNan(&fNan);
     241           0 :     return fNan;
     242         156 : }
     243             : 
     244             : #if DEBUG_PIVOT_TABLE
     245             : void ScDPResultTree::dump() const
     246             : {
     247             :     cout << "primary dimension name: " << maPrimaryDimName << endl;
     248             :     mpRoot->dump(0);
     249             : }
     250             : #endif
     251             : 
     252             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11