Enable symbol library table remapping.

Check the if the schematic being loaded has been remapped (no symbol
library table nicknames defined) and remap accordingly.

Fix issues when resolving the library symbol links in the schematic
symbols.

Add cache library fallback when resolving symbols that cannot be
remapped.

Add remap complete message to remap dialog.

Add HasLibrary() helper to LIB_TABLE_BASE.

Fix issues when loading library symbols using symbol library table.

Add hashing function to symbol library table.

Improve the symbol panel message to warn user when cache library is
used to resolve symbol.
This commit is contained in:
Wayne Stambaugh 2017-09-01 16:42:20 -04:00
parent 636298b5dc
commit 96c3d5ff21
12 changed files with 132 additions and 40 deletions

View File

@ -251,6 +251,14 @@ const wxString LIB_TABLE::GetDescription( const wxString& aNickname )
}
bool LIB_TABLE::HasLibrary( const wxString& aNickname ) const
{
const LIB_TABLE_ROW* row = findRow( aNickname );
return row != nullptr;
}
LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName ) const
{
LIB_TABLE* cur = (LIB_TABLE*) this;

View File

@ -358,6 +358,18 @@ PART_LIB* PART_LIBS::FindLibrary( const wxString& aName )
}
PART_LIB* PART_LIBS::GetCacheLibrary()
{
for( PART_LIBS::iterator it = begin(); it!=end(); ++it )
{
if( it->IsCache() )
return &*it;
}
return NULL;
}
PART_LIB* PART_LIBS::FindLibraryByFullFileName( const wxString& aFullFileName )
{
for( PART_LIBS::iterator it = begin(); it!=end(); ++it )

View File

@ -258,6 +258,8 @@ public:
PART_LIB* FindLibraryByFullFileName( const wxString& aFullFileName );
PART_LIB* GetCacheLibrary();
/**
* Function GetLibraryNames
* returns the list of part library file names without path and extension.

View File

@ -150,7 +150,6 @@ void DIALOG_SYMBOL_REMAP::createProjectSymbolLibTable( REPORTER& aReporter )
fullFileName += tmp;
fullFileName += fn.GetFullName();
break;
}
}
@ -214,9 +213,12 @@ void DIALOG_SYMBOL_REMAP::remapSymbolsToLibTable( REPORTER& aReporter )
symbol->GetLibId().GetLibItemName().wx_str(),
symbol->GetLibId().GetLibNickname().wx_str() );
aReporter.Report( msg, REPORTER::RPT_ACTION );
screen->SetModify();
}
}
}
aReporter.Report( _( "Symbol library table mapping complete!" ), REPORTER::RPT_INFO );
}
@ -253,7 +255,9 @@ bool DIALOG_SYMBOL_REMAP::remapSymbolToLibTable( SCH_COMPONENT* aSymbol )
LIB_ID id = aSymbol->GetLibId();
id.SetLibNickname( row->GetNickName() );
aSymbol->SetLibId( id, Prj().SchSymbolLibTable() );
// Don't resolve symbol library links now.
aSymbol->SetLibId( id, nullptr, nullptr );
return true;
}
}

View File

@ -48,9 +48,8 @@
#include <eeschema_config.h>
#include <sch_legacy_plugin.h>
#include <sch_eagle_plugin.h>
//#define USE_SCH_LEGACY_IO_PLUGIN
#include <symbol_lib_table.h>
#include <dialog_symbol_remap.h>
bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
@ -343,6 +342,18 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
SCH_SCREENS schematic;
// Convert old projects over to use symbol library table.
if( schematic.HasNoFullyDefinedLibIds() )
{
// Make backups of current schematics just in case something goes wrong.
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
SaveEEFile( screen, false, CREATE_BACKUP_FILE );
DIALOG_SYMBOL_REMAP dlgRemap( this );
dlgRemap.ShowQuasiModal();
}
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
}

View File

@ -241,23 +241,27 @@ void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, PART_LIBS* aLibs )
}
void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTable )
void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTable,
PART_LIB* aCacheLib )
{
if( m_lib_id != aLibId )
{
wxCHECK_RET( aSymLibTable, "No symbol library table provided." );
if( m_lib_id == aLibId )
return;
m_lib_id = aLibId;
SetModified();
LIB_ALIAS* alias = aSymLibTable->LoadSymbol( m_lib_id.GetLibNickname(),
m_lib_id.GetLibItemName() );
LIB_ALIAS* alias = nullptr;
if( aSymLibTable && aSymLibTable->HasLibrary( m_lib_id.GetLibNickname() ) )
alias = aSymLibTable->LoadSymbol( m_lib_id.GetLibNickname(), m_lib_id.GetLibItemName() );
if( !alias && aCacheLib )
alias = aCacheLib->FindAlias( m_lib_id.GetLibItemName() );
if( alias && alias->GetPart() )
m_part = alias->GetPart()->SharedPtr();
else
m_part.reset();
}
}
@ -307,9 +311,17 @@ bool SCH_COMPONENT::Resolve( PART_LIBS* aLibs )
}
bool SCH_COMPONENT::Resolve( SYMBOL_LIB_TABLE& aLibTable )
bool SCH_COMPONENT::Resolve( SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib )
{
LIB_ALIAS* alias = aLibTable.LoadSymbol( m_lib_id );
LIB_ALIAS* alias = nullptr;
if( !m_lib_id.GetLibNickname().empty() && aLibTable.HasLibrary( m_lib_id.GetLibNickname() ) )
alias = aLibTable.LoadSymbol( m_lib_id );
// Fall back to cache library. This is temporary until the new schematic file
// format is implemented.
if( !alias && aCacheLib )
alias = aCacheLib->FindAlias( m_lib_id.GetLibItemName() );
if( alias && alias->GetPart() )
{
@ -373,7 +385,8 @@ void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, PART_LIBS* aLi
}
void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, SYMBOL_LIB_TABLE& aLibTable )
void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, SYMBOL_LIB_TABLE& aLibTable,
PART_LIB* aCacheLib )
{
std::vector<SCH_COMPONENT*> cmp_list;
@ -394,7 +407,8 @@ void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, SYMBOL_LIB_TAB
for( unsigned ii = 0; ii < cmp_list.size (); ++ii )
{
SCH_COMPONENT* cmp = cmp_list[ii];
cmp->Resolve( aLibTable );
curr_libid = cmp->m_lib_id;
cmp->Resolve( aLibTable, aCacheLib );
// Propagate the m_part pointer to other members using the same lib_id
for( unsigned jj = ii+1; jj < cmp_list.size (); ++jj )
@ -1258,7 +1272,7 @@ bool SCH_COMPONENT::Save( FILE* f ) const
name1 = toUTFTildaText( GetField( REFERENCE )->GetText() );
}
wxString part_name = GetLibId().GetLibItemName();
wxString part_name = GetLibId().Format();
if( part_name.size() )
{
@ -1756,7 +1770,13 @@ void SCH_COMPONENT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
if( alias->GetName() != part->GetName() )
aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), part->GetName(), BROWN ) );
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), alias->GetLibraryName(), BROWN ) );
if( m_lib_id.GetLibNickname().empty() && alias->GetLib() && alias->GetLib()->IsCache() )
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), alias->GetLibraryName(), RED ) );
else if( !m_lib_id.GetLibNickname().empty() )
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), m_lib_id.GetLibNickname(),
BROWN ) );
else
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), _( "Undefined!!!" ), RED ) );
// Display the current associated footprint, if exists.
if( !GetField( FOOTPRINT )->IsVoid() )

View File

@ -46,7 +46,7 @@ class LIB_ITEM;
class LIB_PIN;
class LIB_PART;
class NETLIST_OBJECT_LIST;
class LIB_PART;
class PART_LIB;
class PART_LIBS;
class SCH_COLLECTOR;
class SCH_SCREEN;
@ -166,7 +166,7 @@ public:
bool IsMovableFromAnchorPoint() override { return false; }
void SetLibId( const LIB_ID& aName, PART_LIBS* aLibs=NULL );
void SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTable );
void SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTable, PART_LIB* aCacheLib );
const LIB_ID& GetLibId() const { return m_lib_id; }
@ -189,11 +189,12 @@ public:
*/
bool Resolve( PART_LIBS* aLibs );
bool Resolve( SYMBOL_LIB_TABLE& aLibTable );
bool Resolve( SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib = NULL );
static void ResolveAll( const SCH_COLLECTOR& aComponents, PART_LIBS* aLibs );
static void ResolveAll( const SCH_COLLECTOR& aComponents, SYMBOL_LIB_TABLE& aLibTable );
static void ResolveAll( const SCH_COLLECTOR& aComponents, SYMBOL_LIB_TABLE& aLibTable,
PART_LIB* aCacheLib = NULL );
int GetUnit() const { return m_unit; }

View File

@ -1312,7 +1312,9 @@ SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( FILE_LINE_READER& aReader )
parseUnquotedString( libName, aReader, line, &line );
libName.Replace( "~", " " );
LIB_ID libId( wxEmptyString, libName );
LIB_ID libId;
libId.Parse( libName );
component->SetLibId( libId );
@ -1687,7 +1689,7 @@ void SCH_LEGACY_PLUGIN::saveComponent( SCH_COMPONENT* aComponent )
name1 = toUTFTildaText( aComponent->GetField( REFERENCE )->GetText() );
}
wxString part_name = aComponent->GetLibId().GetLibItemName();
wxString part_name = aComponent->GetLibId().Format();
if( part_name.size() )
{
@ -2410,6 +2412,9 @@ LIB_PART* SCH_LEGACY_PLUGIN_CACHE::loadPart( FILE_LINE_READER& aReader )
value.SetVisible( false );
}
// Don't set the library alias, this is determined by the symbol library table.
part->SetLibId( LIB_ID( wxEmptyString, part->GetName() ) );
// There are some code paths in SetText() that do not set the root alias to the
// alias list so add it here if it didn't get added by SetText().
if( !part->HasAlias( part->GetName() ) )

View File

@ -4,7 +4,7 @@
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2008-2016 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2017 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
@ -53,6 +53,7 @@
#include <sch_component.h>
#include <sch_text.h>
#include <lib_pin.h>
#include <symbol_lib_table.h>
#define EESCHEMA_FILE_STAMP "EESchema"
@ -534,7 +535,7 @@ void SCH_SCREEN::CheckComponentsToPartsLinks()
if( m_drawList.GetCount() )
{
PART_LIBS* libs = Prj().SchLibs();
SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
int mod_hash = libs->GetModifyHash();
// Must we resolve?
@ -544,7 +545,7 @@ void SCH_SCREEN::CheckComponentsToPartsLinks()
c.Collect( GetDrawItems(), SCH_COLLECTOR::ComponentsOnly );
SCH_COMPONENT::ResolveAll( c, libs );
SCH_COMPONENT::ResolveAll( c, *libs, Prj().SchLibs()->GetCacheLibrary() );
m_modification_sync = mod_hash; // note the last mod_hash
}

View File

@ -40,6 +40,9 @@ using namespace LIB_TABLE_T;
static const wxString global_tbl_name( "sym-lib-table" );
int SYMBOL_LIB_TABLE::m_modifyHash = 1; // starts at 1 and goes up
/// The global symbol library table. This is not dynamically allocated because
/// in a multiple project environment we must keep its address constant (since it is
/// the fallback table for multiple projects).
@ -220,6 +223,26 @@ void SYMBOL_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) cons
}
int SYMBOL_LIB_TABLE::GetModifyHash()
{
int hash = 0;
std::vector< wxString > libNames = GetLogicalLibs();
for( auto libName : libNames )
{
const SYMBOL_LIB_TABLE_ROW* row = FindRow( libName );
wxASSERT( row && (SCH_PLUGIN*) row->plugin );
hash += row->plugin->GetModifyHash();
}
hash += m_modifyHash;
return hash;
}
void SYMBOL_LIB_TABLE::EnumerateSymbolLib( const wxString& aNickname, wxArrayString& aAliasNames )
{
const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname );
@ -270,12 +293,6 @@ LIB_ALIAS* SYMBOL_LIB_TABLE::LoadSymbol( const wxString& aNickname, const wxStri
// having to copy the LIB_ID and its two strings, twice each.
LIB_ID& id = (LIB_ID&) ret->GetPart()->GetLibId();
// Catch any misbehaving plugin, which should be setting internal alias name properly:
wxASSERT( aAliasName == id.GetLibItemName().wx_str() );
// and clearing nickname
wxASSERT( !id.GetLibNickname().size() );
id.SetLibNickname( row->GetNickName() );
}

View File

@ -101,6 +101,8 @@ class SYMBOL_LIB_TABLE : public LIB_TABLE
friend class SYMBOL_LIB_TABLE_GRID;
friend class DIALOG_SYMBOL_LIB_TABLE;
static int m_modifyHash; ///< helper for GetModifyHash()
public:
virtual void Parse( LIB_TABLE_LEXER* aLexer ) override;
@ -131,6 +133,8 @@ public:
*/
const SYMBOL_LIB_TABLE_ROW* FindRow( const wxString& aNickName );
int GetModifyHash();
//-----<PLUGIN API SUBSET, REBASED ON aNickname>---------------------------
/**

View File

@ -371,6 +371,13 @@ public:
*/
const wxString GetDescription( const wxString& aNickname );
/**
* Test for the existence of \a aNickname in the library table.
*
* @return true if a library \a aNickname exists in the table.
*/
bool HasLibrary( const wxString& aNickname ) const;
/**
* Function GetLogicalLibs
*