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 )
|
void DIALOG_LIB_SYMBOL_PROPERTIES::OnEditSpiceModel( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
#ifdef KICAD_SPICE
|
#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 )
|
if( dialog.ShowModal() != wxID_OK )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
diff = (int) m_fields->size() - diff;
|
// Add in any new fields
|
||||||
|
for( const LIB_FIELD& editedField : fields )
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
if( diff > 0 )
|
for( LIB_FIELD& existingField : *m_fields )
|
||||||
{
|
{
|
||||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, diff );
|
if( existingField.GetName() == editedField.GetName() )
|
||||||
m_grid->ProcessTableMessage( msg );
|
{
|
||||||
|
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 );
|
LIB_FIELD& existingField = m_fields->at( ii );
|
||||||
m_grid->ProcessTableMessage( msg );
|
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();
|
OnModify();
|
||||||
|
|
|
@ -362,22 +362,22 @@ int DIALOG_SIM_COMMAND::ShowModal()
|
||||||
{ m_noiseRef, m_noiseRef->GetStringSelection() }
|
{ m_noiseRef, m_noiseRef->GetStringSelection() }
|
||||||
};
|
};
|
||||||
|
|
||||||
for( auto& c : cmbNet )
|
for( const std::pair<wxComboBox* const, wxString>& c : cmbNet )
|
||||||
c.first->Clear();
|
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 );
|
c.first->Append( net );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to restore the previous selection, if possible
|
// 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 );
|
int idx = c.first->FindString( c.second );
|
||||||
|
|
||||||
if( idx != wxNOT_FOUND )
|
if( idx != wxNOT_FOUND )
|
||||||
c.first->SetSelection( idx );
|
c.first->SetSelection( idx );
|
||||||
}
|
}
|
||||||
|
|
||||||
return DIALOG_SIM_COMMAND_BASE::ShowModal();
|
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 ),
|
: DIALOG_SIM_MODEL_BASE( aParent ),
|
||||||
m_symbol( aSymbol ),
|
m_symbol( aSymbol ),
|
||||||
m_fields( aFields ),
|
m_fields( aFields ),
|
||||||
m_fieldsOrigin( aFields ),
|
|
||||||
m_libraryModelsMgr( Prj() ),
|
m_libraryModelsMgr( Prj() ),
|
||||||
m_builtinModelsMgr( Prj() ),
|
m_builtinModelsMgr( Prj() ),
|
||||||
m_prevModel( nullptr ),
|
m_prevModel( nullptr ),
|
||||||
|
@ -314,8 +313,6 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataFromWindow()
|
||||||
|
|
||||||
curModel().WriteFields( m_fields );
|
curModel().WriteFields( m_fields );
|
||||||
|
|
||||||
m_fieldsOrigin = m_fields;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ public:
|
||||||
MODEL
|
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();
|
~DIALOG_SIM_MODEL();
|
||||||
|
|
||||||
|
@ -143,8 +143,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T_symbol& m_symbol;
|
T_symbol& m_symbol;
|
||||||
std::vector<T_field> m_fields; // Local copy of the fields
|
std::vector<T_field>& m_fields;
|
||||||
std::vector<T_field>& m_fieldsOrigin; // Pointer back to the source copy of the fields
|
|
||||||
|
|
||||||
SIM_LIB_MGR m_libraryModelsMgr;
|
SIM_LIB_MGR m_libraryModelsMgr;
|
||||||
SIM_LIB_MGR m_builtinModelsMgr;
|
SIM_LIB_MGR m_builtinModelsMgr;
|
||||||
|
|
|
@ -544,24 +544,64 @@ void DIALOG_SYMBOL_PROPERTIES::OnEditSpiceModel( wxCommandEvent& event )
|
||||||
if( !m_fieldsGrid->CommitPendingChanges() )
|
if( !m_fieldsGrid->CommitPendingChanges() )
|
||||||
return;
|
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 )
|
if( dialog.ShowModal() != wxID_OK )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
diff = (int) m_fields->size() - diff;
|
// Add in any new fields
|
||||||
|
for( const SCH_FIELD& editedField : fields )
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
if( diff > 0 )
|
for( SCH_FIELD& existingField : *m_fields )
|
||||||
{
|
{
|
||||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, diff );
|
if( existingField.GetName() == editedField.GetName() )
|
||||||
m_fieldsGrid->ProcessTableMessage( msg );
|
{
|
||||||
|
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 );
|
SCH_FIELD& existingField = m_fields->at( ii );
|
||||||
m_fieldsGrid->ProcessTableMessage( msg );
|
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();
|
OnModify();
|
||||||
|
|
Loading…
Reference in New Issue