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/legacy_plugin.cpp
|
||||||
../pcbnew/kicad_plugin.cpp
|
../pcbnew/kicad_plugin.cpp
|
||||||
../pcbnew/gpcb_plugin.cpp
|
../pcbnew/gpcb_plugin.cpp
|
||||||
|
../pcbnew/pcb_netlist.cpp
|
||||||
pcb_plot_params_keywords.cpp
|
pcb_plot_params_keywords.cpp
|
||||||
pcb_keywords.cpp
|
pcb_keywords.cpp
|
||||||
../pcbnew/pcb_parser.cpp
|
../pcbnew/pcb_parser.cpp
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <footprint_info.h>
|
#include <footprint_info.h>
|
||||||
#include <io_mgr.h>
|
#include <io_mgr.h>
|
||||||
#include <fp_lib_table.h>
|
#include <fp_lib_table.h>
|
||||||
|
#include <fpid.h>
|
||||||
|
|
||||||
#include <class_module.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
|
bool FOOTPRINT_INFO::InLibrary( const wxString& aLibrary ) const
|
||||||
{
|
{
|
||||||
if( aLibrary.IsEmpty() )
|
if( aLibrary.IsEmpty() )
|
||||||
|
|
|
@ -31,10 +31,14 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include <appl_wxstruct.h>
|
#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_lexer.h>
|
||||||
#include <fp_lib_table.h>
|
#include <fp_lib_table.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace FP_LIB_TABLE_T;
|
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 )
|
bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace )
|
||||||
{
|
{
|
||||||
ensureIndex();
|
ensureIndex();
|
||||||
|
@ -281,8 +314,8 @@ const FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const wxString& aLibraryNickName
|
||||||
|
|
||||||
if( !row )
|
if( !row )
|
||||||
{
|
{
|
||||||
wxString msg = wxString::Format( _("lib table contains no logical lib '%s'" ),
|
wxString msg = wxString::Format( _( "lib table contains no logical lib '%s'" ),
|
||||||
GetChars( aLibraryNickName ) );
|
GetChars( aLibraryNickName ) );
|
||||||
THROW_IO_ERROR( msg );
|
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 FP_LIB_TABLE::LoadGlobalTable( FP_LIB_TABLE& aTable ) throw (IO_ERROR, PARSE_ERROR )
|
||||||
{
|
{
|
||||||
bool tableExists = true;
|
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.
|
* 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 );
|
m_textCtrl->AppendText( aText );
|
||||||
return *this;
|
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
|
./dialogs
|
||||||
../3d-viewer
|
../3d-viewer
|
||||||
../pcbnew
|
../pcbnew
|
||||||
|
../pcbnew/dialogs
|
||||||
../polygon
|
../polygon
|
||||||
../common
|
../common
|
||||||
${INC_AFTER}
|
${INC_AFTER}
|
||||||
|
@ -22,6 +23,8 @@ set( CVPCB_DIALOGS
|
||||||
dialogs/dialog_cvpcb_config_fbp.cpp
|
dialogs/dialog_cvpcb_config_fbp.cpp
|
||||||
dialogs/dialog_display_options.cpp
|
dialogs/dialog_display_options.cpp
|
||||||
dialogs/dialog_display_options_base.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
|
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 <fctsys.h>
|
||||||
#include <appl_wxstruct.h>
|
#include <appl_wxstruct.h>
|
||||||
|
@ -9,6 +33,8 @@
|
||||||
#include <gestfich.h>
|
#include <gestfich.h>
|
||||||
#include <param_config.h>
|
#include <param_config.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
#include <fp_lib_table.h>
|
||||||
|
#include <confirm.h>
|
||||||
|
|
||||||
#include <cvpcb.h>
|
#include <cvpcb.h>
|
||||||
#include <cvpcb_mainframe.h>
|
#include <cvpcb_mainframe.h>
|
||||||
|
@ -59,8 +85,24 @@ void CVPCB_MAINFRAME::LoadProjectFile( const wxString& aFileName )
|
||||||
if( m_NetlistFileExtension.IsEmpty() )
|
if( m_NetlistFileExtension.IsEmpty() )
|
||||||
m_NetlistFileExtension = wxT( "net" );
|
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 );
|
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 <bitmaps.h>
|
||||||
#include <msgpanel.h>
|
#include <msgpanel.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
#include <fpid.h>
|
||||||
|
#include <fp_lib_table.h>
|
||||||
|
#include <pcbcommon.h>
|
||||||
|
|
||||||
#include <io_mgr.h>
|
#include <io_mgr.h>
|
||||||
#include <class_module.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 )
|
MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
|
||||||
{
|
{
|
||||||
CVPCB_MAINFRAME* parent = ( CVPCB_MAINFRAME* ) GetParent();
|
MODULE* footprint;
|
||||||
|
|
||||||
try
|
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 ) );
|
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
|
||||||
|
|
||||||
for( unsigned i = 0; i < parent->m_ModuleLibNames.GetCount(); ++i )
|
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() );
|
fn.GetFullName().GetData() );
|
||||||
|
|
||||||
// @todo we should not be using wxMessageBox directly.
|
// @todo we should not be using wxMessageBox directly.
|
||||||
wxMessageBox( msg, titleLibLoadError, wxOK | wxICON_ERROR, this );
|
wxMessageBox( msg, wxEmptyString, wxOK | wxICON_ERROR, this );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE* footprint = pi->FootprintLoad( libPath, aFootprintName );
|
footprint = pi->FootprintLoad( libPath, aFootprintName );
|
||||||
|
|
||||||
if( footprint )
|
|
||||||
{
|
|
||||||
footprint->SetParent( (EDA_ITEM*) GetBoard() );
|
|
||||||
footprint->SetPosition( wxPoint( 0, 0 ) );
|
|
||||||
return footprint;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch( IO_ERROR ioe )
|
catch( IO_ERROR ioe )
|
||||||
{
|
{
|
||||||
|
@ -513,6 +559,13 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
|
||||||
return NULL;
|
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() );
|
wxString msg = wxString::Format( _( "Footprint '%s' not found" ), aFootprintName.GetData() );
|
||||||
DisplayError( this, msg );
|
DisplayError( this, msg );
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -532,6 +585,7 @@ void DISPLAY_FOOTPRINTS_FRAME::InitDisplay()
|
||||||
FOOTPRINT_INFO* module_info = parentframe->m_footprints.GetModuleInfo( footprintName );
|
FOOTPRINT_INFO* module_info = parentframe->m_footprints.GetModuleInfo( footprintName );
|
||||||
|
|
||||||
const wxChar *libname;
|
const wxChar *libname;
|
||||||
|
|
||||||
if( module_info )
|
if( module_info )
|
||||||
libname = GetChars( module_info->GetLibraryPath() );
|
libname = GetChars( module_info->GetLibraryPath() );
|
||||||
else
|
else
|
||||||
|
|
|
@ -135,8 +135,14 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
|
||||||
{
|
{
|
||||||
if( aFilterType == UNFILTERED )
|
if( aFilterType == UNFILTERED )
|
||||||
{
|
{
|
||||||
|
#if !defined( USE_FP_LIB_TABLE )
|
||||||
msg.Printf( wxT( "%3zu %s" ), newList.GetCount() + 1,
|
msg.Printf( wxT( "%3zu %s" ), newList.GetCount() + 1,
|
||||||
GetChars( aList.GetItem( ii ).m_Module ) );
|
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 );
|
newList.Add( msg );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -153,8 +159,14 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
|
||||||
&& (aComponent->GetNetCount() != aList.GetItem( ii ).m_padCount) )
|
&& (aComponent->GetNetCount() != aList.GetItem( ii ).m_padCount) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
#if !defined( USE_FP_LIB_TABLE )
|
||||||
msg.Printf( wxT( "%3zu %s" ), newList.GetCount() + 1,
|
msg.Printf( wxT( "%3zu %s" ), newList.GetCount() + 1,
|
||||||
aList.GetItem( ii ).m_Module.GetData() );
|
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 );
|
newList.Add( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,9 +181,24 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
|
||||||
selection = 0;
|
selection = 0;
|
||||||
|
|
||||||
DeleteAllItems();
|
DeleteAllItems();
|
||||||
SetItemCount( m_footprintList.GetCount() );
|
|
||||||
SetSelection( selection, true );
|
if( m_footprintList.GetCount() )
|
||||||
Refresh();
|
{
|
||||||
|
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() )
|
if( GetCount() == 0 || oldSelection < 0 || oldSelection >= GetCount() )
|
||||||
SetSelection( 0, true );
|
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 <fctsys.h>
|
||||||
|
#include <build_version.h>
|
||||||
#include <appl_wxstruct.h>
|
#include <appl_wxstruct.h>
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <eda_doc.h>
|
#include <eda_doc.h>
|
||||||
#include <eda_dde.h>
|
#include <eda_dde.h>
|
||||||
#include <gestfich.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_mainframe.h>
|
||||||
|
#include <cvpcb.h>
|
||||||
#include <cvstruct.h>
|
#include <cvstruct.h>
|
||||||
#include <dialog_cvpcb_config.h>
|
#include <dialog_cvpcb_config.h>
|
||||||
#include <class_DisplayFootprintsFrame.h>
|
#include <class_DisplayFootprintsFrame.h>
|
||||||
#include <cvpcb_id.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_X 450
|
||||||
#define FRAME_MIN_SIZE_Y 300
|
#define FRAME_MIN_SIZE_Y 300
|
||||||
|
@ -54,6 +57,16 @@ static const wxString KeepCvpcbOpenEntry( wxT( "KeepCvpcbOpen" ) );
|
||||||
static const wxString FootprintDocFileEntry( wxT( "footprints_doc_file" ) );
|
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 )
|
BEGIN_EVENT_TABLE( CVPCB_MAINFRAME, EDA_BASE_FRAME )
|
||||||
EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, CVPCB_MAINFRAME::LoadNetList )
|
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_SAVE_PROJECT_AS, CVPCB_MAINFRAME::SaveProjectFile )
|
||||||
EVT_MENU( ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE, CVPCB_MAINFRAME::OnKeepOpenOnSave )
|
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 )
|
EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, CVPCB_MAINFRAME::SetLanguage )
|
||||||
|
|
||||||
// Toolbar events
|
// Toolbar events
|
||||||
|
@ -114,6 +131,11 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( const wxString& title, long style ) :
|
||||||
m_undefinedComponentCnt = 0;
|
m_undefinedComponentCnt = 0;
|
||||||
m_skipComponentSelect = false;
|
m_skipComponentSelect = false;
|
||||||
|
|
||||||
|
#if defined( USE_FP_LIB_TABLE )
|
||||||
|
m_globalFootprintTable = NULL;
|
||||||
|
m_footprintLibTable = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Name of the document footprint list
|
/* Name of the document footprint list
|
||||||
* usually located in share/modules/footprints_doc
|
* usually located in share/modules/footprints_doc
|
||||||
* this is of the responsibility to users to create this file
|
* 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 ) );
|
Right().BestSize( (int) ( m_FrameSize.x * 0.30 ), m_FrameSize.y ) );
|
||||||
|
|
||||||
m_auimgr.Update();
|
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 )
|
void CVPCB_MAINFRAME::OnKeepOpenOnSave( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
m_KeepCvpcbOpen = event.IsChecked();
|
m_KeepCvpcbOpen = event.IsChecked();
|
||||||
|
@ -523,7 +602,7 @@ void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
|
||||||
// selected footprint.
|
// selected footprint.
|
||||||
if( FindFocus() == m_ListCmp || FindFocus() == m_LibraryList )
|
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;
|
bool found = false;
|
||||||
|
|
||||||
|
@ -667,7 +746,12 @@ bool CVPCB_MAINFRAME::LoadFootprintFiles()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined( USE_FP_LIB_TABLE )
|
||||||
m_footprints.ReadFootprintFiles( m_ModuleLibNames );
|
m_footprints.ReadFootprintFiles( m_ModuleLibNames );
|
||||||
|
#else
|
||||||
|
if( m_footprintLibTable != NULL )
|
||||||
|
m_footprints.ReadFootprintFiles( *m_footprintLibTable );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Display error messages, if any.
|
// Display error messages, if any.
|
||||||
if( !m_footprints.m_filesNotFound.IsEmpty() || !m_footprints.m_filesInvalid.IsEmpty() )
|
if( !m_footprints.m_filesNotFound.IsEmpty() || !m_footprints.m_filesInvalid.IsEmpty() )
|
||||||
|
@ -770,7 +854,7 @@ int CVPCB_MAINFRAME::ReadSchematicNetlist()
|
||||||
netlistReader->LoadNetlist();
|
netlistReader->LoadNetlist();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wxMessageBox( _( "Unknown netlist format" ), wxEmptyString, wxOK | wxICON_ERROR );
|
wxMessageBox( _( "Unknown netlist format." ), wxEmptyString, wxOK | wxICON_ERROR );
|
||||||
}
|
}
|
||||||
catch( IO_ERROR& ioe )
|
catch( IO_ERROR& ioe )
|
||||||
{
|
{
|
||||||
|
@ -852,6 +936,11 @@ void CVPCB_MAINFRAME::CreateScreenCmp()
|
||||||
wxPoint( 0, 0 ),
|
wxPoint( 0, 0 ),
|
||||||
wxSize( 600, 400 ),
|
wxSize( 600, 400 ),
|
||||||
KICAD_DEFAULT_DRAWFRAME_STYLE );
|
KICAD_DEFAULT_DRAWFRAME_STYLE );
|
||||||
|
|
||||||
|
#if defined( USE_FP_LIB_TABLE )
|
||||||
|
m_DisplayFootprintFrame->SetFootprintLibTable( m_footprintLibTable );
|
||||||
|
#endif
|
||||||
|
|
||||||
m_DisplayFootprintFrame->Show( true );
|
m_DisplayFootprintFrame->Show( true );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -913,8 +1002,23 @@ void CVPCB_MAINFRAME::BuildCmpListBox()
|
||||||
m_ListCmp->m_ComponentList.Add( msg );
|
m_ListCmp->m_ComponentList.Add( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ListCmp->SetItemCount( m_ListCmp->m_ComponentList.Count() );
|
if( m_ListCmp->m_ComponentList.Count() )
|
||||||
m_ListCmp->SetSelection( 0, true );
|
{
|
||||||
|
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 ) );
|
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 );
|
m_LibraryList->SetLibraryList( m_ModuleLibNames );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,21 +5,16 @@
|
||||||
#ifndef __CVPCB_H__
|
#ifndef __CVPCB_H__
|
||||||
#define __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
|
// config for footprints doc file access
|
||||||
#define DEFAULT_FOOTPRINTS_LIST_FILENAME wxT( "footprints_doc/footprints.pdf" )
|
#define DEFAULT_FOOTPRINTS_LIST_FILENAME wxT( "footprints_doc/footprints.pdf" )
|
||||||
|
|
||||||
// Define print format to display a schematic component line
|
// 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 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 FootprintAliasFileExtension;
|
||||||
extern const wxString RetroFileExtension;
|
extern const wxString RetroFileExtension;
|
||||||
|
|
|
@ -32,5 +32,6 @@ enum id_cvpcb_frm
|
||||||
ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
|
ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
|
||||||
ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
|
ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
|
||||||
ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE,
|
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/listctrl.h>
|
||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
#include <netlist_reader.h>
|
#include <pcb_netlist.h>
|
||||||
#include <footprint_info.h>
|
#include <footprint_info.h>
|
||||||
|
|
||||||
#include <wxBasePcbFrame.h>
|
#include <wxBasePcbFrame.h>
|
||||||
#include <param_config.h>
|
#include <param_config.h>
|
||||||
#include <cvpcb.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* Forward declarations of all top-level window classes. */
|
/* Forward declarations of all top-level window classes. */
|
||||||
|
@ -46,6 +45,7 @@ class COMPONENTS_LISTBOX;
|
||||||
class LIBRARY_LISTBOX;
|
class LIBRARY_LISTBOX;
|
||||||
class DISPLAY_FOOTPRINTS_FRAME;
|
class DISPLAY_FOOTPRINTS_FRAME;
|
||||||
class COMPONENT;
|
class COMPONENT;
|
||||||
|
class FP_LIB_TABLE;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,6 +55,16 @@ class CVPCB_MAINFRAME : public EDA_BASE_FRAME
|
||||||
{
|
{
|
||||||
wxArrayString m_footprintListEntries;
|
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:
|
public:
|
||||||
bool m_KeepCvpcbOpen;
|
bool m_KeepCvpcbOpen;
|
||||||
FOOTPRINTS_LISTBOX* m_FootprintList;
|
FOOTPRINTS_LISTBOX* m_FootprintList;
|
||||||
|
@ -92,6 +102,13 @@ public:
|
||||||
*/
|
*/
|
||||||
void OnSelectComponent( wxListEvent& event );
|
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 OnQuit( wxCommandEvent& event );
|
||||||
void OnCloseWindow( wxCloseEvent& Event );
|
void OnCloseWindow( wxCloseEvent& Event );
|
||||||
void OnSize( wxSizeEvent& SizeEvent );
|
void OnSize( wxSizeEvent& SizeEvent );
|
||||||
|
@ -126,6 +143,15 @@ public:
|
||||||
void LoadNetList( wxCommandEvent& event );
|
void LoadNetList( wxCommandEvent& event );
|
||||||
|
|
||||||
void ConfigCvpcb( 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 OnKeepOpenOnSave( wxCommandEvent& event );
|
||||||
void DisplayModule( wxCommandEvent& event );
|
void DisplayModule( wxCommandEvent& event );
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
#include <wx/listctrl.h>
|
#include <wx/listctrl.h>
|
||||||
|
|
||||||
#include <cvpcb.h>
|
|
||||||
|
|
||||||
/* Forward declarations of all top-level window classes. */
|
/* Forward declarations of all top-level window classes. */
|
||||||
class CVPCB_MAINFRAME;
|
class CVPCB_MAINFRAME;
|
||||||
|
|
|
@ -110,11 +110,17 @@ void CVPCB_MAINFRAME::ReCreateMenuBar()
|
||||||
// Menu Preferences:
|
// Menu Preferences:
|
||||||
wxMenu* preferencesMenu = new wxMenu;
|
wxMenu* preferencesMenu = new wxMenu;
|
||||||
|
|
||||||
|
#if !defined( USE_FP_LIB_TABLE )
|
||||||
// Libraries to load
|
// Libraries to load
|
||||||
AddMenuItem( preferencesMenu, wxID_PREFERENCES,
|
AddMenuItem( preferencesMenu, wxID_PREFERENCES,
|
||||||
_( "&Libraries" ),
|
_( "&Libraries" ),
|
||||||
_( "Set footprint libraries to load and library search paths" ),
|
_( "Set footprint libraries to load and library search paths" ),
|
||||||
KiBitmap( config_xpm ) );
|
KiBitmap( config_xpm ) );
|
||||||
|
#else
|
||||||
|
AddMenuItem( preferencesMenu, ID_CVPCB_LIB_TABLE_EDIT,
|
||||||
|
_( "Li&brary Tables" ), _( "Setup footprint libraries" ),
|
||||||
|
KiBitmap( library_table_xpm ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Language submenu
|
// Language submenu
|
||||||
wxGetApp().AddMenuLanguageList( preferencesMenu );
|
wxGetApp().AddMenuLanguageList( preferencesMenu );
|
||||||
|
|
|
@ -31,6 +31,11 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <build_version.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.h>
|
||||||
#include <cvpcb_mainframe.h>
|
#include <cvpcb_mainframe.h>
|
||||||
|
@ -50,7 +55,6 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If no component is selected, select the first one
|
// If no component is selected, select the first one
|
||||||
|
|
||||||
if( m_ListCmp->GetFirstSelected() < 0 )
|
if( m_ListCmp->GetFirstSelected() < 0 )
|
||||||
{
|
{
|
||||||
componentIndex = 0;
|
componentIndex = 0;
|
||||||
|
@ -58,11 +62,9 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate over the selection
|
// iterate over the selection
|
||||||
|
while( m_ListCmp->GetFirstSelected() != -1 )
|
||||||
while( m_ListCmp->GetFirstSelected() != -1)
|
|
||||||
{
|
{
|
||||||
// Get the component for the current iteration
|
// Get the component for the current iteration
|
||||||
|
|
||||||
componentIndex = m_ListCmp->GetFirstSelected();
|
componentIndex = m_ListCmp->GetFirstSelected();
|
||||||
component = m_netlist.GetComponent( componentIndex );
|
component = m_netlist.GetComponent( componentIndex );
|
||||||
|
|
||||||
|
@ -70,13 +72,21 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check to see if the component has already a footprint set.
|
// Check to see if the component has already a footprint set.
|
||||||
|
|
||||||
hasFootprint = !component->GetFPID().empty();
|
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 ) );
|
component->SetFPID( FPID( aFootprintName ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
// 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() ),
|
||||||
|
@ -85,7 +95,6 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
||||||
// 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
|
||||||
// a footprint assigned.
|
// a footprint assigned.
|
||||||
|
|
||||||
if( !hasFootprint )
|
if( !hasFootprint )
|
||||||
{
|
{
|
||||||
hasFootprint = true;
|
hasFootprint = true;
|
||||||
|
@ -115,6 +124,7 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
|
||||||
{
|
{
|
||||||
COMPONENT* component;
|
COMPONENT* component;
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
bool isLegacy = true;
|
||||||
|
|
||||||
ReadSchematicNetlist();
|
ReadSchematicNetlist();
|
||||||
|
|
||||||
|
@ -129,6 +139,87 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
|
||||||
m_ListCmp->Clear();
|
m_ListCmp->Clear();
|
||||||
m_undefinedComponentCnt = 0;
|
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++ )
|
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||||
{
|
{
|
||||||
component = m_netlist.GetComponent( i );
|
component = m_netlist.GetComponent( i );
|
||||||
|
@ -137,10 +228,14 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
|
||||||
GetChars( component->GetReference() ),
|
GetChars( component->GetReference() ),
|
||||||
GetChars( component->GetValue() ),
|
GetChars( component->GetValue() ),
|
||||||
GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
|
GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
|
||||||
|
|
||||||
m_ListCmp->AppendLine( msg );
|
m_ListCmp->AppendLine( msg );
|
||||||
|
|
||||||
if( component->GetFPID().empty() )
|
if( component->GetFPID().empty() )
|
||||||
|
{
|
||||||
m_undefinedComponentCnt += 1;
|
m_undefinedComponentCnt += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !m_netlist.IsEmpty() )
|
if( !m_netlist.IsEmpty() )
|
||||||
|
|
|
@ -102,15 +102,7 @@ public:
|
||||||
* @return the item stored in list if found
|
* @return the item stored in list if found
|
||||||
* @param aFootprintName = the name of item
|
* @param aFootprintName = the name of item
|
||||||
*/
|
*/
|
||||||
FOOTPRINT_INFO * GetModuleInfo( const wxString & aFootprintName )
|
FOOTPRINT_INFO* GetModuleInfo( const wxString & aFootprintName );
|
||||||
{
|
|
||||||
BOOST_FOREACH( FOOTPRINT_INFO& footprint, m_List )
|
|
||||||
{
|
|
||||||
if( aFootprintName.CmpNoCase( footprint.m_Module ) == 0 )
|
|
||||||
return &footprint;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetItem
|
* Function GetItem
|
||||||
|
@ -159,6 +151,13 @@ public:
|
||||||
/// FOOTPRINT object list sort function.
|
/// FOOTPRINT object list sort function.
|
||||||
inline bool operator<( const FOOTPRINT_INFO& item1, const FOOTPRINT_INFO& item2 )
|
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;
|
return StrNumCmp( item1.m_Module, item2.m_Module, INT_MAX, true ) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,13 +31,16 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
//#include <fpid.h>
|
|
||||||
#include <io_mgr.h>
|
#include <io_mgr.h>
|
||||||
|
|
||||||
|
|
||||||
|
class wxFileName;
|
||||||
class OUTPUTFORMATTER;
|
class OUTPUTFORMATTER;
|
||||||
class MODULE;
|
class MODULE;
|
||||||
class FP_LIB_TABLE_LEXER;
|
class FP_LIB_TABLE_LEXER;
|
||||||
|
class NETLIST;
|
||||||
|
class REPORTER;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class FP_LIB_TABLE
|
* Class FP_LIB_TABLE
|
||||||
|
@ -355,12 +358,50 @@ public:
|
||||||
*/
|
*/
|
||||||
const ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );
|
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
|
* Function IsEmpty
|
||||||
* @return true if the footprint library table is empty.
|
* @return true if the footprint library table is empty.
|
||||||
*/
|
*/
|
||||||
bool IsEmpty() const;
|
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
|
* Function ExpandEnvSubsitutions
|
||||||
* replaces any environment variable references with their values and is
|
* replaces any environment variable references with their values and is
|
||||||
|
|
|
@ -136,4 +136,23 @@ public:
|
||||||
REPORTER& Report( const wxString& aText );
|
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_
|
#endif // _REPORTER_H_
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include <pcbcommon.h>
|
#include <pcbcommon.h>
|
||||||
#include <wxBasePcbFrame.h>
|
#include <wxBasePcbFrame.h>
|
||||||
#include <msgpanel.h>
|
#include <msgpanel.h>
|
||||||
#include <netlist_reader.h>
|
#include <pcb_netlist.h>
|
||||||
#include <reporter.h>
|
#include <reporter.h>
|
||||||
#include <base_units.h>
|
#include <base_units.h>
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,13 @@
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <appl_wxstruct.h>
|
#include <appl_wxstruct.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
|
#include <macros.h>
|
||||||
#include <dialog_helpers.h>
|
#include <dialog_helpers.h>
|
||||||
#include <html_messagebox.h>
|
#include <html_messagebox.h>
|
||||||
#include <base_units.h>
|
#include <base_units.h>
|
||||||
#include <wxPcbStruct.h>
|
#include <wxPcbStruct.h>
|
||||||
#include <pcbcommon.h>
|
#include <pcbcommon.h>
|
||||||
|
#include <pcb_netlist.h>
|
||||||
#include <netlist_reader.h>
|
#include <netlist_reader.h>
|
||||||
#include <reporter.h>
|
#include <reporter.h>
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
#include <netlist_lexer.h> // netlist_lexer is common to Eeschema and Pcbnew
|
#include <netlist_lexer.h> // netlist_lexer is common to Eeschema and Pcbnew
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
|
|
||||||
|
#include <pcb_netlist.h>
|
||||||
#include <netlist_reader.h>
|
#include <netlist_reader.h>
|
||||||
|
|
||||||
using namespace NL_T;
|
using namespace NL_T;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <richio.h>
|
#include <richio.h>
|
||||||
#include <kicad_string.h>
|
#include <kicad_string.h>
|
||||||
|
|
||||||
|
#include <pcb_netlist.h>
|
||||||
#include <netlist_reader.h>
|
#include <netlist_reader.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <dialog_helpers.h>
|
#include <dialog_helpers.h>
|
||||||
#include <wxPcbStruct.h>
|
#include <wxPcbStruct.h>
|
||||||
|
#include <pcb_netlist.h>
|
||||||
#include <netlist_reader.h>
|
#include <netlist_reader.h>
|
||||||
#include <reporter.h>
|
#include <reporter.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
|
|
@ -31,267 +31,13 @@
|
||||||
#include <kicad_string.h>
|
#include <kicad_string.h>
|
||||||
#include <reporter.h>
|
#include <reporter.h>
|
||||||
|
|
||||||
|
#include <pcb_netlist.h>
|
||||||
#include <netlist_reader.h>
|
#include <netlist_reader.h>
|
||||||
#include <class_module.h>
|
#include <class_module.h>
|
||||||
|
|
||||||
#include <wx/regex.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()
|
NETLIST_READER::~NETLIST_READER()
|
||||||
{
|
{
|
||||||
if( m_lineReader )
|
if( m_lineReader )
|
||||||
|
@ -308,7 +54,6 @@ NETLIST_READER::~NETLIST_READER()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NETLIST_READER::NETLIST_FILE_T NETLIST_READER::GuessNetlistFileType( LINE_READER* aLineReader )
|
NETLIST_READER::NETLIST_FILE_T NETLIST_READER::GuessNetlistFileType( LINE_READER* aLineReader )
|
||||||
{
|
{
|
||||||
// Orcad Pcb2 netlist format starts by "( {", followed by an unknown comment,
|
// 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:
|
// Find the corresponding item in component list:
|
||||||
COMPONENT* component = aNetlist->GetComponentByReference( reference );
|
COMPONENT* component = aNetlist->GetComponentByReference( reference );
|
||||||
|
|
||||||
// the corresponding component could be no more existing in netlist:
|
// The corresponding component could no longer existing in the netlist. This
|
||||||
// this is the case when it is just removed from schematic,
|
// can happed when it is removed from schematic and still exists in footprint
|
||||||
// and still exists in footprint assignment list, before this list is updated
|
// assignment list. This is an usual case during the life of a design.
|
||||||
// This is an usual case during the life of a design
|
|
||||||
if( component )
|
if( component )
|
||||||
|
{
|
||||||
component->SetFPID( FPID( footprint ) );
|
component->SetFPID( FPID( footprint ) );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
ok = false; // can be used to display a warning in Pcbnew.
|
ok = false; // can be used to display a warning in Pcbnew.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
|
|
|
@ -42,335 +42,8 @@
|
||||||
using namespace NL_T;
|
using namespace NL_T;
|
||||||
|
|
||||||
|
|
||||||
class MODULE;
|
class NETLIST;
|
||||||
class LINE_READER;
|
class COMPONENT;
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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