2011-09-30 18:15:37 +00:00
|
|
|
/**
|
|
|
|
* @file pcbnew/netlist.cpp
|
|
|
|
*/
|
2012-01-26 09:37:36 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1992-2011 Jean-Pierre Charras.
|
|
|
|
* 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
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
/*
|
2012-01-26 09:37:36 +00:00
|
|
|
* Functions to read a netlist:
|
2011-09-16 14:13:02 +00:00
|
|
|
* - Load new footprints and initialize net info
|
2009-04-24 07:36:36 +00:00
|
|
|
* - Test for missing or extra footprints
|
2011-05-03 12:57:44 +00:00
|
|
|
* - Recalculate full connectivity info
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2009-04-24 07:36:36 +00:00
|
|
|
* Important remark:
|
2012-01-26 09:37:36 +00:00
|
|
|
* When reading a netlist, Pcbnew must identify existing footprints (link
|
2009-11-18 12:52:19 +00:00
|
|
|
* between existing footprints an components in netlist)
|
2012-01-26 09:37:36 +00:00
|
|
|
* This identification can be made from 2 fields:
|
2009-04-24 07:36:36 +00:00
|
|
|
* - The reference (U2, R5 ..): this is the normal mode
|
2012-01-26 09:37:36 +00:00
|
|
|
* - The Time Stamp : useful after a full schematic
|
|
|
|
* reannotation because references can be changed for the component linked to its footprint.
|
|
|
|
* So when reading a netlist, ReadPcbNetlist() can use references or time stamps
|
2011-05-03 12:57:44 +00:00
|
|
|
* to identify footprints on board and the corresponding component in schematic.
|
2009-04-24 07:36:36 +00:00
|
|
|
* If we want to fully reannotate a schematic this sequence must be used
|
2011-05-03 12:57:44 +00:00
|
|
|
* 1 - SAVE your board !!!
|
|
|
|
* 2 - Create and read the netlist (to ensure all info is correct, mainly
|
2009-11-18 12:52:19 +00:00
|
|
|
* references and time stamp)
|
2011-05-03 12:57:44 +00:00
|
|
|
* 3 - Reannotate the schematic (references will be changed, but not time stamps )
|
|
|
|
* 4 - Recreate and read the new netlist using the Time Stamp identification
|
2009-11-18 12:52:19 +00:00
|
|
|
* (that reinit the new references)
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2011-04-02 16:14:07 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <algorithm>
|
2011-04-02 16:14:07 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <fctsys.h>
|
|
|
|
#include <class_drawpanel.h>
|
|
|
|
#include <confirm.h>
|
|
|
|
#include <kicad_string.h>
|
|
|
|
#include <gestfich.h>
|
|
|
|
#include <wxPcbStruct.h>
|
|
|
|
#include <richio.h>
|
|
|
|
#include <dialog_helpers.h>
|
|
|
|
#include <macros.h>
|
2011-09-23 13:57:12 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <class_board.h>
|
|
|
|
#include <class_module.h>
|
|
|
|
#include <pcbnew.h>
|
|
|
|
#include <dialog_netlist.h>
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
#include <netlist_reader.h>
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2010-11-12 16:36:43 +00:00
|
|
|
/**
|
|
|
|
* Function OpenNetlistFile
|
2009-04-24 07:36:36 +00:00
|
|
|
* used to open a netlist file
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2011-05-03 12:57:44 +00:00
|
|
|
static FILE* OpenNetlistFile( const wxString& aFullFileName )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
if( aFullFileName.IsEmpty() )
|
2012-01-26 09:37:36 +00:00
|
|
|
return NULL; // No filename: exit
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
FILE* file = wxFopen( aFullFileName, wxT( "rt" ) );
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
if( file == NULL )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
wxString msg;
|
2010-04-23 14:46:00 +00:00
|
|
|
msg.Printf( _( "Netlist file %s not found" ), GetChars( aFullFileName ) );
|
2011-05-03 12:57:44 +00:00
|
|
|
wxMessageBox( msg );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
return file;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
|
2010-11-12 16:36:43 +00:00
|
|
|
/**
|
|
|
|
* Function ReadPcbNetlist
|
2009-11-18 12:52:19 +00:00
|
|
|
* Update footprints (load missing footprints and delete on request extra
|
|
|
|
* footprints)
|
2009-04-24 07:36:36 +00:00
|
|
|
* Update connectivity info ( Net Name list )
|
|
|
|
* Update Reference, value and "TIME STAMP"
|
|
|
|
* @param aNetlistFullFilename = netlist file name (*.net)
|
2009-11-18 12:52:19 +00:00
|
|
|
* @param aCmpFullFileName = cmp/footprint list file name (*.cmp) if not found,
|
2011-05-03 12:57:44 +00:00
|
|
|
* @param aMessageWindow = a wxTextCtrl to print messages (can be NULL).
|
|
|
|
* @param aChangeFootprint = true to change existing footprints
|
|
|
|
* when the netlist gives a different footprint.
|
|
|
|
* false to keep existing footprints
|
|
|
|
* @param aDeleteBadTracks - true to erase erroneous tracks after updating connectivity info.
|
2011-09-16 14:13:02 +00:00
|
|
|
* @param aDeleteExtraFootprints - true to remove unlocked footprints found on board but not
|
|
|
|
* in netlist.
|
2011-05-03 12:57:44 +00:00
|
|
|
* @param aSelect_By_Timestamp - true to use schematic timestamps instead of schematic references
|
|
|
|
* to identify footprints on board
|
|
|
|
* (Must be used after a full reannotation in schematic).
|
2010-04-16 16:28:35 +00:00
|
|
|
* @return true if Ok
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2011-05-03 12:57:44 +00:00
|
|
|
bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
|
|
|
|
const wxString& aCmpFullFileName,
|
|
|
|
wxTextCtrl* aMessageWindow,
|
|
|
|
bool aChangeFootprint,
|
|
|
|
bool aDeleteBadTracks,
|
|
|
|
bool aDeleteExtraFootprints,
|
|
|
|
bool aSelect_By_Timestamp )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
FILE* netfile = OpenNetlistFile( aNetlistFullFilename );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2010-04-16 16:28:35 +00:00
|
|
|
if( !netfile )
|
|
|
|
return false;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2010-04-23 14:46:00 +00:00
|
|
|
SetLastNetListRead( aNetlistFullFilename );
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
bool useCmpfile = ! aCmpFullFileName.IsEmpty() && wxFileExists( aCmpFullFileName );
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
if( aMessageWindow )
|
2009-04-24 07:36:36 +00:00
|
|
|
{
|
|
|
|
wxString msg;
|
2010-04-23 14:46:00 +00:00
|
|
|
msg.Printf( _( "Reading Netlist \"%s\"" ), GetChars( aNetlistFullFilename ) );
|
2009-04-24 07:36:36 +00:00
|
|
|
aMessageWindow->AppendText( msg + wxT( "\n" ) );
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
if( useCmpfile )
|
2011-05-03 12:57:44 +00:00
|
|
|
{
|
2011-09-16 14:13:02 +00:00
|
|
|
msg.Printf( _( "Using component/footprint link file \"%s\"" ),
|
|
|
|
GetChars( aCmpFullFileName ) );
|
2011-05-03 12:57:44 +00:00
|
|
|
aMessageWindow->AppendText( msg + wxT( "\n" ) );
|
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
|
|
|
|
if( aSelect_By_Timestamp )
|
|
|
|
{
|
|
|
|
msg.Printf( _( "Using time stamp selection" ),
|
|
|
|
GetChars( aCmpFullFileName ) );
|
|
|
|
aMessageWindow->AppendText( msg + wxT( "\n" ) );
|
|
|
|
}
|
2011-05-03 12:57:44 +00:00
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-08-03 07:55:08 +00:00
|
|
|
// Clear undo and redo lists to avoid inconsistencies between lists
|
2010-04-16 16:28:35 +00:00
|
|
|
GetScreen()->ClearUndoRedoList();
|
2009-08-03 07:55:08 +00:00
|
|
|
|
2010-04-16 16:28:35 +00:00
|
|
|
OnModify();
|
2011-02-28 18:36:19 +00:00
|
|
|
|
2011-09-16 14:13:02 +00:00
|
|
|
// Clear flags and pointers to avoid inconsistencies
|
2010-04-16 16:28:35 +00:00
|
|
|
GetBoard()->m_Status_Pcb = 0;
|
2011-01-20 11:26:10 +00:00
|
|
|
SetCurItem( NULL );
|
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
wxBusyCursor dummy; // Shows an hourglass while calculating
|
|
|
|
|
|
|
|
NETLIST_READER netList_Reader( this, aMessageWindow );
|
|
|
|
netList_Reader.m_UseTimeStamp = aSelect_By_Timestamp;
|
|
|
|
netList_Reader.m_ChangeFootprints = aChangeFootprint;
|
2012-01-26 09:37:36 +00:00
|
|
|
netList_Reader.m_UseCmpFile = useCmpfile;
|
|
|
|
netList_Reader.SetFilesnames( aNetlistFullFilename, aCmpFullFileName );
|
|
|
|
|
|
|
|
netList_Reader.ReadNetList( netfile );
|
2011-05-03 12:57:44 +00:00
|
|
|
|
|
|
|
// Delete footprints not found in netlist:
|
|
|
|
if( aDeleteExtraFootprints )
|
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
if( IsOK( NULL,
|
|
|
|
_( "Ok to delete not locked footprints not found in netlist?" ) ) )
|
|
|
|
netList_Reader.RemoveExtraFootprints();
|
2011-05-03 12:57:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Rebuild the board connectivity:
|
|
|
|
Compile_Ratsnest( NULL, true );
|
|
|
|
|
2011-05-03 16:57:15 +00:00
|
|
|
if( aDeleteBadTracks && GetBoard()->m_Track )
|
2011-05-03 12:57:44 +00:00
|
|
|
{
|
2011-05-03 16:57:15 +00:00
|
|
|
// Remove erroneous tracks
|
2012-01-26 09:37:36 +00:00
|
|
|
if( RemoveMisConnectedTracks() )
|
|
|
|
Compile_Ratsnest( NULL, true );
|
2011-05-03 12:57:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GetBoard()->DisplayInfo( this );
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->Refresh();
|
2011-05-03 12:57:44 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
/*
|
|
|
|
* Function ReadNetList
|
|
|
|
* The main function to detect the netlist format,and run the right netlist reader
|
|
|
|
* aFile = the already opened file (will be closed by the netlist reader)
|
2011-05-03 12:57:44 +00:00
|
|
|
*/
|
2012-01-26 09:37:36 +00:00
|
|
|
bool NETLIST_READER::ReadNetList( FILE* aFile )
|
2011-05-03 12:57:44 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
// Try to determine the netlist type:
|
|
|
|
bool new_fmt = true;
|
|
|
|
std::string header( "(export" );
|
|
|
|
for( unsigned ii = 0; ii < header.size(); ii++ )
|
2011-05-03 12:57:44 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
int data;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
data = fgetc( aFile );
|
|
|
|
} while ( ( data == ' ' ) &&( EOF != data ) ) ;
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
if( (int)header[ii] == data )
|
2011-05-03 12:57:44 +00:00
|
|
|
continue;
|
2012-01-26 09:37:36 +00:00
|
|
|
new_fmt = false;
|
|
|
|
break;
|
|
|
|
}
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
rewind( aFile );
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
bool success;
|
|
|
|
if( new_fmt )
|
|
|
|
success = ReadKicadNetList( aFile );
|
|
|
|
else
|
|
|
|
success = ReadOldFmtdNetList( aFile );
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
return success;
|
2011-05-03 12:57:44 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
bool NETLIST_READER::InitializeModules()
|
2011-05-03 12:57:44 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
if( m_UseCmpFile ) // Try to get footprint name from .cmp file
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
readModuleComponentLinkfile();
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
for( unsigned ii = 0; ii < m_modulesInNetlist.size(); ii++ )
|
|
|
|
{
|
|
|
|
MODULE_INFO* currmod_info = m_modulesInNetlist[ii];
|
|
|
|
// Test if module is already loaded.
|
|
|
|
wxString * idMod = m_UseTimeStamp?
|
|
|
|
&currmod_info->m_TimeStamp : &currmod_info->m_Reference;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE* module = FindModule( *idMod );
|
|
|
|
if( module == NULL ) // not existing, load it
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
m_newModulesList.push_back( currmod_info );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-19 13:08:24 +00:00
|
|
|
bool success = loadNewModules();
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
// Update modules fields
|
|
|
|
for( unsigned ii = 0; ii < m_modulesInNetlist.size(); ii++ )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE_INFO* currmod_info = m_modulesInNetlist[ii];
|
|
|
|
// Test if module is already loaded.
|
|
|
|
wxString * idMod = m_UseTimeStamp?
|
|
|
|
&currmod_info->m_TimeStamp : &currmod_info->m_Reference;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE* module = FindModule( *idMod );
|
|
|
|
if( module )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
// Update current module ( reference, value and "Time Stamp")
|
|
|
|
module->m_Reference->m_Text = currmod_info->m_Reference;
|
|
|
|
module->m_Value->m_Text = currmod_info->m_Value;
|
|
|
|
module->SetPath( currmod_info->m_TimeStamp );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
else // not existing
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
// clear pads netnames
|
|
|
|
for( MODULE* module = m_pcbframe->GetBoard()->m_Modules; module; module = module->Next() )
|
|
|
|
{
|
|
|
|
for( D_PAD* pad = module->m_Pads; pad; pad = pad->Next() )
|
|
|
|
pad->SetNetname( wxEmptyString );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
return success;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
void NETLIST_READER::TestFootprintsMatchingAndExchange()
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
for( MODULE* module = m_pcbframe->GetBoard()->m_Modules; module; module = module->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
// Search for the corresponding module info
|
|
|
|
MODULE_INFO * mod_info = NULL;
|
|
|
|
for( unsigned ii = 0; ii < m_modulesInNetlist.size(); ii++ )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE_INFO * candidate = m_modulesInNetlist[ii];
|
|
|
|
// Test if mod_info matches the current module:
|
|
|
|
if( candidate->m_Reference.CmpNoCase( module->GetReference() ) == 0 )
|
|
|
|
{
|
|
|
|
mod_info = candidate;
|
|
|
|
break;
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
if( mod_info == NULL ) // not found in netlist
|
|
|
|
continue;
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
if( module->GetLibRef().CmpNoCase( mod_info->m_Footprint ) != 0 )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
if( m_ChangeFootprints ) // footprint exchange allowed.
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE* newModule = m_pcbframe->GetModuleLibrary( wxEmptyString,
|
|
|
|
mod_info->m_Footprint,
|
|
|
|
false );
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
if( newModule )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
// Change old module to the new module (and delete the old one)
|
|
|
|
m_pcbframe->Exchange_Module( module, newModule, NULL );
|
|
|
|
module = newModule;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
else if( m_messageWindow )
|
2009-04-24 07:36:36 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
wxString msg;
|
|
|
|
msg.Printf( _( "Component \"%s\": module [%s] not found\n" ),
|
|
|
|
GetChars( mod_info->m_Reference ),
|
|
|
|
GetChars( mod_info->m_Footprint ) );
|
|
|
|
|
|
|
|
m_messageWindow->AppendText( msg );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
else if( m_messageWindow )
|
|
|
|
{
|
|
|
|
wxString msg;
|
|
|
|
msg.Printf( _( "Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ),
|
|
|
|
GetChars( mod_info->m_Reference ),
|
|
|
|
GetChars( module->GetLibRef() ),
|
|
|
|
GetChars( mod_info->m_Footprint ) );
|
2009-11-18 12:52:19 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
m_messageWindow->AppendText( msg );
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
/**
|
|
|
|
* Function SetPadNetName
|
|
|
|
* Update a pad netname
|
|
|
|
* @param aModule = module reference
|
|
|
|
* @param aPadname = pad name (pad num)
|
|
|
|
* @param aNetname = new net name of the pad
|
|
|
|
* @return a pointer to the pad or NULL if the pad is not found
|
|
|
|
*/
|
|
|
|
D_PAD* NETLIST_READER::SetPadNetName( const wxString & aModule, const wxString & aPadname,
|
|
|
|
const wxString & aNetname )
|
|
|
|
{
|
|
|
|
MODULE* module = m_pcbframe->GetBoard()->FindModuleByReference( aModule );
|
|
|
|
if( module )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
D_PAD * pad = module->FindPadByName( aPadname );
|
|
|
|
if( pad )
|
2011-04-02 16:14:07 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
pad->SetNetname( aNetname );
|
|
|
|
return pad;
|
2011-04-02 16:14:07 +00:00
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
if( m_messageWindow )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
wxString msg;
|
|
|
|
msg.Printf( _( "Module [%s]: Pad [%s] not found" ),
|
|
|
|
GetChars( aModule ), GetChars( aPadname ) );
|
|
|
|
m_messageWindow->AppendText( msg + wxT( "\n" ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
return NULL;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
/* function RemoveExtraFootprints
|
|
|
|
* Remove (delete) not locked footprints found on board, but not in netlist
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2012-01-26 09:37:36 +00:00
|
|
|
void NETLIST_READER::RemoveExtraFootprints()
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE* nextModule;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE* module = m_pcbframe->GetBoard()->m_Modules;
|
|
|
|
for( ; module != NULL; module = nextModule )
|
|
|
|
{
|
|
|
|
unsigned ii;
|
|
|
|
nextModule = module->Next();
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
if( module->m_ModuleStatus & MODULE_is_LOCKED )
|
|
|
|
continue;
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
for( ii = 0; ii < m_modulesInNetlist.size(); ii++ )
|
|
|
|
{
|
|
|
|
MODULE_INFO* mod_info = m_modulesInNetlist[ii];
|
|
|
|
if( module->m_Reference->m_Text.CmpNoCase( mod_info->m_Reference ) == 0 )
|
|
|
|
break; // Module is found in net list.
|
|
|
|
}
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
if( ii == m_modulesInNetlist.size() ) // Module not found in netlist.
|
|
|
|
module->DeleteStructure();
|
|
|
|
}
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
/* Search for a module id the modules existing in the current BOARD.
|
|
|
|
* aId is a key to identify the module to find:
|
|
|
|
* The reference or the full time stamp, according to m_UseTimeStamp
|
|
|
|
* Returns the module is found, NULL otherwise.
|
|
|
|
*/
|
|
|
|
MODULE* NETLIST_READER::FindModule( const wxString& aId )
|
|
|
|
{
|
|
|
|
MODULE* module = m_pcbframe->GetBoard()->m_Modules;
|
|
|
|
for( ; module != NULL; module = module->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
if( m_UseTimeStamp ) // identification by time stamp
|
2009-04-24 07:36:36 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
if( aId.CmpNoCase( module->m_Path ) == 0 )
|
|
|
|
return module;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
else // identification by Reference
|
2009-04-24 07:36:36 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
if( aId.CmpNoCase( module->m_Reference->m_Text ) == 0 )
|
|
|
|
return module;
|
2009-04-24 07:36:36 +00:00
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
return NULL;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
/**
|
|
|
|
* build and shows a list of existing modules on board
|
2009-11-18 12:52:19 +00:00
|
|
|
* The user can select a module from this list
|
2009-04-24 07:36:36 +00:00
|
|
|
* @return a pointer to the selected module or NULL
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2011-03-01 19:26:17 +00:00
|
|
|
MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName( void )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
MODULE* Module;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-01-05 05:21:35 +00:00
|
|
|
if( GetBoard()->m_Modules == NULL )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2010-11-19 18:50:23 +00:00
|
|
|
DisplayError( this, _( "No Modules" ) );
|
|
|
|
return 0;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2010-11-19 18:50:23 +00:00
|
|
|
wxArrayString listnames;
|
2009-04-24 07:36:36 +00:00
|
|
|
Module = (MODULE*) GetBoard()->m_Modules;
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2008-11-24 06:53:43 +00:00
|
|
|
for( ; Module != NULL; Module = (MODULE*) Module->Next() )
|
2010-11-19 18:50:23 +00:00
|
|
|
listnames.Add( Module->m_Reference->m_Text );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-09-06 19:42:46 +00:00
|
|
|
EDA_LIST_DIALOG dlg( this, _( "Components" ), listnames, wxEmptyString );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2010-11-19 18:50:23 +00:00
|
|
|
if( dlg.ShowModal() != wxID_OK )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
wxString ref = dlg.GetTextSelection();
|
|
|
|
Module = (MODULE*) GetBoard()->m_Modules;
|
2011-09-06 19:42:46 +00:00
|
|
|
|
2010-11-19 18:50:23 +00:00
|
|
|
for( ; Module != NULL; Module = Module->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2010-11-19 18:50:23 +00:00
|
|
|
if( Module->m_Reference->m_Text == ref )
|
|
|
|
break;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Module;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
/*
|
|
|
|
* Function Test_Duplicate_Missing_And_Extra_Footprints
|
|
|
|
* Build a list of duplicate, missing and extra footprints
|
|
|
|
* from the current board and a netlist netlist :
|
|
|
|
* Shows 3 lists:
|
|
|
|
* 1 - duplicate footprints on board
|
|
|
|
* 2 - missing footprints (found in netlist but not on board)
|
|
|
|
* 3 - footprints not in netlist but on board
|
|
|
|
* @param aNetlistFullFilename = the full filename netlist
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2011-05-03 12:57:44 +00:00
|
|
|
void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints(
|
|
|
|
const wxString& aNetlistFullFilename )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
int nberr = 0;
|
|
|
|
wxArrayString list; // The list of messages to display
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
if( GetBoard()->m_Modules == NULL )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
DisplayInfoMessage( this, _( "No modules" ) );
|
2009-11-18 12:52:19 +00:00
|
|
|
return;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
FILE* netfile = OpenNetlistFile( aNetlistFullFilename );
|
|
|
|
if( !netfile )
|
|
|
|
return;
|
|
|
|
|
|
|
|
SetLastNetListRead( aNetlistFullFilename );
|
2011-12-16 17:03:25 +00:00
|
|
|
// Build the list of references of the net list modules.
|
2011-05-03 12:57:44 +00:00
|
|
|
NETLIST_READER netList_Reader( this );
|
2012-01-26 09:37:36 +00:00
|
|
|
netList_Reader.SetFilesnames( aNetlistFullFilename, wxEmptyString );
|
|
|
|
netList_Reader.BuildModuleListOnly( true );
|
|
|
|
if( ! netList_Reader.ReadNetList( netfile ) )
|
|
|
|
return; // error
|
2011-04-19 14:28:34 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
std::vector <MODULE_INFO*>& moduleInfoList = netList_Reader.GetModuleInfoList();
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
if( moduleInfoList.size() == 0 )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
wxMessageBox( _( "No modules in NetList" ) );
|
2009-11-18 12:52:19 +00:00
|
|
|
return;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2011-12-16 17:03:25 +00:00
|
|
|
// Search for duplicate footprints.
|
2011-04-19 14:28:34 +00:00
|
|
|
list.Add( _( "Duplicates" ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-05-05 17:45:35 +00:00
|
|
|
MODULE* module = GetBoard()->m_Modules;
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2011-05-05 17:45:35 +00:00
|
|
|
for( ; module != NULL; module = module->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-05 17:45:35 +00:00
|
|
|
MODULE* altmodule = module->Next();
|
2011-04-19 14:28:34 +00:00
|
|
|
|
2011-05-05 17:45:35 +00:00
|
|
|
for( ; altmodule != NULL; altmodule = altmodule->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-05 17:45:35 +00:00
|
|
|
if( module->m_Reference->m_Text.CmpNoCase( altmodule->m_Reference->m_Text ) == 0 )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-05 17:45:35 +00:00
|
|
|
if( module->m_Reference->m_Text.IsEmpty() )
|
|
|
|
list.Add( wxT("<noref>") );
|
|
|
|
else
|
|
|
|
list.Add( module->m_Reference->m_Text );
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
nberr++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
// Search for missing modules on board.
|
2011-04-19 14:28:34 +00:00
|
|
|
list.Add( _( "Missing:" ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
for( unsigned ii = 0; ii < moduleInfoList.size(); ii++ )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE_INFO* mod_info = moduleInfoList[ii];
|
|
|
|
module = GetBoard()->FindModuleByReference( mod_info->m_Reference );
|
2011-05-05 17:45:35 +00:00
|
|
|
if( module == NULL ) // Module missing, not found in board
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
list.Add( mod_info->m_Reference );
|
2007-08-20 19:33:15 +00:00
|
|
|
nberr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
// Search for modules found on board but not in net list.
|
2011-04-19 14:28:34 +00:00
|
|
|
list.Add( _( "Not in Netlist:" ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-05-05 17:45:35 +00:00
|
|
|
module = GetBoard()->m_Modules;
|
|
|
|
for( ; module != NULL; module = module->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
unsigned ii;
|
|
|
|
for( ii = 0; ii < moduleInfoList.size(); ii++ )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE_INFO* mod_info = moduleInfoList[ii];
|
|
|
|
if( module->m_Reference->m_Text.CmpNoCase( mod_info->m_Reference ) == 0 )
|
2011-12-16 17:03:25 +00:00
|
|
|
break; // Module is in net list.
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
if( ii == moduleInfoList.size() ) // Module not found in netlist
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-05 17:45:35 +00:00
|
|
|
list.Add( module->m_Reference->m_Text );
|
2007-08-20 19:33:15 +00:00
|
|
|
nberr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
wxSingleChoiceDialog dlg( this, wxEmptyString, _( "Check Modules" ), list, NULL,
|
2011-04-19 14:28:34 +00:00
|
|
|
wxCHOICEDLG_STYLE & ~wxCANCEL );
|
|
|
|
|
|
|
|
dlg.ShowModal();
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2011-05-03 16:57:15 +00:00
|
|
|
* function readModuleComponentLinkfile
|
2011-05-03 12:57:44 +00:00
|
|
|
* read the *.cmp file ( filename in m_cmplistFullName )
|
2011-05-03 16:57:15 +00:00
|
|
|
* giving the equivalence Footprint_names / components
|
|
|
|
* to find the footprint name corresponding to aCmpIdent
|
2012-01-26 09:37:36 +00:00
|
|
|
* return true if the file can be read
|
2011-05-03 16:57:15 +00:00
|
|
|
*
|
|
|
|
* Sample file:
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2009-11-18 12:52:19 +00:00
|
|
|
* Cmp-Mod V01 Genere by Pcbnew 29/10/2003-13: 11:6 *
|
2007-08-20 19:33:15 +00:00
|
|
|
* BeginCmp
|
2009-04-24 07:36:36 +00:00
|
|
|
* TimeStamp = /32307DE2/AA450F67;
|
2007-08-20 19:33:15 +00:00
|
|
|
* Reference = C1;
|
|
|
|
* ValeurCmp = 47uF;
|
|
|
|
* IdModule = CP6;
|
|
|
|
* EndCmp
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2012-01-26 09:37:36 +00:00
|
|
|
|
|
|
|
bool NETLIST_READER::readModuleComponentLinkfile()
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
wxString refcurrcmp; // Stores value read from line like Reference = BUS1;
|
|
|
|
wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67;
|
2012-01-26 09:37:36 +00:00
|
|
|
wxString footprint; // Stores value read from line like IdModule = CP6;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
FILE* cmpFile = wxFopen( m_cmplistFullName, wxT( "rt" ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
if( cmpFile == NULL )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
wxString msg;
|
2012-01-17 19:23:07 +00:00
|
|
|
msg.Printf( _( "File <%s> not found, use Netlist for footprints selection" ),
|
2011-05-03 12:57:44 +00:00
|
|
|
GetChars( m_cmplistFullName ) );
|
2012-01-17 19:23:07 +00:00
|
|
|
|
|
|
|
if( m_messageWindow )
|
|
|
|
m_messageWindow->AppendText( msg );
|
2011-05-03 12:57:44 +00:00
|
|
|
return false;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2011-09-16 14:13:02 +00:00
|
|
|
// netlineReader dtor will close cmpFile
|
|
|
|
FILE_LINE_READER netlineReader( cmpFile, m_cmplistFullName );
|
2011-05-03 12:57:44 +00:00
|
|
|
wxString buffer;
|
|
|
|
wxString value;
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
while( netlineReader.ReadLine() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
buffer = FROM_UTF8( netlineReader.Line() );
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
if( ! buffer.StartsWith( wxT("BeginCmp") ) )
|
2007-08-20 19:33:15 +00:00
|
|
|
continue;
|
|
|
|
|
2011-12-16 17:03:25 +00:00
|
|
|
// Begin component description.
|
2007-08-20 19:33:15 +00:00
|
|
|
refcurrcmp.Empty();
|
2012-01-26 09:37:36 +00:00
|
|
|
footprint.Empty();
|
2009-04-24 07:36:36 +00:00
|
|
|
timestamp.Empty();
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
while( netlineReader.ReadLine() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
buffer = FROM_UTF8( netlineReader.Line() );
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
if( buffer.StartsWith( wxT("EndCmp") ) )
|
2007-08-20 19:33:15 +00:00
|
|
|
break;
|
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
// store string value, stored between '=' and ';' delimiters.
|
|
|
|
value = buffer.AfterFirst( '=' );
|
|
|
|
value = value.BeforeLast( ';');
|
|
|
|
value.Trim(true);
|
|
|
|
value.Trim(false);
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
if( buffer.StartsWith( wxT("Reference") ) )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
refcurrcmp = value;
|
2007-08-20 19:33:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
if( buffer.StartsWith( wxT("IdModule =" ) ) )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
footprint = value;
|
2007-08-20 19:33:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-05-03 12:57:44 +00:00
|
|
|
|
|
|
|
if( buffer.StartsWith( wxT("TimeStamp =" ) ) )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
timestamp = value;
|
|
|
|
continue;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
// Find the corresponding item in module info list:
|
|
|
|
for( unsigned ii = 0; ii < m_modulesInNetlist.size(); ii++ )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
MODULE_INFO * mod_info = m_modulesInNetlist[ii];
|
|
|
|
if( m_UseTimeStamp ) // Use schematic timestamp to locate the footprint
|
|
|
|
{
|
|
|
|
if( mod_info->m_TimeStamp.CmpNoCase( timestamp ) == 0 &&
|
|
|
|
!timestamp.IsEmpty() )
|
|
|
|
{ // Found
|
|
|
|
if( !footprint.IsEmpty() )
|
|
|
|
mod_info->m_Footprint = footprint;
|
|
|
|
break;
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2012-01-26 09:37:36 +00:00
|
|
|
else // Use schematic reference to locate the footprint
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
if( mod_info->m_Reference.CmpNoCase( refcurrcmp ) == 0 ) // Found!
|
|
|
|
{
|
|
|
|
if( !footprint.IsEmpty() )
|
|
|
|
mod_info->m_Footprint = footprint;
|
|
|
|
break;
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
return true;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
/* Function to sort the footprint list, used by loadNewModules.
|
|
|
|
* the given list is sorted by name
|
|
|
|
*/
|
|
|
|
static bool SortByLibName( MODULE_INFO* ref, MODULE_INFO* cmp )
|
|
|
|
{
|
|
|
|
int ii = ref->m_Footprint.CmpNoCase( cmp->m_Footprint );
|
|
|
|
return ii > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-18 12:52:19 +00:00
|
|
|
/* Load new modules from library.
|
2011-05-03 12:57:44 +00:00
|
|
|
* If a new module is already loaded it is duplicated, which avoids multiple
|
|
|
|
* unnecessary disk or net access to read libraries.
|
2011-08-19 13:08:24 +00:00
|
|
|
* return false if a footprint is not found, true if OK
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2011-08-19 13:08:24 +00:00
|
|
|
bool NETLIST_READER::loadNewModules()
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
MODULE_INFO* ref, * cmp;
|
|
|
|
MODULE* Module = NULL;
|
|
|
|
wxPoint ModuleBestPosition;
|
|
|
|
BOARD* pcb = m_pcbframe->GetBoard();
|
2011-08-19 13:08:24 +00:00
|
|
|
bool success = true;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
if( m_newModulesList.size() == 0 )
|
2011-08-19 13:08:24 +00:00
|
|
|
return true;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
sort( m_newModulesList.begin(), m_newModulesList.end(), SortByLibName );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
// Calculate the footprint "best" position:
|
++PCBNew
* Removed Pcb_Frame argument from BOARD() constructor, since it precludes
having a BOARD being edited by more than one editor, it was a bad design.
And this meant removing m_PcbFrame from BOARD.
* removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame
* Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp
* added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance
* a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed,
such as dialog_mask_clearance, dialog_drc, etc.
* Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it
with build_version.h's #define BOARD_FILE_VERSION, although there may be a
better place for this constant.
* Made the public functions in PARAM_CFG_ARRAY be type const.
void SaveParam(..) const and void ReadParam(..) const
* PARAM_CFG_BASE now has virtual destructor since we have various way of
destroying the derived class and boost::ptr_vector must be told about this.
* Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use
an automatic PARAM_CFG_ARRAY which is on the stack.\
* PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array,
since it has to access the current BOARD and the BOARD can change.
Remember BOARD_DESIGN_SETTINGS are now in the BOARD.
* Made the m_BoundingBox member private, this was a brutally hard task,
and indicative of the lack of commitment to accessors and object oriented
design on the part of KiCad developers. We must do better.
Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox().
* Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
2011-12-05 06:15:33 +00:00
|
|
|
EDA_RECT bbbox = pcb->ComputeBoundingBox( true );
|
|
|
|
|
|
|
|
if( bbbox.GetWidth() || bbbox.GetHeight() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
++PCBNew
* Removed Pcb_Frame argument from BOARD() constructor, since it precludes
having a BOARD being edited by more than one editor, it was a bad design.
And this meant removing m_PcbFrame from BOARD.
* removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame
* Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp
* added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance
* a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed,
such as dialog_mask_clearance, dialog_drc, etc.
* Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it
with build_version.h's #define BOARD_FILE_VERSION, although there may be a
better place for this constant.
* Made the public functions in PARAM_CFG_ARRAY be type const.
void SaveParam(..) const and void ReadParam(..) const
* PARAM_CFG_BASE now has virtual destructor since we have various way of
destroying the derived class and boost::ptr_vector must be told about this.
* Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use
an automatic PARAM_CFG_ARRAY which is on the stack.\
* PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array,
since it has to access the current BOARD and the BOARD can change.
Remember BOARD_DESIGN_SETTINGS are now in the BOARD.
* Made the m_BoundingBox member private, this was a brutally hard task,
and indicative of the lack of commitment to accessors and object oriented
design on the part of KiCad developers. We must do better.
Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox().
* Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
2011-12-05 06:15:33 +00:00
|
|
|
ModuleBestPosition = bbbox.GetEnd();
|
2011-05-03 12:57:44 +00:00
|
|
|
ModuleBestPosition.y += 5000;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
ref = cmp = m_newModulesList[0];
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
for( unsigned ii = 0; ii < m_newModulesList.size(); ii++ )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2011-05-03 12:57:44 +00:00
|
|
|
cmp = m_newModulesList[ii];
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2012-01-26 09:37:36 +00:00
|
|
|
if( (ii == 0) || ( ref->m_Footprint != cmp->m_Footprint) )
|
2008-12-06 08:21:54 +00:00
|
|
|
{
|
2011-12-16 17:03:25 +00:00
|
|
|
// New footprint : must be loaded from a library
|
2012-01-26 09:37:36 +00:00
|
|
|
Module = m_pcbframe->GetModuleLibrary( wxEmptyString, cmp->m_Footprint, false );
|
2011-05-03 12:57:44 +00:00
|
|
|
ref = cmp;
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
if( Module == NULL )
|
|
|
|
{
|
2011-08-19 13:08:24 +00:00
|
|
|
success = false;
|
|
|
|
if( m_messageWindow )
|
|
|
|
{
|
2012-01-26 09:37:36 +00:00
|
|
|
wxString msg;
|
|
|
|
msg.Printf( _( "Component [%s]: footprint <%s> not found" ),
|
|
|
|
GetChars( cmp->m_Reference ),
|
|
|
|
GetChars( cmp->m_Footprint ) );
|
|
|
|
|
2011-08-19 13:08:24 +00:00
|
|
|
msg += wxT("\n");
|
|
|
|
m_messageWindow->AppendText( msg );
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-09-16 14:13:02 +00:00
|
|
|
|
2009-08-19 14:19:35 +00:00
|
|
|
Module->SetPosition( ModuleBestPosition );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-11-18 12:52:19 +00:00
|
|
|
/* Update schematic links : reference "Time Stamp" and schematic
|
2011-09-16 14:13:02 +00:00
|
|
|
* hierarchical path */
|
2012-01-26 09:37:36 +00:00
|
|
|
Module->m_Reference->m_Text = cmp->m_Reference;
|
2011-12-12 08:37:05 +00:00
|
|
|
Module->SetTimeStamp( GetNewTimeStamp() );
|
2012-01-26 09:37:36 +00:00
|
|
|
Module->SetPath( cmp->m_TimeStamp );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-16 14:13:02 +00:00
|
|
|
// Footprint already loaded from a library, duplicate it (faster)
|
2007-08-20 19:33:15 +00:00
|
|
|
if( Module == NULL )
|
2011-12-16 17:03:25 +00:00
|
|
|
continue; // Module does not exist in library.
|
2008-12-06 08:21:54 +00:00
|
|
|
|
2012-01-14 19:50:32 +00:00
|
|
|
MODULE* newmodule = new MODULE( *Module );
|
|
|
|
newmodule->SetParent( pcb );
|
2008-12-06 08:21:54 +00:00
|
|
|
|
2011-05-03 12:57:44 +00:00
|
|
|
pcb->Add( newmodule, ADD_APPEND );
|
2008-12-06 08:21:54 +00:00
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
Module = newmodule;
|
2012-01-26 09:37:36 +00:00
|
|
|
Module->m_Reference->m_Text = cmp->m_Reference;
|
2011-12-12 08:37:05 +00:00
|
|
|
Module->SetTimeStamp( GetNewTimeStamp() );
|
2012-01-26 09:37:36 +00:00
|
|
|
Module->SetPath( cmp->m_TimeStamp );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
2011-08-19 13:08:24 +00:00
|
|
|
|
|
|
|
return success;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|