class WXDLLEXPORT wxGridCellAttr
{
public:
+ enum wxAttrKind
+ {
+ Any,
+ Default,
+ Cell,
+ Row,
+ Col,
+ Merged
+ };
+
// ctors
wxGridCellAttr()
{
// creates a new copy of this object
wxGridCellAttr *Clone() const;
+ void MergeWith(wxGridCellAttr *mergefrom);
// this class is ref counted: it is created with ref count of 1, so
// calling DecRef() once will delete it. Calling IncRef() allows to lock
m_hAlign = hAlign;
m_vAlign = vAlign;
}
- void SetReadOnly(bool isReadOnly = TRUE) { m_isReadOnly = isReadOnly; }
+ void SetReadOnly(bool isReadOnly = TRUE)
+ { m_isReadOnly = isReadOnly ? ReadOnly : ReadWrite; }
// takes ownership of the pointer
void SetRenderer(wxGridCellRenderer *renderer)
void SetEditor(wxGridCellEditor* editor)
{ wxSafeDecRef(m_editor); m_editor = editor; }
+ void SetKind(wxAttrKind kind) { m_attrkind = kind; }
+
// accessors
bool HasTextColour() const { return m_colText.Ok(); }
bool HasBackgroundColour() const { return m_colBack.Ok(); }
bool HasAlignment() const { return (m_hAlign != -1 || m_vAlign != -1); }
bool HasRenderer() const { return m_renderer != NULL; }
bool HasEditor() const { return m_editor != NULL; }
+ bool HasReadWriteMode() const { return m_isReadOnly != Unset; }
const wxColour& GetTextColour() const;
const wxColour& GetBackgroundColour() const;
wxGridCellRenderer *GetRenderer(wxGrid* grid, int row, int col) const;
wxGridCellEditor *GetEditor(wxGrid* grid, int row, int col) const;
- bool IsReadOnly() const { return m_isReadOnly; }
+ bool IsReadOnly() const { return m_isReadOnly == wxGridCellAttr::ReadOnly; }
+
+ wxAttrKind GetKind() { return m_attrkind; }
void SetDefAttr(wxGridCellAttr* defAttr) { m_defGridAttr = defAttr; }
private:
+ enum wxAttrReadMode
+ {
+ Unset = -1,
+ ReadWrite,
+ ReadOnly
+ };
+
// the common part of all ctors
void Init()
{
m_nRef = 1;
- m_isReadOnly = FALSE;
+ m_isReadOnly = Unset;
m_renderer = NULL;
m_editor = NULL;
+
+ m_attrkind = wxGridCellAttr::Cell;
}
// the dtor is private because only DecRef() can delete us
wxGridCellEditor* m_editor;
wxGridCellAttr* m_defGridAttr;
- bool m_isReadOnly;
+ wxAttrReadMode m_isReadOnly;
+
+ wxAttrKind m_attrkind;
// use Clone() instead
DECLARE_NO_COPY_CLASS(wxGridCellAttr);
virtual ~wxGridCellAttrProvider();
// DecRef() must be called on the returned pointer
- virtual wxGridCellAttr *GetAttr(int row, int col) const;
+ virtual wxGridCellAttr *GetAttr(int row, int col,
+ wxGridCellAttr::wxAttrKind kind ) const;
// all these functions take ownership of the pointer, don't call DecRef()
// on it
// by default forwarded to wxGridCellAttrProvider if any. May be
// overridden to handle attributes directly in the table.
- virtual wxGridCellAttr *GetAttr( int row, int col );
+ virtual wxGridCellAttr *GetAttr( int row, int col,
+ wxGridCellAttr::wxAttrKind kind );
+
// these functions take ownership of the pointer
virtual void SetAttr(wxGridCellAttr* attr, int row, int col);
grid->SetCellAlignment(4, 4, wxALIGN_CENTRE, wxALIGN_CENTRE);
grid->SetCellRenderer(4, 4, new MyGridCellRenderer);
- grid->SetCellValue(3, 0, "1");
+ grid->SetCellValue(3, 0, "0");
grid->SetCellRenderer(3, 0, new wxGridCellBoolRenderer);
grid->SetCellEditor(3, 0, new wxGridCellBoolEditor);
attr->SetTextColour(*wxBLUE);
grid->SetColAttr(5, attr);
attr = new wxGridCellAttr;
- attr->SetBackgroundColour(*wxBLUE);
+ attr->SetBackgroundColour(*wxRED);
grid->SetRowAttr(5, attr);
grid->SetCellValue(2, 4, "a wider column");
grid->SetColSize(4, 120);
grid->SetColMinimalWidth(4, 120);
- grid->SetColFormatFloat(5);
- grid->SetCellValue(0, 5, "3.1415");
- grid->SetCellValue(1, 5, "1415");
- grid->SetCellValue(2, 5, "12345.67890");
+ grid->SetCellTextColour(5, 8, *wxGREEN);
+ grid->SetCellValue(5, 8, "Bg from row attr\nText col from cell attr");
+ grid->SetCellValue(5, 5, "Bg from row attr\nText col from col attr");
- grid->SetColFormatFloat(6, 6, 2);
+ grid->SetColFormatFloat(6);
grid->SetCellValue(0, 6, "3.1415");
grid->SetCellValue(1, 6, "1415");
grid->SetCellValue(2, 6, "12345.67890");
+ grid->SetColFormatFloat(7, 6, 2);
+ grid->SetCellValue(0, 7, "3.1415");
+ grid->SetCellValue(1, 7, "1415");
+ grid->SetCellValue(2, 7, "12345.67890");
+
wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
topSizer->Add( grid,
1,
frame->Show(TRUE);
}
+
void GridFrame::OnVTable(wxCommandEvent& )
{
static long s_sizeGrid = 10000;
m_attrForOddRows->DecRef();
}
-wxGridCellAttr *MyGridCellAttrProvider::GetAttr(int row, int col) const
+wxGridCellAttr *MyGridCellAttrProvider::GetAttr(int row, int col,
+ wxGridCellAttr::wxAttrKind kind /* = wxGridCellAttr::Any */) const
{
- wxGridCellAttr *attr = wxGridCellAttrProvider::GetAttr(row, col);
+ wxGridCellAttr *attr = wxGridCellAttrProvider::GetAttr(row, col, kind);
if ( row % 2 )
{
size.y += 10;
SetClientSize(size);
}
+
+
{
if ( m_width == -1 )
{
+ if ( m_precision == -1 )
+ {
// default width/precision
m_format = _T("%f");
+ }
+ else
+ {
+ m_format.Printf(_T("%%.%df"), m_precision);
+ }
}
else if ( m_precision == -1 )
{
}
text.Printf(m_format, val);
+
}
//else: text already contains the string
void wxGridCellFloatRenderer::SetParameters(const wxString& params)
{
- bool ok = TRUE;
-
if ( !params )
{
// reset to defaults
if ( !!tmp )
{
long width;
- if ( !tmp.ToLong(&width) )
+ if ( tmp.ToLong(&width) )
{
- ok = FALSE;
+ SetWidth((int)width);
}
else
{
- SetWidth((int)width);
+ wxLogDebug(_T("Invalid wxGridCellFloatRenderer width parameter string '%s ignored"), params.c_str());
+ }
+ }
tmp = params.AfterFirst(_T(','));
if ( !!tmp )
{
long precision;
- if ( !tmp.ToLong(&precision) )
+ if ( tmp.ToLong(&precision) )
{
- ok = FALSE;
+ SetPrecision((int)precision);
}
else
{
- SetPrecision((int)precision);
- }
- }
- }
+ wxLogDebug(_T("Invalid wxGridCellFloatRenderer precision parameter string '%s ignored"), params.c_str());
}
- if ( !ok )
- {
- wxLogDebug(_T("Invalid wxGridCellFloatRenderer parameter string '%s ignored"), params.c_str());
}
}
}
+
// ----------------------------------------------------------------------------
// wxGridCellBoolRenderer
// ----------------------------------------------------------------------------
if ( IsReadOnly() )
attr->SetReadOnly();
+ attr->SetKind( m_attrkind );
+
attr->SetDefAttr(m_defGridAttr);
return attr;
}
+void wxGridCellAttr::MergeWith(wxGridCellAttr *mergefrom)
+{
+ if ( !HasTextColour() && mergefrom->HasTextColour() )
+ SetTextColour(mergefrom->GetTextColour());
+ if ( !HasBackgroundColour() && mergefrom->HasBackgroundColour() )
+ SetBackgroundColour(mergefrom->GetBackgroundColour());
+ if ( !HasFont() && mergefrom->HasFont() )
+ SetFont(mergefrom->GetFont());
+ if ( !!HasAlignment() && mergefrom->HasAlignment() ){
+ int hAlign, vAlign;
+ mergefrom->GetAlignment( &hAlign, &vAlign);
+ SetAlignment(hAlign, vAlign);
+ }
+
+ // Directly access member functions as GetRender/Editor don't just return
+ // m_renderer/m_editor
+ //
+ // Maybe add support for merge of Render and Editor?
+ if (!HasRenderer() && mergefrom->HasRenderer() )
+ {
+ m_renderer = mergefrom->m_renderer;
+ m_renderer->IncRef();
+ }
+ if ( !HasEditor() && mergefrom->HasEditor() )
+ {
+ m_editor = mergefrom->m_editor;
+ m_editor->IncRef();
+ }
+ if ( !HasReadWriteMode() && mergefrom->HasReadWriteMode() )
+ SetReadOnly(mergefrom->IsReadOnly());
+
+ SetDefAttr(mergefrom->m_defGridAttr);
+}
+
const wxColour& wxGridCellAttr::GetTextColour() const
{
if (HasTextColour())
m_data = new wxGridCellAttrProviderData;
}
-wxGridCellAttr *wxGridCellAttrProvider::GetAttr(int row, int col) const
+wxGridCellAttr *wxGridCellAttrProvider::GetAttr(int row, int col,
+ wxGridCellAttr::wxAttrKind kind ) const
{
wxGridCellAttr *attr = (wxGridCellAttr *)NULL;
if ( m_data )
{
- // first look for the attribute of this specific cell
- attr = m_data->m_cellAttrs.GetAttr(row, col);
-
- if ( !attr )
+ switch(kind)
{
- // then look for the col attr (col attributes are more common than
- // the row ones, hence they have priority)
- attr = m_data->m_colAttrs.GetAttr(col);
- }
-
- if ( !attr )
+ case (wxGridCellAttr::Any):
+ //Get cached merge attributes.
+ // Currenlty not used as no cache implemented as not mutiable
+ // attr = m_data->m_mergeAttr.GetAttr(row, col);
+ if(!attr)
+ {
+ //Basicaly implement old version.
+ //Also check merge cache, so we don't have to re-merge every time..
+ wxGridCellAttr *attrcell = (wxGridCellAttr *)NULL,
+ *attrrow = (wxGridCellAttr *)NULL,
+ *attrcol = (wxGridCellAttr *)NULL;
+
+ attrcell = m_data->m_cellAttrs.GetAttr(row, col);
+ attrcol = m_data->m_colAttrs.GetAttr(col);
+ attrrow = m_data->m_rowAttrs.GetAttr(row);
+
+ if((attrcell != attrrow) && (attrrow !=attrcol) && (attrcell != attrcol)){
+ // Two or move are non NULL
+ attr = new wxGridCellAttr;
+ attr->SetKind(wxGridCellAttr::Merged);
+
+ //Order important..
+ if(attrcell){
+ attr->MergeWith(attrcell);
+ attrcell->DecRef();
+ }
+ if(attrcol){
+ attr->MergeWith(attrcol);
+ attrcol->DecRef();
+ }
+ if(attrrow){
+ attr->MergeWith(attrrow);
+ attrrow->DecRef();
+ }
+ //store merge attr if cache implemented
+ //attr->IncRef();
+ //m_data->m_mergeAttr.SetAttr(attr, row, col);
+ }
+ else
{
- // finally try the row attributes
+ // one or none is non null return it or null.
+ if(attrrow) attr = attrrow;
+ if(attrcol) attr = attrcol;
+ if(attrcell) attr = attrcell;
+ }
+ }
+ break;
+ case (wxGridCellAttr::Cell):
+ attr = m_data->m_cellAttrs.GetAttr(row, col);
+ break;
+ case (wxGridCellAttr::Col):
+ attr = m_data->m_colAttrs.GetAttr(col);
+ break;
+ case (wxGridCellAttr::Row):
attr = m_data->m_rowAttrs.GetAttr(row);
+ break;
+ default:
+ // unused as yet...
+ // (wxGridCellAttr::Default):
+ // (wxGridCellAttr::Merged):
+ break;
}
}
-
return attr;
}
return TRUE;
}
-wxGridCellAttr *wxGridTableBase::GetAttr(int row, int col)
+wxGridCellAttr *wxGridTableBase::GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind)
{
if ( m_attrProvider )
- return m_attrProvider->GetAttr(row, col);
+ return m_attrProvider->GetAttr(row, col, kind);
else
return (wxGridCellAttr *)NULL;
}
{
if ( m_attrProvider )
{
+ attr->SetKind(wxGridCellAttr::Cell);
m_attrProvider->SetAttr(attr, row, col);
}
else
{
if ( m_attrProvider )
{
+ attr->SetKind(wxGridCellAttr::Row);
m_attrProvider->SetRowAttr(attr, row);
}
else
{
if ( m_attrProvider )
{
+ attr->SetKind(wxGridCellAttr::Col);
m_attrProvider->SetColAttr(attr, col);
}
else
m_defaultCellAttr->SetDefAttr(m_defaultCellAttr);
// Set default cell attributes
+ m_defaultCellAttr->SetKind(wxGridCellAttr::Default);
m_defaultCellAttr->SetFont(GetFont());
m_defaultCellAttr->SetAlignment(wxALIGN_LEFT, wxALIGN_TOP);
m_defaultCellAttr->SetTextColour(
if ( m_attrCache.row != -1 )
{
wxSafeDecRef(m_attrCache.attr);
+ m_attrCache.attr = NULL;
m_attrCache.row = -1;
}
}
wxGridCellAttr *attr;
if ( !LookupAttr(row, col, &attr) )
{
- attr = m_table ? m_table->GetAttr(row, col) : (wxGridCellAttr *)NULL;
+ attr = m_table ? m_table->GetAttr(row, col , wxGridCellAttr::Any) : (wxGridCellAttr *)NULL;
CacheAttr(row, col, attr);
}
if (attr)
wxGridCellAttr *wxGrid::GetOrCreateCellAttr(int row, int col) const
{
- wxGridCellAttr *attr;
- if ( !LookupAttr(row, col, &attr) || !attr )
- {
+ wxGridCellAttr *attr = (wxGridCellAttr *)NULL;
wxASSERT_MSG( m_table,
_T("we may only be called if CanHaveAttributes() returned TRUE and then m_table should be !NULL") );
- attr = m_table->GetAttr(row, col);
+ attr = m_table->GetAttr(row, col, wxGridCellAttr::Cell );
if ( !attr )
{
attr = new wxGridCellAttr;
// artificially inc the ref count to match DecRef() in caller
attr->IncRef();
-
m_table->SetAttr(attr, row, col);
}
-
- CacheAttr(row, col, attr);
- }
attr->SetDefAttr(m_defaultCellAttr);
return attr;
}
void wxGrid::SetColFormatCustom(int col, const wxString& typeName)
{
- wxGridCellAttr *attr = new wxGridCellAttr;
+ wxGridCellAttr *attr = (wxGridCellAttr *)NULL;
+
+ attr = m_table->GetAttr(-1, col, wxGridCellAttr::Col );
+ if(!attr)
+ attr = new wxGridCellAttr;
wxGridCellRenderer *renderer = GetDefaultRendererForType(typeName);
attr->SetRenderer(renderer);
SetColAttr(col, attr);
+
}
// ----------------------------------------------------------------------------
if ( CanHaveAttributes() )
{
m_table->SetRowAttr(attr, row);
+ ClearAttrCache();
}
else
{
if ( CanHaveAttributes() )
{
m_table->SetColAttr(attr, col);
+ ClearAttrCache();
}
else
{