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
|
// how big is the editor
|
||||||
wxGridCellAttr* attr = GetCellAttr(r, c);
|
wxGridCellAttr* attr = GetCellAttr(r, c);
|
||||||
wxGridCellEditor* editor = attr->GetEditor(this, r, c);
|
wxGridCellEditor* editor = attr->GetEditor(this, r, c);
|
||||||
editor->GetControl()->GetSize(&w2, &h2);
|
editor->GetWindow()->GetSize(&w2, &h2);
|
||||||
w2 += x;
|
w2 += x;
|
||||||
h2 += y;
|
h2 += y;
|
||||||
if ( w2 > w )
|
if ( w2 > w )
|
||||||
@@ -6877,7 +6877,7 @@ bool wxGrid::IsCellEditControlShown() const
|
|||||||
{
|
{
|
||||||
if ( editor->IsCreated() )
|
if ( editor->IsCreated() )
|
||||||
{
|
{
|
||||||
isShown = editor->GetControl()->IsShown();
|
isShown = editor->GetWindow()->IsShown();
|
||||||
}
|
}
|
||||||
|
|
||||||
editor->DecRef();
|
editor->DecRef();
|
||||||
@@ -6959,13 +6959,13 @@ void wxGrid::ShowCellEditControl()
|
|||||||
this,
|
this,
|
||||||
row,
|
row,
|
||||||
col,
|
col,
|
||||||
editor->GetControl());
|
editor->GetWindow());
|
||||||
GetEventHandler()->ProcessEvent(evt);
|
GetEventHandler()->ProcessEvent(evt);
|
||||||
}
|
}
|
||||||
else if ( editor->GetControl() &&
|
else if ( editor->GetWindow() &&
|
||||||
editor->GetControl()->GetParent() != gridWindow )
|
editor->GetWindow()->GetParent() != gridWindow )
|
||||||
{
|
{
|
||||||
editor->GetControl()->Reparent(gridWindow);
|
editor->GetWindow()->Reparent(gridWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// resize editor to overflow into righthand cells if allowed
|
// resize editor to overflow into righthand cells if allowed
|
||||||
@@ -7009,9 +7009,9 @@ void wxGrid::ShowCellEditControl()
|
|||||||
editor->SetCellAttr( attr );
|
editor->SetCellAttr( attr );
|
||||||
editor->SetSize( rect );
|
editor->SetSize( rect );
|
||||||
if (nXMove != 0)
|
if (nXMove != 0)
|
||||||
editor->GetControl()->Move(
|
editor->GetWindow()->Move(
|
||||||
editor->GetControl()->GetPosition().x + nXMove,
|
editor->GetWindow()->GetPosition().x + nXMove,
|
||||||
editor->GetControl()->GetPosition().y );
|
editor->GetWindow()->GetPosition().y );
|
||||||
editor->Show( true, attr );
|
editor->Show( true, attr );
|
||||||
|
|
||||||
// recalc dimensions in case we need to
|
// recalc dimensions in case we need to
|
||||||
@@ -7036,10 +7036,10 @@ void wxGrid::HideCellEditControl()
|
|||||||
|
|
||||||
wxGridCellAttr *attr = GetCellAttr(row, col);
|
wxGridCellAttr *attr = GetCellAttr(row, col);
|
||||||
wxGridCellEditor *editor = attr->GetEditor(this, 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 )
|
if ( editor->GetWindow()->GetParent() != m_gridWin )
|
||||||
editor->GetControl()->Reparent(m_gridWin);
|
editor->GetWindow()->Reparent(m_gridWin);
|
||||||
|
|
||||||
editor->Show( false );
|
editor->Show( false );
|
||||||
editor->DecRef();
|
editor->DecRef();
|
||||||
|
@@ -74,6 +74,7 @@ private:
|
|||||||
NONGTK_TEST( LabelClick );
|
NONGTK_TEST( LabelClick );
|
||||||
NONGTK_TEST( SortClick );
|
NONGTK_TEST( SortClick );
|
||||||
CPPUNIT_TEST( ColumnOrder );
|
CPPUNIT_TEST( ColumnOrder );
|
||||||
|
WXUISIM_TEST( WindowAsEditorControl );
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
void CellEdit();
|
void CellEdit();
|
||||||
@@ -95,6 +96,7 @@ private:
|
|||||||
void CellFormatting();
|
void CellFormatting();
|
||||||
void Editable();
|
void Editable();
|
||||||
void ReadOnly();
|
void ReadOnly();
|
||||||
|
void WindowAsEditorControl();
|
||||||
void PseudoTest_NativeHeader() { ms_nativeheader = true; }
|
void PseudoTest_NativeHeader() { ms_nativeheader = true; }
|
||||||
void PseudoTest_NativeLabels() { ms_nativeheader = false;
|
void PseudoTest_NativeLabels() { ms_nativeheader = false;
|
||||||
ms_nativelabels = true; }
|
ms_nativelabels = true; }
|
||||||
@@ -742,4 +744,66 @@ void GridTestCase::ReadOnly()
|
|||||||
#endif
|
#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
|
#endif //wxUSE_GRID
|
||||||
|
Reference in New Issue
Block a user