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:
parent
b8ce97b532
commit
1026596964
|
@ -197,14 +197,17 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
|
||||||
// Populate the list of root parts for inherited objects.
|
// Populate the list of root parts for inherited objects.
|
||||||
if( m_libEntry->IsAlias() )
|
if( m_libEntry->IsAlias() )
|
||||||
{
|
{
|
||||||
wxArrayString rootSymbolNames;
|
wxArrayString symbolNames;
|
||||||
wxString libName = m_Parent->GetCurLib();
|
wxString libName = m_Parent->GetCurLib();
|
||||||
|
|
||||||
// Someone forgot to set the current library in the editor frame window.
|
// Someone forgot to set the current library in the editor frame window.
|
||||||
wxCHECK( !libName.empty(), false );
|
wxCHECK( !libName.empty(), false );
|
||||||
|
|
||||||
m_Parent->GetLibManager().GetRootSymbolNames( libName, rootSymbolNames );
|
m_Parent->GetLibManager().GetSymbolNames( libName, symbolNames );
|
||||||
m_inheritanceSelectCombo->Append( rootSymbolNames );
|
|
||||||
|
// 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();
|
LIB_SYMBOL_SPTR rootSymbol = m_libEntry->GetParent().lock();
|
||||||
|
|
||||||
|
@ -371,9 +374,6 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||||
// Verify that the requested parent exists
|
// Verify that the requested parent exists
|
||||||
wxCHECK( newParent, false );
|
wxCHECK( newParent, false );
|
||||||
|
|
||||||
// Verify that the new parent is not an alias.
|
|
||||||
wxCHECK( !newParent->IsAlias(), false );
|
|
||||||
|
|
||||||
m_libEntry->SetParent( newParent );
|
m_libEntry->SetParent( newParent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -457,10 +457,10 @@ int EESCHEMA_JOBS_HANDLER::doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob,
|
||||||
|
|
||||||
LIB_SYMBOL* symbolToPlot = symbol;
|
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() )
|
if( symbol->IsAlias() )
|
||||||
{
|
{
|
||||||
LIB_SYMBOL_SPTR parent = symbol->GetParent().lock();
|
LIB_SYMBOL_SPTR parent = symbol->GetRootSymbol().lock();
|
||||||
symbolToPlot = parent.get();
|
symbolToPlot = parent.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 REPORT( msg ) { if( aReporter ) aReporter->Report( msg ); }
|
||||||
#define ITEM_DESC( item ) ( item )->GetItemDescription( &unitsProvider )
|
#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 )
|
wxString LIB_SYMBOL::GetUnitReference( int aUnit )
|
||||||
{
|
{
|
||||||
return LIB_SYMBOL::SubReference( aUnit, false );
|
return LIB_SYMBOL::SubReference( aUnit, false );
|
||||||
|
|
|
@ -127,6 +127,23 @@ public:
|
||||||
LIB_SYMBOL_REF& GetParent() { return m_parent; }
|
LIB_SYMBOL_REF& GetParent() { return m_parent; }
|
||||||
const LIB_SYMBOL_REF& GetParent() const { 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();
|
void ClearCaches();
|
||||||
|
|
||||||
virtual wxString GetClass() const override
|
virtual wxString GetClass() const override
|
||||||
|
|
|
@ -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 it's a derive symbol, use the parent symbol to perform the pin test.
|
||||||
if( lib_match && lib_match->IsAlias() )
|
if( lib_match && lib_match->IsAlias() )
|
||||||
{
|
{
|
||||||
lib_match_parent = lib_match->GetParent().lock();
|
lib_match_parent = lib_match->GetRootSymbol().lock();
|
||||||
|
|
||||||
if( !lib_match_parent )
|
if( !lib_match_parent )
|
||||||
lib_match = nullptr;
|
lib_match = nullptr;
|
||||||
|
|
|
@ -99,4 +99,5 @@
|
||||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20230221 // Modern power symbols (editable value = net)
|
//#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 20230409 // Add exclude_from_sim markup
|
||||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20230620 // ki_description -> Description Field
|
//#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.
|
||||||
|
|
|
@ -35,6 +35,39 @@
|
||||||
#include <trace_helpers.h>
|
#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_SEXPR_PLUGIN_CACHE::SCH_SEXPR_PLUGIN_CACHE( const wxString& aFullPathAndFileName ) :
|
||||||
SCH_LIB_PLUGIN_CACHE( 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",
|
formatter->Print( 0, "(kicad_symbol_lib (version %d) (generator kicad_symbol_editor)\n",
|
||||||
SEXPR_SYMBOL_LIB_FILE_VERSION );
|
SEXPR_SYMBOL_LIB_FILE_VERSION );
|
||||||
|
|
||||||
|
std::set<LIB_SYMBOL*, LibSymbolFileSort> orderedSymbols;
|
||||||
|
|
||||||
for( const std::pair<const wxString, LIB_SYMBOL*>& parent : m_symbols )
|
for( const std::pair<const wxString, LIB_SYMBOL*>& parent : m_symbols )
|
||||||
{
|
orderedSymbols.emplace( parent.second );
|
||||||
// Save the root symbol first so alias can inherit from them.
|
|
||||||
if( parent.second->IsRoot() )
|
|
||||||
{
|
|
||||||
SaveSymbol( parent.second, *formatter.get(), 1 );
|
|
||||||
|
|
||||||
// Save all of the aliases associated with the current root symbol.
|
for( LIB_SYMBOL* symbol : orderedSymbols )
|
||||||
for( const std::pair<const wxString, LIB_SYMBOL*>& alias : m_symbols )
|
SaveSymbol( symbol, *formatter.get(), 1 );
|
||||||
{
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
formatter->Print( 0, ")\n" );
|
formatter->Print( 0, ")\n" );
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ void SCH_VIEW::DisplaySymbol( LIB_SYMBOL* aSymbol )
|
||||||
// Draw the parent items if the symbol is inherited from another symbol.
|
// Draw the parent items if the symbol is inherited from another symbol.
|
||||||
if( aSymbol->IsAlias() )
|
if( aSymbol->IsAlias() )
|
||||||
{
|
{
|
||||||
std::shared_ptr< LIB_SYMBOL > parent = aSymbol->GetParent().lock();
|
std::shared_ptr< LIB_SYMBOL > parent = aSymbol->GetRootSymbol().lock();
|
||||||
|
|
||||||
wxCHECK( parent, /* void */ );
|
wxCHECK( parent, /* void */ );
|
||||||
|
|
||||||
|
|
|
@ -808,28 +808,27 @@ void SYMBOL_EDIT_FRAME::SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom )
|
||||||
}
|
}
|
||||||
else if( IsSymbolAlias() )
|
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.
|
// 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 unit = GetUnit();
|
||||||
int convert = GetConvert();
|
int convert = GetConvert();
|
||||||
wxString msg;
|
wxString msg;
|
||||||
wxString link;
|
wxString link;
|
||||||
|
|
||||||
msg.Printf( _( "Symbol %s is derived from %s. Symbol graphics will not be editable." ),
|
msg.Printf( _( "Symbol %s is a derived symbol. Symbol graphics will not be editable." ),
|
||||||
UnescapeString( symbolName ),
|
UnescapeString( symbolName ) );
|
||||||
UnescapeString( parentSymbolName ) );
|
|
||||||
|
|
||||||
link.Printf( _( "Open %s" ), UnescapeString( parentSymbolName ) );
|
link.Printf( _( "Open %s" ), UnescapeString( rootSymbolName ) );
|
||||||
|
|
||||||
wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, link, wxEmptyString );
|
wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, link, wxEmptyString );
|
||||||
button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
|
button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
|
||||||
[=]( wxHyperlinkEvent& aEvent )
|
[=]( wxHyperlinkEvent& aEvent )
|
||||||
{
|
{
|
||||||
LoadSymbolFromCurrentLib( parentSymbolName, unit, convert );
|
LoadSymbolFromCurrentLib( rootSymbolName, unit, convert );
|
||||||
} ) );
|
} ) );
|
||||||
|
|
||||||
infobar->RemoveAllButtons();
|
infobar->RemoveAllButtons();
|
||||||
|
|
|
@ -133,8 +133,11 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new symbol in the selected library.
|
* 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 ImportSymbol();
|
||||||
void ExportSymbol();
|
void ExportSymbol();
|
||||||
|
|
|
@ -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 );
|
m_toolManager->RunAction( ACTIONS::cancelInteractive );
|
||||||
|
|
||||||
wxArrayString rootSymbols;
|
wxArrayString symbolNames;
|
||||||
wxString lib = getTargetLib();
|
wxString lib = getTargetLib();
|
||||||
|
|
||||||
if( !m_libMgr->LibraryExists( lib ) )
|
if( !m_libMgr->LibraryExists( lib ) )
|
||||||
|
@ -344,35 +344,32 @@ void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& inheritFromSymbolName )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_libMgr->GetRootSymbolNames( lib, rootSymbols );
|
m_libMgr->GetSymbolNames( lib, symbolNames );
|
||||||
|
|
||||||
rootSymbols.Sort();
|
symbolNames.Sort();
|
||||||
|
|
||||||
wxString _inheritSymbolName;
|
wxString _inheritSymbolName;
|
||||||
wxString _infoMessage;
|
wxString _infoMessage;
|
||||||
|
|
||||||
// if the symbol being inherited from isn't a root symbol, find its root symbol
|
// if the symbol being inherited from isn't a root symbol, find its root symbol
|
||||||
// and use that symbol instead
|
// 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();
|
_inheritSymbolName = aInheritFrom;
|
||||||
wxString rootSymbolName = parent->GetName();
|
_infoMessage = wxString::Format( _( "Deriving from symbol '%s'." ),
|
||||||
_inheritSymbolName = rootSymbolName;
|
_inheritSymbolName );
|
||||||
_infoMessage = wxString::Format( _( "Deriving from '%s', the root symbol of '%s'." ),
|
|
||||||
_inheritSymbolName,
|
|
||||||
inheritFromSymbolName);
|
|
||||||
}
|
}
|
||||||
else
|
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() );
|
dlg.SetMinSize( dlg.GetSize() );
|
||||||
|
|
||||||
if( dlg.ShowModal() == wxID_CANCEL )
|
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'." ),
|
DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
|
||||||
aAlias,
|
aAlias,
|
||||||
aLibrary ) );
|
aLibrary ) );
|
||||||
|
m_treePane->GetLibTree()->RefreshLibTree();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 CERN
|
* 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>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
#include <progress_reporter.h>
|
#include <progress_reporter.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <locale_io.h>
|
#include <locale_io.h>
|
||||||
#include <wx/log.h>
|
#include <confirm.h>
|
||||||
#include <string_utils.h>
|
#include <string_utils.h>
|
||||||
#include "lib_logger.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 )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
wxLogMessage( _( "Library '%s' not found in the Symbol Library Table." ) + e.What(),
|
wxString msg;
|
||||||
aLibrary );
|
|
||||||
|
msg.Printf( _( "Library '%s' not found in the Symbol Library Table." ), aLibrary );
|
||||||
|
DisplayErrorMessage( &m_frame, msg, e.What() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return row;
|
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();
|
std::shared_ptr< LIB_SYMBOL > oldParent = symbol->GetParent().lock();
|
||||||
|
|
||||||
wxCHECK_MSG( oldParent, false,
|
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() ) );
|
symbol->GetName() ) );
|
||||||
|
|
||||||
LIB_SYMBOL* libParent = pi->LoadSymbol( aLibrary, oldParent->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 )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
wxLogMessage( _( "Error loading symbol %s from library '%s'. (%s)" ),
|
wxString msg;
|
||||||
aAlias, aLibrary, e.What() );
|
|
||||||
|
msg.Printf( _( "Error loading symbol %s from library '%s'." ), aAlias, aLibrary );
|
||||||
|
DisplayErrorMessage( &m_frame, msg, e.What() );
|
||||||
bufferedSymbol = nullptr;
|
bufferedSymbol = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -625,9 +630,10 @@ LIB_SYMBOL* SYMBOL_LIBRARY_MANAGER::GetAlias( const wxString& aAlias,
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
wxLogMessage( _( "Cannot load symbol '%s' from library '%s'." ) + e.What(),
|
wxString msg;
|
||||||
aAlias,
|
|
||||||
aLibrary );
|
msg.Printf( _( "Cannot load symbol '%s' from library '%s'." ), aAlias, aLibrary );
|
||||||
|
DisplayErrorMessage( &m_frame, msg, e.What() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return alias;
|
return alias;
|
||||||
|
@ -687,12 +693,13 @@ wxString SYMBOL_LIBRARY_MANAGER::GetUniqueLibraryName() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SYMBOL_LIBRARY_MANAGER::GetRootSymbolNames( const wxString& aLibraryName,
|
void SYMBOL_LIBRARY_MANAGER::GetSymbolNames( const wxString& aLibraryName,
|
||||||
wxArrayString& aRootSymbolNames )
|
wxArrayString& aSymbolNames,
|
||||||
|
SYMBOL_NAME_FILTER aFilter )
|
||||||
{
|
{
|
||||||
LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
|
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 )
|
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;
|
return symbols;
|
||||||
|
@ -972,8 +982,8 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::DeleteBuffer( std::shared_ptr<SYMBOL_BU
|
||||||
bool retv = true;
|
bool retv = true;
|
||||||
|
|
||||||
// Remove all derived symbols to prevent broken inheritance.
|
// Remove all derived symbols to prevent broken inheritance.
|
||||||
if( aSymbolBuf->GetSymbol()->IsRoot() && HasDerivedSymbols( aSymbolBuf->GetSymbol()->GetName() )
|
if( HasDerivedSymbols( aSymbolBuf->GetSymbol()->GetName() )
|
||||||
&& removeChildSymbols( aSymbolBuf ) == 0 )
|
&& ( removeChildSymbols( aSymbolBuf ) == 0 ) )
|
||||||
{
|
{
|
||||||
retv = false;
|
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 )
|
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;
|
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;
|
int cnt = 0;
|
||||||
std::deque< std::shared_ptr<SYMBOL_BUFFER> >::iterator it = m_symbols.begin();
|
std::deque< std::shared_ptr<SYMBOL_BUFFER> >::iterator it = m_symbols.begin();
|
||||||
|
|
||||||
while( it != m_symbols.end() )
|
while( it != m_symbols.end() )
|
||||||
{
|
{
|
||||||
|
LIB_SYMBOL_SPTR parent = (*it)->GetSymbol()->GetParent().lock();
|
||||||
|
|
||||||
if( (*it)->GetSymbol()->IsRoot() )
|
if( !parent )
|
||||||
{
|
{
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
else
|
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 );
|
wxCHECK2( parent == aSymbolBuf->GetSymbol()->SharedPtr(), ++it; continue );
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is symbol of KiCad, a free EDA CAD application.
|
* This program source code file is symbol of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 CERN
|
* 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>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
|
@ -46,6 +46,14 @@ class SYMBOL_LIB_TABLE_ROW;
|
||||||
class LIB_LOGGER;
|
class LIB_LOGGER;
|
||||||
|
|
||||||
|
|
||||||
|
enum class SYMBOL_NAME_FILTER
|
||||||
|
{
|
||||||
|
ALL,
|
||||||
|
ROOT_ONLY,
|
||||||
|
DERIVED_ONLY
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to handle modifications to the symbol libraries.
|
* Class to handle modifications to the symbol libraries.
|
||||||
*/
|
*/
|
||||||
|
@ -238,7 +246,8 @@ public:
|
||||||
*/
|
*/
|
||||||
wxString GetUniqueLibraryName() const;
|
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
|
* 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.
|
* 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 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.
|
* 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.
|
* @param aParent is the #SYMBOL_BUFFER to check against.
|
||||||
* @return the count of #SYMBOL_BUFFER objects removed from the library.
|
* @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;
|
std::deque< std::shared_ptr<SYMBOL_BUFFER> > m_symbols;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 CERN
|
* 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
@ -594,15 +594,22 @@ BOOST_AUTO_TEST_CASE( Inheritance )
|
||||||
{
|
{
|
||||||
std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
|
std::unique_ptr<LIB_SYMBOL> parent = std::make_unique<LIB_SYMBOL>( "parent" );
|
||||||
BOOST_CHECK( parent->IsRoot() );
|
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> ref = std::make_unique<LIB_SYMBOL>( *parent );
|
||||||
|
|
||||||
std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
|
std::unique_ptr<LIB_SYMBOL> child = std::make_unique<LIB_SYMBOL>( "child", parent.get() );
|
||||||
BOOST_CHECK( child->IsAlias() );
|
BOOST_CHECK( child->IsAlias() );
|
||||||
|
BOOST_CHECK_EQUAL( child->GetInheritanceDepth(), 1 );
|
||||||
|
|
||||||
std::unique_ptr<LIB_SYMBOL> grandChild = std::make_unique<LIB_SYMBOL>( "grandchild",
|
std::unique_ptr<LIB_SYMBOL> grandChild = std::make_unique<LIB_SYMBOL>( "grandchild",
|
||||||
child.get() );
|
child.get() );
|
||||||
BOOST_CHECK( grandChild->IsAlias() );
|
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();
|
LIB_SYMBOL_SPTR parentRef = child->GetParent().lock();
|
||||||
BOOST_CHECK( parentRef );
|
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()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Reference in New Issue