Fix crash when grid tries to access deleted field.
This commit is contained in:
parent
419fe236ad
commit
e890986e01
|
@ -606,24 +606,67 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
|
|||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnEditSpiceModel( wxCommandEvent& event )
|
||||
{
|
||||
#ifdef KICAD_SPICE
|
||||
int diff = m_fields->size();
|
||||
if( !m_grid->CommitPendingChanges() )
|
||||
return;
|
||||
|
||||
DIALOG_SIM_MODEL dialog( this, *m_libEntry, *m_fields );
|
||||
std::vector<LIB_FIELD> fields;
|
||||
|
||||
for( const LIB_FIELD& field : *m_fields )
|
||||
fields.emplace_back( field );
|
||||
|
||||
DIALOG_SIM_MODEL dialog( this, *m_libEntry, fields );
|
||||
|
||||
if( dialog.ShowModal() != wxID_OK )
|
||||
return;
|
||||
|
||||
diff = (int) m_fields->size() - diff;
|
||||
// Add in any new fields
|
||||
for( const LIB_FIELD& editedField : fields )
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
if( diff > 0 )
|
||||
{
|
||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, diff );
|
||||
m_grid->ProcessTableMessage( msg );
|
||||
for( LIB_FIELD& existingField : *m_fields )
|
||||
{
|
||||
if( existingField.GetName() == editedField.GetName() )
|
||||
{
|
||||
found = true;
|
||||
existingField.SetText( editedField.GetText() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
m_fields->emplace_back( editedField );
|
||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
|
||||
m_grid->ProcessTableMessage( msg );
|
||||
}
|
||||
}
|
||||
else if( diff < 0 )
|
||||
|
||||
// Remove any deleted fields
|
||||
for( int ii = (int) m_fields->size() - 1; ii >= 0; /* advance in loop */ )
|
||||
{
|
||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, -diff );
|
||||
m_grid->ProcessTableMessage( msg );
|
||||
LIB_FIELD& existingField = m_fields->at( ii );
|
||||
bool found = false;
|
||||
|
||||
for( LIB_FIELD& editedField : fields )
|
||||
{
|
||||
if( editedField.GetName() == existingField.GetName() )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( found )
|
||||
{
|
||||
ii--;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
|
||||
m_grid->ProcessTableMessage( msg );
|
||||
}
|
||||
}
|
||||
|
||||
OnModify();
|
||||
|
|
|
@ -362,22 +362,22 @@ int DIALOG_SIM_COMMAND::ShowModal()
|
|||
{ m_noiseRef, m_noiseRef->GetStringSelection() }
|
||||
};
|
||||
|
||||
for( auto& c : cmbNet )
|
||||
for( const std::pair<wxComboBox* const, wxString>& c : cmbNet )
|
||||
c.first->Clear();
|
||||
|
||||
for( const auto& net : m_circuitModel->GetNets() )
|
||||
for( const std::string& net : m_circuitModel->GetNets() )
|
||||
{
|
||||
for( auto& c : cmbNet )
|
||||
for( const std::pair<wxComboBox* const, wxString>& c : cmbNet )
|
||||
c.first->Append( net );
|
||||
}
|
||||
|
||||
// Try to restore the previous selection, if possible
|
||||
for( auto& c : cmbNet )
|
||||
for( const std::pair<wxComboBox* const, wxString>& c : cmbNet )
|
||||
{
|
||||
int idx = c.first->FindString( c.second );
|
||||
|
||||
if( idx != wxNOT_FOUND )
|
||||
c.first->SetSelection( idx );
|
||||
c.first->SetSelection( idx );
|
||||
}
|
||||
|
||||
return DIALOG_SIM_COMMAND_BASE::ShowModal();
|
||||
|
|
|
@ -50,7 +50,6 @@ DIALOG_SIM_MODEL<T_symbol, T_field>::DIALOG_SIM_MODEL( wxWindow* aParent, T_symb
|
|||
: DIALOG_SIM_MODEL_BASE( aParent ),
|
||||
m_symbol( aSymbol ),
|
||||
m_fields( aFields ),
|
||||
m_fieldsOrigin( aFields ),
|
||||
m_libraryModelsMgr( Prj() ),
|
||||
m_builtinModelsMgr( Prj() ),
|
||||
m_prevModel( nullptr ),
|
||||
|
@ -314,8 +313,6 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataFromWindow()
|
|||
|
||||
curModel().WriteFields( m_fields );
|
||||
|
||||
m_fieldsOrigin = m_fields;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ public:
|
|||
MODEL
|
||||
};
|
||||
|
||||
DIALOG_SIM_MODEL( wxWindow* aParent, T_symbol& aSymbol, std::vector<T_field>& aSchFields );
|
||||
DIALOG_SIM_MODEL( wxWindow* aParent, T_symbol& aSymbol, std::vector<T_field>& aFields );
|
||||
|
||||
~DIALOG_SIM_MODEL();
|
||||
|
||||
|
@ -143,8 +143,7 @@ private:
|
|||
|
||||
private:
|
||||
T_symbol& m_symbol;
|
||||
std::vector<T_field> m_fields; // Local copy of the fields
|
||||
std::vector<T_field>& m_fieldsOrigin; // Pointer back to the source copy of the fields
|
||||
std::vector<T_field>& m_fields;
|
||||
|
||||
SIM_LIB_MGR m_libraryModelsMgr;
|
||||
SIM_LIB_MGR m_builtinModelsMgr;
|
||||
|
|
|
@ -544,24 +544,64 @@ void DIALOG_SYMBOL_PROPERTIES::OnEditSpiceModel( wxCommandEvent& event )
|
|||
if( !m_fieldsGrid->CommitPendingChanges() )
|
||||
return;
|
||||
|
||||
int diff = m_fields->size();
|
||||
std::vector<SCH_FIELD> fields;
|
||||
|
||||
DIALOG_SIM_MODEL dialog( this, *m_symbol, *m_fields );
|
||||
for( const SCH_FIELD& field : *m_fields )
|
||||
fields.emplace_back( field );
|
||||
|
||||
DIALOG_SIM_MODEL dialog( this, *m_symbol, fields );
|
||||
|
||||
if( dialog.ShowModal() != wxID_OK )
|
||||
return;
|
||||
|
||||
diff = (int) m_fields->size() - diff;
|
||||
// Add in any new fields
|
||||
for( const SCH_FIELD& editedField : fields )
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
if( diff > 0 )
|
||||
{
|
||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, diff );
|
||||
m_fieldsGrid->ProcessTableMessage( msg );
|
||||
for( SCH_FIELD& existingField : *m_fields )
|
||||
{
|
||||
if( existingField.GetName() == editedField.GetName() )
|
||||
{
|
||||
found = true;
|
||||
existingField.SetText( editedField.GetText() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
m_fields->emplace_back( editedField );
|
||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
|
||||
m_fieldsGrid->ProcessTableMessage( msg );
|
||||
}
|
||||
}
|
||||
else if( diff < 0 )
|
||||
|
||||
// Remove any deleted fields
|
||||
for( int ii = (int) m_fields->size() - 1; ii >= 0; /* advance in loop */ )
|
||||
{
|
||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, -diff );
|
||||
m_fieldsGrid->ProcessTableMessage( msg );
|
||||
SCH_FIELD& existingField = m_fields->at( ii );
|
||||
bool found = false;
|
||||
|
||||
for( SCH_FIELD& editedField : fields )
|
||||
{
|
||||
if( editedField.GetName() == existingField.GetName() )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( found )
|
||||
{
|
||||
ii--;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
|
||||
m_fieldsGrid->ProcessTableMessage( msg );
|
||||
}
|
||||
}
|
||||
|
||||
OnModify();
|
||||
|
|
Loading…
Reference in New Issue