35 #include <wx/textfile.h> 36 #include <wx/tokenzr.h> 37 #include <wx/wupdlock.h> 38 #include <wx/filedlg.h> 45 static bool empty(
const wxTextCtrl* aCtrl )
47 return aCtrl->GetValue().IsEmpty();
53 wxIntPtr WXUNUSED( aSortData ) )
55 float* t1 = reinterpret_cast<float*>( &aItem1 );
56 float* t2 = reinterpret_cast<float*>( &aItem2 );
81 {
SP_BJT,
_(
"BJT" ), {
"npn",
"pnp" } },
82 {
SP_MOSFET,
_(
"MOSFET" ), {
"nmos",
"pmos",
"vdmos" } },
83 {
SP_JFET,
_(
"JFET" ), {
"njf",
"pjf" } },
100 const char prim = std::toupper( aPrimitive );
102 for(
size_t i = 0; i <
modelTypes.size(); ++i )
115 m_libfields( nullptr ), m_useSchFields( true ),
116 m_spiceEmptyValidator( true ), m_notEmptyValidator( wxFILTER_EMPTY )
123 std::vector<LIB_FIELD>* aFields ) :
126 m_schfields( nullptr ),
127 m_libfields( aFields ),
128 m_useSchFields( false ),
129 m_spiceEmptyValidator( true ),
130 m_notEmptyValidator( wxFILTER_EMPTY )
246 if( !DIALOG_SPICE_MODEL_BASE::TransferDataFromWindow() )
249 wxWindow* page =
m_notebook->GetCurrentPage();
264 wxASSERT_MSG(
false,
"Unhandled passive type" );
278 if( modelIdx >= 0 && modelIdx < (
int)
modelTypes.size() )
298 wxASSERT_MSG(
false,
"Unhandled model type" );
306 for(
int i = 0; i <
SF_END; ++i )
318 const wxString& spiceField =
325 return f.
GetName() == spiceField;
332 return f.
GetName() == spiceField;
347 for(
unsigned int idx = 0; idx < spiceFields.size(); ++idx )
349 const wxString& spiceField = spiceFields[idx];
360 if( field.GetName() == spiceField && !field.GetText().IsEmpty() )
372 if( field.GetName() == spiceField && !field.GetText().IsEmpty() )
441 return DIALOG_SPICE_MODEL_BASE::TransferDataToWindow();
450 msg =
_(
"Symbol pin numbering don't always match the required SPICE pin order\n" 451 "Check the symbol and use \"Alternate node sequence\" to reorder the pins" 459 msg +=
_(
"For a Diode, pin order is anode, cathode" );
463 msg +=
_(
"For a BJT, pin order is collector, base, emitter, substrate (optional)" );
467 msg +=
_(
"For a MOSFET, pin order is drain, gate, source" );
471 msg +=
_(
"For a JFET, pin order is drain, gate, source" );
484 if( aModel.IsEmpty() )
487 wxStringTokenizer tokenizer( aModel,
" ()" );
488 wxString tkn = tokenizer.GetNextToken().Lower();
490 while( tokenizer.HasMoreTokens() )
493 bool genericProcessing =
false;
494 unsigned int genericReqParamsCount = 0;
495 std::vector<wxTextCtrl*> genericControls;
500 if( tkn ==
"dc" || tkn ==
"trans" )
501 tkn = tokenizer.GetNextToken().Lower();
513 else if( tkn ==
"ac" )
518 tkn = tokenizer.GetNextToken().Lower();
529 tkn = tokenizer.GetNextToken().Lower();
537 else if( tkn ==
"pulse" )
541 genericProcessing =
true;
542 genericReqParamsCount = 2;
546 else if( tkn ==
"sin" )
550 genericProcessing =
true;
551 genericReqParamsCount = 2;
555 else if( tkn ==
"exp" )
559 genericProcessing =
true;
560 genericReqParamsCount = 2;
564 else if( tkn ==
"pwl" )
570 while( tokenizer.HasMoreTokens() )
572 tkn = tokenizer.GetNextToken();
575 tkn = tokenizer.GetNextToken();
586 else if( tkn ==
"sffm" )
590 genericProcessing =
true;
591 genericReqParamsCount = 4;
595 else if( tkn ==
"am" )
599 genericProcessing =
true;
600 genericReqParamsCount = 5;
604 else if( tkn ==
"trrandom" )
609 if( !tokenizer.HasMoreTokens() )
612 tkn = tokenizer.GetNextToken().Lower();
614 if( !tkn.ToLong( &type ) )
618 wxCommandEvent
dummy;
622 genericProcessing =
true;
623 genericReqParamsCount = 4;
629 wxASSERT_MSG(
false,
"Unhandled power source type" );
633 if( genericProcessing )
637 for(
unsigned int i = 0; i < genericControls.size(); ++i )
640 if( !tokenizer.HasMoreTokens() )
641 return ( i >= genericReqParamsCount );
643 tkn = tokenizer.GetNextToken().Lower();
644 genericControls[i]->SetValue(
SPICE_VALUE( tkn ).ToSpiceString() );
655 tkn = tokenizer.GetNextToken().Lower();
664 wxString acdc, trans;
666 bool useTrans =
true;
669 bool genericProcessing =
false;
670 unsigned int genericReqParamsCount = 0;
671 std::vector<wxTextCtrl*> genericControls;
701 DisplayError(
this, wxT(
"Invalid AC magnitude or phase" ) );
711 genericProcessing =
true;
713 genericReqParamsCount = 2;
722 genericProcessing =
true;
724 genericReqParamsCount = 2;
732 genericProcessing =
true;
734 genericReqParamsCount = 2;
759 genericProcessing =
true;
761 genericReqParamsCount = 4;
770 genericProcessing =
true;
772 genericReqParamsCount = 5;
782 trans +=
"trrandom(";
785 genericProcessing =
true;
786 genericReqParamsCount = 4;
789 if( genericProcessing )
791 auto first_empty = std::find_if( genericControls.begin(), genericControls.end(),
empty );
792 auto first_not_empty = std::find_if( genericControls.begin(), genericControls.end(),
793 [](
const wxTextCtrl* c ){
return !
empty( c ); } );
795 if(
std::distance( first_not_empty, genericControls.end() ) == 0 )
801 first_empty ) < (
int)genericReqParamsCount )
805 "first %d parameters for the transient source" ),
806 genericReqParamsCount ) );
810 else if( std::find_if_not( first_empty, genericControls.end(),
811 empty ) != genericControls.end() )
813 DisplayError(
nullptr,
_(
"You cannot leave interleaved empty fields " 814 "when defining a transient source" ) );
819 std::for_each( genericControls.begin(), first_empty, [&trans] ( wxTextCtrl* ctrl ) {
834 aTarget.Trim(
false );
835 aTarget.Trim(
true );
851 wxFileName filePath( libname );
852 bool in_subckt =
false;
854 if( !filePath.Exists() )
858 wxWindowUpdateLocker updateLock(
this );
863 file.Open( filePath.GetFullPath() );
872 const wxString& line = line_nr == 0 ? file.GetFirstLine() : file.GetNextLine();
873 fullText << line <<
'\n';
875 wxStringTokenizer tokenizer( line );
877 while( tokenizer.HasMoreTokens() )
879 wxString token = tokenizer.GetNextToken().Lower();
883 if( token ==
".model" && !in_subckt )
885 wxString
name = tokenizer.GetNextToken();
890 token = tokenizer.GetNextToken();
896 else if( token ==
".subckt" )
898 wxASSERT( !in_subckt );
901 wxString
name = tokenizer.GetNextToken();
908 else if( token ==
".ends" )
910 wxASSERT( in_subckt );
922 wxArrayString modelsList;
930 modelsList.Add( model.first );
936 if( !curModel.IsEmpty() )
945 const wxString& spiceField =
951 return f.GetName() == spiceField;
966 const wxString& spiceField =
972 return f.GetName() == spiceField;
982 new_field.SetName( spiceField );
992 if( aTime.IsEmpty() || aValue.IsEmpty() )
1001 m_pwlTime->GetValue().ToDouble( &timeD );
1004 std::memcpy( &data, &timeF,
sizeof( timeF ) );
1024 wxString searchPath = wxFileName( libname ).GetPath();
1026 if( searchPath.IsEmpty() )
1030 wxFileDialog openDlg(
this,
_(
"Select library" ), searchPath,
"", wildcards,
1031 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
1033 if( openDlg.ShowModal() == wxID_CANCEL )
1036 wxFileName libPath( openDlg.GetPath() );
1039 if( libPath.MakeRelativeTo(
Prj().GetProjectPath() )
1040 && !libPath.GetFullPath().StartsWith(
".." ) )
1087 long idx =
m_pwlValList->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
1121 wxFAIL_MSG(
_(
"type of random generator for source is invalid" ) );
1130 const wxString val( aValue.Lower() );
1134 for(
const auto& keyword :
model.keywords )
1136 if( val.StartsWith( keyword ) )
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
wxStaticText * m_staticTextMeg3
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
void onSelectLibrary(wxCommandEvent &event) override
void Init()
Initialize the internal settings.
wxString ToSpiceString() const
Return string value in Spice format (e.g.
static SPICE_PRIMITIVE parseModelType(const wxString &aValue)
SPICE_VALIDATOR m_spiceValidator
wxStaticText * m_staticTextMeg2
void onTypeSelected(wxCommandEvent &event) override
Edited symbol.
std::vector< LIB_FIELD > * m_libfields
This file is part of the common library.
virtual bool TransferDataFromWindow() override
wxStaticText * m_staticTextN2
bool m_useSchFields
Temporary field values.
wxTextCtrl * m_pulseDelay
wxTextCtrl * m_modelLibrary
Field object used in symbol libraries.
static const wxString & GetSpiceFieldName(SPICE_FIELD aField)
Return a string used for a particular component field related to Spice simulation.
bool addPwlValue(const wxString &aTime, const wxString &aValue)
Add a value to the PWL values list.
wxStaticText * m_staticTextG3
wxStaticText * m_staticTextP1
wxTextCtrl * m_fmModIndex
LIB_FIELD & getLibField(int aFieldType)
wxTextCtrl * m_amCarrierFreq
wxTextCtrl * m_nodeSeqVal
std::vector< SCH_FIELD > SCH_FIELDS
A container for several SCH_FIELD items.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
wxPanel * m_pwrTransNoise
static bool StringToBool(const wxString &aStr)
Convert typical boolean string values (no/yes, true/false, 1/0) to a boolean value.
bool parsePowerSource(const wxString &aModel)
Parse a string describing a power source, so appropriate settings are checked in the dialog.
DIALOG_SPICE_MODEL(wxWindow *aParent, SCH_SYMBOL &aSymbol, std::vector< SCH_FIELD > *aSchFields)
wxStaticText * m_staticTextMeg1
wxTextCtrl * m_sinDampFactor
wxStaticText * m_staticTextU2
virtual const wxString GetProjectPath() const
Return the full path of the project.
wxString AllFilesWildcard()
wxString GetName(bool aUseDefaultName=true) const
Return the field name.
wxStaticText * m_staticTextN1
wxString description
Human-readable description.
static int getModelTypeIdx(char aPrimitive)
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
SCH_SYMBOL & m_symbol
Fields from the symbol properties dialog.
wxStaticText * m_staticTextM2
static bool empty(const wxTextCtrl *aCtrl)
wxStaticText * m_staticTextF1
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
wxStaticText * m_staticTextP2
std::vector< std::string > keywords
Keywords indicating the model.
wxTextCtrl * m_genAcPhase
virtual void SetText(const wxString &aText)
void showPinOrderNote(int aModelType)
Display a note info about pin order.
wxTextCtrl * m_pulsePeriod
wxListCtrl * m_pwlValList
wxStaticText * m_staticTextT3
void onRandomSourceType(wxCommandEvent &event) override
wxStaticText * m_staticTextF2
< Helper class to handle Spice way of expressing values (e.g. 10.5 Meg) Helper class to recognize Spi...
wxStaticText * m_staticTextM3
wxStyledTextCtrl * m_libraryContents
static wxString GetSpiceFieldDefVal(SPICE_FIELD aField, SCH_SYMBOL *aSymbol, unsigned aCtl)
Retrieve the default value for a given field.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
wxStaticText * m_staticTextN3
wxStaticText * m_staticTextT2
SPICE_PRIMITIVE type
Character identifying the model.
Definition of file extensions used in Kicad.
SCH_FIELD & getSchField(int aFieldType)
Return or create a field in the edited schematic fields vector.
std::unique_ptr< SCINTILLA_TRICKS > m_scintillaTricks
wxTextCtrl * m_pulseWidth
wxStaticText * m_staticTextG2
wxStaticText * m_staticTextF3
wxTextValidator m_notEmptyValidator
bool generatePowerSource(wxString &aTarget)
Generate a string to describe power source parameters, basing on the current selection.
wxStaticText * m_staticTextU3
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
void onModelSelected(wxCommandEvent &event) override
std::map< int, wxString > m_fieldsTmp
wxTextCtrl * m_expFallDelay
void onPwlRemove(wxCommandEvent &event) override
wxStaticText * m_staticTextK3
wxTextCtrl * m_amSignalDelay
void onPwlAdd(wxCommandEvent &event) override
void loadLibrary(const wxString &aFilePath)
Load a list of components (.model and .subckt) from a spice library file and add them to a combo box.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
wxTextCtrl * m_sinAmplitude
wxStaticText * m_staticTextU1
wxStaticText * m_staticTextG1
SPICE_PRIMITIVE model
Convert string to model.
wxStaticText * m_rnParam2Text
wxStaticText * m_staticTextK1
wxCheckBox * m_nodeSeqCheck
Class DIALOG_SPICE_MODEL_BASE.
wxStaticText * m_stInfoNote
wxTextCtrl * m_expFallConst
std::map< wxString, MODEL > m_models
Column identifiers for PWL power source value list.
wxString GetName(bool aUseDefaultName=true) const
Return the field name.
wxString SpiceLibraryFileWildcard()
wxTextCtrl * m_fmFcarrier
wxStaticText * m_staticTextM1
wxTextCtrl * m_amAmplitude
static int wxCALLBACK comparePwlValues(wxIntPtr aItem1, wxIntPtr aItem2, wxIntPtr WXUNUSED(aSortData))
wxTextCtrl * m_amModulatingFreq
wxTextCtrl * m_pulseNominal
static const std::vector< wxString > & GetSpiceFields()
Return a vector of component field names related to Spice simulation.
wxStaticText * m_staticTextT1
wxTextCtrl * m_expRiseDelay
wxNotebook * m_powerNotebook
void delete_if(_Container &__c, _Function &&__f)
Deletes all values from __c for which __f returns true.
std::vector< SCH_FIELD > * m_schfields
SPICE_VALIDATOR m_spiceEmptyValidator
wxStaticText * m_staticTextP3
static const std::vector< SPICE_MODEL_INFO > modelTypes
wxStaticText * m_staticTextK2
wxTextCtrl * m_expRiseConst
virtual bool TransferDataToWindow() override
wxStaticText * m_rnParam1Text
wxTextCtrl * m_fmAmplitude