Revert "SCH/LIB SYMBOL: never allow null LIB_SYMBOLs in SCH_SYMBOL"

This reverts commit 0b187e7122.
This commit is contained in:
Mike Williams 2024-06-12 13:27:17 -04:00
parent 0c45f85bc0
commit a5e2615251
39 changed files with 669 additions and 425 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -393,10 +393,11 @@ void DIALOG_EDIT_SYMBOLS_LIBID::initDlg()
// the list is larger and looks like it contains all symbols.
SCH_REFERENCE_LIST references;
// build the full list of symbols
// build the full list of symbols including symbol having no symbol in loaded libs
// (orphan symbols)
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++ )
{
@ -762,7 +763,7 @@ bool DIALOG_EDIT_SYMBOLS_LIBID::TransferDataFromWindow()
candidate.m_Symbol->SetValueFieldText( getName( id ) );
candidate.m_Symbol->SetLibId( id );
candidate.m_Symbol->SetLibSymbol( symbol );
candidate.m_Symbol->SetLibSymbol( symbol->Flatten().release() );
candidate.m_Screen->Append( candidate.m_Symbol );
candidate.m_Screen->SetContentModified();

View File

@ -205,7 +205,7 @@ DIALOG_FIELD_PROPERTIES::DIALOG_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const
netlist << wxS( "\r" );
wxArrayString fpFilters = symbol->GetLibSymbolRef().GetFPFilters();
wxArrayString fpFilters = symbol->GetLibSymbolRef()->GetFPFilters();
if( !fpFilters.IsEmpty() )
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 )
{
bool isPower = static_cast<SCH_SYMBOL*>( aItem )->GetLibSymbolRef().IsPower();
bool isPower = static_cast<SCH_SYMBOL*>( aItem )->GetLibSymbolRef()->IsPower();
if( isPower != ( m_typeFilter->GetSelection() == 1 ) )
return;

View File

@ -2221,7 +2221,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSchItemsAdded( SCHEMATIC& aSch,
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
// Don't add power symbols
if( symbol->IsPower() )
if( !symbol->IsMissingLibSymbol() && symbol->IsPower() )
continue;
// 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 );
// Don't add power symbols
if( symbol->IsPower() )
if( !symbol->IsMissingLibSymbol() && symbol->IsPower() )
continue;
// 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 );
allSheets.GetSheetsWithinPath( subSheets, sheetPath );
subSheets.GetSymbolsWithinPath( sheetRefs, sheetPath, false );
subSheets.GetSymbolsWithinPath( sheetRefs, sheetPath, false, false );
break;
}
}

View File

@ -310,15 +310,25 @@ protected:
DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
SCH_SYMBOL* aSymbol ) :
DIALOG_SYMBOL_PROPERTIES_BASE( aParent ),
m_symbol( aSymbol ),
m_part( aSymbol->GetLibSymbolRef() ),
m_symbol( nullptr ),
m_part( nullptr ),
m_fieldsSize( 0, 0 ),
m_lastRequestedFieldsSize( 0, 0 ),
m_lastRequestedPinsSize( 0, 0 ),
m_editorShown( false ),
m_fields( new FIELDS_GRID_TABLE( this, aParent, m_fieldsGrid, m_symbol ) ),
m_fields( 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
m_fieldsGrid->SetDefaultRowSize( m_fieldsGrid->GetDefaultRowSize() + 4 );
m_pinGrid->SetDefaultRowSize( m_pinGrid->GetDefaultRowSize() + 4 );
@ -338,7 +348,7 @@ DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
m_shownColumns = m_fieldsGrid->GetShownColumns();
}
if( m_part.HasAlternateBodyStyle() )
if( m_part && m_part->HasAlternateBodyStyle() )
{
// 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
@ -361,7 +371,7 @@ DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
m_pinGrid->SetTable( m_dataModel );
}
if( m_part.IsPower() )
if( m_part && m_part->IsPower() )
m_spiceFieldsButton->Hide();
m_pinGrid->PushEventHandler( new GRID_TRICKS( m_pinGrid ) );
@ -489,7 +499,7 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow()
m_unitChoice->Enable( false );
}
if( m_part.HasAlternateBodyStyle() )
if( m_part && m_part->HasAlternateBodyStyle() )
{
if( m_symbol->GetBodyStyle() > BODY_STYLE::BASE )
m_cbAlternateSymbol->SetValue( true );
@ -525,8 +535,11 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow()
m_cbExcludeFromBoard->SetValue( m_symbol->GetExcludedFromBoard() );
m_cbDNP->SetValue( m_symbol->GetDNP() );
m_ShowPinNumButt->SetValue( m_part.GetShowPinNumbers() );
m_ShowPinNameButt->SetValue( m_part.GetShowPinNames() );
if( m_part )
{
m_ShowPinNumButt->SetValue( m_part->GetShowPinNumbers() );
m_ShowPinNameButt->SetValue( m_part->GetShowPinNames() );
}
// Set the symbol's library name.
m_tcLibraryID->SetValue( UnescapeString( m_symbol->GetLibId().Format() ) );
@ -1269,12 +1282,12 @@ void DIALOG_SYMBOL_PROPERTIES::OnUnitChoice( wxCommandEvent& event )
void DIALOG_SYMBOL_PROPERTIES::onUpdateEditSymbol( wxUpdateUIEvent& event )
{
event.Enable( m_symbol );
event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
}
void DIALOG_SYMBOL_PROPERTIES::onUpdateEditLibrarySymbol( wxUpdateUIEvent& event )
{
event.Enable( m_symbol );
event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
}

View File

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

View File

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

View File

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

View File

@ -62,7 +62,7 @@ enum
static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath )
{
wxCHECK( aSymbol, wxEmptyString );
wxCHECK( aSymbol && aSymbol->GetLibSymbolRef(), wxEmptyString );
/*
* Symbol netlist format:
@ -81,7 +81,7 @@ static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath )
netlist << wxS( "\r" );
wxArrayString fpFilters = aSymbol->GetLibSymbolRef().GetFPFilters();
wxArrayString fpFilters = aSymbol->GetLibSymbolRef()->GetFPFilters();
if( !fpFilters.IsEmpty() )
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_parentType( SCH_SYMBOL_T ),
m_mandatoryFieldCount( MANDATORY_FIELDS ),
m_part( &aSymbol->GetLibSymbolRef() ),
m_part( aSymbol->GetLibSymbolRef().get() ),
m_symbolNetlist( netList( aSymbol, aFrame->GetCurrentSheet() ) ),
m_fieldNameValidator( FIELD_NAME ),
m_referenceValidator( REFERENCE_FIELD ),

View File

@ -175,43 +175,6 @@ 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 )
{
if( &aSymbol == this )

View File

@ -84,10 +84,6 @@ public:
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
LIB_SYMBOL_SPTR SharedPtr() const { return m_me; }

View File

@ -412,7 +412,7 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroPackages()
footprintText = footprintText.AfterLast( ':' );
wxArrayString footprintAlt;
wxArrayString footprintArray = sym->GetLibSymbolRef().GetFPFilters();
wxArrayString footprintArray = sym->GetLibSymbolRef()->GetFPFilters();
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, "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
@ -651,7 +651,7 @@ wxString NETLIST_EXPORTER_ALLEGRO::getGroupField( int aGroupIndex, const wxArray
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 );

View File

@ -140,8 +140,16 @@ std::vector<PIN_INFO> NETLIST_EXPORTER_BASE::CreatePinList( SCH_SYMBOL* aSymbol,
if( ( ref[0] == wxChar( '#' ) ) || aSymbol->IsPower() )
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( aSymbol->GetLibSymbolRef().GetUnitCount() > 1 )
if( aSymbol->GetLibSymbolRef()->GetUnitCount() > 1 )
{
// Collect all pins for this reference designator by searching the entire design for
// other parts with the same reference designator.
@ -183,7 +191,7 @@ std::vector<PIN_INFO> NETLIST_EXPORTER_BASE::CreatePinList( SCH_SYMBOL* aSymbol,
eraseDuplicatePins( pins );
// record the usage of this library symbol
m_libParts.insert( &aSymbol->GetLibSymbolRef() ); // rejects non-unique pointers
m_libParts.insert( aSymbol->GetLibSymbolRef().get() ); // rejects non-unique pointers
return pins;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3303,16 +3303,16 @@ bool SCH_IO_EAGLE::checkConnections( const SCH_SYMBOL* aSymbol, const SCH_PIN* a
void SCH_IO_EAGLE::addImplicitConnections( SCH_SYMBOL* aSymbol, SCH_SCREEN* aScreen,
bool aUpdateSet )
{
wxCHECK( aSymbol && aScreen, /*void*/ );
wxCHECK( aSymbol && aScreen && aSymbol->GetLibSymbolRef(), /*void*/ );
// Normally power parts also have power input pins,
// but they already force net names on the attached wires
if( aSymbol->GetLibSymbolRef().IsPower() )
if( aSymbol->GetLibSymbolRef()->IsPower() )
return;
int unit = aSymbol->GetUnit();
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;
// Search all units for pins creating implicit connections
@ -3365,7 +3365,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 );

View File

@ -94,6 +94,43 @@ 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 ) :
KIGFX::PAINTER( aGal ),
m_schematic( nullptr )
@ -2138,10 +2175,13 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
int unit = aSymbol->GetUnitSelection( &m_schematic->CurrentSheet() );
int bodyStyle = aSymbol->GetBodyStyle();
std::vector<SCH_PIN*> originalPins = aSymbol->GetLibSymbolRef().GetPins( unit, bodyStyle );
// Use dummy symbol if the actual couldn't be found (or couldn't be locked).
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.
LIB_SYMBOL tempSymbol( aSymbol->GetLibSymbolRef() );
LIB_SYMBOL tempSymbol( *originalSymbol );
std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( unit, bodyStyle );
tempSymbol.SetFlags( aSymbol->GetFlags() );
@ -2635,7 +2675,7 @@ void SCH_PAINTER::draw( const SCH_SHEET* aSheet, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
bool DNP = aSheet->GetDNP();
bool markExclusion = eeconfig()->m_Appearance.mark_sim_exclusions
bool markExclusion = eeconfig()->m_Appearance.mark_sim_exclusions
&& aSheet->GetExcludedFromSim();
if( m_schSettings.IsPrinting() && drawingShadows )

View File

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

View File

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

View File

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

View File

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

View File

@ -313,17 +313,25 @@ public:
* @param aReferences List of references to populate.
* @param aSymbol A symbol to add to aReferences
* @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,
bool aIncludePowerSymbols = true ) const;
bool aIncludePowerSymbols = true,
bool aForceIncludeOrphanSymbols = false ) const;
/**
* Adds #SCH_REFERENCE object to \a aReferences for each symbol in the sheet.
*
* @param aReferences List of references to populate.
* @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 ) const;
void GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true,
bool aForceIncludeOrphanSymbols = false ) const;
/**
* Append a #SCH_REFERENCE_LIST object to \a aRefList based on \a aSymbol,
@ -501,8 +509,12 @@ public:
*
* @param aReferences List of references to populate.
* @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 ) const;
void GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true,
bool aForceIncludeOrphanSymbols = false ) const;
/**
* Add a #SCH_REFERENCE object to \a aReferences for each symbol in the list of sheets that are
@ -511,9 +523,13 @@ public:
* @param aReferences List of references to populate.
* @param aSheetPath Path to return symbols from
* @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,
bool aIncludePowerSymbols = true ) const;
bool aIncludePowerSymbols = true,
bool aForceIncludeOrphanSymbols = false ) const;
/**
* Add a #SCH_SHEET_PATH object to \a aSheets for each sheet in the list that are

View File

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

View File

@ -146,6 +146,21 @@ public:
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
{
return m_instanceReferences;
@ -195,18 +210,26 @@ public:
wxString GetSchSymbolLibraryName() const;
bool UseLibIdLookup() const { return m_schLibSymbolName.IsEmpty(); }
LIB_SYMBOL& GetLibSymbolRef() { return *m_part; }
const LIB_SYMBOL& GetLibSymbolRef() const { return *m_part; }
std::unique_ptr< LIB_SYMBOL >& GetLibSymbolRef() { return m_part; }
const std::unique_ptr< LIB_SYMBOL >& GetLibSymbolRef() const { return m_part; }
/**
* Set this schematic symbol library symbol to \a aLibSymbol
* Set this schematic symbol library symbol reference to \a aLibSymbol
*
* The schematic symbol object will copy and flatten \a aLibSymbol and the pin list will
* be updated accordingly. The #LIB_SYMBOL object must not be null.
* The schematic symbol object owns \a aLibSymbol and the pin list will be updated
* accordingly. The #LIB_SYMBOL object can be null to clear the library symbol link
* 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.
*/
void SetLibSymbol( const LIB_SYMBOL* aLibSymbol );
void SetLibSymbol( LIB_SYMBOL* aLibSymbol );
/**
* @return the associated LIB_SYMBOL's description field (or wxEmptyString).

View File

@ -1629,7 +1629,7 @@ SELECTION& SYMBOL_EDIT_FRAME::GetCurrentSelection()
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 */ );
// 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
{
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
{

View File

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

View File

@ -104,7 +104,7 @@ private:
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;
num_unit.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) );
@ -1824,6 +1824,10 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
// The broken library symbol link indicator cannot be edited.
if( symbol->IsMissingLibSymbol() )
return 0;
editor->LoadSymbolFromSchematic( symbol );
editor->Show( true );
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 )
{
SCH_SYMBOL* symbol = symbols[i].GetSymbol();
LIB_SYMBOL& libSymbol = symbol->GetLibSymbolRef();
LIB_ID id = libSymbol.GetLibId();
LIB_SYMBOL* libSymbol = symbol->GetLibSymbolRef().get();
LIB_ID id = libSymbol->GetLibId();
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!" );
}
else
{
libSymbols[id] = &libSymbol;
libSymbols[id] = libSymbol;
}
symbolMap[id].emplace_back( symbol );
@ -827,7 +827,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
if( item->Type() == SCH_FIELD_T )
symbol = dynamic_cast<SCH_SYMBOL*>( item->GetParent() );
if( symbol && symbol->GetLibSymbolRef().IsPower() )
if( symbol && symbol->GetLibSymbolRef() && symbol->GetLibSymbolRef()->IsPower() )
{
std::vector<SCH_PIN*> pins = symbol->GetPins();
@ -2229,6 +2229,13 @@ int SCH_EDITOR_CONTROL::EditWithSymbolEditor( const TOOL_EVENT& aEvent )
if( symbol->GetEditFlags() != 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 );
symbolEditor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, false );

View File

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

View File

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