mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-17 08:53:06 +08:00
Track active wxGrid editor while editing
Remember the editor instance used for the shown edit control and use it for visibility checks, painting, hiding, and saving. This keeps the edit control lifetime independent of later attribute changes, so replacing a cell or column editor while editing does not make wxGrid hide or save through the wrong editor. Add a regression covering replacement of a column bool editor while its cell is being edited. Fixes #21986. Closes #26670.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
// Modified by: Santiago Palacios
|
||||
// Created: 1/08/1999
|
||||
// Copyright: (c) Michael Bedward
|
||||
// (c) 2026 wxWidgets development team
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -2827,6 +2828,9 @@ protected:
|
||||
bool m_editable; // applies to whole grid
|
||||
bool m_cellEditCtrlEnabled; // is in-place edit currently shown?
|
||||
|
||||
// Editor used by the currently active edit control.
|
||||
wxGridCellEditorPtr m_activeCellEditor;
|
||||
|
||||
TabBehaviour m_tabBehaviour; // determines how the TAB key behaves
|
||||
|
||||
void Init(); // common part of all ctors
|
||||
@@ -3170,6 +3174,15 @@ private:
|
||||
);
|
||||
}
|
||||
|
||||
// Return the editor actually being used by the current edit control.
|
||||
wxGridCellEditorPtr GetActiveCellEditorPtr() const
|
||||
{
|
||||
if ( m_activeCellEditor )
|
||||
return m_activeCellEditor;
|
||||
|
||||
return GetCurrentCellEditorPtr();
|
||||
}
|
||||
|
||||
// Show/hide the cell editor for the current cell unconditionally.
|
||||
|
||||
// Return false if the editor was activated instead of being shown and also
|
||||
|
||||
+12
-7
@@ -5,6 +5,7 @@
|
||||
// Modified by: Robin Dunn, Vadim Zeitlin, Santiago Palacios
|
||||
// Created: 1/08/1999
|
||||
// Copyright: (c) Michael Bedward (mbedward@ozemail.com.au)
|
||||
// (c) 2026 wxWidgets development team
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -2891,6 +2892,7 @@ wxGrid::~wxGrid()
|
||||
// otherwise we crash later when the editor tries to do something with the
|
||||
// half destroyed grid
|
||||
HideCellEditControl();
|
||||
m_activeCellEditor.reset(nullptr);
|
||||
|
||||
// Must do this or ~wxScrollHelper will pop the wrong event handler
|
||||
SetTargetWindow(this);
|
||||
@@ -3397,7 +3399,7 @@ void wxGrid::CalcDimensions()
|
||||
// take into account editor if shown
|
||||
if ( IsCellEditControlShown() )
|
||||
{
|
||||
const wxRect rect = GetCurrentCellEditorPtr()->GetWindow()->GetRect();
|
||||
const wxRect rect = GetActiveCellEditorPtr()->GetWindow()->GetRect();
|
||||
if ( rect.GetRight() > w )
|
||||
w = rect.GetRight();
|
||||
if ( rect.GetBottom() > h )
|
||||
@@ -5150,7 +5152,7 @@ wxGrid::DoGridCellLeftUp(wxMouseEvent& event,
|
||||
ClearSelection();
|
||||
|
||||
if ( DoEnableCellEditControl(wxGridActivationSource::From(event)) )
|
||||
GetCurrentCellEditorPtr()->StartingClick();
|
||||
GetActiveCellEditorPtr()->StartingClick();
|
||||
|
||||
m_waitForSlowClick = false;
|
||||
}
|
||||
@@ -6594,7 +6596,7 @@ void wxGrid::OnChar( wxKeyEvent& event )
|
||||
|
||||
if ( DoEnableCellEditControl(wxGridActivationSource::From(event))
|
||||
&& !specialEditKey )
|
||||
editor->StartingKey(event);
|
||||
GetActiveCellEditorPtr()->StartingKey(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6893,7 +6895,7 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
|
||||
// Note: However, only if it is really _shown_, i.e. not hidden!
|
||||
if ( isCurrent && IsCellEditControlShown() )
|
||||
{
|
||||
attr->GetEditorPtr(this, row, col)->PaintBackground(dc, rect, *attr);
|
||||
GetActiveCellEditorPtr()->PaintBackground(dc, rect, *attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -8003,7 +8005,7 @@ bool wxGrid::IsCellEditControlShown() const
|
||||
|
||||
if ( m_cellEditCtrlEnabled )
|
||||
{
|
||||
if ( wxGridCellEditorPtr editor = GetCurrentCellEditorPtr() )
|
||||
if ( wxGridCellEditorPtr editor = GetActiveCellEditorPtr() )
|
||||
{
|
||||
if ( editor->IsCreated() )
|
||||
{
|
||||
@@ -8022,6 +8024,7 @@ void wxGrid::ShowCellEditControl()
|
||||
if ( !IsVisible( m_currentCellCoords, false ) )
|
||||
{
|
||||
m_cellEditCtrlEnabled = false;
|
||||
m_activeCellEditor.reset(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8082,6 +8085,7 @@ bool wxGrid::DoShowCellEditControl(const wxGridActivationSource& actSource)
|
||||
// before generating any events in case their user-defined handlers decide
|
||||
// to call EnableCellEditControl() to avoid reentrancy problems.
|
||||
m_cellEditCtrlEnabled = true;
|
||||
m_activeCellEditor = editor;
|
||||
|
||||
wxGridWindow *gridWindow = CellToGridWindow(row, col);
|
||||
|
||||
@@ -8216,7 +8220,7 @@ void wxGrid::HideCellEditControl()
|
||||
|
||||
void wxGrid::DoHideCellEditControl()
|
||||
{
|
||||
wxGridCellEditorPtr editor = GetCurrentCellEditorPtr();
|
||||
wxGridCellEditorPtr editor = GetActiveCellEditorPtr();
|
||||
const bool editorHadFocus = editor->GetWindow()->IsDescendant(FindFocus());
|
||||
|
||||
if ( editor->GetWindow()->GetParent() != m_gridWin )
|
||||
@@ -8279,6 +8283,7 @@ void wxGrid::DoAcceptCellEditControl()
|
||||
DoHideCellEditControl();
|
||||
|
||||
DoSaveEditControlValue();
|
||||
m_activeCellEditor.reset(nullptr);
|
||||
}
|
||||
|
||||
void wxGrid::SaveEditControlValue()
|
||||
@@ -8296,7 +8301,7 @@ void wxGrid::DoSaveEditControlValue()
|
||||
|
||||
wxString oldval = GetCellValue(m_currentCellCoords);
|
||||
|
||||
wxGridCellEditorPtr editor = GetCurrentCellEditorPtr();
|
||||
wxGridCellEditorPtr editor = GetActiveCellEditorPtr();
|
||||
|
||||
wxString newval;
|
||||
if ( !editor->EndEdit(row, col, this, oldval, &newval) )
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Author: Steven Lamerton
|
||||
// Created: 2010-06-25
|
||||
// Copyright: (c) 2010 Steven Lamerton
|
||||
// (c) 2026 wxWidgets development team
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "testprec.h"
|
||||
@@ -1541,6 +1542,29 @@ TEST_CASE_METHOD(GridTestCase, "Grid::ReadOnly", "[grid]")
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(GridTestCase, "Grid::ChangeEditorWhileEditing", "[grid]")
|
||||
{
|
||||
wxGridCellAttr* attr = new wxGridCellAttr();
|
||||
attr->SetEditor(new wxGridCellBoolEditor);
|
||||
attr->SetRenderer(new wxGridCellBoolRenderer);
|
||||
m_grid->SetColAttr(0, attr);
|
||||
|
||||
m_grid->SetCellValue(0, 0, "1");
|
||||
m_grid->SetGridCursor(0, 0);
|
||||
m_grid->EnableCellEditControl();
|
||||
|
||||
REQUIRE(m_grid->IsCellEditControlShown());
|
||||
|
||||
attr = new wxGridCellAttr();
|
||||
attr->SetEditor(new wxGridCellBoolEditor);
|
||||
attr->SetRenderer(new wxGridCellBoolRenderer);
|
||||
m_grid->SetColAttr(0, attr);
|
||||
|
||||
m_grid->DisableCellEditControl();
|
||||
|
||||
CHECK(!m_grid->IsCellEditControlShown());
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(GridTestCase, "Grid::WindowAsEditorControl", "[grid]")
|
||||
{
|
||||
#if wxUSE_UIACTIONSIMULATOR
|
||||
|
||||
Reference in New Issue
Block a user