Eeschema: fix bugs in symbol edit properties dialog.

Use flattened (root) library symbols to prevent broken library symbols
in schematic files.

Remove the edited symbol from screen before making changes to the symbol
to prevent potential orphaned symbol libraries being saved in schematic
file.

Add some defensive programming to let developers know that an invalid
library symbol link was used when calling SCH_COMPONENT::SetLibSymbol().
This commit is contained in:
Wayne Stambaugh 2020-05-05 10:55:54 -04:00
parent e208cd8eca
commit 5cf474e1c8
3 changed files with 24 additions and 7 deletions

View File

@ -370,6 +370,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::Validate()
return false; return false;
} }
} }
m_libraryNameTextCtrl->SetValue( id.Format() ); m_libraryNameTextCtrl->SetValue( id.Format() );
// Check for missing field names. // Check for missing field names.
@ -398,6 +399,14 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method. if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method.
return false; return false;
SCH_SCREEN* currentScreen = GetParent()->GetScreen();
wxCHECK( currentScreen, false );
// This needs to be done before the LIB_ID is changed to prevent stale library symbols in
// the schematic file.
currentScreen->Remove( m_cmp );
wxString msg; wxString msg;
// save old cmp in undo list if not already in edit, or moving ... // save old cmp in undo list if not already in edit, or moving ...
@ -428,7 +437,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
return false; return false;
} }
m_cmp->SetLibSymbol( new LIB_PART( *libSymbol ) ); m_cmp->SetLibSymbol( libSymbol->Flatten().release() );
m_cmp->SetLibId( id ); m_cmp->SetLibId( id );
// For symbols with multiple shapes (De Morgan representation) Set the selected shape: // For symbols with multiple shapes (De Morgan representation) Set the selected shape:
@ -520,8 +529,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
} }
} }
m_cmp->UpdatePins(); currentScreen->Append( m_cmp );
GetParent()->TestDanglingEnds(); GetParent()->TestDanglingEnds();
GetParent()->RefreshItem( m_cmp ); GetParent()->RefreshItem( m_cmp );
GetParent()->OnModify(); GetParent()->OnModify();
@ -579,7 +587,9 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnDeleteField( wxCommandEvent& event )
int curRow = m_grid->GetGridCursorRow(); int curRow = m_grid->GetGridCursorRow();
if( curRow < 0 ) if( curRow < 0 )
{
return; return;
}
else if( curRow < MANDATORY_FIELDS ) else if( curRow < MANDATORY_FIELDS )
{ {
DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ), DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
@ -621,8 +631,10 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnMoveUp( wxCommandEvent& event )
m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() ); m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
} }
else else
{
wxBell(); wxBell();
} }
}
void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnMoveDown( wxCommandEvent& event ) void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnMoveDown( wxCommandEvent& event )

View File

@ -247,6 +247,8 @@ wxString SCH_COMPONENT::GetSchSymbolLibraryName() const
void SCH_COMPONENT::SetLibSymbol( LIB_PART* aLibSymbol ) void SCH_COMPONENT::SetLibSymbol( LIB_PART* aLibSymbol )
{ {
wxCHECK2( ( aLibSymbol == nullptr ) || ( aLibSymbol->IsRoot() ), aLibSymbol = nullptr );
m_part.reset( aLibSymbol ); m_part.reset( aLibSymbol );
UpdatePins(); UpdatePins();
} }

View File

@ -224,14 +224,17 @@ public:
* Set this schematic symbol library symbol reference to \a aLibSymbol * Set this schematic symbol library symbol reference to \a aLibSymbol
* *
* The schematic symbol object owns \a aLibSymbol and the pin list will be updated * The schematic symbol object owns \a aLibSymbol and the pin list will be updated
* accordingly. The #LIB_ID object must be valid ( have both a library nickname and * accordingly. The #LIB_PART object can be null to clear the library symbol link
* symbol name ) in order to set the schematic symbol #LIB_ID. Otherwise an assertion * as well as the pin map. If the #LIB_PART object is not null, it must be a root
* will be raised in debug builds and the library symbol will be cleared. The new file * symbol. Otherwise an assertion will be raised in debug builds and the library
* format will no longer require a cache library so all library symbols must be valid. * symbol will be cleared. The new file format will no longer require a cache
* library so all library symbols must be valid.
* *
* @note This is the only way to publicly set the library symbol for a schematic * @note This is the only way to publicly set the library symbol for a schematic
* symbol except for the ctors that take a LIB_PART reference. All previous * symbol except for the ctors that take a LIB_PART reference. All previous
* public resolvers have been deprecated. * public resolvers have been deprecated.
*
* @param aLibSymbol is the library symbol to associate with this schematic symbol.
*/ */
void SetLibSymbol( LIB_PART* aLibSymbol ); void SetLibSymbol( LIB_PART* aLibSymbol );