Make using non-wxControl-derived wxGrid editors really work
While feacaf8714
changed the API to allow
using any wxWindow (and not only a window of a wxControl-derived class)
as the associated window of the grid editor, actually doing resulted in
an immediate crash due to dereferencing a null pointer in wxGrid code
which still expected to have a wxControl.
Fix this by replacing all calls to wxGridCellEditor::GetControl() inside
wxGrid with wxGridCellEditor::GetWindow(), to ensure that a non-null
editor window is used even in this case.
Closes https://github.com/wxWidgets/wxWidgets/pull/1509
This commit is contained in:
committed by
Vadim Zeitlin
parent
0ea4366163
commit
1bce1a1d4c
@@ -2774,7 +2774,7 @@ void wxGrid::CalcDimensions()
|
||||
// how big is the editor
|
||||
wxGridCellAttr* attr = GetCellAttr(r, c);
|
||||
wxGridCellEditor* editor = attr->GetEditor(this, r, c);
|
||||
editor->GetControl()->GetSize(&w2, &h2);
|
||||
editor->GetWindow()->GetSize(&w2, &h2);
|
||||
w2 += x;
|
||||
h2 += y;
|
||||
if ( w2 > w )
|
||||
@@ -6877,7 +6877,7 @@ bool wxGrid::IsCellEditControlShown() const
|
||||
{
|
||||
if ( editor->IsCreated() )
|
||||
{
|
||||
isShown = editor->GetControl()->IsShown();
|
||||
isShown = editor->GetWindow()->IsShown();
|
||||
}
|
||||
|
||||
editor->DecRef();
|
||||
@@ -6959,13 +6959,13 @@ void wxGrid::ShowCellEditControl()
|
||||
this,
|
||||
row,
|
||||
col,
|
||||
editor->GetControl());
|
||||
editor->GetWindow());
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
}
|
||||
else if ( editor->GetControl() &&
|
||||
editor->GetControl()->GetParent() != gridWindow )
|
||||
else if ( editor->GetWindow() &&
|
||||
editor->GetWindow()->GetParent() != gridWindow )
|
||||
{
|
||||
editor->GetControl()->Reparent(gridWindow);
|
||||
editor->GetWindow()->Reparent(gridWindow);
|
||||
}
|
||||
|
||||
// resize editor to overflow into righthand cells if allowed
|
||||
@@ -7009,9 +7009,9 @@ void wxGrid::ShowCellEditControl()
|
||||
editor->SetCellAttr( attr );
|
||||
editor->SetSize( rect );
|
||||
if (nXMove != 0)
|
||||
editor->GetControl()->Move(
|
||||
editor->GetControl()->GetPosition().x + nXMove,
|
||||
editor->GetControl()->GetPosition().y );
|
||||
editor->GetWindow()->Move(
|
||||
editor->GetWindow()->GetPosition().x + nXMove,
|
||||
editor->GetWindow()->GetPosition().y );
|
||||
editor->Show( true, attr );
|
||||
|
||||
// recalc dimensions in case we need to
|
||||
@@ -7036,10 +7036,10 @@ void wxGrid::HideCellEditControl()
|
||||
|
||||
wxGridCellAttr *attr = GetCellAttr(row, col);
|
||||
wxGridCellEditor *editor = attr->GetEditor(this, row, col);
|
||||
const bool editorHadFocus = editor->GetControl()->HasFocus();
|
||||
const bool editorHadFocus = editor->GetWindow()->HasFocus();
|
||||
|
||||
if ( editor->GetControl()->GetParent() != m_gridWin )
|
||||
editor->GetControl()->Reparent(m_gridWin);
|
||||
if ( editor->GetWindow()->GetParent() != m_gridWin )
|
||||
editor->GetWindow()->Reparent(m_gridWin);
|
||||
|
||||
editor->Show( false );
|
||||
editor->DecRef();
|
||||
|
@@ -74,6 +74,7 @@ private:
|
||||
NONGTK_TEST( LabelClick );
|
||||
NONGTK_TEST( SortClick );
|
||||
CPPUNIT_TEST( ColumnOrder );
|
||||
WXUISIM_TEST( WindowAsEditorControl );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void CellEdit();
|
||||
@@ -95,6 +96,7 @@ private:
|
||||
void CellFormatting();
|
||||
void Editable();
|
||||
void ReadOnly();
|
||||
void WindowAsEditorControl();
|
||||
void PseudoTest_NativeHeader() { ms_nativeheader = true; }
|
||||
void PseudoTest_NativeLabels() { ms_nativeheader = false;
|
||||
ms_nativelabels = true; }
|
||||
@@ -742,4 +744,66 @@ void GridTestCase::ReadOnly()
|
||||
#endif
|
||||
}
|
||||
|
||||
void GridTestCase::WindowAsEditorControl()
|
||||
{
|
||||
#if wxUSE_UIACTIONSIMULATOR
|
||||
// A very simple editor using a window not derived from wxControl as the
|
||||
// editor.
|
||||
class TestEditor : public wxGridCellEditor
|
||||
{
|
||||
public:
|
||||
TestEditor() {}
|
||||
|
||||
void Create(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
wxEvtHandler* evtHandler) wxOVERRIDE
|
||||
{
|
||||
SetWindow(new wxWindow(parent, id));
|
||||
wxGridCellEditor::Create(parent, id, evtHandler);
|
||||
}
|
||||
|
||||
void BeginEdit(int, int, wxGrid*) wxOVERRIDE {}
|
||||
|
||||
bool EndEdit(int, int, wxGrid const*, wxString const&,
|
||||
wxString* newval) wxOVERRIDE
|
||||
{
|
||||
*newval = GetValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApplyEdit(int row, int col, wxGrid* grid) wxOVERRIDE
|
||||
{
|
||||
grid->GetTable()->SetValue(row, col, GetValue());
|
||||
}
|
||||
|
||||
void Reset() wxOVERRIDE {}
|
||||
|
||||
wxGridCellEditor* Clone() const wxOVERRIDE { return new TestEditor(); }
|
||||
|
||||
wxString GetValue() const wxOVERRIDE { return "value"; }
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TestEditor);
|
||||
};
|
||||
|
||||
wxGridCellAttr* attr = new wxGridCellAttr();
|
||||
attr->SetRenderer(new wxGridCellStringRenderer());
|
||||
attr->SetEditor(new TestEditor());
|
||||
m_grid->SetAttr(1, 1, attr);
|
||||
|
||||
EventCounter created(m_grid, wxEVT_GRID_EDITOR_CREATED);
|
||||
|
||||
wxUIActionSimulator sim;
|
||||
|
||||
m_grid->SetFocus();
|
||||
m_grid->SetGridCursor(1, 1);
|
||||
m_grid->EnableCellEditControl();
|
||||
|
||||
sim.Char(WXK_RETURN);
|
||||
|
||||
wxYield();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(1, created.GetCount());
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif //wxUSE_GRID
|
||||
|
Reference in New Issue
Block a user