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

Generated by: LCOV version 1.10