+ wxRect rect = CellToRect(row, col);
+ m_gridWin->Refresh(true, &rect);
+ }
+}
+
+void wxGrid::SetCellHighlightROPenWidth(int width)
+{
+ if (m_cellHighlightROPenWidth != width)
+ {
+ m_cellHighlightROPenWidth = width;
+
+ // Just redrawing the cell highlight is not enough since that won't
+ // make any visible change if the the thickness is getting smaller.
+ int row = m_currentCellCoords.GetRow();
+ int col = m_currentCellCoords.GetCol();
+ if ( row == -1 || col == -1 ||
+ GetColWidth(col) <= 0 || GetRowHeight(row) <= 0 )
+ return;
+
+ wxRect rect = CellToRect(row, col);
+ m_gridWin->Refresh(true, &rect);
+ }
+}
+
+void wxGrid::RedrawGridLines()
+{
+ // the lines will be redrawn when the window is thawn
+ if ( GetBatchCount() )
+ return;
+
+ if ( GridLinesEnabled() )
+ {
+ wxClientDC dc( m_gridWin );
+ PrepareDC( dc );
+ DrawAllGridLines( dc, wxRegion() );
+ }
+ else // remove the grid lines
+ {
+ m_gridWin->Refresh();
+ }
+}
+
+void wxGrid::EnableGridLines( bool enable )
+{
+ if ( enable != m_gridLinesEnabled )
+ {
+ m_gridLinesEnabled = enable;
+
+ RedrawGridLines();
+ }
+}
+
+void wxGrid::DoClipGridLines(bool& var, bool clip)
+{
+ if ( clip != var )
+ {
+ var = clip;
+
+ if ( GridLinesEnabled() )
+ RedrawGridLines();
+ }
+}
+
+int wxGrid::GetDefaultRowSize() const
+{
+ return m_defaultRowHeight;
+}
+
+int wxGrid::GetRowSize( int row ) const
+{
+ wxCHECK_MSG( row >= 0 && row < m_numRows, 0, wxT("invalid row index") );
+
+ return GetRowHeight(row);
+}
+
+int wxGrid::GetDefaultColSize() const
+{
+ return m_defaultColWidth;
+}
+
+int wxGrid::GetColSize( int col ) const
+{
+ wxCHECK_MSG( col >= 0 && col < m_numCols, 0, wxT("invalid column index") );
+
+ return GetColWidth(col);
+}
+
+// ============================================================================
+// access to the grid attributes: each of them has a default value in the grid
+// itself and may be overidden on a per-cell basis
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// setting default attributes
+// ----------------------------------------------------------------------------
+
+void wxGrid::SetDefaultCellBackgroundColour( const wxColour& col )
+{
+ m_defaultCellAttr->SetBackgroundColour(col);
+#ifdef __WXGTK__
+ m_gridWin->SetBackgroundColour(col);
+#endif
+}
+
+void wxGrid::SetDefaultCellTextColour( const wxColour& col )
+{
+ m_defaultCellAttr->SetTextColour(col);
+}
+
+void wxGrid::SetDefaultCellAlignment( int horiz, int vert )
+{
+ m_defaultCellAttr->SetAlignment(horiz, vert);
+}
+
+void wxGrid::SetDefaultCellOverflow( bool allow )
+{
+ m_defaultCellAttr->SetOverflow(allow);
+}
+
+void wxGrid::SetDefaultCellFont( const wxFont& font )
+{
+ m_defaultCellAttr->SetFont(font);
+}
+
+// For editors and renderers the type registry takes precedence over the
+// default attr, so we need to register the new editor/renderer for the string
+// data type in order to make setting a default editor/renderer appear to
+// work correctly.
+
+void wxGrid::SetDefaultRenderer(wxGridCellRenderer *renderer)
+{
+ RegisterDataType(wxGRID_VALUE_STRING,
+ renderer,
+ GetDefaultEditorForType(wxGRID_VALUE_STRING));
+}
+
+void wxGrid::SetDefaultEditor(wxGridCellEditor *editor)
+{
+ RegisterDataType(wxGRID_VALUE_STRING,
+ GetDefaultRendererForType(wxGRID_VALUE_STRING),
+ editor);
+}
+
+// ----------------------------------------------------------------------------
+// access to the default attributes
+// ----------------------------------------------------------------------------
+
+wxColour wxGrid::GetDefaultCellBackgroundColour() const
+{
+ return m_defaultCellAttr->GetBackgroundColour();
+}
+
+wxColour wxGrid::GetDefaultCellTextColour() const
+{
+ return m_defaultCellAttr->GetTextColour();
+}
+
+wxFont wxGrid::GetDefaultCellFont() const
+{
+ return m_defaultCellAttr->GetFont();
+}
+
+void wxGrid::GetDefaultCellAlignment( int *horiz, int *vert ) const
+{
+ m_defaultCellAttr->GetAlignment(horiz, vert);
+}
+
+bool wxGrid::GetDefaultCellOverflow() const
+{
+ return m_defaultCellAttr->GetOverflow();
+}
+
+wxGridCellRenderer *wxGrid::GetDefaultRenderer() const
+{
+ return m_defaultCellAttr->GetRenderer(NULL, 0, 0);
+}
+
+wxGridCellEditor *wxGrid::GetDefaultEditor() const
+{
+ return m_defaultCellAttr->GetEditor(NULL, 0, 0);
+}
+
+// ----------------------------------------------------------------------------
+// access to cell attributes
+// ----------------------------------------------------------------------------
+
+wxColour wxGrid::GetCellBackgroundColour(int row, int col) const
+{
+ wxGridCellAttr *attr = GetCellAttr(row, col);
+ wxColour colour = attr->GetBackgroundColour();
+ attr->DecRef();
+
+ return colour;
+}
+
+wxColour wxGrid::GetCellTextColour( int row, int col ) const
+{
+ wxGridCellAttr *attr = GetCellAttr(row, col);
+ wxColour colour = attr->GetTextColour();
+ attr->DecRef();
+
+ return colour;
+}
+
+wxFont wxGrid::GetCellFont( int row, int col ) const
+{
+ wxGridCellAttr *attr = GetCellAttr(row, col);
+ wxFont font = attr->GetFont();
+ attr->DecRef();
+
+ return font;
+}
+
+void wxGrid::GetCellAlignment( int row, int col, int *horiz, int *vert ) const
+{
+ wxGridCellAttr *attr = GetCellAttr(row, col);
+ attr->GetAlignment(horiz, vert);
+ attr->DecRef();
+}
+
+bool wxGrid::GetCellOverflow( int row, int col ) const
+{
+ wxGridCellAttr *attr = GetCellAttr(row, col);
+ bool allow = attr->GetOverflow();
+ attr->DecRef();
+
+ return allow;
+}
+
+wxGrid::CellSpan
+wxGrid::GetCellSize( int row, int col, int *num_rows, int *num_cols ) const
+{
+ wxGridCellAttr *attr = GetCellAttr(row, col);
+ attr->GetSize( num_rows, num_cols );
+ attr->DecRef();
+
+ if ( *num_rows == 1 && *num_cols == 1 )
+ return CellSpan_None; // just a normal cell
+
+ if ( *num_rows < 0 || *num_cols < 0 )
+ return CellSpan_Inside; // covered by a multi-span cell
+
+ // this cell spans multiple cells to its right/bottom
+ return CellSpan_Main;
+}
+
+wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col) const
+{
+ wxGridCellAttr* attr = GetCellAttr(row, col);
+ wxGridCellRenderer* renderer = attr->GetRenderer(this, row, col);
+ attr->DecRef();
+
+ return renderer;
+}
+
+wxGridCellEditor* wxGrid::GetCellEditor(int row, int col) const
+{
+ wxGridCellAttr* attr = GetCellAttr(row, col);
+ wxGridCellEditor* editor = attr->GetEditor(this, row, col);
+ attr->DecRef();
+
+ return editor;
+}
+
+bool wxGrid::IsReadOnly(int row, int col) const
+{
+ wxGridCellAttr* attr = GetCellAttr(row, col);
+ bool isReadOnly = attr->IsReadOnly();
+ attr->DecRef();
+
+ return isReadOnly;
+}
+
+// ----------------------------------------------------------------------------
+// attribute support: cache, automatic provider creation, ...
+// ----------------------------------------------------------------------------
+
+bool wxGrid::CanHaveAttributes() const
+{
+ if ( !m_table )
+ {
+ return false;
+ }
+
+ return m_table->CanHaveAttributes();
+}
+
+void wxGrid::ClearAttrCache()
+{
+ if ( m_attrCache.row != -1 )
+ {
+ wxGridCellAttr *oldAttr = m_attrCache.attr;
+ m_attrCache.attr = NULL;
+ m_attrCache.row = -1;
+ // wxSafeDecRec(...) might cause event processing that accesses
+ // the cached attribute, if one exists (e.g. by deleting the
+ // editor stored within the attribute). Therefore it is important
+ // to invalidate the cache before calling wxSafeDecRef!
+ wxSafeDecRef(oldAttr);
+ }
+}
+
+void wxGrid::CacheAttr(int row, int col, wxGridCellAttr *attr) const
+{
+ if ( attr != NULL )
+ {
+ wxGrid *self = (wxGrid *)this; // const_cast
+
+ self->ClearAttrCache();
+ self->m_attrCache.row = row;
+ self->m_attrCache.col = col;
+ self->m_attrCache.attr = attr;
+ wxSafeIncRef(attr);
+ }
+}
+
+bool wxGrid::LookupAttr(int row, int col, wxGridCellAttr **attr) const
+{
+ if ( row == m_attrCache.row && col == m_attrCache.col )
+ {
+ *attr = m_attrCache.attr;
+ wxSafeIncRef(m_attrCache.attr);
+
+#ifdef DEBUG_ATTR_CACHE
+ gs_nAttrCacheHits++;
+#endif
+
+ return true;
+ }
+ else
+ {
+#ifdef DEBUG_ATTR_CACHE
+ gs_nAttrCacheMisses++;
+#endif
+
+ return false;
+ }
+}
+
+wxGridCellAttr *wxGrid::GetCellAttr(int row, int col) const
+{
+ wxGridCellAttr *attr = NULL;
+ // Additional test to avoid looking at the cache e.g. for
+ // wxNoCellCoords, as this will confuse memory management.
+ if ( row >= 0 )
+ {
+ if ( !LookupAttr(row, col, &attr) )
+ {
+ attr = m_table ? m_table->GetAttr(row, col, wxGridCellAttr::Any)
+ : NULL;
+ CacheAttr(row, col, attr);
+ }
+ }
+
+ if (attr)
+ {
+ attr->SetDefAttr(m_defaultCellAttr);
+ }
+ else
+ {
+ attr = m_defaultCellAttr;
+ attr->IncRef();
+ }
+
+ return attr;
+}
+
+wxGridCellAttr *wxGrid::GetOrCreateCellAttr(int row, int col) const
+{
+ wxGridCellAttr *attr = NULL;
+ bool canHave = ((wxGrid*)this)->CanHaveAttributes();
+
+ wxCHECK_MSG( canHave, attr, wxT("Cell attributes not allowed"));
+ wxCHECK_MSG( m_table, attr, wxT("must have a table") );
+
+ attr = m_table->GetAttr(row, col, wxGridCellAttr::Cell);
+ if ( !attr )
+ {
+ attr = new wxGridCellAttr(m_defaultCellAttr);
+
+ // artificially inc the ref count to match DecRef() in caller
+ attr->IncRef();
+ m_table->SetAttr(attr, row, col);
+ }
+
+ return attr;
+}
+
+// ----------------------------------------------------------------------------
+// setting column attributes (wrappers around SetColAttr)
+// ----------------------------------------------------------------------------
+
+void wxGrid::SetColFormatBool(int col)
+{
+ SetColFormatCustom(col, wxGRID_VALUE_BOOL);
+}
+
+void wxGrid::SetColFormatNumber(int col)
+{
+ SetColFormatCustom(col, wxGRID_VALUE_NUMBER);
+}
+
+void wxGrid::SetColFormatFloat(int col, int width, int precision)
+{
+ wxString typeName = wxGRID_VALUE_FLOAT;
+ if ( (width != -1) || (precision != -1) )
+ {
+ typeName << wxT(':') << width << wxT(',') << precision;
+ }
+
+ SetColFormatCustom(col, typeName);
+}
+
+void wxGrid::SetColFormatCustom(int col, const wxString& typeName)
+{
+ wxGridCellAttr *attr = m_table->GetAttr(-1, col, wxGridCellAttr::Col );
+ if (!attr)
+ attr = new wxGridCellAttr;
+ wxGridCellRenderer *renderer = GetDefaultRendererForType(typeName);
+ attr->SetRenderer(renderer);
+ wxGridCellEditor *editor = GetDefaultEditorForType(typeName);
+ attr->SetEditor(editor);
+
+ SetColAttr(col, attr);
+
+}
+
+// ----------------------------------------------------------------------------
+// setting cell attributes: this is forwarded to the table
+// ----------------------------------------------------------------------------
+
+void wxGrid::SetAttr(int row, int col, wxGridCellAttr *attr)
+{
+ if ( CanHaveAttributes() )
+ {
+ m_table->SetAttr(attr, row, col);
+ ClearAttrCache();
+ }
+ else
+ {
+ wxSafeDecRef(attr);
+ }
+}
+
+void wxGrid::SetRowAttr(int row, wxGridCellAttr *attr)
+{
+ if ( CanHaveAttributes() )
+ {
+ m_table->SetRowAttr(attr, row);
+ ClearAttrCache();
+ }
+ else
+ {
+ wxSafeDecRef(attr);
+ }
+}
+
+void wxGrid::SetColAttr(int col, wxGridCellAttr *attr)
+{
+ if ( CanHaveAttributes() )
+ {
+ m_table->SetColAttr(attr, col);
+ ClearAttrCache();
+ }
+ else
+ {
+ wxSafeDecRef(attr);
+ }
+}
+
+void wxGrid::SetCellBackgroundColour( int row, int col, const wxColour& colour )
+{
+ if ( CanHaveAttributes() )
+ {
+ wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
+ attr->SetBackgroundColour(colour);
+ attr->DecRef();
+ }
+}
+
+void wxGrid::SetCellTextColour( int row, int col, const wxColour& colour )
+{
+ if ( CanHaveAttributes() )
+ {
+ wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
+ attr->SetTextColour(colour);
+ attr->DecRef();
+ }
+}
+
+void wxGrid::SetCellFont( int row, int col, const wxFont& font )
+{
+ if ( CanHaveAttributes() )
+ {
+ wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
+ attr->SetFont(font);
+ attr->DecRef();
+ }
+}
+
+void wxGrid::SetCellAlignment( int row, int col, int horiz, int vert )
+{
+ if ( CanHaveAttributes() )
+ {
+ wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
+ attr->SetAlignment(horiz, vert);
+ attr->DecRef();
+ }
+}
+
+void wxGrid::SetCellOverflow( int row, int col, bool allow )
+{
+ if ( CanHaveAttributes() )
+ {
+ wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
+ attr->SetOverflow(allow);
+ attr->DecRef();
+ }
+}
+
+void wxGrid::SetCellSize( int row, int col, int num_rows, int num_cols )
+{
+ if ( CanHaveAttributes() )
+ {
+ int cell_rows, cell_cols;
+
+ wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
+ attr->GetSize(&cell_rows, &cell_cols);
+ attr->SetSize(num_rows, num_cols);
+ attr->DecRef();
+
+ // Cannot set the size of a cell to 0 or negative values
+ // While it is perfectly legal to do that, this function cannot
+ // handle all the possibilies, do it by hand by getting the CellAttr.
+ // You can only set the size of a cell to 1,1 or greater with this fn
+ wxASSERT_MSG( !((cell_rows < 1) || (cell_cols < 1)),
+ wxT("wxGrid::SetCellSize setting cell size that is already part of another cell"));
+ wxASSERT_MSG( !((num_rows < 1) || (num_cols < 1)),
+ wxT("wxGrid::SetCellSize setting cell size to < 1"));
+
+ // if this was already a multicell then "turn off" the other cells first
+ if ((cell_rows > 1) || (cell_cols > 1))