SCH/LIB SYMBOL: never allow null LIB_SYMBOLs in SCH_SYMBOL

Also always always flatten incoming lib symbols.
This commit is contained in:
Mike Williams 2024-06-04 11:50:20 -04:00
parent aa1fb0604a
commit 0b187e7122
39 changed files with 434 additions and 680 deletions

View File

@ -322,16 +322,16 @@ void SCH_EDIT_FRAME::AnnotateSymbols( SCH_COMMIT* aCommit, ANNOTATE_SCOPE_T aAn
currentSheet.GetSymbols( references ); currentSheet.GetSymbols( references );
if( aRecursive ) if( aRecursive )
subSheets.GetSymbolsWithinPath( references, currentSheet, false, true ); subSheets.GetSymbolsWithinPath( references, currentSheet, false );
break; break;
case ANNOTATE_SELECTION: case ANNOTATE_SELECTION:
for( SCH_SYMBOL* symbol : selectedSymbols ) for( SCH_SYMBOL* symbol : selectedSymbols )
currentSheet.AppendSymbol( references, symbol, false, true ); currentSheet.AppendSymbol( references, symbol, false );
if( aRecursive ) if( aRecursive )
selectedSheets.GetSymbolsWithinPath( references, currentSheet, false, true ); selectedSheets.GetSymbolsWithinPath( references, currentSheet, false );
break; break;
} }
@ -502,7 +502,7 @@ int SCH_EDIT_FRAME::CheckAnnotate( ANNOTATION_ERROR_HANDLER aErrorHandler,
EE_SELECTION& selection = selTool->RequestSelection(); EE_SELECTION& selection = selTool->RequestSelection();
for( SCH_SYMBOL* symbol : getInferredSymbols( selection ) ) for( SCH_SYMBOL* symbol : getInferredSymbols( selection ) )
GetCurrentSheet().AppendSymbol( referenceList, symbol, false, true ); GetCurrentSheet().AppendSymbol( referenceList, symbol, false );
if( aRecursive ) if( aRecursive )
{ {

View File

@ -582,7 +582,7 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
if( sch_pin->IsGlobalPower() ) if( sch_pin->IsGlobalPower() )
return PRIORITY::POWER_PIN; return PRIORITY::POWER_PIN;
else if( !sym || sym->GetExcludedFromBoard() else if( !sym || sym->GetExcludedFromBoard()
|| sym->GetLibSymbolRef()->GetReferenceField().GetText().StartsWith( '#' ) ) || sym->GetLibSymbolRef().GetReferenceField().GetText().StartsWith( '#' ) )
return PRIORITY::NONE; return PRIORITY::NONE;
else else
return PRIORITY::PIN; return PRIORITY::PIN;

View File

@ -472,7 +472,7 @@ bool findSymbolsAndPins(
SCH_REFERENCE_LIST references; SCH_REFERENCE_LIST references;
aSheetPath.GetSymbols( references, false, true ); aSheetPath.GetSymbols( references, false );
for( unsigned ii = 0; ii < references.GetCount(); ii++ ) for( unsigned ii = 0; ii < references.GetCount(); ii++ )
{ {
@ -559,7 +559,7 @@ bool sheetContainsOnlyWantedItems(
} }
SCH_REFERENCE_LIST references; SCH_REFERENCE_LIST references;
aSheetPath.GetSymbols( references, false, true ); aSheetPath.GetSymbols( references, false );
if( references.GetCount() == 0 ) // Empty sheet, obviously do not contain wanted items if( references.GetCount() == 0 ) // Empty sheet, obviously do not contain wanted items
{ {

View File

@ -623,25 +623,23 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
if( symbol_change_info.m_LibId != symbol->GetLibId() ) if( symbol_change_info.m_LibId != symbol->GetLibId() )
symbol->SetLibId( symbol_change_info.m_LibId ); symbol->SetLibId( symbol_change_info.m_LibId );
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( symbol_change_info.m_LibId ); SCH_SCREEN* screen = symbol_change_info.m_Instances[0].LastScreen();
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
SCH_SCREEN* screen = symbol_change_info.m_Instances[0].LastScreen();
symbol->SetLibSymbol( flattenedSymbol.release() ); symbol->SetLibSymbol( frame->GetLibSymbol( symbol_change_info.m_LibId ) );
if( m_resetAttributes->GetValue() ) if( m_resetAttributes->GetValue() )
{ {
// Fetch the attributes from the *flattened* library symbol. They are not supported // Fetch the attributes from the *flattened* library symbol. They are not supported
// in derived symbols. // in derived symbols.
symbol->SetExcludedFromSim( symbol->GetLibSymbolRef()->GetExcludedFromSim() ); symbol->SetExcludedFromSim( symbol->GetLibSymbolRef().GetExcludedFromSim() );
symbol->SetExcludedFromBOM( symbol->GetLibSymbolRef()->GetExcludedFromBOM() ); symbol->SetExcludedFromBOM( symbol->GetLibSymbolRef().GetExcludedFromBOM() );
symbol->SetExcludedFromBoard( symbol->GetLibSymbolRef()->GetExcludedFromBoard() ); symbol->SetExcludedFromBoard( symbol->GetLibSymbolRef().GetExcludedFromBoard() );
} }
if( m_resetPinTextVisibility->GetValue() ) if( m_resetPinTextVisibility->GetValue() )
{ {
symbol->SetShowPinNames( symbol->GetLibSymbolRef()->GetShowPinNames() ); symbol->SetShowPinNames( symbol->GetLibSymbolRef().GetShowPinNames() );
symbol->SetShowPinNumbers( symbol->GetLibSymbolRef()->GetShowPinNumbers() ); symbol->SetShowPinNumbers( symbol->GetLibSymbolRef().GetShowPinNumbers() );
} }
bool removeExtras = m_removeExtraBox->GetValue(); bool removeExtras = m_removeExtraBox->GetValue();
@ -660,9 +658,9 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
continue; continue;
if( i < MANDATORY_FIELDS ) if( i < MANDATORY_FIELDS )
libField = symbol->GetLibSymbolRef()->GetFieldById( (int) i ); libField = symbol->GetLibSymbolRef().GetFieldById( (int) i );
else else
libField = symbol->GetLibSymbolRef()->FindField( field.GetName() ); libField = symbol->GetLibSymbolRef().FindField( field.GetName() );
if( libField ) if( libField )
{ {
@ -732,7 +730,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
} }
std::vector<SCH_FIELD*> libFields; std::vector<SCH_FIELD*> libFields;
symbol->GetLibSymbolRef()->GetFields( libFields ); symbol->GetLibSymbolRef().GetFields( libFields );
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i ) for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
{ {

View File

@ -393,11 +393,10 @@ void DIALOG_EDIT_SYMBOLS_LIBID::initDlg()
// the list is larger and looks like it contains all symbols. // the list is larger and looks like it contains all symbols.
SCH_REFERENCE_LIST references; SCH_REFERENCE_LIST references;
// build the full list of symbols including symbol having no symbol in loaded libs // build the full list of symbols
// (orphan symbols)
GetParent()->Schematic().BuildUnorderedSheetList().GetSymbols( references, GetParent()->Schematic().BuildUnorderedSheetList().GetSymbols( references,
true /* include power symbols */, true /* include power symbols */ );
true /* include orphan symbols */ );
for( unsigned ii = 0; ii < references.GetCount(); ii++ ) for( unsigned ii = 0; ii < references.GetCount(); ii++ )
{ {
@ -763,7 +762,7 @@ bool DIALOG_EDIT_SYMBOLS_LIBID::TransferDataFromWindow()
candidate.m_Symbol->SetValueFieldText( getName( id ) ); candidate.m_Symbol->SetValueFieldText( getName( id ) );
candidate.m_Symbol->SetLibId( id ); candidate.m_Symbol->SetLibId( id );
candidate.m_Symbol->SetLibSymbol( symbol->Flatten().release() ); candidate.m_Symbol->SetLibSymbol( symbol );
candidate.m_Screen->Append( candidate.m_Symbol ); candidate.m_Screen->Append( candidate.m_Symbol );
candidate.m_Screen->SetContentModified(); candidate.m_Screen->SetContentModified();

View File

@ -205,7 +205,7 @@ DIALOG_FIELD_PROPERTIES::DIALOG_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const
netlist << wxS( "\r" ); netlist << wxS( "\r" );
wxArrayString fpFilters = symbol->GetLibSymbolRef()->GetFPFilters(); wxArrayString fpFilters = symbol->GetLibSymbolRef().GetFPFilters();
if( !fpFilters.IsEmpty() ) if( !fpFilters.IsEmpty() )
netlist << EscapeString( wxJoin( fpFilters, ' ' ), CTX_LINE ); netlist << EscapeString( wxJoin( fpFilters, ' ' ), CTX_LINE );

View File

@ -412,7 +412,7 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( SCH_COMMIT* aCommit,
{ {
if( aItem->Type() == SCH_SYMBOL_T ) if( aItem->Type() == SCH_SYMBOL_T )
{ {
bool isPower = static_cast<SCH_SYMBOL*>( aItem )->GetLibSymbolRef()->IsPower(); bool isPower = static_cast<SCH_SYMBOL*>( aItem )->GetLibSymbolRef().IsPower();
if( isPower != ( m_typeFilter->GetSelection() == 1 ) ) if( isPower != ( m_typeFilter->GetSelection() == 1 ) )
return; return;

View File

@ -2221,7 +2221,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSchItemsAdded( SCHEMATIC& aSch,
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item ); SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
// Don't add power symbols // Don't add power symbols
if( !symbol->IsMissingLibSymbol() && symbol->IsPower() ) if( symbol->IsPower() )
continue; continue;
// Add all fields again in case this symbol has a new one // Add all fields again in case this symbol has a new one
@ -2290,7 +2290,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSchItemsChanged( SCHEMATIC& aSch
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item ); SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
// Don't add power symbols // Don't add power symbols
if( !symbol->IsMissingLibSymbol() && symbol->IsPower() ) if( symbol->IsPower() )
continue; continue;
// Add all fields again in case this symbol has a new one // Add all fields again in case this symbol has a new one
@ -2399,7 +2399,7 @@ SCH_REFERENCE_LIST DIALOG_SYMBOL_FIELDS_TABLE::getSheetSymbolReferences( SCH_SHE
subSheets.push_back( sheetPath ); subSheets.push_back( sheetPath );
allSheets.GetSheetsWithinPath( subSheets, sheetPath ); allSheets.GetSheetsWithinPath( subSheets, sheetPath );
subSheets.GetSymbolsWithinPath( sheetRefs, sheetPath, false, false ); subSheets.GetSymbolsWithinPath( sheetRefs, sheetPath, false );
break; break;
} }
} }

View File

@ -310,25 +310,15 @@ protected:
DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent, DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
SCH_SYMBOL* aSymbol ) : SCH_SYMBOL* aSymbol ) :
DIALOG_SYMBOL_PROPERTIES_BASE( aParent ), DIALOG_SYMBOL_PROPERTIES_BASE( aParent ),
m_symbol( nullptr ), m_symbol( aSymbol ),
m_part( nullptr ), m_part( aSymbol->GetLibSymbolRef() ),
m_fieldsSize( 0, 0 ), m_fieldsSize( 0, 0 ),
m_lastRequestedFieldsSize( 0, 0 ), m_lastRequestedFieldsSize( 0, 0 ),
m_lastRequestedPinsSize( 0, 0 ), m_lastRequestedPinsSize( 0, 0 ),
m_editorShown( false ), m_editorShown( false ),
m_fields( nullptr ), m_fields( new FIELDS_GRID_TABLE( this, aParent, m_fieldsGrid, m_symbol ) ),
m_dataModel( nullptr ) m_dataModel( nullptr )
{ {
m_symbol = aSymbol;
m_part = m_symbol->GetLibSymbolRef().get();
// GetLibSymbolRef() now points to the cached part in the schematic, which should always be
// there for usual cases, but can be null when opening old schematics not storing the part
// so we need to handle m_part == nullptr
// wxASSERT( m_part );
m_fields = new FIELDS_GRID_TABLE( this, aParent, m_fieldsGrid, m_symbol );
// Give a bit more room for combobox editors // Give a bit more room for combobox editors
m_fieldsGrid->SetDefaultRowSize( m_fieldsGrid->GetDefaultRowSize() + 4 ); m_fieldsGrid->SetDefaultRowSize( m_fieldsGrid->GetDefaultRowSize() + 4 );
m_pinGrid->SetDefaultRowSize( m_pinGrid->GetDefaultRowSize() + 4 ); m_pinGrid->SetDefaultRowSize( m_pinGrid->GetDefaultRowSize() + 4 );
@ -348,7 +338,7 @@ DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
m_shownColumns = m_fieldsGrid->GetShownColumns(); m_shownColumns = m_fieldsGrid->GetShownColumns();
} }
if( m_part && m_part->HasAlternateBodyStyle() ) if( m_part.HasAlternateBodyStyle() )
{ {
// DeMorgan conversions are a subclass of alternate pin assignments, so don't allow // DeMorgan conversions are a subclass of alternate pin assignments, so don't allow
// free-form alternate assignments as well. (We won't know how to map the alternates // free-form alternate assignments as well. (We won't know how to map the alternates
@ -371,7 +361,7 @@ DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
m_pinGrid->SetTable( m_dataModel ); m_pinGrid->SetTable( m_dataModel );
} }
if( m_part && m_part->IsPower() ) if( m_part.IsPower() )
m_spiceFieldsButton->Hide(); m_spiceFieldsButton->Hide();
m_pinGrid->PushEventHandler( new GRID_TRICKS( m_pinGrid ) ); m_pinGrid->PushEventHandler( new GRID_TRICKS( m_pinGrid ) );
@ -499,7 +489,7 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow()
m_unitChoice->Enable( false ); m_unitChoice->Enable( false );
} }
if( m_part && m_part->HasAlternateBodyStyle() ) if( m_part.HasAlternateBodyStyle() )
{ {
if( m_symbol->GetBodyStyle() > BODY_STYLE::BASE ) if( m_symbol->GetBodyStyle() > BODY_STYLE::BASE )
m_cbAlternateSymbol->SetValue( true ); m_cbAlternateSymbol->SetValue( true );
@ -535,11 +525,8 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow()
m_cbExcludeFromBoard->SetValue( m_symbol->GetExcludedFromBoard() ); m_cbExcludeFromBoard->SetValue( m_symbol->GetExcludedFromBoard() );
m_cbDNP->SetValue( m_symbol->GetDNP() ); m_cbDNP->SetValue( m_symbol->GetDNP() );
if( m_part ) m_ShowPinNumButt->SetValue( m_part.GetShowPinNumbers() );
{ m_ShowPinNameButt->SetValue( m_part.GetShowPinNames() );
m_ShowPinNumButt->SetValue( m_part->GetShowPinNumbers() );
m_ShowPinNameButt->SetValue( m_part->GetShowPinNames() );
}
// Set the symbol's library name. // Set the symbol's library name.
m_tcLibraryID->SetValue( UnescapeString( m_symbol->GetLibId().Format() ) ); m_tcLibraryID->SetValue( UnescapeString( m_symbol->GetLibId().Format() ) );
@ -1282,12 +1269,12 @@ void DIALOG_SYMBOL_PROPERTIES::OnUnitChoice( wxCommandEvent& event )
void DIALOG_SYMBOL_PROPERTIES::onUpdateEditSymbol( wxUpdateUIEvent& event ) void DIALOG_SYMBOL_PROPERTIES::onUpdateEditSymbol( wxUpdateUIEvent& event )
{ {
event.Enable( m_symbol && m_symbol->GetLibSymbolRef() ); event.Enable( m_symbol );
} }
void DIALOG_SYMBOL_PROPERTIES::onUpdateEditLibrarySymbol( wxUpdateUIEvent& event ) void DIALOG_SYMBOL_PROPERTIES::onUpdateEditLibrarySymbol( wxUpdateUIEvent& event )
{ {
event.Enable( m_symbol && m_symbol->GetLibSymbolRef() ); event.Enable( m_symbol );
} }

View File

@ -100,7 +100,7 @@ private:
private: private:
SCH_SYMBOL* m_symbol; SCH_SYMBOL* m_symbol;
LIB_SYMBOL* m_part; const LIB_SYMBOL& m_part;
wxSize m_fieldsSize; wxSize m_fieldsSize;
wxSize m_lastRequestedFieldsSize; wxSize m_lastRequestedFieldsSize;

View File

@ -362,7 +362,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportBom( JOB* aJob )
// Annotation warning check // Annotation warning check
SCH_REFERENCE_LIST referenceList; SCH_REFERENCE_LIST referenceList;
sch->BuildUnorderedSheetList().GetSymbols( referenceList, false, false ); sch->BuildUnorderedSheetList().GetSymbols( referenceList, false );
if( referenceList.GetCount() > 0 ) if( referenceList.GetCount() > 0 )
{ {

View File

@ -419,9 +419,9 @@ int ERC_TESTER::TestMissingUnits()
// Reference unit // Reference unit
SCH_REFERENCE& base_ref = refList.GetItem( 0 ); SCH_REFERENCE& base_ref = refList.GetItem( 0 );
SCH_SYMBOL* unit = base_ref.GetSymbol(); SCH_SYMBOL* unit = base_ref.GetSymbol();
LIB_SYMBOL* libSymbol = base_ref.GetLibPart(); LIB_SYMBOL& libSymbol = base_ref.GetSymbol()->GetLibSymbolRef();
if( static_cast<ssize_t>( refList.GetCount() ) == libSymbol->GetUnitCount() ) if( static_cast<ssize_t>( refList.GetCount() ) == libSymbol.GetUnitCount() )
continue; continue;
std::set<int> lib_units; std::set<int> lib_units;
@ -443,7 +443,7 @@ int ERC_TESTER::TestMissingUnits()
break; break;
} }
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ; missing_pin_units += libSymbol.GetUnitDisplayName( missing_unit ) + ", " ;
} }
missing_pin_units.Truncate( missing_pin_units.length() - 2 ); missing_pin_units.Truncate( missing_pin_units.length() - 2 );
@ -461,7 +461,7 @@ int ERC_TESTER::TestMissingUnits()
++errors; ++errors;
}; };
for( int ii = 1; ii <= libSymbol->GetUnitCount(); ++ii ) for( int ii = 1; ii <= libSymbol.GetUnitCount(); ++ii )
lib_units.insert( lib_units.end(), ii ); lib_units.insert( lib_units.end(), ii );
for( size_t ii = 0; ii < refList.GetCount(); ++ii ) for( size_t ii = 0; ii < refList.GetCount(); ++ii )
@ -494,7 +494,7 @@ int ERC_TESTER::TestMissingUnits()
} }
} }
for( SCH_PIN* pin : libSymbol->GetPins( missing_unit, bodyStyle ) ) for( SCH_PIN* pin : libSymbol.GetPins( missing_unit, bodyStyle ) )
{ {
switch( pin->GetType() ) switch( pin->GetType() )
{ {
@ -996,9 +996,7 @@ int ERC_TESTER::TestLibSymbolIssues()
for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) ) for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
{ {
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item ); SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
LIB_SYMBOL* libSymbolInSchematic = symbol->GetLibSymbolRef().get(); LIB_SYMBOL& libSymbolInSchematic = symbol->GetLibSymbolRef();
wxCHECK2( libSymbolInSchematic, continue );
wxString libName = symbol->GetLibId().GetLibNickname(); wxString libName = symbol->GetLibId().GetLibNickname();
LIB_TABLE_ROW* libTableRow = libTable->FindRow( libName, true ); LIB_TABLE_ROW* libTableRow = libTable->FindRow( libName, true );
@ -1062,7 +1060,7 @@ int ERC_TESTER::TestLibSymbolIssues()
// We have to check for duplicate pins first as they will cause Compare() to fail. // We have to check for duplicate pins first as they will cause Compare() to fail.
std::vector<wxString> messages; std::vector<wxString> messages;
UNITS_PROVIDER unitsProvider( schIUScale, EDA_UNITS::MILS ); UNITS_PROVIDER unitsProvider( schIUScale, EDA_UNITS::MILS );
CheckDuplicatePins( libSymbolInSchematic, messages, &unitsProvider ); CheckDuplicatePins( &libSymbolInSchematic, messages, &unitsProvider );
if( !messages.empty() ) if( !messages.empty() )
{ {
@ -1074,7 +1072,7 @@ int ERC_TESTER::TestLibSymbolIssues()
markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) ); markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
} }
else if( flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 ) else if( flattenedSymbol->Compare( libSymbolInSchematic, flags ) != 0 )
{ {
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_MISMATCH ); std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_MISMATCH );
ercItem->SetItems( symbol ); ercItem->SetItems( symbol );

View File

@ -62,7 +62,7 @@ enum
static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath ) static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath )
{ {
wxCHECK( aSymbol && aSymbol->GetLibSymbolRef(), wxEmptyString ); wxCHECK( aSymbol, wxEmptyString );
/* /*
* Symbol netlist format: * Symbol netlist format:
@ -81,7 +81,7 @@ static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath )
netlist << wxS( "\r" ); netlist << wxS( "\r" );
wxArrayString fpFilters = aSymbol->GetLibSymbolRef()->GetFPFilters(); wxArrayString fpFilters = aSymbol->GetLibSymbolRef().GetFPFilters();
if( !fpFilters.IsEmpty() ) if( !fpFilters.IsEmpty() )
netlist << EscapeString( wxJoin( fpFilters, ' ' ), CTX_LINE ); netlist << EscapeString( wxJoin( fpFilters, ' ' ), CTX_LINE );
@ -146,7 +146,7 @@ FIELDS_GRID_TABLE::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_EDIT_FRAME* aFra
m_dialog( aDialog ), m_dialog( aDialog ),
m_parentType( SCH_SYMBOL_T ), m_parentType( SCH_SYMBOL_T ),
m_mandatoryFieldCount( MANDATORY_FIELDS ), m_mandatoryFieldCount( MANDATORY_FIELDS ),
m_part( aSymbol->GetLibSymbolRef().get() ), m_part( &aSymbol->GetLibSymbolRef() ),
m_symbolNetlist( netList( aSymbol, aFrame->GetCurrentSheet() ) ), m_symbolNetlist( netList( aSymbol, aFrame->GetCurrentSheet() ) ),
m_fieldNameValidator( FIELD_NAME ), m_fieldNameValidator( FIELD_NAME ),
m_referenceValidator( REFERENCE_FIELD ), m_referenceValidator( REFERENCE_FIELD ),

View File

@ -175,6 +175,43 @@ LIB_SYMBOL::LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary ) :
} }
/**
* Used when a LIB_SYMBOL is not found in library to draw a dummy shape.
* This symbol is a 400 mils square with the text "??"
*
* DEF DUMMY U 0 40 Y Y 1 0 N
* F0 "U" 0 -350 60 H V
* F1 "DUMMY" 0 350 60 H V
* DRAW
* T 0 0 0 150 0 0 0 ??
* S -200 200 200 -200 0 1 0
* ENDDRAW
* ENDDEF
*/
LIB_SYMBOL* LIB_SYMBOL::Dummy()
{
static LIB_SYMBOL* symbol;
if( !symbol )
{
symbol = new LIB_SYMBOL( wxEmptyString );
SCH_SHAPE* square = new SCH_SHAPE( SHAPE_T::RECTANGLE, LAYER_DEVICE );
square->SetPosition( VECTOR2I( schIUScale.MilsToIU( -200 ), schIUScale.MilsToIU( 200 ) ) );
square->SetEnd( VECTOR2I( schIUScale.MilsToIU( 200 ), schIUScale.MilsToIU( -200 ) ) );
symbol->AddDrawItem( square );
SCH_TEXT* text = new SCH_TEXT( { 0, 0 }, wxT( "??" ), LAYER_DEVICE );
text->SetTextSize( VECTOR2I( schIUScale.MilsToIU( 150 ), schIUScale.MilsToIU( 150 ) ) );
symbol->AddDrawItem( text );
}
return symbol;
}
const LIB_SYMBOL& LIB_SYMBOL::operator=( const LIB_SYMBOL& aSymbol ) const LIB_SYMBOL& LIB_SYMBOL::operator=( const LIB_SYMBOL& aSymbol )
{ {
if( &aSymbol == this ) if( &aSymbol == this )

View File

@ -84,6 +84,10 @@ public:
virtual ~LIB_SYMBOL() virtual ~LIB_SYMBOL()
{} {}
static LIB_SYMBOL* Dummy();
bool IsDummy() { return this == Dummy(); }
///< http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared ///< http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
LIB_SYMBOL_SPTR SharedPtr() const { return m_me; } LIB_SYMBOL_SPTR SharedPtr() const { return m_me; }

View File

@ -412,7 +412,7 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroPackages()
footprintText = footprintText.AfterLast( ':' ); footprintText = footprintText.AfterLast( ':' );
wxArrayString footprintAlt; wxArrayString footprintAlt;
wxArrayString footprintArray = sym->GetLibSymbolRef()->GetFPFilters(); wxArrayString footprintArray = sym->GetLibSymbolRef().GetFPFilters();
for( const wxString& fp : footprintArray ) for( const wxString& fp : footprintArray )
{ {
@ -440,7 +440,7 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroPackages()
fprintf( d, "PACKAGE '%s'\n", TO_UTF8( formatDevice( footprintText ) ) ); fprintf( d, "PACKAGE '%s'\n", TO_UTF8( formatDevice( footprintText ) ) );
fprintf( d, "CLASS IC\n" ); fprintf( d, "CLASS IC\n" );
std::vector<SCH_PIN*> pinList = sym->GetLibSymbolRef()->GetAllLibPins(); std::vector<SCH_PIN*> pinList = sym->GetLibSymbolRef().GetAllLibPins();
/* /*
* We must erase redundant Pins references in pinList * We must erase redundant Pins references in pinList
@ -651,7 +651,7 @@ wxString NETLIST_EXPORTER_ALLEGRO::getGroupField( int aGroupIndex, const wxArray
for( const wxString& field : aFieldArray ) for( const wxString& field : aFieldArray )
{ {
if( SCH_FIELD* fld = sym->GetLibSymbolRef()->FindField( field, true ) ) if( SCH_FIELD* fld = sym->GetLibSymbolRef().FindField( field, true ) )
{ {
wxString fieldText = fld->GetShownText( false, 0 ); wxString fieldText = fld->GetShownText( false, 0 );

View File

@ -140,16 +140,8 @@ std::vector<PIN_INFO> NETLIST_EXPORTER_BASE::CreatePinList( SCH_SYMBOL* aSymbol,
if( ( ref[0] == wxChar( '#' ) ) || aSymbol->IsPower() ) if( ( ref[0] == wxChar( '#' ) ) || aSymbol->IsPower() )
return pins; return pins;
// if( aSymbol->m_FlagControlMulti == 1 )
// continue; /* yes */
// removed because with multiple instances of one schematic (several sheets pointing to
// 1 screen), this will be erroneously be toggled.
if( !aSymbol->GetLibSymbolRef() )
return pins;
// If symbol is a "multi parts per package" type // If symbol is a "multi parts per package" type
if( aSymbol->GetLibSymbolRef()->GetUnitCount() > 1 ) if( aSymbol->GetLibSymbolRef().GetUnitCount() > 1 )
{ {
// Collect all pins for this reference designator by searching the entire design for // Collect all pins for this reference designator by searching the entire design for
// other parts with the same reference designator. // other parts with the same reference designator.
@ -191,7 +183,7 @@ std::vector<PIN_INFO> NETLIST_EXPORTER_BASE::CreatePinList( SCH_SYMBOL* aSymbol,
eraseDuplicatePins( pins ); eraseDuplicatePins( pins );
// record the usage of this library symbol // record the usage of this library symbol
m_libParts.insert( aSymbol->GetLibSymbolRef().get() ); // rejects non-unique pointers m_libParts.insert( &aSymbol->GetLibSymbolRef() ); // rejects non-unique pointers
return pins; return pins;
} }

View File

@ -77,8 +77,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
std::vector<PIN_INFO> pins = CreatePinList( symbol, sheet, true ); std::vector<PIN_INFO> pins = CreatePinList( symbol, sheet, true );
if( symbol->GetLibSymbolRef() if( symbol->GetLibSymbolRef().GetFPFilters().GetCount() != 0 )
&& symbol->GetLibSymbolRef()->GetFPFilters().GetCount() != 0 )
{ {
cmpList.push_back( SCH_REFERENCE( symbol, sheet ) ); cmpList.push_back( SCH_REFERENCE( symbol, sheet ) );
} }

View File

@ -386,26 +386,25 @@ XNODE* NETLIST_EXPORTER_XML::makeSymbols( unsigned aCtl )
xproperty->AddAttribute( wxT( "name" ), wxT( "dnp" ) ); xproperty->AddAttribute( wxT( "name" ), wxT( "dnp" ) );
} }
if( const std::unique_ptr<LIB_SYMBOL>& part = symbol->GetLibSymbolRef() ) const LIB_SYMBOL& part = symbol->GetLibSymbolRef();
if( part.GetKeyWords().size() )
{ {
if( part->GetKeyWords().size() ) xcomp->AddChild( xproperty = node( wxT( "property" ) ) );
{ xproperty->AddAttribute( wxT( "name" ), wxT( "ki_keywords" ) );
xcomp->AddChild( xproperty = node( wxT( "property" ) ) ); xproperty->AddAttribute( wxT( "value" ), part.GetKeyWords() );
xproperty->AddAttribute( wxT( "name" ), wxT( "ki_keywords" ) ); }
xproperty->AddAttribute( wxT( "value" ), part->GetKeyWords() );
}
if( !part->GetFPFilters().IsEmpty() ) if( !part.GetFPFilters().IsEmpty() )
{ {
wxString filters; wxString filters;
for( const wxString& filter : part->GetFPFilters() ) for( const wxString& filter : part.GetFPFilters() )
filters += ' ' + filter; filters += ' ' + filter;
xcomp->AddChild( xproperty = node( wxT( "property" ) ) ); xcomp->AddChild( xproperty = node( wxT( "property" ) ) );
xproperty->AddAttribute( wxT( "name" ), wxT( "ki_fp_filters" ) ); xproperty->AddAttribute( wxT( "name" ), wxT( "ki_fp_filters" ) );
xproperty->AddAttribute( wxT( "value" ), filters.Trim( false ) ); xproperty->AddAttribute( wxT( "value" ), filters.Trim( false ) );
}
} }
XNODE* xsheetpath; XNODE* xsheetpath;

View File

@ -125,15 +125,15 @@ void SCH_EDIT_FRAME::SelectUnit( SCH_SYMBOL* aSymbol, int aUnit )
void SCH_EDIT_FRAME::FlipBodyStyle( SCH_SYMBOL* aSymbol ) void SCH_EDIT_FRAME::FlipBodyStyle( SCH_SYMBOL* aSymbol )
{ {
if( !aSymbol || !aSymbol->GetLibSymbolRef() ) if( !aSymbol )
return; return;
SCH_COMMIT commit( m_toolManager ); SCH_COMMIT commit( m_toolManager );
wxString msg; wxString msg;
if( !aSymbol->GetLibSymbolRef()->HasAlternateBodyStyle() ) if( !aSymbol->GetLibSymbolRef().HasAlternateBodyStyle() )
{ {
LIB_ID id = aSymbol->GetLibSymbolRef()->GetLibId(); LIB_ID id = aSymbol->GetLibSymbolRef().GetLibId();
msg.Printf( _( "No alternate body style found for symbol '%s' in library '%s'." ), msg.Printf( _( "No alternate body style found for symbol '%s' in library '%s'." ),
id.GetLibItemName().wx_str(), id.GetLibItemName().wx_str(),

View File

@ -2297,7 +2297,7 @@ void SCH_EDIT_FRAME::SaveSymbolToSchematic( const LIB_SYMBOL& aSymbol,
if( !unit->IsNew() ) if( !unit->IsNew() )
commit.Modify( unit, path.LastScreen() ); commit.Modify( unit, path.LastScreen() );
unit->SetLibSymbol( aSymbol.Flatten().release() ); unit->SetLibSymbol( &aSymbol );
unit->UpdateFields( &GetCurrentSheet(), unit->UpdateFields( &GetCurrentSheet(),
true, /* update style */ true, /* update style */
true, /* update ref */ true, /* update ref */

View File

@ -1134,7 +1134,8 @@ void SCH_IO_ALTIUM::ParseComponent( int aIndex, const std::map<wxString, wxStrin
m_libSymbols.insert( { aIndex, ksymbol } ); m_libSymbols.insert( { aIndex, ksymbol } );
// each component has its own symbol for now // each component has its own symbol for now
SCH_SYMBOL* symbol = new SCH_SYMBOL(); SCH_SYMBOL* symbol =
new SCH_SYMBOL( *ksymbol, libId, &m_sheetPath, std::max( 0, elem.currentpartid ) );
symbol->SetPosition( elem.location + m_sheetOffset ); symbol->SetPosition( elem.location + m_sheetOffset );
@ -1143,8 +1144,6 @@ void SCH_IO_ALTIUM::ParseComponent( int aIndex, const std::map<wxString, wxStrin
// TODO: keep it simple for now, and only set position. // TODO: keep it simple for now, and only set position.
// component->SetOrientation( elem.orientation ); // component->SetOrientation( elem.orientation );
symbol->SetLibId( libId );
symbol->SetUnit( std::max( 0, elem.currentpartid ) );
symbol->GetField( DESCRIPTION_FIELD )->SetText( elem.componentdescription ); symbol->GetField( DESCRIPTION_FIELD )->SetText( elem.componentdescription );
SCH_SCREEN* screen = getCurrentScreen(); SCH_SCREEN* screen = getCurrentScreen();
@ -3321,12 +3320,10 @@ void SCH_IO_ALTIUM::ParsePowerPort( const std::map<wxString, wxString>& aPropert
wxCHECK( screen, /* void */ ); wxCHECK( screen, /* void */ );
// each symbol has its own powerSymbolIt for now // each symbol has its own powerSymbolIt for now
SCH_SYMBOL* symbol = new SCH_SYMBOL(); SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libId, &m_sheetPath, 0 );
symbol->SetRef( &m_sheetPath, "#PWR?" ); symbol->SetRef( &m_sheetPath, "#PWR?" );
symbol->GetField( REFERENCE_FIELD )->SetVisible( false ); symbol->GetField( REFERENCE_FIELD )->SetVisible( false );
symbol->SetValueFieldText( elem.text ); symbol->SetValueFieldText( elem.text );
symbol->SetLibId( libId );
symbol->SetLibSymbol( new LIB_SYMBOL( *libSymbol ) );
SCH_FIELD* valueField = symbol->GetField( VALUE_FIELD ); SCH_FIELD* valueField = symbol->GetField( VALUE_FIELD );
valueField->SetVisible( elem.showNetName ); valueField->SetVisible( elem.showNetName );

View File

@ -2159,8 +2159,7 @@ SCH_SYMBOL* CADSTAR_SCH_ARCHIVE_LOADER::loadSchematicSymbol( const SYMBOL& aCads
for( auto& term : termNumMap ) for( auto& term : termNumMap )
{ {
wxString pinNum = term.second; wxString pinNum = term.second;
pinNumToLibPinMap.insert( { pinNum, pinNumToLibPinMap.insert( { pinNum, symbol->GetLibSymbolRef().GetPin( term.second ) } );
symbol->GetLibSymbolRef()->GetPin( term.second ) } );
} }
auto replacePinNumber = auto replacePinNumber =

View File

@ -1780,9 +1780,7 @@ void SCH_IO_EAGLE::loadInstance( wxXmlNode* aInstanceNode )
} }
LIB_ID libId( getLibName(), libIdSymbolName ); LIB_ID libId( getLibName(), libIdSymbolName );
std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>(); std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>( *part, libId, &m_sheetPath, unit );
symbol->SetLibId( libId );
symbol->SetUnit( unit );
symbol->SetPosition( VECTOR2I( einstance.x.ToSchUnits(), -einstance.y.ToSchUnits() ) ); symbol->SetPosition( VECTOR2I( einstance.x.ToSchUnits(), -einstance.y.ToSchUnits() ) );
// assume that footprint library is identical to project name // assume that footprint library is identical to project name
@ -3496,16 +3494,14 @@ bool SCH_IO_EAGLE::checkConnections( const SCH_SYMBOL* aSymbol, const SCH_PIN* a
void SCH_IO_EAGLE::addImplicitConnections( SCH_SYMBOL* aSymbol, SCH_SCREEN* aScreen, void SCH_IO_EAGLE::addImplicitConnections( SCH_SYMBOL* aSymbol, SCH_SCREEN* aScreen,
bool aUpdateSet ) bool aUpdateSet )
{ {
wxCHECK( aSymbol->GetLibSymbolRef(), /*void*/ );
// Normally power parts also have power input pins, // Normally power parts also have power input pins,
// but they already force net names on the attached wires // but they already force net names on the attached wires
if( aSymbol->GetLibSymbolRef()->IsPower() ) if( aSymbol->GetLibSymbolRef().IsPower() )
return; return;
int unit = aSymbol->GetUnit(); int unit = aSymbol->GetUnit();
const wxString reference = aSymbol->GetField( REFERENCE_FIELD )->GetText(); const wxString reference = aSymbol->GetField( REFERENCE_FIELD )->GetText();
std::vector<SCH_PIN*> pins = aSymbol->GetLibSymbolRef()->GetAllLibPins(); std::vector<SCH_PIN*> pins = aSymbol->GetLibSymbolRef().GetAllLibPins();
std::set<int> missingUnits; std::set<int> missingUnits;
// Search all units for pins creating implicit connections // Search all units for pins creating implicit connections
@ -3558,7 +3554,7 @@ void SCH_IO_EAGLE::addImplicitConnections( SCH_SYMBOL* aSymbol, SCH_SCREEN* aScr
} }
} }
if( aUpdateSet && aSymbol->GetLibSymbolRef()->GetUnitCount() > 1 ) if( aUpdateSet && aSymbol->GetLibSymbolRef().GetUnitCount() > 1 )
{ {
auto cmpIt = m_missingCmps.find( reference ); auto cmpIt = m_missingCmps.find( reference );

View File

@ -94,43 +94,6 @@ std::vector<KICAD_T> SCH_PAINTER::g_ScaledSelectionTypes = {
}; };
/**
* Used when a LIB_SYMBOL is not found in library to draw a dummy shape.
* This symbol is a 400 mils square with the text "??"
*
* DEF DUMMY U 0 40 Y Y 1 0 N
* F0 "U" 0 -350 60 H V
* F1 "DUMMY" 0 350 60 H V
* DRAW
* T 0 0 0 150 0 0 0 ??
* S -200 200 200 -200 0 1 0
* ENDDRAW
* ENDDEF
*/
static LIB_SYMBOL* dummy()
{
static LIB_SYMBOL* symbol;
if( !symbol )
{
symbol = new LIB_SYMBOL( wxEmptyString );
SCH_SHAPE* square = new SCH_SHAPE( SHAPE_T::RECTANGLE, LAYER_DEVICE );
square->SetPosition( VECTOR2I( schIUScale.MilsToIU( -200 ), schIUScale.MilsToIU( 200 ) ) );
square->SetEnd( VECTOR2I( schIUScale.MilsToIU( 200 ), schIUScale.MilsToIU( -200 ) ) );
symbol->AddDrawItem( square );
SCH_TEXT* text = new SCH_TEXT( { 0, 0 }, wxT( "??" ), LAYER_DEVICE );
text->SetTextSize( VECTOR2I( schIUScale.MilsToIU( 150 ), schIUScale.MilsToIU( 150 ) ) );
symbol->AddDrawItem( text );
}
return symbol;
}
SCH_PAINTER::SCH_PAINTER( GAL* aGal ) : SCH_PAINTER::SCH_PAINTER( GAL* aGal ) :
KIGFX::PAINTER( aGal ), KIGFX::PAINTER( aGal ),
m_schematic( nullptr ) m_schematic( nullptr )
@ -2175,13 +2138,10 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
int unit = aSymbol->GetUnitSelection( &m_schematic->CurrentSheet() ); int unit = aSymbol->GetUnitSelection( &m_schematic->CurrentSheet() );
int bodyStyle = aSymbol->GetBodyStyle(); int bodyStyle = aSymbol->GetBodyStyle();
// Use dummy symbol if the actual couldn't be found (or couldn't be locked). std::vector<SCH_PIN*> originalPins = aSymbol->GetLibSymbolRef().GetPins( unit, bodyStyle );
LIB_SYMBOL* originalSymbol = aSymbol->GetLibSymbolRef() ? aSymbol->GetLibSymbolRef().get()
: dummy();
std::vector<SCH_PIN*> originalPins = originalSymbol->GetPins( unit, bodyStyle );
// Copy the source so we can re-orient and translate it. // Copy the source so we can re-orient and translate it.
LIB_SYMBOL tempSymbol( *originalSymbol ); LIB_SYMBOL tempSymbol( aSymbol->GetLibSymbolRef() );
std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( unit, bodyStyle ); std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( unit, bodyStyle );
tempSymbol.SetFlags( aSymbol->GetFlags() ); tempSymbol.SetFlags( aSymbol->GetFlags() );
@ -2675,7 +2635,7 @@ void SCH_PAINTER::draw( const SCH_SHEET* aSheet, int aLayer )
{ {
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS; bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
bool DNP = aSheet->GetDNP(); bool DNP = aSheet->GetDNP();
bool markExclusion = eeconfig()->m_Appearance.mark_sim_exclusions bool markExclusion = eeconfig()->m_Appearance.mark_sim_exclusions
&& aSheet->GetExcludedFromSim(); && aSheet->GetExcludedFromSim();
if( m_schSettings.IsPrinting() && drawingShadows ) if( m_schSettings.IsPrinting() && drawingShadows )

View File

@ -544,10 +544,8 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
if( aStartAtCurrent && ref_unit.m_numRef > 0 ) if( aStartAtCurrent && ref_unit.m_numRef > 0 )
minRefId = ref_unit.m_numRef; minRefId = ref_unit.m_numRef;
wxCHECK( ref_unit.GetLibPart(), /* void */ );
// Annotation of one part per package symbols (trivial case). // Annotation of one part per package symbols (trivial case).
if( ref_unit.GetLibPart()->GetUnitCount() <= 1 ) if( ref_unit.GetLibSymbolRef().GetUnitCount() <= 1 )
{ {
if( ref_unit.m_isNew ) if( ref_unit.m_isNew )
{ {
@ -669,7 +667,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
tmp = wxT( "?" ); tmp = wxT( "?" );
if( ( m_flatList[ii].m_unit > 0 ) && ( m_flatList[ii].m_unit < 0x7FFFFFFF ) if( ( m_flatList[ii].m_unit > 0 ) && ( m_flatList[ii].m_unit < 0x7FFFFFFF )
&& m_flatList[ii].GetLibPart()->GetUnitCount() > 1 ) && m_flatList[ii].GetLibSymbolRef().GetUnitCount() > 1 )
{ {
msg.Printf( _( "Item not annotated: %s%s (unit %d)" ), msg.Printf( _( "Item not annotated: %s%s (unit %d)" ),
m_flatList[ii].GetRef(), m_flatList[ii].GetRef(),
@ -689,7 +687,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
// Error if unit number selected does not exist (greater than the number of units in // Error if unit number selected does not exist (greater than the number of units in
// the symbol). This can happen if a symbol has changed in a library after a // the symbol). This can happen if a symbol has changed in a library after a
// previous annotation. // previous annotation.
if( std::max( m_flatList[ii].GetLibPart()->GetUnitCount(), 1 ) < m_flatList[ii].m_unit ) if( std::max( m_flatList[ii].GetLibSymbolRef().GetUnitCount(), 1 ) < m_flatList[ii].m_unit )
{ {
if( m_flatList[ii].m_numRef >= 0 ) if( m_flatList[ii].m_numRef >= 0 )
tmp << m_flatList[ii].m_numRef; tmp << m_flatList[ii].m_numRef;
@ -701,7 +699,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
tmp, tmp,
m_flatList[ii].GetSymbol()->SubReference( m_flatList[ii].GetUnit() ), m_flatList[ii].GetSymbol()->SubReference( m_flatList[ii].GetUnit() ),
m_flatList[ii].m_unit, m_flatList[ii].m_unit,
m_flatList[ii].GetLibPart()->GetUnitCount() ); m_flatList[ii].GetLibSymbolRef().GetUnitCount() );
aHandler( ERCE_EXTRA_UNITS, msg, &m_flatList[ii], nullptr ); aHandler( ERCE_EXTRA_UNITS, msg, &m_flatList[ii], nullptr );
error++; error++;
@ -738,7 +736,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
msg.Printf( _( "Duplicate items %s%s%s\n" ), msg.Printf( _( "Duplicate items %s%s%s\n" ),
first.GetRef(), first.GetRef(),
tmp, tmp,
first.GetLibPart()->GetUnitCount() > 1 ? first.GetSymbol()->SubReference( first.GetUnit() ) first.GetLibSymbolRef().GetUnitCount() > 1 ? first.GetSymbol()->SubReference( first.GetUnit() )
: wxString( wxT( "" ) ) ); : wxString( wxT( "" ) ) );
aHandler( ERCE_DUPLICATE_REFERENCE, msg, &first, &m_flatList[ii+1] ); aHandler( ERCE_DUPLICATE_REFERENCE, msg, &first, &m_flatList[ii+1] );
@ -748,7 +746,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
/* Test error if units are different but number of parts per package /* Test error if units are different but number of parts per package
* too high (ex U3 ( 1 part) and we find U3B this is an error) */ * too high (ex U3 ( 1 part) and we find U3B this is an error) */
if( first.GetLibPart()->GetUnitCount() != second.GetLibPart()->GetUnitCount() ) if( first.GetLibSymbolRef().GetUnitCount() != second.GetLibSymbolRef().GetUnitCount() )
{ {
if( first.m_numRef >= 0 ) if( first.m_numRef >= 0 )
tmp << first.m_numRef; tmp << first.m_numRef;
@ -839,11 +837,10 @@ void SCH_REFERENCE::Annotate()
bool SCH_REFERENCE::AlwaysAnnotate() const bool SCH_REFERENCE::AlwaysAnnotate() const
{ {
wxCHECK( m_rootSymbol && m_rootSymbol->GetLibSymbolRef() wxCHECK( m_rootSymbol && !m_rootSymbol->GetRef( &m_sheetPath ).IsEmpty(), false );
&& !m_rootSymbol->GetRef( &m_sheetPath ).IsEmpty(), false );
return m_rootSymbol->GetLibSymbolRef()->IsPower() return m_rootSymbol->GetLibSymbolRef().IsPower()
|| m_rootSymbol->GetRef( &m_sheetPath )[0] == wxUniChar( '#' ); || m_rootSymbol->GetRef( &m_sheetPath )[0] == wxUniChar( '#' );
} }
@ -966,7 +963,7 @@ void SCH_REFERENCE_LIST::Show( const char* aPrefix )
SCH_REFERENCE& schref = m_flatList[i]; SCH_REFERENCE& schref = m_flatList[i];
printf( " [%-2d] ref:%-8s num:%-3d lib_part:%s\n", i, schref.m_ref.ToStdString().c_str(), printf( " [%-2d] ref:%-8s num:%-3d lib_part:%s\n", i, schref.m_ref.ToStdString().c_str(),
schref.m_numRef, TO_UTF8( schref.GetLibPart()->GetName() ) ); schref.m_numRef, TO_UTF8( schref.GetLibSymbolRef().GetName() ) );
} }
} }
#endif #endif

View File

@ -91,7 +91,7 @@ public:
SCH_SYMBOL* GetSymbol() const { return m_rootSymbol; } SCH_SYMBOL* GetSymbol() const { return m_rootSymbol; }
LIB_SYMBOL* GetLibPart() const { return m_rootSymbol->GetLibSymbolRef().get(); } LIB_SYMBOL& GetLibSymbolRef() const { return m_rootSymbol->GetLibSymbolRef(); }
const SCH_SHEET_PATH& GetSheetPath() const { return m_sheetPath; } const SCH_SHEET_PATH& GetSheetPath() const { return m_sheetPath; }
@ -99,7 +99,7 @@ public:
int GetUnit() const { return m_unit; } int GetUnit() const { return m_unit; }
void SetUnit( int aUnit ) { m_unit = aUnit; } void SetUnit( int aUnit ) { m_unit = aUnit; }
bool IsMultiUnit() const { return GetLibPart()->GetUnitCount() > 1; } bool IsMultiUnit() const { return GetLibSymbolRef().GetUnitCount() > 1; }
const wxString GetValue() const { return m_value; } const wxString GetValue() const { return m_value; }
void SetValue( const wxString& aValue ) { m_value = aValue; } void SetValue( const wxString& aValue ) { m_value = aValue; }
@ -188,7 +188,7 @@ public:
// To avoid a risk of duplicate, for power symbols the ref number is 0nnn instead of nnn. // To avoid a risk of duplicate, for power symbols the ref number is 0nnn instead of nnn.
// Just because sometimes only power symbols are annotated // Just because sometimes only power symbols are annotated
if( GetLibPart() && GetLibPart()->IsPower() ) if( GetLibSymbolRef().IsPower() )
ref = wxT( "0" ); ref = wxT( "0" );
return ref << m_numRef; return ref << m_numRef;
@ -225,10 +225,7 @@ public:
bool IsUnitsLocked() bool IsUnitsLocked()
{ {
if( GetLibPart() ) return GetLibSymbolRef().UnitsLocked();
return GetLibPart()->UnitsLocked();
else
return true; // Assume units locked when we don't have a library
} }
private: private:

View File

@ -160,16 +160,16 @@ void SCH_SCREEN::Append( SCH_ITEM* aItem, bool aUpdateLibSymbol )
{ {
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem ); SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem );
if( symbol->GetLibSymbolRef() ) if( symbol->GetLibSymbolRef().IsDummy() )
{ {
symbol->GetLibSymbolRef()->GetDrawItems().sort(); symbol->GetLibSymbolRef().GetDrawItems().sort();
auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() ); auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
if( it == m_libSymbols.end() || !it->second ) if( it == m_libSymbols.end() || !it->second )
{ {
m_libSymbols[symbol->GetSchSymbolLibraryName()] = m_libSymbols[symbol->GetSchSymbolLibraryName()] =
new LIB_SYMBOL( *symbol->GetLibSymbolRef() ); new LIB_SYMBOL( symbol->GetLibSymbolRef() );
} }
else else
{ {
@ -181,7 +181,7 @@ void SCH_SCREEN::Append( SCH_ITEM* aItem, bool aUpdateLibSymbol )
foundSymbol->GetDrawItems().sort(); foundSymbol->GetDrawItems().sort();
if( *foundSymbol != *symbol->GetLibSymbolRef() ) if( *foundSymbol != symbol->GetLibSymbolRef() )
{ {
wxString newName; wxString newName;
std::vector<wxString> matches; std::vector<wxString> matches;
@ -200,20 +200,20 @@ void SCH_SCREEN::Append( SCH_ITEM* aItem, bool aUpdateLibSymbol )
wxCHECK2( foundSymbol, continue ); wxCHECK2( foundSymbol, continue );
wxString tmp = symbol->GetLibSymbolRef()->GetName(); wxString tmp = symbol->GetLibSymbolRef().GetName();
// Temporarily update the new symbol library symbol name so it // Temporarily update the new symbol library symbol name so it
// doesn't fail on the name comparison below. // doesn't fail on the name comparison below.
symbol->GetLibSymbolRef()->SetName( foundSymbol->GetName() ); symbol->GetLibSymbolRef().SetName( foundSymbol->GetName() );
if( *foundSymbol == *symbol->GetLibSymbolRef() ) if( *foundSymbol == symbol->GetLibSymbolRef() )
{ {
newName = libSymbolName; newName = libSymbolName;
symbol->GetLibSymbolRef()->SetName( tmp ); symbol->GetLibSymbolRef().SetName( tmp );
break; break;
} }
symbol->GetLibSymbolRef()->SetName( tmp ); symbol->GetLibSymbolRef().SetName( tmp );
foundSymbol = nullptr; foundSymbol = nullptr;
} }
@ -243,11 +243,11 @@ void SCH_SCREEN::Append( SCH_ITEM* aItem, bool aUpdateLibSymbol )
// Update the schematic symbol library link as this symbol does not // Update the schematic symbol library link as this symbol does not
// exist in any symbol library. // exist in any symbol library.
LIB_ID newLibId( wxEmptyString, newName ); LIB_ID newLibId( wxEmptyString, newName );
LIB_SYMBOL* newLibSymbol = new LIB_SYMBOL( *symbol->GetLibSymbolRef() ); LIB_SYMBOL* newLibSymbol = new LIB_SYMBOL( symbol->GetLibSymbolRef() );
newLibSymbol->SetLibId( newLibId ); newLibSymbol->SetLibId( newLibId );
newLibSymbol->SetName( newName ); newLibSymbol->SetName( newName );
symbol->SetLibSymbol( newLibSymbol->Flatten().release() ); symbol->SetLibSymbol( newLibSymbol );
m_libSymbols[newName] = newLibSymbol; m_libSymbols[newName] = newLibSymbol;
} }
} }
@ -815,8 +815,7 @@ void SCH_SCREEN::UpdateSymbolLinks( REPORTER* aReporter )
aReporter->ReportTail( msg, RPT_SEVERITY_INFO ); aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
} }
// Internal library symbols are already flattened so just make a copy. symbol->SetLibSymbol( it->second );
symbol->SetLibSymbol( new LIB_SYMBOL( *it->second ) );
continue; continue;
} }
@ -919,7 +918,7 @@ void SCH_SCREEN::UpdateSymbolLinks( REPORTER* aReporter )
} }
if( libSymbol.get() ) // Only change the old link if the new link exists if( libSymbol.get() ) // Only change the old link if the new link exists
symbol->SetLibSymbol( libSymbol.release() ); symbol->SetLibSymbol( libSymbol.get() );
} }
// Changing the symbol may adjust the bbox of the symbol. This re-inserts the // Changing the symbol may adjust the bbox of the symbol. This re-inserts the
@ -946,9 +945,7 @@ void SCH_SCREEN::UpdateLocalLibSymbolLinks()
LIB_SYMBOL* libSymbol = nullptr; LIB_SYMBOL* libSymbol = nullptr;
if( it != m_libSymbols.end() ) if( it != m_libSymbols.end() )
libSymbol = new LIB_SYMBOL( *it->second ); symbol->SetLibSymbol( it->second );
symbol->SetLibSymbol( libSymbol );
m_rtree.insert( symbol ); m_rtree.insert( symbol );
} }
@ -1131,9 +1128,6 @@ SCH_PIN* SCH_SCREEN::GetPin( const VECTOR2I& aPosition, SCH_SYMBOL** aSymbol,
{ {
pin = nullptr; pin = nullptr;
if( !candidate->GetLibSymbolRef() )
continue;
for( SCH_PIN* test_pin : candidate->GetLibPins() ) for( SCH_PIN* test_pin : candidate->GetLibPins() )
{ {
if( candidate->GetPinPhysicalPosition( test_pin ) == aPosition ) if( candidate->GetPinPhysicalPosition( test_pin ) == aPosition )
@ -1514,8 +1508,7 @@ void SCH_SCREEN::FixLegacyPowerSymbolMismatches()
// Fix pre-8.0 legacy power symbols with invisible pins // Fix pre-8.0 legacy power symbols with invisible pins
// that have mismatched pin names and value fields // that have mismatched pin names and value fields
if( symbol->GetLibSymbolRef() if( symbol->GetLibSymbolRef().IsPower()
&& symbol->GetLibSymbolRef()->IsPower()
&& symbol->GetAllLibPins().size() > 0 && symbol->GetAllLibPins().size() > 0
&& symbol->GetAllLibPins()[0]->IsGlobalPower() && symbol->GetAllLibPins()[0]->IsGlobalPower()
&& !symbol->GetAllLibPins()[0]->IsVisible() ) && !symbol->GetAllLibPins()[0]->IsVisible() )

View File

@ -416,33 +416,27 @@ void SCH_SHEET_PATH::UpdateAllScreenReferences() const
} }
void SCH_SHEET_PATH::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols ) const
void SCH_SHEET_PATH::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols,
bool aForceIncludeOrphanSymbols ) const
{ {
for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_SYMBOL_T ) ) for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
{ {
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item ); SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
AppendSymbol( aReferences, symbol, aIncludePowerSymbols, aForceIncludeOrphanSymbols ); AppendSymbol( aReferences, symbol, aIncludePowerSymbols );
} }
} }
void SCH_SHEET_PATH::AppendSymbol( SCH_REFERENCE_LIST& aReferences, SCH_SYMBOL* aSymbol, void SCH_SHEET_PATH::AppendSymbol( SCH_REFERENCE_LIST& aReferences, SCH_SYMBOL* aSymbol,
bool aIncludePowerSymbols, bool aIncludePowerSymbols ) const
bool aForceIncludeOrphanSymbols ) const
{ {
// Skip pseudo-symbols, which have a reference starting with #. This mainly // Skip pseudo-symbols, which have a reference starting with #. This mainly
// affects power symbols. // affects power symbols.
if( aIncludePowerSymbols || aSymbol->GetRef( this )[0] != wxT( '#' ) ) if( aIncludePowerSymbols || aSymbol->GetRef( this )[0] != wxT( '#' ) )
{ {
if( aSymbol->GetLibSymbolRef() || aForceIncludeOrphanSymbols ) SCH_REFERENCE schReference( aSymbol, *this );
{
SCH_REFERENCE schReference( aSymbol, *this );
schReference.SetSheetNumber( m_virtualPageNumber ); schReference.SetSheetNumber( m_virtualPageNumber );
aReferences.AddItem( schReference ); aReferences.AddItem( schReference );
}
} }
} }
@ -462,14 +456,14 @@ void SCH_SHEET_PATH::AppendMultiUnitSymbol( SCH_MULTI_UNIT_REFERENCE_MAP& aRefLi
SCH_SYMBOL* aSymbol, SCH_SYMBOL* aSymbol,
bool aIncludePowerSymbols ) const bool aIncludePowerSymbols ) const
{ {
wxCHECK( aSymbol, /* void */ );
// Skip pseudo-symbols, which have a reference starting with #. This mainly // Skip pseudo-symbols, which have a reference starting with #. This mainly
// affects power symbols. // affects power symbols.
if( !aIncludePowerSymbols && aSymbol->GetRef( this )[0] == wxT( '#' ) ) if( !aIncludePowerSymbols && aSymbol->GetRef( this )[0] == wxT( '#' ) )
return; return;
LIB_SYMBOL* symbol = aSymbol->GetLibSymbolRef().get(); if( aSymbol->GetLibSymbolRef().GetUnitCount() > 1 )
if( symbol && symbol->GetUnitCount() > 1 )
{ {
SCH_REFERENCE schReference = SCH_REFERENCE( aSymbol, *this ); SCH_REFERENCE schReference = SCH_REFERENCE( aSymbol, *this );
schReference.SetSheetNumber( m_virtualPageNumber ); schReference.SetSheetNumber( m_virtualPageNumber );
@ -944,9 +938,8 @@ void SCH_SHEET_LIST::AnnotatePowerSymbols()
for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) ) for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
{ {
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item ); SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
LIB_SYMBOL* libSymbol = symbol->GetLibSymbolRef().get();
if( libSymbol && libSymbol->IsPower() ) if( symbol->GetLibSymbolRef().IsPower() )
{ {
SCH_REFERENCE schReference( symbol, sheet ); SCH_REFERENCE schReference( symbol, sheet );
references.AddItem( schReference ); references.AddItem( schReference );
@ -999,23 +992,21 @@ void SCH_SHEET_LIST::AnnotatePowerSymbols()
} }
void SCH_SHEET_LIST::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols, void SCH_SHEET_LIST::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols ) const
bool aForceIncludeOrphanSymbols ) const
{ {
for( const SCH_SHEET_PATH& sheet : *this ) for( const SCH_SHEET_PATH& sheet : *this )
sheet.GetSymbols( aReferences, aIncludePowerSymbols, aForceIncludeOrphanSymbols ); sheet.GetSymbols( aReferences, aIncludePowerSymbols );
} }
void SCH_SHEET_LIST::GetSymbolsWithinPath( SCH_REFERENCE_LIST& aReferences, void SCH_SHEET_LIST::GetSymbolsWithinPath( SCH_REFERENCE_LIST& aReferences,
const SCH_SHEET_PATH& aSheetPath, const SCH_SHEET_PATH& aSheetPath,
bool aIncludePowerSymbols, bool aIncludePowerSymbols ) const
bool aForceIncludeOrphanSymbols ) const
{ {
for( const SCH_SHEET_PATH& sheet : *this ) for( const SCH_SHEET_PATH& sheet : *this )
{ {
if( sheet.IsContainedWithin( aSheetPath ) ) if( sheet.IsContainedWithin( aSheetPath ) )
sheet.GetSymbols( aReferences, aIncludePowerSymbols, aForceIncludeOrphanSymbols ); sheet.GetSymbols( aReferences, aIncludePowerSymbols );
} }
} }

View File

@ -313,25 +313,17 @@ public:
* @param aReferences List of references to populate. * @param aReferences List of references to populate.
* @param aSymbol A symbol to add to aReferences * @param aSymbol A symbol to add to aReferences
* @param aIncludePowerSymbols set to false to only get normal symbols. * @param aIncludePowerSymbols set to false to only get normal symbols.
* @param aForceIncludeOrphanSymbols set to true to include symbols having no symbol found
* in lib. The normal option is false, and set to true
* only to build the full list of symbols.
*/ */
void AppendSymbol( SCH_REFERENCE_LIST& aReferences, SCH_SYMBOL* aSymbol, void AppendSymbol( SCH_REFERENCE_LIST& aReferences, SCH_SYMBOL* aSymbol,
bool aIncludePowerSymbols = true, bool aIncludePowerSymbols = true ) const;
bool aForceIncludeOrphanSymbols = false ) const;
/** /**
* Adds #SCH_REFERENCE object to \a aReferences for each symbol in the sheet. * Adds #SCH_REFERENCE object to \a aReferences for each symbol in the sheet.
* *
* @param aReferences List of references to populate. * @param aReferences List of references to populate.
* @param aIncludePowerSymbols set to false to only get normal symbols. * @param aIncludePowerSymbols set to false to only get normal symbols.
* @param aForceIncludeOrphanSymbols set to true to include symbols having no symbol found
* in lib. The normal option is false, and set to true
* only to build the full list of symbols.
*/ */
void GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true, void GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true ) const;
bool aForceIncludeOrphanSymbols = false ) const;
/** /**
* Append a #SCH_REFERENCE_LIST object to \a aRefList based on \a aSymbol, * Append a #SCH_REFERENCE_LIST object to \a aRefList based on \a aSymbol,
@ -509,12 +501,8 @@ public:
* *
* @param aReferences List of references to populate. * @param aReferences List of references to populate.
* @param aIncludePowerSymbols Set to false to only get normal symbols. * @param aIncludePowerSymbols Set to false to only get normal symbols.
* @param aForceIncludeOrphanSymbols Set to true to include symbols having no symbol found
* in lib. The normal option is false, and set to true
* only to build the full list of symbols.
*/ */
void GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true, void GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true ) const;
bool aForceIncludeOrphanSymbols = false ) const;
/** /**
* Add a #SCH_REFERENCE object to \a aReferences for each symbol in the list of sheets that are * Add a #SCH_REFERENCE object to \a aReferences for each symbol in the list of sheets that are
@ -523,13 +511,9 @@ public:
* @param aReferences List of references to populate. * @param aReferences List of references to populate.
* @param aSheetPath Path to return symbols from * @param aSheetPath Path to return symbols from
* @param aIncludePowerSymbols Set to false to only get normal symbols. * @param aIncludePowerSymbols Set to false to only get normal symbols.
* @param aForceIncludeOrphanSymbols Set to true to include symbols having no symbol found
* in lib. The normal option is false, and set to true
* only to build the full list of symbols.
*/ */
void GetSymbolsWithinPath( SCH_REFERENCE_LIST& aReferences, const SCH_SHEET_PATH& aSheetPath, void GetSymbolsWithinPath( SCH_REFERENCE_LIST& aReferences, const SCH_SHEET_PATH& aSheetPath,
bool aIncludePowerSymbols = true, bool aIncludePowerSymbols = true ) const;
bool aForceIncludeOrphanSymbols = false ) const;
/** /**
* Add a #SCH_SHEET_PATH object to \a aSheets for each sheet in the list that are * Add a #SCH_SHEET_PATH object to \a aSheets for each sheet in the list that are

View File

@ -63,40 +63,7 @@ std::string toUTFTildaText( const wxString& txt )
} }
/** SCH_SYMBOL::SCH_SYMBOL() : SCH_SYMBOL( *LIB_SYMBOL::Dummy(), LIB_ID(), nullptr, 0 ) { }
* Used to draw a dummy shape when a LIB_SYMBOL is not found in library
*
* This symbol is a 400 mils square with the text "??"
*/
static LIB_SYMBOL* dummy()
{
static LIB_SYMBOL* symbol;
if( !symbol )
{
symbol = new LIB_SYMBOL( wxEmptyString );
SCH_SHAPE* square = new SCH_SHAPE( SHAPE_T::RECTANGLE, LAYER_DEVICE );
square->SetPosition( VECTOR2I( schIUScale.MilsToIU( -200 ), schIUScale.MilsToIU( 200 ) ) );
square->SetEnd( VECTOR2I( schIUScale.MilsToIU( 200 ), schIUScale.MilsToIU( -200 ) ) );
symbol->AddDrawItem( square );
SCH_TEXT* text = new SCH_TEXT( { 0, 0 }, wxT( "??"), LAYER_DEVICE );
text->SetTextSize( VECTOR2I( schIUScale.MilsToIU( 150 ), schIUScale.MilsToIU( 150 ) ) );
symbol->AddDrawItem( text );
}
return symbol;
}
SCH_SYMBOL::SCH_SYMBOL() :
SYMBOL( nullptr, SCH_SYMBOL_T )
{
Init( VECTOR2I( 0, 0 ) );
}
SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId, SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId,
@ -104,17 +71,13 @@ SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId,
const VECTOR2I& aPosition, EDA_ITEM* aParent ) : const VECTOR2I& aPosition, EDA_ITEM* aParent ) :
SYMBOL( aParent, SCH_SYMBOL_T ) SYMBOL( aParent, SCH_SYMBOL_T )
{ {
SetLibSymbol( &aSymbol );
Init( aPosition ); Init( aPosition );
m_unit = aUnit; m_unit = aUnit;
m_bodyStyle = aBodyStyle; m_bodyStyle = aBodyStyle;
m_lib_id = aLibId; m_lib_id = aLibId;
std::unique_ptr< LIB_SYMBOL > part;
part = aSymbol.Flatten();
part->SetParent();
SetLibSymbol( part.release() );
// Copy fields from the library symbol // Copy fields from the library symbol
UpdateFields( aSheet, UpdateFields( aSheet,
@ -155,6 +118,8 @@ SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const SCH_SHEET_PATH* aSheet,
SCH_SYMBOL::SCH_SYMBOL( const SCH_SYMBOL& aSymbol ) : SCH_SYMBOL::SCH_SYMBOL( const SCH_SYMBOL& aSymbol ) :
SYMBOL( aSymbol ) SYMBOL( aSymbol )
{ {
SetLibSymbol( &aSymbol.GetLibSymbolRef() );
m_parent = aSymbol.m_parent; m_parent = aSymbol.m_parent;
m_pos = aSymbol.m_pos; m_pos = aSymbol.m_pos;
m_unit = aSymbol.m_unit; m_unit = aSymbol.m_unit;
@ -183,9 +148,6 @@ SCH_SYMBOL::SCH_SYMBOL( const SCH_SYMBOL& aSymbol ) :
m_pins.back()->SetParent( this ); m_pins.back()->SetParent( this );
} }
if( aSymbol.m_part )
SetLibSymbol( new LIB_SYMBOL( *aSymbol.m_part ) );
m_fieldsAutoplaced = aSymbol.m_fieldsAutoplaced; m_fieldsAutoplaced = aSymbol.m_fieldsAutoplaced;
m_schLibSymbolName = aSymbol.m_schLibSymbolName; m_schLibSymbolName = aSymbol.m_schLibSymbolName;
} }
@ -230,12 +192,6 @@ EDA_ITEM* SCH_SYMBOL::Clone() const
} }
bool SCH_SYMBOL::IsMissingLibSymbol() const
{
return m_part == nullptr;
}
bool SCH_SYMBOL::IsMovableFromAnchorPoint() const bool SCH_SYMBOL::IsMovableFromAnchorPoint() const
{ {
// If a symbol's anchor is not grid-aligned to its pins then moving from the anchor is // If a symbol's anchor is not grid-aligned to its pins then moving from the anchor is
@ -272,39 +228,31 @@ wxString SCH_SYMBOL::GetSchSymbolLibraryName() const
} }
void SCH_SYMBOL::SetLibSymbol( LIB_SYMBOL* aLibSymbol ) void SCH_SYMBOL::SetLibSymbol( const LIB_SYMBOL* aLibSymbol )
{ {
wxCHECK2( !aLibSymbol || aLibSymbol->IsRoot(), aLibSymbol = nullptr ); wxASSERT_MSG( aLibSymbol, wxT( "SCH_SYMBOL::SetLibSymbol() called with NULL pointer" ) );
m_part.reset( aLibSymbol ); m_part.reset( aLibSymbol->Flatten().release() );
m_part->SetParent();
UpdatePins(); UpdatePins();
} }
wxString SCH_SYMBOL::GetDescription() const wxString SCH_SYMBOL::GetDescription() const
{ {
if( m_part ) return m_part->GetDescription();
return m_part->GetDescription();
return wxEmptyString;
} }
wxString SCH_SYMBOL::GetKeyWords() const wxString SCH_SYMBOL::GetKeyWords() const
{ {
if( m_part ) return m_part->GetKeyWords();
return m_part->GetKeyWords();
return wxEmptyString;
} }
wxString SCH_SYMBOL::GetDatasheet() const wxString SCH_SYMBOL::GetDatasheet() const
{ {
if( m_part ) return m_part->GetDatasheetField().GetText();
return m_part->GetDatasheetField().GetText();
return wxEmptyString;
} }
@ -329,9 +277,6 @@ void SCH_SYMBOL::UpdatePins()
m_pinMap.clear(); m_pinMap.clear();
if( !m_part )
return;
for( SCH_PIN* libPin : m_part->GetAllLibPins() ) for( SCH_PIN* libPin : m_part->GetAllLibPins() )
{ {
// NW: Don't filter by unit: this data-structure is used for all instances, // NW: Don't filter by unit: this data-structure is used for all instances,
@ -435,10 +380,7 @@ void SCH_SYMBOL::SetBodyStyle( int aBodyStyle )
bool SCH_SYMBOL::HasAlternateBodyStyle() const bool SCH_SYMBOL::HasAlternateBodyStyle() const
{ {
if( m_part ) return m_part->HasAlternateBodyStyle();
return m_part->HasAlternateBodyStyle();
return false;
} }
@ -450,25 +392,18 @@ void SCH_SYMBOL::SetTransform( const TRANSFORM& aTransform )
int SCH_SYMBOL::GetUnitCount() const int SCH_SYMBOL::GetUnitCount() const
{ {
if( m_part ) return m_part->GetUnitCount();
return m_part->GetUnitCount();
return 0;
} }
wxString SCH_SYMBOL::GetUnitDisplayName( int aUnit ) const wxString SCH_SYMBOL::GetUnitDisplayName( int aUnit ) const
{ {
wxCHECK( m_part, ( wxString::Format( _( "Unit %s" ), SubReference( aUnit ) ) ) );
return m_part->GetUnitDisplayName( aUnit ); return m_part->GetUnitDisplayName( aUnit );
} }
bool SCH_SYMBOL::HasUnitDisplayName( int aUnit ) const bool SCH_SYMBOL::HasUnitDisplayName( int aUnit ) const
{ {
wxCHECK( m_part, false );
return m_part->HasUnitDisplayName( aUnit ); return m_part->HasUnitDisplayName( aUnit );
} }
@ -476,8 +411,6 @@ bool SCH_SYMBOL::HasUnitDisplayName( int aUnit ) const
void SCH_SYMBOL::PrintBackground( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle, void SCH_SYMBOL::PrintBackground( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
const VECTOR2I& aOffset, bool aDimmed ) const VECTOR2I& aOffset, bool aDimmed )
{ {
wxCHECK( m_part, /* void */ );
SCH_RENDER_SETTINGS localRenderSettings( *aSettings ); SCH_RENDER_SETTINGS localRenderSettings( *aSettings );
localRenderSettings.m_Transform = m_transform; localRenderSettings.m_Transform = m_transform;
localRenderSettings.m_ShowVisibleFields = false; localRenderSettings.m_ShowVisibleFields = false;
@ -501,42 +434,35 @@ void SCH_SYMBOL::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBo
if( m_DNP ) if( m_DNP )
aDimmed = true; aDimmed = true;
if( m_part ) std::vector<SCH_PIN*> libPins = m_part->GetPins( m_unit, m_bodyStyle );
LIB_SYMBOL tempSymbol( *m_part );
std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( m_unit, m_bodyStyle );
// Copy the pin info from the symbol to the temp pins
for( unsigned i = 0; i < tempPins.size(); ++ i )
{ {
std::vector<SCH_PIN*> libPins = m_part->GetPins( m_unit, m_bodyStyle ); SCH_PIN* symbolPin = GetPin( libPins[ i ] );
LIB_SYMBOL tempSymbol( *m_part ); SCH_PIN* tempPin = tempPins[ i ];
std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( m_unit, m_bodyStyle );
// Copy the pin info from the symbol to the temp pins tempPin->SetName( symbolPin->GetShownName() );
for( unsigned i = 0; i < tempPins.size(); ++ i ) tempPin->SetType( symbolPin->GetType() );
{ tempPin->SetShape( symbolPin->GetShape() );
SCH_PIN* symbolPin = GetPin( libPins[ i ] );
SCH_PIN* tempPin = tempPins[ i ];
tempPin->SetName( symbolPin->GetShownName() );
tempPin->SetType( symbolPin->GetType() );
tempPin->SetShape( symbolPin->GetShape() );
}
for( SCH_ITEM& item : tempSymbol.GetDrawItems() )
{
if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( &item ) )
{
// Use SCH_FIELD's text resolver
SCH_FIELD dummy( this, -1 );
dummy.SetText( text->GetText() );
text->SetText( dummy.GetShownText( false ) );
}
}
tempSymbol.Print( &localRenderSettings, m_unit, m_bodyStyle, m_pos + aOffset, false,
aDimmed );
} }
else // Use dummy() part if the actual cannot be found.
for( SCH_ITEM& item : tempSymbol.GetDrawItems() )
{ {
dummy()->Print( &localRenderSettings, 0, 0, m_pos + aOffset, aForceNoFill, aDimmed ); if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( &item ) )
{
// Use SCH_FIELD's text resolver
SCH_FIELD dummy( this, -1 );
dummy.SetText( text->GetText() );
text->SetText( dummy.GetShownText( false ) );
}
} }
tempSymbol.Print( &localRenderSettings, m_unit, m_bodyStyle, m_pos + aOffset, false,
aDimmed );
for( SCH_FIELD& field : m_fields ) for( SCH_FIELD& field : m_fields )
field.Print( &localRenderSettings, m_unit, m_bodyStyle, aOffset, aForceNoFill, aDimmed ); field.Print( &localRenderSettings, m_unit, m_bodyStyle, aOffset, aForceNoFill, aDimmed );
@ -1025,66 +951,63 @@ SCH_FIELD* SCH_SYMBOL::FindField( const wxString& aFieldName, bool aIncludeDefau
void SCH_SYMBOL::UpdateFields( const SCH_SHEET_PATH* aPath, bool aUpdateStyle, bool aUpdateRef, void SCH_SYMBOL::UpdateFields( const SCH_SHEET_PATH* aPath, bool aUpdateStyle, bool aUpdateRef,
bool aUpdateOtherFields, bool aResetRef, bool aResetOtherFields ) bool aUpdateOtherFields, bool aResetRef, bool aResetOtherFields )
{ {
if( m_part ) std::vector<SCH_FIELD*> fields;
m_part->GetFields( fields );
for( const SCH_FIELD* libField : fields )
{ {
std::vector<SCH_FIELD*> fields; int id = libField->GetId();
m_part->GetFields( fields ); SCH_FIELD* schField;
for( const SCH_FIELD* libField : fields ) if( libField->IsMandatory() )
{ {
int id = libField->GetId(); schField = GetFieldById( id );
SCH_FIELD* schField; }
else
{
schField = FindField( libField->GetCanonicalName() );
if( libField->IsMandatory() ) if( !schField )
{ {
schField = GetFieldById( id ); wxString fieldName = libField->GetCanonicalName();
SCH_FIELD newField( VECTOR2I( 0, 0 ), GetFieldCount(), this, fieldName );
schField = AddField( newField );
} }
else }
{
schField = FindField( libField->GetCanonicalName() );
if( !schField ) if( aUpdateStyle )
{ {
wxString fieldName = libField->GetCanonicalName(); schField->ImportValues( *libField );
SCH_FIELD newField( VECTOR2I( 0, 0 ), GetFieldCount(), this, fieldName ); schField->SetTextPos( m_pos + libField->GetTextPos() );
schField = AddField( newField ); }
}
}
if( aUpdateStyle ) if( id == REFERENCE_FIELD && aPath )
{ {
schField->ImportValues( *libField ); if( aResetRef )
schField->SetTextPos( m_pos + libField->GetTextPos() ); SetRef( aPath, m_part->GetReferenceField().GetText() );
} else if( aUpdateRef )
SetRef( aPath, libField->GetText() );
if( id == REFERENCE_FIELD && aPath ) }
{ else if( id == VALUE_FIELD )
if( aResetRef ) {
SetRef( aPath, m_part->GetReferenceField().GetText() ); SetValueFieldText( UnescapeString( libField->GetText() ) );
else if( aUpdateRef ) }
SetRef( aPath, libField->GetText() ); else if( id == FOOTPRINT_FIELD )
} {
else if( id == VALUE_FIELD ) if( aResetOtherFields || aUpdateOtherFields )
{ SetFootprintFieldText( libField->GetText() );
SetValueFieldText( UnescapeString( libField->GetText() ) ); }
} else if( id == DATASHEET_FIELD )
else if( id == FOOTPRINT_FIELD ) {
{ if( aResetOtherFields )
if( aResetOtherFields || aUpdateOtherFields ) schField->SetText( GetDatasheet() ); // alias-specific value
SetFootprintFieldText( libField->GetText() ); else if( aUpdateOtherFields )
} schField->SetText( libField->GetText() );
else if( id == DATASHEET_FIELD ) }
{ else
if( aResetOtherFields ) {
schField->SetText( GetDatasheet() ); // alias-specific value if( aResetOtherFields || aUpdateOtherFields )
else if( aUpdateOtherFields ) schField->SetText( libField->GetText() );
schField->SetText( libField->GetText() );
}
else
{
if( aResetOtherFields || aUpdateOtherFields )
schField->SetText( libField->GetText() );
}
} }
} }
} }
@ -1137,19 +1060,13 @@ const SCH_PIN* SCH_SYMBOL::GetPin( const VECTOR2I& aPos ) const
std::vector<SCH_PIN*> SCH_SYMBOL::GetLibPins() const std::vector<SCH_PIN*> SCH_SYMBOL::GetLibPins() const
{ {
if( m_part ) return m_part->GetPins( m_unit, m_bodyStyle );
return m_part->GetPins( m_unit, m_bodyStyle );
return std::vector<SCH_PIN*>();
} }
std::vector<SCH_PIN*> SCH_SYMBOL::GetAllLibPins() const std::vector<SCH_PIN*> SCH_SYMBOL::GetAllLibPins() const
{ {
if( m_part ) return m_part->GetAllLibPins();
return m_part->GetAllLibPins();
return std::vector<SCH_PIN*>();
} }
@ -1839,11 +1756,7 @@ BOX2I SCH_SYMBOL::doGetBoundingBox( bool aIncludePins, bool aIncludeFields ) con
{ {
BOX2I bBox; BOX2I bBox;
if( m_part ) bBox = m_part->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
bBox = m_part->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
else
bBox = dummy()->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
bBox = m_transform.TransformCoordinate( bBox ); bBox = m_transform.TransformCoordinate( bBox );
bBox.Normalize(); bBox.Normalize();
@ -1921,87 +1834,64 @@ void SCH_SYMBOL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_
aList.emplace_back( _( "Exclude from" ), msg ); aList.emplace_back( _( "Exclude from" ), msg );
}; };
// part and alias can differ if alias is not the root if( !m_part->IsDummy() )
if( m_part )
{ {
if( m_part.get() != dummy() ) if( m_part->IsPower() )
{ {
if( m_part->IsPower() ) // Don't use GetShownText(); we want to see the variable references here
{ aList.emplace_back( _( "Power symbol" ),
// Don't use GetShownText(); we want to see the variable references here KIUI::EllipsizeStatusText( aFrame, GetField( VALUE_FIELD )->GetText() ) );
aList.emplace_back( _( "Power symbol" ), }
KIUI::EllipsizeStatusText( aFrame, GetField( VALUE_FIELD )->GetText() ) ); else
} {
else aList.emplace_back( _( "Reference" ),
{ UnescapeString( GetRef( currentSheet ) ) );
aList.emplace_back( _( "Reference" ),
UnescapeString( GetRef( currentSheet ) ) );
// Don't use GetShownText(); we want to see the variable references here // Don't use GetShownText(); we want to see the variable references here
aList.emplace_back( _( "Value" ), aList.emplace_back( _( "Value" ),
KIUI::EllipsizeStatusText( aFrame, GetField( VALUE_FIELD )->GetText() ) ); KIUI::EllipsizeStatusText( aFrame, GetField( VALUE_FIELD )->GetText() ) );
addExcludes(); addExcludes();
aList.emplace_back( _( "Name" ), aList.emplace_back( _( "Name" ),
KIUI::EllipsizeStatusText( aFrame, GetLibId().GetLibItemName() ) ); KIUI::EllipsizeStatusText( aFrame, GetLibId().GetLibItemName() ) );
} }
#if 0 // Display symbol flags, for debug only #if 0 // Display symbol flags, for debug only
aList.emplace_back( _( "flags" ), wxString::Format( "%X", GetEditFlags() ) ); aList.emplace_back( _( "flags" ), wxString::Format( "%X", GetEditFlags() ) );
#endif #endif
if( !m_part->IsRoot() ) if( !m_part->IsRoot() )
{ {
msg = _( "Missing parent" ); msg = _( "Missing parent" );
std::shared_ptr< LIB_SYMBOL > parent = m_part->GetParent().lock(); std::shared_ptr< LIB_SYMBOL > parent = m_part->GetParent().lock();
if( parent ) if( parent )
msg = parent->GetName(); msg = parent->GetName();
aList.emplace_back( _( "Derived from" ), UnescapeString( msg ) ); aList.emplace_back( _( "Derived from" ), UnescapeString( msg ) );
} }
else if( !m_lib_id.GetLibNickname().empty() ) else if( !m_lib_id.GetLibNickname().empty() )
{ {
aList.emplace_back( _( "Library" ), m_lib_id.GetLibNickname() ); aList.emplace_back( _( "Library" ), m_lib_id.GetLibNickname() );
}
else
{
aList.emplace_back( _( "Library" ), _( "Undefined!!!" ) );
}
// Display the current associated footprint, if exists.
// Don't use GetShownText(); we want to see the variable references here
msg = KIUI::EllipsizeStatusText( aFrame, GetField( FOOTPRINT_FIELD )->GetText() );
if( msg.IsEmpty() )
msg = _( "<Unknown>" );
aList.emplace_back( _( "Footprint" ), msg );
// Display description of the symbol, and keywords found in lib
aList.emplace_back( _( "Description" ) + wxT( ": " )
+ GetField( DESCRIPTION_FIELD )->GetText(),
_( "Keywords" ) + wxT( ": " ) + m_part->GetKeyWords() );
} }
}
else
{
aList.emplace_back( _( "Reference" ), GetRef( currentSheet ) );
// Don't use GetShownText(); we want to see the variable references here
aList.emplace_back( _( "Value" ),
KIUI::EllipsizeStatusText( aFrame, GetField( VALUE_FIELD )->GetText() ) );
addExcludes();
aList.emplace_back( _( "Name" ),
KIUI::EllipsizeStatusText( aFrame, GetLibId().GetLibItemName() ) );
wxString libNickname = GetLibId().GetLibNickname();
if( libNickname.empty() )
msg = _( "No library defined!" );
else else
msg.Printf( _( "Symbol not found in %s!" ), libNickname ); {
aList.emplace_back( _( "Library" ), _( "Undefined!!!" ) );
}
aList.emplace_back( _( "Library" ), msg ); // Display the current associated footprint, if exists.
// Don't use GetShownText(); we want to see the variable references here
msg = KIUI::EllipsizeStatusText( aFrame, GetField( FOOTPRINT_FIELD )->GetText() );
if( msg.IsEmpty() )
msg = _( "<Unknown>" );
aList.emplace_back( _( "Footprint" ), msg );
// Display description of the symbol, and keywords found in lib
aList.emplace_back( _( "Description" ) + wxT( ": " )
+ GetField( DESCRIPTION_FIELD )->GetText(),
_( "Keywords" ) + wxT( ": " ) + m_part->GetKeyWords() );
} }
} }
@ -2221,15 +2111,10 @@ std::vector<VECTOR2I> SCH_SYMBOL::GetConnectionPoints() const
SCH_ITEM* SCH_SYMBOL::GetDrawItem( const VECTOR2I& aPosition, KICAD_T aType ) SCH_ITEM* SCH_SYMBOL::GetDrawItem( const VECTOR2I& aPosition, KICAD_T aType )
{ {
if( m_part ) // Calculate the position relative to the symbol.
{ VECTOR2I libPosition = aPosition - m_pos;
// Calculate the position relative to the symbol.
VECTOR2I libPosition = aPosition - m_pos;
return m_part->LocateDrawItem( m_unit, m_bodyStyle, aType, libPosition, m_transform ); return m_part->LocateDrawItem( m_unit, m_bodyStyle, aType, libPosition, m_transform );
}
return nullptr;
} }
@ -2460,94 +2345,91 @@ void SCH_SYMBOL::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS&
if( aBackground ) if( aBackground )
return; return;
if( m_part ) std::vector<SCH_PIN*> libPins = m_part->GetPins( GetUnit(), GetBodyStyle() );
// Copy the source so we can re-orient and translate it.
LIB_SYMBOL tempSymbol( *m_part );
std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( GetUnit(), GetBodyStyle() );
// Copy the pin info from the symbol to the temp pins
for( unsigned i = 0; i < tempPins.size(); ++ i )
{ {
std::vector<SCH_PIN*> libPins = m_part->GetPins( GetUnit(), GetBodyStyle() ); SCH_PIN* symbolPin = GetPin( libPins[ i ] );
SCH_PIN* tempPin = tempPins[ i ];
// Copy the source so we can re-orient and translate it. tempPin->SetName( symbolPin->GetShownName() );
LIB_SYMBOL tempSymbol( *m_part ); tempPin->SetType( symbolPin->GetType() );
std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( GetUnit(), GetBodyStyle() ); tempPin->SetShape( symbolPin->GetShape() );
// Copy the pin info from the symbol to the temp pins if( symbolPin->IsDangling() )
for( unsigned i = 0; i < tempPins.size(); ++ i ) tempPin->SetFlags( IS_DANGLING );
{
SCH_PIN* symbolPin = GetPin( libPins[ i ] );
SCH_PIN* tempPin = tempPins[ i ];
tempPin->SetName( symbolPin->GetShownName() );
tempPin->SetType( symbolPin->GetType() );
tempPin->SetShape( symbolPin->GetShape() );
if( symbolPin->IsDangling() )
tempPin->SetFlags( IS_DANGLING );
}
for( SCH_ITEM& item : tempSymbol.GetDrawItems() )
{
if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( &item ) )
{
// Use SCH_FIELD's text resolver
SCH_FIELD dummy( this, -1 );
dummy.SetText( text->GetText() );
text->SetText( dummy.GetShownText( false ) );
}
}
SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
TRANSFORM savedTransform = renderSettings->m_Transform;
renderSettings->m_Transform = GetTransform();
aPlotter->StartBlock( nullptr );
for( bool local_background : { true, false } )
{
tempSymbol.Plot( aPlotter, local_background, aPlotOpts, GetUnit(), GetBodyStyle(),
m_pos, GetDNP() );
for( SCH_FIELD field : m_fields )
{
field.ClearRenderCache();
field.Plot( aPlotter, local_background, aPlotOpts, GetUnit(), GetBodyStyle(),
m_pos, GetDNP() );
}
}
if( m_DNP )
PlotDNP( aPlotter );
SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
// Plot attributes to a hypertext menu
if( aPlotOpts.m_PDFPropertyPopups )
{
std::vector<wxString> properties;
for( const SCH_FIELD& field : GetFields() )
{
wxString text_field = field.GetShownText( sheet, false);
if( text_field.IsEmpty() )
continue;
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
field.GetName(), text_field ) );
}
if( !m_part->GetKeyWords().IsEmpty() )
{
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
_( "Keywords" ),
m_part->GetKeyWords() ) );
}
aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
}
aPlotter->EndBlock( nullptr );
renderSettings->m_Transform = savedTransform;
if( !m_part->IsPower() )
aPlotter->Bookmark( GetBoundingBox(), GetRef( sheet ), _( "Symbols" ) );
} }
for( SCH_ITEM& item : tempSymbol.GetDrawItems() )
{
if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( &item ) )
{
// Use SCH_FIELD's text resolver
SCH_FIELD dummy( this, -1 );
dummy.SetText( text->GetText() );
text->SetText( dummy.GetShownText( false ) );
}
}
SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
TRANSFORM savedTransform = renderSettings->m_Transform;
renderSettings->m_Transform = GetTransform();
aPlotter->StartBlock( nullptr );
for( bool local_background : { true, false } )
{
tempSymbol.Plot( aPlotter, local_background, aPlotOpts, GetUnit(), GetBodyStyle(),
m_pos, GetDNP() );
for( SCH_FIELD field : m_fields )
{
field.ClearRenderCache();
field.Plot( aPlotter, local_background, aPlotOpts, GetUnit(), GetBodyStyle(),
m_pos, GetDNP() );
}
}
if( m_DNP )
PlotDNP( aPlotter );
SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
// Plot attributes to a hypertext menu
if( aPlotOpts.m_PDFPropertyPopups )
{
std::vector<wxString> properties;
for( const SCH_FIELD& field : GetFields() )
{
wxString text_field = field.GetShownText( sheet, false);
if( text_field.IsEmpty() )
continue;
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
field.GetName(), text_field ) );
}
if( !m_part->GetKeyWords().IsEmpty() )
{
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
_( "Keywords" ),
m_part->GetKeyWords() ) );
}
aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
}
aPlotter->EndBlock( nullptr );
renderSettings->m_Transform = savedTransform;
if( !m_part->IsPower() )
aPlotter->Bookmark( GetBoundingBox(), GetRef( sheet ), _( "Symbols" ) );
} }
@ -2578,33 +2460,30 @@ void SCH_SYMBOL::PlotDNP( PLOTTER* aPlotter ) const
void SCH_SYMBOL::PlotPins( PLOTTER* aPlotter ) const void SCH_SYMBOL::PlotPins( PLOTTER* aPlotter ) const
{ {
if( m_part ) SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
TRANSFORM savedTransform = renderSettings->m_Transform;
renderSettings->m_Transform = GetTransform();
std::vector<SCH_PIN*> libPins = m_part->GetPins( GetUnit(), GetBodyStyle() );
// Copy the source to stay const
LIB_SYMBOL tempSymbol( *m_part );
std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( GetUnit(), GetBodyStyle() );
SCH_PLOT_OPTS plotOpts;
// Copy the pin info from the symbol to the temp pins
for( unsigned i = 0; i < tempPins.size(); ++ i )
{ {
SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter ); SCH_PIN* symbolPin = GetPin( libPins[ i ] );
TRANSFORM savedTransform = renderSettings->m_Transform; SCH_PIN* tempPin = tempPins[ i ];
renderSettings->m_Transform = GetTransform();
std::vector<SCH_PIN*> libPins = m_part->GetPins( GetUnit(), GetBodyStyle() ); tempPin->SetName( symbolPin->GetShownName() );
tempPin->SetType( symbolPin->GetType() );
// Copy the source to stay const tempPin->SetShape( symbolPin->GetShape() );
LIB_SYMBOL tempSymbol( *m_part ); tempPin->Plot( aPlotter, false, plotOpts, GetUnit(), GetBodyStyle(), m_pos, GetDNP() );
std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( GetUnit(), GetBodyStyle() );
SCH_PLOT_OPTS plotOpts;
// Copy the pin info from the symbol to the temp pins
for( unsigned i = 0; i < tempPins.size(); ++ i )
{
SCH_PIN* symbolPin = GetPin( libPins[ i ] );
SCH_PIN* tempPin = tempPins[ i ];
tempPin->SetName( symbolPin->GetShownName() );
tempPin->SetType( symbolPin->GetType() );
tempPin->SetShape( symbolPin->GetShape() );
tempPin->Plot( aPlotter, false, plotOpts, GetUnit(), GetBodyStyle(), m_pos, GetDNP() );
}
renderSettings->m_Transform = savedTransform;
} }
renderSettings->m_Transform = savedTransform;
} }
@ -2686,7 +2565,7 @@ bool SCH_SYMBOL::IsSymbolLikePowerGlobalLabel() const
// It is a Power symbol // It is a Power symbol
// It has only one pin type Power input // It has only one pin type Power input
if( !GetLibSymbolRef() || !GetLibSymbolRef()->IsPower() ) if( !GetLibSymbolRef().IsPower() )
return false; return false;
std::vector<SCH_PIN*> pin_list = GetAllLibPins(); std::vector<SCH_PIN*> pin_list = GetAllLibPins();
@ -2700,16 +2579,12 @@ bool SCH_SYMBOL::IsSymbolLikePowerGlobalLabel() const
bool SCH_SYMBOL::IsPower() const bool SCH_SYMBOL::IsPower() const
{ {
wxCHECK( m_part, false );
return m_part->IsPower(); return m_part->IsPower();
} }
bool SCH_SYMBOL::IsNormal() const bool SCH_SYMBOL::IsNormal() const
{ {
wxCHECK( m_part, false );
return m_part->IsNormal(); return m_part->IsNormal();
} }
@ -2798,22 +2673,11 @@ static struct SCH_SYMBOL_DESC
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Mirror Y" ), propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Mirror Y" ),
&SCH_SYMBOL::SetMirrorY, &SCH_SYMBOL::GetMirrorY ) ); &SCH_SYMBOL::SetMirrorY, &SCH_SYMBOL::GetMirrorY ) );
auto hasLibPart =
[]( INSPECTABLE* aItem ) -> bool
{
if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
return symbol->GetLibSymbolRef() != nullptr;
return false;
};
propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Pin numbers" ), propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Pin numbers" ),
&SYMBOL::SetShowPinNumbers, &SYMBOL::GetShowPinNumbers ) ) &SYMBOL::SetShowPinNumbers, &SYMBOL::GetShowPinNumbers ) );
.SetAvailableFunc( hasLibPart );
propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Pin names" ), propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Pin names" ),
&SYMBOL::SetShowPinNames, &SYMBOL::GetShowPinNames ) ) &SYMBOL::SetShowPinNames, &SYMBOL::GetShowPinNames ) );
.SetAvailableFunc( hasLibPart );
const wxString groupFields = _HKI( "Fields" ); const wxString groupFields = _HKI( "Fields" );

View File

@ -146,21 +146,6 @@ public:
return wxT( "SCH_SYMBOL" ); return wxT( "SCH_SYMBOL" );
} }
/**
* Check to see if the library symbol is set to the dummy library symbol.
*
* When the library symbol is missing (which technically should not happen now that the
* library symbols are cached in the schematic file), a dummy library symbol is substituted
* for the missing symbol as an indicator that something is amiss. The dummy symbol cannot
* be edited so a check for this symbol must be performed before attempting to edit the
* library symbol with the library editor or it will crash KiCad.
*
* @see dummy()
*
* @return true if the library symbol is missing or false if it is valid.
*/
bool IsMissingLibSymbol() const;
const std::vector<SCH_SYMBOL_INSTANCE>& GetInstances() const const std::vector<SCH_SYMBOL_INSTANCE>& GetInstances() const
{ {
return m_instanceReferences; return m_instanceReferences;
@ -210,26 +195,18 @@ public:
wxString GetSchSymbolLibraryName() const; wxString GetSchSymbolLibraryName() const;
bool UseLibIdLookup() const { return m_schLibSymbolName.IsEmpty(); } bool UseLibIdLookup() const { return m_schLibSymbolName.IsEmpty(); }
std::unique_ptr< LIB_SYMBOL >& GetLibSymbolRef() { return m_part; } LIB_SYMBOL& GetLibSymbolRef() { return *m_part; }
const std::unique_ptr< LIB_SYMBOL >& GetLibSymbolRef() const { return m_part; } const LIB_SYMBOL& GetLibSymbolRef() const { return *m_part; }
/** /**
* Set this schematic symbol library symbol reference to \a aLibSymbol * Set this schematic symbol library symbol to \a aLibSymbol
* *
* The schematic symbol object owns \a aLibSymbol and the pin list will be updated * The schematic symbol object will copy and flatten \a aLibSymbol and the pin list will
* accordingly. The #LIB_SYMBOL object can be null to clear the library symbol link * be updated accordingly. The #LIB_SYMBOL object must not be null.
* as well as the pin map. If the #LIB_SYMBOL object is not null, it must be a root
* symbol. Otherwise an assertion will be raised in debug builds and the library
* 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
* symbol except for the ctors that take a LIB_SYMBOL reference. All previous
* public resolvers have been deprecated.
* *
* @param aLibSymbol is the library symbol to associate with this schematic symbol. * @param aLibSymbol is the library symbol to associate with this schematic symbol.
*/ */
void SetLibSymbol( LIB_SYMBOL* aLibSymbol ); void SetLibSymbol( const LIB_SYMBOL* aLibSymbol );
/** /**
* @return the associated LIB_SYMBOL's description field (or wxEmptyString). * @return the associated LIB_SYMBOL's description field (or wxEmptyString).

View File

@ -1628,7 +1628,7 @@ SELECTION& SYMBOL_EDIT_FRAME::GetCurrentSelection()
void SYMBOL_EDIT_FRAME::LoadSymbolFromSchematic( SCH_SYMBOL* aSymbol ) void SYMBOL_EDIT_FRAME::LoadSymbolFromSchematic( SCH_SYMBOL* aSymbol )
{ {
std::unique_ptr<LIB_SYMBOL> symbol = aSymbol->GetLibSymbolRef()->Flatten(); std::unique_ptr<LIB_SYMBOL> symbol = aSymbol->GetLibSymbolRef().Flatten();
wxCHECK( symbol, /* void */ ); wxCHECK( symbol, /* void */ );
// Take in account the symbol orientation and mirroring. to calculate the field // Take in account the symbol orientation and mirroring. to calculate the field

View File

@ -404,7 +404,7 @@ void EE_INSPECTION_TOOL::DiffSymbol( SCH_SYMBOL* symbol )
else else
{ {
std::unique_ptr<LIB_SYMBOL> flattenedLibSymbol; std::unique_ptr<LIB_SYMBOL> flattenedLibSymbol;
std::unique_ptr<LIB_SYMBOL> flattenedSchSymbol = symbol->GetLibSymbolRef()->Flatten(); std::unique_ptr<LIB_SYMBOL> flattenedSchSymbol = symbol->GetLibSymbolRef().Flatten();
try try
{ {

View File

@ -74,7 +74,7 @@ SELECTION_CONDITION EE_CONDITIONS::SingleSymbol = []( const SELECTION& aSel )
SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aSel.Front() ); SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aSel.Front() );
if( symbol ) if( symbol )
return !symbol->GetLibSymbolRef() || !symbol->GetLibSymbolRef()->IsPower(); return !symbol->GetLibSymbolRef().IsPower();
} }
return false; return false;
@ -94,7 +94,7 @@ SELECTION_CONDITION EE_CONDITIONS::SingleDeMorganSymbol = []( const SELECTION& a
SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aSel.Front() ); SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aSel.Front() );
if( symbol ) if( symbol )
return symbol->GetLibSymbolRef() && symbol->GetLibSymbolRef()->HasAlternateBodyStyle(); return symbol->GetLibSymbolRef().HasAlternateBodyStyle();
} }
return false; return false;
@ -108,7 +108,7 @@ SELECTION_CONDITION EE_CONDITIONS::SingleMultiUnitSymbol = []( const SELECTION&
SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aSel.Front() ); SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aSel.Front() );
if( symbol ) if( symbol )
return symbol->GetLibSymbolRef() && symbol->GetLibSymbolRef()->GetUnitCount() >= 2; return symbol->GetLibSymbolRef().GetUnitCount() >= 2;
} }
return false; return false;

View File

@ -104,7 +104,7 @@ private:
int unit = symbol->GetUnit(); int unit = symbol->GetUnit();
for( int ii = 0; ii < symbol->GetLibSymbolRef()->GetUnitCount(); ii++ ) for( int ii = 0; ii < symbol->GetLibSymbolRef().GetUnitCount(); ii++ )
{ {
wxString num_unit; wxString num_unit;
num_unit.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) ); num_unit.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) );
@ -1824,10 +1824,6 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() ) if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true ); blocking_win->Close( true );
// The broken library symbol link indicator cannot be edited.
if( symbol->IsMissingLibSymbol() )
return 0;
editor->LoadSymbolFromSchematic( symbol ); editor->LoadSymbolFromSchematic( symbol );
editor->Show( true ); editor->Show( true );
editor->Raise(); editor->Raise();

View File

@ -369,17 +369,17 @@ int SCH_EDITOR_CONTROL::ExportSymbolsToLibrary( const TOOL_EVENT& aEvent )
for( size_t i = 0; i < symbols.GetCount(); ++i ) for( size_t i = 0; i < symbols.GetCount(); ++i )
{ {
SCH_SYMBOL* symbol = symbols[i].GetSymbol(); SCH_SYMBOL* symbol = symbols[i].GetSymbol();
LIB_SYMBOL* libSymbol = symbol->GetLibSymbolRef().get(); LIB_SYMBOL& libSymbol = symbol->GetLibSymbolRef();
LIB_ID id = libSymbol->GetLibId(); LIB_ID id = libSymbol.GetLibId();
if( libSymbols.count( id ) ) if( libSymbols.count( id ) )
{ {
wxASSERT_MSG( libSymbols[id]->Compare( *libSymbol, SCH_ITEM::COMPARE_FLAGS::ERC ) == 0, wxASSERT_MSG( libSymbols[id]->Compare( libSymbol, SCH_ITEM::COMPARE_FLAGS::ERC ) == 0,
"Two symbols have the same LIB_ID but are different!" ); "Two symbols have the same LIB_ID but are different!" );
} }
else else
{ {
libSymbols[id] = libSymbol; libSymbols[id] = &libSymbol;
} }
symbolMap[id].emplace_back( symbol ); symbolMap[id].emplace_back( symbol );
@ -827,7 +827,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
if( item->Type() == SCH_FIELD_T ) if( item->Type() == SCH_FIELD_T )
symbol = dynamic_cast<SCH_SYMBOL*>( item->GetParent() ); symbol = dynamic_cast<SCH_SYMBOL*>( item->GetParent() );
if( symbol && symbol->GetLibSymbolRef() && symbol->GetLibSymbolRef()->IsPower() ) if( symbol && symbol->GetLibSymbolRef().IsPower() )
{ {
std::vector<SCH_PIN*> pins = symbol->GetPins(); std::vector<SCH_PIN*> pins = symbol->GetPins();
@ -2229,13 +2229,6 @@ int SCH_EDITOR_CONTROL::EditWithSymbolEditor( const TOOL_EVENT& aEvent )
if( symbol->GetEditFlags() != 0 ) if( symbol->GetEditFlags() != 0 )
return 0; return 0;
if( symbol->IsMissingLibSymbol() )
{
m_frame->ShowInfoBarError( _( "Symbols with broken library symbol links cannot "
"be edited." ) );
return 0;
}
m_toolMgr->RunAction( ACTIONS::showSymbolEditor ); m_toolMgr->RunAction( ACTIONS::showSymbolEditor );
symbolEditor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, false ); symbolEditor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, false );

View File

@ -174,8 +174,7 @@ int SYMBOL_SEARCH_HANDLER::Search( const wxString& aQuery )
{ {
SCH_SYMBOL* sym = static_cast<SCH_SYMBOL*>( item ); SCH_SYMBOL* sym = static_cast<SCH_SYMBOL*>( item );
// IsPower depends on non-missing lib symbol association if( sym->IsPower() )
if( !sym->IsMissingLibSymbol() && sym->IsPower() )
return false; return false;
for( SCH_FIELD& field : sym->GetFields() ) for( SCH_FIELD& field : sym->GetFields() )
@ -255,8 +254,7 @@ int POWER_SEARCH_HANDLER::Search( const wxString& aQuery )
{ {
SCH_SYMBOL* sym = static_cast<SCH_SYMBOL*>( item ); SCH_SYMBOL* sym = static_cast<SCH_SYMBOL*>( item );
// IsPower depends on non-missing lib symbol association return sym->IsPower();
return !sym->IsMissingLibSymbol() && sym->IsPower();
} }
return false; return false;

View File

@ -41,8 +41,7 @@ struct LEGACY_POWER_SYMBOLS_TEST_FIXTURE
// Fix pre-8.0 legacy power symbols with invisible pins // Fix pre-8.0 legacy power symbols with invisible pins
// that have mismatched pin names and value fields // that have mismatched pin names and value fields
if( symbol->GetLibSymbolRef() if( symbol->GetLibSymbolRef().IsPower()
&& symbol->GetLibSymbolRef()->IsPower()
&& symbol->GetAllLibPins().size() > 0 && symbol->GetAllLibPins().size() > 0
&& symbol->GetAllLibPins()[0]->IsGlobalPower() && symbol->GetAllLibPins()[0]->IsGlobalPower()
&& !symbol->GetAllLibPins()[0]->IsVisible() ) && !symbol->GetAllLibPins()[0]->IsVisible() )