CvPcb footprint library table implementation.
* Add code to CvPcb to handle assigning component footprints from the footprint library table instead of the search path method. * Add code to CvPcb to allow editing of the footprint library table. * CvPcb footprint and component panes display fully qualified FPID names. * Make CvPcb library pane display footprint library table nicknames instead of library file names. * Add code to FP_LIB_TABLE object to test the paths in the table against the list of libraries loaded from the project file. * Add code to FP_LIB_TABLE to convert assigned footprints in a NETLIST from legacy format to footprint library table format. * Split out COMPONENT_NET, COMPONENT, and NETLIST objects from netlist_reader files and create new pcb_netlist files. * Fix minor wxListView scroll bar sizing issues. * Add new token and code to save and load FPID nickname in board file. * Add new token and code to save and load FPID nickname in s-expression net list file. * Add WX_STRING_REPORT object to dump strings to a wxString object.
This commit is contained in:
parent
87290e5248
commit
ce409e3699
|
@ -137,6 +137,7 @@ set(PCB_COMMON_SRCS
|
|||
../pcbnew/legacy_plugin.cpp
|
||||
../pcbnew/kicad_plugin.cpp
|
||||
../pcbnew/gpcb_plugin.cpp
|
||||
../pcbnew/pcb_netlist.cpp
|
||||
pcb_plot_params_keywords.cpp
|
||||
pcb_keywords.cpp
|
||||
../pcbnew/pcb_parser.cpp
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <footprint_info.h>
|
||||
#include <io_mgr.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <fpid.h>
|
||||
|
||||
#include <class_module.h>
|
||||
|
||||
|
@ -182,6 +183,31 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( FP_LIB_TABLE& aTable )
|
|||
}
|
||||
|
||||
|
||||
FOOTPRINT_INFO* FOOTPRINT_LIST::GetModuleInfo( const wxString & aFootprintName )
|
||||
{
|
||||
BOOST_FOREACH( FOOTPRINT_INFO& footprint, m_List )
|
||||
{
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
FPID fpid;
|
||||
|
||||
wxCHECK_MSG( fpid.Parse( TO_UTF8( aFootprintName ) ) < 0, NULL,
|
||||
wxString::Format( wxT( "<%s> is not a valid FPID." ),
|
||||
GetChars( aFootprintName ) ) );
|
||||
|
||||
wxString libNickname = FROM_UTF8( fpid.GetLibNickname().c_str() );
|
||||
wxString footprintName = FROM_UTF8( fpid.GetFootprintName().c_str() );
|
||||
|
||||
if( libNickname == footprint.m_libName && footprintName == footprint.m_Module )
|
||||
return &footprint;
|
||||
#else
|
||||
if( aFootprintName.CmpNoCase( footprint.m_Module ) == 0 )
|
||||
return &footprint;
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool FOOTPRINT_INFO::InLibrary( const wxString& aLibrary ) const
|
||||
{
|
||||
if( aLibrary.IsEmpty() )
|
||||
|
|
|
@ -31,10 +31,14 @@
|
|||
#include <set>
|
||||
|
||||
#include <appl_wxstruct.h>
|
||||
#include <pcb_netlist.h>
|
||||
#include <reporter.h>
|
||||
#include <footprint_info.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <fpid.h>
|
||||
#include <fp_lib_table_lexer.h>
|
||||
#include <fp_lib_table.h>
|
||||
|
||||
|
||||
using namespace FP_LIB_TABLE_T;
|
||||
|
||||
|
||||
|
@ -251,6 +255,35 @@ const FP_LIB_TABLE::ROW* FP_LIB_TABLE::findRow( const wxString& aNickName )
|
|||
}
|
||||
|
||||
|
||||
const FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRowByURI( const wxString& aURI )
|
||||
{
|
||||
FP_LIB_TABLE* cur = this;
|
||||
|
||||
do
|
||||
{
|
||||
cur->ensureIndex();
|
||||
|
||||
for( unsigned i = 0; i < cur->rows.size(); i++ )
|
||||
{
|
||||
wxString uri = ExpandSubstitutions( cur->rows[i].GetFullURI() );
|
||||
|
||||
if( wxFileName::GetPathSeparator() == wxChar( '\\' ) && uri.Find( wxChar( '/' ) ) >= 0 )
|
||||
uri.Replace( wxT( "/" ), wxT( "\\" ) );
|
||||
|
||||
if( (wxFileName::IsCaseSensitive() && uri == aURI)
|
||||
|| (!wxFileName::IsCaseSensitive() && uri.Upper() == aURI.Upper() ) )
|
||||
{
|
||||
return &cur->rows[i]; // found
|
||||
}
|
||||
}
|
||||
|
||||
// not found, search fall back table(s), if any
|
||||
} while( ( cur = cur->fallBack ) != 0 );
|
||||
|
||||
return 0; // not found
|
||||
}
|
||||
|
||||
|
||||
bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace )
|
||||
{
|
||||
ensureIndex();
|
||||
|
@ -281,8 +314,8 @@ const FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const wxString& aLibraryNickName
|
|||
|
||||
if( !row )
|
||||
{
|
||||
wxString msg = wxString::Format( _("lib table contains no logical lib '%s'" ),
|
||||
GetChars( aLibraryNickName ) );
|
||||
wxString msg = wxString::Format( _( "lib table contains no logical lib '%s'" ),
|
||||
GetChars( aLibraryNickName ) );
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
|
@ -320,6 +353,185 @@ bool FP_LIB_TABLE::IsEmpty() const
|
|||
}
|
||||
|
||||
|
||||
bool FP_LIB_TABLE::MissingLegacyLibs( const wxArrayString& aLibNames, wxString* aErrorMsg )
|
||||
{
|
||||
bool retv = false;
|
||||
|
||||
for( unsigned i = 0; i < aLibNames.GetCount(); i++ )
|
||||
{
|
||||
wxFileName fn = wxFileName( wxEmptyString, aLibNames[i], LegacyFootprintLibPathExtension );
|
||||
wxString legacyLibPath = wxGetApp().FindLibraryPath( fn );
|
||||
|
||||
if( legacyLibPath.IsEmpty() )
|
||||
continue;
|
||||
|
||||
if( FindRowByURI( legacyLibPath ) == 0 )
|
||||
{
|
||||
retv = true;
|
||||
|
||||
if( aErrorMsg )
|
||||
*aErrorMsg += wxT( "\"" ) + legacyLibPath + wxT( "\"\n" );
|
||||
}
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
||||
bool FP_LIB_TABLE::ConvertFromLegacy( NETLIST& aNetList, const wxArrayString& aLibNames,
|
||||
REPORTER* aReporter ) throw( IO_ERROR )
|
||||
{
|
||||
wxString msg;
|
||||
FPID lastFPID;
|
||||
COMPONENT* component;
|
||||
MODULE* module = 0;
|
||||
bool retv = true;
|
||||
|
||||
if( aNetList.IsEmpty() )
|
||||
return true;
|
||||
|
||||
aNetList.SortByFPID();
|
||||
|
||||
wxString libPath;
|
||||
wxFileName fn;
|
||||
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
|
||||
|
||||
for( unsigned ii = 0; ii < aNetList.GetCount(); ii++ )
|
||||
{
|
||||
component = aNetList.GetComponent( ii );
|
||||
|
||||
// The footprint hasn't been assigned yet so ignore it.
|
||||
if( component->GetFPID().empty() )
|
||||
continue;
|
||||
|
||||
if( component->GetFPID() != lastFPID )
|
||||
{
|
||||
module = NULL;
|
||||
|
||||
for( unsigned ii = 0; ii < aLibNames.GetCount(); ii++ )
|
||||
{
|
||||
fn = wxFileName( wxEmptyString, aLibNames[ii], LegacyFootprintLibPathExtension );
|
||||
|
||||
libPath = wxGetApp().FindLibraryPath( fn );
|
||||
|
||||
if( !libPath )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Cannot find footprint library file \"%s\" in any of the "
|
||||
"KiCad legacy library search paths.\n" ),
|
||||
GetChars( fn.GetFullPath() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
retv = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
module = pi->FootprintLoad( libPath,
|
||||
FROM_UTF8( component->GetFPID().GetFootprintName().c_str() ) );
|
||||
|
||||
if( module )
|
||||
{
|
||||
lastFPID = component->GetFPID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( module == NULL )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Component `%s` footprint <%s> was not found in any legacy "
|
||||
"library.\n" ),
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
// Clear the footprint assignment since the old library lookup method is no
|
||||
// longer valid.
|
||||
FPID emptyFPID;
|
||||
component->SetFPID( emptyFPID );
|
||||
retv = false;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug( wxT( "Found component %s footprint %s in legacy library <%s>." ),
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) ),
|
||||
GetChars( libPath ) );
|
||||
|
||||
wxString libNickname;
|
||||
|
||||
FP_LIB_TABLE* cur = this;
|
||||
|
||||
do
|
||||
{
|
||||
cur->ensureIndex();
|
||||
|
||||
for( unsigned i = 0; i < cur->rows.size(); i++ )
|
||||
{
|
||||
wxString uri = ExpandSubstitutions( cur->rows[i].GetFullURI() );
|
||||
|
||||
if( wxFileName::GetPathSeparator() == wxChar( '\\' )
|
||||
&& uri.Find( wxChar( '/' ) ) >= 0 )
|
||||
uri.Replace( wxT( "/"), wxT( "\\" ) );
|
||||
|
||||
wxLogDebug( wxT( "Comparing legacy path <%s> to lib table path <%s>." ),
|
||||
GetChars( libPath ), GetChars( uri ) );
|
||||
|
||||
if( uri == libPath )
|
||||
{
|
||||
libNickname = cur->rows[i].GetNickName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while( ( cur = cur->fallBack ) != 0 && libNickname.IsEmpty() );
|
||||
|
||||
if( libNickname.IsEmpty() )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Component `%s` footprint <%s> legacy library path <%s > "
|
||||
"was not found in the footprint library table.\n" ),
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
retv = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
FPID newFPID = lastFPID;
|
||||
|
||||
newFPID.SetLibNickname( libNickname );
|
||||
|
||||
if( !newFPID.IsValid() )
|
||||
{
|
||||
msg.Printf( _( "Component `%s` FPID <%s> is not valid.\n" ),
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( FROM_UTF8( newFPID.Format().c_str() ) ) );
|
||||
aReporter->Report( msg );
|
||||
retv = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The footprint name should already be set.
|
||||
component->SetFPID( newFPID );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
||||
bool FP_LIB_TABLE::LoadGlobalTable( FP_LIB_TABLE& aTable ) throw (IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
bool tableExists = true;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file reporter.h
|
||||
* @file reporter.cpp
|
||||
*/
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
|
@ -43,3 +43,13 @@ REPORTER& WX_TEXT_CTRL_REPORTER::Report( const wxString& aText )
|
|||
m_textCtrl->AppendText( aText );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
REPORTER& WX_STRING_REPORTER::Report( const wxString& aText )
|
||||
{
|
||||
wxCHECK_MSG( m_string != NULL, *this,
|
||||
wxT( "No wxString object defined in WX_STRING_REPORTER." ) );
|
||||
|
||||
*m_string << aText;
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ include_directories(
|
|||
./dialogs
|
||||
../3d-viewer
|
||||
../pcbnew
|
||||
../pcbnew/dialogs
|
||||
../polygon
|
||||
../common
|
||||
${INC_AFTER}
|
||||
|
@ -22,6 +23,8 @@ set( CVPCB_DIALOGS
|
|||
dialogs/dialog_cvpcb_config_fbp.cpp
|
||||
dialogs/dialog_display_options.cpp
|
||||
dialogs/dialog_display_options_base.cpp
|
||||
../pcbnew/dialogs/dialog_fp_lib_table.cpp
|
||||
../pcbnew/dialogs/dialog_fp_lib_table_base.cpp
|
||||
)
|
||||
|
||||
set( CVPCB_SRCS
|
||||
|
|
|
@ -1,6 +1,30 @@
|
|||
/*************/
|
||||
/** cfg.cpp **/
|
||||
/*************/
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2007 Jean-Pierre Charras, jean-pierre.charras
|
||||
* Copyright (C) 1992-2011 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cfg.cpp
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <appl_wxstruct.h>
|
||||
|
@ -9,6 +33,8 @@
|
|||
#include <gestfich.h>
|
||||
#include <param_config.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <confirm.h>
|
||||
|
||||
#include <cvpcb.h>
|
||||
#include <cvpcb_mainframe.h>
|
||||
|
@ -59,8 +85,24 @@ void CVPCB_MAINFRAME::LoadProjectFile( const wxString& aFileName )
|
|||
if( m_NetlistFileExtension.IsEmpty() )
|
||||
m_NetlistFileExtension = wxT( "net" );
|
||||
|
||||
/* User library path takes precedent over default library search paths. */
|
||||
// User library path takes precedent over default library search paths.
|
||||
wxGetApp().InsertLibraryPath( m_UserLibraryPath, 1 );
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
delete m_footprintLibTable;
|
||||
|
||||
// Attempt to load the project footprint library table if it exists.
|
||||
m_footprintLibTable = new FP_LIB_TABLE();
|
||||
|
||||
try
|
||||
{
|
||||
m_footprintLibTable->Load( fn, m_globalFootprintTable );
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
{
|
||||
DisplayError( this, ioe.errorText );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#include <bitmaps.h>
|
||||
#include <msgpanel.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <fpid.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <pcbcommon.h>
|
||||
|
||||
#include <io_mgr.h>
|
||||
#include <class_module.h>
|
||||
|
@ -473,10 +476,59 @@ EDA_COLOR_T DISPLAY_FOOTPRINTS_FRAME::GetGridColor() const
|
|||
|
||||
MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
|
||||
{
|
||||
CVPCB_MAINFRAME* parent = ( CVPCB_MAINFRAME* ) GetParent();
|
||||
MODULE* footprint;
|
||||
|
||||
try
|
||||
{
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
FPID fpid;
|
||||
|
||||
if( fpid.Parse( TO_UTF8( aFootprintName ) ) >= 0 )
|
||||
{
|
||||
DisplayInfoMessage( this, wxString::Format( wxT( "Footprint ID <%s> is not valid." ),
|
||||
GetChars( aFootprintName ) ) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wxString libName = FROM_UTF8( fpid.GetLibNickname().c_str() );
|
||||
|
||||
wxLogDebug( wxT( "Load footprint <%s> from library <%s>." ),
|
||||
fpid.GetFootprintName().c_str(), fpid.GetLibNickname().c_str() );
|
||||
|
||||
const FP_LIB_TABLE::ROW* row;
|
||||
|
||||
try
|
||||
{
|
||||
row = m_footprintLibTable->FindRow( libName );
|
||||
|
||||
if( row == NULL )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "No library named <%s> was found in the footprint library table." ),
|
||||
fpid.GetLibNickname().c_str() );
|
||||
DisplayInfoMessage( this, msg );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
{
|
||||
DisplayError( this, ioe.errorText );
|
||||
}
|
||||
|
||||
wxString footprintName = FROM_UTF8( fpid.GetFootprintName().c_str() );
|
||||
wxString libPath = row->GetFullURI();
|
||||
|
||||
libPath = FP_LIB_TABLE::ExpandSubstitutions( libPath );
|
||||
|
||||
wxLogDebug( wxT( "Loading footprint <%s> from library <%s>." ),
|
||||
GetChars( footprintName ), GetChars( libPath ) );
|
||||
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::EnumFromStr( row->GetType() ) ) );
|
||||
|
||||
footprint = pi->FootprintLoad( libPath, footprintName );
|
||||
#else
|
||||
CVPCB_MAINFRAME* parent = ( CVPCB_MAINFRAME* ) GetParent();
|
||||
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
|
||||
|
||||
for( unsigned i = 0; i < parent->m_ModuleLibNames.GetCount(); ++i )
|
||||
|
@ -493,19 +545,13 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
|
|||
fn.GetFullName().GetData() );
|
||||
|
||||
// @todo we should not be using wxMessageBox directly.
|
||||
wxMessageBox( msg, titleLibLoadError, wxOK | wxICON_ERROR, this );
|
||||
wxMessageBox( msg, wxEmptyString, wxOK | wxICON_ERROR, this );
|
||||
continue;
|
||||
}
|
||||
|
||||
MODULE* footprint = pi->FootprintLoad( libPath, aFootprintName );
|
||||
|
||||
if( footprint )
|
||||
{
|
||||
footprint->SetParent( (EDA_ITEM*) GetBoard() );
|
||||
footprint->SetPosition( wxPoint( 0, 0 ) );
|
||||
return footprint;
|
||||
}
|
||||
footprint = pi->FootprintLoad( libPath, aFootprintName );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
{
|
||||
|
@ -513,6 +559,13 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if( footprint )
|
||||
{
|
||||
footprint->SetParent( (EDA_ITEM*) GetBoard() );
|
||||
footprint->SetPosition( wxPoint( 0, 0 ) );
|
||||
return footprint;
|
||||
}
|
||||
|
||||
wxString msg = wxString::Format( _( "Footprint '%s' not found" ), aFootprintName.GetData() );
|
||||
DisplayError( this, msg );
|
||||
return NULL;
|
||||
|
@ -532,6 +585,7 @@ void DISPLAY_FOOTPRINTS_FRAME::InitDisplay()
|
|||
FOOTPRINT_INFO* module_info = parentframe->m_footprints.GetModuleInfo( footprintName );
|
||||
|
||||
const wxChar *libname;
|
||||
|
||||
if( module_info )
|
||||
libname = GetChars( module_info->GetLibraryPath() );
|
||||
else
|
||||
|
|
|
@ -135,8 +135,14 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
|
|||
{
|
||||
if( aFilterType == UNFILTERED )
|
||||
{
|
||||
#if !defined( USE_FP_LIB_TABLE )
|
||||
msg.Printf( wxT( "%3zu %s" ), newList.GetCount() + 1,
|
||||
GetChars( aList.GetItem( ii ).m_Module ) );
|
||||
#else
|
||||
msg.Printf( wxT( "%3zu %s:%s" ), newList.GetCount() + 1,
|
||||
GetChars( aList.GetItem( ii ).GetLibraryName() ),
|
||||
GetChars( aList.GetItem( ii ).m_Module ) );
|
||||
#endif
|
||||
newList.Add( msg );
|
||||
continue;
|
||||
}
|
||||
|
@ -153,8 +159,14 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
|
|||
&& (aComponent->GetNetCount() != aList.GetItem( ii ).m_padCount) )
|
||||
continue;
|
||||
|
||||
#if !defined( USE_FP_LIB_TABLE )
|
||||
msg.Printf( wxT( "%3zu %s" ), newList.GetCount() + 1,
|
||||
aList.GetItem( ii ).m_Module.GetData() );
|
||||
#else
|
||||
msg.Printf( wxT( "%3zu %s:%s" ), newList.GetCount() + 1,
|
||||
GetChars( aList.GetItem( ii ).GetLibraryName() ),
|
||||
GetChars( aList.GetItem( ii ).m_Module ) );
|
||||
#endif
|
||||
newList.Add( msg );
|
||||
}
|
||||
|
||||
|
@ -169,9 +181,24 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
|
|||
selection = 0;
|
||||
|
||||
DeleteAllItems();
|
||||
SetItemCount( m_footprintList.GetCount() );
|
||||
SetSelection( selection, true );
|
||||
Refresh();
|
||||
|
||||
if( m_footprintList.GetCount() )
|
||||
{
|
||||
SetItemCount( m_footprintList.GetCount() );
|
||||
SetSelection( selection, true );
|
||||
RefreshItems( 0L, m_footprintList.GetCount()-1 );
|
||||
|
||||
#if defined (__WXGTK__ )
|
||||
// @bug On GTK and wxWidgets 2.8.x, this will assert in debug builds because the
|
||||
// column parameter is -1. This was the only way to prevent GTK3 from
|
||||
// ellipsizing long strings down to a few characters. It still doesn't set
|
||||
// the scroll bars correctly (too short) but it's better than any of the
|
||||
// other alternatives. If someone knows how to fix this, please do.
|
||||
SetColumnWidth( -1, wxLIST_AUTOSIZE );
|
||||
#else
|
||||
SetColumnWidth( 0, wxLIST_AUTOSIZE );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -124,7 +124,21 @@ void LIBRARY_LISTBOX::SetLibraryList( const wxArrayString& aList )
|
|||
if( GetCount() == 0 || oldSelection < 0 || oldSelection >= GetCount() )
|
||||
SetSelection( 0, true );
|
||||
|
||||
Refresh();
|
||||
if( m_libraryList.Count() )
|
||||
{
|
||||
RefreshItems( 0L, m_libraryList.Count()-1 );
|
||||
|
||||
#if defined (__WXGTK__ )
|
||||
// @bug On GTK and wxWidgets 2.8.x, this will assert in debug builds because the
|
||||
// column parameter is -1. This was the only way to prevent GTK3 from
|
||||
// ellipsizing long strings down to a few characters. It still doesn't set
|
||||
// the scroll bars correctly (too short) but it's better than any of the
|
||||
// other alternatives. If someone knows how to fix this, please do.
|
||||
SetColumnWidth( -1, wxLIST_AUTOSIZE );
|
||||
#else
|
||||
SetColumnWidth( 0, wxLIST_AUTOSIZE );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,22 +28,25 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <build_version.h>
|
||||
#include <appl_wxstruct.h>
|
||||
#include <macros.h>
|
||||
#include <confirm.h>
|
||||
#include <eda_doc.h>
|
||||
#include <eda_dde.h>
|
||||
#include <gestfich.h>
|
||||
#include <html_messagebox.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <netlist_reader.h>
|
||||
|
||||
#include <cvpcb_mainframe.h>
|
||||
#include <cvpcb.h>
|
||||
#include <cvstruct.h>
|
||||
#include <dialog_cvpcb_config.h>
|
||||
#include <class_DisplayFootprintsFrame.h>
|
||||
#include <cvpcb_id.h>
|
||||
#include <html_messagebox.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include <build_version.h>
|
||||
|
||||
#define FRAME_MIN_SIZE_X 450
|
||||
#define FRAME_MIN_SIZE_Y 300
|
||||
|
@ -54,6 +57,16 @@ static const wxString KeepCvpcbOpenEntry( wxT( "KeepCvpcbOpen" ) );
|
|||
static const wxString FootprintDocFileEntry( wxT( "footprints_doc_file" ) );
|
||||
|
||||
|
||||
/**
|
||||
* Function InvokePcbLibTableEditor
|
||||
* shows the modal DIALOG_FP_LIB_TABLE for purposes of editing two lib tables.
|
||||
*
|
||||
* @return int - bits 0 and 1 tell whether a change was made to the @a aGlobal
|
||||
* and/or the @a aProject table, respectively. If set, table was modified.
|
||||
*/
|
||||
int InvokePcbLibTableEditor( wxFrame* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject );
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( CVPCB_MAINFRAME, EDA_BASE_FRAME )
|
||||
EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, CVPCB_MAINFRAME::LoadNetList )
|
||||
|
||||
|
@ -69,6 +82,10 @@ BEGIN_EVENT_TABLE( CVPCB_MAINFRAME, EDA_BASE_FRAME )
|
|||
EVT_MENU( ID_SAVE_PROJECT_AS, CVPCB_MAINFRAME::SaveProjectFile )
|
||||
EVT_MENU( ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE, CVPCB_MAINFRAME::OnKeepOpenOnSave )
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
EVT_MENU( ID_CVPCB_LIB_TABLE_EDIT, CVPCB_MAINFRAME::OnEditFootprintLibraryTable )
|
||||
#endif
|
||||
|
||||
EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, CVPCB_MAINFRAME::SetLanguage )
|
||||
|
||||
// Toolbar events
|
||||
|
@ -114,6 +131,11 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( const wxString& title, long style ) :
|
|||
m_undefinedComponentCnt = 0;
|
||||
m_skipComponentSelect = false;
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
m_globalFootprintTable = NULL;
|
||||
m_footprintLibTable = NULL;
|
||||
#endif
|
||||
|
||||
/* Name of the document footprint list
|
||||
* usually located in share/modules/footprints_doc
|
||||
* this is of the responsibility to users to create this file
|
||||
|
@ -185,6 +207,39 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( const wxString& title, long style ) :
|
|||
Right().BestSize( (int) ( m_FrameSize.x * 0.30 ), m_FrameSize.y ) );
|
||||
|
||||
m_auimgr.Update();
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
if( m_globalFootprintTable == NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_globalFootprintTable = new FP_LIB_TABLE();
|
||||
|
||||
if( !FP_LIB_TABLE::LoadGlobalTable( *m_globalFootprintTable ) )
|
||||
{
|
||||
DisplayInfoMessage( this, wxT( "You have run CvPcb for the first time using the "
|
||||
"new footprint library table method of finding "
|
||||
"footprints. CvPcb has either copied the default "
|
||||
"table or created an empty table in your home "
|
||||
"folder. You must first configure the library "
|
||||
"table to include all footprint libraries not "
|
||||
"included with KiCad. See the \"Footprint Library "
|
||||
"Table\" section of the CvPcb documentation for "
|
||||
"more information." ) );
|
||||
}
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "An error occurred attempting to load the global footprint library "
|
||||
"table:\n\n%s" ), GetChars( ioe.errorText ) );
|
||||
DisplayError( this, msg );
|
||||
}
|
||||
|
||||
m_footprintLibTable = new FP_LIB_TABLE( m_globalFootprintTable );
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -466,6 +521,30 @@ void CVPCB_MAINFRAME::ConfigCvpcb( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent )
|
||||
{
|
||||
int r = InvokePcbLibTableEditor( this, m_globalFootprintTable, m_footprintLibTable );
|
||||
|
||||
if( r & 1 )
|
||||
{
|
||||
FILE_OUTPUTFORMATTER sf( FP_LIB_TABLE::GetGlobalTableFileName() );
|
||||
m_globalFootprintTable->Format( &sf, 0 );
|
||||
}
|
||||
|
||||
if( r & 2 )
|
||||
{
|
||||
wxFileName fn = m_NetlistFileName;
|
||||
fn.SetName( FP_LIB_TABLE::GetFileName() );
|
||||
fn.SetExt( wxEmptyString );
|
||||
|
||||
FILE_OUTPUTFORMATTER sf( fn.GetFullPath() );
|
||||
m_footprintLibTable->Format( &sf, 0 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::OnKeepOpenOnSave( wxCommandEvent& event )
|
||||
{
|
||||
m_KeepCvpcbOpen = event.IsChecked();
|
||||
|
@ -523,7 +602,7 @@ void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
|
|||
// selected footprint.
|
||||
if( FindFocus() == m_ListCmp || FindFocus() == m_LibraryList )
|
||||
{
|
||||
wxString module = FROM_UTF8( component->GetFPID().GetFootprintName().c_str() );
|
||||
wxString module = FROM_UTF8( component->GetFPID().Format().c_str() );
|
||||
|
||||
bool found = false;
|
||||
|
||||
|
@ -667,7 +746,12 @@ bool CVPCB_MAINFRAME::LoadFootprintFiles()
|
|||
return false;
|
||||
}
|
||||
|
||||
#if !defined( USE_FP_LIB_TABLE )
|
||||
m_footprints.ReadFootprintFiles( m_ModuleLibNames );
|
||||
#else
|
||||
if( m_footprintLibTable != NULL )
|
||||
m_footprints.ReadFootprintFiles( *m_footprintLibTable );
|
||||
#endif
|
||||
|
||||
// Display error messages, if any.
|
||||
if( !m_footprints.m_filesNotFound.IsEmpty() || !m_footprints.m_filesInvalid.IsEmpty() )
|
||||
|
@ -770,7 +854,7 @@ int CVPCB_MAINFRAME::ReadSchematicNetlist()
|
|||
netlistReader->LoadNetlist();
|
||||
}
|
||||
else
|
||||
wxMessageBox( _( "Unknown netlist format" ), wxEmptyString, wxOK | wxICON_ERROR );
|
||||
wxMessageBox( _( "Unknown netlist format." ), wxEmptyString, wxOK | wxICON_ERROR );
|
||||
}
|
||||
catch( IO_ERROR& ioe )
|
||||
{
|
||||
|
@ -852,6 +936,11 @@ void CVPCB_MAINFRAME::CreateScreenCmp()
|
|||
wxPoint( 0, 0 ),
|
||||
wxSize( 600, 400 ),
|
||||
KICAD_DEFAULT_DRAWFRAME_STYLE );
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
m_DisplayFootprintFrame->SetFootprintLibTable( m_footprintLibTable );
|
||||
#endif
|
||||
|
||||
m_DisplayFootprintFrame->Show( true );
|
||||
}
|
||||
else
|
||||
|
@ -913,8 +1002,23 @@ void CVPCB_MAINFRAME::BuildCmpListBox()
|
|||
m_ListCmp->m_ComponentList.Add( msg );
|
||||
}
|
||||
|
||||
m_ListCmp->SetItemCount( m_ListCmp->m_ComponentList.Count() );
|
||||
m_ListCmp->SetSelection( 0, true );
|
||||
if( m_ListCmp->m_ComponentList.Count() )
|
||||
{
|
||||
m_ListCmp->SetItemCount( m_ListCmp->m_ComponentList.Count() );
|
||||
m_ListCmp->SetSelection( 0, true );
|
||||
m_ListCmp->RefreshItems( 0L, m_ListCmp->m_ComponentList.Count()-1 );
|
||||
|
||||
#if defined (__WXGTK__ )
|
||||
// @bug On GTK and wxWidgets 2.8.x, this will assert in debug builds because the
|
||||
// column parameter is -1. This was the only way to prevent GTK3 from
|
||||
// ellipsizing long strings down to a few characters. It still doesn't set
|
||||
// the scroll bars correctly (too short) but it's better than any of the
|
||||
// other alternatives. If someone knows how to fix this, please do.
|
||||
m_ListCmp->SetColumnWidth( -1, wxLIST_AUTOSIZE );
|
||||
#else
|
||||
m_ListCmp->SetColumnWidth( 0, wxLIST_AUTOSIZE );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -932,7 +1036,21 @@ void CVPCB_MAINFRAME::BuildLIBRARY_LISTBOX()
|
|||
wxFONTWEIGHT_NORMAL ) );
|
||||
}
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
if( m_footprintLibTable )
|
||||
{
|
||||
wxArrayString libNames;
|
||||
|
||||
std::vector< wxString > libNickNames = m_footprintLibTable->GetLogicalLibs();
|
||||
|
||||
for( unsigned ii = 0; ii < libNickNames.size(); ii++ )
|
||||
libNames.Add( libNickNames[ii] );
|
||||
|
||||
m_LibraryList->SetLibraryList( libNames );
|
||||
}
|
||||
#else
|
||||
m_LibraryList->SetLibraryList( m_ModuleLibNames );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,21 +5,16 @@
|
|||
#ifndef __CVPCB_H__
|
||||
#define __CVPCB_H__
|
||||
|
||||
#include <pcbcommon.h>
|
||||
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
||||
// config for footprints doc file access
|
||||
#define DEFAULT_FOOTPRINTS_LIST_FILENAME wxT( "footprints_doc/footprints.pdf" )
|
||||
|
||||
// Define print format to display a schematic component line
|
||||
#define CMP_FORMAT wxT( "%3d %8s - %16s : %-.32s" )
|
||||
#define CMP_FORMAT wxT( "%3d %8s - %16s : %s" )
|
||||
|
||||
#define FILTERFOOTPRINTKEY "FilterFootprint"
|
||||
|
||||
#define LISTB_STYLE (wxSUNKEN_BORDER | wxLC_NO_HEADER | wxLC_REPORT | wxLC_VIRTUAL)
|
||||
#define LISTB_STYLE ( wxSUNKEN_BORDER | wxLC_NO_HEADER | wxLC_REPORT | wxLC_VIRTUAL | \
|
||||
wxLC_SINGLE_SEL | wxVSCROLL | wxHSCROLL )
|
||||
|
||||
extern const wxString FootprintAliasFileExtension;
|
||||
extern const wxString RetroFileExtension;
|
||||
|
|
|
@ -32,5 +32,6 @@ enum id_cvpcb_frm
|
|||
ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
|
||||
ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
|
||||
ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE,
|
||||
ID_CVPCB_LIBRARY_LIST
|
||||
ID_CVPCB_LIBRARY_LIST,
|
||||
ID_CVPCB_LIB_TABLE_EDIT
|
||||
};
|
||||
|
|
|
@ -31,12 +31,11 @@
|
|||
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/filename.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <pcb_netlist.h>
|
||||
#include <footprint_info.h>
|
||||
|
||||
#include <wxBasePcbFrame.h>
|
||||
#include <param_config.h>
|
||||
#include <cvpcb.h>
|
||||
|
||||
|
||||
/* Forward declarations of all top-level window classes. */
|
||||
|
@ -46,6 +45,7 @@ class COMPONENTS_LISTBOX;
|
|||
class LIBRARY_LISTBOX;
|
||||
class DISPLAY_FOOTPRINTS_FRAME;
|
||||
class COMPONENT;
|
||||
class FP_LIB_TABLE;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -55,6 +55,16 @@ class CVPCB_MAINFRAME : public EDA_BASE_FRAME
|
|||
{
|
||||
wxArrayString m_footprintListEntries;
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
/// The global footprint library table.
|
||||
FP_LIB_TABLE* m_globalFootprintTable;
|
||||
|
||||
/// The project footprint library table. This is a combination of the project
|
||||
/// footprint library table and the global footprint table. This is the one to
|
||||
/// use when finding a #MODULE.
|
||||
FP_LIB_TABLE* m_footprintLibTable;
|
||||
#endif
|
||||
|
||||
public:
|
||||
bool m_KeepCvpcbOpen;
|
||||
FOOTPRINTS_LISTBOX* m_FootprintList;
|
||||
|
@ -92,6 +102,13 @@ public:
|
|||
*/
|
||||
void OnSelectComponent( wxListEvent& event );
|
||||
|
||||
/**
|
||||
* Function OnEditFootrprintLibraryTable
|
||||
* displays the footprint library table editing dialog and updates the global and local
|
||||
* footprint tables accordingly.
|
||||
*/
|
||||
void OnEditFootrprintLibraryTable( wxCommandEvent& event );
|
||||
|
||||
void OnQuit( wxCommandEvent& event );
|
||||
void OnCloseWindow( wxCloseEvent& Event );
|
||||
void OnSize( wxSizeEvent& SizeEvent );
|
||||
|
@ -126,6 +143,15 @@ public:
|
|||
void LoadNetList( wxCommandEvent& event );
|
||||
|
||||
void ConfigCvpcb( wxCommandEvent& event );
|
||||
|
||||
/**
|
||||
* Function OnEditLibraryTable
|
||||
* envokes the footpirnt library table edit dialog.
|
||||
*/
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
void OnEditFootprintLibraryTable( wxCommandEvent& aEvent );
|
||||
#endif
|
||||
|
||||
void OnKeepOpenOnSave( wxCommandEvent& event );
|
||||
void DisplayModule( wxCommandEvent& event );
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include <wx/listctrl.h>
|
||||
|
||||
#include <cvpcb.h>
|
||||
|
||||
/* Forward declarations of all top-level window classes. */
|
||||
class CVPCB_MAINFRAME;
|
||||
|
|
|
@ -110,11 +110,17 @@ void CVPCB_MAINFRAME::ReCreateMenuBar()
|
|||
// Menu Preferences:
|
||||
wxMenu* preferencesMenu = new wxMenu;
|
||||
|
||||
#if !defined( USE_FP_LIB_TABLE )
|
||||
// Libraries to load
|
||||
AddMenuItem( preferencesMenu, wxID_PREFERENCES,
|
||||
_( "&Libraries" ),
|
||||
_( "Set footprint libraries to load and library search paths" ),
|
||||
KiBitmap( config_xpm ) );
|
||||
#else
|
||||
AddMenuItem( preferencesMenu, ID_CVPCB_LIB_TABLE_EDIT,
|
||||
_( "Li&brary Tables" ), _( "Setup footprint libraries" ),
|
||||
KiBitmap( library_table_xpm ) );
|
||||
#endif
|
||||
|
||||
// Language submenu
|
||||
wxGetApp().AddMenuLanguageList( preferencesMenu );
|
||||
|
|
|
@ -31,6 +31,11 @@
|
|||
#include <common.h>
|
||||
#include <confirm.h>
|
||||
#include <build_version.h>
|
||||
#include <macros.h>
|
||||
#include <fpid.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <reporter.h>
|
||||
#include <html_messagebox.h>
|
||||
|
||||
#include <cvpcb.h>
|
||||
#include <cvpcb_mainframe.h>
|
||||
|
@ -50,7 +55,6 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
|||
return;
|
||||
|
||||
// If no component is selected, select the first one
|
||||
|
||||
if( m_ListCmp->GetFirstSelected() < 0 )
|
||||
{
|
||||
componentIndex = 0;
|
||||
|
@ -58,11 +62,9 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
|||
}
|
||||
|
||||
// iterate over the selection
|
||||
|
||||
while( m_ListCmp->GetFirstSelected() != -1)
|
||||
while( m_ListCmp->GetFirstSelected() != -1 )
|
||||
{
|
||||
// Get the component for the current iteration
|
||||
|
||||
componentIndex = m_ListCmp->GetFirstSelected();
|
||||
component = m_netlist.GetComponent( componentIndex );
|
||||
|
||||
|
@ -70,13 +72,21 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
|||
return;
|
||||
|
||||
// Check to see if the component has already a footprint set.
|
||||
|
||||
hasFootprint = !component->GetFPID().empty();
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
FPID fpid;
|
||||
|
||||
wxCHECK_RET( fpid.Parse( TO_UTF8( aFootprintName ) ) < 0,
|
||||
wxString::Format( wxT( "<%s> is not a valid FPID." ),
|
||||
GetChars( aFootprintName ) ) );
|
||||
|
||||
component->SetFPID( fpid );
|
||||
#else
|
||||
component->SetFPID( FPID( aFootprintName ) );
|
||||
#endif
|
||||
|
||||
// create the new component description
|
||||
|
||||
description.Printf( CMP_FORMAT, componentIndex + 1,
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( component->GetValue() ),
|
||||
|
@ -85,7 +95,6 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
|||
// If the component hasn't had a footprint associated with it
|
||||
// it now has, so we decrement the count of components without
|
||||
// a footprint assigned.
|
||||
|
||||
if( !hasFootprint )
|
||||
{
|
||||
hasFootprint = true;
|
||||
|
@ -115,6 +124,7 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
|
|||
{
|
||||
COMPONENT* component;
|
||||
wxString msg;
|
||||
bool isLegacy = true;
|
||||
|
||||
ReadSchematicNetlist();
|
||||
|
||||
|
@ -129,6 +139,87 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
|
|||
m_ListCmp->Clear();
|
||||
m_undefinedComponentCnt = 0;
|
||||
|
||||
if( m_netlist.AnyFootprintsLinked() )
|
||||
{
|
||||
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||
{
|
||||
component = m_netlist.GetComponent( i );
|
||||
|
||||
if( component->GetFPID().empty() )
|
||||
continue;
|
||||
|
||||
if( isLegacy )
|
||||
{
|
||||
if( !component->GetFPID().IsLegacy() )
|
||||
isLegacy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isLegacy = false; // None of the components have footprints assigned.
|
||||
}
|
||||
|
||||
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
wxString missingLibs;
|
||||
|
||||
// Check if footprint links were generated before the footprint library table was implemented.
|
||||
if( isLegacy )
|
||||
{
|
||||
if( m_footprintLibTable->MissingLegacyLibs( m_ModuleLibNames, &missingLibs ) )
|
||||
{
|
||||
msg = wxT( "The following legacy libraries are defined in the project file "
|
||||
"were not found in the footprint library table:\n\n" ) + missingLibs;
|
||||
msg += wxT( "\nDo you want to update the footprint library table before "
|
||||
"attempting to update the assigned footprints?" );
|
||||
|
||||
if( IsOK( this, msg ) )
|
||||
{
|
||||
wxCommandEvent cmd;
|
||||
|
||||
OnEditFootprintLibraryTable( cmd );
|
||||
}
|
||||
}
|
||||
|
||||
msg = wxT( "Some or all of the assigned footprints contain legacy entries. Would you "
|
||||
"like CvPcb to attempt to convert them to the new footprint library table "
|
||||
"format?" );
|
||||
|
||||
if( IsOK( this, msg ) )
|
||||
{
|
||||
msg.Clear();
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
|
||||
if( !m_footprintLibTable->ConvertFromLegacy( m_netlist, m_ModuleLibNames, &reporter ) )
|
||||
{
|
||||
HTML_MESSAGE_BOX dlg( this, wxEmptyString );
|
||||
|
||||
dlg.MessageSet( wxT( "The following errors occurred attempt to convert the "
|
||||
"footprint assignments:\n\n" ) );
|
||||
dlg.ListSet( msg );
|
||||
dlg.MessageSet( wxT( "\nYou will need to reassign them manually if you want them "
|
||||
"to be updated correctly the next time you import the "
|
||||
"netlist in Pcbnew." ) );
|
||||
dlg.ShowModal();
|
||||
}
|
||||
|
||||
m_modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear the legacy footprint assignments.
|
||||
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||
{
|
||||
FPID emptyFPID;
|
||||
component = m_netlist.GetComponent( i );
|
||||
component->SetFPID( emptyFPID );
|
||||
m_modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||
{
|
||||
component = m_netlist.GetComponent( i );
|
||||
|
@ -137,10 +228,14 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
|
|||
GetChars( component->GetReference() ),
|
||||
GetChars( component->GetValue() ),
|
||||
GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
|
||||
|
||||
m_ListCmp->AppendLine( msg );
|
||||
|
||||
if( component->GetFPID().empty() )
|
||||
{
|
||||
m_undefinedComponentCnt += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_netlist.IsEmpty() )
|
||||
|
|
|
@ -102,15 +102,7 @@ public:
|
|||
* @return the item stored in list if found
|
||||
* @param aFootprintName = the name of item
|
||||
*/
|
||||
FOOTPRINT_INFO * GetModuleInfo( const wxString & aFootprintName )
|
||||
{
|
||||
BOOST_FOREACH( FOOTPRINT_INFO& footprint, m_List )
|
||||
{
|
||||
if( aFootprintName.CmpNoCase( footprint.m_Module ) == 0 )
|
||||
return &footprint;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
FOOTPRINT_INFO* GetModuleInfo( const wxString & aFootprintName );
|
||||
|
||||
/**
|
||||
* Function GetItem
|
||||
|
@ -159,6 +151,13 @@ public:
|
|||
/// FOOTPRINT object list sort function.
|
||||
inline bool operator<( const FOOTPRINT_INFO& item1, const FOOTPRINT_INFO& item2 )
|
||||
{
|
||||
#if defined( USE_FP_LIB_TABLE )
|
||||
int retv = StrNumCmp( item1.m_libName, item2.m_libName, INT_MAX, true );
|
||||
|
||||
if( retv != 0 )
|
||||
return retv < 0;
|
||||
#endif
|
||||
|
||||
return StrNumCmp( item1.m_Module, item2.m_Module, INT_MAX, true ) < 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,13 +31,16 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
//#include <fpid.h>
|
||||
#include <io_mgr.h>
|
||||
|
||||
|
||||
class wxFileName;
|
||||
class OUTPUTFORMATTER;
|
||||
class MODULE;
|
||||
class FP_LIB_TABLE_LEXER;
|
||||
class NETLIST;
|
||||
class REPORTER;
|
||||
|
||||
|
||||
/**
|
||||
* Class FP_LIB_TABLE
|
||||
|
@ -355,12 +358,50 @@ public:
|
|||
*/
|
||||
const ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function FindRowByURI
|
||||
* returns a #ROW if aURE is found in this table or in any chained
|
||||
* fallBack table fragments, else NULL.
|
||||
*/
|
||||
const ROW* FindRowByURI( const wxString& aURI );
|
||||
|
||||
/**
|
||||
* Function IsEmpty
|
||||
* @return true if the footprint library table is empty.
|
||||
*/
|
||||
bool IsEmpty() const;
|
||||
|
||||
/**
|
||||
* Function MissingLegacyLibs
|
||||
* tests the list of \a aLibNames by URI to determine if any of them are missing from
|
||||
* the #FP_LIB_TABLE.
|
||||
*
|
||||
* @note The missing legacy footprint library test is performed by using old library
|
||||
* file path lookup method. If the library is found, it is compared against all
|
||||
* of the URIs in the table rather than the nickname. This was done because the
|
||||
* user could change the nicknames from the default table. Using the full path
|
||||
* is more reliable.
|
||||
*
|
||||
* @param aLibNames is the list of legacy library names.
|
||||
* @param aErrorMsg is a pointer to a wxString object to store the URIs of any missing
|
||||
* legacy library paths. Can be NULL.
|
||||
* @return true if there are missing legacy libraries. Otherwise false.
|
||||
*/
|
||||
bool MissingLegacyLibs( const wxArrayString& aLibNames, wxString* aErrorMsg = NULL );
|
||||
|
||||
/**
|
||||
* Function ConvertFromLegacy
|
||||
* converts the footprint names in \a aNetList from the legacy fromat to the #FPID format.
|
||||
*
|
||||
* @param aNetList is the #NETLIST object to convert.
|
||||
* @param aLibNames is the list of legacy footprint library names from the currently loaded
|
||||
* project.
|
||||
* @param aReporter is the #REPORTER object to dump messages into.
|
||||
* @return true if all footprint names were successfully converted to a valid FPID.
|
||||
*/
|
||||
bool ConvertFromLegacy( NETLIST& aNetList, const wxArrayString& aLibNames,
|
||||
REPORTER* aReporter = NULL ) throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function ExpandEnvSubsitutions
|
||||
* replaces any environment variable references with their values and is
|
||||
|
|
|
@ -136,4 +136,23 @@ public:
|
|||
REPORTER& Report( const wxString& aText );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class WX_STRING_REPROTER
|
||||
* is a wrapper for reporting to a wxString object.
|
||||
*/
|
||||
class WX_STRING_REPORTER : public REPORTER
|
||||
{
|
||||
wxString* m_string;
|
||||
|
||||
public:
|
||||
WX_STRING_REPORTER( wxString* aString ) :
|
||||
REPORTER(),
|
||||
m_string( aString )
|
||||
{
|
||||
}
|
||||
|
||||
REPORTER& Report( const wxString& aText );
|
||||
};
|
||||
|
||||
#endif // _REPORTER_H_
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include <pcbcommon.h>
|
||||
#include <wxBasePcbFrame.h>
|
||||
#include <msgpanel.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <pcb_netlist.h>
|
||||
#include <reporter.h>
|
||||
#include <base_units.h>
|
||||
|
||||
|
|
|
@ -29,11 +29,13 @@
|
|||
#include <fctsys.h>
|
||||
#include <appl_wxstruct.h>
|
||||
#include <confirm.h>
|
||||
#include <macros.h>
|
||||
#include <dialog_helpers.h>
|
||||
#include <html_messagebox.h>
|
||||
#include <base_units.h>
|
||||
#include <wxPcbStruct.h>
|
||||
#include <pcbcommon.h>
|
||||
#include <pcb_netlist.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <reporter.h>
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <wx/wx.h>
|
||||
#include <netlist_lexer.h> // netlist_lexer is common to Eeschema and Pcbnew
|
||||
#include <macros.h>
|
||||
|
||||
#include <pcb_netlist.h>
|
||||
#include <netlist_reader.h>
|
||||
|
||||
using namespace NL_T;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <richio.h>
|
||||
#include <kicad_string.h>
|
||||
|
||||
#include <pcb_netlist.h>
|
||||
#include <netlist_reader.h>
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <confirm.h>
|
||||
#include <dialog_helpers.h>
|
||||
#include <wxPcbStruct.h>
|
||||
#include <pcb_netlist.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <reporter.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
|
|
@ -31,267 +31,13 @@
|
|||
#include <kicad_string.h>
|
||||
#include <reporter.h>
|
||||
|
||||
#include <pcb_netlist.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <class_module.h>
|
||||
|
||||
#include <wx/regex.h>
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
/**
|
||||
* Function NestedSpace
|
||||
* outputs nested space for pretty indenting.
|
||||
* @param aNestLevel The nest count
|
||||
* @param aReporter A reference to a #REPORTER object where to output.
|
||||
* @return REPORTER& for continuation.
|
||||
**/
|
||||
static REPORTER& NestedSpace( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
for( int i = 0; i < aNestLevel; ++i )
|
||||
aReporter.Report( wxT( " " ) );
|
||||
|
||||
return aReporter;
|
||||
}
|
||||
|
||||
|
||||
void COMPONENT_NET::Show( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( wxString::Format( wxT( "<pin_name=%s net_name=%s>\n" ),
|
||||
GetChars( m_pinName ), GetChars( m_netName ) ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void COMPONENT::SetModule( MODULE* aModule )
|
||||
{
|
||||
m_footprint.reset( aModule );
|
||||
|
||||
if( aModule == NULL )
|
||||
return;
|
||||
|
||||
aModule->SetReference( m_reference );
|
||||
aModule->SetValue( m_value );
|
||||
aModule->SetFPID( m_fpid );
|
||||
aModule->SetPath( m_timeStamp );
|
||||
}
|
||||
|
||||
|
||||
COMPONENT_NET COMPONENT::m_emptyNet;
|
||||
|
||||
|
||||
const COMPONENT_NET& COMPONENT::GetNet( const wxString& aPinName )
|
||||
{
|
||||
for( unsigned i = 0; i < m_nets.size(); i++ )
|
||||
{
|
||||
if( m_nets[i].GetPinName() == aPinName )
|
||||
return m_nets[i];
|
||||
}
|
||||
|
||||
return m_emptyNet;
|
||||
}
|
||||
|
||||
|
||||
bool COMPONENT::MatchesFootprintFilters( const wxString& aFootprintName ) const
|
||||
{
|
||||
if( m_footprintFilters.GetCount() == 0 )
|
||||
return true;
|
||||
|
||||
// The matching is case insensitive
|
||||
wxString name = aFootprintName.Upper();
|
||||
|
||||
for( unsigned ii = 0; ii < m_footprintFilters.GetCount(); ii++ )
|
||||
{
|
||||
if( name.Matches( m_footprintFilters[ii].Upper() ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
void COMPONENT::Show( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( wxT( "<component>\n" ) );
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( wxString::Format( wxT( "<ref=%s value=%s name=%s library=%s fpid=%s "
|
||||
" timestamp=%s>\n" ),
|
||||
GetChars( m_reference ), GetChars( m_value ),
|
||||
GetChars( m_name ), GetChars( m_library ),
|
||||
m_fpid.Format().c_str(),
|
||||
GetChars( m_timeStamp ) ) );
|
||||
|
||||
if( !m_footprintFilters.IsEmpty() )
|
||||
{
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( wxT( "<fp_filters>\n" ) );
|
||||
|
||||
for( unsigned i = 0; i < m_footprintFilters.GetCount(); i++ )
|
||||
{
|
||||
NestedSpace( aNestLevel+2, aReporter );
|
||||
aReporter.Report( wxString::Format( wxT( "<%s>\n" ),
|
||||
GetChars( m_footprintFilters[i] ) ) );
|
||||
}
|
||||
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( wxT( "</fp_filters>\n" ) );
|
||||
}
|
||||
|
||||
if( !m_nets.empty() )
|
||||
{
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( wxT( "<nets>\n" ) );
|
||||
|
||||
for( unsigned i = 0; i < m_nets.size(); i++ )
|
||||
m_nets[i].Show( aNestLevel+3, aReporter );
|
||||
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( "</nets>\n" );
|
||||
}
|
||||
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( "</component>\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void NETLIST::AddComponent( COMPONENT* aComponent )
|
||||
{
|
||||
m_components.push_back( aComponent );
|
||||
}
|
||||
|
||||
|
||||
COMPONENT* NETLIST::GetComponentByReference( const wxString& aReference )
|
||||
{
|
||||
COMPONENT* component = NULL;
|
||||
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
if( m_components[i].GetReference() == aReference )
|
||||
{
|
||||
component = &m_components[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
|
||||
COMPONENT* NETLIST::GetComponentByTimeStamp( const wxString& aTimeStamp )
|
||||
{
|
||||
COMPONENT* component = NULL;
|
||||
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
if( m_components[i].GetTimeStamp() == aTimeStamp )
|
||||
{
|
||||
component = &m_components[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function ByFPID
|
||||
* is a helper function used to sort the component list used by loadNewModules.
|
||||
*/
|
||||
static bool ByFPID( const COMPONENT& ref, const COMPONENT& cmp )
|
||||
{
|
||||
return ref.GetFPID() > cmp.GetFPID();
|
||||
}
|
||||
|
||||
|
||||
void NETLIST::SortByFPID()
|
||||
{
|
||||
m_components.sort( ByFPID );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Operator <
|
||||
* compares two #COMPONENT objects by reference designator.
|
||||
*/
|
||||
bool operator < ( const COMPONENT& item1, const COMPONENT& item2 )
|
||||
{
|
||||
return StrNumCmp( item1.GetReference(), item2.GetReference(), INT_MAX, true ) < 0;
|
||||
}
|
||||
|
||||
|
||||
void NETLIST::SortByReference()
|
||||
{
|
||||
m_components.sort();
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST::AnyFootprintsLinked() const
|
||||
{
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
if( !m_components[i].GetFPID().empty() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST::AllFootprintsLinked() const
|
||||
{
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
if( m_components[i].GetFPID().empty() )
|
||||
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 )
|
||||
void NETLIST::Show( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( "<netlist>\n" );
|
||||
|
||||
if( !m_components.empty() )
|
||||
{
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( "<components>\n" );
|
||||
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
m_components[i].Show( aNestLevel+2, aReporter );
|
||||
}
|
||||
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
|
||||
aReporter.Report( "</components>\n" );
|
||||
}
|
||||
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( "</netlist>\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
NETLIST_READER::~NETLIST_READER()
|
||||
{
|
||||
if( m_lineReader )
|
||||
|
@ -308,7 +54,6 @@ NETLIST_READER::~NETLIST_READER()
|
|||
}
|
||||
|
||||
|
||||
|
||||
NETLIST_READER::NETLIST_FILE_T NETLIST_READER::GuessNetlistFileType( LINE_READER* aLineReader )
|
||||
{
|
||||
// Orcad Pcb2 netlist format starts by "( {", followed by an unknown comment,
|
||||
|
@ -447,14 +192,17 @@ bool CMP_READER::Load( NETLIST* aNetlist ) throw( IO_ERROR, PARSE_ERROR )
|
|||
// Find the corresponding item in component list:
|
||||
COMPONENT* component = aNetlist->GetComponentByReference( reference );
|
||||
|
||||
// the corresponding component could be no more existing in netlist:
|
||||
// this is the case when it is just removed from schematic,
|
||||
// and still exists in footprint assignment list, before this list is updated
|
||||
// This is an usual case during the life of a design
|
||||
// The corresponding component could no longer existing in the netlist. This
|
||||
// can happed when it is removed from schematic and still exists in footprint
|
||||
// assignment list. This is an usual case during the life of a design.
|
||||
if( component )
|
||||
{
|
||||
component->SetFPID( FPID( footprint ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false; // can be used to display a warning in Pcbnew.
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
|
|
@ -42,335 +42,8 @@
|
|||
using namespace NL_T;
|
||||
|
||||
|
||||
class MODULE;
|
||||
class LINE_READER;
|
||||
class REPORTER;
|
||||
|
||||
|
||||
/**
|
||||
* Class COMPONENT_NET
|
||||
* is used to store the component pin name to net name associations stored in a netlist.
|
||||
*/
|
||||
class COMPONENT_NET
|
||||
{
|
||||
wxString m_pinName;
|
||||
wxString m_netNumber;
|
||||
wxString m_netName;
|
||||
|
||||
public:
|
||||
COMPONENT_NET() {}
|
||||
|
||||
COMPONENT_NET( const wxString& aPinName, const wxString& aNetName )
|
||||
{
|
||||
m_pinName = aPinName;
|
||||
m_netName = aNetName;
|
||||
}
|
||||
|
||||
const wxString& GetPinName() const { return m_pinName; }
|
||||
|
||||
const wxString& GetNetName() const { return m_netName; }
|
||||
|
||||
bool IsValid() const { return !m_pinName.IsEmpty(); }
|
||||
|
||||
bool operator <( const COMPONENT_NET& aNet ) const
|
||||
{
|
||||
return m_pinName < aNet.m_pinName;
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
/**
|
||||
* Function Show
|
||||
* is used to output the object tree, currently for debugging only.
|
||||
* @param aNestLevel An aid to prettier tree indenting, and is the level
|
||||
* of nesting of this object within the overall tree.
|
||||
* @param aReporter A reference to a #REPORTER object to output to.
|
||||
*/
|
||||
virtual void Show( int aNestLevel, REPORTER& aReporter );
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector< COMPONENT_NET > COMPONENT_NETS;
|
||||
|
||||
|
||||
/**
|
||||
* Class COMPONENT
|
||||
* is used to store components and all of their related information found in a netlist.
|
||||
*/
|
||||
class COMPONENT
|
||||
{
|
||||
COMPONENT_NETS m_nets;
|
||||
wxArrayString m_footprintFilters; ///< Footprint filters found in netlist.
|
||||
wxString m_reference; ///< The component reference designator found in netlist.
|
||||
wxString m_value; ///< The component value found in netlist.
|
||||
|
||||
// ZZZ This timestamp is string, not time_t
|
||||
wxString m_timeStamp; ///< The component full time stamp found in netlist.
|
||||
|
||||
/// The name of the component in #m_library used when it was placed on the schematic..
|
||||
wxString m_name;
|
||||
|
||||
/**
|
||||
* The name of the component library where #m_name was found.
|
||||
*/
|
||||
wxString m_library;
|
||||
|
||||
/// The #FPID of the footprint assigned to the component.
|
||||
FPID m_fpid;
|
||||
|
||||
/// The #MODULE loaded for #m_footprintName found in #m_footprintLib.
|
||||
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;
|
||||
|
||||
public:
|
||||
COMPONENT( const FPID& aFPID,
|
||||
const wxString& aReference,
|
||||
const wxString& aValue,
|
||||
const wxString& aTimeStamp )
|
||||
{
|
||||
m_fpid = aFPID;
|
||||
m_reference = aReference;
|
||||
m_value = aValue;
|
||||
m_timeStamp = aTimeStamp;
|
||||
m_footprintChanged = false;
|
||||
}
|
||||
|
||||
virtual ~COMPONENT() { };
|
||||
|
||||
void AddNet( const wxString& aPinName, const wxString& aNetName )
|
||||
{
|
||||
m_nets.push_back( COMPONENT_NET( aPinName, aNetName ) );
|
||||
}
|
||||
|
||||
unsigned GetNetCount() const { return m_nets.size(); }
|
||||
|
||||
const COMPONENT_NET& GetNet( unsigned aIndex ) const { return m_nets[aIndex]; }
|
||||
|
||||
const COMPONENT_NET& GetNet( const wxString& aPinName );
|
||||
|
||||
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& GetValue() const { return m_value; }
|
||||
|
||||
void SetFPID( const FPID& aFPID )
|
||||
{
|
||||
m_footprintChanged = !m_fpid.empty() && (m_fpid != aFPID);
|
||||
m_fpid = aFPID;
|
||||
}
|
||||
|
||||
const FPID& GetFPID() const { return m_fpid; }
|
||||
|
||||
const wxString& GetTimeStamp() const { return m_timeStamp; }
|
||||
|
||||
void SetFootprintFilters( const wxArrayString& aFilterList )
|
||||
{
|
||||
m_footprintFilters = aFilterList;
|
||||
}
|
||||
|
||||
const wxArrayString& GetFootprintFilters() const { return m_footprintFilters; }
|
||||
|
||||
/**
|
||||
* Function MatchesFootprintFilters
|
||||
*
|
||||
* @return true if \a aFootprintName matches any of the footprint filters or no footprint
|
||||
* filters are defined.
|
||||
*/
|
||||
bool MatchesFootprintFilters( const wxString& aFootprintName ) const;
|
||||
|
||||
MODULE* GetModule( bool aRelease = false )
|
||||
{
|
||||
return ( aRelease ) ? m_footprint.release() : m_footprint.get();
|
||||
}
|
||||
|
||||
void SetModule( MODULE* aModule );
|
||||
|
||||
bool IsLibSource( const wxString& aLibrary, const wxString& aName ) const
|
||||
{
|
||||
return aLibrary == m_library && aName == m_name;
|
||||
}
|
||||
|
||||
bool FootprintChanged() const { return m_footprintChanged; }
|
||||
|
||||
#if defined(DEBUG)
|
||||
/**
|
||||
* Function Show
|
||||
* is used to output the object tree, currently for debugging only.
|
||||
* @param aNestLevel An aid to prettier tree indenting, and is the level
|
||||
* of nesting of this object within the overall tree.
|
||||
* @param aReporter A reference to a #REPORTER object to output to.
|
||||
*/
|
||||
virtual void Show( int aNestLevel, REPORTER& aReporter );
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
typedef boost::ptr_vector< COMPONENT > COMPONENTS;
|
||||
typedef COMPONENTS::iterator COMPONENTS_ITER;
|
||||
typedef COMPONENTS::const_iterator COMPONENTS_CITER;
|
||||
|
||||
|
||||
/**
|
||||
* Class NETLIST
|
||||
* stores all of information read from a netlist along with the flags used to update
|
||||
* the NETLIST in the #BOARD.
|
||||
*/
|
||||
class NETLIST
|
||||
{
|
||||
COMPONENTS m_components; ///< Components found in the netlist.
|
||||
|
||||
/// Remove footprints from #BOARD not found in netlist when true.
|
||||
bool m_deleteExtraFootprints;
|
||||
|
||||
/// Do not actually make any changes. Only report changes to #BOARD from netlist
|
||||
/// when true.
|
||||
bool m_isDryRun;
|
||||
|
||||
/// Find component by time stamp if true or reference designator if false.
|
||||
bool m_findByTimeStamp;
|
||||
|
||||
/// Replace component footprints when they differ from the netlist if true.
|
||||
bool m_replaceFootprints;
|
||||
|
||||
public:
|
||||
NETLIST() :
|
||||
m_deleteExtraFootprints( false ),
|
||||
m_isDryRun( false ),
|
||||
m_findByTimeStamp( false ),
|
||||
m_replaceFootprints( false )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Function IsEmpty()
|
||||
* @return true if there are no components in the netlist.
|
||||
*/
|
||||
bool IsEmpty() const { return m_components.empty(); }
|
||||
|
||||
/**
|
||||
* Function Clear
|
||||
* removes all components from the netlist.
|
||||
*/
|
||||
void Clear() { m_components.clear(); }
|
||||
|
||||
/**
|
||||
* Function GetCount
|
||||
* @return the number of components in the netlist.
|
||||
*/
|
||||
unsigned GetCount() const { return m_components.size(); }
|
||||
|
||||
/**
|
||||
* Function GetComponent
|
||||
* returns the #COMPONENT at \a aIndex.
|
||||
*
|
||||
* @param aIndex the index in #m_components to fetch.
|
||||
* @return a pointer to the #COMPONENT at \a Index.
|
||||
*/
|
||||
COMPONENT* GetComponent( unsigned aIndex ) { return &m_components[ aIndex ]; }
|
||||
|
||||
/**
|
||||
* Function AddComponent
|
||||
* adds \a aComponent to the NETLIST.
|
||||
*
|
||||
* @note If \a aComponent already exists in the NETLIST, \a aComponent is deleted
|
||||
* to prevent memory leaks. An assertion is raised in debug builds.
|
||||
*
|
||||
* @param aComponent is the COMPONENT to save to the NETLIST.
|
||||
*/
|
||||
void AddComponent( COMPONENT* aComponent );
|
||||
|
||||
/*
|
||||
* Function GetComponentByReference
|
||||
* returns a #COMPONENT by \a aReference.
|
||||
*
|
||||
* @param aReference is the reference designator the #COMPONENT.
|
||||
* @return a pointer to the #COMPONENT that matches \a aReference if found. Otherwise NULL.
|
||||
*/
|
||||
COMPONENT* GetComponentByReference( const wxString& aReference );
|
||||
|
||||
/*
|
||||
* Function GetComponentByTimeStamp
|
||||
* returns a #COMPONENT by \a aTimeStamp.
|
||||
*
|
||||
* @param aTimeStamp is the time stamp the #COMPONENT.
|
||||
* @return a pointer to the #COMPONENT that matches \a aTimeStamp if found. Otherwise NULL.
|
||||
*/
|
||||
COMPONENT* GetComponentByTimeStamp( const wxString& aTimeStamp );
|
||||
|
||||
void SortByFPID();
|
||||
|
||||
void SortByReference();
|
||||
|
||||
void SetDeleteExtraFootprints( bool aDeleteExtraFootprints )
|
||||
{
|
||||
m_deleteExtraFootprints = aDeleteExtraFootprints;
|
||||
}
|
||||
|
||||
bool GetDeleteExtraFootprints() const { return m_deleteExtraFootprints; }
|
||||
|
||||
void SetIsDryRun( bool aIsDryRun ) { m_isDryRun = aIsDryRun; }
|
||||
|
||||
bool IsDryRun() const { return m_isDryRun; }
|
||||
|
||||
void SetFindByTimeStamp( bool aFindByTimeStamp ) { m_findByTimeStamp = aFindByTimeStamp; }
|
||||
|
||||
bool IsFindByTimeStamp() const { return m_findByTimeStamp; }
|
||||
|
||||
void SetReplaceFootprints( bool aReplaceFootprints )
|
||||
{
|
||||
m_replaceFootprints = aReplaceFootprints;
|
||||
}
|
||||
|
||||
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)
|
||||
/**
|
||||
* Function Show
|
||||
* is used to output the object tree, currently for debugging only.
|
||||
* @param aNestLevel An aid to prettier tree indenting, and is the level
|
||||
* of nesting of this object within the overall tree.
|
||||
* @param aReporter A reference to a #REPORTER object to output to.
|
||||
*/
|
||||
virtual void Show( int aNestLevel, REPORTER& aReporter );
|
||||
#endif
|
||||
};
|
||||
class NETLIST;
|
||||
class COMPONENT;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,278 @@
|
|||
/**
|
||||
* @file pcb_netlist.cpp
|
||||
*/
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2011 Jean-Pierre Charras.
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>.
|
||||
* Copyright (C) 1992-2011 KiCad Developers, see change_log.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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <macros.h>
|
||||
#include <kicad_string.h>
|
||||
#include <reporter.h>
|
||||
|
||||
#include <pcb_netlist.h>
|
||||
#include <class_module.h>
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
/**
|
||||
* Function NestedSpace
|
||||
* outputs nested space for pretty indenting.
|
||||
* @param aNestLevel The nest count
|
||||
* @param aReporter A reference to a #REPORTER object where to output.
|
||||
* @return REPORTER& for continuation.
|
||||
**/
|
||||
static REPORTER& NestedSpace( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
for( int i = 0; i < aNestLevel; ++i )
|
||||
aReporter.Report( wxT( " " ) );
|
||||
|
||||
return aReporter;
|
||||
}
|
||||
|
||||
|
||||
void COMPONENT_NET::Show( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( wxString::Format( wxT( "<pin_name=%s net_name=%s>\n" ),
|
||||
GetChars( m_pinName ), GetChars( m_netName ) ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void COMPONENT::SetModule( MODULE* aModule )
|
||||
{
|
||||
m_footprint.reset( aModule );
|
||||
|
||||
if( aModule == NULL )
|
||||
return;
|
||||
|
||||
aModule->SetReference( m_reference );
|
||||
aModule->SetValue( m_value );
|
||||
aModule->SetFPID( m_fpid );
|
||||
aModule->SetPath( m_timeStamp );
|
||||
}
|
||||
|
||||
|
||||
COMPONENT_NET COMPONENT::m_emptyNet;
|
||||
|
||||
|
||||
const COMPONENT_NET& COMPONENT::GetNet( const wxString& aPinName )
|
||||
{
|
||||
for( unsigned i = 0; i < m_nets.size(); i++ )
|
||||
{
|
||||
if( m_nets[i].GetPinName() == aPinName )
|
||||
return m_nets[i];
|
||||
}
|
||||
|
||||
return m_emptyNet;
|
||||
}
|
||||
|
||||
|
||||
bool COMPONENT::MatchesFootprintFilters( const wxString& aFootprintName ) const
|
||||
{
|
||||
if( m_footprintFilters.GetCount() == 0 )
|
||||
return true;
|
||||
|
||||
// The matching is case insensitive
|
||||
wxString name = aFootprintName.Upper();
|
||||
|
||||
for( unsigned ii = 0; ii < m_footprintFilters.GetCount(); ii++ )
|
||||
{
|
||||
if( name.Matches( m_footprintFilters[ii].Upper() ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
void COMPONENT::Show( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( wxT( "<component>\n" ) );
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( wxString::Format( wxT( "<ref=%s value=%s name=%s library=%s fpid=%s "
|
||||
"timestamp=%s>\n" ),
|
||||
GetChars( m_reference ), GetChars( m_value ),
|
||||
GetChars( m_name ), GetChars( m_library ),
|
||||
m_fpid.Format().c_str(),
|
||||
GetChars( m_timeStamp ) ) );
|
||||
|
||||
if( !m_footprintFilters.IsEmpty() )
|
||||
{
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( wxT( "<fp_filters>\n" ) );
|
||||
|
||||
for( unsigned i = 0; i < m_footprintFilters.GetCount(); i++ )
|
||||
{
|
||||
NestedSpace( aNestLevel+2, aReporter );
|
||||
aReporter.Report( wxString::Format( wxT( "<%s>\n" ),
|
||||
GetChars( m_footprintFilters[i] ) ) );
|
||||
}
|
||||
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( wxT( "</fp_filters>\n" ) );
|
||||
}
|
||||
|
||||
if( !m_nets.empty() )
|
||||
{
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( wxT( "<nets>\n" ) );
|
||||
|
||||
for( unsigned i = 0; i < m_nets.size(); i++ )
|
||||
m_nets[i].Show( aNestLevel+3, aReporter );
|
||||
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( "</nets>\n" );
|
||||
}
|
||||
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( "</component>\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void NETLIST::AddComponent( COMPONENT* aComponent )
|
||||
{
|
||||
m_components.push_back( aComponent );
|
||||
}
|
||||
|
||||
|
||||
COMPONENT* NETLIST::GetComponentByReference( const wxString& aReference )
|
||||
{
|
||||
COMPONENT* component = NULL;
|
||||
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
if( m_components[i].GetReference() == aReference )
|
||||
{
|
||||
component = &m_components[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
|
||||
COMPONENT* NETLIST::GetComponentByTimeStamp( const wxString& aTimeStamp )
|
||||
{
|
||||
COMPONENT* component = NULL;
|
||||
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
if( m_components[i].GetTimeStamp() == aTimeStamp )
|
||||
{
|
||||
component = &m_components[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function ByFPID
|
||||
* is a helper function used to sort the component list used by loadNewModules.
|
||||
*/
|
||||
static bool ByFPID( const COMPONENT& ref, const COMPONENT& cmp )
|
||||
{
|
||||
return ref.GetFPID() > cmp.GetFPID();
|
||||
}
|
||||
|
||||
|
||||
void NETLIST::SortByFPID()
|
||||
{
|
||||
m_components.sort( ByFPID );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Operator <
|
||||
* compares two #COMPONENT objects by reference designator.
|
||||
*/
|
||||
bool operator < ( const COMPONENT& item1, const COMPONENT& item2 )
|
||||
{
|
||||
return StrNumCmp( item1.GetReference(), item2.GetReference(), INT_MAX, true ) < 0;
|
||||
}
|
||||
|
||||
|
||||
void NETLIST::SortByReference()
|
||||
{
|
||||
m_components.sort();
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST::AnyFootprintsLinked() const
|
||||
{
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
if( !m_components[i].GetFPID().empty() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST::AllFootprintsLinked() const
|
||||
{
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
if( m_components[i].GetFPID().empty() )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if defined( DEBUG )
|
||||
void NETLIST::Show( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( "<netlist>\n" );
|
||||
|
||||
if( !m_components.empty() )
|
||||
{
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( "<components>\n" );
|
||||
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
m_components[i].Show( aNestLevel+2, aReporter );
|
||||
}
|
||||
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
|
||||
aReporter.Report( "</components>\n" );
|
||||
}
|
||||
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( "</netlist>\n" );
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,367 @@
|
|||
#ifndef PCB_NETLIST_H
|
||||
#define PCB_NETLIST_H
|
||||
|
||||
/**
|
||||
* @file pcb_netlist.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Jean-Pierre Charras.
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>.
|
||||
* Copyright (C) 2012 KiCad Developers, see CHANGELOG.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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
#include <wx/arrstr.h>
|
||||
|
||||
#include <fpid.h>
|
||||
|
||||
|
||||
class MODULE;
|
||||
class REPORTER;
|
||||
|
||||
|
||||
/**
|
||||
* Class COMPONENT_NET
|
||||
* is used to store the component pin name to net name associations stored in a netlist.
|
||||
*/
|
||||
class COMPONENT_NET
|
||||
{
|
||||
wxString m_pinName;
|
||||
wxString m_netNumber;
|
||||
wxString m_netName;
|
||||
|
||||
public:
|
||||
COMPONENT_NET() {}
|
||||
|
||||
COMPONENT_NET( const wxString& aPinName, const wxString& aNetName )
|
||||
{
|
||||
m_pinName = aPinName;
|
||||
m_netName = aNetName;
|
||||
}
|
||||
|
||||
const wxString& GetPinName() const { return m_pinName; }
|
||||
|
||||
const wxString& GetNetName() const { return m_netName; }
|
||||
|
||||
bool IsValid() const { return !m_pinName.IsEmpty(); }
|
||||
|
||||
bool operator <( const COMPONENT_NET& aNet ) const
|
||||
{
|
||||
return m_pinName < aNet.m_pinName;
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
/**
|
||||
* Function Show
|
||||
* is used to output the object tree, currently for debugging only.
|
||||
* @param aNestLevel An aid to prettier tree indenting, and is the level
|
||||
* of nesting of this object within the overall tree.
|
||||
* @param aReporter A reference to a #REPORTER object to output to.
|
||||
*/
|
||||
virtual void Show( int aNestLevel, REPORTER& aReporter );
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector< COMPONENT_NET > COMPONENT_NETS;
|
||||
|
||||
|
||||
/**
|
||||
* Class COMPONENT
|
||||
* is used to store components and all of their related information found in a netlist.
|
||||
*/
|
||||
class COMPONENT
|
||||
{
|
||||
COMPONENT_NETS m_nets;
|
||||
wxArrayString m_footprintFilters; ///< Footprint filters found in netlist.
|
||||
wxString m_reference; ///< The component reference designator found in netlist.
|
||||
wxString m_value; ///< The component value found in netlist.
|
||||
|
||||
// ZZZ This timestamp is string, not time_t
|
||||
wxString m_timeStamp; ///< The component full time stamp found in netlist.
|
||||
|
||||
/// The name of the component in #m_library used when it was placed on the schematic..
|
||||
wxString m_name;
|
||||
|
||||
/// The name of the component library where #m_name was found.
|
||||
wxString m_library;
|
||||
|
||||
/// The #FPID of the footprint assigned to the component.
|
||||
FPID m_fpid;
|
||||
|
||||
/// The #MODULE loaded for #m_footprintName found in #m_footprintLib.
|
||||
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;
|
||||
|
||||
public:
|
||||
COMPONENT( const FPID& aFPID,
|
||||
const wxString& aReference,
|
||||
const wxString& aValue,
|
||||
const wxString& aTimeStamp )
|
||||
{
|
||||
m_fpid = aFPID;
|
||||
m_reference = aReference;
|
||||
m_value = aValue;
|
||||
m_timeStamp = aTimeStamp;
|
||||
m_footprintChanged = false;
|
||||
}
|
||||
|
||||
virtual ~COMPONENT() { };
|
||||
|
||||
void AddNet( const wxString& aPinName, const wxString& aNetName )
|
||||
{
|
||||
m_nets.push_back( COMPONENT_NET( aPinName, aNetName ) );
|
||||
}
|
||||
|
||||
unsigned GetNetCount() const { return m_nets.size(); }
|
||||
|
||||
const COMPONENT_NET& GetNet( unsigned aIndex ) const { return m_nets[aIndex]; }
|
||||
|
||||
const COMPONENT_NET& GetNet( const wxString& aPinName );
|
||||
|
||||
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& GetValue() const { return m_value; }
|
||||
|
||||
void SetFPID( const FPID& aFPID )
|
||||
{
|
||||
m_footprintChanged = !m_fpid.empty() && (m_fpid != aFPID);
|
||||
m_fpid = aFPID;
|
||||
}
|
||||
|
||||
const FPID& GetFPID() const { return m_fpid; }
|
||||
|
||||
const wxString& GetTimeStamp() const { return m_timeStamp; }
|
||||
|
||||
void SetFootprintFilters( const wxArrayString& aFilterList )
|
||||
{
|
||||
m_footprintFilters = aFilterList;
|
||||
}
|
||||
|
||||
const wxArrayString& GetFootprintFilters() const { return m_footprintFilters; }
|
||||
|
||||
/**
|
||||
* Function MatchesFootprintFilters
|
||||
*
|
||||
* @return true if \a aFootprintName matches any of the footprint filters or no footprint
|
||||
* filters are defined.
|
||||
*/
|
||||
bool MatchesFootprintFilters( const wxString& aFootprintName ) const;
|
||||
|
||||
MODULE* GetModule( bool aRelease = false )
|
||||
{
|
||||
return ( aRelease ) ? m_footprint.release() : m_footprint.get();
|
||||
}
|
||||
|
||||
void SetModule( MODULE* aModule );
|
||||
|
||||
bool IsLibSource( const wxString& aLibrary, const wxString& aName ) const
|
||||
{
|
||||
return aLibrary == m_library && aName == m_name;
|
||||
}
|
||||
|
||||
bool FootprintChanged() const { return m_footprintChanged; }
|
||||
|
||||
#if defined(DEBUG)
|
||||
/**
|
||||
* Function Show
|
||||
* is used to output the object tree, currently for debugging only.
|
||||
* @param aNestLevel An aid to prettier tree indenting, and is the level
|
||||
* of nesting of this object within the overall tree.
|
||||
* @param aReporter A reference to a #REPORTER object to output to.
|
||||
*/
|
||||
virtual void Show( int aNestLevel, REPORTER& aReporter );
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
typedef boost::ptr_vector< COMPONENT > COMPONENTS;
|
||||
typedef COMPONENTS::iterator COMPONENTS_ITER;
|
||||
typedef COMPONENTS::const_iterator COMPONENTS_CITER;
|
||||
|
||||
|
||||
/**
|
||||
* Class NETLIST
|
||||
* stores all of information read from a netlist along with the flags used to update
|
||||
* the NETLIST in the #BOARD.
|
||||
*/
|
||||
class NETLIST
|
||||
{
|
||||
COMPONENTS m_components; ///< Components found in the netlist.
|
||||
|
||||
/// Remove footprints from #BOARD not found in netlist when true.
|
||||
bool m_deleteExtraFootprints;
|
||||
|
||||
/// Do not actually make any changes. Only report changes to #BOARD from netlist
|
||||
/// when true.
|
||||
bool m_isDryRun;
|
||||
|
||||
/// Find component by time stamp if true or reference designator if false.
|
||||
bool m_findByTimeStamp;
|
||||
|
||||
/// Replace component footprints when they differ from the netlist if true.
|
||||
bool m_replaceFootprints;
|
||||
|
||||
public:
|
||||
NETLIST() :
|
||||
m_deleteExtraFootprints( false ),
|
||||
m_isDryRun( false ),
|
||||
m_findByTimeStamp( false ),
|
||||
m_replaceFootprints( false )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Function IsEmpty()
|
||||
* @return true if there are no components in the netlist.
|
||||
*/
|
||||
bool IsEmpty() const { return m_components.empty(); }
|
||||
|
||||
/**
|
||||
* Function Clear
|
||||
* removes all components from the netlist.
|
||||
*/
|
||||
void Clear() { m_components.clear(); }
|
||||
|
||||
/**
|
||||
* Function GetCount
|
||||
* @return the number of components in the netlist.
|
||||
*/
|
||||
unsigned GetCount() const { return m_components.size(); }
|
||||
|
||||
/**
|
||||
* Function GetComponent
|
||||
* returns the #COMPONENT at \a aIndex.
|
||||
*
|
||||
* @param aIndex the index in #m_components to fetch.
|
||||
* @return a pointer to the #COMPONENT at \a Index.
|
||||
*/
|
||||
COMPONENT* GetComponent( unsigned aIndex ) { return &m_components[ aIndex ]; }
|
||||
|
||||
/**
|
||||
* Function AddComponent
|
||||
* adds \a aComponent to the NETLIST.
|
||||
*
|
||||
* @note If \a aComponent already exists in the NETLIST, \a aComponent is deleted
|
||||
* to prevent memory leaks. An assertion is raised in debug builds.
|
||||
*
|
||||
* @param aComponent is the COMPONENT to save to the NETLIST.
|
||||
*/
|
||||
void AddComponent( COMPONENT* aComponent );
|
||||
|
||||
/*
|
||||
* Function GetComponentByReference
|
||||
* returns a #COMPONENT by \a aReference.
|
||||
*
|
||||
* @param aReference is the reference designator the #COMPONENT.
|
||||
* @return a pointer to the #COMPONENT that matches \a aReference if found. Otherwise NULL.
|
||||
*/
|
||||
COMPONENT* GetComponentByReference( const wxString& aReference );
|
||||
|
||||
/*
|
||||
* Function GetComponentByTimeStamp
|
||||
* returns a #COMPONENT by \a aTimeStamp.
|
||||
*
|
||||
* @param aTimeStamp is the time stamp the #COMPONENT.
|
||||
* @return a pointer to the #COMPONENT that matches \a aTimeStamp if found. Otherwise NULL.
|
||||
*/
|
||||
COMPONENT* GetComponentByTimeStamp( const wxString& aTimeStamp );
|
||||
|
||||
void SortByFPID();
|
||||
|
||||
void SortByReference();
|
||||
|
||||
void SetDeleteExtraFootprints( bool aDeleteExtraFootprints )
|
||||
{
|
||||
m_deleteExtraFootprints = aDeleteExtraFootprints;
|
||||
}
|
||||
|
||||
bool GetDeleteExtraFootprints() const { return m_deleteExtraFootprints; }
|
||||
|
||||
void SetIsDryRun( bool aIsDryRun ) { m_isDryRun = aIsDryRun; }
|
||||
|
||||
bool IsDryRun() const { return m_isDryRun; }
|
||||
|
||||
void SetFindByTimeStamp( bool aFindByTimeStamp ) { m_findByTimeStamp = aFindByTimeStamp; }
|
||||
|
||||
bool IsFindByTimeStamp() const { return m_findByTimeStamp; }
|
||||
|
||||
void SetReplaceFootprints( bool aReplaceFootprints )
|
||||
{
|
||||
m_replaceFootprints = aReplaceFootprints;
|
||||
}
|
||||
|
||||
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)
|
||||
/**
|
||||
* Function Show
|
||||
* is used to output the object tree, currently for debugging only.
|
||||
* @param aNestLevel An aid to prettier tree indenting, and is the level
|
||||
* of nesting of this object within the overall tree.
|
||||
* @param aReporter A reference to a #REPORTER object to output to.
|
||||
*/
|
||||
virtual void Show( int aNestLevel, REPORTER& aReporter );
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif // PCB_NETLIST_H
|
Loading…
Reference in New Issue