Update simulator with NUMERIC_EVAL, decimal separator processing, etc.
Also includes fixes for instance data and resolving of textvar references. Also includes virtual d'tors for IBIS parser to get rid of all the compile warnings on CLang. Fixes https://gitlab.com/kicad/code/kicad/issues/12357
This commit is contained in:
parent
54dd494ff2
commit
b7d41e0e56
|
@ -59,11 +59,12 @@ expr(A) ::= expr(B) PLUS expr(C). { A.dValue = B.dValue + C.dValue; A.va
|
||||||
expr(A) ::= expr(B) MINUS expr(C). { A.dValue = B.dValue - C.dValue; A.valid=C.valid; }
|
expr(A) ::= expr(B) MINUS expr(C). { A.dValue = B.dValue - C.dValue; A.valid=C.valid; }
|
||||||
expr(A) ::= expr(B) MULT expr(C). { A.dValue = B.dValue * C.dValue; A.valid=C.valid; }
|
expr(A) ::= expr(B) MULT expr(C). { A.dValue = B.dValue * C.dValue; A.valid=C.valid; }
|
||||||
expr(A) ::= expr(B) DIVIDE expr(C). {
|
expr(A) ::= expr(B) DIVIDE expr(C). {
|
||||||
if (C.dValue != 0.0) {
|
if( C.dValue != 0.0 )
|
||||||
A.dValue = B.dValue / C.dValue;
|
A.dValue = B.dValue / C.dValue;
|
||||||
}
|
else
|
||||||
else pEval->parseError("Div by zero");
|
pEval->parseError( "Divide by zero" );
|
||||||
A.valid=C.valid;
|
|
||||||
}
|
A.valid = C.valid;
|
||||||
expr(A) ::= PARENL expr(B) PARENR. { A.dValue = B.dValue; A.valid=B.valid; }
|
}
|
||||||
|
expr(A) ::= PARENL expr(B) PARENR. { A.dValue = B.dValue; A.valid = B.valid; }
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ void NUMERIC_EVALUATOR::SetDefaultUnits( EDA_UNITS aUnits )
|
||||||
case EDA_UNITS::MILS: m_defaultUnits = Unit::Mil; break;
|
case EDA_UNITS::MILS: m_defaultUnits = Unit::Mil; break;
|
||||||
case EDA_UNITS::INCHES: m_defaultUnits = Unit::Inch; break;
|
case EDA_UNITS::INCHES: m_defaultUnits = Unit::Inch; break;
|
||||||
case EDA_UNITS::DEGREES: m_defaultUnits = Unit::Degrees; break;
|
case EDA_UNITS::DEGREES: m_defaultUnits = Unit::Degrees; break;
|
||||||
|
case EDA_UNITS::UNSCALED: m_defaultUnits = Unit::SI; break;
|
||||||
default: m_defaultUnits = Unit::MM; break;
|
default: m_defaultUnits = Unit::MM; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,47 +197,82 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
|
||||||
if( m_token.pos >= m_token.inputLen )
|
if( m_token.pos >= m_token.inputLen )
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
// Support for old school decimal separators (ie: "2K2")
|
||||||
|
auto isOldSchoolDecimalSeparator =
|
||||||
|
[]( char ch, double* siScaler ) -> bool
|
||||||
|
{
|
||||||
|
switch( ch )
|
||||||
|
{
|
||||||
|
case 'a': *siScaler = 1.0e-18; return true;
|
||||||
|
case 'f': *siScaler = 1.0e-15; return true;
|
||||||
|
case 'p': *siScaler = 1.0e-12; return true;
|
||||||
|
case 'n': *siScaler = 1.0e-9; return true;
|
||||||
|
case 'u': *siScaler = 1.0e-6; return true;
|
||||||
|
case 'm': *siScaler = 1.0e-3; return true;
|
||||||
|
case 'k':
|
||||||
|
case 'K': *siScaler = 1.0e3; return true;
|
||||||
|
case 'M': *siScaler = 1.0e6; return true;
|
||||||
|
case 'G': *siScaler = 1.0e9; return true;
|
||||||
|
case 'T': *siScaler = 1.0e12; return true;
|
||||||
|
case 'P': *siScaler = 1.0e15; return true;
|
||||||
|
case 'E': *siScaler = 1.0e18; return true;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
auto isDecimalSeparator =
|
auto isDecimalSeparator =
|
||||||
[&]( char ch ) -> bool
|
[&]( char ch ) -> bool
|
||||||
{
|
{
|
||||||
return ( ch == m_localeDecimalSeparator || ch == '.' || ch == ',' );
|
double dummy;
|
||||||
|
|
||||||
|
if( ch == m_localeDecimalSeparator || ch == '.' || ch == ',' )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if( m_defaultUnits == Unit::SI && isOldSchoolDecimalSeparator( ch, &dummy ) )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Lambda: get value as string, store into clToken.token and update current index.
|
// Lambda: get value as string, store into clToken.token and update current index.
|
||||||
auto extractNumber =
|
auto extractNumber =
|
||||||
[&]()
|
[&]( double* aScaler )
|
||||||
{
|
{
|
||||||
bool haveSeparator = false;
|
bool haveSeparator = false;
|
||||||
idx = 0;
|
double siScaler = 1.0;
|
||||||
char ch = m_token.input[ m_token.pos ];
|
char ch = m_token.input[ m_token.pos ];
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if( isDecimalSeparator( ch ) && haveSeparator )
|
|
||||||
break;
|
|
||||||
|
|
||||||
m_token.token[ idx++ ] = ch;
|
|
||||||
|
|
||||||
if( isDecimalSeparator( ch ) )
|
if( isDecimalSeparator( ch ) )
|
||||||
|
{
|
||||||
|
if( haveSeparator )
|
||||||
|
break;
|
||||||
|
else
|
||||||
haveSeparator = true;
|
haveSeparator = true;
|
||||||
|
|
||||||
|
if( isOldSchoolDecimalSeparator( ch, &siScaler ) )
|
||||||
|
*aScaler = siScaler;
|
||||||
|
|
||||||
|
m_token.token[ idx++ ] = m_localeDecimalSeparator;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_token.token[ idx++ ] = ch;
|
||||||
|
}
|
||||||
|
|
||||||
ch = m_token.input[ ++m_token.pos ];
|
ch = m_token.input[ ++m_token.pos ];
|
||||||
} while( isdigit( ch ) || isDecimalSeparator( ch ) );
|
} while( isdigit( ch ) || isDecimalSeparator( ch ) );
|
||||||
|
|
||||||
m_token.token[ idx ] = 0;
|
m_token.token[ idx ] = 0;
|
||||||
|
|
||||||
// Ensure that the systems decimal separator is used
|
|
||||||
for( int i = strlen( m_token.token ); i; i-- )
|
|
||||||
{
|
|
||||||
if( isDecimalSeparator( m_token.token[ i - 1 ] ) )
|
|
||||||
m_token.token[ i - 1 ] = m_localeDecimalSeparator;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Lamda: Get unit for current token.
|
// Lamda: Get unit for current token.
|
||||||
// Valid units are ", in, mm, mil and thou. Returns Unit::Invalid otherwise.
|
// Valid units are ", in, mm, mil and thou. Returns Unit::Invalid otherwise.
|
||||||
auto checkUnit =
|
auto checkUnit =
|
||||||
[this]() -> Unit
|
[&]( double* siScaler ) -> Unit
|
||||||
{
|
{
|
||||||
char ch = m_token.input[ m_token.pos ];
|
char ch = m_token.input[ m_token.pos ];
|
||||||
|
|
||||||
|
@ -289,6 +325,13 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
|
||||||
return Unit::Mil;
|
return Unit::Mil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_defaultUnits == Unit::SI && sizeLeft >= 1
|
||||||
|
&& isOldSchoolDecimalSeparator( ch, siScaler ) )
|
||||||
|
{
|
||||||
|
m_token.pos++;
|
||||||
|
return Unit::SI;
|
||||||
|
}
|
||||||
|
|
||||||
return Unit::Invalid;
|
return Unit::Invalid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -305,20 +348,21 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double siScaler;
|
||||||
Unit convertFrom;
|
Unit convertFrom;
|
||||||
|
|
||||||
if( ch == 0 )
|
if( ch == 0 )
|
||||||
{
|
{
|
||||||
/* End of input */
|
/* End of input */
|
||||||
}
|
}
|
||||||
else if( isdigit( ch ) || isDecimalSeparator( ch ))
|
else if( isdigit( ch ) || isDecimalSeparator( ch ) )
|
||||||
{
|
{
|
||||||
// VALUE
|
// VALUE
|
||||||
extractNumber();
|
extractNumber( &siScaler );
|
||||||
retval.token = VALUE;
|
retval.token = VALUE;
|
||||||
retval.value.dValue = atof( m_token.token );
|
retval.value.dValue = atof( m_token.token ) * siScaler;
|
||||||
}
|
}
|
||||||
else if( ( convertFrom = checkUnit() ) != Unit::Invalid )
|
else if( ( convertFrom = checkUnit( &siScaler ) ) != Unit::Invalid )
|
||||||
{
|
{
|
||||||
// UNIT
|
// UNIT
|
||||||
// Units are appended to a VALUE.
|
// Units are appended to a VALUE.
|
||||||
|
@ -368,6 +412,10 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
|
||||||
{
|
{
|
||||||
retval.value.dValue = 1.0;
|
retval.value.dValue = 1.0;
|
||||||
}
|
}
|
||||||
|
else if( m_defaultUnits == Unit::SI )
|
||||||
|
{
|
||||||
|
retval.value.dValue = siScaler;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( isalpha( ch ) )
|
else if( isalpha( ch ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -243,6 +243,10 @@ template <typename T>
|
||||||
bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
|
bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
|
||||||
{
|
{
|
||||||
m_pinAssignmentsGrid->CommitPendingChanges();
|
m_pinAssignmentsGrid->CommitPendingChanges();
|
||||||
|
|
||||||
|
// This should have been done in wxPGTextCtrlEditor::OnTextCtrlEvent(), but something must
|
||||||
|
// be clearing it before we get here, resulting in CommitChangesFromEditor() doing nothing
|
||||||
|
m_paramGrid->GetGrid()->EditorsValueWasModified();
|
||||||
m_paramGrid->GetGrid()->CommitChangesFromEditor();
|
m_paramGrid->GetGrid()->CommitChangesFromEditor();
|
||||||
|
|
||||||
if( !DIALOG_SIM_MODEL_BASE::TransferDataFromWindow() )
|
if( !DIALOG_SIM_MODEL_BASE::TransferDataFromWindow() )
|
||||||
|
@ -277,12 +281,14 @@ bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
|
||||||
SIM_MODEL::SetFieldValue(
|
SIM_MODEL::SetFieldValue(
|
||||||
m_fields, SIM_LIBRARY_KIBIS::PIN_FIELD,
|
m_fields, SIM_LIBRARY_KIBIS::PIN_FIELD,
|
||||||
kibismodel->GetIbisPins().at( m_ibisPinCombobox->GetSelection() ).first );
|
kibismodel->GetIbisPins().at( m_ibisPinCombobox->GetSelection() ).first );
|
||||||
SIM_MODEL::SetFieldValue( m_fields, SIM_LIBRARY_KIBIS::MODEL_FIELD,
|
|
||||||
|
SIM_MODEL::SetFieldValue(
|
||||||
|
m_fields, SIM_LIBRARY_KIBIS::MODEL_FIELD,
|
||||||
std::string( m_ibisModelCombobox->GetValue().c_str() ) );
|
std::string( m_ibisModelCombobox->GetValue().c_str() ) );
|
||||||
|
|
||||||
SIM_MODEL::SetFieldValue(
|
SIM_MODEL::SetFieldValue(
|
||||||
m_fields, SIM_LIBRARY_KIBIS::DIFF_FIELD,
|
m_fields, SIM_LIBRARY_KIBIS::DIFF_FIELD,
|
||||||
( kibismodel->CanDifferential() && m_differentialCheckbox->GetValue() ) ? "1"
|
( kibismodel->CanDifferential() && m_differentialCheckbox->GetValue() ) ? "1" : "" );
|
||||||
: "" );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,13 +650,14 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForce
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::string modelName = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD );
|
std::string modelName = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD );
|
||||||
|
int pinCount = m_symbol.GetRawPins().size();
|
||||||
|
|
||||||
for( auto& [baseModelName, baseModel] : library()->GetModels() )
|
for( auto& [baseModelName, baseModel] : library()->GetModels() )
|
||||||
{
|
{
|
||||||
if( baseModelName == modelName )
|
if( baseModelName == modelName )
|
||||||
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetRawPins().size(), m_fields );
|
m_libraryModelsMgr.CreateModel( baseModel, pinCount, m_fields );
|
||||||
else
|
else
|
||||||
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetRawPins().size() );
|
m_libraryModelsMgr.CreateModel( baseModel, pinCount );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
|
@ -800,7 +807,7 @@ wxPGProperty* DIALOG_SIM_MODEL<T>::newParamProperty( int aParamIndex ) const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prop = new SIM_ENUM_PROPERTY( paramDescription, param.info.name, curModel(),
|
prop = new SIM_ENUM_PROPERTY( paramDescription, param.info.name, curModel(),
|
||||||
aParamIndex, SIM_VALUE::TYPE_STRING );
|
aParamIndex );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -939,32 +946,6 @@ int DIALOG_SIM_MODEL<T>::getModelPinIndex( const wxString& aModelPinString ) con
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void DIALOG_SIM_MODEL<T>::onKeyDown( wxKeyEvent& aEvent )
|
|
||||||
{
|
|
||||||
// Because wxPropertyGrid has special handling for the tab key, wxPropertyGrid::DedicateKey()
|
|
||||||
// and wxPropertyGrid::AddActionTrigger() don't work for it. So instead we translate it to an
|
|
||||||
// (up or down) arrow key, which has proper handling (select next or previous property) defined
|
|
||||||
// by the aforementioned functions.
|
|
||||||
|
|
||||||
if( aEvent.GetKeyCode() == WXK_TAB )
|
|
||||||
{
|
|
||||||
wxWindow* focus = FindFocus();
|
|
||||||
wxPropertyGrid* pg = focus ? dynamic_cast<wxPropertyGrid*>( focus->GetParent() ) : nullptr;
|
|
||||||
|
|
||||||
if( pg )
|
|
||||||
{
|
|
||||||
pg->CommitChangesFromEditor();
|
|
||||||
|
|
||||||
aEvent.m_keyCode = aEvent.ShiftDown() ? WXK_UP : WXK_DOWN;
|
|
||||||
aEvent.m_shiftDown = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aEvent.Skip();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void DIALOG_SIM_MODEL<T>::onRadioButton( wxCommandEvent& aEvent )
|
void DIALOG_SIM_MODEL<T>::onRadioButton( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
|
@ -1187,8 +1168,7 @@ void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
|
||||||
m_libraryModelsMgr.GetModels().at( m_modelNameCombobox->GetSelection() ).get() );
|
m_libraryModelsMgr.GetModels().at( m_modelNameCombobox->GetSelection() ).get() );
|
||||||
|
|
||||||
m_libraryModelsMgr.SetModel( m_modelNameCombobox->GetSelection(),
|
m_libraryModelsMgr.SetModel( m_modelNameCombobox->GetSelection(),
|
||||||
std::make_unique<SIM_MODEL_KIBIS>( type,
|
std::make_unique<SIM_MODEL_KIBIS>( type, kibisModel,
|
||||||
kibisModel,
|
|
||||||
m_fields ) );
|
m_fields ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,6 @@ private:
|
||||||
wxString getModelPinString( int aModelPinIndex ) const;
|
wxString getModelPinString( int aModelPinIndex ) const;
|
||||||
int getModelPinIndex( const wxString& aModelPinString ) const;
|
int getModelPinIndex( const wxString& aModelPinString ) const;
|
||||||
|
|
||||||
void onKeyDown( wxKeyEvent& aEvent ) override;
|
|
||||||
void onRadioButton( wxCommandEvent& aEvent ) override;
|
void onRadioButton( wxCommandEvent& aEvent ) override;
|
||||||
void onLibraryPathTextEnter( wxCommandEvent& aEvent ) override;
|
void onLibraryPathTextEnter( wxCommandEvent& aEvent ) override;
|
||||||
void onLibraryPathTextKillFocus( wxFocusEvent& aEvent ) override;
|
void onLibraryPathTextKillFocus( wxFocusEvent& aEvent ) override;
|
||||||
|
|
|
@ -197,6 +197,9 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
|
||||||
bSizerMargins->Add( m_saveInValueCheckbox, 0, wxALL, 6 );
|
bSizerMargins->Add( m_saveInValueCheckbox, 0, wxALL, 6 );
|
||||||
|
|
||||||
|
|
||||||
|
bSizerMargins->Add( 0, 3, 0, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
bSizerPanel->Add( bSizerMargins, 1, wxEXPAND, 5 );
|
bSizerPanel->Add( bSizerMargins, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
@ -244,7 +247,7 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
|
||||||
bSizer10->Fit( m_pinAssignmentsPanel );
|
bSizer10->Fit( m_pinAssignmentsPanel );
|
||||||
m_notebook->AddPage( m_pinAssignmentsPanel, _("Pin Assignments"), false );
|
m_notebook->AddPage( m_pinAssignmentsPanel, _("Pin Assignments"), false );
|
||||||
|
|
||||||
bSizer8->Add( m_notebook, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
|
bSizer8->Add( m_notebook, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
|
||||||
|
|
||||||
wxBoxSizer* bSizer81;
|
wxBoxSizer* bSizer81;
|
||||||
bSizer81 = new wxBoxSizer( wxHORIZONTAL );
|
bSizer81 = new wxBoxSizer( wxHORIZONTAL );
|
||||||
|
@ -275,7 +278,6 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
|
||||||
this->Centre( wxBOTH );
|
this->Centre( wxBOTH );
|
||||||
|
|
||||||
// Connect Events
|
// Connect Events
|
||||||
this->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_SIM_MODEL_BASE::onKeyDown ) );
|
|
||||||
m_useLibraryModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
|
m_useLibraryModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
|
||||||
m_pathLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this );
|
m_pathLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this );
|
||||||
m_libraryPathText->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this );
|
m_libraryPathText->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this );
|
||||||
|
@ -317,7 +319,6 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
|
||||||
DIALOG_SIM_MODEL_BASE::~DIALOG_SIM_MODEL_BASE()
|
DIALOG_SIM_MODEL_BASE::~DIALOG_SIM_MODEL_BASE()
|
||||||
{
|
{
|
||||||
// Disconnect Events
|
// Disconnect Events
|
||||||
this->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_SIM_MODEL_BASE::onKeyDown ) );
|
|
||||||
m_useLibraryModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
|
m_useLibraryModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
|
||||||
m_pathLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this );
|
m_pathLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this );
|
||||||
m_libraryPathText->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this );
|
m_libraryPathText->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this );
|
||||||
|
|
|
@ -56,7 +56,6 @@
|
||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
<property name="window_style"></property>
|
<property name="window_style"></property>
|
||||||
<event name="OnKeyDown">onKeyDown</event>
|
|
||||||
<object class="wxBoxSizer" expanded="1">
|
<object class="wxBoxSizer" expanded="1">
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="name">bSizer8</property>
|
<property name="name">bSizer8</property>
|
||||||
|
@ -64,7 +63,7 @@
|
||||||
<property name="permission">none</property>
|
<property name="permission">none</property>
|
||||||
<object class="sizeritem" expanded="1">
|
<object class="sizeritem" expanded="1">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
|
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
|
||||||
<property name="proportion">1</property>
|
<property name="proportion">1</property>
|
||||||
<object class="wxNotebook" expanded="1">
|
<object class="wxNotebook" expanded="1">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
|
@ -1519,11 +1518,11 @@
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="notebookpage" expanded="0">
|
<object class="notebookpage" expanded="1">
|
||||||
<property name="bitmap"></property>
|
<property name="bitmap"></property>
|
||||||
<property name="label">Code</property>
|
<property name="label">Code</property>
|
||||||
<property name="select">0</property>
|
<property name="select">0</property>
|
||||||
<object class="wxPanel" expanded="0">
|
<object class="wxPanel" expanded="1">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
<property name="LeftDockable">1</property>
|
<property name="LeftDockable">1</property>
|
||||||
<property name="RightDockable">1</property>
|
<property name="RightDockable">1</property>
|
||||||
|
@ -1574,7 +1573,7 @@
|
||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
<property name="window_style">wxTAB_TRAVERSAL</property>
|
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||||
<object class="wxBoxSizer" expanded="0">
|
<object class="wxBoxSizer" expanded="1">
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="name">bSizer5</property>
|
<property name="name">bSizer5</property>
|
||||||
<property name="orient">wxVERTICAL</property>
|
<property name="orient">wxVERTICAL</property>
|
||||||
|
@ -1717,6 +1716,16 @@
|
||||||
<event name="OnCheckBox">onSaveInValueCheckbox</event>
|
<event name="OnCheckBox">onSaveInValueCheckbox</event>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxEXPAND</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="spacer" expanded="1">
|
||||||
|
<property name="height">3</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="width">0</property>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
|
|
@ -84,7 +84,6 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
|
||||||
wxButton* m_sdbSizer1Cancel;
|
wxButton* m_sdbSizer1Cancel;
|
||||||
|
|
||||||
// Virtual event handlers, override them in your derived class
|
// Virtual event handlers, override them in your derived class
|
||||||
virtual void onKeyDown( wxKeyEvent& event ) { event.Skip(); }
|
|
||||||
virtual void onRadioButton( wxCommandEvent& event ) { event.Skip(); }
|
virtual void onRadioButton( wxCommandEvent& event ) { event.Skip(); }
|
||||||
virtual void onLibraryPathLabelUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
virtual void onLibraryPathLabelUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||||
virtual void onLibraryPathTextKillFocus( wxFocusEvent& event ) { event.Skip(); }
|
virtual void onLibraryPathTextKillFocus( wxFocusEvent& event ) { event.Skip(); }
|
||||||
|
|
|
@ -217,11 +217,16 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||||
|
|
||||||
SPICE_ITEM spiceItem;
|
SPICE_ITEM spiceItem;
|
||||||
|
|
||||||
// This is a little bit dangerous as any value fetched from the fields will not
|
for( int i = 0; i < symbol->GetFieldCount(); ++i )
|
||||||
// be instance-data aware, and will just fetch the value of some random sheet
|
{
|
||||||
// (whatever sheet the user happens to be looking at). However, we currently only
|
spiceItem.fields.emplace_back( VECTOR2I(), i, symbol,
|
||||||
// use it to fetch "Sim_*" fields, which have no instance data.
|
symbol->GetFields()[ i ].GetName() );
|
||||||
spiceItem.fields = &symbol->GetFields();
|
|
||||||
|
if( i == REFERENCE_FIELD )
|
||||||
|
spiceItem.fields.back().SetText( symbol->GetRef( &sheet ) );
|
||||||
|
else
|
||||||
|
spiceItem.fields.back().SetText( symbol->GetFields()[i].GetShownText( 0, false ) );
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -371,7 +376,7 @@ bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aS
|
||||||
void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol,
|
void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol,
|
||||||
SPICE_ITEM& aItem )
|
SPICE_ITEM& aItem )
|
||||||
{
|
{
|
||||||
SIM_LIBRARY::MODEL libModel = m_libMgr.CreateModel( aSymbol );
|
SIM_LIBRARY::MODEL libModel = m_libMgr.CreateModel( &aSheet, aSymbol );
|
||||||
|
|
||||||
aItem.baseModelName = libModel.name;
|
aItem.baseModelName = libModel.name;
|
||||||
aItem.model = &libModel.model;
|
aItem.model = &libModel.model;
|
||||||
|
|
|
@ -210,7 +210,12 @@ public:
|
||||||
class IbisComponentPin : public IBIS_INPUT
|
class IbisComponentPin : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IbisComponentPin( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
IbisComponentPin( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
|
virtual ~IbisComponentPin()
|
||||||
|
{};
|
||||||
|
|
||||||
std::string m_pinName;
|
std::string m_pinName;
|
||||||
std::string m_signalName;
|
std::string m_signalName;
|
||||||
|
@ -232,7 +237,13 @@ public:
|
||||||
class IbisComponentPinMapping : public IBIS_INPUT
|
class IbisComponentPinMapping : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IbisComponentPinMapping( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
IbisComponentPinMapping( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
|
virtual ~IbisComponentPinMapping()
|
||||||
|
{};
|
||||||
|
|
||||||
std::string m_pinName;
|
std::string m_pinName;
|
||||||
std::string m_PDref;
|
std::string m_PDref;
|
||||||
std::string m_PUref;
|
std::string m_PUref;
|
||||||
|
@ -247,7 +258,13 @@ public:
|
||||||
class IbisDiffPinEntry : public IBIS_INPUT
|
class IbisDiffPinEntry : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IbisDiffPinEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), tdelay( aReporter ){};
|
IbisDiffPinEntry( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter ),
|
||||||
|
tdelay( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
|
virtual ~IbisDiffPinEntry()
|
||||||
|
{};
|
||||||
|
|
||||||
std::string pinA;
|
std::string pinA;
|
||||||
std::string pinB;
|
std::string pinB;
|
||||||
|
@ -259,7 +276,10 @@ public:
|
||||||
class IbisDiffPin : IBIS_INPUT
|
class IbisDiffPin : IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IbisDiffPin( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
IbisDiffPin( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
std::vector<IbisDiffPinEntry> m_entries;
|
std::vector<IbisDiffPinEntry> m_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -272,6 +292,9 @@ public:
|
||||||
m_diffPin( aReporter )
|
m_diffPin( aReporter )
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
virtual ~IbisComponent()
|
||||||
|
{};
|
||||||
|
|
||||||
std::string m_name = "";
|
std::string m_name = "";
|
||||||
std::string m_manufacturer = "";
|
std::string m_manufacturer = "";
|
||||||
IbisComponentPackage m_package;
|
IbisComponentPackage m_package;
|
||||||
|
@ -297,7 +320,13 @@ public:
|
||||||
class IbisModelSelector : public IBIS_INPUT
|
class IbisModelSelector : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IbisModelSelector( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
IbisModelSelector( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
|
virtual ~IbisModelSelector()
|
||||||
|
{};
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::vector<IbisModelSelectorEntry> m_models;
|
std::vector<IbisModelSelectorEntry> m_models;
|
||||||
|
|
||||||
|
@ -308,7 +337,14 @@ public:
|
||||||
class IVtableEntry : public IBIS_INPUT
|
class IVtableEntry : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IVtableEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), I( aReporter ){};
|
IVtableEntry( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter ),
|
||||||
|
I( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
|
virtual ~IVtableEntry()
|
||||||
|
{};
|
||||||
|
|
||||||
double V = 0;
|
double V = 0;
|
||||||
TypMinMaxValue I;
|
TypMinMaxValue I;
|
||||||
};
|
};
|
||||||
|
@ -317,7 +353,10 @@ public:
|
||||||
class IVtable : public IBIS_INPUT
|
class IVtable : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IVtable( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
IVtable( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
std::vector<IVtableEntry> m_entries;
|
std::vector<IVtableEntry> m_entries;
|
||||||
|
|
||||||
bool Check() override;
|
bool Check() override;
|
||||||
|
@ -353,7 +392,14 @@ private:
|
||||||
class VTtableEntry : public IBIS_INPUT
|
class VTtableEntry : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VTtableEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), V( aReporter ){};
|
VTtableEntry( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter ),
|
||||||
|
V( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
|
virtual ~VTtableEntry()
|
||||||
|
{};
|
||||||
|
|
||||||
double t = 0;
|
double t = 0;
|
||||||
TypMinMaxValue V = 0;
|
TypMinMaxValue V = 0;
|
||||||
};
|
};
|
||||||
|
@ -361,7 +407,10 @@ public:
|
||||||
class VTtable : public IBIS_INPUT
|
class VTtable : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VTtable( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
VTtable( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
std::vector<VTtableEntry> m_entries;
|
std::vector<VTtableEntry> m_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -468,7 +517,8 @@ enum class IBIS_MODEL_POLARITY
|
||||||
class IbisModel : IBIS_INPUT
|
class IbisModel : IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IbisModel( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ),
|
IbisModel( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter ),
|
||||||
m_C_comp( aReporter ),
|
m_C_comp( aReporter ),
|
||||||
m_voltageRange( aReporter ),
|
m_voltageRange( aReporter ),
|
||||||
m_temperatureRange( aReporter ),
|
m_temperatureRange( aReporter ),
|
||||||
|
@ -487,6 +537,9 @@ public:
|
||||||
m_ramp( aReporter )
|
m_ramp( aReporter )
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
virtual ~IbisModel()
|
||||||
|
{};
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
IBIS_MODEL_TYPE m_type = IBIS_MODEL_TYPE::UNDEFINED;
|
IBIS_MODEL_TYPE m_type = IBIS_MODEL_TYPE::UNDEFINED;
|
||||||
/* The Polarity, Enable, Vinl, Vinh, Vmeas, Cref, Rref, and Vref subparameters are optional. */
|
/* The Polarity, Enable, Vinl, Vinh, Vmeas, Cref, Rref, and Vref subparameters are optional. */
|
||||||
|
@ -527,7 +580,12 @@ public:
|
||||||
class IbisPackageModel : public IBIS_INPUT
|
class IbisPackageModel : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IbisPackageModel( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
IbisPackageModel( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
|
virtual ~IbisPackageModel()
|
||||||
|
{};
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::string m_manufacturer;
|
std::string m_manufacturer;
|
||||||
|
@ -546,7 +604,13 @@ public:
|
||||||
class IbisFile : public IBIS_INPUT
|
class IbisFile : public IBIS_INPUT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IbisFile( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), m_header( aReporter ){};
|
IbisFile( IBIS_REPORTER* aReporter ) :
|
||||||
|
IBIS_INPUT( aReporter ),
|
||||||
|
m_header( aReporter )
|
||||||
|
{};
|
||||||
|
|
||||||
|
virtual ~IbisFile()
|
||||||
|
{};
|
||||||
|
|
||||||
IbisHeader m_header;
|
IbisHeader m_header;
|
||||||
std::vector<IbisComponent> m_components;
|
std::vector<IbisComponent> m_components;
|
||||||
|
|
|
@ -95,9 +95,21 @@ template SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int a
|
||||||
const std::vector<LIB_FIELD>& aFields );
|
const std::vector<LIB_FIELD>& aFields );
|
||||||
|
|
||||||
|
|
||||||
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol )
|
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, SCH_SYMBOL& aSymbol )
|
||||||
{
|
{
|
||||||
return CreateModel( aSymbol.GetFields(), static_cast<int>( aSymbol.GetRawPins().size() ) );
|
std::vector<SCH_FIELD> fields;
|
||||||
|
|
||||||
|
for( int i = 0; i < aSymbol.GetFieldCount(); ++i )
|
||||||
|
{
|
||||||
|
fields.emplace_back( VECTOR2I(), i, &aSymbol, aSymbol.GetFields()[ i ].GetName() );
|
||||||
|
|
||||||
|
if( i == REFERENCE_FIELD )
|
||||||
|
fields.back().SetText( aSymbol.GetRef( aSheetPath ) );
|
||||||
|
else
|
||||||
|
fields.back().SetText( aSymbol.GetFields()[ i ].GetShownText( 0, false ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateModel( fields, static_cast<int>( aSymbol.GetRawPins().size() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -154,8 +166,8 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::string& aLibraryPath,
|
||||||
|
|
||||||
if( !baseModel )
|
if( !baseModel )
|
||||||
{
|
{
|
||||||
THROW_IO_ERROR(
|
THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model: could not find "
|
||||||
wxString::Format( _( "Error loading simulation model: could not find base model '%s' in library '%s'" ),
|
"base model '%s' in library '%s'" ),
|
||||||
aBaseModelName,
|
aBaseModelName,
|
||||||
absolutePath ) );
|
absolutePath ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
const std::vector<T>& aFields );
|
const std::vector<T>& aFields );
|
||||||
|
|
||||||
// TODO: The argument can be made const.
|
// TODO: The argument can be made const.
|
||||||
SIM_LIBRARY::MODEL CreateModel( SCH_SYMBOL& aSymbol );
|
SIM_LIBRARY::MODEL CreateModel( const SCH_SHEET_PATH* aSheetPath, SCH_SYMBOL& aSymbol );
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SIM_LIBRARY::MODEL CreateModel( const std::vector<T>& aFields, int aSymbolPinCount );
|
SIM_LIBRARY::MODEL CreateModel( const std::vector<T>& aFields, int aSymbolPinCount );
|
||||||
|
|
|
@ -499,8 +499,7 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, unsigned aSymbolPinCou
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount )
|
||||||
unsigned aSymbolPinCount )
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<SIM_MODEL> model = Create( aBaseModel.GetType() );
|
std::unique_ptr<SIM_MODEL> model = Create( aBaseModel.GetType() );
|
||||||
|
|
||||||
|
|
|
@ -395,9 +395,9 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static TYPE InferTypeFromLegacyFields( const std::vector<T>& aFields );
|
static TYPE InferTypeFromLegacyFields( const std::vector<T>& aFields );
|
||||||
|
|
||||||
|
|
||||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, unsigned aSymbolPinCount );
|
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, unsigned aSymbolPinCount );
|
||||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel,
|
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount );
|
||||||
unsigned aSymbolPinCount );
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
||||||
|
|
|
@ -61,11 +61,11 @@ std::vector<std::string> SPICE_GENERATOR_KIBIS::CurrentNames( const SPICE_ITEM&
|
||||||
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const std::string aCwd,
|
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const std::string aCwd,
|
||||||
const std::string aCacheDir ) const
|
const std::string aCacheDir ) const
|
||||||
{
|
{
|
||||||
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::LIBRARY_FIELD );
|
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY::LIBRARY_FIELD );
|
||||||
std::string ibisCompName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::NAME_FIELD );
|
std::string ibisCompName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY::NAME_FIELD );
|
||||||
std::string ibisPinName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::PIN_FIELD );
|
std::string ibisPinName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::PIN_FIELD );
|
||||||
std::string ibisModelName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::MODEL_FIELD );
|
std::string ibisModelName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::MODEL_FIELD );
|
||||||
bool diffMode = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
bool diffMode = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
||||||
|
|
||||||
wxFileName libPath = wxFileName( wxString( ibisLibFilename ) );
|
wxFileName libPath = wxFileName( wxString( ibisLibFilename ) );
|
||||||
|
|
||||||
|
@ -77,8 +77,7 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const st
|
||||||
|
|
||||||
if( !kibis.m_valid )
|
if( !kibis.m_valid )
|
||||||
{
|
{
|
||||||
THROW_IO_ERROR( wxString::Format( _( "Invalid IBIS file '%s'" ),
|
THROW_IO_ERROR( wxString::Format( _( "Invalid IBIS file '%s'" ), ibisLibFilename ) );
|
||||||
ibisLibFilename ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KIBIS_COMPONENT* kcomp = kibis.GetComponent( std::string( ibisCompName ) );
|
KIBIS_COMPONENT* kcomp = kibis.GetComponent( std::string( ibisCompName ) );
|
||||||
|
@ -267,7 +266,8 @@ void SIM_MODEL_KIBIS::SwitchSingleEndedDiff( bool aDiff )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource ) : SIM_MODEL_KIBIS( aType )
|
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource ) :
|
||||||
|
SIM_MODEL_KIBIS( aType )
|
||||||
{
|
{
|
||||||
for( PARAM& param1 : m_params )
|
for( PARAM& param1 : m_params )
|
||||||
{
|
{
|
||||||
|
|
|
@ -592,6 +592,7 @@ void SIM_PLOT_FRAME::AddTuner( SCH_SYMBOL* aSymbol )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SIM_PLOT_FRAME::UpdateTunerValue( SCH_SYMBOL* aSymbol, const wxString& aValue )
|
void SIM_PLOT_FRAME::UpdateTunerValue( SCH_SYMBOL* aSymbol, const wxString& aValue )
|
||||||
{
|
{
|
||||||
for( EDA_ITEM* item : m_schematicFrame->GetScreen()->Items().OfType( SCH_SYMBOL_T ) )
|
for( EDA_ITEM* item : m_schematicFrame->GetScreen()->Items().OfType( SCH_SYMBOL_T ) )
|
||||||
|
@ -599,7 +600,8 @@ void SIM_PLOT_FRAME::UpdateTunerValue( SCH_SYMBOL* aSymbol, const wxString& aVal
|
||||||
if( item == aSymbol )
|
if( item == aSymbol )
|
||||||
{
|
{
|
||||||
SIM_LIB_MGR mgr( Prj() );
|
SIM_LIB_MGR mgr( Prj() );
|
||||||
SIM_MODEL& model = mgr.CreateModel( *aSymbol ).model;
|
SIM_MODEL& model = mgr.CreateModel( &m_schematicFrame->GetCurrentSheet(),
|
||||||
|
*aSymbol ).model;
|
||||||
|
|
||||||
const SIM_MODEL::PARAM* tunerParam = model.GetTunerParam();
|
const SIM_MODEL::PARAM* tunerParam = model.GetTunerParam();
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <confirm.h>
|
|
||||||
#include <wx/combo.h>
|
#include <wx/combo.h>
|
||||||
#include <wx/combobox.h>
|
|
||||||
#include <wx/notebook.h>
|
|
||||||
|
|
||||||
// Include simulator headers after wxWidgets headers to avoid conflicts with Windows headers
|
// Include simulator headers after wxWidgets headers to avoid conflicts with Windows headers
|
||||||
// (especially on msys2 + wxWidgets 3.0.x)
|
// (especially on msys2 + wxWidgets 3.0.x)
|
||||||
|
@ -34,229 +31,11 @@
|
||||||
#include <ki_exception.h>
|
#include <ki_exception.h>
|
||||||
|
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE( SIM_VALIDATOR, wxValidator )
|
|
||||||
EVT_KEY_DOWN( SIM_VALIDATOR::onKeyDown )
|
|
||||||
wxEND_EVENT_TABLE()
|
|
||||||
|
|
||||||
|
|
||||||
void SIM_VALIDATOR::navigate( int flags )
|
|
||||||
{
|
|
||||||
wxWindow* textCtrl = GetWindow();
|
|
||||||
if( !textCtrl )
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxPropertyGrid* paramGrid = dynamic_cast<wxPropertyGrid*>( textCtrl->GetParent() );
|
|
||||||
if( !paramGrid )
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxPropertyGridManager* paramGridMgr =
|
|
||||||
dynamic_cast<wxPropertyGridManager*>( paramGrid->GetParent() );
|
|
||||||
if( !paramGridMgr )
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
|
||||||
// Workaround for wxWindow::Navigate() working differently on GTK. Same workaround is
|
|
||||||
// in the WxWidgets source code.
|
|
||||||
if( flags == wxNavigationKeyEvent::IsBackward )
|
|
||||||
{
|
|
||||||
if( wxWindow* sibling = paramGridMgr->GetPrevSibling() )
|
|
||||||
{
|
|
||||||
sibling->SetFocusFromKbd();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( flags == wxNavigationKeyEvent::IsForward )
|
|
||||||
{
|
|
||||||
if( wxWindow* sibling = paramGridMgr->GetNextSibling() )
|
|
||||||
{
|
|
||||||
sibling->SetFocusFromKbd();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We didn't find the sibling, so instead we try another workaround by by finding the notebook
|
|
||||||
// we are in, and jumping out of it.
|
|
||||||
for( wxWindow* window = paramGridMgr; window; window = window->GetParent() )
|
|
||||||
{
|
|
||||||
if( wxNotebook* notebook = dynamic_cast<wxNotebook*>( window ) )
|
|
||||||
{
|
|
||||||
if( flags == wxNavigationKeyEvent::IsBackward )
|
|
||||||
{
|
|
||||||
for( wxWindow* sibling = notebook->GetNextSibling();
|
|
||||||
sibling;
|
|
||||||
sibling = sibling->GetNextSibling() )
|
|
||||||
{
|
|
||||||
if( sibling->IsFocusable() )
|
|
||||||
{
|
|
||||||
sibling->SetFocusFromKbd();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( flags == wxNavigationKeyEvent::IsForward )
|
|
||||||
{
|
|
||||||
for( wxWindow* sibling = notebook->GetNextSibling();
|
|
||||||
sibling;
|
|
||||||
sibling = sibling->GetNextSibling() )
|
|
||||||
{
|
|
||||||
if( sibling->IsFocusable() )
|
|
||||||
{
|
|
||||||
sibling->SetFocusFromKbd();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
paramGridMgr->Navigate( flags );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SIM_VALIDATOR::onKeyDown( wxKeyEvent& aEvent )
|
|
||||||
{
|
|
||||||
// Because wxPropertyGrid has special handling for the tab key, wxPropertyGrid::DedicateKey()
|
|
||||||
// and wxPropertyGrid::AddActionTrigger() don't work for it. So instead we translate it to an
|
|
||||||
// (up or down) arrow key, which has proper handling (select next or previous property) defined
|
|
||||||
// by the aforementioned functions.
|
|
||||||
|
|
||||||
if( aEvent.GetKeyCode() == WXK_TAB )
|
|
||||||
{
|
|
||||||
// However, before that, if this is the first or last property, we instead want to navigate
|
|
||||||
// to the next or previous widget.
|
|
||||||
wxWindow* textCtrl = GetWindow();
|
|
||||||
if( !textCtrl )
|
|
||||||
{
|
|
||||||
aEvent.Skip();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxPropertyGrid* paramGrid = dynamic_cast<wxPropertyGrid*>( textCtrl->GetParent() );
|
|
||||||
if( !paramGrid )
|
|
||||||
{
|
|
||||||
aEvent.Skip();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxPropertyGridIterator it = paramGrid->GetIterator( wxPG_ITERATE_VISIBLE,
|
|
||||||
paramGrid->GetSelection() );
|
|
||||||
if( !it.AtEnd() )
|
|
||||||
it.Next();
|
|
||||||
|
|
||||||
bool isFirst = paramGrid->GetSelection() == paramGrid->wxPropertyGridInterface::GetFirst();
|
|
||||||
bool isLast = it.AtEnd();
|
|
||||||
|
|
||||||
if( isFirst && aEvent.ShiftDown() )
|
|
||||||
{
|
|
||||||
navigate( wxNavigationKeyEvent::IsBackward );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( isLast && !aEvent.ShiftDown() )
|
|
||||||
{
|
|
||||||
navigate( wxNavigationKeyEvent::IsForward );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aEvent.GetModifiers() == wxMOD_SHIFT )
|
|
||||||
{
|
|
||||||
aEvent.m_shiftDown = false;
|
|
||||||
aEvent.m_keyCode = WXK_UP;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
aEvent.m_keyCode = WXK_DOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
aEvent.Skip();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE( SIM_BOOL_VALIDATOR, SIM_VALIDATOR )
|
|
||||||
wxEND_EVENT_TABLE()
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_BOOL_VALIDATOR::Validate( wxWindow* aParent )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SIM_STRING_VALIDATOR::SIM_STRING_VALIDATOR( SIM_VALUE::TYPE aValueType,
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
|
||||||
: SIM_VALIDATOR(),
|
|
||||||
m_valueType( aValueType ),
|
|
||||||
m_notation( aNotation )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxObject* SIM_STRING_VALIDATOR::Clone() const
|
|
||||||
{
|
|
||||||
return new SIM_STRING_VALIDATOR( *this );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_STRING_VALIDATOR::Validate( wxWindow* aParent )
|
|
||||||
{
|
|
||||||
if( !m_validatorWindow->IsEnabled() )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
wxTextEntry* const textEntry = getTextEntry();
|
|
||||||
|
|
||||||
if( !textEntry )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return isValid( textEntry->GetValue() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_STRING_VALIDATOR::TransferToWindow()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_STRING_VALIDATOR::TransferFromWindow()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_STRING_VALIDATOR::isValid( const wxString& aString )
|
|
||||||
{
|
|
||||||
return SIM_VALUE_GRAMMAR::IsValid( aString.ToStdString(), m_valueType, m_notation );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxTextEntry* SIM_STRING_VALIDATOR::getTextEntry()
|
|
||||||
{
|
|
||||||
if( !m_validatorWindow )
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// Taken from wxTextValidator.
|
|
||||||
|
|
||||||
if( wxDynamicCast( m_validatorWindow, wxTextCtrl ) )
|
|
||||||
return ( wxTextCtrl* ) m_validatorWindow;
|
|
||||||
|
|
||||||
if( wxDynamicCast( m_validatorWindow, wxComboBox ) )
|
|
||||||
return ( wxComboBox* ) m_validatorWindow;
|
|
||||||
|
|
||||||
if( wxDynamicCast( m_validatorWindow, wxComboCtrl ) )
|
|
||||||
return ( wxComboCtrl* ) m_validatorWindow;
|
|
||||||
|
|
||||||
wxFAIL_MSG(
|
|
||||||
"SIM_STRING_VALIDATOR can only be used with wxTextCtrl, wxComboBox, or wxComboCtrl"
|
|
||||||
);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SIM_PROPERTY::SIM_PROPERTY( SIM_MODEL& aModel, int aParamIndex ) :
|
SIM_PROPERTY::SIM_PROPERTY( SIM_MODEL& aModel, int aParamIndex ) :
|
||||||
m_model( aModel ),
|
m_model( aModel ),
|
||||||
m_paramIndex( aParamIndex ),
|
m_paramIndex( aParamIndex ),
|
||||||
|
m_needsEval( false ),
|
||||||
|
m_eval( EDA_UNITS::UNSCALED ),
|
||||||
m_disabled( false )
|
m_disabled( false )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -269,9 +48,8 @@ void SIM_PROPERTY::Disable()
|
||||||
|
|
||||||
|
|
||||||
SIM_BOOL_PROPERTY::SIM_BOOL_PROPERTY( const wxString& aLabel, const wxString& aName,
|
SIM_BOOL_PROPERTY::SIM_BOOL_PROPERTY( const wxString& aLabel, const wxString& aName,
|
||||||
SIM_MODEL& aModel,
|
SIM_MODEL& aModel, int aParamIndex ) :
|
||||||
int aParamIndex )
|
wxBoolProperty( aLabel, aName ),
|
||||||
: wxBoolProperty( aLabel, aName ),
|
|
||||||
SIM_PROPERTY( aModel, aParamIndex )
|
SIM_PROPERTY( aModel, aParamIndex )
|
||||||
{
|
{
|
||||||
auto simValue = dynamic_cast<SIM_VALUE_INST<bool>*>(
|
auto simValue = dynamic_cast<SIM_VALUE_INST<bool>*>(
|
||||||
|
@ -285,7 +63,7 @@ SIM_BOOL_PROPERTY::SIM_BOOL_PROPERTY( const wxString& aLabel, const wxString& aN
|
||||||
|
|
||||||
wxValidator* SIM_BOOL_PROPERTY::DoGetValidator() const
|
wxValidator* SIM_BOOL_PROPERTY::DoGetValidator() const
|
||||||
{
|
{
|
||||||
return new SIM_BOOL_VALIDATOR();
|
return new SIM_VALIDATOR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -309,11 +87,10 @@ void SIM_BOOL_PROPERTY::OnSetValue()
|
||||||
|
|
||||||
|
|
||||||
SIM_STRING_PROPERTY::SIM_STRING_PROPERTY( const wxString& aLabel, const wxString& aName,
|
SIM_STRING_PROPERTY::SIM_STRING_PROPERTY( const wxString& aLabel, const wxString& aName,
|
||||||
SIM_MODEL& aModel,
|
SIM_MODEL& aModel, int aParamIndex,
|
||||||
int aParamIndex,
|
|
||||||
SIM_VALUE::TYPE aValueType,
|
SIM_VALUE::TYPE aValueType,
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
SIM_VALUE_GRAMMAR::NOTATION aNotation ) :
|
||||||
: wxStringProperty( aLabel, aName ),
|
wxStringProperty( aLabel, aName ),
|
||||||
SIM_PROPERTY( aModel, aParamIndex ),
|
SIM_PROPERTY( aModel, aParamIndex ),
|
||||||
m_valueType( aValueType ),
|
m_valueType( aValueType ),
|
||||||
m_notation( aNotation )
|
m_notation( aNotation )
|
||||||
|
@ -322,9 +99,61 @@ SIM_STRING_PROPERTY::SIM_STRING_PROPERTY( const wxString& aLabel, const wxString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SIM_STRING_PROPERTY::OnEvent( wxPropertyGrid* propgrid, wxWindow* wnd_primary, wxEvent& event )
|
||||||
|
{
|
||||||
|
if( event.GetEventType() == wxEVT_SET_FOCUS )
|
||||||
|
{
|
||||||
|
wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wnd_primary );
|
||||||
|
|
||||||
|
if( textEntry )
|
||||||
|
{
|
||||||
|
wxString oldStr = m_eval.OriginalText();
|
||||||
|
|
||||||
|
if( oldStr.length() && oldStr != textEntry->GetValue() )
|
||||||
|
{
|
||||||
|
SetValueInEvent( oldStr );
|
||||||
|
textEntry->SetValue( oldStr );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_needsEval = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( event.GetEventType() == wxEVT_KILL_FOCUS )
|
||||||
|
{
|
||||||
|
wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wnd_primary );
|
||||||
|
|
||||||
|
if( textEntry && m_eval.Process( textEntry->GetValue() ) )
|
||||||
|
{
|
||||||
|
SetValueInEvent( m_eval.Result() );
|
||||||
|
m_needsEval = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( event.GetEventType() == wxEVT_KEY_DOWN )
|
||||||
|
{
|
||||||
|
wxKeyEvent& keyEvent = dynamic_cast<wxKeyEvent&>( event );
|
||||||
|
wxPropertyGrid* propGrid = dynamic_cast<wxPropertyGrid*>( wnd_primary->GetParent() );
|
||||||
|
|
||||||
|
if( propGrid )
|
||||||
|
{
|
||||||
|
if( keyEvent.GetKeyCode() == WXK_TAB )
|
||||||
|
{
|
||||||
|
propGrid->CommitChangesFromEditor();
|
||||||
|
|
||||||
|
keyEvent.m_keyCode = keyEvent.ShiftDown() ? WXK_UP : WXK_DOWN;
|
||||||
|
keyEvent.m_shiftDown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxValidator* SIM_STRING_PROPERTY::DoGetValidator() const
|
wxValidator* SIM_STRING_PROPERTY::DoGetValidator() const
|
||||||
{
|
{
|
||||||
return new SIM_STRING_VALIDATOR( m_valueType, m_notation );
|
return new SIM_VALIDATOR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -334,28 +163,18 @@ bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aT
|
||||||
if( m_disabled )
|
if( m_disabled )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wxString baseParamValue = m_model.GetBaseParam( m_paramIndex ).value->ToString();
|
wxString evaledText;
|
||||||
aVariant = aText;
|
|
||||||
|
|
||||||
// TODO: Don't use string comparison.
|
if( m_needsEval && m_eval.Process( aText ) )
|
||||||
if( m_model.GetBaseModel() && ( aText == "" || aText == baseParamValue ) )
|
evaledText = m_eval.Result();
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_model.SetParamValue( m_paramIndex, "" ); // Nullify.
|
|
||||||
}
|
|
||||||
catch( const IO_ERROR& )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
aVariant = baseParamValue; // Use the inherited value (if it exists) if null.
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
evaledText = aText;
|
||||||
m_model.SetParamValue( m_paramIndex, std::string( aText.ToUTF8() ) );
|
|
||||||
|
wxString baseParamValue = m_model.GetBaseParam( m_paramIndex ).value->ToString();
|
||||||
|
aVariant = evaledText;
|
||||||
|
|
||||||
|
m_model.SetParamValue( m_paramIndex, std::string( evaledText.ToUTF8() ) );
|
||||||
aVariant = GetParam().value->ToString();
|
aVariant = GetParam().value->ToString();
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -373,12 +192,8 @@ static wxArrayString convertStringsToWx( const std::vector<std::string>& aString
|
||||||
|
|
||||||
|
|
||||||
SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
|
SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
|
||||||
SIM_MODEL& aModel,
|
SIM_MODEL& aModel, int aParamIndex ) :
|
||||||
int aParamIndex,
|
wxEnumProperty( aLabel, aName, convertStringsToWx( aModel.GetParam( aParamIndex ).info.enumValues ) ),
|
||||||
SIM_VALUE::TYPE aValueType,
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
|
||||||
: wxEnumProperty( aLabel, aName,
|
|
||||||
convertStringsToWx( aModel.GetParam( aParamIndex ).info.enumValues ) ),
|
|
||||||
SIM_PROPERTY( aModel, aParamIndex )
|
SIM_PROPERTY( aModel, aParamIndex )
|
||||||
{
|
{
|
||||||
auto it = std::find( GetParam().info.enumValues.begin(), GetParam().info.enumValues.end(),
|
auto it = std::find( GetParam().info.enumValues.begin(), GetParam().info.enumValues.end(),
|
||||||
|
|
|
@ -31,51 +31,15 @@
|
||||||
#include <wx/propgrid/props.h>
|
#include <wx/propgrid/props.h>
|
||||||
|
|
||||||
#include <sim/sim_model.h>
|
#include <sim/sim_model.h>
|
||||||
|
#include "libeval/numeric_evaluator.h"
|
||||||
|
|
||||||
|
|
||||||
class SIM_VALIDATOR : public wxValidator
|
class SIM_VALIDATOR : public wxValidator
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
void navigate( int flags );
|
bool Validate( wxWindow* aParent ) override { return true; }
|
||||||
|
bool TransferToWindow() override { return true; }
|
||||||
void onKeyDown( wxKeyEvent& aEvent );
|
bool TransferFromWindow() override { return true; }
|
||||||
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SIM_STRING_VALIDATOR : public SIM_VALIDATOR
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SIM_STRING_VALIDATOR( SIM_VALUE::TYPE aValueType, SIM_VALUE_GRAMMAR::NOTATION aNotation );
|
|
||||||
SIM_STRING_VALIDATOR( const SIM_STRING_VALIDATOR& aValidator ) = default;
|
|
||||||
|
|
||||||
wxObject* Clone() const override;
|
|
||||||
|
|
||||||
bool Validate( wxWindow* aParent ) override;
|
|
||||||
bool TransferToWindow() override;
|
|
||||||
bool TransferFromWindow() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isValid( const wxString& aString );
|
|
||||||
|
|
||||||
wxTextEntry* getTextEntry();
|
|
||||||
|
|
||||||
SIM_VALUE::TYPE m_valueType;
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION m_notation;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SIM_BOOL_VALIDATOR : public SIM_VALIDATOR
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SIM_BOOL_VALIDATOR() : SIM_VALIDATOR() {}
|
|
||||||
SIM_BOOL_VALIDATOR( const SIM_BOOL_VALIDATOR& aValidator ) = default;
|
|
||||||
|
|
||||||
bool Validate( wxWindow* aParent ) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +55,11 @@ public:
|
||||||
protected:
|
protected:
|
||||||
SIM_MODEL& m_model;
|
SIM_MODEL& m_model;
|
||||||
int m_paramIndex;
|
int m_paramIndex;
|
||||||
bool m_disabled; // If true, never access the models.
|
|
||||||
|
bool m_needsEval;
|
||||||
|
mutable NUMERIC_EVALUATOR m_eval;
|
||||||
|
|
||||||
|
bool m_disabled; ///< If true, never access the models.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,6 +92,8 @@ public:
|
||||||
bool StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 )
|
bool StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 )
|
||||||
const override;
|
const override;
|
||||||
|
|
||||||
|
bool OnEvent( wxPropertyGrid* propgrid, wxWindow* wnd_primary, wxEvent& event ) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SIM_VALUE::TYPE m_valueType;
|
SIM_VALUE::TYPE m_valueType;
|
||||||
SIM_VALUE_GRAMMAR::NOTATION m_notation;
|
SIM_VALUE_GRAMMAR::NOTATION m_notation;
|
||||||
|
@ -133,11 +103,8 @@ protected:
|
||||||
class SIM_ENUM_PROPERTY : public wxEnumProperty, public SIM_PROPERTY
|
class SIM_ENUM_PROPERTY : public wxEnumProperty, public SIM_PROPERTY
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
|
SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName, SIM_MODEL& aModel,
|
||||||
SIM_MODEL& aModel,
|
int aParamIndex );
|
||||||
int aParamIndex,
|
|
||||||
SIM_VALUE::TYPE aValueType = SIM_VALUE::TYPE_FLOAT,
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI );
|
|
||||||
|
|
||||||
bool IntToValue( wxVariant& aVariant, int aNumber, int aArgFlags = 0 ) const override;
|
bool IntToValue( wxVariant& aVariant, int aNumber, int aArgFlags = 0 ) const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -482,7 +482,13 @@ bool SIM_VALUE_INT::FromString( const std::string& aString, NOTATION aNotation )
|
||||||
template <>
|
template <>
|
||||||
bool SIM_VALUE_FLOAT::FromString( const std::string& aString, NOTATION aNotation )
|
bool SIM_VALUE_FLOAT::FromString( const std::string& aString, NOTATION aNotation )
|
||||||
{
|
{
|
||||||
SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( aString, aNotation );
|
wxString buf( aString );
|
||||||
|
|
||||||
|
// Convert any entered decimal point separators to the one our PEGTL grammar expects
|
||||||
|
buf.Replace( wxT( "," ), wxT( "." ) );
|
||||||
|
|
||||||
|
SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( buf.ToStdString(),
|
||||||
|
aNotation );
|
||||||
m_value = std::nullopt;
|
m_value = std::nullopt;
|
||||||
|
|
||||||
if( !parseResult.isOk )
|
if( !parseResult.isOk )
|
||||||
|
@ -513,8 +519,7 @@ bool SIM_VALUE_FLOAT::FromString( const std::string& aString, NOTATION aNotation
|
||||||
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
bool SIM_VALUE_COMPLEX::FromString( const std::string& aString,
|
bool SIM_VALUE_COMPLEX::FromString( const std::string& aString, NOTATION aNotation )
|
||||||
NOTATION aNotation )
|
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct SPICE_ITEM
|
||||||
std::string baseModelName;
|
std::string baseModelName;
|
||||||
std::string modelName;
|
std::string modelName;
|
||||||
const SIM_MODEL* model = nullptr;
|
const SIM_MODEL* model = nullptr;
|
||||||
const std::vector<SCH_FIELD>* fields = nullptr;
|
std::vector<SCH_FIELD> fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,12 @@ class SIM_LIBRARY_SPICE;
|
||||||
class SPICE_LIBRARY_PARSER
|
class SPICE_LIBRARY_PARSER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SPICE_LIBRARY_PARSER( SIM_LIBRARY_SPICE& aLibrary ) : m_library( aLibrary ) {}
|
SPICE_LIBRARY_PARSER( SIM_LIBRARY_SPICE& aLibrary ) :
|
||||||
|
m_library( aLibrary )
|
||||||
|
{};
|
||||||
|
|
||||||
|
virtual ~SPICE_LIBRARY_PARSER()
|
||||||
|
{};
|
||||||
|
|
||||||
virtual void ReadFile( const std::string& aFilePath );
|
virtual void ReadFile( const std::string& aFilePath );
|
||||||
|
|
||||||
|
|
|
@ -866,6 +866,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
|
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
|
||||||
EDA_ITEM* item = selTool->GetNode( aPosition );
|
EDA_ITEM* item = selTool->GetNode( aPosition );
|
||||||
|
SCH_SHEET_PATH& sheet = m_frame->GetCurrentSheet();
|
||||||
|
|
||||||
if( !item )
|
if( !item )
|
||||||
return false;
|
return false;
|
||||||
|
@ -879,10 +880,10 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
std::vector<LIB_PIN*> pins = symbol->GetLibPins();
|
std::vector<LIB_PIN*> pins = symbol->GetLibPins();
|
||||||
|
|
||||||
SIM_LIB_MGR mgr( m_frame->Prj() );
|
SIM_LIB_MGR mgr( m_frame->Prj() );
|
||||||
SIM_MODEL& model = mgr.CreateModel( *symbol ).model;
|
SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol ).model;
|
||||||
|
|
||||||
SPICE_ITEM spiceItem;
|
SPICE_ITEM spiceItem;
|
||||||
spiceItem.refName = std::string( symbol->GetRef( &m_frame->GetCurrentSheet() ).ToUTF8() );
|
spiceItem.refName = std::string( symbol->GetRef( &sheet ).ToUTF8() );
|
||||||
std::vector<std::string> currentNames =
|
std::vector<std::string> currentNames =
|
||||||
model.SpiceGenerator().CurrentNames( spiceItem );
|
model.SpiceGenerator().CurrentNames( spiceItem );
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,6 @@ Supported units are millimeters (mm), Mil (mil) and inch (")
|
||||||
// This namespace is used for the lemon parser
|
// This namespace is used for the lemon parser
|
||||||
namespace numEval
|
namespace numEval
|
||||||
{
|
{
|
||||||
|
|
||||||
struct TokenType
|
struct TokenType
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
|
@ -93,7 +92,7 @@ namespace numEval
|
||||||
|
|
||||||
class NUMERIC_EVALUATOR
|
class NUMERIC_EVALUATOR
|
||||||
{
|
{
|
||||||
enum class Unit { Invalid, MM, CM, Inch, Mil, Degrees };
|
enum class Unit { Invalid, MM, CM, Inch, Mil, Degrees, SI };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NUMERIC_EVALUATOR( EDA_UNITS aUnits );
|
NUMERIC_EVALUATOR( EDA_UNITS aUnits );
|
||||||
|
@ -162,16 +161,19 @@ private:
|
||||||
struct TokenStat
|
struct TokenStat
|
||||||
{
|
{
|
||||||
TokenStat() :
|
TokenStat() :
|
||||||
input( nullptr ), token( nullptr ), inputLen( 0 ), outputLen( 0 ), pos( 0 )
|
input( nullptr ),
|
||||||
{ /* empty */ }
|
token( nullptr ),
|
||||||
|
inputLen( 0 ),
|
||||||
|
outputLen( 0 ),
|
||||||
|
pos( 0 )
|
||||||
|
{};
|
||||||
|
|
||||||
const char* input; // current input string ("var=4")
|
const char* input; // current input string ("var=4")
|
||||||
char* token; // output token ("var", type:VAR; "4", type:VALUE)
|
char* token; // output token ("var", type:VAR; "4", type:VALUE)
|
||||||
size_t inputLen; // strlen(input)
|
size_t inputLen; // strlen(input)
|
||||||
size_t outputLen; // At least 64, up to input length
|
size_t outputLen; // At least 64, up to input length
|
||||||
size_t pos; // current index
|
size_t pos; // current index
|
||||||
}
|
} m_token;
|
||||||
m_token;
|
|
||||||
|
|
||||||
char m_localeDecimalSeparator;
|
char m_localeDecimalSeparator;
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,10 @@
|
||||||
#include <string_utils.h>
|
#include <string_utils.h>
|
||||||
|
|
||||||
|
|
||||||
PCB_PROPERTIES_PANEL::PCB_PROPERTIES_PANEL( wxWindow* aParent, PCB_EDIT_FRAME* aFrame )
|
PCB_PROPERTIES_PANEL::PCB_PROPERTIES_PANEL( wxWindow* aParent, PCB_EDIT_FRAME* aFrame ) :
|
||||||
: PROPERTIES_PANEL( aParent, aFrame ), m_frame( aFrame ), m_propMgr( PROPERTY_MANAGER::Instance() )
|
PROPERTIES_PANEL( aParent, aFrame ),
|
||||||
|
m_frame( aFrame ),
|
||||||
|
m_propMgr( PROPERTY_MANAGER::Instance() )
|
||||||
{
|
{
|
||||||
m_propMgr.Rebuild();
|
m_propMgr.Rebuild();
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
Loading…
Reference in New Issue