LCOV - code coverage report
Current view: top level - sc/source/core/data - colorscale.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 143 420 34.0 %
Date: 2012-08-25 Functions: 27 67 40.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 97 530 18.3 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
       4                 :            :  *
       5                 :            :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :            :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :            :  * the License or as specified alternatively below. You may obtain a copy of
       8                 :            :  * the License at http://www.mozilla.org/MPL/
       9                 :            :  *
      10                 :            :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :            :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :            :  * for the specific language governing rights and limitations under the
      13                 :            :  * License.
      14                 :            :  *
      15                 :            :  * Major Contributor(s):
      16                 :            :  * Copyright (C) 2012 Markus Mohrhard <markus.mohrhard@googlemail.com> (initial developer)
      17                 :            :  *
      18                 :            :  * All Rights Reserved.
      19                 :            :  *
      20                 :            :  * For minor contributions see the git repository.
      21                 :            :  *
      22                 :            :  * Alternatively, the contents of this file may be used under the terms of
      23                 :            :  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      24                 :            :  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
      25                 :            :  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
      26                 :            :  * instead of those above.
      27                 :            :  */
      28                 :            : 
      29                 :            : #include "colorscale.hxx"
      30                 :            : #include "document.hxx"
      31                 :            : #include "cell.hxx"
      32                 :            : #include "fillinfo.hxx"
      33                 :            : #if DUMP_FORMAT_INFO
      34                 :            : #include <iostream>
      35                 :            : #endif
      36                 :            : 
      37                 :          0 : ScColorScaleEntry::ScColorScaleEntry():
      38                 :            :     mnVal(0),
      39                 :            :     mpCell(NULL),
      40                 :          0 :     meType(COLORSCALE_VALUE)
      41                 :            : {
      42                 :          0 : }
      43                 :            : 
      44                 :         27 : ScColorScaleEntry::ScColorScaleEntry(double nVal, const Color& rCol):
      45                 :            :     mnVal(nVal),
      46                 :            :     maColor(rCol),
      47                 :            :     mpCell(NULL),
      48                 :         27 :     meType(COLORSCALE_VALUE)
      49                 :            : {
      50                 :         27 : }
      51                 :            : 
      52                 :          0 : ScColorScaleEntry::ScColorScaleEntry(const ScColorScaleEntry& rEntry):
      53                 :            :     mnVal(rEntry.mnVal),
      54                 :            :     maColor(rEntry.maColor),
      55                 :            :     mpCell(),
      56                 :          0 :     meType(rEntry.meType)
      57                 :            : {
      58                 :          0 : }
      59                 :            : 
      60                 :          0 : ScColorScaleEntry::ScColorScaleEntry(ScDocument* pDoc, const ScColorScaleEntry& rEntry):
      61                 :            :     mnVal(rEntry.mnVal),
      62                 :            :     maColor(rEntry.maColor),
      63                 :            :     mpCell(),
      64                 :          0 :     meType(rEntry.meType)
      65                 :            : {
      66         [ #  # ]:          0 :     if(rEntry.mpCell)
      67                 :            :     {
      68 [ #  # ][ #  # ]:          0 :         mpCell.reset(static_cast<ScFormulaCell*>(rEntry.mpCell->Clone(*pDoc, SC_CLONECELL_NOMAKEABS_EXTERNAL)));
                 [ #  # ]
      69         [ #  # ]:          0 :         mpCell->StartListeningTo( pDoc );
      70                 :            :     }
      71                 :          0 : }
      72                 :            : 
      73                 :          0 : ScColorScaleEntry::~ScColorScaleEntry()
      74                 :            : {
      75                 :          0 : }
      76                 :            : 
      77                 :          3 : void ScColorScaleEntry::SetFormula( const rtl::OUString& rFormula, ScDocument* pDoc, const ScAddress& rAddr, formula::FormulaGrammar::Grammar eGrammar )
      78                 :            : {
      79         [ +  - ]:          3 :     mpCell.reset(new ScFormulaCell( pDoc, rAddr, rFormula, eGrammar ));
      80                 :          3 :     mpCell->StartListeningTo( pDoc );
      81                 :          3 : }
      82                 :            : 
      83                 :          0 : const ScTokenArray* ScColorScaleEntry::GetFormula() const
      84                 :            : {
      85         [ #  # ]:          0 :     if(mpCell)
      86                 :            :     {
      87                 :          0 :         return mpCell->GetCode();
      88                 :            :     }
      89                 :            : 
      90                 :          0 :     return NULL;
      91                 :            : }
      92                 :            : 
      93                 :          0 : rtl::OUString ScColorScaleEntry::GetFormula( formula::FormulaGrammar::Grammar eGrammar ) const
      94                 :            : {
      95                 :          0 :     rtl::OUString aFormula;
      96         [ #  # ]:          0 :     if(mpCell)
      97                 :            :     {
      98         [ #  # ]:          0 :         mpCell->GetFormula(aFormula, eGrammar);
      99                 :            :     }
     100                 :            : 
     101                 :          0 :     return aFormula;
     102                 :            : }
     103                 :            : 
     104                 :          0 : double ScColorScaleEntry::GetValue() const
     105                 :            : {
     106         [ #  # ]:          0 :     if(mpCell)
     107                 :            :     {
     108                 :          0 :         mpCell->Interpret();
     109         [ #  # ]:          0 :         if(mpCell->IsValue())
     110                 :          0 :             return mpCell->GetValue();
     111                 :            : 
     112                 :          0 :         return std::numeric_limits<double>::max();
     113                 :            :     }
     114                 :            : 
     115                 :          0 :     return mnVal;
     116                 :            : }
     117                 :            : 
     118                 :          0 : void ScColorScaleEntry::SetValue(double nValue)
     119                 :            : {
     120                 :          0 :     mnVal = nValue;
     121                 :          0 : }
     122                 :            : 
     123                 :          0 : void ScColorScaleEntry::UpdateMoveTab( SCTAB nOldTab, SCTAB nNewTab, SCTAB nTabNo )
     124                 :            : {
     125         [ #  # ]:          0 :     if(mpCell)
     126                 :            :     {
     127                 :          0 :         mpCell->UpdateMoveTab( nOldTab, nNewTab, nTabNo );
     128                 :            :     }
     129                 :          0 : }
     130                 :            : 
     131                 :          0 : void ScColorScaleEntry::UpdateReference( UpdateRefMode eUpdateRefMode,
     132                 :            :             const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
     133                 :            : {
     134         [ #  # ]:          0 :     if(mpCell)
     135                 :            :     {
     136                 :          0 :         mpCell->UpdateReference( eUpdateRefMode, rRange, nDx, nDy, nDz );
     137                 :            :     }
     138                 :          0 : }
     139                 :            : 
     140                 :         36 : const Color& ScColorScaleEntry::GetColor() const
     141                 :            : {
     142                 :         36 :     return maColor;
     143                 :            : }
     144                 :            : 
     145                 :          0 : void ScColorScaleEntry::SetColor(const Color& rColor)
     146                 :            : {
     147                 :          0 :     maColor = rColor;
     148                 :          0 : }
     149                 :            : 
     150                 :         12 : ScColorFormat::ScColorFormat(ScDocument* pDoc):
     151                 :         12 :     ScFormatEntry(pDoc)
     152                 :            : {
     153                 :         12 : }
     154                 :            : 
     155                 :          0 : ScColorFormat::~ScColorFormat()
     156                 :            : {
     157         [ #  # ]:          0 : }
     158                 :            : 
     159                 :         12 : void ScColorFormat::SetParent( ScConditionalFormat* pParent )
     160                 :            : {
     161                 :         12 :     mpParent = pParent;
     162                 :         12 : }
     163                 :            : 
     164                 :         12 : ScColorScaleFormat::ScColorScaleFormat(ScDocument* pDoc):
     165         [ +  - ]:         12 :     ScColorFormat(pDoc)
     166                 :            : {
     167                 :         12 : }
     168                 :            : 
     169                 :          0 : ScColorScaleFormat::ScColorScaleFormat(ScDocument* pDoc, const ScColorScaleFormat& rFormat):
     170         [ #  # ]:          0 :     ScColorFormat(pDoc)
     171                 :            : {
     172 [ #  # ][ #  # ]:          0 :     for(const_iterator itr = rFormat.begin(); itr != rFormat.end(); ++itr)
         [ #  # ][ #  # ]
                 [ #  # ]
     173                 :            :     {
     174 [ #  # ][ #  # ]:          0 :         maColorScales.push_back(new ScColorScaleEntry(pDoc, *itr));
         [ #  # ][ #  # ]
     175                 :            :     }
     176                 :          0 : }
     177                 :            : 
     178                 :          0 : ScColorFormat* ScColorScaleFormat::Clone(ScDocument* pDoc) const
     179                 :            : {
     180         [ #  # ]:          0 :     return new ScColorScaleFormat(pDoc, *this);
     181                 :            : }
     182                 :            : 
     183         [ #  # ]:          0 : ScColorScaleFormat::~ScColorScaleFormat()
     184                 :            : {
     185         [ #  # ]:          0 : }
     186                 :            : 
     187                 :         27 : void ScColorScaleFormat::AddEntry( ScColorScaleEntry* pEntry )
     188                 :            : {
     189                 :         27 :     maColorScales.push_back( pEntry );
     190                 :         27 : }
     191                 :            : 
     192                 :         24 : void ScColorScaleEntry::SetType( ScColorScaleEntryType eType )
     193                 :            : {
     194                 :         24 :     meType = eType;
     195         [ +  + ]:         24 :     if(eType != COLORSCALE_FORMULA)
     196                 :         21 :         mpCell.reset();
     197                 :         24 : }
     198                 :            : 
     199                 :        108 : ScColorScaleEntryType ScColorScaleEntry::GetType() const
     200                 :            : {
     201                 :        108 :     return meType;
     202                 :            : }
     203                 :            : 
     204                 :            : namespace {
     205                 :            : 
     206                 :         18 : double getMinValue(const ScRange& rRange, ScDocument* pDoc)
     207                 :            : {
     208                 :         18 :     double aMinValue = std::numeric_limits<double>::max();
     209                 :            :     //iterate through columns
     210                 :         18 :     SCTAB nTab = rRange.aStart.Tab();
     211         [ +  + ]:         54 :     for(SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
     212                 :            :     {
     213         [ +  + ]:        144 :         for(SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
     214                 :            :         {
     215                 :        108 :             ScAddress aAddr(nCol, nRow, rRange.aStart.Tab());
     216         [ +  - ]:        108 :             CellType eType = pDoc->GetCellType(aAddr);
     217         [ +  - ]:        108 :             if(eType == CELLTYPE_VALUE)
     218                 :            :             {
     219         [ +  - ]:        108 :                 double aVal = pDoc->GetValue(nCol, nRow, nTab);
     220         [ +  + ]:        108 :                 if( aVal < aMinValue )
     221                 :         18 :                     aMinValue = aVal;
     222                 :            :             }
     223         [ #  # ]:          0 :             else if(eType == CELLTYPE_FORMULA)
     224                 :            :             {
     225 [ #  # ][ #  # ]:          0 :                 if(static_cast<ScFormulaCell*>(pDoc->GetCell(aAddr))->IsValue())
         [ #  # ][ #  # ]
     226                 :            :                 {
     227         [ #  # ]:          0 :                     double aVal = pDoc->GetValue(nCol, nRow, nTab);
     228         [ #  # ]:          0 :                     if( aVal < aMinValue )
     229                 :          0 :                         aMinValue = aVal;
     230                 :            :                 }
     231                 :            :             }
     232                 :            :         }
     233                 :            :     }
     234                 :         18 :     return aMinValue;
     235                 :            : }
     236                 :            : 
     237                 :         18 : double getMaxValue(const ScRange& rRange, ScDocument* pDoc)
     238                 :            : {
     239                 :         18 :     double aMaxValue = std::numeric_limits<double>::min();
     240                 :            :     //iterate through columns
     241                 :         18 :     SCTAB nTab = rRange.aStart.Tab();
     242         [ +  + ]:         54 :     for(SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
     243                 :            :     {
     244         [ +  + ]:        144 :         for(SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
     245                 :            :         {
     246                 :        108 :             ScAddress aAddr(nCol, nRow, rRange.aStart.Tab());
     247         [ +  - ]:        108 :             CellType eType = pDoc->GetCellType(aAddr);
     248         [ +  - ]:        108 :             if(eType == CELLTYPE_VALUE)
     249                 :            :             {
     250         [ +  - ]:        108 :                 double aVal = pDoc->GetValue(nCol, nRow, nTab);
     251         [ +  - ]:        108 :                 if( aVal > aMaxValue )
     252                 :        108 :                     aMaxValue = aVal;
     253                 :            :             }
     254         [ #  # ]:          0 :             else if(eType == CELLTYPE_FORMULA)
     255                 :            :             {
     256 [ #  # ][ #  # ]:          0 :                 if(static_cast<ScFormulaCell*>(pDoc->GetCell(aAddr))->IsValue())
         [ #  # ][ #  # ]
     257                 :            :                 {
     258         [ #  # ]:          0 :                     double aVal = pDoc->GetValue(nCol, nRow, nTab);
     259         [ #  # ]:          0 :                     if( aVal > aMaxValue )
     260                 :          0 :                         aMaxValue = aVal;
     261                 :            :                 }
     262                 :            :             }
     263                 :            :         }
     264                 :            :     }
     265                 :         18 :     return aMaxValue;
     266                 :            : }
     267                 :            : 
     268                 :         18 : double getMinValue(const ScRangeList& rList, ScDocument* pDoc)
     269                 :            : {
     270                 :         18 :     double aMinValue = std::numeric_limits<double>::max();
     271                 :            : 
     272                 :         18 :     size_t n = rList.size();
     273         [ +  + ]:         36 :     for(size_t i = 0; i < n; ++i)
     274                 :            :     {
     275                 :         18 :         const ScRange* pRange = rList[i];
     276                 :         18 :         double aVal = getMinValue(*pRange, pDoc);
     277         [ +  - ]:         18 :         if( aVal < aMinValue )
     278                 :         18 :             aMinValue = aVal;
     279                 :            :     }
     280                 :         18 :     return aMinValue;
     281                 :            : }
     282                 :            : 
     283                 :         18 : double getMaxValue(const ScRangeList& rList, ScDocument* pDoc)
     284                 :            : {
     285                 :         18 :     double aMaxVal = std::numeric_limits<double>::min();
     286                 :            : 
     287                 :         18 :     size_t n = rList.size();
     288         [ +  + ]:         36 :     for(size_t i = 0; i < n; ++i)
     289                 :            :     {
     290                 :         18 :         const ScRange* pRange = rList[i];
     291                 :         18 :         double aVal = getMaxValue(*pRange, pDoc);
     292         [ +  - ]:         18 :         if( aVal > aMaxVal )
     293                 :         18 :             aMaxVal = aVal;
     294                 :            :     }
     295                 :            : 
     296                 :         18 :     return aMaxVal;
     297                 :            : }
     298                 :            : 
     299                 :            : }
     300                 :            : 
     301                 :         18 : double ScColorScaleFormat::GetMinValue() const
     302                 :            : {
     303         [ +  - ]:         18 :     const_iterator itr = maColorScales.begin();
     304                 :            : 
     305 [ +  - ][ +  - ]:         18 :     if(itr->GetType() == COLORSCALE_VALUE || itr->GetType() == COLORSCALE_FORMULA)
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
                 [ -  + ]
     306 [ #  # ][ #  # ]:          0 :         return itr->GetValue();
     307                 :            :     else
     308                 :            :     {
     309 [ +  - ][ +  - ]:         18 :         return getMinValue(GetRange(), mpDoc);
     310                 :            :     }
     311                 :            : }
     312                 :            : 
     313                 :         18 : double ScColorScaleFormat::GetMaxValue() const
     314                 :            : {
     315         [ +  - ]:         18 :     ColorScaleEntries::const_reverse_iterator itr = maColorScales.rbegin();
     316                 :            : 
     317 [ +  - ][ +  - ]:         18 :     if(itr->GetType() == COLORSCALE_VALUE || itr->GetType() == COLORSCALE_FORMULA)
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
                 [ -  + ]
     318 [ #  # ][ #  # ]:          0 :         return itr->GetValue();
     319                 :            :     else
     320                 :            :     {
     321 [ +  - ][ +  - ]:         18 :         return getMaxValue(GetRange(), mpDoc);
     322                 :            :     }
     323                 :            : }
     324                 :            : 
     325                 :         18 : void ScColorScaleFormat::calcMinMax(double& rMin, double& rMax) const
     326                 :            : {
     327                 :         18 :     rMin = GetMinValue();
     328                 :         18 :     rMax = GetMaxValue();
     329                 :         18 : }
     330                 :            : 
     331                 :         39 : const ScRangeList& ScColorFormat::GetRange() const
     332                 :            : {
     333                 :         39 :     return mpParent->GetRange();
     334                 :            : }
     335                 :            : 
     336                 :          0 : void ScColorFormat::getValues(std::vector<double>& rValues) const
     337                 :            : {
     338                 :          0 :     size_t n = GetRange().size();
     339                 :          0 :     const ScRangeList& aRanges = GetRange();
     340         [ #  # ]:          0 :     for(size_t i = 0; i < n; ++i)
     341                 :            :     {
     342                 :          0 :         const ScRange* pRange = aRanges[i];
     343                 :          0 :         SCTAB nTab = pRange->aStart.Tab();
     344         [ #  # ]:          0 :         for(SCCOL nCol = pRange->aStart.Col(); nCol <= pRange->aEnd.Col(); ++nCol)
     345                 :            :         {
     346         [ #  # ]:          0 :             for(SCCOL nRow = pRange->aStart.Row(); nRow <= pRange->aEnd.Row(); ++nRow)
     347                 :            :             {
     348                 :          0 :                 ScAddress aAddr(nCol, nRow, nTab);
     349         [ #  # ]:          0 :                 CellType eType = mpDoc->GetCellType(aAddr);
     350         [ #  # ]:          0 :                 if(eType == CELLTYPE_VALUE)
     351                 :            :                 {
     352         [ #  # ]:          0 :                     double aVal = mpDoc->GetValue(nCol, nRow, nTab);
     353         [ #  # ]:          0 :                     rValues.push_back(aVal);
     354                 :            :                 }
     355         [ #  # ]:          0 :                 else if(eType == CELLTYPE_FORMULA)
     356                 :            :                 {
     357 [ #  # ][ #  # ]:          0 :                     if(static_cast<ScFormulaCell*>(mpDoc->GetCell(aAddr))->IsValue())
         [ #  # ][ #  # ]
     358                 :            :                     {
     359         [ #  # ]:          0 :                         double aVal = mpDoc->GetValue(nCol, nRow, nTab);
     360         [ #  # ]:          0 :                         rValues.push_back(aVal);
     361                 :            :                     }
     362                 :            :                 }
     363                 :            :             }
     364                 :            :         }
     365                 :            :     }
     366                 :          0 : }
     367                 :            : 
     368                 :            : namespace {
     369                 :            : 
     370                 :         54 : sal_uInt8 GetColorValue( double nVal, double nVal1, sal_uInt8 nColVal1, double nVal2, sal_uInt8 nColVal2 )
     371                 :            : {
     372         [ +  + ]:         54 :     if (nVal <= nVal1)
     373                 :          9 :         return nColVal1;
     374                 :            : 
     375         [ +  + ]:         45 :     if (nVal >= nVal2)
     376                 :          9 :         return nColVal2;
     377                 :            : 
     378                 :         36 :     sal_uInt8 nColVal = static_cast<sal_uInt8>((nVal - nVal1)/(nVal2-nVal1)*(nColVal2-nColVal1))+nColVal1;
     379                 :         54 :     return nColVal;
     380                 :            : }
     381                 :            : 
     382                 :         18 : Color CalcColor( double nVal, double nVal1, const Color& rCol1, double nVal2, const Color& rCol2)
     383                 :            : {
     384                 :         18 :     sal_uInt8 nColRed = GetColorValue(nVal, nVal1, rCol1.GetRed(), nVal2, rCol2.GetRed());
     385                 :         18 :     sal_uInt8 nColBlue = GetColorValue(nVal, nVal1, rCol1.GetBlue(), nVal2, rCol2.GetBlue());
     386                 :         18 :     sal_uInt8 nColGreen = GetColorValue(nVal, nVal1, rCol1.GetGreen(), nVal2, rCol2.GetGreen());
     387                 :            : 
     388                 :         18 :     return Color(nColRed, nColGreen, nColBlue);
     389                 :            : }
     390                 :            : 
     391                 :          0 : double GetPercentile( std::vector<double>& rArray, double fPercentile )
     392                 :            : {
     393                 :          0 :     size_t nSize = rArray.size();
     394                 :          0 :     size_t nIndex = (size_t)::rtl::math::approxFloor( fPercentile * (nSize-1));
     395                 :          0 :     double fDiff = fPercentile * (nSize-1) - ::rtl::math::approxFloor( fPercentile * (nSize-1));
     396         [ #  # ]:          0 :     std::vector<double>::iterator iter = rArray.begin() + nIndex;
     397         [ #  # ]:          0 :     ::std::nth_element( rArray.begin(), iter, rArray.end());
     398         [ #  # ]:          0 :     if (fDiff == 0.0)
     399         [ #  # ]:          0 :         return *iter;
     400                 :            :     else
     401                 :            :     {
     402         [ #  # ]:          0 :         double fVal = *iter;
     403 [ #  # ][ #  # ]:          0 :         iter = rArray.begin() + nIndex+1;
     404         [ #  # ]:          0 :         ::std::nth_element( rArray.begin(), iter, rArray.end());
     405         [ #  # ]:          0 :         return fVal + fDiff * (*iter - fVal);
     406                 :            :     }
     407                 :            : }
     408                 :            : 
     409                 :            : }
     410                 :            : 
     411                 :         36 : double ScColorScaleFormat::CalcValue(double nMin, double nMax, ScColorScaleFormat::const_iterator& itr) const
     412                 :            : {
     413   [ -  +  -  +  :         36 :     switch(itr->GetType())
                -  -  - ]
     414                 :            :     {
     415                 :            :         case COLORSCALE_PERCENT:
     416                 :          0 :             return nMin + (nMax-nMin)*(itr->GetValue()/100);
     417                 :            :         case COLORSCALE_MIN:
     418                 :         18 :             return nMin;
     419                 :            :         case COLORSCALE_AUTOMIN:
     420         [ #  # ]:          0 :             return std::min<double>(0, nMin);
     421                 :            :         case COLORSCALE_MAX:
     422                 :         18 :             return nMax;
     423                 :            :         case COLORSCALE_AUTOMAX:
     424         [ #  # ]:          0 :             return std::max<double>(0, nMax);
     425                 :            :         case COLORSCALE_PERCENTILE:
     426                 :            :         {
     427         [ #  # ]:          0 :             std::vector<double> aValues;
     428         [ #  # ]:          0 :             getValues(aValues);
     429         [ #  # ]:          0 :             if(aValues.size() == 1)
     430         [ #  # ]:          0 :                 return aValues[0];
     431                 :            :             else
     432                 :            :             {
     433 [ #  # ][ #  # ]:          0 :                 double fPercentile = itr->GetValue()/100.0;
     434         [ #  # ]:          0 :                 return GetPercentile(aValues, fPercentile);
     435                 :          0 :             }
     436                 :            :         }
     437                 :            : 
     438                 :            :         default:
     439                 :          0 :         break;
     440                 :            :     }
     441                 :            : 
     442                 :         36 :     return itr->GetValue();
     443                 :            : }
     444                 :            : 
     445                 :         18 : Color* ScColorScaleFormat::GetColor( const ScAddress& rAddr ) const
     446                 :            : {
     447         [ +  - ]:         18 :     CellType eCellType = mpDoc->GetCellType(rAddr);
     448 [ -  + ][ #  # ]:         18 :     if(eCellType != CELLTYPE_VALUE && eCellType != CELLTYPE_FORMULA)
     449                 :          0 :         return NULL;
     450                 :            : 
     451         [ -  + ]:         18 :     if (eCellType == CELLTYPE_FORMULA)
     452                 :            :     {
     453 [ #  # ][ #  # ]:          0 :         if(!static_cast<ScFormulaCell*>(mpDoc->GetCell(rAddr))->IsValue())
         [ #  # ][ #  # ]
     454                 :          0 :             return NULL;
     455                 :            :     }
     456                 :            : 
     457                 :            :     // now we have for sure a value
     458         [ +  - ]:         18 :     double nVal = mpDoc->GetValue(rAddr);
     459                 :            : 
     460         [ -  + ]:         18 :     if (maColorScales.size() < 2)
     461                 :          0 :         return NULL;
     462                 :            : 
     463                 :         18 :     double nMin = std::numeric_limits<double>::max();
     464                 :         18 :     double nMax = std::numeric_limits<double>::min();
     465         [ +  - ]:         18 :     calcMinMax(nMin, nMax);
     466                 :            : 
     467                 :            :     // this check is for safety
     468         [ -  + ]:         18 :     if(nMin >= nMax)
     469                 :          0 :         return NULL;
     470                 :            : 
     471         [ +  - ]:         18 :     const_iterator itr = begin();
     472         [ +  - ]:         18 :     double nValMin = CalcValue(nMin, nMax, itr);
     473 [ +  - ][ +  - ]:         18 :     Color rColMin = itr->GetColor();
     474         [ +  - ]:         18 :     ++itr;
     475         [ +  - ]:         18 :     double nValMax = CalcValue(nMin, nMax, itr);
     476 [ +  - ][ +  - ]:         18 :     Color rColMax = itr->GetColor();
     477                 :            : 
     478         [ +  - ]:         18 :     ++itr;
     479 [ +  - ][ +  - ]:         18 :     while(itr != end() && nVal > nValMax)
         [ -  + ][ #  # ]
                 [ +  - ]
           [ -  +  #  # ]
     480                 :            :     {
     481                 :          0 :         rColMin = rColMax;
     482                 :          0 :         nValMin = nValMax;
     483 [ #  # ][ #  # ]:          0 :         rColMax = itr->GetColor();
     484         [ #  # ]:          0 :         nValMax = CalcValue(nMin, nMax, itr);
     485         [ #  # ]:          0 :         ++itr;
     486                 :            :     }
     487                 :            : 
     488                 :         18 :     Color aColor = CalcColor(nVal, nValMin, rColMin, nValMax, rColMax);
     489                 :            : 
     490         [ +  - ]:         18 :     return new Color(aColor);
     491                 :            : }
     492                 :            : 
     493                 :            : #if DUMP_FORMAT_INFO
     494                 :          3 : void ScColorScaleFormat::dumpInfo() const
     495                 :            : {
     496                 :          3 :     std::cout << "Color Scale" << std::endl;
     497                 :          3 :     const ScRangeList& rRange = GetRange();
     498                 :          3 :     size_t n = rRange.size();
     499         [ +  + ]:          6 :     for(size_t i = 0; i < n; ++i)
     500                 :            :     {
     501                 :          3 :         const ScRange* pRange = rRange[i];
     502                 :          3 :         SCTAB nTab = pRange->aStart.Tab();
     503         [ +  + ]:          9 :         for( SCCOL nCol = pRange->aStart.Col(), nEndCol = pRange->aEnd.Col(); nCol <= nEndCol; ++nCol)
     504                 :            :         {
     505         [ +  + ]:         24 :             for( SCROW nRow = pRange->aStart.Row(), nEndRow = pRange->aEnd.Row(); nRow <= nEndRow; ++nRow)
     506                 :            :             {
     507         [ +  - ]:         18 :                 boost::scoped_ptr<Color> pColor( GetColor(ScAddress(nCol, nRow, nTab)) );
     508 [ +  - ][ +  - ]:         18 :                 std::cout << nCol << "," << nRow << "," << nTab << ",";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     509 [ +  - ][ +  - ]:         18 :                 std::cout << ((int)pColor->GetRed()) << "," << ((int)pColor->GetGreen()) << "," << ((int)pColor->GetBlue());
         [ +  - ][ +  - ]
                 [ +  - ]
     510         [ +  - ]:         18 :                 std::cout << std::endl;
     511         [ +  - ]:         18 :             }
     512                 :            :         }
     513                 :            :     }
     514                 :          3 : }
     515                 :            : #endif
     516                 :            : 
     517                 :          0 : void ScColorScaleFormat::UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab)
     518                 :            : {
     519                 :          0 :     SCTAB nThisTab = GetRange().front()->aStart.Tab();
     520 [ #  # ][ #  # ]:          0 :     for(iterator itr = begin(); itr != end(); ++itr)
         [ #  # ][ #  # ]
                 [ #  # ]
     521                 :            :     {
     522 [ #  # ][ #  # ]:          0 :         itr->UpdateMoveTab(nOldTab, nNewTab, nThisTab);
     523                 :            :     }
     524                 :          0 : }
     525                 :            : 
     526                 :          0 : void ScColorScaleFormat::UpdateReference( UpdateRefMode eUpdateRefMode,
     527                 :            :             const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
     528                 :            : {
     529 [ #  # ][ #  # ]:          0 :     for(iterator itr = begin(); itr != end(); ++itr)
         [ #  # ][ #  # ]
                 [ #  # ]
     530                 :            :     {
     531 [ #  # ][ #  # ]:          0 :         itr->UpdateReference(eUpdateRefMode, rRange, nDx, nDy, nDz);
     532                 :            :     }
     533                 :          0 : }
     534                 :            : 
     535                 :          0 : bool ScColorScaleFormat::CheckEntriesForRel(const ScRange& rRange) const
     536                 :            : {
     537                 :          0 :     bool bNeedUpdate = false;
     538 [ #  # ][ #  # ]:          0 :     for(const_iterator itr = begin(); itr != end(); ++itr)
         [ #  # ][ #  # ]
                 [ #  # ]
     539                 :            :     {
     540 [ #  # ][ #  # ]:          0 :         ScColorScaleEntryType eType = itr->GetType();
     541      [ #  #  # ]:          0 :         switch(eType)
     542                 :            :         {
     543                 :            :             case COLORSCALE_MIN:
     544                 :            :             case COLORSCALE_MAX:
     545                 :            :             case COLORSCALE_AUTOMIN:
     546                 :            :             case COLORSCALE_AUTOMAX:
     547                 :          0 :                 bNeedUpdate = true;
     548                 :          0 :                 break;
     549                 :            :             case COLORSCALE_FORMULA:
     550                 :          0 :                 return true;
     551                 :            :             default:
     552                 :          0 :                 break;
     553                 :            :         }
     554                 :            :     }
     555                 :            : 
     556                 :            :     // TODO: check also if the changed value is the new min/max
     557                 :            :     // or has been the old min/max value
     558 [ #  # ][ #  # ]:          0 :     bNeedUpdate = bNeedUpdate && GetRange().Intersects(rRange);
     559                 :          0 :     return bNeedUpdate;
     560                 :            : }
     561                 :            : 
     562                 :          0 : void ScColorScaleFormat::DataChanged(const ScRange& rRange)
     563                 :            : {
     564                 :          0 :     bool bNeedUpdate = CheckEntriesForRel(rRange);
     565         [ #  # ]:          0 :     if(bNeedUpdate)
     566                 :            :     {
     567                 :          0 :         size_t n = GetRange().size();
     568         [ #  # ]:          0 :         for(size_t i = 0; i < n; ++i)
     569                 :            :         {
     570                 :          0 :             const ScRange* pRange = GetRange()[i];
     571                 :          0 :             mpDoc->RepaintRange(*pRange);
     572                 :            :         }
     573                 :            :     }
     574                 :          0 : }
     575                 :            : 
     576                 :         12 : condformat::ScFormatEntryType ScColorScaleFormat::GetType() const
     577                 :            : {
     578                 :         12 :     return condformat::COLORSCALE;
     579                 :            : }
     580                 :            : 
     581                 :          0 : ScColorScaleFormat::iterator ScColorScaleFormat::begin()
     582                 :            : {
     583                 :          0 :     return maColorScales.begin();
     584                 :            : }
     585                 :            : 
     586                 :         18 : ScColorScaleFormat::const_iterator ScColorScaleFormat::begin() const
     587                 :            : {
     588                 :         18 :     return maColorScales.begin();
     589                 :            : }
     590                 :            : 
     591                 :          0 : ScColorScaleFormat::iterator ScColorScaleFormat::end()
     592                 :            : {
     593                 :          0 :     return maColorScales.end();
     594                 :            : }
     595                 :            : 
     596                 :         18 : ScColorScaleFormat::const_iterator ScColorScaleFormat::end() const
     597                 :            : {
     598                 :         18 :     return maColorScales.end();
     599                 :            : }
     600                 :            : 
     601                 :          0 : size_t ScColorScaleFormat::size() const
     602                 :            : {
     603                 :          0 :     return maColorScales.size();
     604                 :            : }
     605                 :            : 
     606                 :          0 : ScDataBarFormat::ScDataBarFormat(ScDocument* pDoc):
     607                 :          0 :     ScColorFormat(pDoc)
     608                 :            : {
     609                 :          0 : }
     610                 :            : 
     611                 :          0 : ScDataBarFormat::ScDataBarFormat(ScDocument* pDoc, const ScDataBarFormat& rFormat):
     612                 :            :     ScColorFormat(pDoc),
     613 [ #  # ][ #  # ]:          0 :     mpFormatData(new ScDataBarFormatData(*rFormat.mpFormatData))
     614                 :            : {
     615                 :          0 : }
     616                 :            : 
     617                 :          0 : void ScDataBarFormat::SetDataBarData( ScDataBarFormatData* pData )
     618                 :            : {
     619                 :          0 :     mpFormatData.reset(pData);
     620                 :          0 : }
     621                 :            : 
     622                 :          0 : const ScDataBarFormatData* ScDataBarFormat::GetDataBarData() const
     623                 :            : {
     624                 :          0 :     return mpFormatData.get();
     625                 :            : }
     626                 :            : 
     627                 :          0 : ScColorFormat* ScDataBarFormat::Clone(ScDocument* pDoc) const
     628                 :            : {
     629         [ #  # ]:          0 :     return new ScDataBarFormat(pDoc, *this);
     630                 :            : }
     631                 :            : 
     632                 :          0 : condformat::ScFormatEntryType ScDataBarFormat::GetType() const
     633                 :            : {
     634                 :          0 :     return condformat::DATABAR;
     635                 :            : }
     636                 :            : 
     637                 :          0 : void ScDataBarFormat::UpdateReference( UpdateRefMode eRefMode,
     638                 :            :             const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
     639                 :            : {
     640                 :          0 :     mpFormatData->mpUpperLimit->UpdateReference( eRefMode, rRange, nDx, nDy, nDz );
     641                 :          0 :     mpFormatData->mpLowerLimit->UpdateReference( eRefMode, rRange, nDx, nDy, nDz );
     642                 :          0 : }
     643                 :            : 
     644                 :            : namespace {
     645                 :            : 
     646                 :          0 : bool NeedUpdate(ScColorScaleEntry* pEntry)
     647                 :            : {
     648         [ #  # ]:          0 :     switch(pEntry->GetType())
     649                 :            :     {
     650                 :            :         case COLORSCALE_MIN:
     651                 :            :         case COLORSCALE_MAX:
     652                 :            :         case COLORSCALE_FORMULA:
     653                 :            :         case COLORSCALE_AUTOMIN:
     654                 :            :         case COLORSCALE_AUTOMAX:
     655                 :          0 :             return true;
     656                 :            :         default:
     657                 :          0 :             return false;
     658                 :            :     }
     659                 :            : }
     660                 :            : 
     661                 :            : }
     662                 :            : 
     663                 :          0 : void ScDataBarFormat::DataChanged(const ScRange& rRange)
     664                 :            : {
     665                 :          0 :     bool bNeedUpdate = false;
     666                 :            : 
     667                 :          0 :     bNeedUpdate = NeedUpdate(mpFormatData->mpUpperLimit.get());
     668                 :          0 :     bNeedUpdate &= NeedUpdate(mpFormatData->mpLowerLimit.get());
     669                 :            : 
     670                 :          0 :     bNeedUpdate &= GetRange().Intersects(rRange);
     671                 :            : 
     672         [ #  # ]:          0 :     if(bNeedUpdate)
     673                 :            :     {
     674                 :          0 :         size_t n = GetRange().size();
     675         [ #  # ]:          0 :         for(size_t i = 0; i < n; ++i)
     676                 :            :         {
     677                 :          0 :             const ScRange* pRange = GetRange()[i];
     678                 :          0 :             mpDoc->RepaintRange(*pRange);
     679                 :            :         }
     680                 :            :     }
     681                 :          0 : }
     682                 :            : 
     683                 :          0 : void ScDataBarFormat::UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab)
     684                 :            : {
     685                 :          0 :     SCTAB nThisTab = GetRange().front()->aStart.Tab();
     686                 :          0 :     mpFormatData->mpUpperLimit->UpdateMoveTab(nOldTab, nNewTab, nThisTab);
     687                 :          0 :     mpFormatData->mpLowerLimit->UpdateMoveTab(nOldTab, nNewTab, nThisTab);
     688                 :          0 : }
     689                 :            : 
     690                 :          0 : double ScDataBarFormat::getMin(double nMin, double nMax) const
     691                 :            : {
     692   [ #  #  #  #  :          0 :     switch(mpFormatData->mpLowerLimit->GetType())
                      # ]
     693                 :            :     {
     694                 :            :         case COLORSCALE_MIN:
     695                 :          0 :             return nMin;
     696                 :            : 
     697                 :            :         case COLORSCALE_AUTOMIN:
     698         [ #  # ]:          0 :             return std::min<double>(0, nMin);
     699                 :            : 
     700                 :            :         case COLORSCALE_PERCENT:
     701                 :          0 :             return nMin + (nMax-nMin)/100*mpFormatData->mpLowerLimit->GetValue();
     702                 :            : 
     703                 :            :         case COLORSCALE_PERCENTILE:
     704                 :            :         {
     705         [ #  # ]:          0 :             double fPercentile = mpFormatData->mpLowerLimit->GetValue()/100.0;
     706         [ #  # ]:          0 :             std::vector<double> aValues;
     707         [ #  # ]:          0 :             getValues(aValues);
     708         [ #  # ]:          0 :             return GetPercentile(aValues, fPercentile);
     709                 :            :         }
     710                 :            : 
     711                 :            :         default:
     712                 :          0 :         break;
     713                 :            :     }
     714                 :            : 
     715                 :          0 :     return mpFormatData->mpLowerLimit->GetValue();
     716                 :            : }
     717                 :            : 
     718                 :          0 : double ScDataBarFormat::getMax(double nMin, double nMax) const
     719                 :            : {
     720   [ #  #  #  #  :          0 :     switch(mpFormatData->mpUpperLimit->GetType())
                      # ]
     721                 :            :     {
     722                 :            :         case COLORSCALE_MAX:
     723                 :          0 :             return nMax;
     724                 :            :         case COLORSCALE_AUTOMAX:
     725         [ #  # ]:          0 :             return std::max<double>(0, nMax);
     726                 :            :         case COLORSCALE_PERCENT:
     727                 :          0 :             return nMin + (nMax-nMin)/100*mpFormatData->mpUpperLimit->GetValue();
     728                 :            :         case COLORSCALE_PERCENTILE:
     729                 :            :         {
     730         [ #  # ]:          0 :             double fPercentile = mpFormatData->mpUpperLimit->GetValue()/100.0;
     731         [ #  # ]:          0 :             std::vector<double> aValues;
     732         [ #  # ]:          0 :             getValues(aValues);
     733         [ #  # ]:          0 :             return GetPercentile(aValues, fPercentile);
     734                 :            :         }
     735                 :            : 
     736                 :            :         default:
     737                 :          0 :             break;
     738                 :            :     }
     739                 :            : 
     740                 :          0 :     return mpFormatData->mpUpperLimit->GetValue();
     741                 :            : }
     742                 :            : 
     743                 :          0 : ScDataBarInfo* ScDataBarFormat::GetDataBarInfo(const ScAddress& rAddr) const
     744                 :            : {
     745                 :          0 :     CellType eCellType = mpDoc->GetCellType(rAddr);
     746 [ #  # ][ #  # ]:          0 :     if(eCellType != CELLTYPE_VALUE && eCellType != CELLTYPE_FORMULA)
     747                 :          0 :         return NULL;
     748                 :            : 
     749         [ #  # ]:          0 :     if (eCellType == CELLTYPE_FORMULA)
     750                 :            :     {
     751 [ #  # ][ #  # ]:          0 :         if(!static_cast<ScFormulaCell*>(mpDoc->GetCell(rAddr))->IsValue())
     752                 :          0 :             return NULL;
     753                 :            :     }
     754                 :            : 
     755                 :            :     // now we have for sure a value
     756                 :            :     //
     757                 :          0 :     double nValMin = getMinValue(GetRange(), mpDoc);
     758                 :          0 :     double nValMax = getMaxValue(GetRange(), mpDoc);
     759                 :          0 :     double nMin = getMin(nValMin, nValMax);
     760                 :          0 :     double nMax = getMax(nValMin, nValMax);
     761                 :            : 
     762                 :            : 
     763                 :          0 :     double nValue = mpDoc->GetValue(rAddr);
     764                 :            : 
     765                 :          0 :     ScDataBarInfo* pInfo = new ScDataBarInfo();
     766         [ #  # ]:          0 :     if(mpFormatData->meAxisPosition == databar::NONE)
     767                 :            :     {
     768         [ #  # ]:          0 :         if(nValue <= nMin)
     769                 :            :         {
     770                 :          0 :             pInfo->mnLength = 0;
     771                 :            :         }
     772         [ #  # ]:          0 :         else if(nValue >= nMax)
     773                 :            :         {
     774                 :          0 :             pInfo->mnLength = 100;
     775                 :            :         }
     776                 :            :         else
     777                 :            :         {
     778                 :          0 :             double nDiff = nMax - nMin;
     779                 :          0 :             pInfo->mnLength = (nValue - nMin)/nDiff*100.0;
     780                 :            :         }
     781                 :          0 :         pInfo->mnZero = 0;
     782                 :            :     }
     783                 :            :     else
     784                 :            :     {
     785                 :          0 :         double nMinPositive = 0;
     786                 :          0 :         double nMaxNegative = 0;
     787                 :            :         //calculate the zero position first
     788         [ #  # ]:          0 :         if(mpFormatData->meAxisPosition == databar::AUTOMATIC)
     789                 :            :         {
     790         [ #  # ]:          0 :             if(nMin < 0)
     791                 :            :             {
     792         [ #  # ]:          0 :                 if(nMax < 0)
     793                 :          0 :                     pInfo->mnZero = 100;
     794                 :            :                 else
     795                 :            :                 {
     796                 :          0 :                     pInfo->mnZero = -100*nMin/(nMax-nMin);
     797                 :            :                 }
     798                 :            :             }
     799                 :            :             else
     800                 :          0 :                 pInfo->mnZero = 0;
     801                 :            : 
     802                 :            :             // if max or min is used we may need to adjust it
     803                 :            :             // for the length calculation
     804 [ #  # ][ #  # ]:          0 :             if (mpFormatData->mpLowerLimit->GetType() == COLORSCALE_MIN && nMin > 0)
                 [ #  # ]
     805                 :          0 :                 nMinPositive = nMin;
     806 [ #  # ][ #  # ]:          0 :             if (mpFormatData->mpUpperLimit->GetType() == COLORSCALE_MAX && nMax < 0)
                 [ #  # ]
     807                 :          0 :                 nMaxNegative = nMax;
     808                 :            :         }
     809         [ #  # ]:          0 :         else if( mpFormatData->meAxisPosition == databar::MIDDLE)
     810                 :          0 :             pInfo->mnZero = 50;
     811                 :            : 
     812                 :            :         //calculate the length
     813         [ #  # ]:          0 :         if(nValue < 0)
     814                 :            :         {
     815         [ #  # ]:          0 :             if (nValue < nMin)
     816                 :          0 :                 pInfo->mnLength = -100;
     817                 :            :             else
     818                 :          0 :                 pInfo->mnLength = -100 * (nValue-nMaxNegative)/(nMin-nMaxNegative);
     819                 :            :         }
     820                 :            :         else
     821                 :            :         {
     822         [ #  # ]:          0 :             if ( nValue > nMax )
     823                 :          0 :                 pInfo->mnLength = 100;
     824                 :            :             else
     825                 :          0 :                 pInfo->mnLength = (nValue-nMinPositive)/(nMax-nMinPositive)*100;
     826                 :            :         }
     827                 :            :     }
     828                 :            : 
     829                 :            : 
     830                 :            :     // set color
     831 [ #  # ][ #  # ]:          0 :     if(mpFormatData->mbNeg && nValue < 0)
                 [ #  # ]
     832                 :            :     {
     833         [ #  # ]:          0 :         if(mpFormatData->mpNegativeColor)
     834                 :            :         {
     835                 :          0 :             pInfo->maColor = *mpFormatData->mpNegativeColor.get();
     836                 :            :         }
     837                 :            :         else
     838                 :            :         {
     839                 :            :             // default negative color is red
     840                 :          0 :             pInfo->maColor = COL_LIGHTRED;
     841                 :            :         }
     842                 :            : 
     843                 :            :     }
     844                 :            :     else
     845                 :          0 :         pInfo->maColor = mpFormatData->maPositiveColor;
     846                 :            : 
     847                 :          0 :     pInfo->mbGradient = mpFormatData->mbGradient;
     848                 :          0 :     pInfo->mbShowValue = !mpFormatData->mbOnlyBar;
     849                 :          0 :     pInfo->maAxisColor = mpFormatData->maAxisColor;
     850                 :            : 
     851                 :          0 :     return pInfo;
     852                 :            : }
     853                 :            : 
     854                 :            : #if DUMP_FORMAT_INFO
     855                 :          0 : void ScDataBarFormat::dumpInfo() const
     856                 :            : {
     857                 :          0 :     const ScRangeList& rRange = GetRange();
     858                 :          0 :     size_t n = rRange.size();
     859         [ #  # ]:          0 :     for(size_t i = 0; i < n; ++i)
     860                 :            :     {
     861                 :          0 :         const ScRange* pRange = rRange[i];
     862                 :          0 :         SCTAB nTab = pRange->aStart.Tab();
     863         [ #  # ]:          0 :         for( SCCOL nCol = pRange->aStart.Col(), nEndCol = pRange->aEnd.Col(); nCol <= nEndCol; ++nCol)
     864                 :            :         {
     865         [ #  # ]:          0 :             for( SCROW nRow = pRange->aStart.Row(), nEndRow = pRange->aEnd.Row(); nRow <= nEndRow; ++nRow)
     866                 :            :             {
     867         [ #  # ]:          0 :                 boost::scoped_ptr<ScDataBarInfo> pInfo( GetDataBarInfo(ScAddress(nCol, nRow, nTab)) );
     868 [ #  # ][ #  # ]:          0 :                 std::cout << nCol << "," << nRow << "," << nTab << "," << pInfo->mnZero << ",";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     869 [ #  # ][ #  # ]:          0 :                 std::cout << pInfo->mnLength << "," << pInfo->mbGradient << "," << pInfo->mbShowValue << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     870         [ #  # ]:          0 :                 std::cout << std::endl;
     871         [ #  # ]:          0 :             }
     872                 :            :         }
     873                 :            :     }
     874 [ +  - ][ +  - ]:        153 : }
     875                 :            : #endif
     876                 :            : 
     877                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10