class wxGridCellEditorEvtHandler : public wxEvtHandler
{
public:
- wxGridCellEditorEvtHandler()
- : m_grid(0), m_editor(0)
- { }
wxGridCellEditorEvtHandler(wxGrid* grid, wxGridCellEditor* editor)
- : m_grid(grid), m_editor(editor)
- { }
+ : m_grid(grid),
+ m_editor(editor),
+ m_inSetFocus(false)
+ {
+ }
+ void OnKillFocus(wxFocusEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnChar(wxKeyEvent& event);
+ void SetInSetFocus(bool inSetFocus) { m_inSetFocus = inSetFocus; }
+
private:
wxGrid* m_grid;
wxGridCellEditor* m_editor;
- DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler)
+
+ // Work around the fact that a focus kill event can be sent to
+ // a combobox within a set focus event.
+ bool m_inSetFocus;
+
DECLARE_EVENT_TABLE()
+ DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler)
DECLARE_NO_COPY_CLASS(wxGridCellEditorEvtHandler)
};
-IMPLEMENT_DYNAMIC_CLASS( wxGridCellEditorEvtHandler, wxEvtHandler )
+IMPLEMENT_ABSTRACT_CLASS(wxGridCellEditorEvtHandler, wxEvtHandler)
+
BEGIN_EVENT_TABLE( wxGridCellEditorEvtHandler, wxEvtHandler )
+ EVT_KILL_FOCUS( wxGridCellEditorEvtHandler::OnKillFocus )
EVT_KEY_DOWN( wxGridCellEditorEvtHandler::OnKeyDown )
EVT_CHAR( wxGridCellEditorEvtHandler::OnChar )
END_EVENT_TABLE()
// through in that case.
if ((ctrl || alt) && !(ctrl && alt))
return false;
-
+
#if wxUSE_UNICODE
int key = event.GetUnicodeKey();
bool keyOk = true;
keyOk = (key <= 127);
}
return keyOk;
-#else
+#else // !wxUSE_UNICODE
int key = event.GetKeyCode();
- if (key <= 255)
+ if (key <= 255)
return true;
-#endif
return false;
+#endif // wxUSE_UNICODE/!wxUSE_UNICODE
}
void wxGridCellEditor::StartingKey(wxKeyEvent& event)
wxTextCtrl* tc = Text();
wxChar ch;
long pos;
-
+
#if wxUSE_UNICODE
ch = event.GetUnicodeKey();
if (ch <= 127)
- ch = event.GetKeyCode();
+ ch = (wxChar)event.GetKeyCode();
#else
- ch = event.GetKeyCode();
+ ch = (wxChar)event.GetKeyCode();
#endif
switch (ch)
{
void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event)
{
+ int keycode = event.GetKeyCode();
if ( !HasRange() )
{
- int keycode = event.GetKeyCode();
if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-')
{
wxGridCellTextEditor::StartingKey(event);
return;
}
}
-
+#if wxUSE_SPINCTRL
+ else
+ {
+ if ( wxIsdigit(keycode) )
+ {
+ wxSpinCtrl* spin = (wxSpinCtrl*)m_control;
+ spin->SetValue(keycode - '0');
+ spin->SetSelection(1,1);
+ return;
+ }
+ }
+#endif
event.Skip();
}
tmpbuf[0] = (char) keycode;
tmpbuf[1] = '\0';
wxString strbuf(tmpbuf, *wxConvCurrent);
+#if wxUSE_INTL
bool is_decimal_point = ( strbuf ==
wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) );
+#else
+ bool is_decimal_point = ( strbuf == _T(".") );
+#endif
if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-'
|| is_decimal_point )
{
tmpbuf[0] = (char) keycode;
tmpbuf[1] = '\0';
wxString strbuf(tmpbuf, *wxConvCurrent);
+#if wxUSE_INTL
bool is_decimal_point =
( strbuf == wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,
wxLOCALE_CAT_NUMBER) );
- if ( (keycode < 128) &&
+#else
+ bool is_decimal_point = ( strbuf == _T(".") );
+#endif
+ if ( (keycode < 128) &&
(wxIsdigit(keycode) || tolower(keycode) == 'e' ||
is_decimal_point || keycode == '+' || keycode == '-') )
return true;
case WXK_SPACE:
CBox()->SetValue(!CBox()->GetValue());
break;
-
+
case '+':
CBox()->SetValue(true);
break;
-
+
case '-':
CBox()->SetValue(false);
break;
wxASSERT_MSG(m_control,
wxT("The wxGridCellEditor must be Created first!"));
+ wxGridCellEditorEvtHandler* evtHandler = NULL;
+ if (m_control)
+ evtHandler = wxDynamicCast(m_control->GetEventHandler(), wxGridCellEditorEvtHandler);
+
+ // Don't immediately end if we get a kill focus event within BeginEdit
+ if (evtHandler)
+ evtHandler->SetInSetFocus(true);
+
m_startValue = grid->GetTable()->GetValue(row, col);
if (m_allowOthers)
{
// find the right position, or default to the first if not found
int pos = Combo()->FindString(m_startValue);
- if (pos == -1)
+ if (pos == wxNOT_FOUND)
pos = 0;
Combo()->SetSelection(pos);
}
Combo()->SetInsertionPointEnd();
Combo()->SetFocus();
+
+ if (evtHandler)
+ evtHandler->SetInSetFocus(false);
}
bool wxGridCellChoiceEditor::EndEdit(int row, int col,
// wxGridCellEditorEvtHandler
// ----------------------------------------------------------------------------
+void wxGridCellEditorEvtHandler::OnKillFocus(wxFocusEvent& event)
+{
+ // Don't disable the cell if we're just starting to edit it
+ if (m_inSetFocus)
+ return;
+
+ // accept changes
+ m_grid->DisableCellEditControl();
+
+ event.Skip();
+}
+
void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
{
switch ( event.GetKeyCode() )
mergefrom->GetAlignment( &hAlign, &vAlign);
SetAlignment(hAlign, vAlign);
}
-
- mergefrom->GetSize( &m_sizeRows, &m_sizeCols );
+ if ( !HasSize() && mergefrom->HasSize() )
+ mergefrom->GetSize( &m_sizeRows, &m_sizeCols );
// Directly access member functions as GetRender/Editor don't just return
// m_renderer/m_editor
return (wxGridCellAttr *)NULL;
}
+
void wxGridTableBase::SetAttr(wxGridCellAttr* attr, int row, int col)
{
if ( m_attrProvider )
void wxGridWindow::OnMouseEvent( wxMouseEvent& event )
{
+ if (event.ButtonDown(wxMOUSE_BTN_LEFT) && FindFocus() != this)
+ SetFocus();
+
m_owner->ProcessGridCellMouseEvent( event );
}
y = wxMax( h - 1, 0 );
// do set scrollbar parameters
- SetScrollbars( GRID_SCROLL_LINE_X, GRID_SCROLL_LINE_Y,
+ SetScrollbars( m_scrollLineX, m_scrollLineY,
GetScrollX(w), GetScrollY(h), x, y,
GetBatchCount() != 0);
break;
case WXGRID_CURSOR_SELECT_ROW:
+ {
if ( (row = YToRow( y )) >= 0 )
{
if ( m_selection )
event.MetaDown() );
}
}
+ }
+ break;
// default label to suppress warnings about "enumeration value
// 'xxx' not handled in switch
break;
case WXGRID_CURSOR_SELECT_COL:
+ {
if ( (col = XToCol( x )) >= 0 )
{
if ( m_selection )
event.MetaDown() );
}
}
+ }
+ break;
// default label to suppress warnings about "enumeration value
// 'xxx' not handled in switch
// visible (even after calling MakeCellVisible the
// control is not created and calling StartingKey will
// crash the app
- if ( editor->IsCreated() && m_cellEditCtrlEnabled )
+ if ( event.GetKeyCode() != WXK_F2 && editor->IsCreated() && m_cellEditCtrlEnabled )
editor->StartingKey(event);
}
else
int topRow = internalYToRow(top);
int rightCol = internalXToCol(right);
int bottomRow = internalYToRow(bottom);
- wxRegion clippedcells(0, 0, cw, ch);
+#ifndef __WXMAC__
+ // CS: I don't know why suddenly unscrolled coordinates are used for clipping
+ wxRegion clippedcells(0, 0, cw, ch);
int i, j, cell_rows, cell_cols;
wxRect rect;
}
}
}
+#else
+ wxRegion clippedcells( left , top, right - left, bottom - top);
+
+ int i, j, cell_rows, cell_cols;
+ wxRect rect;
+
+ for (j=topRow; j<bottomRow; j++)
+ {
+ for (i=leftCol; i<rightCol; i++)
+ {
+ GetCellSize( j, i, &cell_rows, &cell_cols );
+ if ((cell_rows > 1) || (cell_cols > 1))
+ {
+ rect = CellToRect(j,i);
+ clippedcells.Subtract(rect);
+ }
+ else if ((cell_rows < 0) || (cell_cols < 0))
+ {
+ rect = CellToRect(j+cell_rows, i+cell_cols);
+ clippedcells.Subtract(rect);
+ }
+ }
+ }
+#endif
dc.SetClippingRegion( clippedcells );
dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) );
void wxGrid::DrawRowLabel( wxDC& dc, int row )
{
- if ( GetRowHeight(row) <= 0 )
+ if ( GetRowHeight(row) <= 0 || m_rowLabelWidth <= 0 )
return;
wxRect rect;
-#ifdef __WXGTK__
+#ifdef __WXGTK20__
rect.SetX( 1 );
rect.SetY( GetRowTop(row) + 1 );
rect.SetWidth( m_rowLabelWidth - 2 );
void wxGrid::DrawColLabel( wxDC& dc, int col )
{
- if ( GetColWidth(col) <= 0 )
+ if ( GetColWidth(col) <= 0 || m_colLabelHeight <= 0 )
return;
int colLeft = GetColLeft(col);
wxRect rect;
-#ifdef __WXGTK__
+#ifdef __WXGTK20__
rect.SetX( colLeft + 1 );
rect.SetY( 1 );
rect.SetWidth( GetColWidth(col) - 2 );
wxRect rect( CellToRect(row, col) );
CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y );
rect.width = m_gridWin->GetClientSize().GetWidth() - rect.x;
+#ifdef __WXMAC__
+ // ensure that the pixels under the focus ring get refreshed as well
+ rect.Inflate(10,10);
+#endif
m_gridWin->Refresh( false, &rect );
}
}
//
// Sometimes GRID_SCROLL_LINE/2 is not enough, so just add a full
// scroll unit...
- ypos += GRID_SCROLL_LINE_Y;
+ ypos += m_scrollLineY;
}
if ( left < 0 )
xpos = x0 + (right - cw);
// see comment for ypos above
- xpos += GRID_SCROLL_LINE_X;
+ xpos += m_scrollLineX;
}
if ( xpos != -1 || ypos != -1 )
{
if ( xpos != -1 )
- xpos /= GRID_SCROLL_LINE_X;
+ xpos /= m_scrollLineX;
if ( ypos != -1 )
- ypos /= GRID_SCROLL_LINE_Y;
+ ypos /= m_scrollLineY;
Scroll( xpos, ypos );
AdjustScrollbars();
}
// won't get the scrollbars if we're sized exactly to this width
// CalcDimension adds m_extraWidth + 1 etc. to calculate the necessary
// scrollbar steps
- wxSize sizeFit(GetScrollX(size.x + m_extraWidth + 1) * GRID_SCROLL_LINE_X,
- GetScrollY(size.y + m_extraHeight + 1) * GRID_SCROLL_LINE_Y);
+ wxSize sizeFit(GetScrollX(size.x + m_extraWidth + 1) * m_scrollLineX,
+ GetScrollY(size.y + m_extraHeight + 1) * m_scrollLineY);
// distribute the extra space between the columns/rows to avoid having
// extra white space