[Libreoffice-commits] .: 4 commits - sc/inc sc/source

Markus Mohrhard mmohrhard at kemper.freedesktop.org
Fri May 18 01:52:18 PDT 2012


 sc/inc/colorscale.hxx                      |  127 +++++++++++++++++--
 sc/inc/document.hxx                        |   12 -
 sc/inc/fillinfo.hxx                        |   32 ++++
 sc/source/core/data/colorscale.cxx         |  189 ++++++++++++++++++++++++++---
 sc/source/core/data/documen2.cxx           |    4 
 sc/source/core/data/documen4.cxx           |    8 -
 sc/source/core/data/fillinfo.cxx           |   14 +-
 sc/source/core/data/table2.cxx             |   10 -
 sc/source/filter/excel/xecontent.cxx       |   11 +
 sc/source/filter/inc/condformatbuffer.hxx  |   21 +++
 sc/source/filter/inc/condformatcontext.hxx |   13 +
 sc/source/filter/oox/condformatbuffer.cxx  |  142 ++++++++++++++++++++-
 sc/source/filter/oox/condformatcontext.cxx |   37 +++++
 sc/source/ui/view/output.cxx               |   72 ++++++++++-
 14 files changed, 621 insertions(+), 71 deletions(-)

New commits:
commit d961b694348a0dd048761a6046de7393ac077f31
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri May 18 10:33:16 2012 +0200

    implement databar import from oox
    
    Change-Id: Id510acbc7291b94610e0e2c769d8cee582baa9a7

diff --git a/sc/source/filter/inc/condformatbuffer.hxx b/sc/source/filter/inc/condformatbuffer.hxx
index b8b2d65..de2c906 100644
--- a/sc/source/filter/inc/condformatbuffer.hxx
+++ b/sc/source/filter/inc/condformatbuffer.hxx
@@ -39,6 +39,8 @@ namespace com { namespace sun { namespace star {
     namespace sheet { class XSheetConditionalEntries; }
 } } }
 class ScColorScaleFormat;
+class ScDataBarFormat;
+struct ScDataBarFormatData;
 
 namespace oox {
 namespace xls {
@@ -112,6 +114,23 @@ private:
     sal_uInt32 mnCol;
 };
 
+class DataBarRule : public WorksheetHelper
+{
+public:
+    DataBarRule( const CondFormat& rFormat );
+    void importCfvo( const AttributeList& rAttribs );
+    void importColor( const AttributeList& rAttribs );
+
+    void SetData( ScDataBarFormat* pFormat, ScDocument* pDoc, const ScAddress& rAddr );
+
+private:
+    const CondFormat& mrCondFormat;
+    ScDataBarFormatData* mpFormat;
+
+    boost::scoped_ptr<ColorScaleRuleModelEntry> mpUpperLimit;
+    boost::scoped_ptr<ColorScaleRuleModelEntry> mpLowerLimit;
+};
+
 
 // ============================================================================
 
@@ -138,11 +157,13 @@ public:
     inline sal_Int32    getPriority() const { return maModel.mnPriority; }
 
     ColorScaleRule*     getColorScale();
+    DataBarRule*        getDataBar();
 
 private:
     const CondFormat&   mrCondFormat;
     CondFormatRuleModel maModel;
     boost::scoped_ptr<ColorScaleRule> mpColor;
+    boost::scoped_ptr<DataBarRule> mpDataBar;
 };
 
 typedef ::boost::shared_ptr< CondFormatRule > CondFormatRuleRef;
diff --git a/sc/source/filter/inc/condformatcontext.hxx b/sc/source/filter/inc/condformatcontext.hxx
index 7af6258..08f5341 100644
--- a/sc/source/filter/inc/condformatcontext.hxx
+++ b/sc/source/filter/inc/condformatcontext.hxx
@@ -48,8 +48,17 @@ public:
     virtual void        onStartElement( const AttributeList& rAttribs );
     virtual void        onCharacters( const ::rtl::OUString& rChars );
 
-    virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
-    virtual void        onStartRecord( SequenceInputStream& rStrm );
+private:
+    CondFormatRuleRef mxRule;
+};
+
+class DataBarContext : public WorksheetContextBase
+{
+public:
+    explicit DataBarContext( CondFormatContext& rFormat, CondFormatRuleRef xRule );
+
+    virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+    virtual void        onStartElement( const AttributeList& rAttribs );
 
 private:
     CondFormatRuleRef mxRule;
diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx
index 719f3a5..655b264 100644
--- a/sc/source/filter/oox/condformatbuffer.cxx
+++ b/sc/source/filter/oox/condformatbuffer.cxx
@@ -224,12 +224,11 @@ void ColorScaleRule::importColor( const AttributeList& rAttribs )
     ++mnCol;
 }
 
-void ColorScaleRule::AddEntries( ScColorScaleFormat* pFormat, ScDocument* pDoc, const ScAddress& rAddr )
+namespace {
+
+ScColorScaleEntry* ConvertToModel( const ColorScaleRuleModelEntry& rEntry, ScDocument* pDoc, const ScAddress& rAddr )
 {
-    for(size_t i = 0; i < maColorScaleRuleEntries.size(); ++i)
-    {
-        ScColorScaleEntry* pEntry = new ScColorScaleEntry(maColorScaleRuleEntries[i].mnVal, maColorScaleRuleEntries[i].maColor);
-        const ColorScaleRuleModelEntry& rEntry = maColorScaleRuleEntries[i];
+        ScColorScaleEntry* pEntry = new ScColorScaleEntry(rEntry.mnVal, rEntry.maColor);
 
         if(rEntry.mbMin)
             pEntry->SetMin(true);
@@ -241,11 +240,105 @@ void ColorScaleRule::AddEntries( ScColorScaleFormat* pFormat, ScDocument* pDoc,
         if(!rEntry.maFormula.isEmpty())
             pEntry->SetFormula(rEntry.maFormula, pDoc, rAddr, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1);
 
+        return pEntry;
+}
+
+}
+
+void ColorScaleRule::AddEntries( ScColorScaleFormat* pFormat, ScDocument* pDoc, const ScAddress& rAddr )
+{
+    for(size_t i = 0; i < maColorScaleRuleEntries.size(); ++i)
+    {
+        const ColorScaleRuleModelEntry& rEntry = maColorScaleRuleEntries[i];
+
+        ScColorScaleEntry* pEntry = ConvertToModel( rEntry, pDoc, rAddr );
+
         pFormat->AddEntry( pEntry );
     }
 }
 
 // ============================================================================
+//
+DataBarRule::DataBarRule( const CondFormat& rFormat ):
+    WorksheetHelper( rFormat ),
+    mrCondFormat( rFormat ),
+    mpFormat(new ScDataBarFormatData)
+{
+}
+
+void DataBarRule::importColor( const AttributeList& rAttribs )
+{
+    sal_Int32 nColor = 0;
+    if( rAttribs.hasAttribute( XML_rgb ) )
+        nColor = rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT );
+    else if( rAttribs.hasAttribute( XML_theme ) )
+    {
+        sal_uInt32 nThemeIndex = rAttribs.getUnsigned( XML_theme, 0 );
+        nColor = getTheme().getColorByToken( nThemeIndex );
+    }
+
+    ::Color aColor = RgbToRgbComponents( nColor );
+
+    mpFormat->maPositiveColor = aColor;
+}
+
+void DataBarRule::importCfvo( const AttributeList& rAttribs )
+{
+    ColorScaleRuleModelEntry* pEntry;
+    if(!mpLowerLimit)
+    {
+        mpLowerLimit.reset(new ColorScaleRuleModelEntry);
+        pEntry = mpLowerLimit.get();
+    }
+    else
+    {
+        mpUpperLimit.reset(new ColorScaleRuleModelEntry);
+        pEntry = mpUpperLimit.get();
+    }
+    rtl::OUString aType = rAttribs.getString( XML_type, rtl::OUString() );
+
+    double nVal = rAttribs.getDouble( XML_val, 0.0 );
+    pEntry->mnVal = nVal;
+    if (aType == "num")
+    {
+        // nothing to do
+    }
+    else if( aType == "min" )
+    {
+        pEntry->mbMin = true;
+    }
+    else if( aType == "max" )
+    {
+        pEntry->mbMax = true;
+    }
+    else if( aType == "percent" )
+    {
+        pEntry->mbPercent = true;
+    }
+    else if( aType == "percentile" )
+    {
+        // this is most likely wrong but I have no idea what the difference
+        // between percent and percentile should be when calculating colors
+        pEntry->mbPercent = true;
+    }
+    else if( aType == "formula" )
+    {
+        rtl::OUString aFormula = rAttribs.getString( XML_val, rtl::OUString() );
+        pEntry->maFormula = aFormula;
+    }
+}
+
+void DataBarRule::SetData( ScDataBarFormat* pFormat, ScDocument* pDoc, const ScAddress& rAddr )
+{
+    ScColorScaleEntry* pUpperEntry = ConvertToModel( *mpUpperLimit.get(), pDoc, rAddr);
+    ScColorScaleEntry* pLowerEntry = ConvertToModel( *mpLowerLimit.get(), pDoc, rAddr);
+
+    mpFormat->mpUpperLimit.reset( pUpperEntry );
+    mpFormat->mpLowerLimit.reset( pLowerEntry );
+    pFormat->SetDataBarData(mpFormat);
+}
+
+// ============================================================================
 
 CondFormatRuleModel::CondFormatRuleModel() :
     mnPriority( -1 ),
@@ -712,7 +805,7 @@ void CondFormatRule::finalizeImport( const Reference< XSheetConditionalEntries >
         ScDocument& rDoc = getScDocument();
         ScColorScaleFormat* pFormat = new ScColorScaleFormat(&rDoc);
 
-        sal_Int32 nIndex = rDoc.AddColorScaleFormat(pFormat);
+        sal_Int32 nIndex = rDoc.AddColorFormat(pFormat);
 
         ScRangeList aList;
         // apply attributes to cells
@@ -736,15 +829,52 @@ void CondFormatRule::finalizeImport( const Reference< XSheetConditionalEntries >
         else
             mpColor->AddEntries( pFormat, &rDoc, ScAddress() );
     }
+    else if (mpDataBar)
+    {
+        ScRangeList aList;
+
+        ScDocument& rDoc = getScDocument();
+        ScDataBarFormat* pFormat = new ScDataBarFormat(&rDoc);
+
+        sal_Int32 nIndex = rDoc.AddColorFormat(pFormat);
+
+        // apply attributes to cells
+        //
+        const ApiCellRangeList& rRanges = mrCondFormat.getRanges();
+        for( ApiCellRangeList::const_iterator itr = rRanges.begin(); itr != rRanges.end(); ++itr)
+        {
+            ScRange aRange;
+            ScUnoConversion::FillScRange(aRange, *itr);
+            ScPatternAttr aPattern( rDoc.GetPool() );
+            aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_COLORSCALE, nIndex ) );
+            ScMarkData aMarkData;
+            aMarkData.SetMarkArea(aRange);
+            rDoc.ApplySelectionPattern( aPattern , aMarkData);
+
+            aList.Append(aRange);
+        }
+        pFormat->SetRange(aList);
+
+        mpDataBar->SetData( pFormat, &rDoc, aList.front()->aStart );
+    }
 }
 
 ColorScaleRule* CondFormatRule::getColorScale()
 {
     if(!mpColor)
         mpColor.reset( new ColorScaleRule(mrCondFormat) );
+
     return mpColor.get();
 }
 
+DataBarRule* CondFormatRule::getDataBar()
+{
+    if(!mpDataBar)
+        mpDataBar.reset( new DataBarRule(mrCondFormat) );
+
+    return mpDataBar.get();
+}
+
 // ============================================================================
 
 CondFormatModel::CondFormatModel() :
diff --git a/sc/source/filter/oox/condformatcontext.cxx b/sc/source/filter/oox/condformatcontext.cxx
index ff73a8e..01ad6a4 100644
--- a/sc/source/filter/oox/condformatcontext.cxx
+++ b/sc/source/filter/oox/condformatcontext.cxx
@@ -79,15 +79,46 @@ void ColorScaleContext::onCharacters( const OUString&  )
 
 }
 
-ContextHandlerRef ColorScaleContext::onCreateRecordContext( sal_Int32, SequenceInputStream& )
+// ============================================================================
+
+DataBarContext::DataBarContext( CondFormatContext& rFragment, CondFormatRuleRef xRule ) :
+    WorksheetContextBase( rFragment ),
+    mxRule( xRule )
+{
+}
+
+ContextHandlerRef DataBarContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
 {
+    switch( getCurrentElement() )
+    {
+        case XLS_TOKEN( cfRule ):
+            return (nElement == XLS_TOKEN( colorScale )) ? this : 0;
+        case XLS_TOKEN( dataBar ):
+            if (nElement == XLS_TOKEN( cfvo ))
+                return this;
+            else if (nElement == XLS_TOKEN( color ))
+                return this;
+            else
+                return 0;
+    }
     return 0;
 }
 
-void ColorScaleContext::onStartRecord( SequenceInputStream& )
+void DataBarContext::onStartElement( const AttributeList& rAttribs )
 {
+    switch( getCurrentElement() )
+    {
+        case XLS_TOKEN( cfvo ):
+            mxRule->getDataBar()->importCfvo( rAttribs );
+        break;
+        case XLS_TOKEN( color ):
+            mxRule->getDataBar()->importColor( rAttribs );
+        break;
+    }
 }
 
+// ============================================================================
+
 CondFormatContext::CondFormatContext( WorksheetFragmentBase& rFragment ) :
     WorksheetContextBase( rFragment )
 {
@@ -104,6 +135,8 @@ ContextHandlerRef CondFormatContext::onCreateContext( sal_Int32 nElement, const
                 return this;
             else if (nElement == XLS_TOKEN( colorScale ) )
                 return new ColorScaleContext( *this, mxRule );
+            else if (nElement == XLS_TOKEN( dataBar ) )
+                return new DataBarContext( *this, mxRule );
             else
                 return 0;
     }
commit 862f56d19e1c57d3d648275877fc434fb119e80f
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri May 18 10:33:58 2012 +0200

    implement databars in the core
    
    We currently only support either a databar or a color scale at an area.
    This limitation will be removed in 3.7
    
    Change-Id: I6236729822db891203479dff8554466706b4c6a8

diff --git a/sc/inc/colorscale.hxx b/sc/inc/colorscale.hxx
index 2596953..317a27d 100644
--- a/sc/inc/colorscale.hxx
+++ b/sc/inc/colorscale.hxx
@@ -39,12 +39,6 @@ class ScFormulaCell;
 class ScTokenArray;
 class ScDataBarInfo;
 
-struct ScDataBarFormatData
-{
-    Color maPositiveColor;
-    bool mbGradient;
-};
-
 class SC_DLLPUBLIC ScColorScaleEntry
 {
 private:
@@ -78,6 +72,50 @@ public:
     void SetPercent(bool bPercent);
 };
 
+struct ScDataBarFormatData
+{
+    ScDataBarFormatData():
+        mbGradient(true),
+        mbNeg(true),
+        mbSameDirection(false) {}
+
+    /**
+     * Color for all Positive Values and if mbNeg == false also for negative ones
+     */
+    Color maPositiveColor;
+    /**
+     * Specifies the color for negative values. This is optional and depends on mbNeg.
+     *
+     * Default color is 0xFF0000, this value is not set
+     */
+    boost::scoped_ptr<Color> mpNegativeColor;
+    /**
+     * Paint the bars with gradient. If this is used the default is to draw with
+     * borders.
+     *
+     * Default is true
+     */
+    bool mbGradient;
+    /**
+     * Use different color for negative values. Color is specified in
+     * mpNegativeColor and defaults to 0xFF0000
+     *
+     * Default is true
+     */
+    bool mbNeg; //differentiate between negative values
+    /**
+     * Paint negative values into the same direction as positive values
+     * If false we will set the mid point according to the upper and lower limit and negative
+     * values are painted to the left and positive to the right
+     *
+     * Default is false
+     */
+    bool mbSameDirection;
+
+    boost::scoped_ptr<ScColorScaleEntry> mpUpperLimit;
+    boost::scoped_ptr<ScColorScaleEntry> mpLowerLimit;
+};
+
 enum ScColorFormatType
 {
     COLORSCALE,
@@ -147,9 +185,12 @@ class SC_DLLPUBLIC ScDataBarFormat : public ScColorFormat
 public:
     ScDataBarFormat(ScDocument* pDoc);
     ScDataBarFormat(ScDocument* pDoc, const ScDataBarFormat& rFormat);
+    virtual ScColorFormat* Clone(ScDocument* pDoc = NULL) const;
 
     ScDataBarInfo* GetDataBarInfo(const ScAddress& rAddr) const;
 
+    void SetDataBarData( ScDataBarFormatData* pData );
+
     virtual void DataChanged(const ScRange& rRange);
     virtual void UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab);
     virtual void UpdateReference( UpdateRefMode eUpdateRefMode,
@@ -157,7 +198,7 @@ public:
 
     virtual ScColorFormatType GetType() const;
 private:
-    ScDataBarFormatData maFormatData;
+    boost::scoped_ptr<ScDataBarFormatData> mpFormatData;
 };
 
 class SC_DLLPUBLIC ScColorFormatList
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 7e14a5c..ed8eb3b 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -96,7 +96,7 @@ class ScChartCollection;
 class ScChartListenerCollection;
 class ScConditionalFormat;
 class ScConditionalFormatList;
-class ScColorScaleFormat;
+class ScColorFormat;
 class ScColorFormatList;
 class ScDBCollection;
 class ScDBData;
@@ -1199,7 +1199,7 @@ public:
     void            ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark );
 
     SC_DLLPUBLIC sal_uLong          AddCondFormat( const ScConditionalFormat& rNew );
-    SC_DLLPUBLIC sal_uLong          AddColorScaleFormat( ScColorScaleFormat* pNew );
+    SC_DLLPUBLIC sal_uLong          AddColorFormat( ScColorFormat* pNew );
     SC_DLLPUBLIC void           FindConditionalFormat( sal_uLong nKey, ScRangeList& rRanges );
     SC_DLLPUBLIC void           FindConditionalFormat( sal_uLong nKey, ScRangeList& rRanges, SCTAB nTab );
     void            ConditionalChanged( sal_uLong nKey );
diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx
index 5aecd51..c2fa4a7 100644
--- a/sc/inc/fillinfo.hxx
+++ b/sc/inc/fillinfo.hxx
@@ -68,6 +68,25 @@ struct ScDataBarInfo
     Color maColor;
     double mnLength; // -100 to 100
     bool mbGradient;
+
+    bool operator==(const ScDataBarInfo& r) const
+    {
+        if( mnZero != r.mnZero )
+            return false;
+        if( maColor != r.maColor )
+            return false;
+        if(mnLength != r.mnLength)
+            return false;
+        if (mbGradient != r.mbGradient)
+            return false;
+
+        return true;
+    }
+
+    bool operator!=(const ScDataBarInfo& r) const
+    {
+        return !(*this == r);
+    }
 };
 
 struct CellInfo
diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx
index 1892a75..501a094 100644
--- a/sc/source/core/data/colorscale.cxx
+++ b/sc/source/core/data/colorscale.cxx
@@ -29,6 +29,7 @@
 #include "colorscale.hxx"
 #include "document.hxx"
 #include "cell.hxx"
+#include "fillinfo.hxx"
 
 ScColorScaleEntry::ScColorScaleEntry(double nVal, const Color& rCol):
     mnVal(nVal),
@@ -532,6 +533,135 @@ ScColorScaleFormat::const_iterator ScColorScaleFormat::end() const
     return maColorScales.end();
 }
 
+ScDataBarFormat::ScDataBarFormat(ScDocument* pDoc):
+    ScColorFormat(pDoc)
+{
+}
+
+ScDataBarFormat::ScDataBarFormat(ScDocument* pDoc, const ScDataBarFormat& rFormat):
+    ScColorFormat(pDoc, rFormat)
+{
+}
+
+void ScDataBarFormat::SetDataBarData( ScDataBarFormatData* pData )
+{
+    mpFormatData.reset(pData);
+}
+
+ScColorFormat* ScDataBarFormat::Clone(ScDocument* pDoc) const
+{
+    return new ScDataBarFormat(pDoc, *this);
+}
+
+ScColorFormatType ScDataBarFormat::GetType() const
+{
+    return DATABAR;
+}
+
+void ScDataBarFormat::UpdateReference( UpdateRefMode ,
+            const ScRange& , SCsCOL , SCsROW , SCsTAB  )
+{
+}
+
+void ScDataBarFormat::DataChanged(const ScRange& )
+{
+
+}
+
+void ScDataBarFormat::UpdateMoveTab(SCTAB , SCTAB )
+{
+}
+
+ScDataBarInfo* ScDataBarFormat::GetDataBarInfo(const ScAddress& rAddr) const
+{
+    CellType eCellType = mpDoc->GetCellType(rAddr);
+    if(eCellType != CELLTYPE_VALUE && eCellType != CELLTYPE_FORMULA)
+        return NULL;
+
+    if (eCellType == CELLTYPE_FORMULA)
+    {
+        if(!static_cast<ScFormulaCell*>(mpDoc->GetCell(rAddr))->IsValue())
+            return NULL;
+    }
+
+    // now we have for sure a value
+    //
+    double nMin = -2;
+    double nMax = 10;
+
+    double nValue = mpDoc->GetValue(rAddr);
+
+    ScDataBarInfo* pInfo = new ScDataBarInfo();
+    if(mpFormatData->mbSameDirection || nMin > 0)
+    {
+        if(nValue <= nMin)
+        {
+            pInfo->mnLength = 0;
+        }
+        else if(nValue >= nMax)
+        {
+            pInfo->mnLength = 100;
+        }
+        else
+        {
+            double nDiff = nMax - nMin;
+            pInfo->mnLength = (nValue - nMin)/nDiff*100.0;
+        }
+        pInfo->mnZero = 0;
+    }
+    else
+    {
+        //calculate the zero position first
+        if(nMin < 0)
+        {
+            if(nMax < 0)
+                pInfo->mnZero = 100;
+            else
+            {
+                pInfo->mnZero = -100*nMin/(nMax-nMin);
+            }
+        }
+
+        //calculate the length
+        if(nValue < 0)
+        {
+            if (nValue < nMin)
+                pInfo->mnLength = -100;
+            else
+                pInfo->mnLength = -100 * nValue/nMin;
+        }
+        else
+        {
+            if ( nValue > nMax )
+                pInfo->mnLength = 100;
+            else
+                pInfo->mnLength = nValue/nMax*100;
+        }
+    }
+
+
+    // set color
+    if(mpFormatData->mbNeg && nValue < 0)
+    {
+        if(mpFormatData->mpNegativeColor)
+        {
+            pInfo->maColor = *mpFormatData->mpNegativeColor.get();
+        }
+        else
+        {
+            // default negative color is red
+            pInfo->maColor = COL_RED;
+        }
+
+    }
+    else
+        pInfo->maColor = mpFormatData->maPositiveColor;
+
+    return pInfo;
+}
+
+//-----------------------------------------------------------------
+
 ScColorFormatList::ScColorFormatList(ScDocument* pDoc, const ScColorFormatList& rList)
 {
     for(const_iterator itr = rList.begin(); itr != rList.end(); ++itr)
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 76d3773..6ec09a3 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -640,7 +640,7 @@ ScColorFormatList* ScDocument::GetColorScaleList()
 
 //takes ownership
 // returns a 1-based index, 0 is reserved for no entry
-sal_uLong ScDocument::AddColorScaleFormat( ScColorScaleFormat* pNew )
+sal_uLong ScDocument::AddColorFormat( ScColorFormat* pNew )
 {
     if(!pNew)
         return 0;
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index 4b227b0..7e5c050 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -488,11 +488,14 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
                             pCondForm = pCondFormList->GetFormat( nConditional );
 
                         const ScColorScaleFormat* pColorScale = NULL;
+                        const ScDataBarFormat* pDataBar = NULL;
                         if ( nColorScale && mpColorScaleList )
                         {
                             ScColorFormat* pFormat = mpColorScaleList->GetFormat( nColorScale );
                             if(pFormat->GetType() == COLORSCALE)
                                 pColorScale = static_cast<ScColorScaleFormat*>(pFormat);
+                            else if(pFormat->GetType() == DATABAR)
+                                pDataBar = static_cast<ScDataBarFormat*>(pFormat);
                         }
 
                         do
@@ -574,6 +577,11 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
                                     Color* pColor = pColorScale->GetColor( ScAddress( nX, nCurRow, nTab ) );
                                     pInfo->pColorScale = pColor;
                                 }
+                                if( pDataBar )
+                                {
+                                    ScDataBarInfo* pDataBarInfo = pDataBar->GetDataBarInfo( ScAddress( nX, nCurRow, nTab ) );
+                                    pInfo->pDataBar = pDataBarInfo;
+                                }
 
                                 ++nArrY;
                             }
commit eb3d3a0a7d49b51942e7f39cdcde1be0b11349e7
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu May 17 11:04:56 2012 +0200

    restructure colorscale code a bit to allow adding databars
    
    This is just a first step. In a second step we need another layer to
    allow color scales and databars applied to the same range and finally
    merge them with normal conditional formatting.
    
    Change-Id: I0452ed12dd9b2d5395cf005d75a902fbb7a984ad

diff --git a/sc/inc/colorscale.hxx b/sc/inc/colorscale.hxx
index 61346b6..2596953 100644
--- a/sc/inc/colorscale.hxx
+++ b/sc/inc/colorscale.hxx
@@ -37,6 +37,13 @@
 class ScDocument;
 class ScFormulaCell;
 class ScTokenArray;
+class ScDataBarInfo;
+
+struct ScDataBarFormatData
+{
+    Color maPositiveColor;
+    bool mbGradient;
+};
 
 class SC_DLLPUBLIC ScColorScaleEntry
 {
@@ -71,11 +78,39 @@ public:
     void SetPercent(bool bPercent);
 };
 
-class SC_DLLPUBLIC ScColorScaleFormat
+enum ScColorFormatType
 {
-private:
+    COLORSCALE,
+    DATABAR
+};
+
+class SC_DLLPUBLIC ScColorFormat
+{
+public:
+    ScColorFormat(ScDocument* pDoc);
+    ScColorFormat(ScDocument* pDoc, const ScColorFormat& rFormat);
+    virtual ~ScColorFormat();
+
+    void SetRange(const ScRangeList& rList);
+    const ScRangeList& GetRange() const;
+
+    virtual void DataChanged(const ScRange& rRange) = 0;
+    virtual void UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab) = 0;
+    virtual void UpdateReference( UpdateRefMode eUpdateRefMode,
+            const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) = 0;
+
+    virtual ScColorFormat* Clone(ScDocument* pDoc = NULL) const = 0;
+
+    virtual ScColorFormatType GetType() const = 0;
+
+protected:
     ScRangeList maRanges;
     ScDocument* mpDoc;
+};
+
+class SC_DLLPUBLIC ScColorScaleFormat : public ScColorFormat
+{
+private:
     typedef boost::ptr_vector<ScColorScaleEntry> ColorScaleEntries;
     ColorScaleEntries maColorScales;
 
@@ -87,17 +122,18 @@ private:
 public:
     ScColorScaleFormat(ScDocument* pDoc);
     ScColorScaleFormat(ScDocument* pDoc, const ScColorScaleFormat& rFormat);
+    virtual ~ScColorScaleFormat();
+    virtual ScColorFormat* Clone(ScDocument* pDoc = NULL) const;
 
     Color* GetColor(const ScAddress& rAddr) const;
     void AddEntry(ScColorScaleEntry* pEntry);
-    void SetRange(const ScRangeList& rList);
-    const ScRangeList& GetRange() const;
 
-    void DataChanged(const ScRange& rRange);
-    void UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab);
-    void UpdateReference( UpdateRefMode eUpdateRefMode,
+    virtual void DataChanged(const ScRange& rRange);
+    virtual void UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab);
+    virtual void UpdateReference( UpdateRefMode eUpdateRefMode,
             const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
 
+    virtual ScColorFormatType GetType() const;
     typedef ColorScaleEntries::iterator iterator;
     typedef ColorScaleEntries::const_iterator const_iterator;
     iterator begin();
@@ -106,20 +142,38 @@ public:
     const_iterator end() const;
 };
 
-class SC_DLLPUBLIC ScColorScaleFormatList
+class SC_DLLPUBLIC ScDataBarFormat : public ScColorFormat
+{
+public:
+    ScDataBarFormat(ScDocument* pDoc);
+    ScDataBarFormat(ScDocument* pDoc, const ScDataBarFormat& rFormat);
+
+    ScDataBarInfo* GetDataBarInfo(const ScAddress& rAddr) const;
+
+    virtual void DataChanged(const ScRange& rRange);
+    virtual void UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab);
+    virtual void UpdateReference( UpdateRefMode eUpdateRefMode,
+            const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
+
+    virtual ScColorFormatType GetType() const;
+private:
+    ScDataBarFormatData maFormatData;
+};
+
+class SC_DLLPUBLIC ScColorFormatList
 {
 private:
-    typedef boost::ptr_vector<ScColorScaleFormat> ColorScaleFormatContainer;
-    boost::ptr_vector<ScColorScaleFormat> maColorScaleFormats;
+    typedef boost::ptr_vector<ScColorFormat> ColorFormatContainer;
+    ColorFormatContainer maColorScaleFormats;
 public:
-    ScColorScaleFormatList() {};
-    ScColorScaleFormatList(ScDocument* pDoc, const ScColorScaleFormatList& rList);
+    ScColorFormatList() {};
+    ScColorFormatList(ScDocument* pDoc, const ScColorFormatList& rList);
 
-    typedef ColorScaleFormatContainer::iterator iterator;
-    typedef ColorScaleFormatContainer::const_iterator const_iterator;
+    typedef ColorFormatContainer::iterator iterator;
+    typedef ColorFormatContainer::const_iterator const_iterator;
 
-    ScColorScaleFormat* GetFormat(sal_uInt32 nFormat);
-    void AddFormat( ScColorScaleFormat* pFormat );
+    ScColorFormat* GetFormat(sal_uInt32 nFormat);
+    void AddFormat( ScColorFormat* pFormat );
 
     void DataChanged(const ScRange& rRange);
     void UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab);
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 0fecf8d..7e14a5c 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -97,7 +97,7 @@ class ScChartListenerCollection;
 class ScConditionalFormat;
 class ScConditionalFormatList;
 class ScColorScaleFormat;
-class ScColorScaleFormatList;
+class ScColorFormatList;
 class ScDBCollection;
 class ScDBData;
 class ScDetOpData;
@@ -246,7 +246,7 @@ private:
     ScDrawLayer*        pDrawLayer;                     // SdrModel
     rtl::Reference<XColorList> pColorList;
     ScConditionalFormatList* pCondFormList;             // conditional formats
-    boost::scoped_ptr<ScColorScaleFormatList> mpColorScaleList; //color scales
+    boost::scoped_ptr<ScColorFormatList> mpColorScaleList; //color scales
     ScValidationDataList* pValidationList;              // validity
     SvNumberFormatterIndexTable*    pFormatExchangeList;    // for application of number formats
     TableContainer maTabs;
@@ -1212,8 +1212,8 @@ public:
                     { return pCondFormList; }
     void            SetCondFormList(ScConditionalFormatList* pNew);
 
-    SC_DLLPUBLIC const ScColorScaleFormatList* GetColorScaleList() const;
-    SC_DLLPUBLIC ScColorScaleFormatList* GetColorScaleList();
+    SC_DLLPUBLIC const ScColorFormatList* GetColorScaleList() const;
+    SC_DLLPUBLIC ScColorFormatList* GetColorScaleList();
 
     ScValidationDataList* GetValidationList() const
                     { return pValidationList; }
diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx
index bad6a14..1892a75 100644
--- a/sc/source/core/data/colorscale.cxx
+++ b/sc/source/core/data/colorscale.cxx
@@ -120,21 +120,43 @@ const Color& ScColorScaleEntry::GetColor() const
     return maColor;
 }
 
-ScColorScaleFormat::ScColorScaleFormat(ScDocument* pDoc):
+ScColorFormat::ScColorFormat(ScDocument* pDoc):
     mpDoc(pDoc)
 {
 }
 
-ScColorScaleFormat::ScColorScaleFormat(ScDocument* pDoc, const ScColorScaleFormat& rFormat):
+ScColorFormat::ScColorFormat(ScDocument* pDoc, const ScColorFormat& rFormat):
     maRanges(rFormat.maRanges),
     mpDoc(pDoc)
 {
+}
+
+ScColorFormat::~ScColorFormat()
+{
+}
+
+ScColorScaleFormat::ScColorScaleFormat(ScDocument* pDoc):
+    ScColorFormat(pDoc)
+{
+}
+
+ScColorScaleFormat::ScColorScaleFormat(ScDocument* pDoc, const ScColorScaleFormat& rFormat):
+    ScColorFormat(pDoc, rFormat)
+{
     for(const_iterator itr = rFormat.begin(); itr != rFormat.end(); ++itr)
     {
         maColorScales.push_back(new ScColorScaleEntry(pDoc, *itr));
     }
 }
 
+ScColorFormat* ScColorScaleFormat::Clone(ScDocument* pDoc) const
+{
+    return new ScColorScaleFormat(pDoc, *this);
+}
+
+ScColorScaleFormat::~ScColorScaleFormat()
+{
+}
 
 void ScColorScaleFormat::AddEntry( ScColorScaleEntry* pEntry )
 {
@@ -292,12 +314,12 @@ void ScColorScaleFormat::calcMinMax(double& rMin, double& rMax) const
     rMax = GetMaxValue();
 }
 
-void ScColorScaleFormat::SetRange(const ScRangeList& rList)
+void ScColorFormat::SetRange(const ScRangeList& rList)
 {
     maRanges = rList;
 }
 
-const ScRangeList& ScColorScaleFormat::GetRange() const
+const ScRangeList& ScColorFormat::GetRange() const
 {
     return maRanges;
 }
@@ -485,6 +507,11 @@ void ScColorScaleFormat::DataChanged(const ScRange& rRange)
     }
 }
 
+ScColorFormatType ScColorScaleFormat::GetType() const
+{
+    return COLORSCALE;
+}
+
 ScColorScaleFormat::iterator ScColorScaleFormat::begin()
 {
     return maColorScales.begin();
@@ -505,21 +532,21 @@ ScColorScaleFormat::const_iterator ScColorScaleFormat::end() const
     return maColorScales.end();
 }
 
-ScColorScaleFormatList::ScColorScaleFormatList(ScDocument* pDoc, const ScColorScaleFormatList& rList)
+ScColorFormatList::ScColorFormatList(ScDocument* pDoc, const ScColorFormatList& rList)
 {
     for(const_iterator itr = rList.begin(); itr != rList.end(); ++itr)
     {
-        maColorScaleFormats.push_back(new ScColorScaleFormat(pDoc, *itr));
+        maColorScaleFormats.push_back(itr->Clone(pDoc));
     }
 }
 
-void ScColorScaleFormatList::AddFormat( ScColorScaleFormat* pFormat )
+void ScColorFormatList::AddFormat( ScColorFormat* pFormat )
 {
     maColorScaleFormats.push_back( pFormat );
 }
 
 // attention nFormat is 1 based, 0 is reserved for no format
-ScColorScaleFormat* ScColorScaleFormatList::GetFormat(sal_uInt32 nFormat)
+ScColorFormat* ScColorFormatList::GetFormat(sal_uInt32 nFormat)
 {
     if( nFormat > size() || !nFormat )
         return NULL;
@@ -527,32 +554,32 @@ ScColorScaleFormat* ScColorScaleFormatList::GetFormat(sal_uInt32 nFormat)
     return &maColorScaleFormats[nFormat-1];
 }
 
-ScColorScaleFormatList::iterator ScColorScaleFormatList::begin()
+ScColorFormatList::iterator ScColorFormatList::begin()
 {
     return maColorScaleFormats.begin();
 }
 
-ScColorScaleFormatList::const_iterator ScColorScaleFormatList::begin() const
+ScColorFormatList::const_iterator ScColorFormatList::begin() const
 {
     return maColorScaleFormats.begin();
 }
 
-ScColorScaleFormatList::iterator ScColorScaleFormatList::end()
+ScColorFormatList::iterator ScColorFormatList::end()
 {
     return maColorScaleFormats.end();
 }
 
-ScColorScaleFormatList::const_iterator ScColorScaleFormatList::end() const
+ScColorFormatList::const_iterator ScColorFormatList::end() const
 {
     return maColorScaleFormats.end();
 }
 
-size_t ScColorScaleFormatList::size() const
+size_t ScColorFormatList::size() const
 {
     return maColorScaleFormats.size();
 }
 
-void ScColorScaleFormatList::DataChanged(const ScRange& rRange)
+void ScColorFormatList::DataChanged(const ScRange& rRange)
 {
     for(iterator itr = begin(); itr != end(); ++itr)
     {
@@ -560,7 +587,7 @@ void ScColorScaleFormatList::DataChanged(const ScRange& rRange)
     }
 }
 
-void ScColorScaleFormatList::UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab)
+void ScColorFormatList::UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab)
 {
     for(iterator itr = begin(); itr != end(); ++itr)
     {
@@ -568,7 +595,7 @@ void ScColorScaleFormatList::UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab)
     }
 }
 
-void ScColorScaleFormatList::UpdateReference( UpdateRefMode eUpdateRefMode,
+void ScColorFormatList::UpdateReference( UpdateRefMode eUpdateRefMode,
             const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
 {
     for(iterator itr = begin(); itr != end(); ++itr)
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 87ad7d4..0135892 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -476,9 +476,9 @@ void ScDocument::InitClipPtrs( ScDocument* pSourceDoc )
     if ( pSourceCond )
         pCondFormList = new ScConditionalFormatList(this, *pSourceCond);
 
-    const ScColorScaleFormatList* pSourceColorScaleList = pSourceDoc->mpColorScaleList.get();
+    const ScColorFormatList* pSourceColorScaleList = pSourceDoc->mpColorScaleList.get();
     if ( pSourceColorScaleList )
-        mpColorScaleList.reset(new ScColorScaleFormatList(this, *pSourceColorScaleList));
+        mpColorScaleList.reset(new ScColorFormatList(this, *pSourceColorScaleList));
 
     const ScValidationDataList* pSourceValid = pSourceDoc->pValidationList;
     if ( pSourceValid )
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index cae9473..76d3773 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -628,12 +628,12 @@ sal_uLong ScDocument::AddCondFormat( const ScConditionalFormat& rNew )
     return nNewKey;
 }
 
-const ScColorScaleFormatList* ScDocument::GetColorScaleList() const
+const ScColorFormatList* ScDocument::GetColorScaleList() const
 {
     return mpColorScaleList.get();
 }
 
-ScColorScaleFormatList* ScDocument::GetColorScaleList()
+ScColorFormatList* ScDocument::GetColorScaleList()
 {
     return mpColorScaleList.get();
 }
@@ -646,7 +646,7 @@ sal_uLong ScDocument::AddColorScaleFormat( ScColorScaleFormat* pNew )
         return 0;
 
     if(!mpColorScaleList)
-        mpColorScaleList.reset(new ScColorScaleFormatList());
+        mpColorScaleList.reset(new ScColorFormatList());
 
     mpColorScaleList->AddFormat( pNew );
 
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index 9d7fc2f..4b227b0 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -489,7 +489,11 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
 
                         const ScColorScaleFormat* pColorScale = NULL;
                         if ( nColorScale && mpColorScaleList )
-                            pColorScale = mpColorScaleList->GetFormat( nColorScale );
+                        {
+                            ScColorFormat* pFormat = mpColorScaleList->GetFormat( nColorScale );
+                            if(pFormat->GetType() == COLORSCALE)
+                                pColorScale = static_cast<ScColorScaleFormat*>(pFormat);
+                        }
 
                         do
                         {
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 9674c2a..09a171f 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -702,8 +702,8 @@ void ScTable::CopyColorScales( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow
     std::map<sal_Int32, sal_Int32> aOldIdToNewId;
     std::map<sal_Int32, ScRangeList> aIdToRange;
 
-    ScColorScaleFormatList* pColorScaleList = pDocument->GetColorScaleList();
-    ScColorScaleFormatList* pOldColorScaleList = pTable->pDocument->GetColorScaleList();
+    ScColorFormatList* pColorScaleList = pDocument->GetColorScaleList();
+    ScColorFormatList* pOldColorScaleList = pTable->pDocument->GetColorScaleList();
     for(SCCOL i = nCol1; i <= nCol2; ++i)
     {
         ScAttrIterator* pIter = aCol[i-nDx].CreateAttrIterator( nRow1-nDy, nRow2-nDy );
@@ -714,8 +714,8 @@ void ScTable::CopyColorScales( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow
         {
             if (aOldIdToNewId.find(nId) == aOldIdToNewId.end())
             {
-                ScColorScaleFormat* pFormat = pOldColorScaleList->GetFormat(nId);
-                ScColorScaleFormat* pNewFormat = new ScColorScaleFormat(pDocument, *pFormat);
+                ScColorFormat* pFormat = pOldColorScaleList->GetFormat(nId);
+                ScColorFormat* pNewFormat = pFormat->Clone(pDocument);
                 sal_Int32 nNewId = pColorScaleList->size() + 1;
                 //not in list => create entries in both maps and new format
                 pColorScaleList->AddFormat(pNewFormat);
@@ -731,7 +731,7 @@ void ScTable::CopyColorScales( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow
             itr != aIdToRange.end(); ++itr)
     {
         sal_uInt32 nNewKey = aOldIdToNewId.find(itr->first)->second;
-        ScColorScaleFormat* pFormat = pColorScaleList->GetFormat( nNewKey );
+        ScColorFormat* pFormat = pColorScaleList->GetFormat( nNewKey );
         pFormat->UpdateReference(URM_MOVE, ScRange(nCol1 - nDx, nRow1 - nDy, pTable->nTab, nCol2 - nDx, nRow2 - nDy, pTable->nTab),
                 nDx, nDy, pTable->nTab - nTab);
         pFormat->SetRange(itr->second);
diff --git a/sc/source/filter/excel/xecontent.cxx b/sc/source/filter/excel/xecontent.cxx
index 968aab2..9f42dcb 100644
--- a/sc/source/filter/excel/xecontent.cxx
+++ b/sc/source/filter/excel/xecontent.cxx
@@ -1084,16 +1084,19 @@ XclExpCondFormatBuffer::XclExpCondFormatBuffer( const XclExpRoot& rRoot ) :
                 maCondfmtList.AppendRecord( xCondfmtRec );
         }
     }
-    if( const ScColorScaleFormatList* pColorScaleList = GetDoc().GetColorScaleList() )
+    if( const ScColorFormatList* pColorScaleList = GetDoc().GetColorScaleList() )
     {
-        for( ScColorScaleFormatList::const_iterator itr = pColorScaleList->begin();
+        for( ScColorFormatList::const_iterator itr = pColorScaleList->begin();
                 itr != pColorScaleList->end(); ++itr)
         {
             const ScRangeList& rList = itr->GetRange();
             if (rList.front()->aStart.Tab() == GetCurrScTab())
             {
-                XclExpColorScaleList::RecordRefType xColorScaleRec( new XclExpColorScale( GetRoot(), *itr ) );
-                maColorScaleList.AppendRecord( xColorScaleRec );
+                if(itr->GetType() == COLORSCALE)
+                {
+                    XclExpColorScaleList::RecordRefType xColorScaleRec( new XclExpColorScale( GetRoot(), static_cast<const ScColorScaleFormat&>(*itr) ) );
+                    maColorScaleList.AppendRecord( xColorScaleRec );
+                }
             }
         }
     }
commit 914fc75da516218bb072245a5c2e3038a4e3639e
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu May 17 11:03:14 2012 +0200

    add render code for data bars
    
    Still missing some advanced features like gradients, dotted line at the
    zero point, ...
    
    Change-Id: If8409ffab658315a6fed220e61d0854680633e1e

diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx
index a5786ba..5aecd51 100644
--- a/sc/inc/fillinfo.hxx
+++ b/sc/inc/fillinfo.hxx
@@ -62,6 +62,14 @@ enum ScShadowPart
     SC_SHADOW_CORNER
 };
 
+struct ScDataBarInfo
+{
+    double mnZero; // 0 to 100
+    Color maColor;
+    double mnLength; // -100 to 100
+    bool mbGradient;
+};
+
 struct CellInfo
 {
     ScBaseCell*                 pCell;
@@ -69,6 +77,7 @@ struct CellInfo
     const ScPatternAttr*        pPatternAttr;
     const SfxItemSet*           pConditionSet;
     const Color*                pColorScale;
+    const ScDataBarInfo*        pDataBar;
 
     const SvxBrushItem*         pBackground;
 
@@ -104,11 +113,13 @@ struct CellInfo
     sal_Bool                        bEditEngine : 1;            // output-internal
 
     CellInfo():
-        pColorScale(NULL) {}
+        pColorScale(NULL),
+        pDataBar(NULL) {}
 
     ~CellInfo()
     {
         delete pColorScale;
+        delete pDataBar;
     }
 };
 
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index 0c46c0b..2f968b7 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -769,6 +769,15 @@ sal_Bool lcl_EqualBack( const RowInfo& rFirst, const RowInfo& rOther,
 
         if (pCol1 && (*pCol1 != *pCol2))
             return false;
+
+        const ScDataBarInfo* pInfo1 = rFirst.pCellInfo[nX+1].pDataBar;
+        const ScDataBarInfo* pInfo2 = rOther.pCellInfo[nX+1].pDataBar;
+
+        if( (pInfo1 && !pInfo2) || (!pInfo1 && pInfo2) )
+            return false;
+
+        if (pInfo1 && (*pInfo1 != *pInfo2))
+            return false;
     }
 
     return sal_True;
@@ -790,26 +799,62 @@ void ScOutputData::DrawDocumentBackground()
 
 namespace {
 
+void drawDataBars( const ScDataBarInfo* pOldDataBarInfo, OutputDevice* pDev, const Rectangle& rRect)
+{
+    long nPosZero = 0;
+    if(pOldDataBarInfo->mnZero)
+    {
+        //need to calculate null point in cell
+        long nLength = rRect.Right() - rRect.Left();
+        nPosZero = static_cast<long>(rRect.Left() + nLength*pOldDataBarInfo->mnZero/100.0);
+    }
+    else
+    {
+        nPosZero = rRect.Left();
+    }
+    Rectangle aPaintRect = rRect;
+
+    if(pOldDataBarInfo->mnLength < 0)
+    {
+        aPaintRect.Right() = nPosZero;
+        long nLength = nPosZero - aPaintRect.Left();
+        aPaintRect.Left() = nPosZero + static_cast<long>(nLength * pOldDataBarInfo->mnLength/100.0);
+    }
+    else if(pOldDataBarInfo->mnLength > 0)
+    {
+        aPaintRect.Left() = nPosZero;
+        long nLength = aPaintRect.Right() - nPosZero;
+        aPaintRect.Right() = nPosZero + static_cast<long>(nLength * pOldDataBarInfo->mnLength/100.0);
+    }
+    else
+        return;
+
+    //TODO: improve this for gradient fill
+    pDev->SetFillColor(pOldDataBarInfo->maColor);
+    pDev->DrawRect(aPaintRect);
+}
+
 void drawCells(const Color* pColor, const SvxBrushItem* pBackground, const Color*& pOldColor, const SvxBrushItem*& pOldBackground,
-        Rectangle& rRect, long nPosX, long nSignedOneX, OutputDevice* pDev)
+        Rectangle& rRect, long nPosX, long nSignedOneX, OutputDevice* pDev, const ScDataBarInfo* pDataBarInfo, const ScDataBarInfo*& pOldDataBarInfo)
 {
 
     // need to paint if old color scale has been used and now
     // we have a different color or a style based background
     // we can here fall back to pointer comparison
-    if (pOldColor && (pBackground || pOldColor != pColor))
+    if (pOldColor && (pBackground || pOldColor != pColor || pOldDataBarInfo || pDataBarInfo))
     {
-
         rRect.Right() = nPosX-nSignedOneX;
         if( !pOldColor->GetTransparency() )
         {
             pDev->SetFillColor( *pOldColor );
             pDev->DrawRect( rRect );
         }
+        if( pOldDataBarInfo )
+            drawDataBars( pOldDataBarInfo, pDev, rRect );
         rRect.Left() = nPosX - nSignedOneX;
     }
 
-    if ( pOldBackground && (pColor ||pBackground != pOldBackground) )
+    if ( pOldBackground && (pColor ||pBackground != pOldBackground || pOldDataBarInfo || pDataBarInfo) )
     {
         rRect.Right() = nPosX-nSignedOneX;
         if (pOldBackground)             // ==0 if hidden
@@ -821,6 +866,14 @@ void drawCells(const Color* pColor, const SvxBrushItem* pBackground, const Color
                 pDev->DrawRect( rRect );
             }
         }
+        if( pOldDataBarInfo )
+            drawDataBars( pOldDataBarInfo, pDev, rRect );
+        rRect.Left() = nPosX - nSignedOneX;
+    }
+
+    if (!pOldBackground && !pOldColor && pDataBarInfo)
+    {
+        rRect.Right() = nPosX -nSignedOneX;
         rRect.Left() = nPosX - nSignedOneX;
     }
 
@@ -837,6 +890,11 @@ void drawCells(const Color* pColor, const SvxBrushItem* pBackground, const Color
         pOldBackground = pBackground;
         pOldColor = NULL;
     }
+
+    if(pDataBarInfo)
+        pOldDataBarInfo = pDataBarInfo;
+    else
+        pOldDataBarInfo = NULL;
 }
 
 }
@@ -897,6 +955,7 @@ void ScOutputData::DrawBackground()
                 const SvxBrushItem* pBackground;
                 const Color* pOldColor = NULL;
                 const Color* pColor = NULL;
+                const ScDataBarInfo* pOldDataBarInfo = NULL;
                 for (SCCOL nX=nX1; nX<=nX2; nX++)
                 {
                     CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
@@ -936,11 +995,12 @@ void ScOutputData::DrawBackground()
                     }
 
                     pColor = pInfo->pColorScale;
-                    drawCells( pColor, pBackground, pOldColor, pOldBackground, aRect, nPosX, nSignedOneX, pDev );
+                    const ScDataBarInfo* pDataBarInfo = pInfo->pDataBar;
+                    drawCells( pColor, pBackground, pOldColor, pOldBackground, aRect, nPosX, nSignedOneX, pDev, pDataBarInfo, pOldDataBarInfo );
 
                     nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
                 }
-                drawCells( NULL, NULL, pOldColor, pOldBackground, aRect, nPosX, nSignedOneX, pDev );
+                drawCells( NULL, NULL, pOldColor, pOldBackground, aRect, nPosX, nSignedOneX, pDev, NULL, pOldDataBarInfo );
 
                 nArrY += nSkip;
             }


More information about the Libreoffice-commits mailing list