Move delay selection out of UpdateUI

Calling actions from within UpdateUI can cause loops that crash or
substantially slow

Fixes https://gitlab.com/kicad/code/kicad/issues/10616
This commit is contained in:
Seth Hillbrand 2022-01-26 16:04:45 -08:00
parent b87e4efc68
commit 9ab2eb391f
2 changed files with 62 additions and 46 deletions

View File

@ -23,6 +23,8 @@
#include "dialog_symbol_properties.h"
#include <memory>
#include <bitmaps.h>
#include <wx/tooltip.h>
#include <grid_tricks.h>
@ -44,12 +46,16 @@
#include <schematic.h>
#include <tool/tool_manager.h>
#include <tool/actions.h>
#include <math/vector2d.h>
#ifdef KICAD_SPICE
#include <dialog_spice_model.h>
#endif /* KICAD_SPICE */
wxDEFINE_EVENT( SYMBOL_DELAY_FOCUS, wxCommandEvent );
wxDEFINE_EVENT( SYMBOL_DELAY_SELECTION, wxCommandEvent );
enum PIN_TABLE_COL_ORDER
{
COL_NUMBER,
@ -292,9 +298,6 @@ DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
m_fields = new FIELDS_GRID_TABLE<SCH_FIELD>( this, aParent, m_fieldsGrid, m_part );
m_delayedFocusRow = REFERENCE_FIELD;
m_delayedFocusColumn = FDC_VALUE;
m_delayedSelection = true;
m_editorShown = false;
m_lastRequestedSize = wxSize( 0, 0 );
@ -372,6 +375,17 @@ DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
wxGridEventHandler( DIALOG_SYMBOL_PROPERTIES::OnPinTableColSort ),
nullptr, this );
Connect( SYMBOL_DELAY_FOCUS,
wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES::HandleDelayedFocus ), nullptr, this );
Connect( SYMBOL_DELAY_SELECTION,
wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES::HandleDelayedSelection ), nullptr,
this );
QueueEvent( new wxCommandEvent( SYMBOL_DELAY_SELECTION ) );
wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
evt->SetClientData( new VECTOR2I( REFERENCE_FIELD, FDC_VALUE ) );
QueueEvent( evt );
finishDialogSettings();
}
@ -558,9 +572,9 @@ bool DIALOG_SYMBOL_PROPERTIES::Validate()
{
DisplayErrorMessage( this, _( "References must start with a letter." ) );
m_delayedFocusColumn = FDC_VALUE;
m_delayedFocusRow = REFERENCE_FIELD;
m_delayedSelection = false;
wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
evt->SetClientData( new VECTOR2I( REFERENCE_FIELD, FDC_VALUE ) );
QueueEvent( evt );
return false;
}
@ -575,9 +589,9 @@ bool DIALOG_SYMBOL_PROPERTIES::Validate()
{
DisplayErrorMessage( this, _( "Fields must have a name." ) );
m_delayedFocusColumn = FDC_NAME;
m_delayedFocusRow = i;
m_delayedSelection = false;
wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
evt->SetClientData( new VECTOR2I( i, FDC_VALUE ) );
QueueEvent( evt );
return false;
}
@ -763,9 +777,9 @@ void DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
{
event.Veto();
m_delayedFocusRow = event.GetRow();
m_delayedFocusColumn = event.GetCol();
m_delayedSelection = false;
wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
evt->SetClientData( new VECTOR2I( event.GetRow(), event.GetCol() ) );
QueueEvent( evt );
}
else if( event.GetCol() == FDC_NAME )
{
@ -781,9 +795,9 @@ void DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
DisplayError( this, wxString::Format( _( "Field name '%s' already in use." ),
newName ) );
event.Veto();
m_delayedFocusRow = event.GetRow();
m_delayedFocusColumn = event.GetCol();
m_delayedSelection = false;
wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
evt->SetClientData( new VECTOR2I( event.GetRow(), event.GetCol() ) );
QueueEvent( evt );
}
}
}
@ -795,7 +809,7 @@ void DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
void DIALOG_SYMBOL_PROPERTIES::OnGridEditorShown( wxGridEvent& aEvent )
{
if( aEvent.GetRow() == REFERENCE_FIELD && aEvent.GetCol() == FDC_VALUE )
m_delayedSelection= true;
QueueEvent( new wxCommandEvent( SYMBOL_DELAY_SELECTION ) );
m_editorShown = true;
}
@ -1046,36 +1060,39 @@ void DIALOG_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
if( !m_fieldsGrid->IsCellEditControlShown() )
AdjustFieldsGridColumns();
}
// Handle a delayed focus
if( m_delayedFocusRow >= 0 )
{
m_fieldsGrid->SetFocus();
m_fieldsGrid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
m_fieldsGrid->SetGridCursor( m_delayedFocusRow, m_delayedFocusColumn );
m_fieldsGrid->EnableCellEditControl( true );
m_fieldsGrid->ShowCellEditControl();
m_delayedFocusRow = -1;
m_delayedFocusColumn = -1;
}
// Handle a delayed selection
if( m_delayedSelection )
{
wxGridCellEditor* cellEditor = m_fieldsGrid->GetCellEditor( REFERENCE_FIELD, FDC_VALUE );
if( wxTextEntry* txt = dynamic_cast<wxTextEntry*>( cellEditor->GetControl() ) )
KIUI::SelectReferenceNumber( txt );
cellEditor->DecRef(); // we're done; must release
m_delayedSelection = false;
}
}
void DIALOG_SYMBOL_PROPERTIES::HandleDelayedFocus( wxCommandEvent& event )
{
VECTOR2I *loc = static_cast<VECTOR2I*>( event.GetClientData() );
wxCHECK_RET( loc, wxT( "Missing focus cell location" ) );
// Handle a delayed focus
m_fieldsGrid->SetFocus();
m_fieldsGrid->MakeCellVisible( loc->x, loc->y );
m_fieldsGrid->SetGridCursor( loc->x, loc->y );
m_fieldsGrid->EnableCellEditControl( true );
m_fieldsGrid->ShowCellEditControl();
delete loc;
}
void DIALOG_SYMBOL_PROPERTIES::HandleDelayedSelection( wxCommandEvent& event )
{
// Handle a delayed selection
wxGridCellEditor* cellEditor = m_fieldsGrid->GetCellEditor( REFERENCE_FIELD, FDC_VALUE );
if( wxTextEntry* txt = dynamic_cast<wxTextEntry*>( cellEditor->GetControl() ) )
KIUI::SelectReferenceNumber( txt );
cellEditor->DecRef(); // we're done; must release
}
void DIALOG_SYMBOL_PROPERTIES::OnSizeFieldsGrid( wxSizeEvent& event )
{
wxSize new_size = event.GetSize();

View File

@ -92,6 +92,8 @@ private:
void AdjustFieldsGridColumns();
void AdjustPinsGridColumns();
void HandleDelayedFocus( wxCommandEvent& event );
void HandleDelayedSelection( wxCommandEvent& event );
private:
SCH_SYMBOL* m_symbol;
@ -100,9 +102,6 @@ private:
wxSize m_fieldsSize;
wxSize m_lastRequestedSize;
wxSize m_pinsSize;
int m_delayedFocusRow;
int m_delayedFocusColumn;
bool m_delayedSelection;
bool m_editorShown;
wxString m_shownColumns;