// data structures used for the data type registry
// ----------------------------------------------------------------------------
-struct wxGridDataTypeInfo {
+struct wxGridDataTypeInfo
+{
wxGridDataTypeInfo(const wxString& typeName,
wxGridCellRenderer* renderer,
wxGridCellEditor* editor)
WX_DEFINE_ARRAY(wxGridDataTypeInfo*, wxGridDataTypeInfoArray);
-class WXDLLEXPORT wxGridTypeRegistry {
+class WXDLLEXPORT wxGridTypeRegistry
+{
public:
~wxGridTypeRegistry();
+
void RegisterDataType(const wxString& typeName,
wxGridCellRenderer* renderer,
wxGridCellEditor* editor);
wxGridDataTypeInfoArray m_typeinfo;
};
-
-
-
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
{
if (m_control)
{
+ m_control->PopEventHandler(TRUE /* delete it*/);
+
m_control->Destroy();
m_control = NULL;
}
{
wxASSERT_MSG(m_control,
wxT("The wxGridCellEditor must be Created first!"));
- m_control->SetSize(rect);
+ m_control->SetSize(rect, wxSIZE_ALLOW_MINUS_ONE);
}
void wxGridCellEditor::HandleReturn(wxKeyEvent& event)
// unix
//
#if defined(__WXGTK__)
- rect.Inflate(rect.x ? 1 : 0, rect.y ? 1 : 0);
+ if (rect.x != 0)
+ {
+ rect.x += 1;
+ rect.y += 1;
+ rect.width -= 1;
+ rect.height -= 1;
+ }
#else // !GTK
- int extra = rect.x && rect.y ? 2 : 1;
+ int extra_x = ( rect.x > 2 )? 2 : 1;
+ int extra_y = ( rect.y > 2 )? 2 : 1;
#if defined(__WXMOTIF__)
- extra *= 2;
+ extra_x *= 2;
+ extra_y *= 2;
#endif
- rect.SetLeft( wxMax(0, rect.x - extra) );
- rect.SetTop( wxMax(0, rect.y - extra) );
- rect.SetRight( rect.GetRight() + 2*extra );
- rect.SetBottom( rect.GetBottom() + 2*extra );
+ rect.SetLeft( wxMax(0, rect.x - extra_x) );
+ rect.SetTop( wxMax(0, rect.y - extra_y) );
+ rect.SetRight( rect.GetRight() + 2*extra_x );
+ rect.SetBottom( rect.GetBottom() + 2*extra_y );
#endif // GTK/!GTK
wxGridCellEditor::SetSize(rect);
Text()->SetFocus();
}
-bool wxGridCellTextEditor::EndEdit(int row, int col, bool saveValue,
+bool wxGridCellTextEditor::EndEdit(int row, int col,
wxGrid* grid)
{
wxASSERT_MSG(m_control,
}
else
{
- wxFAIL_MSG( _T("this cell doesn't have numeric value") );
-
- return;
+ wxString sValue = table->GetValue(row, col);
+ if (! sValue.ToLong(&m_valueOld))
+ {
+ wxFAIL_MSG( _T("this cell doesn't have numeric value") );
+ return;
+ }
}
if ( HasRange() )
}
}
-bool wxGridCellNumberEditor::EndEdit(int row, int col, bool saveValue,
+bool wxGridCellNumberEditor::EndEdit(int row, int col,
wxGrid* grid)
{
bool changed;
if ( changed )
{
- grid->GetTable()->SetValueAsLong(row, col, value);
+ if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER))
+ grid->GetTable()->SetValueAsLong(row, col, value);
+ else
+ grid->GetTable()->SetValue(row, col, wxString::Format("%ld", value));
}
return changed;
event.Skip();
}
+
// ----------------------------------------------------------------------------
// wxGridCellFloatEditor
// ----------------------------------------------------------------------------
}
else
{
- wxFAIL_MSG( _T("this cell doesn't have float value") );
-
- return;
+ wxString sValue = table->GetValue(row, col);
+ if (! sValue.ToDouble(&m_valueOld))
+ {
+ wxFAIL_MSG( _T("this cell doesn't have float value") );
+ return;
+ }
}
DoBeginEdit(GetString());
}
-bool wxGridCellFloatEditor::EndEdit(int row, int col, bool saveValue,
+bool wxGridCellFloatEditor::EndEdit(int row, int col,
wxGrid* grid)
{
double value;
if ( Text()->GetValue().ToDouble(&value) && (value != m_valueOld) )
{
- grid->GetTable()->SetValueAsDouble(row, col, value);
+ if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT))
+ grid->GetTable()->SetValueAsDouble(row, col, value);
+ else
+ grid->GetTable()->SetValue(row, col, wxString::Format("%f", value));
return TRUE;
}
void wxGridCellBoolEditor::SetSize(const wxRect& r)
{
+ bool resize = FALSE;
+ wxSize size = m_control->GetSize();
+ wxCoord minSize = wxMin(r.width, r.height);
+
+ // check if the checkbox is not too big/small for this cell
+ wxSize sizeBest = m_control->GetBestSize();
+ if ( !(size == sizeBest) )
+ {
+ // reset to default size if it had been made smaller
+ size = sizeBest;
+
+ resize = TRUE;
+ }
+
+ if ( size.x >= minSize || size.y >= minSize )
+ {
+ // leave 1 pixel margin
+ size.x = size.y = minSize - 2;
+
+ resize = TRUE;
+ }
+
+ if ( resize )
+ {
+ m_control->SetSize(size);
+ }
+
// position it in the centre of the rectangle (TODO: support alignment?)
- wxCoord w, h;
- m_control->GetSize(&w, &h);
+#if defined(__WXGTK__) || defined (__WXMOTIF__)
// the checkbox without label still has some space to the right in wxGTK,
// so shift it to the right
-#ifdef __WXGTK__
- w -= 8;
-#endif // GTK
+ size.x -= 8;
+#elif defined(__WXMSW__)
+ // here too...
+ size.x -= 6;
+ size.y -= 2;
+#endif
- m_control->Move(r.x + r.width/2 - w/2, r.y + r.height/2 - h/2);
+ m_control->Move(r.x + r.width/2 - size.x/2, r.y + r.height/2 - size.y/2);
}
void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr)
wxASSERT_MSG(m_control,
wxT("The wxGridCellEditor must be Created first!"));
- if (grid->GetTable()->CanGetValueAs(row, col, wxT("bool")))
+ if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))
m_startValue = grid->GetTable()->GetValueAsBool(row, col);
else
m_startValue = !!grid->GetTable()->GetValue(row, col);
}
bool wxGridCellBoolEditor::EndEdit(int row, int col,
- bool saveValue,
wxGrid* grid)
{
wxASSERT_MSG(m_control,
if ( changed )
{
- if (grid->GetTable()->CanGetValueAs(row, col, wxT("bool")))
+ if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))
grid->GetTable()->SetValueAsBool(row, col, value);
else
grid->GetTable()->SetValue(row, col, value ? _T("1") : wxEmptyString);
wxGridCellEditor::Create(parent, id, evtHandler);
}
-void wxGridCellChoiceEditor::PaintBackground(const wxRect& WXUNUSED(rectCell),
- wxGridCellAttr * WXUNUSED(attr))
+void wxGridCellChoiceEditor::PaintBackground(const wxRect& rectCell,
+ wxGridCellAttr * attr)
{
// as we fill the entire client area, don't do anything here to minimize
// flicker
+
+ // TODO: It doesn't actually fill the client area since the height of a
+ // combo always defaults to the standard... Until someone has time to
+ // figure out the right rectangle to paint, just do it the normal way...
+ wxGridCellEditor::PaintBackground(rectCell, attr);
}
void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
m_startValue = grid->GetTable()->GetValue(row, col);
Combo()->SetValue(m_startValue);
+ size_t count = m_choices.GetCount();
+ for (size_t i=0; i<count; i++)
+ {
+ if (m_startValue == m_choices[i])
+ {
+ Combo()->SetSelection(i);
+ break;
+ }
+ }
Combo()->SetInsertionPointEnd();
Combo()->SetFocus();
}
-bool wxGridCellChoiceEditor::EndEdit(int row, int col,
- bool saveValue,
+bool wxGridCellChoiceEditor::EndEdit(int row, int col,
wxGrid* grid)
{
wxString value = Combo()->GetValue();
{
text.Printf(_T("%ld"), table->GetValueAsLong(row, col));
}
- //else: leave the string empty or put 0 into it?
+ else
+ {
+ text = table->GetValue(row, col);
+ }
return text;
}
text.Printf(m_format, table->GetValueAsDouble(row, col));
}
- //else: leave the string empty or put 0 into it?
+ else
+ {
+ text = table->GetValue(row, col);
+ }
return text;
}
wxSize wxGridCellBoolRenderer::ms_sizeCheckMark;
+// FIXME these checkbox size calculations are really ugly...
+
// between checkmark and box
-static const wxCoord wxGRID_CHECKMARK_MARGIN = 4;
+#ifdef __WXGTK__
+ static const wxCoord wxGRID_CHECKMARK_MARGIN = 4;
+#else
+ static const wxCoord wxGRID_CHECKMARK_MARGIN = 2;
+#endif
wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid,
wxGridCellAttr& WXUNUSED(attr),
checkSize = size.y + wxGRID_CHECKMARK_MARGIN;
// FIXME wxGTK::wxCheckBox::GetBestSize() gives "wrong" result
-#ifdef __WXGTK__
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
checkSize -= size.y / 2;
#endif
// draw a check mark in the centre (ignoring alignment - TODO)
wxSize size = GetBestSize(grid, attr, dc, row, col);
+
+ // don't draw outside the cell
+ wxCoord minSize = wxMin(rect.width, rect.height);
+ if ( size.x >= minSize || size.y >= minSize )
+ {
+ // and even leave (at least) 1 pixel margin
+ size.x = size.y = minSize - 2;
+ }
+
+ // draw a border around checkmark
wxRect rectMark;
rectMark.x = rect.x + rect.width/2 - size.x/2;
rectMark.y = rect.y + rect.height/2 - size.y/2;
rectMark.Inflate(-wxGRID_CHECKMARK_MARGIN);
+#ifdef __WXMSW__
+ // looks nicer under MSW
+ rectMark.x++;
+#endif // MSW
+
bool value;
- if (grid.GetTable()->CanGetValueAs(row, col, wxT("bool")))
+ if ( grid.GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) )
value = grid.GetTable()->GetValueAsBool(row, col);
else
value = !!grid.GetTable()->GetValue(row, col);
// GetRenderer and GetEditor use a slightly different decision path about
-// which to use. If a non-default attr object has one then it is used,
-// otherwise the default editor or renderer passed in is used. It should be
-// the default for the data type of the cell. If it is NULL (because the
-// table has a type that the grid does not have in its registry,) then the
-// grid's default editor or renderer is used.
-
-wxGridCellRenderer* wxGridCellAttr::GetRenderer(wxGridCellRenderer* def) const
-{
- if ((m_defGridAttr != this || def == NULL) && HasRenderer())
- return m_renderer;
- else if (def)
- return def;
- else if (m_defGridAttr != this)
- return m_defGridAttr->GetRenderer(NULL);
- else
- {
+// which attribute to use. If a non-default attr object has one then it is
+// used, otherwise the default editor or renderer is fetched from the grid and
+// used. It should be the default for the data type of the cell. If it is
+// NULL (because the table has a type that the grid does not have in its
+// registry,) then the grid's default editor or renderer is used.
+
+wxGridCellRenderer* wxGridCellAttr::GetRenderer(wxGrid* grid, int row, int col) const
+{
+ if ((m_defGridAttr != this || grid == NULL) && HasRenderer())
+ return m_renderer; // use local attribute
+
+ wxGridCellRenderer* renderer = NULL;
+ if (grid) // get renderer for the data type
+ renderer = grid->GetDefaultRendererForCell(row, col);
+
+ if (! renderer)
+ // if we still don't have one then use the grid default
+ renderer = m_defGridAttr->GetRenderer(NULL,0,0);
+
+ if (! renderer)
wxFAIL_MSG(wxT("Missing default cell attribute"));
- return NULL;
- }
+
+ return renderer;
}
-wxGridCellEditor* wxGridCellAttr::GetEditor(wxGridCellEditor* def) const
+wxGridCellEditor* wxGridCellAttr::GetEditor(wxGrid* grid, int row, int col) const
{
- if ((m_defGridAttr != this || def == NULL) && HasEditor())
- return m_editor;
- else if (def)
- return def;
- else if (m_defGridAttr != this)
- return m_defGridAttr->GetEditor(NULL);
- else
- {
+ if ((m_defGridAttr != this || grid == NULL) && HasEditor())
+ return m_editor; // use local attribute
+
+ wxGridCellEditor* editor = NULL;
+ if (grid) // get renderer for the data type
+ editor = grid->GetDefaultEditorForCell(row, col);
+
+ if (! editor)
+ // if we still don't have one then use the grid default
+ editor = m_defGridAttr->GetEditor(NULL,0,0);
+
+ if (! editor)
wxFAIL_MSG(wxT("Missing default cell attribute"));
- return NULL;
- }
+
+ return editor;
}
// ----------------------------------------------------------------------------
wxGridTypeRegistry::~wxGridTypeRegistry()
{
- for (size_t i=0; i<m_typeinfo.Count(); i++)
+ size_t count = m_typeinfo.Count();
+ for ( size_t i = 0; i < count; i++ )
delete m_typeinfo[i];
}
#if WXGRID_DRAW_LINES
m_owner->DrawAllGridLines( dc, reg );
#endif
+ m_owner->DrawGridSpace( dc );
m_owner->DrawHighlight( dc );
}
if ( !m_owner->ProcessEvent( event ) ) event.Skip();
}
-// We are trapping erase background events to reduce flicker under MSW
-// and GTK but this can leave junk in the space beyond the last row and
-// col. So here we paint these spaces if they are visible.
-//
+
void wxGridWindow::OnEraseBackground(wxEraseEvent& event)
{
- int cw, ch;
- GetClientSize( &cw, &ch );
-
- int right, bottom;
- m_owner->CalcUnscrolledPosition( cw, ch, &right, &bottom );
-
- wxRect rightRect;
- rightRect = m_owner->CellToRect( 0, m_owner->GetNumberCols()-1 );
-
- wxRect bottomRect;
- bottomRect = m_owner->CellToRect( m_owner->GetNumberRows()-1, 0 );
-
- if ( right > rightRect.GetRight() || bottom > bottomRect.GetBottom() )
- {
- int left, top;
- m_owner->CalcUnscrolledPosition( 0, 0, &left, &top );
-
- wxClientDC dc( this );
- m_owner->PrepareDC( dc );
- dc.SetBrush( wxBrush(m_owner->GetDefaultCellBackgroundColour(), wxSOLID) );
- dc.SetPen( *wxTRANSPARENT_PEN );
-
- if ( right > rightRect.GetRight() )
- dc.DrawRectangle( rightRect.GetRight()+1, top, right - rightRect.GetRight(), ch );
-
- if ( bottom > bottomRect.GetBottom() )
- dc.DrawRectangle( left, bottomRect.GetBottom()+1, cw, bottom - bottomRect.GetBottom() );
- }
}
m_winCapture = (wxWindow *)NULL;
m_canDragRowSize = TRUE;
m_canDragColSize = TRUE;
+ m_canDragGridSize = TRUE;
m_dragLastPos = -1;
m_dragRowOrCol = -1;
m_isDragging = FALSE;
m_inOnKeyDown = FALSE;
m_batchCount = 0;
+
+ m_extraWidth =
+ m_extraHeight = 50;
+
+ CalcDimensions();
}
// ----------------------------------------------------------------------------
if ( m_numRows > 0 && m_numCols > 0 )
{
- int right = GetColRight( m_numCols-1 ) + 50;
- int bottom = GetRowBottom( m_numRows-1 ) + 50;
+ int right = GetColRight( m_numCols-1 ) + m_extraWidth;
+ int bottom = GetRowBottom( m_numRows-1 ) + m_extraHeight;
// TODO: restore the scroll position that we had before sizing
//
// Hide the edit control, so it
// won't interfer with drag-shrinking.
if ( IsCellEditControlEnabled() )
+ {
HideCellEditControl();
+ SaveEditControlValue();
+ }
// Have we captured the mouse yet?
if (! m_winCapture)
m_isDragging = FALSE;
m_startDragPos = wxDefaultPosition;
+ // VZ: if we do this, the mode is reset to WXGRID_CURSOR_SELECT_CELL
+ // immediately after it becomes WXGRID_CURSOR_RESIZE_ROW/COL under
+ // wxGTK
+#if 0
+ if ( event.Entering() || event.Leaving() )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
+ }
+ else
+#endif // 0
- if ( coords != wxGridNoCellCoords )
+ // ------------ Left button pressed
+ //
+ if ( event.LeftDown() && coords != wxGridNoCellCoords )
{
- // VZ: if we do this, the mode is reset to WXGRID_CURSOR_SELECT_CELL
- // immediately after it becomes WXGRID_CURSOR_RESIZE_ROW/COL under
- // wxGTK
-#if 0
- if ( event.Entering() || event.Leaving() )
+ if ( event.ShiftDown() )
{
- ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
- m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
+ SelectBlock( m_currentCellCoords, coords );
}
- else
-#endif // 0
-
- // ------------ Left button pressed
- //
- if ( event.LeftDown() )
+ else if ( XToEdgeOfCol(x) < 0 &&
+ YToEdgeOfRow(y) < 0 )
{
- DisableCellEditControl();
- if ( event.ShiftDown() )
- {
- SelectBlock( m_currentCellCoords, coords );
- }
- else if ( XToEdgeOfCol(x) < 0 &&
- YToEdgeOfRow(y) < 0 )
+ if ( !SendEvent( wxEVT_GRID_CELL_LEFT_CLICK,
+ coords.GetRow(),
+ coords.GetCol(),
+ event ) )
{
- if ( !SendEvent( wxEVT_GRID_CELL_LEFT_CLICK,
- coords.GetRow(),
- coords.GetCol(),
- event ) )
+ DisableCellEditControl();
+ MakeCellVisible( coords );
+
+ // if this is the second click on this cell then start
+ // the edit control
+ if ( m_waitForSlowClick &&
+ (coords == m_currentCellCoords) &&
+ CanEnableCellControl())
{
- MakeCellVisible( coords );
-
- // if this is the second click on this cell then start
- // the edit control
- if ( m_waitForSlowClick &&
- (coords == m_currentCellCoords) &&
- CanEnableCellControl())
- {
- EnableCellEditControl();
+ EnableCellEditControl();
- wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords);
- attr->GetEditor(GetDefaultEditorForCell(coords.GetRow(), coords.GetCol()))->StartingClick();
- attr->DecRef();
+ wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords);
+ attr->GetEditor(this, coords.GetRow(), coords.GetCol())->StartingClick();
+ attr->DecRef();
- m_waitForSlowClick = FALSE;
- }
- else
- {
- SetCurrentCell( coords );
- m_waitForSlowClick = TRUE;
- }
+ m_waitForSlowClick = FALSE;
+ }
+ else
+ {
+ SetCurrentCell( coords );
+ m_waitForSlowClick = TRUE;
}
}
}
+ }
- // ------------ Left double click
- //
- else if ( event.LeftDClick() )
+ // ------------ Left double click
+ //
+ else if ( event.LeftDClick() && coords != wxGridNoCellCoords )
+ {
+ DisableCellEditControl();
+
+ if ( XToEdgeOfCol(x) < 0 && YToEdgeOfRow(y) < 0 )
{
- DisableCellEditControl();
- if ( XToEdgeOfCol(x) < 0 && YToEdgeOfRow(y) < 0 )
- {
- SendEvent( wxEVT_GRID_CELL_LEFT_DCLICK,
- coords.GetRow(),
- coords.GetCol(),
- event );
- }
+ SendEvent( wxEVT_GRID_CELL_LEFT_DCLICK,
+ coords.GetRow(),
+ coords.GetCol(),
+ event );
}
+ }
- // ------------ Left button released
- //
- else if ( event.LeftUp() )
+ // ------------ Left button released
+ //
+ else if ( event.LeftUp() )
+ {
+ if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
- if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
+ if ( IsSelection() )
{
- if ( IsSelection() )
+ if (m_winCapture)
{
- if (m_winCapture)
- {
- m_winCapture->ReleaseMouse();
- m_winCapture = NULL;
- }
- SendEvent( wxEVT_GRID_RANGE_SELECT, -1, -1, event );
+ m_winCapture->ReleaseMouse();
+ m_winCapture = NULL;
}
-
- // Show the edit control, if it has been hidden for
- // drag-shrinking.
- ShowCellEditControl();
+ SendEvent( wxEVT_GRID_RANGE_SELECT, -1, -1, event );
}
- else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
- {
- ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
- DoEndDragResizeRow();
- // Note: we are ending the event *after* doing
- // default processing in this case
- //
- SendEvent( wxEVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event );
- }
- else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
- {
- ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
- DoEndDragResizeCol();
+ // Show the edit control, if it has been hidden for
+ // drag-shrinking.
+ ShowCellEditControl();
+ }
+ else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ DoEndDragResizeRow();
- // Note: we are ending the event *after* doing
- // default processing in this case
- //
- SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event );
- }
+ // Note: we are ending the event *after* doing
+ // default processing in this case
+ //
+ SendEvent( wxEVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event );
+ }
+ else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ DoEndDragResizeCol();
- m_dragLastPos = -1;
+ // Note: we are ending the event *after* doing
+ // default processing in this case
+ //
+ SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event );
}
+ m_dragLastPos = -1;
+ }
+
- // ------------ Right button down
- //
- else if ( event.RightDown() )
+ // ------------ Right button down
+ //
+ else if ( event.RightDown() && coords != wxGridNoCellCoords )
+ {
+ DisableCellEditControl();
+ if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_CLICK,
+ coords.GetRow(),
+ coords.GetCol(),
+ event ) )
{
- DisableCellEditControl();
- if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_CLICK,
- coords.GetRow(),
- coords.GetCol(),
- event ) )
- {
- // no default action at the moment
- }
+ // no default action at the moment
}
+ }
- // ------------ Right double click
- //
- else if ( event.RightDClick() )
+ // ------------ Right double click
+ //
+ else if ( event.RightDClick() && coords != wxGridNoCellCoords )
+ {
+ DisableCellEditControl();
+ if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_DCLICK,
+ coords.GetRow(),
+ coords.GetCol(),
+ event ) )
{
- DisableCellEditControl();
- if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_DCLICK,
- coords.GetRow(),
- coords.GetCol(),
- event ) )
- {
- // no default action at the moment
- }
+ // no default action at the moment
}
+ }
+
+ // ------------ Moving and no button action
+ //
+ else if ( event.Moving() && !event.IsButton() )
+ {
+ int dragRow = YToEdgeOfRow( y );
+ int dragCol = XToEdgeOfCol( x );
- // ------------ Moving and no button action
+ // Dragging on the corner of a cell to resize in both
+ // directions is not implemented yet...
//
- else if ( event.Moving() && !event.IsButton() )
+ if ( dragRow >= 0 && dragCol >= 0 )
{
- int dragRow = YToEdgeOfRow( y );
- int dragCol = XToEdgeOfCol( x );
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ return;
+ }
- // Dragging on the corner of a cell to resize in both
- // directions is not implemented yet...
- //
- if ( dragRow >= 0 && dragCol >= 0 )
- {
- ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
- return;
- }
+ if ( dragRow >= 0 )
+ {
+ m_dragRowOrCol = dragRow;
- if ( dragRow >= 0 )
+ if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
- m_dragRowOrCol = dragRow;
-
- if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
- {
- if ( CanDragRowSize() )
- ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW);
- }
-
- return;
+ if ( CanDragRowSize() && CanDragGridSize() )
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW);
}
if ( dragCol >= 0 )
{
m_dragRowOrCol = dragCol;
+ }
- if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
- {
- if ( CanDragColSize() )
- ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL);
- }
+ return;
+ }
- return;
- }
+ if ( dragCol >= 0 )
+ {
+ m_dragRowOrCol = dragCol;
- // Neither on a row or col edge
- //
- if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
+ if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
- ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ if ( CanDragColSize() && CanDragGridSize() )
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL);
}
+
+ return;
+ }
+
+ // Neither on a row or col edge
+ //
+ if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
}
}
}
dc.SetLogicalFunction( wxINVERT );
dc.DrawLine( left, m_dragLastPos, left+cw, m_dragLastPos );
HideCellEditControl();
+ SaveEditControlValue();
int rowTop = GetRowTop(m_dragRowOrCol);
SetRowSize( m_dragRowOrCol,
dc.SetLogicalFunction( wxINVERT );
dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top+ch );
HideCellEditControl();
+ SaveEditControlValue();
int colLeft = GetColLeft(m_dragRowOrCol);
SetColSize( m_dragRowOrCol,
{
if ( m_table )
{
+ if (IsCellEditControlEnabled())
+ DisableCellEditControl();
+
m_table->Clear();
- SetEditControlValue();
if ( !GetBatchCount() ) m_gridWin->Refresh();
}
}
if ( !GetBatchCount() ) Refresh();
}
- SetEditControlValue();
return ok;
}
else
if ( !GetBatchCount() ) Refresh();
}
- SetEditControlValue();
return ok;
}
else
m_numRows && m_numCols )
{
m_currentCellCoords.Set(0, 0);
- SetEditControlValue();
ShowCellEditControl();
}
MovePageDown();
break;
- // We don't want these keys to trigger the edit control, any others?
- case WXK_SHIFT:
- case WXK_ALT:
- case WXK_CONTROL:
- case WXK_CAPITAL:
- event.Skip();
- break;
-
case WXK_SPACE:
if ( !IsEditable() )
{
// Otherwise fall through to default
default:
- // now try the cell edit control
- //
- if ( !IsCellEditControlEnabled() && CanEnableCellControl() )
+ // alphanumeric keys or F2 (special key just for this) enable
+ // the cell edit control
+ if ( !(event.AltDown() ||
+ event.MetaDown() ||
+ event.ControlDown()) &&
+ (isalnum(event.KeyCode()) || event.KeyCode() == WXK_F2) &&
+ !IsCellEditControlEnabled() &&
+ CanEnableCellControl() )
{
EnableCellEditControl();
int row = m_currentCellCoords.GetRow();
int col = m_currentCellCoords.GetCol();
wxGridCellAttr* attr = GetCellAttr(row, col);
- attr->GetEditor(GetDefaultEditorForCell(row, col))->StartingKey(event);
+ attr->GetEditor(this, row, col)->StartingKey(event);
attr->DecRef();
}
else
{
- // let others process char events for readonly cells
+ // let others process char events with modifiers or all
+ // char events for readonly cells
event.Skip();
}
break;
m_currentCellCoords != wxGridNoCellCoords )
{
HideCellEditControl();
- SaveEditControlValue();
DisableCellEditControl();
// Clear the old current cell highlight
m_currentCellCoords = coords;
- SetEditControlValue();
-
if ( m_displayed )
{
wxClientDC dc(m_gridWin);
}
+void wxGrid::DrawGridSpace( wxDC& dc )
+{
+ if ( m_numRows && m_numCols )
+ {
+ int cw, ch;
+ m_gridWin->GetClientSize( &cw, &ch );
+
+ int right, bottom;
+ CalcUnscrolledPosition( cw, ch, &right, &bottom );
+
+ if ( right > GetColRight(m_numCols-1) ||
+ bottom > GetRowBottom(m_numRows-1) )
+ {
+ int left, top;
+ CalcUnscrolledPosition( 0, 0, &left, &top );
+
+ dc.SetBrush( wxBrush(GetDefaultCellBackgroundColour(), wxSOLID) );
+ dc.SetPen( *wxTRANSPARENT_PEN );
+
+ if ( right > GetColRight(m_numCols-1) )
+ dc.DrawRectangle( GetColRight(m_numCols-1), top,
+ right - GetColRight(m_numCols-1), ch );
+
+ if ( bottom > GetRowBottom(m_numRows-1) )
+ dc.DrawRectangle( left, GetRowBottom(m_numRows-1),
+ cw, bottom - GetRowBottom(m_numRows-1) );
+ }
+ }
+}
+
+
void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
{
int row = coords.GetRow();
// if the editor is shown, we should use it and not the renderer
if ( isCurrent && IsCellEditControlEnabled() )
{
- attr->GetEditor(GetDefaultEditorForCell(row, col))->
- PaintBackground(rect, attr);
+ attr->GetEditor(this, row, col)->PaintBackground(rect, attr);
}
else
{
// but all the rest is drawn by the cell renderer and hence may be
// customized
- attr->GetRenderer(GetDefaultRendererForCell(row,col))->
+ attr->GetRenderer(this, row, col)->
Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords));
}
int top, bottom, left, right;
+#ifndef __WXGTK__
if (reg.IsEmpty())
{
int cw, ch;
CalcUnscrolledPosition( x, y, &left, &top );
CalcUnscrolledPosition( x + w, y + h, &right, &bottom );
}
+#else
+ int cw, ch;
+ m_gridWin->GetClientSize(&cw, &ch);
+ CalcUnscrolledPosition( 0, 0, &left, &top );
+ CalcUnscrolledPosition( cw, ch, &right, &bottom );
+#endif
// avoid drawing grid lines past the last row and col
//
// do it before ShowCellEditControl()
m_cellEditCtrlEnabled = enable;
- SetEditControlValue();
ShowCellEditControl();
}
else
rect.y--;
wxGridCellAttr* attr = GetCellAttr(row, col);
- wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col));
+ wxGridCellEditor* editor = attr->GetEditor(this, row, col);
if ( !editor->IsCreated() )
{
editor->Create(m_gridWin, -1,
new wxGridCellEditorEvtHandler(this, editor));
}
+ editor->Show( TRUE, attr );
+
editor->SetSize( rect );
- editor->Show( TRUE, attr );
editor->BeginEdit(row, col, this);
attr->DecRef();
}
int col = m_currentCellCoords.GetCol();
wxGridCellAttr* attr = GetCellAttr(row, col);
- attr->GetEditor(GetDefaultEditorForCell(row, col))->Show( FALSE );
+ attr->GetEditor(this, row, col)->Show( FALSE );
attr->DecRef();
m_gridWin->SetFocus();
}
}
-void wxGrid::SetEditControlValue( const wxString& value )
-{
- // RD: The new Editors get the value from the table themselves now. This
- // method can probably be removed...
-}
-
-
void wxGrid::SaveEditControlValue()
{
if ( IsCellEditControlEnabled() )
int col = m_currentCellCoords.GetCol();
wxGridCellAttr* attr = GetCellAttr(row, col);
- wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col));
- bool changed = editor->EndEdit(row, col, TRUE, this);
+ wxGridCellEditor* editor = attr->GetEditor(this, row, col);
+ bool changed = editor->EndEdit(row, col, this);
attr->DecRef();
wxGridCellRenderer *wxGrid::GetDefaultRenderer() const
{
- return m_defaultCellAttr->GetRenderer(NULL);
+ return m_defaultCellAttr->GetRenderer(NULL,0,0);
}
wxGridCellEditor *wxGrid::GetDefaultEditor() const
{
- return m_defaultCellAttr->GetEditor(NULL);
+ return m_defaultCellAttr->GetEditor(NULL,0,0);
}
// ----------------------------------------------------------------------------
wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col)
{
wxGridCellAttr* attr = GetCellAttr(row, col);
- wxGridCellRenderer* renderer = attr->GetRenderer(GetDefaultRendererForCell(row,col));
+ wxGridCellRenderer* renderer = attr->GetRenderer(this, row, col);
attr->DecRef();
return renderer;
}
wxGridCellEditor* wxGrid::GetCellEditor(int row, int col)
{
wxGridCellAttr* attr = GetCellAttr(row, col);
- wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col));
+ wxGridCellEditor* editor = attr->GetEditor(this, row, col);
attr->DecRef();
return editor;
}
m_canDragColSize = enable;
}
+void wxGrid::EnableDragGridSize( bool enable )
+{
+ m_canDragGridSize = enable;
+}
+
void wxGrid::SetDefaultRowSize( int height, bool resizeExistingRows )
{
return obj ? (int)obj : WXGRID_MIN_COL_WIDTH;
}
+// ----------------------------------------------------------------------------
+// auto sizing
+// ----------------------------------------------------------------------------
+
void wxGrid::AutoSizeColumn( int col, bool setAsMin )
{
wxClientDC dc(m_gridWin);
for ( int row = 0; row < m_numRows; row++ )
{
wxGridCellAttr* attr = GetCellAttr(row, col);
- wxGridCellRenderer* renderer = attr->GetRenderer(GetDefaultRendererForCell(row,col));
+ wxGridCellRenderer* renderer = attr->GetRenderer(this, row, col);
if ( renderer )
{
width = renderer->GetBestSize(*this, *attr, dc, row, col).x;
}
}
-void wxGrid::AutoSizeColumns( bool setAsMin )
+int wxGrid::SetOrCalcColumnSizes(bool calcOnly, bool setAsMin)
{
+ int width = m_rowLabelWidth;
+
for ( int col = 0; col < m_numCols; col++ )
{
- AutoSizeColumn(col, setAsMin);
+ if ( !calcOnly )
+ {
+ AutoSizeColumn(col, setAsMin);
+ }
+
+ width += GetColWidth(col);
}
+
+ return width;
}
-//
-// ------ cell value accessor functions
-//
+int wxGrid::SetOrCalcRowSizes(bool calcOnly, bool setAsMin)
+{
+ int height = m_colLabelHeight;
+
+ for ( int row = 0; row < m_numRows; row++ )
+ {
+ // if ( !calcOnly ) AutoSizeRow(row, setAsMin) -- TODO
+
+ height += GetRowHeight(row);
+ }
+
+ return height;
+}
+
+void wxGrid::AutoSize()
+{
+ // set the size too
+ SetSize(SetOrCalcColumnSizes(FALSE), SetOrCalcRowSizes(FALSE));
+}
+
+wxSize wxGrid::DoGetBestSize() const
+{
+ // don't set sizes, only calculate them
+ wxGrid *self = (wxGrid *)this; // const_cast
+
+ return wxSize(self->SetOrCalcColumnSizes(TRUE),
+ self->SetOrCalcRowSizes(TRUE));
+}
+
+void wxGrid::Fit()
+{
+ AutoSize();
+}
+
+// ----------------------------------------------------------------------------
+// cell value accessor functions
+// ----------------------------------------------------------------------------
void wxGrid::SetCellValue( int row, int col, const wxString& s )
{
DrawCell( dc, wxGridCellCoords(row, col) );
}
-#if 0 // TODO: edit in place
-
if ( m_currentCellCoords.GetRow() == row &&
- m_currentCellCoords.GetCol() == col )
+ m_currentCellCoords.GetCol() == col &&
+ IsCellEditControlEnabled())
{
- SetEditControlValue( s );
+ HideCellEditControl();
+ ShowCellEditControl(); // will reread data from table
}
-#endif
-
}
}