From 10265969640487d0660c010d28894945fd50e255 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Sun, 20 Aug 2023 12:05:31 -0400 Subject: [PATCH] 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. --- .../dialogs/dialog_lib_symbol_properties.cpp | 12 ++-- eeschema/eeschema_jobs_handler.cpp | 4 +- eeschema/lib_symbol.cpp | 28 ++++++++ eeschema/lib_symbol.h | 17 +++++ eeschema/project_rescue.cpp | 2 +- eeschema/sch_file_versions.h | 3 +- .../kicad/sch_sexpr_lib_plugin_cache.cpp | 58 ++++++++++------ eeschema/sch_view.cpp | 2 +- eeschema/symbol_editor/symbol_edit_frame.cpp | 15 ++-- eeschema/symbol_editor/symbol_edit_frame.h | 5 +- eeschema/symbol_editor/symbol_editor.cpp | 28 ++++---- eeschema/symbol_library_manager.cpp | 68 ++++++++++++------- eeschema/symbol_library_manager.h | 19 ++++-- eeschema/tools/symbol_editor_control.cpp | 2 +- qa/tests/eeschema/test_lib_part.cpp | 40 +++++++++++ 15 files changed, 218 insertions(+), 85 deletions(-) diff --git a/eeschema/dialogs/dialog_lib_symbol_properties.cpp b/eeschema/dialogs/dialog_lib_symbol_properties.cpp index 8c3a4ca201..9cfc9a8ca8 100644 --- a/eeschema/dialogs/dialog_lib_symbol_properties.cpp +++ b/eeschema/dialogs/dialog_lib_symbol_properties.cpp @@ -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 ); } diff --git a/eeschema/eeschema_jobs_handler.cpp b/eeschema/eeschema_jobs_handler.cpp index 6d9f5ceda7..14588004c8 100644 --- a/eeschema/eeschema_jobs_handler.cpp +++ b/eeschema/eeschema_jobs_handler.cpp @@ -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(); } diff --git a/eeschema/lib_symbol.cpp b/eeschema/lib_symbol.cpp index df41cae708..79fd0bca2c 100644 --- a/eeschema/lib_symbol.cpp +++ b/eeschema/lib_symbol.cpp @@ -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 ); diff --git a/eeschema/lib_symbol.h b/eeschema/lib_symbol.h index 8c04609740..c77ade2158 100644 --- a/eeschema/lib_symbol.h +++ b/eeschema/lib_symbol.h @@ -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 diff --git a/eeschema/project_rescue.cpp b/eeschema/project_rescue.cpp index dfaf7d0c32..d186aacb61 100644 --- a/eeschema/project_rescue.cpp +++ b/eeschema/project_rescue.cpp @@ -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; diff --git a/eeschema/sch_file_versions.h b/eeschema/sch_file_versions.h index d6c141202f..cb1cf09e4a 100644 --- a/eeschema/sch_file_versions.h +++ b/eeschema/sch_file_versions.h @@ -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. diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_lib_plugin_cache.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_lib_plugin_cache.cpp index ec00ac20da..7b3c3f4a60 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_lib_plugin_cache.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_lib_plugin_cache.cpp @@ -35,6 +35,39 @@ #include +/** + * 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& aOpt ) formatter->Print( 0, "(kicad_symbol_lib (version %d) (generator kicad_symbol_editor)\n", SEXPR_SYMBOL_LIB_FILE_VERSION ); + std::set orderedSymbols; + for( const std::pair& 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& alias : m_symbols ) - { - if( !alias.second->IsAlias() ) - continue; - - std::shared_ptr 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" ); diff --git a/eeschema/sch_view.cpp b/eeschema/sch_view.cpp index ea77509efd..e14ce3e963 100644 --- a/eeschema/sch_view.cpp +++ b/eeschema/sch_view.cpp @@ -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 */ ); diff --git a/eeschema/symbol_editor/symbol_edit_frame.cpp b/eeschema/symbol_editor/symbol_edit_frame.cpp index 77648b0760..b4b54262f4 100644 --- a/eeschema/symbol_editor/symbol_edit_frame.cpp +++ b/eeschema/symbol_editor/symbol_edit_frame.cpp @@ -808,28 +808,27 @@ void SYMBOL_EDIT_FRAME::SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom ) } else if( IsSymbolAlias() ) { - std::shared_ptr parent = m_symbol->GetParent().lock(); + std::shared_ptr 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( [=]( wxHyperlinkEvent& aEvent ) { - LoadSymbolFromCurrentLib( parentSymbolName, unit, convert ); + LoadSymbolFromCurrentLib( rootSymbolName, unit, convert ); } ) ); infobar->RemoveAllButtons(); diff --git a/eeschema/symbol_editor/symbol_edit_frame.h b/eeschema/symbol_editor/symbol_edit_frame.h index 5cbf4f223c..3827d8be67 100644 --- a/eeschema/symbol_editor/symbol_edit_frame.h +++ b/eeschema/symbol_editor/symbol_edit_frame.h @@ -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(); diff --git a/eeschema/symbol_editor/symbol_editor.cpp b/eeschema/symbol_editor/symbol_editor.cpp index 19910c6f28..8f85e8bcf2 100644 --- a/eeschema/symbol_editor/symbol_editor.cpp +++ b/eeschema/symbol_editor/symbol_editor.cpp @@ -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 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; } diff --git a/eeschema/symbol_library_manager.cpp b/eeschema/symbol_library_manager.cpp index 18a59f04bd..beff4c7d14 100644 --- a/eeschema/symbol_library_manager.cpp +++ b/eeschema/symbol_library_manager.cpp @@ -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 * * This program is free software; you can redistribute it and/or @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #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 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_ptrGetSymbol()->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 aSymbolBuf ) +int SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::removeChildSymbols( std::shared_ptr& aSymbolBuf ) { - wxCHECK( aSymbolBuf && aSymbolBuf->GetSymbol()->IsRoot(), 0 ); + wxCHECK( aSymbolBuf, 0 ); int cnt = 0; std::deque< std::shared_ptr >::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 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 ); diff --git a/eeschema/symbol_library_manager.h b/eeschema/symbol_library_manager.h index 37866f8f79..b29a352a68 100644 --- a/eeschema/symbol_library_manager.h +++ b/eeschema/symbol_library_manager.h @@ -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 * @@ -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 aSymbolBuf ); + int removeChildSymbols( std::shared_ptr& aSymbolBuf ); std::deque< std::shared_ptr > m_symbols; diff --git a/eeschema/tools/symbol_editor_control.cpp b/eeschema/tools/symbol_editor_control.cpp index 93668cf2d2..90e530c4df 100644 --- a/eeschema/tools/symbol_editor_control.cpp +++ b/eeschema/tools/symbol_editor_control.cpp @@ -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 diff --git a/qa/tests/eeschema/test_lib_part.cpp b/qa/tests/eeschema/test_lib_part.cpp index 686f76ca8d..4e16be3198 100644 --- a/qa/tests/eeschema/test_lib_part.cpp +++ b/qa/tests/eeschema/test_lib_part.cpp @@ -594,15 +594,22 @@ BOOST_AUTO_TEST_CASE( Inheritance ) { std::unique_ptr parent = std::make_unique( "parent" ); BOOST_CHECK( parent->IsRoot() ); + BOOST_CHECK_EQUAL( parent->GetInheritanceDepth(), 0 ); std::unique_ptr ref = std::make_unique( *parent ); std::unique_ptr child = std::make_unique( "child", parent.get() ); BOOST_CHECK( child->IsAlias() ); + BOOST_CHECK_EQUAL( child->GetInheritanceDepth(), 1 ); std::unique_ptr grandChild = std::make_unique( "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 symbol = std::make_unique( "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()