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: */
|