+}
+
+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))
+ {
+ int i, j;
+ for (j=row; j < row + cell_rows; j++)
+ {
+ for (i=col; i < col + cell_cols; i++)
+ {
+ if ((i != col) || (j != row))
+ {
+ wxGridCellAttr *attr_stub = GetOrCreateCellAttr(j, i);
+ attr_stub->SetSize( 1, 1 );
+ attr_stub->DecRef();
+ }
+ }
+ }
+ }
+
+ // mark the cells that will be covered by this cell to
+ // negative or zero values to point back at this cell
+ if (((num_rows > 1) || (num_cols > 1)) && (num_rows >= 1) && (num_cols >= 1))
+ {
+ int i, j;
+ for (j=row; j < row + num_rows; j++)
+ {
+ for (i=col; i < col + num_cols; i++)
+ {
+ if ((i != col) || (j != row))
+ {
+ wxGridCellAttr *attr_stub = GetOrCreateCellAttr(j, i);
+ attr_stub->SetSize( row - j, col - i );
+ attr_stub->DecRef();
+ }
+ }
+ }
+ }
+ }
+}
+
+void wxGrid::SetCellRenderer(int row, int col, wxGridCellRenderer *renderer)
+{
+ if ( CanHaveAttributes() )
+ {
+ wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
+ attr->SetRenderer(renderer);
+ attr->DecRef();
+ }
+}
+
+void wxGrid::SetCellEditor(int row, int col, wxGridCellEditor* editor)
+{
+ if ( CanHaveAttributes() )
+ {
+ wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
+ attr->SetEditor(editor);
+ attr->DecRef();
+ }
+}
+
+void wxGrid::SetReadOnly(int row, int col, bool isReadOnly)
+{
+ if ( CanHaveAttributes() )
+ {
+ wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
+ attr->SetReadOnly(isReadOnly);
+ attr->DecRef();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Data type registration
+// ----------------------------------------------------------------------------
+
+void wxGrid::RegisterDataType(const wxString& typeName,
+ wxGridCellRenderer* renderer,
+ wxGridCellEditor* editor)
+{
+ m_typeRegistry->RegisterDataType(typeName, renderer, editor);
+}
+
+
+wxGridCellEditor * wxGrid::GetDefaultEditorForCell(int row, int col) const
+{
+ wxString typeName = m_table->GetTypeName(row, col);
+ return GetDefaultEditorForType(typeName);
+}
+
+wxGridCellRenderer * wxGrid::GetDefaultRendererForCell(int row, int col) const
+{
+ wxString typeName = m_table->GetTypeName(row, col);
+ return GetDefaultRendererForType(typeName);
+}
+
+wxGridCellEditor * wxGrid::GetDefaultEditorForType(const wxString& typeName) const
+{
+ int index = m_typeRegistry->FindOrCloneDataType(typeName);
+ if ( index == wxNOT_FOUND )
+ {
+ wxFAIL_MSG(wxString::Format(wxT("Unknown data type name [%s]"), typeName.c_str()));
+
+ return NULL;
+ }
+
+ return m_typeRegistry->GetEditor(index);
+}
+
+wxGridCellRenderer * wxGrid::GetDefaultRendererForType(const wxString& typeName) const
+{
+ int index = m_typeRegistry->FindOrCloneDataType(typeName);
+ if ( index == wxNOT_FOUND )
+ {
+ wxFAIL_MSG(wxString::Format(wxT("Unknown data type name [%s]"), typeName.c_str()));
+
+ return NULL;
+ }
+
+ return m_typeRegistry->GetRenderer(index);
+}
+
+// ----------------------------------------------------------------------------
+// row/col size
+// ----------------------------------------------------------------------------
+
+void wxGrid::DoDisableLineResize(int line, wxGridFixedIndicesSet *& setFixed)
+{
+ if ( !setFixed )
+ {
+ setFixed = new wxGridFixedIndicesSet;
+ }
+
+ setFixed->insert(line);
+}
+
+bool
+wxGrid::DoCanResizeLine(int line, const wxGridFixedIndicesSet *setFixed) const
+{
+ return !setFixed || !setFixed->count(line);
+}
+
+void wxGrid::EnableDragRowSize( bool enable )
+{
+ m_canDragRowSize = enable;
+}
+
+void wxGrid::EnableDragColSize( bool enable )
+{
+ m_canDragColSize = enable;
+}
+
+void wxGrid::EnableDragGridSize( bool enable )
+{
+ m_canDragGridSize = enable;
+}
+
+void wxGrid::EnableDragCell( bool enable )
+{
+ m_canDragCell = enable;
+}
+
+void wxGrid::SetDefaultRowSize( int height, bool resizeExistingRows )
+{
+ m_defaultRowHeight = wxMax( height, m_minAcceptableRowHeight );
+
+ if ( resizeExistingRows )
+ {
+ // since we are resizing all rows to the default row size,
+ // we can simply clear the row heights and row bottoms
+ // arrays (which also allows us to take advantage of
+ // some speed optimisations)
+ m_rowHeights.Empty();
+ m_rowBottoms.Empty();
+ if ( !GetBatchCount() )
+ CalcDimensions();
+ }
+}
+
+void wxGrid::SetRowSize( int row, int height )
+{
+ wxCHECK_RET( row >= 0 && row < m_numRows, wxT("invalid row index") );
+
+ // if < 0 then calculate new height from label
+ if ( height < 0 )
+ {
+ long w, h;
+ wxArrayString lines;
+ wxClientDC dc(m_rowLabelWin);
+ dc.SetFont(GetLabelFont());
+ StringToLines(GetRowLabelValue( row ), lines);
+ GetTextBoxSize( dc, lines, &w, &h );
+ //check that it is not less than the minimal height
+ height = wxMax(h, GetRowMinimalAcceptableHeight());
+ }
+
+ // See comment in SetColSize
+ if ( height < GetRowMinimalAcceptableHeight())
+ return;
+
+ if ( m_rowHeights.IsEmpty() )
+ {
+ // need to really create the array
+ InitRowHeights();
+ }
+
+ int h = wxMax( 0, height );
+ int diff = h - m_rowHeights[row];
+
+ m_rowHeights[row] = h;
+ for ( int i = row; i < m_numRows; i++ )
+ {
+ m_rowBottoms[i] += diff;
+ }
+
+ if ( !GetBatchCount() )
+ CalcDimensions();
+}
+
+void wxGrid::SetDefaultColSize( int width, bool resizeExistingCols )
+{
+ // we dont allow zero default column width
+ m_defaultColWidth = wxMax( wxMax( width, m_minAcceptableColWidth ), 1 );
+
+ if ( resizeExistingCols )
+ {
+ // since we are resizing all columns to the default column size,
+ // we can simply clear the col widths and col rights
+ // arrays (which also allows us to take advantage of
+ // some speed optimisations)
+ m_colWidths.Empty();
+ m_colRights.Empty();
+ if ( !GetBatchCount() )
+ CalcDimensions();
+ }
+}
+
+void wxGrid::SetColSize( int col, int width )
+{
+ wxCHECK_RET( col >= 0 && col < m_numCols, wxT("invalid column index") );
+
+ // if < 0 then calculate new width from label
+ if ( width < 0 )
+ {
+ long w, h;
+ wxArrayString lines;
+ wxClientDC dc(m_colWindow);
+ dc.SetFont(GetLabelFont());
+ StringToLines(GetColLabelValue(col), lines);
+ if ( GetColLabelTextOrientation() == wxHORIZONTAL )
+ GetTextBoxSize( dc, lines, &w, &h );
+ else
+ GetTextBoxSize( dc, lines, &h, &w );
+ width = w + 6;
+ //check that it is not less than the minimal width
+ width = wxMax(width, GetColMinimalAcceptableWidth());
+ }
+
+ // we intentionally don't test whether the width is less than
+ // GetColMinimalWidth() here but we do compare it with
+ // GetColMinimalAcceptableWidth() as otherwise things currently break (see
+ // #651) -- and we also always allow the width of 0 as it has the special
+ // sense of hiding the column
+ if ( width > 0 && width < GetColMinimalAcceptableWidth() )
+ return;
+
+ if ( m_colWidths.IsEmpty() )
+ {
+ // need to really create the array
+ InitColWidths();
+ }