sc/inc/colorscale.hxx | 19 ++ sc/source/core/data/colorscale.cxx | 193 ++++++++++++++++++++++++++++- sc/source/filter/inc/condformatbuffer.hxx | 25 +++ sc/source/filter/oox/condformatbuffer.cxx | 55 +++++++- sc/source/filter/oox/condformatcontext.cxx | 2 5 files changed, 276 insertions(+), 18 deletions(-)
New commits: commit 777bbda955407c56805de3a3f4e96b0c13be6570 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Thu May 10 12:40:06 2012 +0200 finally support min/max and percentile in color scales Still some updating problems. If min or max is changed the whole area is not updated. Change-Id: I9a513fd9c0613d48ce33524672a31078d8aedf46 diff --git a/sc/inc/colorscale.hxx b/sc/inc/colorscale.hxx index 65a2fd6..b71c38b 100644 --- a/sc/inc/colorscale.hxx +++ b/sc/inc/colorscale.hxx @@ -69,12 +69,13 @@ private: double GetMinValue() const; double GetMaxValue() const; - void calcMinMax(double& nMin, double nMax) const; + void calcMinMax(double& nMin, double& nMax) const; public: ScColorScaleFormat(ScDocument* pDoc); Color* GetColor(const ScAddress& rAddr) const; void AddEntry(ScColorScaleEntry* pEntry); + void SetRange(const ScRangeList& rList); typedef ColorScaleEntries::iterator iterator; typedef ColorScaleEntries::const_iterator const_iterator; diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx index c970f37..3cc0e5a 100644 --- a/sc/source/core/data/colorscale.cxx +++ b/sc/source/core/data/colorscale.cxx @@ -32,14 +32,19 @@ ScColorScaleEntry::ScColorScaleEntry(double nVal, const Color& rCol): mnVal(nVal), - maColor(rCol) -{ + maColor(rCol), + mbMin(false), + mbMax(false), + mbPercent(false){ } ScColorScaleEntry::ScColorScaleEntry(const ScColorScaleEntry& rEntry): mnVal(rEntry.mnVal), - maColor(rEntry.maColor) + maColor(rEntry.maColor), + mbMin(false), + mbMax(false), + mbPercent(false) { } @@ -204,12 +209,17 @@ double ScColorScaleFormat::GetMaxValue() const return aMaxVal;; } -void ScColorScaleFormat::calcMinMax(double& rMin, double rMax) const +void ScColorScaleFormat::calcMinMax(double& rMin, double& rMax) const { rMin = GetMinValue(); rMax = GetMaxValue(); } +void ScColorScaleFormat::SetRange(const ScRangeList& rList) +{ + maRanges = rList; +} + namespace { sal_uInt8 GetColorValue( double nVal, double nVal1, sal_uInt8 nColVal1, double nVal2, sal_uInt8 nColVal2 ) @@ -233,6 +243,24 @@ Color CalcColor( double nVal, double nVal1, const Color& rCol1, double nVal2, co return Color(nColRed, nColGreen, nColBlue); } +double CalcValue(double nMin, double nMax, ScColorScaleFormat::const_iterator& itr) +{ + if(itr->GetPercent()) + { + return nMin + (nMax-nMin)*(itr->GetValue()/100); + } + else if(itr->GetMin()) + { + return nMin; + } + else if(itr->GetMax()) + { + return nMax; + } + + return itr->GetValue(); +} + } Color* ScColorScaleFormat::GetColor( const ScAddress& rAddr ) const @@ -253,23 +281,28 @@ Color* ScColorScaleFormat::GetColor( const ScAddress& rAddr ) const if (maColorScales.size() < 2) return NULL; + double nMin = std::numeric_limits<double>::max(); + double nMax = std::numeric_limits<double>::min(); + calcMinMax(nMin, nMax); + + // this check is for safety + if(nMin >= nMax) + return NULL; + const_iterator itr = begin(); - double nValMin = itr->GetValue(); + double nValMin = CalcValue(nMin, nMax, itr); Color rColMin = itr->GetColor(); ++itr; - double nValMax = itr->GetValue(); + double nValMax = CalcValue(nMin, nMax, itr); Color rColMax = itr->GetColor(); - double nMin; - double nMax; - calcMinMax(nMin, nMax); - ++itr; while(itr != end() && nVal > nValMin) { rColMin = rColMax; nValMin = nValMax; rColMax = itr->GetColor(); + nValMax = CalcValue(nMin, nMax, itr); nValMax = itr->GetValue(); ++itr; } diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx index 0b6ddf7..89ba949 100644 --- a/sc/source/filter/oox/condformatbuffer.cxx +++ b/sc/source/filter/oox/condformatbuffer.cxx @@ -172,7 +172,7 @@ void ColorScaleRule::importCfvo( const AttributeList& rAttribs ) { maColorScaleRuleEntries[mnCfvo].mbMax = true; } - else if( aType == "percent" ) + else if( aType == "percentile" ) { maColorScaleRuleEntries[mnCfvo].mbPercent = true; } @@ -696,6 +696,7 @@ void CondFormatRule::finalizeImport( const Reference< XSheetConditionalEntries > mpColor->AddEntries( pFormat ); sal_Int32 nIndex = rDoc.AddColorScaleFormat(pFormat); + ScRangeList aList; // apply attributes to cells // const ApiCellRangeList& rRanges = mrCondFormat.getRanges(); @@ -709,7 +710,10 @@ void CondFormatRule::finalizeImport( const Reference< XSheetConditionalEntries > ScMarkData aMarkData; aMarkData.SetMarkArea(aRange); pShell->GetDocFunc().ApplyAttributes( aMarkData, aPattern, sal_True, sal_True ); + + aList.Append(aRange); } + pFormat->SetRange(aList); } } commit e6e1470c6e9c027aa5794a88280a2b56a5062663 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Thu May 10 10:50:36 2012 +0200 import min, max and percent entries for color scales from xlsx Change-Id: I Icebacfd711851c9223ed8f38d6445c82f575a47d diff --git a/sc/source/filter/inc/condformatbuffer.hxx b/sc/source/filter/inc/condformatbuffer.hxx index 0da0ba0..7eb6342 100644 --- a/sc/source/filter/inc/condformatbuffer.hxx +++ b/sc/source/filter/inc/condformatbuffer.hxx @@ -76,20 +76,39 @@ struct CondFormatRuleModel void setBiff12TextType( sal_Int32 nOperator ); }; +struct ColorScaleRuleModelEntry +{ + ::Color maColor; + double mnVal; + + bool mbMin; + bool mbMax; + bool mbPercent; + + ColorScaleRuleModelEntry(): + maColor(), + mnVal(0), + mbMin(false), + mbMax(false), + mbPercent(false) {} +}; + class ColorScaleRule : public WorksheetHelper { public: ColorScaleRule( const CondFormat& rFormat ); - void importValue( const AttributeList& rAttribs ); + void importCfvo( const AttributeList& rAttribs ); void importColor( const AttributeList& rAttribs ); void AddEntries( ScColorScaleFormat* pFormat ); private: const CondFormat& mrCondFormat; - std::vector< ::Color > maColors; - std::vector< double > maValues; + std::vector< ColorScaleRuleModelEntry > maColorScaleRuleEntries; + + sal_uInt32 mnCfvo; + sal_uInt32 mnCol; }; diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx index 8cc7778..0b6ddf7 100644 --- a/sc/source/filter/oox/condformatbuffer.cxx +++ b/sc/source/filter/oox/condformatbuffer.cxx @@ -145,18 +145,39 @@ void lclAppendProperty( ::std::vector< PropertyValue >& orProps, const OUString& ColorScaleRule::ColorScaleRule( const CondFormat& rFormat ): WorksheetHelper( rFormat ), - mrCondFormat( rFormat ) + mrCondFormat( rFormat ), + mnCfvo(0), + mnCol(0) { } -void ColorScaleRule::importValue( const AttributeList& rAttribs ) +void ColorScaleRule::importCfvo( const AttributeList& rAttribs ) { + if(mnCfvo >= maColorScaleRuleEntries.size()) + maColorScaleRuleEntries.push_back(ColorScaleRuleModelEntry()); + rtl::OUString aType = rAttribs.getString( XML_type, rtl::OUString() ); + + double nVal = rAttribs.getDouble( XML_val, 0.0 ); + maColorScaleRuleEntries[mnCfvo].mnVal = nVal; if (aType == "num") { - double nVal = rAttribs.getDouble( XML_val, 0.0 ); - maValues.push_back(nVal); + // nothing to do + } + else if( aType == "min" ) + { + maColorScaleRuleEntries[mnCfvo].mbMin = true; } + else if( aType == "max" ) + { + maColorScaleRuleEntries[mnCfvo].mbMax = true; + } + else if( aType == "percent" ) + { + maColorScaleRuleEntries[mnCfvo].mbPercent = true; + } + + ++mnCfvo; } namespace { @@ -177,17 +198,31 @@ void ColorScaleRule::importColor( const AttributeList& rAttribs ) sal_Int32 nColor = rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT ); ::Color aColor = RgbToRgbComponents( nColor ); - maColors.push_back(aColor); + + if(mnCol >= maColorScaleRuleEntries.size()) + maColorScaleRuleEntries.push_back(ColorScaleRuleModelEntry()); + + maColorScaleRuleEntries[mnCol].maColor = aColor; + ++mnCol; } void ColorScaleRule::AddEntries( ScColorScaleFormat* pFormat ) { //assume that both vectors contain the same entries // TODO: check it - size_t n = std::min<size_t>(maColors.size(), maValues.size()); - for(size_t i = 0; i < n; ++i) + for(size_t i = 0; i < maColorScaleRuleEntries.size(); ++i) { - pFormat->AddEntry( new ScColorScaleEntry(maValues[i], maColors[i]) ); + ScColorScaleEntry* pEntry = new ScColorScaleEntry(maColorScaleRuleEntries[i].mnVal, maColorScaleRuleEntries[i].maColor); + const ColorScaleRuleModelEntry& rEntry = maColorScaleRuleEntries[i]; + + if(rEntry.mbMin) + pEntry->SetMin(true); + if(rEntry.mbMax) + pEntry->SetMax(true); + if(rEntry.mbPercent) + pEntry->SetPercent(true); + + pFormat->AddEntry( pEntry ); } } diff --git a/sc/source/filter/oox/condformatcontext.cxx b/sc/source/filter/oox/condformatcontext.cxx index 0ba54c7..ff73a8e 100644 --- a/sc/source/filter/oox/condformatcontext.cxx +++ b/sc/source/filter/oox/condformatcontext.cxx @@ -66,7 +66,7 @@ void ColorScaleContext::onStartElement( const AttributeList& rAttribs ) switch( getCurrentElement() ) { case XLS_TOKEN( cfvo ): - mxRule->getColorScale()->importValue( rAttribs ); + mxRule->getColorScale()->importCfvo( rAttribs ); break; case XLS_TOKEN( color ): mxRule->getColorScale()->importColor( rAttribs ); commit f26bf2ba01fc8ed453f3a42a39c26e2cf809c40f Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Thu May 10 07:06:40 2012 +0200 first part for min/max in color scales Change-Id: Ib397b93ac0a5a72052fdaa5bf41199e5967ad559 diff --git a/sc/inc/colorscale.hxx b/sc/inc/colorscale.hxx index 01ff306..65a2fd6 100644 --- a/sc/inc/colorscale.hxx +++ b/sc/inc/colorscale.hxx @@ -39,21 +39,37 @@ class SC_DLLPUBLIC ScColorScaleEntry private: double mnVal; Color maColor; + + bool mbMin; + bool mbMax; + bool mbPercent; public: ScColorScaleEntry(double nVal, const Color& rCol); ScColorScaleEntry(const ScColorScaleEntry& rEntry); const Color& GetColor() const; double GetValue() const; + + bool GetMin() const; + bool GetMax() const; + bool GetPercent() const; + void SetMin(bool bMin); + void SetMax(bool bMax); + void SetPercent(bool bPercent); }; class SC_DLLPUBLIC ScColorScaleFormat { private: - ScRangeList maRange; + ScRangeList maRanges; ScDocument* mpDoc; typedef boost::ptr_vector<ScColorScaleEntry> ColorScaleEntries; ColorScaleEntries maColorScales; + + double GetMinValue() const; + double GetMaxValue() const; + + void calcMinMax(double& nMin, double nMax) const; public: ScColorScaleFormat(ScDocument* pDoc); diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx index f05afb0..c970f37 100644 --- a/sc/source/core/data/colorscale.cxx +++ b/sc/source/core/data/colorscale.cxx @@ -64,6 +64,152 @@ void ScColorScaleFormat::AddEntry( ScColorScaleEntry* pEntry ) maColorScales.push_back( pEntry ); } +bool ScColorScaleEntry::GetMin() const +{ + return mbMin; +} + +bool ScColorScaleEntry::GetMax() const +{ + return mbMax; +} + +bool ScColorScaleEntry::GetPercent() const +{ + return mbPercent; +} + +void ScColorScaleEntry::SetMin(bool bMin) +{ + mbMin = bMin; +} + +void ScColorScaleEntry::SetMax(bool bMax) +{ + mbMax = bMax; +} + +void ScColorScaleEntry::SetPercent(bool bPercent) +{ + mbPercent = bPercent; +} + +namespace { + +double getMinValue(const ScRange& rRange, ScDocument* pDoc) +{ + double aMinValue = std::numeric_limits<double>::max(); + //iterate through columns + SCTAB nTab = rRange.aStart.Tab(); + for(SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol) + { + for(SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow) + { + ScAddress aAddr(nCol, nRow, rRange.aStart.Tab()); + CellType eType = pDoc->GetCellType(aAddr); + if(eType == CELLTYPE_VALUE) + { + double aVal = pDoc->GetValue(nCol, nRow, nTab); + if( aVal < aMinValue ) + aMinValue = aVal; + } + else if(eType == CELLTYPE_FORMULA) + { + if(static_cast<ScFormulaCell*>(pDoc->GetCell(aAddr))->IsValue()) + { + double aVal = pDoc->GetValue(nCol, nRow, nTab); + if( aVal < aMinValue ) + aMinValue = aVal; + } + } + } + } + return aMinValue; +} + +double getMaxValue(const ScRange& rRange, ScDocument* pDoc) +{ + double aMaxValue = std::numeric_limits<double>::min(); + //iterate through columns + SCTAB nTab = rRange.aStart.Tab(); + for(SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol) + { + for(SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow) + { + ScAddress aAddr(nCol, nRow, rRange.aStart.Tab()); + CellType eType = pDoc->GetCellType(aAddr); + if(eType == CELLTYPE_VALUE) + { + double aVal = pDoc->GetValue(nCol, nRow, nTab); + if( aVal > aMaxValue ) + aMaxValue = aVal; + } + else if(eType == CELLTYPE_FORMULA) + { + if(static_cast<ScFormulaCell*>(pDoc->GetCell(aAddr))->IsValue()) + { + double aVal = pDoc->GetValue(nCol, nRow, nTab); + if( aVal > aMaxValue ) + aMaxValue = aVal; + } + } + } + } + return aMaxValue; +} + +} + +double ScColorScaleFormat::GetMinValue() const +{ + const_iterator itr = maColorScales.begin(); + + double aMinValue = std::numeric_limits<double>::max(); + if(!itr->GetMin()) + return itr->GetValue(); + else + { + size_t n = maRanges.size(); + for(size_t i = 0; i < n; ++i) + { + const ScRange* pRange = maRanges[i]; + double aVal = getMinValue(*pRange, mpDoc); + if( aVal < aMinValue ) + aMinValue = aVal; + } + } + + return aMinValue; +} + +double ScColorScaleFormat::GetMaxValue() const +{ + ColorScaleEntries::const_reverse_iterator itr = maColorScales.rbegin(); + + double aMaxVal = std::numeric_limits<double>::min(); + if(!itr->GetMax()) + return itr->GetValue(); + else + { + size_t n = maRanges.size(); + for(size_t i = 0; i < n; ++i) + { + const ScRange* pRange = maRanges[i]; + double aVal = getMaxValue(*pRange, mpDoc); + if( aVal > aMaxVal ) + aMaxVal = aVal; + } + } + + return aMaxVal;; +} + +void ScColorScaleFormat::calcMinMax(double& rMin, double rMax) const +{ + rMin = GetMinValue(); + rMax = GetMaxValue(); +} + namespace { sal_uInt8 GetColorValue( double nVal, double nVal1, sal_uInt8 nColVal1, double nVal2, sal_uInt8 nColVal2 ) @@ -114,6 +260,10 @@ Color* ScColorScaleFormat::GetColor( const ScAddress& rAddr ) const double nValMax = itr->GetValue(); Color rColMax = itr->GetColor(); + double nMin; + double nMax; + calcMinMax(nMin, nMax); + ++itr; while(itr != end() && nVal > nValMin) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits