// implementation
// ============================================================================
+wxDEFINE_EVENT( wxEVT_GRID_HIDE_EDITOR, wxCommandEvent );
+
// ----------------------------------------------------------------------------
// wxGridCellEditorEvtHandler
// ----------------------------------------------------------------------------
void wxGridCellEditorEvtHandler::OnKillFocus(wxFocusEvent& event)
{
+ // We must let the native control have this event so in any case don't mark
+ // it as handled, otherwise various weird problems can happen (see #11681).
+ event.Skip();
+
// Don't disable the cell if we're just starting to edit it
- if ( m_inSetFocus )
- {
- event.Skip();
+ if (m_inSetFocus)
return;
- }
- // accept changes
- m_grid->DisableCellEditControl();
+ // Tell the grid to dismiss the control but don't do it immediately as it
+ // could result in the editor being destroyed right now and a crash in the
+ // code searching for the next event handler, so post an event asking the
+ // grid to do it slightly later instead.
- // notice that we must not skip the event here because the call above may
- // delete the control which received the kill focus event in the first
- // place and if we pretend not having processed the event, the search for a
- // handler for it will continue using the now deleted object resulting in a
- // crash
+ // FIXME-VC6: Once we drop support for VC6, we should use a simpler
+ // m_grid->CallAfter(&wxGrid::DisableCellEditControl) and get
+ // rid of wxEVT_GRID_HIDE_EDITOR entirely.
+ m_grid->GetEventHandler()->
+ AddPendingEvent(wxCommandEvent(wxEVT_GRID_HIDE_EDITOR));
}
void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
m_control->PushEventHandler(evtHandler);
}
-void wxGridCellEditor::PaintBackground(const wxRect& rectCell,
- wxGridCellAttr *attr)
+void wxGridCellEditor::PaintBackground(wxDC& dc,
+ const wxRect& rectCell,
+ const wxGridCellAttr& attr)
{
// erase the background because we might not fill the cell
- wxClientDC dc(m_control->GetParent());
- wxGridWindow* gridWindow = wxDynamicCast(m_control->GetParent(), wxGridWindow);
- if (gridWindow)
- gridWindow->GetOwner()->PrepareDC(dc);
-
dc.SetPen(*wxTRANSPARENT_PEN);
- dc.SetBrush(wxBrush(attr->GetBackgroundColour()));
+ dc.SetBrush(wxBrush(attr.GetBackgroundColour()));
dc.DrawRectangle(rectCell);
-
- // redraw the control we just painted over
- m_control->Refresh();
}
void wxGridCellEditor::Destroy()
// wxGridCellTextEditor
// ----------------------------------------------------------------------------
-wxGridCellTextEditor::wxGridCellTextEditor()
+wxGridCellTextEditor::wxGridCellTextEditor(size_t maxChars)
{
- m_maxChars = 0;
+ m_maxChars = maxChars;
}
void wxGridCellTextEditor::Create(wxWindow* parent,
wxEvtHandler* evtHandler,
long style)
{
- // Use of wxTE_RICH2 is a strange hack to work around the bug #11681: a
- // plain text control seems to lose its caret somehow when we hide it and
- // show it again for a different cell.
- style |= wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER | wxTE_RICH2;
+ style |= wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER;
- m_control = new wxTextCtrl(parent, id, wxEmptyString,
- wxDefaultPosition, wxDefaultSize,
- style);
+ wxTextCtrl* const text = new wxTextCtrl(parent, id, wxEmptyString,
+ wxDefaultPosition, wxDefaultSize,
+ style);
+ text->SetMargins(0, 0);
+ m_control = text;
#ifdef __WXOSX__
wxWidgetImpl* impl = m_control->GetPeer();
{
Text()->SetMaxLength(m_maxChars);
}
+ // validate text in textctrl, if validator is set
+ if ( m_validator )
+ {
+ Text()->SetValidator(*m_validator);
+ }
wxGridCellEditor::Create(parent, id, evtHandler);
}
-void wxGridCellTextEditor::PaintBackground(const wxRect& WXUNUSED(rectCell),
- wxGridCellAttr * WXUNUSED(attr))
+void wxGridCellTextEditor::PaintBackground(wxDC& WXUNUSED(dc),
+ const wxRect& WXUNUSED(rectCell),
+ const wxGridCellAttr& WXUNUSED(attr))
{
// as we fill the entire client area,
// don't do anything here to minimize flicker
{
Text()->SetValue(startValue);
Text()->SetInsertionPointEnd();
- Text()->SetSelection(-1, -1);
+ Text()->SelectAll();
Text()->SetFocus();
}
}
}
+void wxGridCellTextEditor::SetValidator(const wxValidator& validator)
+{
+ m_validator.reset(static_cast<wxValidator*>(validator.Clone()));
+}
+
+wxGridCellEditor *wxGridCellTextEditor::Clone() const
+{
+ wxGridCellTextEditor* editor = new wxGridCellTextEditor(m_maxChars);
+ if ( m_validator )
+ {
+ editor->SetValidator(*m_validator);
+ }
+ return editor;
+}
+
// return the value in the text control
wxString wxGridCellTextEditor::GetValue() const
{
wxGridCellEditor::SetSize(rectTallEnough);
}
-void wxGridCellChoiceEditor::PaintBackground(const wxRect& rectCell,
- wxGridCellAttr * attr)
+void wxGridCellChoiceEditor::PaintBackground(wxDC& dc,
+ const wxRect& rectCell,
+ const 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);
+ wxGridCellEditor::PaintBackground(dc, rectCell, attr);
}
void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)