LCOV - code coverage report
Current view: top level - sc/source/core/data - colorscale.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 275 611 45.0 %
Date: 2015-06-13 12:38:46 Functions: 56 110 50.9 %
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 "colorscale.hxx"
      11             : #include "document.hxx"
      12             : #include "formulacell.hxx"
      13             : #include "fillinfo.hxx"
      14             : #include "iconsets.hrc"
      15             : #include "scresid.hxx"
      16             : #include "tokenarray.hxx"
      17             : #include "refupdatecontext.hxx"
      18             : 
      19             : #include <formula/token.hxx>
      20             : 
      21             : #include <algorithm>
      22             : 
      23             : class ScFormulaListener : public SvtListener
      24             : {
      25             : private:
      26             :     std::vector<ScRange> maCells;
      27             :     mutable bool mbDirty;
      28             :     ScDocument* mpDoc;
      29             : 
      30             :     void startListening(ScTokenArray* pTokens, const ScAddress& rPos);
      31             : 
      32             : public:
      33             :     ScFormulaListener(ScFormulaCell* pCell);
      34             :     virtual ~ScFormulaListener();
      35             : 
      36             :     void Notify( const SfxHint& rHint ) SAL_OVERRIDE;
      37             : 
      38             :     bool NeedsRepaint() const;
      39             : };
      40             : 
      41          22 : ScFormulaListener::ScFormulaListener(ScFormulaCell* pCell):
      42             :     mbDirty(false),
      43          22 :     mpDoc(pCell->GetDocument())
      44             : {
      45          22 :     startListening( pCell->GetCode(), pCell->aPos );
      46          22 : }
      47             : 
      48          22 : void ScFormulaListener::startListening(ScTokenArray* pArr, const ScAddress& rPos)
      49             : {
      50          22 :     pArr->Reset();
      51             :     formula::FormulaToken* t;
      52          66 :     while ( ( t = pArr->GetNextReferenceRPN() ) != NULL )
      53             :     {
      54          22 :         switch (t->GetType())
      55             :         {
      56             :             case formula::svSingleRef:
      57             :             {
      58          22 :                 ScAddress aCell =  t->GetSingleRef()->toAbs(rPos);
      59          22 :                 if (aCell.IsValid())
      60          22 :                     mpDoc->StartListeningCell(aCell, this);
      61             : 
      62          22 :                 maCells.push_back(aCell);
      63             :             }
      64          22 :             break;
      65             :             case formula::svDoubleRef:
      66             :             {
      67           0 :                 const ScSingleRefData& rRef1 = *t->GetSingleRef();
      68           0 :                 const ScSingleRefData& rRef2 = *t->GetSingleRef2();
      69           0 :                 ScAddress aCell1 = rRef1.toAbs(rPos);
      70           0 :                 ScAddress aCell2 = rRef2.toAbs(rPos);
      71           0 :                 if (aCell1.IsValid() && aCell2.IsValid())
      72             :                 {
      73           0 :                     if (t->GetOpCode() == ocColRowNameAuto)
      74             :                     {   // automagically
      75           0 :                         if ( rRef1.IsColRel() )
      76             :                         {   // ColName
      77           0 :                             aCell2.SetRow(MAXROW);
      78             :                         }
      79             :                         else
      80             :                         {   // RowName
      81           0 :                             aCell2.SetCol(MAXCOL);
      82             :                         }
      83             :                     }
      84           0 :                     mpDoc->StartListeningArea(ScRange(aCell1, aCell2), false, this);
      85           0 :                     maCells.push_back(ScRange(aCell1, aCell2));
      86             :                 }
      87             :             }
      88           0 :             break;
      89             :             default:
      90             :                 ;   // nothing
      91             :         }
      92             :     }
      93             : 
      94          22 : }
      95             : 
      96             : namespace {
      97             : 
      98             : struct StopListeningCell
      99             : {
     100          20 :     StopListeningCell(ScDocument* pDoc, SvtListener* pListener):
     101          20 :         mpDoc(pDoc), mpListener(pListener) {}
     102             : 
     103          20 :     void operator()(const ScRange& rRange)
     104             :     {
     105          60 :         for(SCTAB nTab = rRange.aStart.Tab(),
     106          20 :                 nTabEnd = rRange.aEnd.Tab(); nTab <= nTabEnd; ++nTab)
     107             :         {
     108          60 :             for(SCCOL nCol = rRange.aStart.Col(),
     109          20 :                     nColEnd = rRange.aEnd.Col(); nCol <= nColEnd; ++nCol)
     110             :             {
     111          60 :                 for(SCROW nRow = rRange.aStart.Row(),
     112          20 :                         nRowEnd = rRange.aEnd.Row(); nRow <= nRowEnd; ++nRow)
     113             :                 {
     114          20 :                     mpDoc->EndListeningCell(ScAddress(nCol, nRow, nTab), mpListener);
     115             :                 }
     116             :             }
     117             :         }
     118          20 :     }
     119             : 
     120             : private:
     121             :     ScDocument* mpDoc;
     122             :     SvtListener* mpListener;
     123             : };
     124             : 
     125             : }
     126             : 
     127          60 : ScFormulaListener::~ScFormulaListener()
     128             : {
     129          20 :     std::for_each(maCells.begin(), maCells.end(), StopListeningCell(mpDoc, this));
     130          40 : }
     131             : 
     132           0 : void ScFormulaListener::Notify( const SfxHint& )
     133             : {
     134           0 :     mbDirty = true;
     135           0 : }
     136             : 
     137           0 : bool ScFormulaListener::NeedsRepaint() const
     138             : {
     139           0 :     bool bRet = mbDirty;
     140           0 :     mbDirty = false;
     141           0 :     return bRet;
     142             : }
     143             : 
     144          12 : ScColorScaleEntry::ScColorScaleEntry():
     145             :     mnVal(0),
     146          12 :     meType(COLORSCALE_VALUE)
     147             : {
     148          12 : }
     149             : 
     150         236 : ScColorScaleEntry::ScColorScaleEntry(double nVal, const Color& rCol):
     151             :     mnVal(nVal),
     152             :     maColor(rCol),
     153         236 :     meType(COLORSCALE_VALUE)
     154             : {
     155         236 : }
     156             : 
     157          19 : ScColorScaleEntry::ScColorScaleEntry(const ScColorScaleEntry& rEntry):
     158             :     mnVal(rEntry.mnVal),
     159             :     maColor(rEntry.maColor),
     160          19 :     meType(rEntry.meType)
     161             : {
     162          19 :     if(rEntry.mpCell)
     163             :     {
     164           0 :         mpCell.reset(new ScFormulaCell(*rEntry.mpCell, *rEntry.mpCell->GetDocument(), rEntry.mpCell->aPos, SC_CLONECELL_NOMAKEABS_EXTERNAL));
     165           0 :         mpCell->StartListeningTo( mpCell->GetDocument() );
     166           0 :         mpListener.reset(new ScFormulaListener(mpCell.get()));
     167             :     }
     168          19 : }
     169             : 
     170           0 : ScColorScaleEntry::ScColorScaleEntry(ScDocument* pDoc, const ScColorScaleEntry& rEntry):
     171             :     mnVal(rEntry.mnVal),
     172             :     maColor(rEntry.maColor),
     173             :     mpCell(),
     174           0 :     meType(rEntry.meType)
     175             : {
     176           0 :     if(rEntry.mpCell)
     177             :     {
     178           0 :         mpCell.reset(new ScFormulaCell(*rEntry.mpCell, *rEntry.mpCell->GetDocument(), rEntry.mpCell->aPos, SC_CLONECELL_NOMAKEABS_EXTERNAL));
     179           0 :         mpCell->StartListeningTo( pDoc );
     180           0 :         mpListener.reset(new ScFormulaListener(mpCell.get()));
     181             :     }
     182           0 : }
     183             : 
     184         426 : ScColorScaleEntry::~ScColorScaleEntry()
     185             : {
     186         213 :     if(mpCell)
     187          20 :         mpCell->EndListeningTo(mpCell->GetDocument());
     188         213 : }
     189             : 
     190          22 : void ScColorScaleEntry::SetFormula( const OUString& rFormula, ScDocument* pDoc, const ScAddress& rAddr, formula::FormulaGrammar::Grammar eGrammar )
     191             : {
     192          22 :     mpCell.reset(new ScFormulaCell( pDoc, rAddr, rFormula, eGrammar ));
     193          22 :     mpCell->StartListeningTo( pDoc );
     194          22 :     mpListener.reset(new ScFormulaListener(mpCell.get()));
     195          22 : }
     196             : 
     197           4 : const ScTokenArray* ScColorScaleEntry::GetFormula() const
     198             : {
     199           4 :     if(mpCell)
     200             :     {
     201           4 :         return mpCell->GetCode();
     202             :     }
     203             : 
     204           0 :     return NULL;
     205             : }
     206             : 
     207           3 : OUString ScColorScaleEntry::GetFormula( formula::FormulaGrammar::Grammar eGrammar ) const
     208             : {
     209           3 :     OUString aFormula;
     210           3 :     if(mpCell)
     211             :     {
     212           3 :         mpCell->GetFormula(aFormula, eGrammar);
     213             :     }
     214             : 
     215           3 :     return aFormula;
     216             : }
     217             : 
     218         196 : double ScColorScaleEntry::GetValue() const
     219             : {
     220         196 :     if(mpCell)
     221             :     {
     222           0 :         mpCell->Interpret();
     223           0 :         if(mpCell->IsValue())
     224           0 :             return mpCell->GetValue();
     225             : 
     226           0 :         return std::numeric_limits<double>::max();
     227             :     }
     228             : 
     229         196 :     return mnVal;
     230             : }
     231             : 
     232          12 : void ScColorScaleEntry::SetValue(double nValue)
     233             : {
     234          12 :     mnVal = nValue;
     235          12 :     mpCell.reset();
     236          12 : }
     237             : 
     238           0 : void ScColorScaleEntry::UpdateReference( sc::RefUpdateContext& rCxt )
     239             : {
     240           0 :     if (!mpCell)
     241           0 :         return;
     242             : 
     243           0 :     mpCell->UpdateReference(rCxt);
     244           0 :     mpListener.reset(new ScFormulaListener(mpCell.get()));
     245             : }
     246             : 
     247           0 : void ScColorScaleEntry::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
     248             : {
     249           0 :     if (!mpCell)
     250           0 :         return;
     251             : 
     252           0 :     mpCell->UpdateInsertTab(rCxt);
     253           0 :     mpListener.reset(new ScFormulaListener(mpCell.get()));
     254             : }
     255             : 
     256           0 : void ScColorScaleEntry::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt )
     257             : {
     258           0 :     if (!mpCell)
     259           0 :         return;
     260             : 
     261           0 :     mpCell->UpdateDeleteTab(rCxt);
     262           0 :     mpListener.reset(new ScFormulaListener(mpCell.get()));
     263             : }
     264             : 
     265           0 : void ScColorScaleEntry::UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt )
     266             : {
     267           0 :     if (!mpCell)
     268           0 :         return;
     269             : 
     270           0 :     SCTAB nTabNo = rCxt.getNewTab(mpCell->aPos.Tab());
     271           0 :     mpCell->UpdateMoveTab(rCxt, nTabNo);
     272           0 :     mpListener.reset(new ScFormulaListener(mpCell.get()));
     273             : }
     274             : 
     275           0 : bool ScColorScaleEntry::NeedsRepaint() const
     276             : {
     277           0 :     if(mpListener)
     278           0 :         return mpListener->NeedsRepaint();
     279             : 
     280           0 :     return false;
     281             : }
     282             : 
     283           0 : void ScColorScaleEntry::SetColor(const Color& rColor)
     284             : {
     285           0 :     maColor = rColor;
     286           0 : }
     287             : 
     288         110 : ScColorFormat::ScColorFormat(ScDocument* pDoc)
     289             :     : ScFormatEntry(pDoc)
     290         110 :     , mpParent(NULL)
     291             : {
     292         110 : }
     293             : 
     294          90 : ScColorFormat::~ScColorFormat()
     295             : {
     296          90 : }
     297             : 
     298         104 : void ScColorFormat::SetParent( ScConditionalFormat* pParent )
     299             : {
     300         104 :     mpParent = pParent;
     301         104 : }
     302             : 
     303          47 : ScColorScaleFormat::ScColorScaleFormat(ScDocument* pDoc):
     304          47 :     ScColorFormat(pDoc)
     305             : {
     306          47 : }
     307             : 
     308           0 : ScColorScaleFormat::ScColorScaleFormat(ScDocument* pDoc, const ScColorScaleFormat& rFormat):
     309           0 :     ScColorFormat(pDoc)
     310             : {
     311           0 :     for(const_iterator itr = rFormat.begin(); itr != rFormat.end(); ++itr)
     312             :     {
     313           0 :         maColorScales.push_back(new ScColorScaleEntry(pDoc, *itr));
     314             :     }
     315           0 : }
     316             : 
     317           0 : ScColorFormat* ScColorScaleFormat::Clone(ScDocument* pDoc) const
     318             : {
     319           0 :     return new ScColorScaleFormat(pDoc, *this);
     320             : }
     321             : 
     322          82 : ScColorScaleFormat::~ScColorScaleFormat()
     323             : {
     324          82 : }
     325             : 
     326         120 : void ScColorScaleFormat::AddEntry( ScColorScaleEntry* pEntry )
     327             : {
     328         120 :     maColorScales.push_back( pEntry );
     329         120 : }
     330             : 
     331         255 : void ScColorScaleEntry::SetType( ScColorScaleEntryType eType )
     332             : {
     333         255 :     meType = eType;
     334         255 :     if(eType != COLORSCALE_FORMULA)
     335             :     {
     336         230 :         mpCell.reset();
     337         230 :         mpListener.reset();
     338             :     }
     339         255 : }
     340             : 
     341           0 : double ScColorScaleFormat::GetMinValue() const
     342             : {
     343           0 :     const_iterator itr = maColorScales.begin();
     344             : 
     345           0 :     if(itr->GetType() == COLORSCALE_VALUE || itr->GetType() == COLORSCALE_FORMULA)
     346           0 :         return itr->GetValue();
     347             :     else
     348             :     {
     349           0 :         return getMinValue();
     350             :     }
     351             : }
     352             : 
     353           0 : double ScColorScaleFormat::GetMaxValue() const
     354             : {
     355           0 :     ColorScaleEntries::const_reverse_iterator itr = maColorScales.rbegin();
     356             : 
     357           0 :     if(itr->GetType() == COLORSCALE_VALUE || itr->GetType() == COLORSCALE_FORMULA)
     358           0 :         return itr->GetValue();
     359             :     else
     360             :     {
     361           0 :         return getMaxValue();
     362             :     }
     363             : }
     364             : 
     365           0 : void ScColorScaleFormat::calcMinMax(double& rMin, double& rMax) const
     366             : {
     367           0 :     rMin = GetMinValue();
     368           0 :     rMax = GetMaxValue();
     369           0 : }
     370             : 
     371          27 : const ScRangeList& ScColorFormat::GetRange() const
     372             : {
     373          27 :     return mpParent->GetRange();
     374             : }
     375             : 
     376         130 : std::vector<double>& ScColorFormat::getValues() const
     377             : {
     378         130 :     if(!mpCache)
     379             :     {
     380           8 :         mpCache.reset(new ScColorFormatCache);
     381           8 :         std::vector<double>& rValues = mpCache->maValues;
     382             : 
     383           8 :         size_t n = GetRange().size();
     384           8 :         const ScRangeList& aRanges = GetRange();
     385          16 :         for(size_t i = 0; i < n; ++i)
     386             :         {
     387           8 :             const ScRange* pRange = aRanges[i];
     388           8 :             SCTAB nTab = pRange->aStart.Tab();
     389             : 
     390           8 :             SCCOL nColStart = pRange->aStart.Col();
     391           8 :             SCROW nRowStart = pRange->aStart.Row();
     392           8 :             SCCOL nColEnd = pRange->aEnd.Col();
     393           8 :             SCROW nRowEnd = pRange->aEnd.Row();
     394             : 
     395           8 :             if(nRowEnd == MAXROW)
     396             :             {
     397           0 :                 bool bShrunk = false;
     398             :                 mpDoc->ShrinkToUsedDataArea(bShrunk, nTab, nColStart, nRowStart,
     399           0 :                         nColEnd, nRowEnd, false);
     400             :             }
     401          16 :             for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
     402             :             {
     403          73 :                 for(SCROW nRow = nRowStart; nRow <= nRowEnd; ++nRow)
     404             :                 {
     405          65 :                     ScAddress aAddr(nCol, nRow, nTab);
     406          65 :                     CellType eType = mpDoc->GetCellType(aAddr);
     407          65 :                     if(eType == CELLTYPE_VALUE)
     408             :                     {
     409          65 :                         double aVal = mpDoc->GetValue(nCol, nRow, nTab);
     410          65 :                         rValues.push_back(aVal);
     411             :                     }
     412           0 :                     else if(eType == CELLTYPE_FORMULA)
     413             :                     {
     414           0 :                         ScFormulaCell *pCell = mpDoc->GetFormulaCell(aAddr);
     415           0 :                         if (pCell && pCell->IsValue())
     416             :                         {
     417           0 :                             double aVal = mpDoc->GetValue(nCol, nRow, nTab);
     418           0 :                             rValues.push_back(aVal);
     419             :                         }
     420             :                     }
     421             :                 }
     422             :             }
     423             :         }
     424             : 
     425           8 :         std::sort(rValues.begin(), rValues.end());
     426             :     }
     427             : 
     428         130 :     return mpCache->maValues;
     429             : }
     430             : 
     431          65 : double ScColorFormat::getMinValue() const
     432             : {
     433          65 :     std::vector<double>& rValues = getValues();
     434          65 :     if(rValues.empty())
     435           0 :         return 0;
     436          65 :     return rValues[0];
     437             : }
     438             : 
     439          65 : double ScColorFormat::getMaxValue() const
     440             : {
     441          65 :     std::vector<double>& rValues = getValues();
     442          65 :     if(rValues.empty())
     443           0 :         return 0;
     444          65 :     return rValues[rValues.size()-1];
     445             : }
     446             : 
     447           0 : void ScColorFormat::startRendering()
     448             : {
     449           0 :     mpCache.reset();
     450           0 : }
     451             : 
     452           0 : void ScColorFormat::endRendering()
     453             : {
     454           0 :     mpCache.reset();
     455           0 : }
     456             : 
     457             : namespace {
     458             : 
     459           0 : sal_uInt8 GetColorValue( double nVal, double nVal1, sal_uInt8 nColVal1, double nVal2, sal_uInt8 nColVal2 )
     460             : {
     461           0 :     if (nVal <= nVal1)
     462           0 :         return nColVal1;
     463             : 
     464           0 :     if (nVal >= nVal2)
     465           0 :         return nColVal2;
     466             : 
     467           0 :     sal_uInt8 nColVal = static_cast<sal_uInt8>((nVal - nVal1)/(nVal2-nVal1)*(nColVal2-nColVal1))+nColVal1;
     468           0 :     return nColVal;
     469             : }
     470             : 
     471           0 : Color CalcColor( double nVal, double nVal1, const Color& rCol1, double nVal2, const Color& rCol2)
     472             : {
     473           0 :     sal_uInt8 nColRed = GetColorValue(nVal, nVal1, rCol1.GetRed(), nVal2, rCol2.GetRed());
     474           0 :     sal_uInt8 nColBlue = GetColorValue(nVal, nVal1, rCol1.GetBlue(), nVal2, rCol2.GetBlue());
     475           0 :     sal_uInt8 nColGreen = GetColorValue(nVal, nVal1, rCol1.GetGreen(), nVal2, rCol2.GetGreen());
     476             : 
     477           0 :     return Color(nColRed, nColGreen, nColBlue);
     478             : }
     479             : 
     480             : /**
     481             :  * @param rVector sorted vector of the array
     482             :  * @param fPercentile percentile
     483             :  */
     484           0 : double GetPercentile( const std::vector<double>& rArray, double fPercentile )
     485             : {
     486           0 :     size_t nSize = rArray.size();
     487           0 :     size_t nIndex = (size_t)::rtl::math::approxFloor( fPercentile * (nSize-1));
     488           0 :     double fDiff = fPercentile * (nSize-1) - ::rtl::math::approxFloor( fPercentile * (nSize-1));
     489           0 :     std::vector<double>::const_iterator iter = rArray.begin() + nIndex;
     490           0 :     if (fDiff == 0.0)
     491           0 :         return *iter;
     492             :     else
     493             :     {
     494           0 :         double fVal = *iter;
     495           0 :         iter = rArray.begin() + nIndex+1;
     496           0 :         return fVal + fDiff * (*iter - fVal);
     497             :     }
     498             : }
     499             : 
     500             : }
     501             : 
     502           0 : double ScColorScaleFormat::CalcValue(double nMin, double nMax, ScColorScaleFormat::const_iterator& itr) const
     503             : {
     504           0 :     switch(itr->GetType())
     505             :     {
     506             :         case COLORSCALE_PERCENT:
     507           0 :             return nMin + (nMax-nMin)*(itr->GetValue()/100);
     508             :         case COLORSCALE_MIN:
     509           0 :             return nMin;
     510             :         case COLORSCALE_MAX:
     511           0 :             return nMax;
     512             :         case COLORSCALE_PERCENTILE:
     513             :         {
     514           0 :             std::vector<double>& rValues = getValues();
     515           0 :             if(rValues.size() == 1)
     516           0 :                 return rValues[0];
     517             :             else
     518             :             {
     519           0 :                 double fPercentile = itr->GetValue()/100.0;
     520           0 :                 return GetPercentile(rValues, fPercentile);
     521             :             }
     522             :         }
     523             : 
     524             :         default:
     525           0 :         break;
     526             :     }
     527             : 
     528           0 :     return itr->GetValue();
     529             : }
     530             : 
     531           0 : Color* ScColorScaleFormat::GetColor( const ScAddress& rAddr ) const
     532             : {
     533           0 :     CellType eCellType = mpDoc->GetCellType(rAddr);
     534           0 :     if(eCellType != CELLTYPE_VALUE && eCellType != CELLTYPE_FORMULA)
     535           0 :         return NULL;
     536             : 
     537           0 :     if (eCellType == CELLTYPE_FORMULA)
     538             :     {
     539           0 :         ScFormulaCell *pCell = mpDoc->GetFormulaCell(rAddr);
     540           0 :         if (!pCell || !pCell->IsValue())
     541           0 :             return NULL;
     542             :     }
     543             : 
     544             :     // now we have for sure a value
     545           0 :     double nVal = mpDoc->GetValue(rAddr);
     546             : 
     547           0 :     if (maColorScales.size() < 2)
     548           0 :         return NULL;
     549             : 
     550           0 :     double nMin = std::numeric_limits<double>::max();
     551           0 :     double nMax = std::numeric_limits<double>::min();
     552           0 :     calcMinMax(nMin, nMax);
     553             : 
     554             :     // this check is for safety
     555           0 :     if(nMin >= nMax)
     556           0 :         return NULL;
     557             : 
     558           0 :     const_iterator itr = begin();
     559           0 :     double nValMin = CalcValue(nMin, nMax, itr);
     560           0 :     Color rColMin = itr->GetColor();
     561           0 :     ++itr;
     562           0 :     double nValMax = CalcValue(nMin, nMax, itr);
     563           0 :     Color rColMax = itr->GetColor();
     564             : 
     565           0 :     ++itr;
     566           0 :     while(itr != end() && nVal > nValMax)
     567             :     {
     568           0 :         rColMin = rColMax;
     569           0 :         nValMin = nValMax;
     570           0 :         rColMax = itr->GetColor();
     571           0 :         nValMax = CalcValue(nMin, nMax, itr);
     572           0 :         ++itr;
     573             :     }
     574             : 
     575           0 :     Color aColor = CalcColor(nVal, nValMin, rColMin, nValMax, rColMax);
     576             : 
     577           0 :     return new Color(aColor);
     578             : }
     579             : 
     580           0 : void ScColorScaleFormat::UpdateReference( sc::RefUpdateContext& rCxt )
     581             : {
     582           0 :     for(iterator itr = begin(); itr != end(); ++itr)
     583           0 :         itr->UpdateReference(rCxt);
     584           0 : }
     585             : 
     586           0 : void ScColorScaleFormat::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
     587             : {
     588           0 :     for (iterator it = begin(); it != end(); ++it)
     589           0 :         it->UpdateInsertTab(rCxt);
     590           0 : }
     591             : 
     592           0 : void ScColorScaleFormat::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt )
     593             : {
     594           0 :     for (iterator it = begin(); it != end(); ++it)
     595           0 :         it->UpdateDeleteTab(rCxt);
     596           0 : }
     597             : 
     598           0 : void ScColorScaleFormat::UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt )
     599             : {
     600           0 :     for (iterator it = begin(); it != end(); ++it)
     601           0 :         it->UpdateMoveTab(rCxt);
     602           0 : }
     603             : 
     604           0 : bool ScColorScaleFormat::NeedsRepaint() const
     605             : {
     606           0 :     for(const_iterator itr = begin(), itrEnd = end();
     607             :             itr != itrEnd; ++itr)
     608             :     {
     609           0 :         if(itr->NeedsRepaint())
     610           0 :             return true;
     611             :     }
     612           0 :     return false;
     613             : }
     614             : 
     615           0 : bool ScColorScaleFormat::CheckEntriesForRel(const ScRange& rRange) const
     616             : {
     617           0 :     bool bNeedUpdate = false;
     618           0 :     for(const_iterator itr = begin(); itr != end(); ++itr)
     619             :     {
     620           0 :         ScColorScaleEntryType eType = itr->GetType();
     621           0 :         switch(eType)
     622             :         {
     623             :             case COLORSCALE_MIN:
     624             :             case COLORSCALE_MAX:
     625           0 :                 bNeedUpdate = true;
     626           0 :                 break;
     627             :             case COLORSCALE_FORMULA:
     628           0 :                 return true;
     629             :             default:
     630           0 :                 break;
     631             :         }
     632             :     }
     633             : 
     634             :     // TODO: check also if the changed value is the new min/max
     635             :     // or has been the old min/max value
     636           0 :     bNeedUpdate = bNeedUpdate && GetRange().Intersects(rRange);
     637           0 :     return bNeedUpdate;
     638             : }
     639             : 
     640           0 : void ScColorScaleFormat::DataChanged(const ScRange& rRange)
     641             : {
     642           0 :     bool bNeedUpdate = CheckEntriesForRel(rRange);
     643           0 :     if(bNeedUpdate)
     644             :     {
     645           0 :         mpDoc->RepaintRange(GetRange());
     646             :     }
     647           0 : }
     648             : 
     649          99 : condformat::ScFormatEntryType ScColorScaleFormat::GetType() const
     650             : {
     651          99 :     return condformat::COLORSCALE;
     652             : }
     653             : 
     654           0 : ScColorScaleFormat::iterator ScColorScaleFormat::begin()
     655             : {
     656           0 :     return maColorScales.begin();
     657             : }
     658             : 
     659          36 : ScColorScaleFormat::const_iterator ScColorScaleFormat::begin() const
     660             : {
     661          36 :     return maColorScales.begin();
     662             : }
     663             : 
     664           0 : ScColorScaleFormat::iterator ScColorScaleFormat::end()
     665             : {
     666           0 :     return maColorScales.end();
     667             : }
     668             : 
     669          78 : ScColorScaleFormat::const_iterator ScColorScaleFormat::end() const
     670             : {
     671          78 :     return maColorScales.end();
     672             : }
     673             : 
     674          21 : ScColorScaleEntry* ScColorScaleFormat::GetEntry(size_t nPos)
     675             : {
     676          21 :     if (maColorScales.size() <= nPos)
     677           0 :         return NULL;
     678             : 
     679          21 :     return &maColorScales[nPos];
     680             : }
     681             : 
     682           2 : const ScColorScaleEntry* ScColorScaleFormat::GetEntry(size_t nPos) const
     683             : {
     684           2 :     if (maColorScales.size() <= nPos)
     685           0 :         return NULL;
     686             : 
     687           2 :     return &maColorScales[nPos];
     688             : }
     689             : 
     690          60 : size_t ScColorScaleFormat::size() const
     691             : {
     692          60 :     return maColorScales.size();
     693             : }
     694             : 
     695           0 : void ScColorScaleFormat::EnsureSize()
     696             : {
     697           0 :     if (maColorScales.size() < 2)
     698             :     {
     699             :         // TODO: create 2 valid entries
     700             :     }
     701           0 : }
     702             : 
     703          50 : ScDataBarFormat::ScDataBarFormat(ScDocument* pDoc):
     704          50 :     ScColorFormat(pDoc)
     705             : {
     706          50 : }
     707             : 
     708           0 : ScDataBarFormat::ScDataBarFormat(ScDocument* pDoc, const ScDataBarFormat& rFormat):
     709             :     ScColorFormat(pDoc),
     710           0 :     mpFormatData(new ScDataBarFormatData(*rFormat.mpFormatData))
     711             : {
     712           0 : }
     713             : 
     714          50 : void ScDataBarFormat::SetDataBarData( ScDataBarFormatData* pData )
     715             : {
     716          50 :     mpFormatData.reset(pData);
     717          50 : }
     718             : 
     719          51 : ScDataBarFormatData* ScDataBarFormat::GetDataBarData()
     720             : {
     721          51 :     return mpFormatData.get();
     722             : }
     723             : 
     724          62 : const ScDataBarFormatData* ScDataBarFormat::GetDataBarData() const
     725             : {
     726          62 :     return mpFormatData.get();
     727             : }
     728             : 
     729           0 : ScColorFormat* ScDataBarFormat::Clone(ScDocument* pDoc) const
     730             : {
     731           0 :     return new ScDataBarFormat(pDoc, *this);
     732             : }
     733             : 
     734         109 : condformat::ScFormatEntryType ScDataBarFormat::GetType() const
     735             : {
     736         109 :     return condformat::DATABAR;
     737             : }
     738             : 
     739           0 : void ScDataBarFormat::UpdateReference( sc::RefUpdateContext& rCxt )
     740             : {
     741           0 :     mpFormatData->mpUpperLimit->UpdateReference(rCxt);
     742           0 :     mpFormatData->mpLowerLimit->UpdateReference(rCxt);
     743           0 : }
     744             : 
     745           0 : void ScDataBarFormat::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
     746             : {
     747           0 :     mpFormatData->mpUpperLimit->UpdateInsertTab(rCxt);
     748           0 :     mpFormatData->mpLowerLimit->UpdateInsertTab(rCxt);
     749           0 : }
     750             : 
     751           0 : void ScDataBarFormat::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt )
     752             : {
     753           0 :     mpFormatData->mpUpperLimit->UpdateDeleteTab(rCxt);
     754           0 :     mpFormatData->mpLowerLimit->UpdateDeleteTab(rCxt);
     755           0 : }
     756             : 
     757           0 : void ScDataBarFormat::UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt )
     758             : {
     759           0 :     mpFormatData->mpUpperLimit->UpdateMoveTab(rCxt);
     760           0 :     mpFormatData->mpLowerLimit->UpdateMoveTab(rCxt);
     761           0 : }
     762             : 
     763           0 : bool ScDataBarFormat::NeedsRepaint() const
     764             : {
     765           0 :     return mpFormatData->mpUpperLimit->NeedsRepaint() ||
     766           0 :         mpFormatData->mpLowerLimit->NeedsRepaint();
     767             : }
     768             : 
     769             : namespace {
     770             : 
     771           0 : bool NeedUpdate(ScColorScaleEntry* pEntry)
     772             : {
     773           0 :     switch(pEntry->GetType())
     774             :     {
     775             :         case COLORSCALE_MIN:
     776             :         case COLORSCALE_MAX:
     777             :         case COLORSCALE_FORMULA:
     778             :         case COLORSCALE_AUTO:
     779           0 :             return true;
     780             :         default:
     781           0 :             return false;
     782             :     }
     783             : }
     784             : 
     785             : }
     786             : 
     787           0 : void ScDataBarFormat::DataChanged(const ScRange& rRange)
     788             : {
     789           0 :     bool bNeedUpdate = NeedUpdate(mpFormatData->mpUpperLimit.get());
     790           0 :     bNeedUpdate |= NeedUpdate(mpFormatData->mpLowerLimit.get());
     791             : 
     792           0 :     bNeedUpdate &= GetRange().Intersects(rRange);
     793             : 
     794           0 :     if(bNeedUpdate)
     795             :     {
     796           0 :         mpDoc->RepaintRange(GetRange());
     797             :     }
     798           0 : }
     799             : 
     800          57 : double ScDataBarFormat::getMin(double nMin, double nMax) const
     801             : {
     802          57 :     switch(mpFormatData->mpLowerLimit->GetType())
     803             :     {
     804             :         case COLORSCALE_MIN:
     805           4 :             return nMin;
     806             : 
     807             :         case COLORSCALE_AUTO:
     808           4 :             return std::min<double>(0, nMin);
     809             : 
     810             :         case COLORSCALE_PERCENT:
     811           0 :             return nMin + (nMax-nMin)/100*mpFormatData->mpLowerLimit->GetValue();
     812             : 
     813             :         case COLORSCALE_PERCENTILE:
     814             :         {
     815           0 :             double fPercentile = mpFormatData->mpLowerLimit->GetValue()/100.0;
     816           0 :             std::vector<double>& rValues = getValues();
     817           0 :             return GetPercentile(rValues, fPercentile);
     818             :         }
     819             : 
     820             :         default:
     821          49 :         break;
     822             :     }
     823             : 
     824          49 :     return mpFormatData->mpLowerLimit->GetValue();
     825             : }
     826             : 
     827          57 : double ScDataBarFormat::getMax(double nMin, double nMax) const
     828             : {
     829          57 :     switch(mpFormatData->mpUpperLimit->GetType())
     830             :     {
     831             :         case COLORSCALE_MAX:
     832           4 :             return nMax;
     833             :         case COLORSCALE_AUTO:
     834           4 :             return std::max<double>(0, nMax);
     835             :         case COLORSCALE_PERCENT:
     836           0 :             return nMin + (nMax-nMin)/100*mpFormatData->mpUpperLimit->GetValue();
     837             :         case COLORSCALE_PERCENTILE:
     838             :         {
     839           0 :             double fPercentile = mpFormatData->mpUpperLimit->GetValue()/100.0;
     840           0 :             std::vector<double>& rValues = getValues();
     841           0 :             return GetPercentile(rValues, fPercentile);
     842             :         }
     843             : 
     844             :         default:
     845          49 :             break;
     846             :     }
     847             : 
     848          49 :     return mpFormatData->mpUpperLimit->GetValue();
     849             : }
     850             : 
     851          57 : ScDataBarInfo* ScDataBarFormat::GetDataBarInfo(const ScAddress& rAddr) const
     852             : {
     853          57 :     CellType eCellType = mpDoc->GetCellType(rAddr);
     854          57 :     if(eCellType != CELLTYPE_VALUE && eCellType != CELLTYPE_FORMULA)
     855           0 :         return NULL;
     856             : 
     857          57 :     if (eCellType == CELLTYPE_FORMULA)
     858             :     {
     859           0 :         ScFormulaCell *pCell = mpDoc->GetFormulaCell(rAddr);
     860           0 :         if (!pCell || !pCell->IsValue())
     861           0 :             return NULL;
     862             :     }
     863             : 
     864             :     // now we have for sure a value
     865             : 
     866          57 :     double nValMin = getMinValue();
     867          57 :     double nValMax = getMaxValue();
     868          57 :     double nMin = getMin(nValMin, nValMax);
     869          57 :     double nMax = getMax(nValMin, nValMax);
     870          57 :     double nMinLength = mpFormatData->mnMinLength;
     871          57 :     double nMaxLength = mpFormatData->mnMaxLength;
     872             : 
     873          57 :     double nValue = mpDoc->GetValue(rAddr);
     874             : 
     875          57 :     ScDataBarInfo* pInfo = new ScDataBarInfo();
     876          57 :     if(mpFormatData->meAxisPosition == databar::NONE)
     877             :     {
     878           0 :         if(nValue <= nMin)
     879             :         {
     880           0 :             pInfo->mnLength = nMinLength;
     881             :         }
     882           0 :         else if(nValue >= nMax)
     883             :         {
     884           0 :             pInfo->mnLength = nMaxLength;
     885             :         }
     886             :         else
     887             :         {
     888           0 :             double nDiff = nMax - nMin;
     889           0 :             pInfo->mnLength = nMinLength + (nValue - nMin)/nDiff * (nMaxLength-nMinLength);
     890             :         }
     891           0 :         pInfo->mnZero = 0;
     892             :     }
     893          57 :     else if (mpFormatData->meAxisPosition == databar::AUTOMATIC)
     894             :     {
     895             :         // if auto is used we may need to adjust it
     896             :         // for the length calculation
     897          32 :         if (mpFormatData->mpLowerLimit->GetType() == COLORSCALE_AUTO && nMin > 0)
     898           0 :             nMin = 0;
     899          32 :         if (mpFormatData->mpUpperLimit->GetType() == COLORSCALE_MAX && nMax < 0)
     900           0 :             nMax = 0;
     901             : 
     902             :         //calculate the zero position first
     903          32 :         if(nMin < 0)
     904             :         {
     905          16 :             if(nMax < 0)
     906           0 :                 pInfo->mnZero = 100;
     907             :             else
     908             :             {
     909          16 :                 pInfo->mnZero = -100*nMin/(nMax-nMin);
     910             :             }
     911             :         }
     912             :         else
     913          16 :             pInfo->mnZero = 0;
     914             : 
     915          32 :         double nMinNonNegative = std::max(0.0, nMin);
     916          32 :         double nMaxNonPositive = std::min(0.0, nMax);
     917             :         //calculate the length
     918          32 :         if(nValue < 0 && nMin < 0)
     919             :         {
     920          12 :             if (nValue < nMin)
     921           2 :                 pInfo->mnLength = -100;
     922             :             else
     923           4 :                 pInfo->mnLength = -100 * (nValue-nMaxNonPositive)/(nMin-nMaxNonPositive);
     924             :         }
     925             :         else
     926             :         {
     927          26 :             if ( nValue > nMax )
     928           3 :                 pInfo->mnLength = 100;
     929          23 :             else if (nValue <= nMin)
     930           3 :                 pInfo->mnLength = 0;
     931             :             else
     932          20 :                 pInfo->mnLength = 100 * (nValue-nMinNonNegative)/(nMax-nMinNonNegative);
     933             :         }
     934             :     }
     935          25 :     else if( mpFormatData->meAxisPosition == databar::MIDDLE)
     936             :     {
     937          25 :         pInfo->mnZero = 50;
     938          25 :         double nAbsMax = std::max(std::abs(nMin), std::abs(nMax));
     939          25 :         if (nValue < 0 && nMin < 0)
     940             :         {
     941          12 :             if (nValue < nMin)
     942           2 :                 pInfo->mnLength = nMaxLength * (nMin/nAbsMax);
     943             :             else
     944           4 :                 pInfo->mnLength = nMaxLength * (nValue/nAbsMax);
     945             :         }
     946             :         else
     947             :         {
     948          19 :             if (nValue > nMax)
     949           2 :                 pInfo->mnLength = nMaxLength * (nMax/nAbsMax);
     950             :             else
     951          17 :                 pInfo->mnLength = nMaxLength * (std::max(nValue, nMin)/nAbsMax);
     952             :         }
     953             :     }
     954             : 
     955             :     // set color
     956          57 :     if(mpFormatData->mbNeg && nValue < 0)
     957             :     {
     958          12 :         if(mpFormatData->mpNegativeColor)
     959             :         {
     960           0 :             pInfo->maColor = *mpFormatData->mpNegativeColor.get();
     961             :         }
     962             :         else
     963             :         {
     964             :             // default negative color is red
     965          12 :             pInfo->maColor = COL_LIGHTRED;
     966             :         }
     967             : 
     968             :     }
     969             :     else
     970          45 :         pInfo->maColor = mpFormatData->maPositiveColor;
     971             : 
     972          57 :     pInfo->mbGradient = mpFormatData->mbGradient;
     973          57 :     pInfo->mbShowValue = !mpFormatData->mbOnlyBar;
     974          57 :     pInfo->maAxisColor = mpFormatData->maAxisColor;
     975             : 
     976          57 :     return pInfo;
     977             : }
     978             : 
     979           0 : void ScDataBarFormat::EnsureSize()
     980             : {
     981           0 :     if (!mpFormatData->mpLowerLimit)
     982             :     {
     983             :         // TODO: implement
     984             :     }
     985           0 :     if (!mpFormatData->mpUpperLimit)
     986             :     {
     987             :         // TODO: implement
     988             :     }
     989           0 : }
     990             : 
     991           8 : ScIconSetFormat::ScIconSetFormat(ScDocument* pDoc):
     992             :     ScColorFormat(pDoc),
     993           8 :     mpFormatData(new ScIconSetFormatData)
     994             : {
     995           8 : }
     996             : 
     997           5 : ScIconSetFormat::ScIconSetFormat(ScDocument* pDoc, const ScIconSetFormat& rFormat):
     998             :     ScColorFormat(pDoc),
     999           5 :     mpFormatData(new ScIconSetFormatData(*rFormat.mpFormatData))
    1000             : {
    1001           5 : }
    1002             : 
    1003           5 : ScColorFormat* ScIconSetFormat::Clone( ScDocument* pDoc ) const
    1004             : {
    1005           5 :     return new ScIconSetFormat(pDoc, *this);
    1006             : }
    1007             : 
    1008           8 : void ScIconSetFormat::SetIconSetData( ScIconSetFormatData* pFormatData )
    1009             : {
    1010           8 :     mpFormatData.reset( pFormatData );
    1011           8 : }
    1012             : 
    1013           0 : ScIconSetFormatData* ScIconSetFormat::GetIconSetData()
    1014             : {
    1015           0 :     return mpFormatData.get();
    1016             : }
    1017             : 
    1018           3 : const ScIconSetFormatData* ScIconSetFormat::GetIconSetData() const
    1019             : {
    1020           3 :     return mpFormatData.get();
    1021             : }
    1022             : 
    1023          13 : ScIconSetInfo* ScIconSetFormat::GetIconSetInfo(const ScAddress& rAddr) const
    1024             : {
    1025          13 :     CellType eCellType = mpDoc->GetCellType(rAddr);
    1026          13 :     if(eCellType != CELLTYPE_VALUE && eCellType != CELLTYPE_FORMULA)
    1027           0 :         return NULL;
    1028             : 
    1029          13 :     if (eCellType == CELLTYPE_FORMULA)
    1030             :     {
    1031           0 :         ScFormulaCell *pCell = mpDoc->GetFormulaCell(rAddr);
    1032           0 :         if (!pCell || !pCell->IsValue())
    1033           0 :             return NULL;
    1034             :     }
    1035             : 
    1036             :     // now we have for sure a value
    1037          13 :     double nVal = mpDoc->GetValue(rAddr);
    1038             : 
    1039          13 :     if (mpFormatData->maEntries.size() < 2)
    1040           0 :         return NULL;
    1041             : 
    1042          13 :     double nMin = GetMinValue();
    1043          13 :     double nMax = GetMaxValue();
    1044             : 
    1045             :     // this check is for safety
    1046          13 :     if(nMin > nMax)
    1047           0 :         return NULL;
    1048             : 
    1049          13 :     sal_Int32 nIndex = 0;
    1050          13 :     const_iterator itr = begin();
    1051          13 :     ++itr;
    1052          13 :     double nValMax = CalcValue(nMin, nMax, itr);
    1053             : 
    1054          13 :     ++itr;
    1055          40 :     while(itr != end() && nVal >= nValMax)
    1056             :     {
    1057          14 :         ++nIndex;
    1058          14 :         nValMax = CalcValue(nMin, nMax, itr);
    1059          14 :         ++itr;
    1060             :     }
    1061          13 :     if(nVal >= nValMax)
    1062           4 :         ++nIndex;
    1063             : 
    1064          13 :     ScIconSetInfo* pInfo = new ScIconSetInfo;
    1065             : 
    1066          13 :     if(mpFormatData->mbReverse)
    1067             :     {
    1068           0 :         sal_Int32 nMaxIndex = mpFormatData->maEntries.size() - 1;
    1069           0 :         nIndex = nMaxIndex - nIndex;
    1070             :     }
    1071             : 
    1072          13 :     if (mpFormatData->mbCustom && sal_Int32(mpFormatData->maCustomVector.size()) > nIndex)
    1073             :     {
    1074           8 :         ScIconSetType eCustomType = mpFormatData->maCustomVector[nIndex].first;
    1075           8 :         sal_Int32 nCustomIndex = mpFormatData->maCustomVector[nIndex].second;
    1076           8 :         if (nCustomIndex == -1)
    1077             :         {
    1078           2 :             delete pInfo;
    1079           2 :             return NULL;
    1080             :         }
    1081             : 
    1082           6 :         pInfo->eIconSetType = eCustomType;
    1083           6 :         pInfo->nIconIndex = nCustomIndex;
    1084             :     }
    1085             :     else
    1086             :     {
    1087           5 :         pInfo->nIconIndex = nIndex;
    1088           5 :         pInfo->eIconSetType = mpFormatData->eIconSetType;
    1089             :     }
    1090             : 
    1091          11 :     pInfo->mbShowValue = mpFormatData->mbShowValue;
    1092          11 :     return pInfo;
    1093             : }
    1094             : 
    1095          13 : condformat::ScFormatEntryType ScIconSetFormat::GetType() const
    1096             : {
    1097          13 :     return condformat::ICONSET;
    1098             : }
    1099             : 
    1100           0 : void ScIconSetFormat::DataChanged( const ScRange& )
    1101             : {
    1102           0 : }
    1103             : 
    1104           0 : void ScIconSetFormat::UpdateReference( sc::RefUpdateContext& rCxt )
    1105             : {
    1106           0 :     for(iterator itr = begin(); itr != end(); ++itr)
    1107             :     {
    1108           0 :         itr->UpdateReference(rCxt);
    1109             :     }
    1110           0 : }
    1111             : 
    1112           0 : void ScIconSetFormat::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
    1113             : {
    1114           0 :     for(iterator itr = begin(); itr != end(); ++itr)
    1115             :     {
    1116           0 :         itr->UpdateInsertTab(rCxt);
    1117             :     }
    1118           0 : }
    1119             : 
    1120           0 : void ScIconSetFormat::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt )
    1121             : {
    1122           0 :     for(iterator itr = begin(); itr != end(); ++itr)
    1123             :     {
    1124           0 :         itr->UpdateDeleteTab(rCxt);
    1125             :     }
    1126           0 : }
    1127             : 
    1128           0 : void ScIconSetFormat::UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt )
    1129             : {
    1130           0 :     for(iterator itr = begin(); itr != end(); ++itr)
    1131             :     {
    1132           0 :         itr->UpdateMoveTab(rCxt);
    1133             :     }
    1134           0 : }
    1135             : 
    1136           0 : bool ScIconSetFormat::NeedsRepaint() const
    1137             : {
    1138           0 :     for(const_iterator itr = begin(); itr != end(); ++itr)
    1139             :     {
    1140           0 :         if(itr->NeedsRepaint())
    1141           0 :             return true;
    1142             :     }
    1143             : 
    1144           0 :     return false;
    1145             : }
    1146             : 
    1147           0 : ScIconSetFormat::iterator ScIconSetFormat::begin()
    1148             : {
    1149           0 :     return mpFormatData->maEntries.begin();
    1150             : }
    1151             : 
    1152          26 : ScIconSetFormat::const_iterator ScIconSetFormat::begin() const
    1153             : {
    1154          26 :     return mpFormatData->maEntries.begin();
    1155             : }
    1156             : 
    1157           0 : ScIconSetFormat::iterator ScIconSetFormat::end()
    1158             : {
    1159           0 :     return mpFormatData->maEntries.end();
    1160             : }
    1161             : 
    1162          27 : ScIconSetFormat::const_iterator ScIconSetFormat::end() const
    1163             : {
    1164          27 :     return mpFormatData->maEntries.end();
    1165             : }
    1166             : 
    1167          13 : double ScIconSetFormat::GetMinValue() const
    1168             : {
    1169          13 :     const_iterator itr = begin();
    1170             : 
    1171          13 :     if(itr->GetType() == COLORSCALE_VALUE || itr->GetType() == COLORSCALE_FORMULA)
    1172           5 :         return itr->GetValue();
    1173             :     else
    1174             :     {
    1175           8 :         return getMinValue();
    1176             :     }
    1177             : }
    1178             : 
    1179          13 : double ScIconSetFormat::GetMaxValue() const
    1180             : {
    1181          13 :     boost::ptr_vector<ScColorScaleEntry>::const_reverse_iterator itr = mpFormatData->maEntries.rbegin();
    1182             : 
    1183          13 :     if(itr->GetType() == COLORSCALE_VALUE || itr->GetType() == COLORSCALE_FORMULA)
    1184           5 :         return itr->GetValue();
    1185             :     else
    1186             :     {
    1187           8 :         return getMaxValue();
    1188             :     }
    1189             : }
    1190             : 
    1191          27 : double ScIconSetFormat::CalcValue(double nMin, double nMax, ScIconSetFormat::const_iterator& itr) const
    1192             : {
    1193          27 :     switch(itr->GetType())
    1194             :     {
    1195             :         case COLORSCALE_PERCENT:
    1196          19 :             return nMin + (nMax-nMin)*(itr->GetValue()/100);
    1197             :         case COLORSCALE_MIN:
    1198           0 :             return nMin;
    1199             :         case COLORSCALE_MAX:
    1200           0 :             return nMax;
    1201             :         case COLORSCALE_PERCENTILE:
    1202             :         {
    1203           0 :             std::vector<double>& rValues = getValues();
    1204           0 :             if(rValues.size() == 1)
    1205           0 :                 return rValues[0];
    1206             :             else
    1207             :             {
    1208           0 :                 double fPercentile = itr->GetValue()/100.0;
    1209           0 :                 return GetPercentile(rValues, fPercentile);
    1210             :             }
    1211             :         }
    1212             : 
    1213             :         default:
    1214           8 :         break;
    1215             :     }
    1216             : 
    1217           8 :     return itr->GetValue();
    1218             : }
    1219             : 
    1220             : namespace {
    1221             : 
    1222             : ScIconSetMap aIconSetMap[] = {
    1223             :     { "3Arrows", IconSet_3Arrows, 3 },
    1224             :     { "3ArrowsGray", IconSet_3ArrowsGray, 3 },
    1225             :     { "3Flags", IconSet_3Flags, 3 },
    1226             :     { "3TrafficLights1", IconSet_3TrafficLights1, 3 },
    1227             :     { "3TrafficLights2", IconSet_3TrafficLights2, 3 },
    1228             :     { "3Signs", IconSet_3Signs, 3 },
    1229             :     { "3Symbols", IconSet_3Symbols, 3 },
    1230             :     { "3Symbols2", IconSet_3Symbols2, 3 },
    1231             :     { "3Smilies", IconSet_3Smilies, 3 },
    1232             :     { "3ColorSmilies", IconSet_3ColorSmilies, 3 },
    1233             :     { "3Stars", IconSet_3Stars, 3 },
    1234             :     { "3Triangles", IconSet_3Triangles, 3 },
    1235             :     { "4Arrows", IconSet_4Arrows, 4 },
    1236             :     { "4ArrowsGray", IconSet_4ArrowsGray, 4 },
    1237             :     { "4RedToBlack", IconSet_4RedToBlack, 4 },
    1238             :     { "4Rating", IconSet_4Rating, 4 },
    1239             :     { "4TrafficLights", IconSet_4TrafficLights, 4 },
    1240             :     { "5Arrows", IconSet_5Arrows, 5 },
    1241             :     { "5ArrowsGray", IconSet_5ArrowsGray, 5 },
    1242             :     { "5Rating", IconSet_5Ratings, 5 },
    1243             :     { "5Quarters", IconSet_5Quarters, 5 },
    1244             :     { "5Boxes", IconSet_5Boxes, 5 },
    1245             :     { NULL, IconSet_3Arrows, 0 }
    1246             : };
    1247             : 
    1248             : }
    1249             : 
    1250          15 : ScIconSetMap* ScIconSetFormat::getIconSetMap()
    1251             : {
    1252          15 :     return aIconSetMap;
    1253             : }
    1254             : 
    1255           0 : size_t ScIconSetFormat::size() const
    1256             : {
    1257           0 :     return mpFormatData->maEntries.size();
    1258             : }
    1259             : 
    1260             : 
    1261             : namespace {
    1262             : 
    1263             : const sal_Int32 a3TrafficLights1[] = {
    1264             :     BMP_ICON_SET_CIRCLES1_RED, BMP_ICON_SET_CIRCLES1_YELLOW, BMP_ICON_SET_CIRCLES1_GREEN
    1265             : };
    1266             : 
    1267             : const sal_Int32 a3TrafficLights2[] = {
    1268             :     BMP_ICON_SET_TRAFFICLIGHTS_RED, BMP_ICON_SET_TRAFFICLIGHTS_YELLOW, BMP_ICON_SET_TRAFFICLIGHTS_GREEN
    1269             : };
    1270             : 
    1271             : const sal_Int32 a3Arrows[] = {
    1272             :     BMP_ICON_SET_COLORARROWS_DOWN, BMP_ICON_SET_COLORARROWS_SAME, BMP_ICON_SET_COLORARROWS_UP
    1273             : };
    1274             : 
    1275             : const sal_Int32 a3ArrowsGray[] = {
    1276             :     BMP_ICON_SET_GRAYARROWS_DOWN, BMP_ICON_SET_GRAYARROWS_SAME, BMP_ICON_SET_GRAYARROWS_UP
    1277             : };
    1278             : 
    1279             : const sal_Int32 a3Flags[] = {
    1280             :     BMP_ICON_SET_FLAGS_RED, BMP_ICON_SET_FLAGS_YELLOW, BMP_ICON_SET_FLAGS_GREEN
    1281             : };
    1282             : 
    1283             : const sal_Int32 a3Smilies[] = {
    1284             :     BMP_ICON_SET_POSITIVE_YELLOW_SMILIE, BMP_ICON_SET_NEUTRAL_YELLOW_SMILIE, BMP_ICON_SET_NEGATIVE_YELLOW_SMILIE
    1285             : };
    1286             : 
    1287             : const sal_Int32 a3ColorSmilies[] = {
    1288             :     BMP_ICON_SET_POSITIVE_GREEN_SMILIE, BMP_ICON_SET_NEUTRAL_YELLOW_SMILIE, BMP_ICON_SET_NEGATIVE_RED_SMILIE
    1289             : };
    1290             : 
    1291             : const sal_Int32 a3Stars[] = {
    1292             :     BMP_ICON_SET_STARS_EMPTY, BMP_ICON_SET_STARS_HALF, BMP_ICON_SET_STARS_FULL
    1293             : };
    1294             : 
    1295             : const sal_Int32 a3Triangles[] = {
    1296             :     BMP_ICON_SET_TRIANGLES_DOWN, BMP_ICON_SET_TRIANGLES_SAME, BMP_ICON_SET_TRIANGLES_UP
    1297             : };
    1298             : 
    1299             : const sal_Int32 a4Arrows[] = {
    1300             :     BMP_ICON_SET_COLORARROWS_DOWN, BMP_ICON_SET_COLORARROWS_SLIGHTLY_DOWN, BMP_ICON_SET_COLORARROWS_SLIGHTLY_UP, BMP_ICON_SET_COLORARROWS_UP
    1301             : };
    1302             : 
    1303             : const sal_Int32 a4ArrowsGray[] = {
    1304             :     BMP_ICON_SET_GRAYARROWS_DOWN, BMP_ICON_SET_GRAYARROWS_SLIGHTLY_DOWN, BMP_ICON_SET_GRAYARROWS_SLIGHTLY_UP, BMP_ICON_SET_GRAYARROWS_UP
    1305             : };
    1306             : 
    1307             : const sal_Int32 a5Arrows[] = {
    1308             :     BMP_ICON_SET_COLORARROWS_DOWN, BMP_ICON_SET_COLORARROWS_SLIGHTLY_DOWN,
    1309             :     BMP_ICON_SET_COLORARROWS_SAME, BMP_ICON_SET_COLORARROWS_SLIGHTLY_UP, BMP_ICON_SET_COLORARROWS_UP
    1310             : };
    1311             : 
    1312             : const sal_Int32 a5ArrowsGray[] = {
    1313             :     BMP_ICON_SET_GRAYARROWS_DOWN, BMP_ICON_SET_GRAYARROWS_SLIGHTLY_DOWN,
    1314             :     BMP_ICON_SET_GRAYARROWS_SAME, BMP_ICON_SET_GRAYARROWS_SLIGHTLY_UP, BMP_ICON_SET_GRAYARROWS_UP
    1315             : };
    1316             : 
    1317             : const sal_Int32 a4TrafficLights[] = {
    1318             :     BMP_ICON_SET_CIRCLES1_GRAY, BMP_ICON_SET_CIRCLES1_RED,
    1319             :     BMP_ICON_SET_CIRCLES1_YELLOW, BMP_ICON_SET_CIRCLES1_GREEN
    1320             : };
    1321             : 
    1322             : const sal_Int32 a5Quarters[] = {
    1323             :     BMP_ICON_SET_PIES_EMPTY, BMP_ICON_SET_PIES_ONE_QUARTER, BMP_ICON_SET_PIES_HALF,
    1324             :     BMP_ICON_SET_PIES_THREE_QUARTER, BMP_ICON_SET_PIES_FULL,
    1325             : };
    1326             : 
    1327             : const sal_Int32 a5Boxes[] = {
    1328             :     BMP_ICON_SET_SQUARES_EMPTY, BMP_ICON_SET_SQUARES_ONE_QUARTER,
    1329             :     BMP_ICON_SET_SQUARES_HALF, BMP_ICON_SET_SQUARES_THREE_QUARTER,
    1330             :     BMP_ICON_SET_SQUARES_FULL
    1331             : };
    1332             : 
    1333             : const sal_Int32 a3Symbols1[] = {
    1334             :     BMP_ICON_SET_SYMBOLS1_CROSS, BMP_ICON_SET_SYMBOLS1_EXCLAMATION_MARK, BMP_ICON_SET_SYMBOLS1_CHECK
    1335             : };
    1336             : 
    1337             : const sal_Int32 a3Signs[] = {
    1338             :     BMP_ICON_SET_SHAPES_DIAMOND, BMP_ICON_SET_SHAPES_TRIANGLE, BMP_ICON_SET_SHAPES_CIRCLE
    1339             : };
    1340             : 
    1341             : const sal_Int32 a4RedToBlack[] = {
    1342             :     BMP_ICON_SET_CIRCLES2_DARK_GRAY, BMP_ICON_SET_CIRCLES2_LIGHT_GRAY,
    1343             :     BMP_ICON_SET_CIRCLES2_LIGHT_RED, BMP_ICON_SET_CIRCLES2_DARK_RED
    1344             : };
    1345             : 
    1346             : const sal_Int32 a4Ratings[] = {
    1347             :     BMP_ICON_SET_BARS_ONE_QUARTER, BMP_ICON_SET_BARS_HALF,
    1348             :     BMP_ICON_SET_BARS_THREE_QUARTER, BMP_ICON_SET_BARS_FULL
    1349             : };
    1350             : 
    1351             : const sal_Int32 a5Ratings[] = {
    1352             :     BMP_ICON_SET_BARS_EMPTY, BMP_ICON_SET_BARS_ONE_QUARTER, BMP_ICON_SET_BARS_HALF,
    1353             :     BMP_ICON_SET_BARS_THREE_QUARTER, BMP_ICON_SET_BARS_FULL
    1354             : };
    1355             : 
    1356             : struct ScIconSetBitmapMap {
    1357             :     ScIconSetType eType;
    1358             :     const sal_Int32* nBitmaps;
    1359             : };
    1360             : 
    1361             : static const ScIconSetBitmapMap aBitmapMap[] = {
    1362             :     { IconSet_3Arrows, a3Arrows },
    1363             :     { IconSet_3ArrowsGray, a3ArrowsGray },
    1364             :     { IconSet_3Flags, a3Flags },
    1365             :     { IconSet_3Signs, a3Signs },
    1366             :     { IconSet_3Symbols, a3Symbols1 },
    1367             :     { IconSet_3Symbols2, a3Symbols1 },
    1368             :     { IconSet_3TrafficLights1, a3TrafficLights1 },
    1369             :     { IconSet_3TrafficLights2, a3TrafficLights2 },
    1370             :     { IconSet_3Smilies, a3Smilies },
    1371             :     { IconSet_3ColorSmilies, a3ColorSmilies },
    1372             :     { IconSet_3Triangles, a3Triangles },
    1373             :     { IconSet_3Stars, a3Stars },
    1374             :     { IconSet_4Arrows, a4Arrows },
    1375             :     { IconSet_4ArrowsGray, a4ArrowsGray },
    1376             :     { IconSet_4Rating, a4Ratings },
    1377             :     { IconSet_4RedToBlack, a4RedToBlack },
    1378             :     { IconSet_4TrafficLights, a4TrafficLights },
    1379             :     { IconSet_5Arrows, a5Arrows },
    1380             :     { IconSet_5ArrowsGray, a5ArrowsGray },
    1381             :     { IconSet_5Quarters, a5Quarters },
    1382             :     { IconSet_5Ratings, a5Ratings },
    1383             :     { IconSet_5Boxes, a5Boxes }
    1384             : };
    1385             : 
    1386             : }
    1387             : 
    1388           0 : BitmapEx& ScIconSetFormat::getBitmap( ScIconSetType eType, sal_Int32 nIndex )
    1389             : {
    1390           0 :     static std::map< sal_Int32, BitmapEx > aIconSetBitmaps;
    1391             : 
    1392           0 :     sal_Int32 nBitmap = -1;
    1393             : 
    1394           0 :     for(size_t i = 0; i < SAL_N_ELEMENTS(aBitmapMap); ++i)
    1395             :     {
    1396           0 :         if(aBitmapMap[i].eType == eType)
    1397             :         {
    1398           0 :             nBitmap = *(aBitmapMap[i].nBitmaps + nIndex);
    1399           0 :             break;
    1400             :         }
    1401             :     }
    1402             :     assert( nBitmap != -1 );
    1403             : 
    1404           0 :     std::map<sal_Int32, BitmapEx>::iterator itr = aIconSetBitmaps.find( nBitmap );
    1405           0 :     if(itr != aIconSetBitmaps.end())
    1406           0 :         return itr->second;
    1407             : 
    1408           0 :     BitmapEx aBitmap = BitmapEx(ScResId(nBitmap));
    1409           0 :     std::pair<sal_Int32, BitmapEx> aPair( nBitmap, aBitmap );
    1410           0 :     std::pair<std::map<sal_Int32, BitmapEx>::iterator, bool> itrNew = aIconSetBitmaps.insert(aPair);
    1411             :     assert(itrNew.second);
    1412             : 
    1413           0 :     return itrNew.first->second;
    1414             : }
    1415             : 
    1416           0 : void ScIconSetFormat::EnsureSize()
    1417             : {
    1418           0 :     ScIconSetType eType = mpFormatData->eIconSetType;
    1419           0 :     for (size_t i = 0; i < SAL_N_ELEMENTS(aIconSetMap); ++i)
    1420             :     {
    1421           0 :         if (aIconSetMap[i].eType == eType)
    1422             :         {
    1423             :             // size_t nElements = aIconSetMap[i].nElements;
    1424             :             // TODO: implement
    1425           0 :             break;
    1426             :         }
    1427             :     }
    1428         156 : }
    1429             : 
    1430             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11