Improve robustness of numeric evaluation.
It would appear that some platforms process the KILL_FOCUS event after running TransferDataFromWindow(). This change makes sure that the evaluation is done no matter the order. Fixes: lp:1793911 * https://bugs.launchpad.net/kicad/+bug/1793911
This commit is contained in:
parent
90df7a8b22
commit
3024ded91e
|
@ -136,6 +136,12 @@ bool NUMERIC_EVALUATOR::Process( const wxString& aString )
|
|||
m_parseFinished = false;
|
||||
Token tok;
|
||||
|
||||
if( aString.IsEmpty() )
|
||||
{
|
||||
m_parseFinished = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
tok = getToken();
|
||||
|
|
|
@ -76,9 +76,6 @@ void TEXT_CTRL_EVAL::onTextEnter( wxCommandEvent& aEvent )
|
|||
|
||||
void TEXT_CTRL_EVAL::evaluate()
|
||||
{
|
||||
if( GetValue().IsEmpty() )
|
||||
wxTextCtrl::SetValue( "0" );
|
||||
|
||||
if( m_eval.Process( GetValue() ) )
|
||||
SetValue( m_eval.Result() );
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ UNIT_BINDER::UNIT_BINDER( EDA_DRAW_FRAME* aParent,
|
|||
m_min = aMin;
|
||||
m_max = aMax;
|
||||
m_allowEval = allowEval && dynamic_cast<wxTextEntry*>( m_value );
|
||||
m_needsEval = false;
|
||||
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
if( textEntry )
|
||||
|
@ -58,13 +59,6 @@ UNIT_BINDER::UNIT_BINDER( EDA_DRAW_FRAME* aParent,
|
|||
|
||||
m_value->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ), NULL, this );
|
||||
m_value->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( UNIT_BINDER::onKillFocus ), NULL, this );
|
||||
|
||||
// Connect wxEVT_TEXT_ENTER when (and *only when*) m_value has the wxTE_PROCESS_ENTER style
|
||||
// because if this style does not exist:
|
||||
// 1 - Connect wxEVT_TEXT_ENTER is useless
|
||||
// 2 - it generates wxWidgets assert
|
||||
if( m_value->HasFlag( wxTE_PROCESS_ENTER ) )
|
||||
m_value->Connect( wxEVT_TEXT_ENTER, wxCommandEventHandler( UNIT_BINDER::onTextEnter ), NULL, this );
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,6 +80,8 @@ void UNIT_BINDER::onSetFocus( wxFocusEvent& aEvent )
|
|||
|
||||
if( oldStr.length() )
|
||||
textEntry->SetValue( oldStr );
|
||||
|
||||
m_needsEval = true;
|
||||
}
|
||||
|
||||
aEvent.Skip();
|
||||
|
@ -94,8 +90,15 @@ void UNIT_BINDER::onSetFocus( wxFocusEvent& aEvent )
|
|||
|
||||
void UNIT_BINDER::onKillFocus( wxFocusEvent& aEvent )
|
||||
{
|
||||
if( m_allowEval )
|
||||
evaluate();
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
|
||||
if( m_allowEval && textEntry )
|
||||
{
|
||||
if( m_eval.Process( textEntry->GetValue() ) )
|
||||
textEntry->ChangeValue( m_eval.Result() );
|
||||
|
||||
m_needsEval = false;
|
||||
}
|
||||
|
||||
Validate( true );
|
||||
|
||||
|
@ -103,32 +106,6 @@ void UNIT_BINDER::onKillFocus( wxFocusEvent& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void UNIT_BINDER::onTextEnter( wxCommandEvent& aEvent )
|
||||
{
|
||||
if( m_allowEval )
|
||||
evaluate();
|
||||
|
||||
// Send an OK event to the parent dialog
|
||||
wxCommandEvent event( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK );
|
||||
wxPostEvent( m_value->GetParent(), event );
|
||||
}
|
||||
|
||||
|
||||
void UNIT_BINDER::evaluate()
|
||||
{
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
|
||||
if( !textEntry )
|
||||
return;
|
||||
|
||||
if( textEntry->GetValue().IsEmpty() )
|
||||
textEntry->ChangeValue( "0" );
|
||||
|
||||
if( m_eval.Process( textEntry->GetValue() ) )
|
||||
textEntry->ChangeValue( m_eval.Result() );
|
||||
}
|
||||
|
||||
|
||||
wxString valueDescriptionFromLabel( wxStaticText* aLabel )
|
||||
{
|
||||
wxString desc = aLabel->GetLabel();
|
||||
|
@ -208,10 +185,13 @@ void UNIT_BINDER::SetValue( int aValue )
|
|||
|
||||
void UNIT_BINDER::SetValue( wxString aValue )
|
||||
{
|
||||
if( dynamic_cast<wxTextEntry*>( m_value ) )
|
||||
dynamic_cast<wxTextEntry*>( m_value )->SetValue( aValue );
|
||||
else if( dynamic_cast<wxStaticText*>( m_value ) )
|
||||
dynamic_cast<wxStaticText*>( m_value )->SetLabel( aValue );
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
auto staticText = dynamic_cast<wxStaticText*>( m_value );
|
||||
|
||||
if( textEntry )
|
||||
textEntry->SetValue( aValue );
|
||||
else if( staticText )
|
||||
staticText->SetLabel( aValue );
|
||||
|
||||
if( m_allowEval )
|
||||
m_eval.Clear();
|
||||
|
@ -228,10 +208,13 @@ void UNIT_BINDER::ChangeValue( int aValue )
|
|||
|
||||
void UNIT_BINDER::ChangeValue( wxString aValue )
|
||||
{
|
||||
if( dynamic_cast<wxTextEntry*>( m_value ) )
|
||||
dynamic_cast<wxTextEntry*>( m_value )->ChangeValue( aValue );
|
||||
else if( dynamic_cast<wxStaticText*>( m_value ) )
|
||||
dynamic_cast<wxStaticText*>( m_value )->SetLabel( aValue );
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
auto staticText = dynamic_cast<wxStaticText*>( m_value );
|
||||
|
||||
if( textEntry )
|
||||
textEntry->ChangeValue( aValue );
|
||||
else if( staticText )
|
||||
staticText->SetLabel( aValue );
|
||||
|
||||
if( m_allowEval )
|
||||
m_eval.Clear();
|
||||
|
@ -240,23 +223,34 @@ void UNIT_BINDER::ChangeValue( wxString aValue )
|
|||
}
|
||||
|
||||
|
||||
int UNIT_BINDER::GetValue() const
|
||||
int UNIT_BINDER::GetValue()
|
||||
{
|
||||
wxString s;
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
auto staticText = dynamic_cast<wxStaticText*>( m_value );
|
||||
|
||||
if( dynamic_cast<wxTextEntry*>( m_value ) )
|
||||
s = dynamic_cast<wxTextEntry*>( m_value )->GetValue();
|
||||
else if( dynamic_cast<wxStaticText*>( m_value ) )
|
||||
s = dynamic_cast<wxStaticText*>( m_value )->GetLabel();
|
||||
if( m_needsEval && textEntry )
|
||||
{
|
||||
if( m_eval.Process( textEntry->GetValue() ) )
|
||||
textEntry->ChangeValue( m_eval.Result() );
|
||||
|
||||
return ValueFromString( m_units, s, m_useMils );
|
||||
m_needsEval = false;
|
||||
}
|
||||
|
||||
if( textEntry )
|
||||
return ValueFromString( m_units, textEntry->GetValue(), m_useMils );
|
||||
else if( staticText )
|
||||
return ValueFromString( m_units, staticText->GetLabel(), m_useMils );
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool UNIT_BINDER::IsIndeterminate() const
|
||||
{
|
||||
if( dynamic_cast<wxTextEntry*>( m_value ) )
|
||||
return dynamic_cast<wxTextEntry*>( m_value )->GetValue() == INDETERMINATE;
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
|
||||
if( textEntry )
|
||||
return textEntry->GetValue() == INDETERMINATE;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
* Function GetValue
|
||||
* Returns the current value in Internal Units.
|
||||
*/
|
||||
virtual int GetValue() const;
|
||||
virtual int GetValue();
|
||||
|
||||
/**
|
||||
* Function IsIndeterminate
|
||||
|
@ -125,11 +125,8 @@ protected:
|
|||
|
||||
void onSetFocus( wxFocusEvent& aEvent );
|
||||
void onKillFocus( wxFocusEvent& aEvent );
|
||||
void onTextEnter( wxCommandEvent& aEvent );
|
||||
void delayedFocusHandler( wxIdleEvent& aEvent );
|
||||
|
||||
void evaluate();
|
||||
|
||||
///> The bound widgets
|
||||
wxStaticText* m_label;
|
||||
wxWindow* m_value;
|
||||
|
@ -147,6 +144,7 @@ protected:
|
|||
///> Evaluator
|
||||
NUMERIC_EVALUATOR m_eval;
|
||||
bool m_allowEval;
|
||||
bool m_needsEval;
|
||||
};
|
||||
|
||||
#endif /* __UNIT_BINDER_H_ */
|
||||
|
|
Loading…
Reference in New Issue