More post Pcbnew NETLIST_READER change clean up.

* Fix both legacy and s-expression netlist readers when footprints are
  assigned in the netlist.
* Add some helper functions to NETLIST for detecting when footprints are set
  or not set and when they have been changed while loading the .cmp file.
* Rename a few functions to improve their readability.
This commit is contained in:
Wayne Stambaugh 2013-04-28 16:20:40 -04:00
parent 6b500d606c
commit 4a9681d5c7
11 changed files with 193 additions and 104 deletions

View File

@ -165,7 +165,7 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event )
bool found = false; bool found = false;
m_ListCmp->SetSelection( ii++, true ); m_ListCmp->SetSelection( ii++, true );
if( !component->GetFootprintLibName().IsEmpty() ) if( !component->GetFootprintName().IsEmpty() )
continue; continue;
BOOST_FOREACH( FOOTPRINT_ALIAS& alias, aliases ) BOOST_FOREACH( FOOTPRINT_ALIAS& alias, aliases )

View File

@ -344,7 +344,7 @@ void CVPCB_MAINFRAME::ToFirstNA( wxCommandEvent& event )
for( unsigned jj = 0; jj < m_netlist.GetCount(); jj++ ) for( unsigned jj = 0; jj < m_netlist.GetCount(); jj++ )
{ {
if( m_netlist.GetComponent( jj )->GetFootprintLibName().IsEmpty() && ii > selection ) if( m_netlist.GetComponent( jj )->GetFootprintName().IsEmpty() && ii > selection )
{ {
m_ListCmp->SetSelection( ii ); m_ListCmp->SetSelection( ii );
SendMessageToEESCHEMA(); SendMessageToEESCHEMA();
@ -374,7 +374,7 @@ void CVPCB_MAINFRAME::ToPreviousNA( wxCommandEvent& event )
for( unsigned kk = m_netlist.GetCount() - 1; kk >= 0; kk-- ) for( unsigned kk = m_netlist.GetCount() - 1; kk >= 0; kk-- )
{ {
if( m_netlist.GetComponent( kk )->GetFootprintLibName().IsEmpty() && ii < selection ) if( m_netlist.GetComponent( kk )->GetFootprintName().IsEmpty() && ii < selection )
{ {
m_ListCmp->SetSelection( ii ); m_ListCmp->SetSelection( ii );
SendMessageToEESCHEMA(); SendMessageToEESCHEMA();
@ -414,7 +414,7 @@ void CVPCB_MAINFRAME::DelAssociations( wxCommandEvent& event )
for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
{ {
m_netlist.GetComponent( i )->SetFootprintLibName( wxEmptyString ); m_netlist.GetComponent( i )->SetFootprintName( wxEmptyString );
SetNewPkg( wxEmptyString ); SetNewPkg( wxEmptyString );
} }
@ -568,7 +568,7 @@ void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
if( FindFocus() == m_ListCmp ) if( FindFocus() == m_ListCmp )
{ {
wxString module = m_netlist.GetComponent( selection )->GetFootprintLibName(); wxString module = m_netlist.GetComponent( selection )->GetFootprintName();
bool found = false; bool found = false;
for( int ii = 0; ii < m_FootprintList->GetCount(); ii++ ) for( int ii = 0; ii < m_FootprintList->GetCount(); ii++ )
@ -788,8 +788,8 @@ int CVPCB_MAINFRAME::ReadSchematicNetlist()
// not the actual name of the footprint. // not the actual name of the footprint.
for( unsigned ii = 0; ii < m_netlist.GetCount(); ii++ ) for( unsigned ii = 0; ii < m_netlist.GetCount(); ii++ )
{ {
if( m_netlist.GetComponent( ii )->GetFootprintLibName() == wxT( "$noname" ) ) if( m_netlist.GetComponent( ii )->GetFootprintName() == wxT( "$noname" ) )
m_netlist.GetComponent( ii )->SetFootprintLibName( wxEmptyString ); m_netlist.GetComponent( ii )->SetFootprintName( wxEmptyString );
} }
// Sort components by reference: // Sort components by reference:
@ -840,7 +840,7 @@ bool CVPCB_MAINFRAME::WriteComponentLinkFile( const wxString& aFullFileName )
retval |= fprintf( outputFile, "Reference = %s;\n", TO_UTF8( component->GetReference() ) ); retval |= fprintf( outputFile, "Reference = %s;\n", TO_UTF8( component->GetReference() ) );
retval |= fprintf( outputFile, "ValeurCmp = %s;\n", TO_UTF8( component->GetValue() ) ); retval |= fprintf( outputFile, "ValeurCmp = %s;\n", TO_UTF8( component->GetValue() ) );
retval |= fprintf( outputFile, "IdModule = %s;\n", retval |= fprintf( outputFile, "IdModule = %s;\n",
TO_UTF8( component->GetFootprintLibName() ) ); TO_UTF8( component->GetFootprintName() ) );
retval |= fprintf( outputFile, "EndCmp\n" ); retval |= fprintf( outputFile, "EndCmp\n" );
} }

View File

@ -117,7 +117,7 @@ void CVPCB_MAINFRAME::BuildCmpListBox()
msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1, msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1,
GetChars( component->GetReference() ), GetChars( component->GetReference() ),
GetChars( component->GetValue() ), GetChars( component->GetValue() ),
GetChars( component->GetFootprintLibName() ) ); GetChars( component->GetFootprintName() ) );
m_ListCmp->m_ComponentList.Add( msg ); m_ListCmp->m_ComponentList.Add( msg );
} }

View File

@ -71,16 +71,16 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
// Check to see if the component has already a footprint set. // Check to see if the component has already a footprint set.
hasFootprint = !(component->GetFootprintLibName().IsEmpty()); hasFootprint = !(component->GetFootprintName().IsEmpty());
component->SetFootprintLibName( aFootprintName ); component->SetFootprintName( aFootprintName );
// create the new component description // create the new component description
description.Printf( CMP_FORMAT, componentIndex + 1, description.Printf( CMP_FORMAT, componentIndex + 1,
GetChars( component->GetReference() ), GetChars( component->GetReference() ),
GetChars( component->GetValue() ), GetChars( component->GetValue() ),
GetChars( component->GetFootprintLibName() ) ); GetChars( component->GetFootprintName() ) );
// If the component hasn't had a footprint associated with it // If the component hasn't had a footprint associated with it
// it now has, so we decrement the count of components without // it now has, so we decrement the count of components without
@ -135,10 +135,10 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1, msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1,
GetChars( component->GetReference() ), GetChars( component->GetReference() ),
GetChars( component->GetValue() ), GetChars( component->GetValue() ),
GetChars( component->GetFootprintLibName() ) ); GetChars( component->GetFootprintName() ) );
m_ListCmp->AppendLine( msg ); m_ListCmp->AppendLine( msg );
if( component->GetFootprintLibName().IsEmpty() ) if( component->GetFootprintName().IsEmpty() )
m_undefinedComponentCnt += 1; m_undefinedComponentCnt += 1;
} }

View File

@ -2373,7 +2373,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter )
msg.Printf( _( "Checking netlist component footprint \"%s:%s:%s\".\n" ), msg.Printf( _( "Checking netlist component footprint \"%s:%s:%s\".\n" ),
GetChars( component->GetReference() ), GetChars( component->GetReference() ),
GetChars( component->GetTimeStamp() ), GetChars( component->GetTimeStamp() ),
GetChars( component->GetFootprintLibName() ) ); GetChars( component->GetFootprintName() ) );
aReporter->Report( msg ); aReporter->Report( msg );
} }
@ -2390,13 +2390,13 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter )
msg.Printf( _( "Adding new component \"%s:%s\" footprint \"%s\".\n" ), msg.Printf( _( "Adding new component \"%s:%s\" footprint \"%s\".\n" ),
GetChars( component->GetReference() ), GetChars( component->GetReference() ),
GetChars( component->GetTimeStamp() ), GetChars( component->GetTimeStamp() ),
GetChars( component->GetFootprintLibName() ) ); GetChars( component->GetFootprintName() ) );
else else
msg.Printf( _( "Cannot add new component \"%s:%s\" due to missing " msg.Printf( _( "Cannot add new component \"%s:%s\" due to missing "
"footprint \"%s\".\n" ), "footprint \"%s\".\n" ),
GetChars( component->GetReference() ), GetChars( component->GetReference() ),
GetChars( component->GetTimeStamp() ), GetChars( component->GetTimeStamp() ),
GetChars( component->GetFootprintLibName() ) ); GetChars( component->GetFootprintName() ) );
aReporter->Report( msg ); aReporter->Report( msg );
} }
@ -2414,8 +2414,8 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter )
else // An existing footprint. else // An existing footprint.
{ {
// Test for footprint change. // Test for footprint change.
if( !component->GetFootprintLibName().IsEmpty() && if( !component->GetFootprintName().IsEmpty() &&
footprint->GetLibRef() != component->GetFootprintLibName() ) footprint->GetLibRef() != component->GetFootprintName() )
{ {
if( aNetlist.GetReplaceFootprints() ) if( aNetlist.GetReplaceFootprints() )
{ {
@ -2427,13 +2427,13 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter )
GetChars( footprint->GetReference() ), GetChars( footprint->GetReference() ),
GetChars( footprint->GetPath() ), GetChars( footprint->GetPath() ),
GetChars( footprint->GetLibRef() ), GetChars( footprint->GetLibRef() ),
GetChars( component->GetFootprintLibName() ) ); GetChars( component->GetFootprintName() ) );
else else
msg.Printf( _( "Cannot replace component \"%s:%s\" due to missing " msg.Printf( _( "Cannot replace component \"%s:%s\" due to missing "
"footprint \"%s\".\n" ), "footprint \"%s\".\n" ),
GetChars( footprint->GetReference() ), GetChars( footprint->GetReference() ),
GetChars( footprint->GetPath() ), GetChars( footprint->GetPath() ),
GetChars( component->GetFootprintLibName() ) ); GetChars( component->GetFootprintName() ) );
aReporter->Report( msg ); aReporter->Report( msg );
} }

View File

@ -98,6 +98,7 @@ DIALOG_NETLIST::DIALOG_NETLIST( PCB_EDIT_FRAME* aParent, wxDC * aDC,
GetSizer()->SetSizeHints( this ); GetSizer()->SetSizeHints( this );
} }
void DIALOG_NETLIST::OnOpenNetlistClick( wxCommandEvent& event ) void DIALOG_NETLIST::OnOpenNetlistClick( wxCommandEvent& event )
{ {
wxString lastPath = wxFileName::GetCwd(); wxString lastPath = wxFileName::GetCwd();

View File

@ -283,12 +283,12 @@ void KICAD_NETLIST_PARSER::parseComponent() throw( IO_ERROR, PARSE_ERROR )
*/ */
wxString ref; wxString ref;
wxString value; wxString value;
wxString componentName; wxString footprintName;
wxString libPartName; wxString library;
wxString libName; wxString name;
wxString pathtimestamp, timestamp; wxString pathtimestamp, timestamp;
// The token comp was read, so the next data is (ref P1)
// The token comp was read, so the next data is (ref P1)
while( (token = NextTok()) != T_RIGHT ) while( (token = NextTok()) != T_RIGHT )
{ {
if( token == T_LEFT ) if( token == T_LEFT )
@ -310,7 +310,7 @@ void KICAD_NETLIST_PARSER::parseComponent() throw( IO_ERROR, PARSE_ERROR )
case T_footprint: case T_footprint:
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
componentName = FROM_UTF8( CurText() ); footprintName = FROM_UTF8( CurText() );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -324,13 +324,13 @@ void KICAD_NETLIST_PARSER::parseComponent() throw( IO_ERROR, PARSE_ERROR )
if( token == T_lib ) if( token == T_lib )
{ {
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
libName = FROM_UTF8( CurText() ); library = FROM_UTF8( CurText() );
NeedRIGHT(); NeedRIGHT();
} }
else if( token == T_part ) else if( token == T_part )
{ {
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
libPartName = FROM_UTF8( CurText() ); name = FROM_UTF8( CurText() );
NeedRIGHT(); NeedRIGHT();
} }
else else
@ -362,8 +362,9 @@ void KICAD_NETLIST_PARSER::parseComponent() throw( IO_ERROR, PARSE_ERROR )
} }
pathtimestamp += timestamp; pathtimestamp += timestamp;
COMPONENT* component = new COMPONENT( componentName, ref, value, pathtimestamp ); COMPONENT* component = new COMPONENT( footprintName, ref, value, pathtimestamp );
component->SetLibrarySource( libName, libPartName ); component->SetName( name );
component->SetLibrary( library );
m_netlist->AddComponent( component ); m_netlist->AddComponent( component );
} }

View File

@ -102,9 +102,10 @@ COMPONENT* LEGACY_NETLIST_READER::loadComponent( char* aText ) throw( PARSE_ERRO
char* text; char* text;
wxString msg; wxString msg;
wxString timeStamp; // the full time stamp read from netlist wxString timeStamp; // the full time stamp read from netlist
wxString name; // the component name read from netlist wxString footprintName; // the footprint name read from netlist
wxString value; // the component value read from netlist wxString value; // the component value read from netlist
wxString reference; // the component schematic reference designator read from netlist wxString reference; // the component schematic reference designator read from netlist
wxString name; // the name of component that was placed in the schematic
char line[1024]; char line[1024];
strcpy( line, aText ); strcpy( line, aText );
@ -126,12 +127,16 @@ COMPONENT* LEGACY_NETLIST_READER::loadComponent( char* aText ) throw( PARSE_ERRO
// Read footprint name (second word) // Read footprint name (second word)
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
{ {
msg = _( "Cannot parse name in component section of netlist." ); msg = _( "Cannot parse footprint name in component section of netlist." );
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(), THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
m_lineReader->Length() ); m_lineReader->Length() );
} }
name = FROM_UTF8( text ); footprintName = FROM_UTF8( text );
// The footprint name will have to be looked up in the *.cmp file.
if( footprintName == wxT( "$noname" ) )
footprintName = wxEmptyString;
// Read schematic reference designator (third word) // Read schematic reference designator (third word)
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
@ -153,7 +158,18 @@ COMPONENT* LEGACY_NETLIST_READER::loadComponent( char* aText ) throw( PARSE_ERRO
value = FROM_UTF8( text ); value = FROM_UTF8( text );
COMPONENT* component = new COMPONENT( name, reference, value, timeStamp ); // Read component name (fifth word) {Lib=C}
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
{
msg = _( "Cannot parse name comment in component section of netlist." );
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
m_lineReader->Length() );
}
name = FROM_UTF8( text ).AfterFirst( wxChar( '=' ) ).BeforeLast( wxChar( '}' ) );
COMPONENT* component = new COMPONENT( footprintName, reference, value, timeStamp );
component->SetName( name );
m_netlist->AddComponent( component ); m_netlist->AddComponent( component );
return component; return component;
} }

View File

@ -73,7 +73,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
} }
catch( IO_ERROR& ioe ) catch( IO_ERROR& ioe )
{ {
msg = wxString::Format( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() ); msg.Printf( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() );
wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR ); wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
return; return;
} }
@ -160,15 +160,17 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName()
void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter ) void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
throw( IO_ERROR, PARSE_ERROR ) throw( IO_ERROR, PARSE_ERROR )
{ {
bool loadFootprint;
wxString msg; wxString msg;
wxString lastFootprintLibName; wxString lastFootprintLibName;
COMPONENT* component; COMPONENT* component;
MODULE* module; MODULE* module;
MODULE* fpOnBoard;
if( aNetlist.IsEmpty() ) if( aNetlist.IsEmpty() )
return; return;
aNetlist.SortByFootprintLibName(); aNetlist.SortByFootprintName();
wxString libPath; wxString libPath;
wxFileName fn; wxFileName fn;
@ -179,8 +181,17 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
{ {
component = aNetlist.GetComponent( ii ); component = aNetlist.GetComponent( ii );
// @todo Check if component is already on BOARD and only load footprint if it's needed. // Check if component footprint is already on BOARD and only load the footprint from
if( ii == 0 || component->GetFootprintLibName() != lastFootprintLibName ) // the library if it's needed.
if( aNetlist.IsFindByTimeStamp() )
fpOnBoard = m_Pcb->FindModule( aNetlist.GetComponent( ii )->GetTimeStamp(), true );
else
fpOnBoard = m_Pcb->FindModule( aNetlist.GetComponent( ii )->GetReference() );
loadFootprint = (fpOnBoard != NULL) &&
(fpOnBoard->GetPath() != component->GetFootprintName());
if( loadFootprint && (component->GetFootprintName() != lastFootprintLibName) )
{ {
module = NULL; module = NULL;
@ -194,11 +205,11 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
if( !libPath ) if( !libPath )
continue; continue;
module = pi->FootprintLoad( libPath, component->GetFootprintLibName() ); module = pi->FootprintLoad( libPath, component->GetFootprintName() );
if( module ) if( module )
{ {
lastFootprintLibName = component->GetFootprintLibName(); lastFootprintLibName = component->GetFootprintName();
break; break;
} }
} }
@ -211,7 +222,7 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
msg.Printf( _( "*** Warning: component `%s` footprint <%s> was not found in " msg.Printf( _( "*** Warning: component `%s` footprint <%s> was not found in "
"any libraries. ***\n" ), "any libraries. ***\n" ),
GetChars( component->GetReference() ), GetChars( component->GetReference() ),
GetChars( component->GetFootprintLibName() ) ); GetChars( component->GetFootprintName() ) );
aReporter->Report( msg ); aReporter->Report( msg );
} }

View File

@ -72,7 +72,7 @@ void COMPONENT::SetModule( MODULE* aModule )
aModule->SetReference( m_reference ); aModule->SetReference( m_reference );
aModule->SetValue( m_value ); aModule->SetValue( m_value );
aModule->SetLibRef( m_footprintLibName ); aModule->SetLibRef( m_footprintName );
aModule->SetPath( m_timeStamp ); aModule->SetPath( m_timeStamp );
} }
@ -98,9 +98,11 @@ void COMPONENT::Show( int aNestLevel, REPORTER& aReporter )
NestedSpace( aNestLevel, aReporter ); NestedSpace( aNestLevel, aReporter );
aReporter.Report( wxT( "<component>\n" ) ); aReporter.Report( wxT( "<component>\n" ) );
NestedSpace( aNestLevel+1, aReporter ); NestedSpace( aNestLevel+1, aReporter );
aReporter.Report( wxString::Format( wxT( "<ref=%s value=%s name=%s fpid=%s timestamp=%s>\n" ), aReporter.Report( wxString::Format( wxT( "<ref=%s value=%s name=%s library=%s footprint=%s "
"footprint-lib=%s timestamp=%s>\n" ),
GetChars( m_reference ), GetChars( m_value ), GetChars( m_reference ), GetChars( m_value ),
GetChars( m_name ), GetChars( m_footprintLibName ), GetChars( m_name ), GetChars( m_library ),
GetChars( m_footprintName ), GetChars( m_footprintLib ),
GetChars( m_timeStamp ) ) ); GetChars( m_timeStamp ) ) );
if( !m_footprintFilters.IsEmpty() ) if( !m_footprintFilters.IsEmpty() )
@ -177,36 +179,19 @@ COMPONENT* NETLIST::GetComponentByTimeStamp( const wxString& aTimeStamp )
} }
COMPONENT* NETLIST::GetComponentByLibName( const wxString& aLibName )
{
COMPONENT* component = NULL;
for( unsigned i = 0; i < m_components.size(); i++ )
{
if( m_components[i].GetLibName() == aLibName )
{
component = &m_components[i];
break;
}
}
return component;
}
/** /**
* Function SortByLibName * Function ByFootprintName
* is a helper function used to sort the component list used by loadNewModules. * is a helper function used to sort the component list used by loadNewModules.
*/ */
static bool SortByLibName( const COMPONENT& ref, const COMPONENT& cmp ) static bool ByFootprintName( const COMPONENT& ref, const COMPONENT& cmp )
{ {
return ref.GetFootprintLibName().CmpNoCase( cmp.GetFootprintLibName() ) > 0; return ref.GetFootprintName().CmpNoCase( cmp.GetFootprintName() ) > 0;
} }
void NETLIST::SortByFootprintLibName() void NETLIST::SortByFootprintName()
{ {
m_components.sort( SortByLibName ); m_components.sort( ByFootprintName );
} }
@ -226,6 +211,42 @@ void NETLIST::SortByReference()
} }
bool NETLIST::AnyFootprintsLinked() const
{
for( unsigned i = 0; i < m_components.size(); i++ )
{
if( !m_components[i].GetFootprintName().IsEmpty() )
return true;
}
return false;
}
bool NETLIST::AllFootprintsLinked() const
{
for( unsigned i = 0; i < m_components.size(); i++ )
{
if( m_components[i].GetFootprintName().IsEmpty() )
return false;
}
return true;
}
bool NETLIST::AnyFootprintsChanged() const
{
for( unsigned i = 0; i < m_components.size(); i++ )
{
if( m_components[i].FootprintChanged() )
return true;
}
return false;
}
#if defined( DEBUG ) #if defined( DEBUG )
void NETLIST::Show( int aNestLevel, REPORTER& aReporter ) void NETLIST::Show( int aNestLevel, REPORTER& aReporter )
{ {
@ -413,6 +434,6 @@ void CMP_READER::Load( NETLIST* aNetlist ) throw( IO_ERROR, PARSE_ERROR )
m_lineReader->LineNumber(), m_lineReader->Length() ); m_lineReader->LineNumber(), m_lineReader->Length() );
} }
component->SetFootprintLibName( footprint ); component->SetFootprintName( footprint );
} }
} }

View File

@ -30,7 +30,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <algorithm>
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
#include <fctsys.h> #include <fctsys.h>
@ -106,31 +105,46 @@ class COMPONENT
// ZZZ This timestamp is string, not time_t // ZZZ This timestamp is string, not time_t
wxString m_timeStamp; ///< The component full time stamp found in netlist. wxString m_timeStamp; ///< The component full time stamp found in netlist.
wxString m_name; ///< The name of the component found in the netlist.
/// The name of the footprint in the library assigned to the component. /// The name of the component in #m_library used when it was placed on the schematic..
wxString m_footprintLibName; wxString m_name;
/// The lib part name used to look up the component library part information. This only has /**
/// meaning in the new s-expression netlist file format. * The name of the component library where #m_name was found. This will be set to
wxString m_libraryName; * wxEmptyString for legacy netlist files.
wxString m_libraryPartName; */
wxString m_library;
/// The footprint loaded from the library for this component. /// The name of the footprint in the footprint library assigned to the component.
wxString m_footprintName;
/**
* The name of the footprint library that #m_footprintName is located. This will be
* set to wxEmptyString for legacy netlist formats indicating that all libraries need
* to be searched.
*/
wxString m_footprintLib;
/// The #MODULE loaded for #m_footprintName found in #m_footprintLib.
std::auto_ptr< MODULE > m_footprint; std::auto_ptr< MODULE > m_footprint;
/// Set to true if #m_footprintName or #m_footprintLib was changed when the footprint
/// link file was read.
bool m_footprintChanged;
static COMPONENT_NET m_emptyNet; static COMPONENT_NET m_emptyNet;
public: public:
COMPONENT( const wxString& aName, COMPONENT( const wxString& aFootprintName,
const wxString& aReference, const wxString& aReference,
const wxString& aValue, const wxString& aValue,
const wxString& aTimeStamp ) const wxString& aTimeStamp )
{ {
m_name = aName; m_footprintName = aFootprintName;
m_reference = aReference; m_reference = aReference;
m_value = aValue; m_value = aValue;
m_timeStamp = aTimeStamp; m_timeStamp = aTimeStamp;
m_footprintChanged = false;
} }
virtual ~COMPONENT() { }; virtual ~COMPONENT() { };
@ -148,27 +162,34 @@ public:
void SortPins() { sort( m_nets.begin(), m_nets.end() ); } void SortPins() { sort( m_nets.begin(), m_nets.end() ); }
void SetName( const wxString& aName ) { m_name = aName;}
const wxString& GetName() const { return m_name; }
void SetLibrary( const wxString& aLibrary ) { m_library = aLibrary; }
const wxString& GetLibrary() const { return m_library; }
const wxString& GetReference() const { return m_reference; } const wxString& GetReference() const { return m_reference; }
const wxString& GetValue() const { return m_value; } const wxString& GetValue() const { return m_value; }
void SetFootprintLibName( const wxString& aFootprintLibName ) void SetFootprintName( const wxString& aFootprintName )
{ {
m_footprintLibName = aFootprintLibName; m_footprintChanged = !m_footprintName.IsEmpty() && (m_footprintName != aFootprintName);
m_footprintName = aFootprintName;
} }
const wxString& GetFootprintLibName() const { return m_footprintLibName; } const wxString& GetFootprintName() const { return m_footprintName; }
void SetFootprintLib( const wxString& aFootprintLib )
{
m_footprintChanged = !m_footprintLib.IsEmpty() && (m_footprintLib != aFootprintLib);
m_footprintLib = aFootprintLib;
}
const wxString& GetFootprintLib() const { return m_footprintLib; }
const wxString& GetTimeStamp() const { return m_timeStamp; } const wxString& GetTimeStamp() const { return m_timeStamp; }
const wxString& GetLibName() const { return m_name; }
void SetLibrarySource( const wxString& aLibName, const wxString& aCompName )
{
m_libraryName = aLibName;
m_libraryPartName = aCompName;
}
void SetFootprintFilters( const wxArrayString& aFilterList ) void SetFootprintFilters( const wxArrayString& aFilterList )
{ {
m_footprintFilters = aFilterList; m_footprintFilters = aFilterList;
@ -183,11 +204,13 @@ public:
void SetModule( MODULE* aModule ); void SetModule( MODULE* aModule );
bool IsLibSource( const wxString& aLibName, const wxString& aCompName ) const bool IsLibSource( const wxString& aLibrary, const wxString& aName ) const
{ {
return aLibName == m_libraryName && aCompName == m_libraryPartName; return aLibrary == m_library && aName == m_name;
} }
bool FootprintChanged() const { return m_footprintChanged; }
#if defined(DEBUG) #if defined(DEBUG)
/** /**
* Function Show * Function Show
@ -293,16 +316,7 @@ public:
*/ */
COMPONENT* GetComponentByTimeStamp( const wxString& aTimeStamp ); COMPONENT* GetComponentByTimeStamp( const wxString& aTimeStamp );
/* void SortByFootprintName();
* Function GetComponentByLibName
* returns a #COMPONENT by \a aLibName.
*
* @param aLibName is the component library name of the #COMPONENT.
* @return a pointer to the #COMPONENT that matches \a aLibName if found. Otherwise NULL.
*/
COMPONENT* GetComponentByLibName( const wxString& aLibName );
void SortByFootprintLibName();
void SortByReference(); void SortByReference();
@ -328,6 +342,31 @@ public:
bool GetReplaceFootprints() const { return m_replaceFootprints; } bool GetReplaceFootprints() const { return m_replaceFootprints; }
/**
* Function AnyFootprintsLinked
* @return true if any component with a footprint link is found.
*/
bool AnyFootprintsLinked() const;
/**
* Function AllFootprintsLinked
* @return true if all components have a footprint link.
*/
bool AllFootprintsLinked() const;
/**
* Function NoFootprintsLinked
* @return true if none of the components have a footprint link.
*/
bool NoFootprintsLinked() const { return !AnyFootprintsLinked(); }
/**
* Function AnyFootprintsChanged
* @return true if any components footprints were changed when the footprint link file
* (*.cmp) was loaded.
*/
bool AnyFootprintsChanged() const;
#if defined(DEBUG) #if defined(DEBUG)
/** /**
* Function Show * Function Show