Allow symbols to be derived from other derived symbols.

[CHANGED] Symbols can now be derived from other derived symbols removing
          the requirement to derive from root symbols.
This commit is contained in:
Wayne Stambaugh 2023-08-20 12:05:31 -04:00
parent b8ce97b532
commit 1026596964
15 changed files with 218 additions and 85 deletions

View File

@ -197,14 +197,17 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
// Populate the list of root parts for inherited objects.
if( m_libEntry->IsAlias() )
{
wxArrayString rootSymbolNames;
wxArrayString symbolNames;
wxString libName = m_Parent->GetCurLib();
// Someone forgot to set the current library in the editor frame window.
wxCHECK( !libName.empty(), false );
m_Parent->GetLibManager().GetRootSymbolNames( libName, rootSymbolNames );
m_inheritanceSelectCombo->Append( rootSymbolNames );
m_Parent->GetLibManager().GetSymbolNames( libName, symbolNames );
// Do allow an inherited symbol to be derived from itself.
symbolNames.Remove( m_libEntry->GetName() );
m_inheritanceSelectCombo->Append( symbolNames );
LIB_SYMBOL_SPTR rootSymbol = m_libEntry->GetParent().lock();
@ -371,9 +374,6 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
// Verify that the requested parent exists
wxCHECK( newParent, false );
// Verify that the new parent is not an alias.
wxCHECK( !newParent->IsAlias(), false );
m_libEntry->SetParent( newParent );
}

View File

@ -457,10 +457,10 @@ int EESCHEMA_JOBS_HANDLER::doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob,
LIB_SYMBOL* symbolToPlot = symbol;
// if the symbol is an alias, then the draw items are stored in the parent
// if the symbol is an alias, then the draw items are stored in the root symbol
if( symbol->IsAlias() )
{
LIB_SYMBOL_SPTR parent = symbol->GetParent().lock();
LIB_SYMBOL_SPTR parent = symbol->GetRootSymbol().lock();
symbolToPlot = parent.get();
}

View File

@ -236,6 +236,22 @@ const LIB_SYMBOL& LIB_SYMBOL::operator=( const LIB_SYMBOL& aSymbol )
}
unsigned LIB_SYMBOL::GetInheritanceDepth() const
{
unsigned depth = 0;
LIB_SYMBOL_SPTR parent = GetParent().lock();
while( parent )
{
depth += 1;
parent = parent->GetParent().lock();
}
return depth;
}
#define REPORT( msg ) { if( aReporter ) aReporter->Report( msg ); }
#define ITEM_DESC( item ) ( item )->GetItemDescription( &unitsProvider )
@ -518,6 +534,18 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags, REPORTER* aR
}
LIB_SYMBOL_REF LIB_SYMBOL::GetRootSymbol() const
{
const LIB_SYMBOL_SPTR sp = m_parent.lock();
// Recurse until the parent symbol is empty.
if( sp )
return sp->GetRootSymbol();
return m_me;
}
wxString LIB_SYMBOL::GetUnitReference( int aUnit )
{
return LIB_SYMBOL::SubReference( aUnit, false );

View File

@ -127,6 +127,23 @@ public:
LIB_SYMBOL_REF& GetParent() { return m_parent; }
const LIB_SYMBOL_REF& GetParent() const { return m_parent; }
/**
* Get the number of parents for this symbol.
*
* @return the inhertance depth for this symbol.
*/
unsigned GetInheritanceDepth() const;
/**
* Get the parent symbol that does not have another parent.
*
* Now that derived symbols can be derived from other derived symbols, this method provides
* way to get to the base symbol in the derivation change.
*
* @return the weak_ptr to the root symbol of this symbol.
*/
LIB_SYMBOL_REF GetRootSymbol() const;
void ClearCaches();
virtual wxString GetClass() const override

View File

@ -433,7 +433,7 @@ void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(
// If it's a derive symbol, use the parent symbol to perform the pin test.
if( lib_match && lib_match->IsAlias() )
{
lib_match_parent = lib_match->GetParent().lock();
lib_match_parent = lib_match->GetRootSymbol().lock();
if( !lib_match_parent )
lib_match = nullptr;

View File

@ -99,4 +99,5 @@
//#define SEXPR_SCHEMATIC_FILE_VERSION 20230221 // Modern power symbols (editable value = net)
//#define SEXPR_SCHEMATIC_FILE_VERSION 20230409 // Add exclude_from_sim markup
//#define SEXPR_SCHEMATIC_FILE_VERSION 20230620 // ki_description -> Description Field
#define SEXPR_SCHEMATIC_FILE_VERSION 20230808 // Move Sim.Enable field to exclude_from_sim attr
//#define SEXPR_SCHEMATIC_FILE_VERSION 20230808 // Move Sim.Enable field to exclude_from_sim attr
#define SEXPR_SCHEMATIC_FILE_VERSION 20230819 // Allow multiple library symbol inheritance depth.

View File

@ -35,6 +35,39 @@
#include <trace_helpers.h>
/**
* Symbol library file sorting algorithm.
*
* The sort order of symbol library files is a twofold process based on the inheritance
* depth of a given symbol. The following criteria is used to sort the symbols in the
* library file:
*
* 1. The inheritance depth from 0 to N.
* 2. The alphabetical order using our #ValueStringCompare natural sorting.
*
* @note It is imperative that symbols with an inheritance depth of 0 are stored in the
* file before symbols with an inheritance depth of 1 and so on and so forth. This
* is necessary because the symbol library file parser expects parent symbols to be
* defined before child symbols to ensure they can be parented on load.
*
* @param aLhs is the left hand side to compare.
* @parem aRhs is the right hand side to compare.
* @return true if @a aLhs is less than @a aRhs otherwise false.
*/
struct LibSymbolFileSort
{
bool operator() ( const LIB_SYMBOL* aLhs, const LIB_SYMBOL* aRhs ) const
{
wxCHECK( aLhs && aRhs, false );
if( aLhs->GetInheritanceDepth() < aRhs->GetInheritanceDepth() )
return true;
return ( ValueStringCompare( aLhs->GetName(), aRhs->GetName() ) < 0 );
}
};
SCH_SEXPR_PLUGIN_CACHE::SCH_SEXPR_PLUGIN_CACHE( const wxString& aFullPathAndFileName ) :
SCH_LIB_PLUGIN_CACHE( aFullPathAndFileName )
{
@ -95,28 +128,13 @@ void SCH_SEXPR_PLUGIN_CACHE::Save( const std::optional<bool>& aOpt )
formatter->Print( 0, "(kicad_symbol_lib (version %d) (generator kicad_symbol_editor)\n",
SEXPR_SYMBOL_LIB_FILE_VERSION );
std::set<LIB_SYMBOL*, LibSymbolFileSort> orderedSymbols;
for( const std::pair<const wxString, LIB_SYMBOL*>& parent : m_symbols )
{
// Save the root symbol first so alias can inherit from them.
if( parent.second->IsRoot() )
{
SaveSymbol( parent.second, *formatter.get(), 1 );
orderedSymbols.emplace( parent.second );
// Save all of the aliases associated with the current root symbol.
for( const std::pair<const wxString, LIB_SYMBOL*>& alias : m_symbols )
{
if( !alias.second->IsAlias() )
continue;
std::shared_ptr<LIB_SYMBOL> aliasParent = alias.second->GetParent().lock();
if( aliasParent.get() != parent.second )
continue;
SaveSymbol( alias.second, *formatter.get(), 1 );
}
}
}
for( LIB_SYMBOL* symbol : orderedSymbols )
SaveSymbol( symbol, *formatter.get(), 1 );
formatter->Print( 0, ")\n" );

View File

@ -159,7 +159,7 @@ void SCH_VIEW::DisplaySymbol( LIB_SYMBOL* aSymbol )
// Draw the parent items if the symbol is inherited from another symbol.
if( aSymbol->IsAlias() )
{
std::shared_ptr< LIB_SYMBOL > parent = aSymbol->GetParent().lock();
std::shared_ptr< LIB_SYMBOL > parent = aSymbol->GetRootSymbol().lock();
wxCHECK( parent, /* void */ );

View File

@ -808,28 +808,27 @@ void SYMBOL_EDIT_FRAME::SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom )
}
else if( IsSymbolAlias() )
{
std::shared_ptr<LIB_SYMBOL> parent = m_symbol->GetParent().lock();
std::shared_ptr<LIB_SYMBOL> rootSymbol = m_symbol->GetRootSymbol().lock();
// Don't assume the parent symbol shared pointer is still valid.
wxCHECK( parent, /* void */ );
wxCHECK( rootSymbol, /* void */ );
wxString parentSymbolName = parent->GetName();
wxString rootSymbolName = rootSymbol->GetName();
int unit = GetUnit();
int convert = GetConvert();
wxString msg;
wxString link;
msg.Printf( _( "Symbol %s is derived from %s. Symbol graphics will not be editable." ),
UnescapeString( symbolName ),
UnescapeString( parentSymbolName ) );
msg.Printf( _( "Symbol %s is a derived symbol. Symbol graphics will not be editable." ),
UnescapeString( symbolName ) );
link.Printf( _( "Open %s" ), UnescapeString( parentSymbolName ) );
link.Printf( _( "Open %s" ), UnescapeString( rootSymbolName ) );
wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, link, wxEmptyString );
button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
[=]( wxHyperlinkEvent& aEvent )
{
LoadSymbolFromCurrentLib( parentSymbolName, unit, convert );
LoadSymbolFromCurrentLib( rootSymbolName, unit, convert );
} ) );
infobar->RemoveAllButtons();

View File

@ -133,8 +133,11 @@ public:
/**
* Create a new symbol in the selected library.
*
* @param aInheritFrom is the name of the symbol to derive the new symbol from or empty
* to create a new root symbol.
*/
void CreateNewSymbol( const wxString& inheritFromSymbolName = wxEmptyString );
void CreateNewSymbol( const wxString& aInheritFrom = wxEmptyString );
void ImportSymbol();
void ExportSymbol();

View File

@ -329,11 +329,11 @@ void SYMBOL_EDIT_FRAME::SaveAll()
}
void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& inheritFromSymbolName )
void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& aInheritFrom )
{
m_toolManager->RunAction( ACTIONS::cancelInteractive );
wxArrayString rootSymbols;
wxArrayString symbolNames;
wxString lib = getTargetLib();
if( !m_libMgr->LibraryExists( lib ) )
@ -344,35 +344,32 @@ void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& inheritFromSymbolName )
return;
}
m_libMgr->GetRootSymbolNames( lib, rootSymbols );
m_libMgr->GetSymbolNames( lib, symbolNames );
rootSymbols.Sort();
symbolNames.Sort();
wxString _inheritSymbolName;
wxString _infoMessage;
// if the symbol being inherited from isn't a root symbol, find its root symbol
// and use that symbol instead
if( !inheritFromSymbolName.IsEmpty() )
if( !aInheritFrom.IsEmpty() )
{
LIB_SYMBOL* inheritFromSymbol = m_libMgr->GetBufferedSymbol( inheritFromSymbolName, lib );
LIB_SYMBOL* inheritFromSymbol = m_libMgr->GetBufferedSymbol( aInheritFrom, lib );
if( inheritFromSymbol && !inheritFromSymbol->IsRoot() )
if( inheritFromSymbol )
{
std::shared_ptr<LIB_SYMBOL> parent = inheritFromSymbol->GetParent().lock();
wxString rootSymbolName = parent->GetName();
_inheritSymbolName = rootSymbolName;
_infoMessage = wxString::Format( _( "Deriving from '%s', the root symbol of '%s'." ),
_inheritSymbolName,
inheritFromSymbolName);
_inheritSymbolName = aInheritFrom;
_infoMessage = wxString::Format( _( "Deriving from symbol '%s'." ),
_inheritSymbolName );
}
else
{
_inheritSymbolName = inheritFromSymbolName;
_inheritSymbolName = aInheritFrom;
}
}
DIALOG_LIB_NEW_SYMBOL dlg( this, _infoMessage, &rootSymbols, _inheritSymbolName );
DIALOG_LIB_NEW_SYMBOL dlg( this, _infoMessage, &symbolNames, _inheritSymbolName );
dlg.SetMinSize( dlg.GetSize() );
if( dlg.ShowModal() == wxID_CANCEL )
@ -1006,6 +1003,7 @@ void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLib
DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
aAlias,
aLibrary ) );
m_treePane->GetLibTree()->RefreshLibTree();
return;
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -39,7 +39,7 @@
#include <progress_reporter.h>
#include <list>
#include <locale_io.h>
#include <wx/log.h>
#include <confirm.h>
#include <string_utils.h>
#include "lib_logger.h"
@ -156,8 +156,10 @@ SYMBOL_LIB_TABLE_ROW* SYMBOL_LIBRARY_MANAGER::GetLibrary( const wxString& aLibra
}
catch( const IO_ERROR& e )
{
wxLogMessage( _( "Library '%s' not found in the Symbol Library Table." ) + e.What(),
aLibrary );
wxString msg;
msg.Printf( _( "Library '%s' not found in the Symbol Library Table." ), aLibrary );
DisplayErrorMessage( &m_frame, msg, e.What() );
}
return row;
@ -223,7 +225,8 @@ bool SYMBOL_LIBRARY_MANAGER::SaveLibrary( const wxString& aLibrary, const wxStri
std::shared_ptr< LIB_SYMBOL > oldParent = symbol->GetParent().lock();
wxCHECK_MSG( oldParent, false,
wxString::Format( wxT( "Derived symbol '%s' found with undefined parent." ),
wxString::Format( wxT( "Derived symbol '%s' found with "
"undefined parent." ),
symbol->GetName() ) );
LIB_SYMBOL* libParent = pi->LoadSymbol( aLibrary, oldParent->GetName(),
@ -438,8 +441,10 @@ LIB_SYMBOL* SYMBOL_LIBRARY_MANAGER::GetBufferedSymbol( const wxString& aAlias,
}
catch( const IO_ERROR& e )
{
wxLogMessage( _( "Error loading symbol %s from library '%s'. (%s)" ),
aAlias, aLibrary, e.What() );
wxString msg;
msg.Printf( _( "Error loading symbol %s from library '%s'." ), aAlias, aLibrary );
DisplayErrorMessage( &m_frame, msg, e.What() );
bufferedSymbol = nullptr;
}
}
@ -625,9 +630,10 @@ LIB_SYMBOL* SYMBOL_LIBRARY_MANAGER::GetAlias( const wxString& aAlias,
}
catch( const IO_ERROR& e )
{
wxLogMessage( _( "Cannot load symbol '%s' from library '%s'." ) + e.What(),
aAlias,
aLibrary );
wxString msg;
msg.Printf( _( "Cannot load symbol '%s' from library '%s'." ), aAlias, aLibrary );
DisplayErrorMessage( &m_frame, msg, e.What() );
}
return alias;
@ -687,12 +693,13 @@ wxString SYMBOL_LIBRARY_MANAGER::GetUniqueLibraryName() const
}
void SYMBOL_LIBRARY_MANAGER::GetRootSymbolNames( const wxString& aLibraryName,
wxArrayString& aRootSymbolNames )
void SYMBOL_LIBRARY_MANAGER::GetSymbolNames( const wxString& aLibraryName,
wxArrayString& aSymbolNames,
SYMBOL_NAME_FILTER aFilter )
{
LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
libBuf.GetRootSymbolNames( aRootSymbolNames );
libBuf.GetSymbolNames( aSymbolNames, aFilter );
}
@ -778,7 +785,10 @@ std::set<LIB_SYMBOL*> SYMBOL_LIBRARY_MANAGER::getOriginalSymbols( const wxString
}
catch( const IO_ERROR& e )
{
wxLogMessage( _( "Cannot enumerate library '%s'." ) + e.What(), aLibrary );
wxString msg;
msg.Printf( _( "Cannot enumerate library '%s'." ), aLibrary );
DisplayErrorMessage( &m_frame, msg, e.What() );
}
return symbols;
@ -972,8 +982,8 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::DeleteBuffer( std::shared_ptr<SYMBOL_BU
bool retv = true;
// Remove all derived symbols to prevent broken inheritance.
if( aSymbolBuf->GetSymbol()->IsRoot() && HasDerivedSymbols( aSymbolBuf->GetSymbol()->GetName() )
&& removeChildSymbols( aSymbolBuf ) == 0 )
if( HasDerivedSymbols( aSymbolBuf->GetSymbol()->GetName() )
&& ( removeChildSymbols( aSymbolBuf ) == 0 ) )
{
retv = false;
}
@ -1294,14 +1304,16 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::HasDerivedSymbols( const wxString& aPar
}
void SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::GetRootSymbolNames( wxArrayString& aRootSymbolNames )
void SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::GetSymbolNames( wxArrayString& aSymbolNames,
SYMBOL_NAME_FILTER aFilter )
{
for( auto& entry : m_symbols )
{
if( entry->GetSymbol()->IsAlias() )
if( ( entry->GetSymbol()->IsAlias() && ( aFilter == SYMBOL_NAME_FILTER::ROOT_ONLY ) )
|| ( entry->GetSymbol()->IsRoot() && ( aFilter == SYMBOL_NAME_FILTER::DERIVED_ONLY ) ) )
continue;
aRootSymbolNames.Add( UnescapeString( entry->GetSymbol()->GetName() ) );
aSymbolNames.Add( UnescapeString( entry->GetSymbol()->GetName() ) );
}
}
@ -1329,27 +1341,33 @@ size_t SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::GetDerivedSymbolNames( const wxString
}
int SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::removeChildSymbols( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf )
int SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::removeChildSymbols( std::shared_ptr<SYMBOL_BUFFER>& aSymbolBuf )
{
wxCHECK( aSymbolBuf && aSymbolBuf->GetSymbol()->IsRoot(), 0 );
wxCHECK( aSymbolBuf, 0 );
int cnt = 0;
std::deque< std::shared_ptr<SYMBOL_BUFFER> >::iterator it = m_symbols.begin();
while( it != m_symbols.end() )
{
LIB_SYMBOL_SPTR parent = (*it)->GetSymbol()->GetParent().lock();
if( (*it)->GetSymbol()->IsRoot() )
if( !parent )
{
++it;
}
else
{
LIB_SYMBOL_SPTR parent = (*it)->GetSymbol()->GetParent().lock();
if( HasDerivedSymbols( parent->GetName() ) )
{
std::shared_ptr<SYMBOL_BUFFER> symbolBuf = GetBuffer( parent->GetName() );
wxCHECK2( parent, ++it; continue );
wxCHECK2( symbolBuf, ++it; continue );
if( parent->GetName() == aSymbolBuf->GetSymbol()->GetName() )
cnt += removeChildSymbols( symbolBuf );
it = m_symbols.begin();
}
else if( parent->GetName() == aSymbolBuf->GetSymbol()->GetName() )
{
wxCHECK2( parent == aSymbolBuf->GetSymbol()->SharedPtr(), ++it; continue );

View File

@ -2,7 +2,7 @@
* This program source code file is symbol of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -46,6 +46,14 @@ class SYMBOL_LIB_TABLE_ROW;
class LIB_LOGGER;
enum class SYMBOL_NAME_FILTER
{
ALL,
ROOT_ONLY,
DERIVED_ONLY
};
/**
* Class to handle modifications to the symbol libraries.
*/
@ -238,7 +246,8 @@ public:
*/
wxString GetUniqueLibraryName() const;
void GetRootSymbolNames( const wxString& aLibName, wxArrayString& aRootSymbolNames );
void GetSymbolNames( const wxString& aLibName, wxArrayString& aSymbolNames,
SYMBOL_NAME_FILTER aFilter = SYMBOL_NAME_FILTER::ALL );
/**
* Check if symbol \a aSymbolName in library \a aLibraryName is a root symbol that
@ -370,8 +379,10 @@ protected:
* Fetch a list of root symbols names from the library buffer.
*
* @param aRootSymbolNames is a reference to a list to populate with root symbol names.
* @param aFilter is the symbol derivation type.
*/
void GetRootSymbolNames( wxArrayString& aRootSymbolNames );
void GetSymbolNames( wxArrayString& aSymbolNames,
SYMBOL_NAME_FILTER aFilter = SYMBOL_NAME_FILTER::ALL );
/**
* Fetch all of the symbols derived from a \a aSymbolName into \a aList.
@ -390,7 +401,7 @@ protected:
* @param aParent is the #SYMBOL_BUFFER to check against.
* @return the count of #SYMBOL_BUFFER objects removed from the library.
*/
int removeChildSymbols( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf );
int removeChildSymbols( std::shared_ptr<SYMBOL_BUFFER>& aSymbolBuf );
std::deque< std::shared_ptr<SYMBOL_BUFFER> > m_symbols;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@ -594,15 +594,22 @@ BOOST_AUTO_TEST_CASE( Inheritance )
{
std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
BOOST_CHECK( parent->IsRoot() );
BOOST_CHECK_EQUAL( parent->GetInheritanceDepth(), 0 );
std::unique_ptr<LIB_SYMBOL> ref = std::make_unique<LIB_SYMBOL>( *parent );
std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
BOOST_CHECK( child->IsAlias() );
BOOST_CHECK_EQUAL( child->GetInheritanceDepth(), 1 );
std::unique_ptr<LIB_SYMBOL> grandChild = std::make_unique<LIB_SYMBOL>( "grandchild",
child.get() );
BOOST_CHECK( grandChild->IsAlias() );
BOOST_CHECK_EQUAL( grandChild->GetInheritanceDepth(), 2 );
BOOST_CHECK( parent->GetRootSymbol().lock().get() == parent.get() );
BOOST_CHECK( child->GetRootSymbol().lock().get() == parent.get() );
BOOST_CHECK( grandChild->GetRootSymbol().lock().get() == parent.get() );
LIB_SYMBOL_SPTR parentRef = child->GetParent().lock();
BOOST_CHECK( parentRef );
@ -657,4 +664,37 @@ BOOST_AUTO_TEST_CASE( CopyConstructor )
}
/**
* Check the power and legacy power symbol tests.
*/
BOOST_AUTO_TEST_CASE( IsPowerTest )
{
std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( "power" );
LIB_PIN* pin = new LIB_PIN( symbol.get() );
pin->SetNumber( "1" );
pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
pin->SetVisible( false );
symbol->AddDrawItem( pin );
BOOST_CHECK( !symbol->IsPower() );
BOOST_CHECK( symbol->IsNormal() );
symbol->SetPower();
BOOST_CHECK( symbol->IsPower() );
BOOST_CHECK( !symbol->IsNormal() );
// symbol->SetNormal();
// symbol->GetReferenceField().SetText( wxS( "#PWR" ) );
// BOOST_CHECK( symbol->IsPower() );
// Legacy power symbols are limited to a single pin.
// pin = new LIB_PIN( symbol.get() );
// pin->SetNumber( "2" );
// pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
// pin->SetVisible( false );
// symbol->AddDrawItem( pin );
// BOOST_CHECK( !symbol->IsPower() );
}
BOOST_AUTO_TEST_SUITE_END()