From b6916c490c83774bfc5dc47aff497d4635aca3e9 Mon Sep 17 00:00:00 2001 From: John Beard Date: Thu, 7 Mar 2019 16:21:49 +0000 Subject: [PATCH] Pcbnew: allow tab traversal of footprint orientation text control Disable the text update event for the orientation cutom value field before updating it when the radio buttons are selected. This allows to use the conventional EVT_TEXT handler, rather than KEYDOWN, which has two effects: * Tabbing though the dialog no longer sets custom orientation * Click-driven clipboard actions trigger the update correctly. Introduce a helper function in validators.h to assist in updating validated fields without triggering further events. Fixes: lp:1819006 * https://bugs.launchpad.net/kicad/+bug/1819006 --- common/validators.cpp | 11 +++++++++++ include/validators.h | 19 +++++++++++++++++++ .../dialog_edit_footprint_for_BoardEditor.cpp | 12 +++++++++--- .../dialog_edit_footprint_for_BoardEditor.h | 8 +++++++- ...og_edit_footprint_for_BoardEditor_base.cpp | 4 ++-- ...og_edit_footprint_for_BoardEditor_base.fbp | 2 +- ...alog_edit_footprint_for_BoardEditor_base.h | 2 +- 7 files changed, 50 insertions(+), 8 deletions(-) diff --git a/common/validators.cpp b/common/validators.cpp index 5315df598d..f0529bdd9e 100644 --- a/common/validators.cpp +++ b/common/validators.cpp @@ -218,3 +218,14 @@ void ENV_VAR_NAME_VALIDATOR::OnTextChanged( wxCommandEvent& event ) event.Skip(); } + + +void KIUI::ValidatorTransferToWindowWithoutEvents( wxValidator& aValidator ) +{ + wxWindow* ctrl = aValidator.GetWindow(); + + wxCHECK_RET( ctrl != nullptr, "Transferring validator data without a control" ); + + wxEventBlocker orient_update_blocker( ctrl, wxEVT_ANY ); + aValidator.TransferToWindow(); +} \ No newline at end of file diff --git a/include/validators.h b/include/validators.h index fb67e2b496..c472b40e1e 100644 --- a/include/validators.h +++ b/include/validators.h @@ -112,4 +112,23 @@ public: void OnTextChanged( wxCommandEvent& event ); }; +namespace KIUI +{ +/** + * Call a text validator's TransferToWindow method without firing + * a text change event. + * + * This is useful when you want to keep a validator in sync with other data, + * but the act of changing it should not trigger other updates. It is the + * validator equivalent of ChangeValue() compared to SetValue(). + * + * This function blocks all events, but the same technique can be used to + * selectively block events. + * + * @param aValidator the validator to update the control of + */ +void ValidatorTransferToWindowWithoutEvents( wxValidator& aValidator ); + +} // namespace KIUI + #endif // #ifndef VALIDATORS_H diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.cpp b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.cpp index 9931aac206..9a2b5f5aa4 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.cpp +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.cpp @@ -223,11 +223,11 @@ void DIALOG_FOOTPRINT_BOARD_EDITOR::ModuleOrientEvent( wxCommandEvent& ) else if( m_Orient180->GetValue() ) m_OrientValue = 180.0; - m_OrientValidator.TransferToWindow(); + updateOrientationControl(); } -void DIALOG_FOOTPRINT_BOARD_EDITOR::OnOtherOrientation( wxKeyEvent& aEvent ) +void DIALOG_FOOTPRINT_BOARD_EDITOR::OnOtherOrientation( wxCommandEvent& aEvent ) { m_OrientOther->SetValue( true ); @@ -281,7 +281,7 @@ bool DIALOG_FOOTPRINT_BOARD_EDITOR::TransferDataToWindow() else m_OrientOther->SetValue( true ); - m_OrientValidator.TransferToWindow(); + updateOrientationControl(); m_BoardSideCtrl->SetSelection( (m_footprint->GetLayer() == B_Cu) ? 1 : 0 ); @@ -899,3 +899,9 @@ void DIALOG_FOOTPRINT_BOARD_EDITOR::OnGridSize( wxSizeEvent& aEvent ) aEvent.Skip(); } + + +void DIALOG_FOOTPRINT_BOARD_EDITOR::updateOrientationControl() +{ + KIUI::ValidatorTransferToWindowWithoutEvents( m_OrientValidator ); +} \ No newline at end of file diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.h b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.h index a043b8bcf4..9f52d20c16 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.h +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.h @@ -102,7 +102,7 @@ private: void UpdateModule( wxCommandEvent& ) override; void ExchangeModule( wxCommandEvent& ) override; void ModuleOrientEvent( wxCommandEvent& ) override; - void OnOtherOrientation( wxKeyEvent& aEvent ) override; + void OnOtherOrientation( wxCommandEvent& aEvent ) override; void Cfg3DPath( wxCommandEvent& ) override; void OnGridSize( wxSizeEvent& aEvent ) override; void OnAddField( wxCommandEvent& ) override; @@ -112,6 +112,12 @@ private: void select3DModel( int aModelIdx ); void adjustGridColumns( int aWidth ); + + /** + * Update the orientation validated control, without triggering a change + * event on the control (which would update the radio buttons) + */ + void updateOrientationControl(); }; diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.cpp b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.cpp index ad257cfdec..0ebcd8c0f2 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.cpp +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.cpp @@ -541,7 +541,7 @@ DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::DIALOG_FOOTPRINT_BOARD_EDITOR_BASE( wxWindow m_Orient270->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::ModuleOrientEvent ), NULL, this ); m_Orient180->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::ModuleOrientEvent ), NULL, this ); m_OrientOther->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::ModuleOrientEvent ), NULL, this ); - m_OrientValueCtrl->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnOtherOrientation ), NULL, this ); + m_OrientValueCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnOtherOrientation ), NULL, this ); m_buttonUpdate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::UpdateModule ), NULL, this ); m_buttonExchange->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::ExchangeModule ), NULL, this ); m_buttonModuleEditor->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::EditFootprint ), NULL, this ); @@ -567,7 +567,7 @@ DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::~DIALOG_FOOTPRINT_BOARD_EDITOR_BASE() m_Orient270->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::ModuleOrientEvent ), NULL, this ); m_Orient180->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::ModuleOrientEvent ), NULL, this ); m_OrientOther->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::ModuleOrientEvent ), NULL, this ); - m_OrientValueCtrl->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnOtherOrientation ), NULL, this ); + m_OrientValueCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnOtherOrientation ), NULL, this ); m_buttonUpdate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::UpdateModule ), NULL, this ); m_buttonExchange->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::ExchangeModule ), NULL, this ); m_buttonModuleEditor->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::EditFootprint ), NULL, this ); diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.fbp b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.fbp index d288eb34ea..510fd825cb 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.fbp +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.fbp @@ -1307,7 +1307,7 @@ - OnOtherOrientation + OnOtherOrientation diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.h b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.h index 542a2282e0..219b3afc9f 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.h +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.h @@ -128,7 +128,7 @@ class DIALOG_FOOTPRINT_BOARD_EDITOR_BASE : public DIALOG_SHIM virtual void OnAddField( wxCommandEvent& event ) { event.Skip(); } virtual void OnDeleteField( wxCommandEvent& event ) { event.Skip(); } virtual void ModuleOrientEvent( wxCommandEvent& event ) { event.Skip(); } - virtual void OnOtherOrientation( wxKeyEvent& event ) { event.Skip(); } + virtual void OnOtherOrientation( wxCommandEvent& event ) { event.Skip(); } virtual void UpdateModule( wxCommandEvent& event ) { event.Skip(); } virtual void ExchangeModule( wxCommandEvent& event ) { event.Skip(); } virtual void EditFootprint( wxCommandEvent& event ) { event.Skip(); }