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
This commit is contained in:
Markus Mohrhard 2012-05-18 10:33:58 +02:00
parent eb3d3a0a7d
commit 862f56d19e
6 changed files with 208 additions and 10 deletions

View file

@ -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

View file

@ -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 );

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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;
}