Pcbnew NETLIST_READER improvements.
* Create separate NETLIST object to hold contents of netlist files. * Read entire netlist and footprint link files before making applying changes to board. * Add BOARD::ReplaceNetlist() function to eliminate the calls between the NETLIST_READER, PCB_EDIT_FRAME, and BOARD objects. * Change placement of new components below the center of the current board or in the center of the page if the BOARD is empty. * Add dry run option to netlist dialog to print changes to message control without making changes. * Add button to netlist dialog to allow saving contents of message control to a file. * Eliminate the need to compile netlist_reader_*.cpp in both CvPcb and Pcbnew. * Add netlist_reader_*.cpp to the pcbcommon library. * Remove redundant load component link file code from CvPcb. * Modify CvPcb new to work with the new NETLIST_READER object. * Add compare() function and < and == operators to FPID object. * Add REPORTER class to hide an underlying string writing implementation for use in low level objects. Thank you Dick for the idea. * Lots of minor coding policy, Doxygen comment, and missing license fixes.
This commit is contained in:
parent
d8ba7b3af8
commit
61b4f8a9eb
|
@ -112,7 +112,8 @@ public:
|
|||
* Function GetNodeProperties
|
||||
* Collects all node properties to map.
|
||||
*
|
||||
* @param aProps contains map of found properties
|
||||
* @param aNode is an XML node.
|
||||
* @param aProps contains map of found properties.
|
||||
*/
|
||||
static void GetNodeProperties( wxXmlNode* aNode, PROPERTY_MAP& aProps );
|
||||
|
||||
|
|
9
TODO.txt
9
TODO.txt
|
@ -10,7 +10,7 @@ WXMAC Platform
|
|||
Common
|
||||
------
|
||||
* Grep for @TODO or TODO for sourcecode tasks
|
||||
* Use doxygen compatible comments on member functions (.h files)
|
||||
* Use Doxygen compatible comments on member functions (.h files)
|
||||
* Add tooltip text to all non-obvious controls in every dialog window.
|
||||
Use wxFormBuilder.
|
||||
* Component and module search displays in which library the
|
||||
|
@ -113,9 +113,9 @@ const wxString FP_LIB_TABLE::ExpandSubtitutions( const wxString aString )
|
|||
|
||||
|
||||
|
||||
EESchema
|
||||
Eeschema
|
||||
--------
|
||||
* Drag and drop between two EESchema windows.
|
||||
* Drag and drop between two Eeschema windows.
|
||||
|
||||
Wayne:
|
||||
E3) Hook up perform last library search hot key to replace search libraries for
|
||||
|
@ -159,5 +159,6 @@ PCBNew
|
|||
of PLUGIN::Footprint*() functions. At least LEGACY and KICAD are both needed
|
||||
concurrently.
|
||||
|
||||
|
||||
*) Add a hot key to toggle the 45 degree constraint on and off so that it can be
|
||||
changed when drawing a trace.
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ set(COMMON_SRCS
|
|||
newstroke_font.cpp
|
||||
projet_config.cpp
|
||||
ptree.cpp
|
||||
reporter.cpp
|
||||
richio.cpp
|
||||
selcolor.cpp
|
||||
string.cpp
|
||||
|
@ -116,6 +117,9 @@ set(PCB_COMMON_SRCS
|
|||
../pcbnew/class_zone_settings.cpp
|
||||
../pcbnew/classpcb.cpp
|
||||
../pcbnew/collectors.cpp
|
||||
../pcbnew/netlist_reader_common.cpp
|
||||
../pcbnew/netlist_reader_firstformat.cpp
|
||||
../pcbnew/netlist_reader_kicad.cpp
|
||||
../pcbnew/sel_layer.cpp
|
||||
../pcbnew/pcb_plot_params.cpp
|
||||
../pcbnew/io_mgr.cpp
|
||||
|
|
|
@ -310,6 +310,26 @@ std::string FPID::Format( const std::string& aLogicalLib, const std::string& aFo
|
|||
}
|
||||
|
||||
|
||||
int FPID::compare( const FPID& aFPID ) const
|
||||
{
|
||||
// Don't bother comparing the same object.
|
||||
if( this == &aFPID )
|
||||
return 0;
|
||||
|
||||
int retv = nickname.compare( aFPID.nickname );
|
||||
|
||||
if( retv != 0 )
|
||||
return retv;
|
||||
|
||||
retv = footprint.compare( aFPID.footprint );
|
||||
|
||||
if( retv != 0 )
|
||||
return retv;
|
||||
|
||||
return revision.compare( aFPID.revision );
|
||||
}
|
||||
|
||||
|
||||
#if 0 && defined(DEBUG)
|
||||
|
||||
// build this with Debug CMAKE_BUILD_TYPE
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* @file reporter.h
|
||||
*/
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 1992-2013 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 <reporter.h>
|
||||
|
||||
|
||||
REPORTER& REPORTER::Report( const char *aText )
|
||||
{
|
||||
Report( FROM_UTF8( aText ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
REPORTER& WX_TEXT_CTRL_REPORTER::Report( const wxString& aText )
|
||||
{
|
||||
wxCHECK_MSG( m_textCtrl != NULL, *this,
|
||||
wxT( "No wxTextCtrl object defined in WX_TEXT_CTRL_REPORTER." ) );
|
||||
|
||||
m_textCtrl->AppendText( aText );
|
||||
return *this;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 20012 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 2012 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 2008-2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
|
@ -96,3 +96,4 @@ const wxString PSFileWildcard( _( "PostScript files (.ps)|*.ps" ) );
|
|||
const wxString ReportFileWildcard = _( "Report files (*.rpt)|*.rpt" );
|
||||
const wxString FootprintPlaceFileWildcard = _( "Footprint place files (*.pos)|*.pos" );
|
||||
const wxString Shapes3DFileWildcard( _( "Vrml and x3d files (*.wrl *.x3d)|*.wrl;*.x3d" ) );
|
||||
const wxString TextWildcard( _( "Text files (*.txt)|*.txt" ) );
|
||||
|
|
|
@ -27,9 +27,6 @@ set(CVPCB_DIALOGS
|
|||
|
||||
set(CVPCB_SRCS
|
||||
../common/base_units.cpp
|
||||
../pcbnew/netlist_reader_common.cpp
|
||||
../pcbnew/netlist_reader_kicad.cpp
|
||||
../pcbnew/netlist_reader_firstformat.cpp
|
||||
../pcbnew/class_drc_item.cpp
|
||||
autosel.cpp
|
||||
cfg.cpp
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2012 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 autosel.cpp
|
||||
*/
|
||||
|
@ -39,10 +62,16 @@ typedef boost::ptr_vector< FOOTPRINT_ALIAS > FOOTPRINT_ALIAS_LIST;
|
|||
wxString GetQuotedText( wxString & text )
|
||||
{
|
||||
int i = text.Find( QUOTE );
|
||||
if( wxNOT_FOUND == i ) return wxT( "" );
|
||||
|
||||
if( wxNOT_FOUND == i )
|
||||
return wxT( "" );
|
||||
|
||||
wxString shrt = text.Mid( i + 1 );
|
||||
i = shrt.Find( QUOTE );
|
||||
if( wxNOT_FOUND == i ) return wxT( "" );
|
||||
|
||||
if( wxNOT_FOUND == i )
|
||||
return wxT( "" );
|
||||
|
||||
text = shrt.Mid( i + 1 );
|
||||
return shrt.Mid( 0, i );
|
||||
}
|
||||
|
@ -52,13 +81,14 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event )
|
|||
{
|
||||
FOOTPRINT_ALIAS_LIST aliases;
|
||||
FOOTPRINT_ALIAS* alias;
|
||||
COMPONENT* component;
|
||||
wxFileName fn;
|
||||
wxString msg, tmp;
|
||||
char Line[1024];
|
||||
FILE* file;
|
||||
size_t ii;
|
||||
|
||||
if( m_components.empty() )
|
||||
if( m_netlist.IsEmpty() )
|
||||
return;
|
||||
|
||||
/* Find equivalents in all available files. */
|
||||
|
@ -79,8 +109,8 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event )
|
|||
|
||||
if( !tmp )
|
||||
{
|
||||
msg.Printf( _( "Footprint alias library file <%s> could not be \
|
||||
found in the default search paths." ),
|
||||
msg.Printf( _( "Footprint alias library file <%s> could not be found in the "
|
||||
"default search paths." ),
|
||||
GetChars( fn.GetFullName() ) );
|
||||
wxMessageBox( msg, titleLibLoadError, wxOK | wxICON_ERROR );
|
||||
continue;
|
||||
|
@ -127,18 +157,21 @@ found in the default search paths." ),
|
|||
|
||||
m_skipComponentSelect = true;
|
||||
ii = 0;
|
||||
BOOST_FOREACH( COMPONENT_INFO& component, m_components )
|
||||
|
||||
for( unsigned kk = 0; kk < m_netlist.GetCount(); kk++ )
|
||||
{
|
||||
component = m_netlist.GetComponent( kk );
|
||||
|
||||
bool found = false;
|
||||
m_ListCmp->SetSelection( ii++, true );
|
||||
|
||||
if( !component.m_Footprint.IsEmpty() )
|
||||
if( !component->GetFootprintLibName().IsEmpty() )
|
||||
continue;
|
||||
|
||||
BOOST_FOREACH( FOOTPRINT_ALIAS& alias, aliases )
|
||||
{
|
||||
|
||||
if( alias.m_Name.CmpNoCase( component.m_Value ) != 0 )
|
||||
if( alias.m_Name.CmpNoCase( component->GetValue() ) != 0 )
|
||||
continue;
|
||||
|
||||
/* filter alias so one can use multiple aliases (for polar and nonpolar caps for
|
||||
|
@ -147,23 +180,23 @@ found in the default search paths." ),
|
|||
|
||||
if( module )
|
||||
{
|
||||
size_t filtercount = component.m_FootprintFilter.GetCount();
|
||||
size_t filtercount = component->GetFootprintFilters().GetCount();
|
||||
found = ( 0 == filtercount ); // if no entries, do not filter
|
||||
|
||||
for( size_t jj = 0; jj < filtercount && !found; jj++ )
|
||||
{
|
||||
found = module->m_Module.Matches( component.m_FootprintFilter[jj] );
|
||||
found = module->m_Module.Matches( component->GetFootprintFilters()[jj] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Printf( _( "Component %s: footprint %s not found in \
|
||||
any of the project footprint libraries." ),
|
||||
GetChars( component.m_Reference ),
|
||||
msg.Printf( _( "Component %s: footprint %s not found in any of the project "
|
||||
"footprint libraries." ),
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( alias.m_FootprintName ) );
|
||||
wxMessageBox( msg, _( "CvPcb Error" ), wxOK | wxICON_ERROR,
|
||||
this );
|
||||
wxMessageBox( msg, _( "CvPcb Error" ), wxOK | wxICON_ERROR, this );
|
||||
}
|
||||
|
||||
if( found )
|
||||
{
|
||||
SetNewPkg( alias.m_FootprintName );
|
||||
|
@ -171,15 +204,20 @@ any of the project footprint libraries." ),
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/* obviously the last chance: there's only one filter matching one footprint */
|
||||
if( !found && 1 == component.m_FootprintFilter.GetCount() ) {
|
||||
if( !found && 1 == component->GetFootprintFilters().GetCount() )
|
||||
{
|
||||
/* we do not need to analyse wildcards: single footprint do not contain them */
|
||||
/* and if there are wildcards it just will not match any */
|
||||
FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( component.m_FootprintFilter[0] );
|
||||
if( module ) {
|
||||
SetNewPkg( component.m_FootprintFilter[0] );
|
||||
FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( component->GetFootprintFilters()[0] );
|
||||
|
||||
if( module )
|
||||
{
|
||||
SetNewPkg( component->GetFootprintFilters()[0] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_skipComponentSelect = false;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,30 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 1992-2012 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 class_footprints_listbox.cpp
|
||||
* class to display the list fo available footprints
|
||||
* class to display the list of available footprints
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
|
@ -132,7 +156,7 @@ void FOOTPRINTS_LISTBOX::SetFootprintFullList( FOOTPRINT_LIST& list )
|
|||
}
|
||||
|
||||
|
||||
void FOOTPRINTS_LISTBOX::SetFootprintFilteredList( COMPONENT_INFO* Component,
|
||||
void FOOTPRINTS_LISTBOX::SetFootprintFilteredList( COMPONENT* aComponent,
|
||||
FOOTPRINT_LIST& list )
|
||||
{
|
||||
wxString msg;
|
||||
|
@ -149,13 +173,16 @@ void FOOTPRINTS_LISTBOX::SetFootprintFilteredList( COMPONENT_INFO* Component,
|
|||
// The search is case insensitive
|
||||
wxString module = footprint.m_Module.Upper();
|
||||
wxString candidate;
|
||||
for( jj = 0; jj < Component->m_FootprintFilter.GetCount(); jj++ )
|
||||
|
||||
for( jj = 0; jj < aComponent->GetFootprintFilters().GetCount(); jj++ )
|
||||
{
|
||||
candidate = Component->m_FootprintFilter[jj].Upper();
|
||||
candidate = aComponent->GetFootprintFilters()[jj].Upper();
|
||||
|
||||
if( !module.Matches( candidate ) )
|
||||
continue;
|
||||
|
||||
msg.Printf( wxT( "%3zu %s" ), m_FilteredFootprintList.GetCount() + 1,
|
||||
footprint.m_Module.GetData() );
|
||||
footprint.m_Module.GetData() );
|
||||
m_FilteredFootprintList.Add( msg );
|
||||
hasItem = true;
|
||||
}
|
||||
|
@ -172,8 +199,10 @@ void FOOTPRINTS_LISTBOX::SetFootprintFilteredList( COMPONENT_INFO* Component,
|
|||
Refresh();
|
||||
}
|
||||
|
||||
void FOOTPRINTS_LISTBOX::SetFootprintFilteredByPinCount( COMPONENT_INFO* Component,
|
||||
FOOTPRINT_LIST& list ) {
|
||||
|
||||
void FOOTPRINTS_LISTBOX::SetFootprintFilteredByPinCount( COMPONENT* aComponent,
|
||||
FOOTPRINT_LIST& list )
|
||||
{
|
||||
wxString msg;
|
||||
int oldSelection = GetSelection();
|
||||
bool hasItem = false;
|
||||
|
@ -184,10 +213,10 @@ void FOOTPRINTS_LISTBOX::SetFootprintFilteredByPinCount( COMPONENT_INFO* Compone
|
|||
{
|
||||
FOOTPRINT_INFO& footprint = list.GetItem(ii);
|
||||
|
||||
if( Component->m_pinCount == footprint.m_padCount )
|
||||
if( aComponent->GetNetCount() == footprint.m_padCount )
|
||||
{
|
||||
msg.Printf( wxT( "%3zu %s" ), m_FilteredFootprintList.GetCount() + 1,
|
||||
footprint.m_Module.GetData() );
|
||||
footprint.m_Module.GetData() );
|
||||
m_FilteredFootprintList.Add( msg );
|
||||
hasItem = true;
|
||||
}
|
||||
|
@ -204,13 +233,7 @@ void FOOTPRINTS_LISTBOX::SetFootprintFilteredByPinCount( COMPONENT_INFO* Compone
|
|||
Refresh();
|
||||
}
|
||||
|
||||
/** Set the footprint list. We can have 2 footprint list:
|
||||
* The full footprint list
|
||||
* The filtered footprint list (if the current selected component has a
|
||||
* filter for footprints)
|
||||
* @param FullList true = full footprint list, false = filtered footprint list
|
||||
* @param Redraw = true to redraw the window
|
||||
*/
|
||||
|
||||
void FOOTPRINTS_LISTBOX::SetActiveFootprintList( bool FullList, bool Redraw )
|
||||
{
|
||||
bool old_selection = m_UseFootprintFullList;
|
||||
|
@ -226,10 +249,12 @@ void FOOTPRINTS_LISTBOX::SetActiveFootprintList( bool FullList, bool Redraw )
|
|||
if( m_ActiveFootprintList )
|
||||
{
|
||||
bool new_selection;
|
||||
|
||||
if( FullList )
|
||||
new_selection = true;
|
||||
else
|
||||
new_selection = false;
|
||||
|
||||
if( new_selection != old_selection )
|
||||
SetSelection( 0, true );
|
||||
}
|
||||
|
@ -264,14 +289,12 @@ void FOOTPRINTS_LISTBOX::SetActiveFootprintList( bool FullList, bool Redraw )
|
|||
/**************************************/
|
||||
|
||||
BEGIN_EVENT_TABLE( FOOTPRINTS_LISTBOX, ITEMS_LISTBOX_BASE )
|
||||
EVT_SIZE( ITEMS_LISTBOX_BASE::OnSize )
|
||||
EVT_CHAR( FOOTPRINTS_LISTBOX::OnChar )
|
||||
EVT_SIZE( ITEMS_LISTBOX_BASE::OnSize )
|
||||
EVT_CHAR( FOOTPRINTS_LISTBOX::OnChar )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
/********************************************************/
|
||||
void FOOTPRINTS_LISTBOX::OnLeftClick( wxListEvent& event )
|
||||
/********************************************************/
|
||||
{
|
||||
FOOTPRINT_INFO* Module;
|
||||
wxString footprintName = GetSelectedFootprint();
|
||||
|
@ -297,9 +320,7 @@ void FOOTPRINTS_LISTBOX::OnLeftClick( wxListEvent& event )
|
|||
}
|
||||
|
||||
|
||||
/******************************************************/
|
||||
void FOOTPRINTS_LISTBOX::OnLeftDClick( wxListEvent& event )
|
||||
/******************************************************/
|
||||
{
|
||||
wxString footprintName = GetSelectedFootprint();
|
||||
|
||||
|
@ -307,21 +328,10 @@ void FOOTPRINTS_LISTBOX::OnLeftDClick( wxListEvent& event )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function OnChar
|
||||
* called on a key pressed
|
||||
* Call default handler for some special keys,
|
||||
* and for "ascii" keys, select the first footprint
|
||||
* that the name starts by the letter.
|
||||
* This is the defaut behaviour of a listbox, but because we use
|
||||
* virtual lists, the listbox does not know anything to what is displayed,
|
||||
* we must handle this behaviour here.
|
||||
* Furthermore the footprint name is not at the beginning of
|
||||
* displayed lines (the first word is the line number)
|
||||
*/
|
||||
void FOOTPRINTS_LISTBOX::OnChar( wxKeyEvent& event )
|
||||
{
|
||||
int key = event.GetKeyCode();
|
||||
|
||||
switch( key )
|
||||
{
|
||||
case WXK_LEFT:
|
||||
|
@ -343,16 +353,20 @@ void FOOTPRINTS_LISTBOX::OnChar( wxKeyEvent& event )
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Search for an item name starting by the key code:
|
||||
key = toupper(key);
|
||||
|
||||
for( unsigned ii = 0; ii < m_ActiveFootprintList->GetCount(); ii++ )
|
||||
{
|
||||
wxString text = m_ActiveFootprintList->Item(ii);
|
||||
|
||||
/* search for the start char of the footprint name.
|
||||
* we must skip the line number
|
||||
*/
|
||||
*/
|
||||
text.Trim(false); // Remove leading spaces in line
|
||||
unsigned jj = 0;
|
||||
|
||||
for( ; jj < text.Len(); jj++ )
|
||||
{
|
||||
// skip line number
|
||||
|
@ -367,6 +381,7 @@ void FOOTPRINTS_LISTBOX::OnChar( wxKeyEvent& event )
|
|||
}
|
||||
|
||||
int start_char = toupper( text[jj] );
|
||||
|
||||
if( key == start_char )
|
||||
{
|
||||
Focus( ii );
|
||||
|
|
|
@ -334,7 +334,7 @@ void CVPCB_MAINFRAME::ToFirstNA( wxCommandEvent& event )
|
|||
int ii = 0;
|
||||
int selection;
|
||||
|
||||
if( m_components.empty() )
|
||||
if( m_netlist.IsEmpty() )
|
||||
return;
|
||||
|
||||
selection = m_ListCmp->GetSelection();
|
||||
|
@ -342,9 +342,9 @@ void CVPCB_MAINFRAME::ToFirstNA( wxCommandEvent& event )
|
|||
if( selection < 0 )
|
||||
selection = 0;
|
||||
|
||||
BOOST_FOREACH( COMPONENT_INFO & component, m_components )
|
||||
for( unsigned jj = 0; jj < m_netlist.GetCount(); jj++ )
|
||||
{
|
||||
if( component.m_Footprint.IsEmpty() && ii > selection )
|
||||
if( m_netlist.GetComponent( jj )->GetFootprintLibName().IsEmpty() && ii > selection )
|
||||
{
|
||||
m_ListCmp->SetSelection( ii );
|
||||
SendMessageToEESCHEMA();
|
||||
|
@ -363,7 +363,7 @@ void CVPCB_MAINFRAME::ToPreviousNA( wxCommandEvent& event )
|
|||
int ii;
|
||||
int selection;
|
||||
|
||||
if( m_components.empty() )
|
||||
if( m_netlist.IsEmpty() )
|
||||
return;
|
||||
|
||||
ii = m_ListCmp->GetCount() - 1;
|
||||
|
@ -372,9 +372,9 @@ void CVPCB_MAINFRAME::ToPreviousNA( wxCommandEvent& event )
|
|||
if( selection < 0 )
|
||||
selection = m_ListCmp->GetCount() - 1;
|
||||
|
||||
BOOST_REVERSE_FOREACH( COMPONENT_INFO & component, m_components )
|
||||
for( unsigned kk = m_netlist.GetCount() - 1; kk >= 0; kk-- )
|
||||
{
|
||||
if( component.m_Footprint.IsEmpty() && ii < selection )
|
||||
if( m_netlist.GetComponent( kk )->GetFootprintLibName().IsEmpty() && ii < selection )
|
||||
{
|
||||
m_ListCmp->SetSelection( ii );
|
||||
SendMessageToEESCHEMA();
|
||||
|
@ -412,15 +412,15 @@ void CVPCB_MAINFRAME::DelAssociations( wxCommandEvent& event )
|
|||
m_skipComponentSelect = true;
|
||||
m_ListCmp->SetSelection( 0 );
|
||||
|
||||
BOOST_FOREACH( COMPONENT_INFO & component, m_components )
|
||||
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||
{
|
||||
component.m_Footprint.Empty();
|
||||
m_netlist.GetComponent( i )->SetFootprintLibName( wxEmptyString );
|
||||
SetNewPkg( wxEmptyString );
|
||||
}
|
||||
|
||||
m_skipComponentSelect = false;
|
||||
m_ListCmp->SetSelection( 0 );
|
||||
m_undefinedComponentCnt = m_components.size();
|
||||
m_undefinedComponentCnt = m_netlist.GetCount();
|
||||
}
|
||||
|
||||
DisplayStatus();
|
||||
|
@ -538,18 +538,18 @@ void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
|
|||
|
||||
else
|
||||
{
|
||||
if( &m_components[ selection ] == NULL )
|
||||
if( m_netlist.GetComponent( selection ) == NULL )
|
||||
m_FootprintList->SetActiveFootprintList( SELECT_FULL_LIST, REDRAW_LIST );
|
||||
else
|
||||
{
|
||||
if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST ) )
|
||||
{
|
||||
m_FootprintList->SetFootprintFilteredByPinCount( &m_components[ selection ],
|
||||
m_FootprintList->SetFootprintFilteredByPinCount( m_netlist.GetComponent( selection ),
|
||||
m_footprints );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FootprintList->SetFootprintFilteredList( &m_components[ selection ],
|
||||
m_FootprintList->SetFootprintFilteredList( m_netlist.GetComponent( selection ),
|
||||
m_footprints );
|
||||
}
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
|
|||
|
||||
if( FindFocus() == m_ListCmp )
|
||||
{
|
||||
wxString module = *(&m_components[ selection ].m_Footprint);
|
||||
wxString module = m_netlist.GetComponent( selection )->GetFootprintLibName();
|
||||
|
||||
bool found = false;
|
||||
for( int ii = 0; ii < m_FootprintList->GetCount(); ii++ )
|
||||
|
@ -642,7 +642,8 @@ void CVPCB_MAINFRAME::DisplayStatus()
|
|||
{
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "Components: %d (free: %d)" ), (int) m_components.size(), m_undefinedComponentCnt );
|
||||
msg.Printf( _( "Components: %d (free: %d)" ), (int) m_netlist.GetCount(),
|
||||
m_undefinedComponentCnt );
|
||||
SetStatusText( msg, 0 );
|
||||
|
||||
SetStatusText( wxEmptyString, 1 );
|
||||
|
@ -733,9 +734,9 @@ void CVPCB_MAINFRAME::SendMessageToEESCHEMA()
|
|||
{
|
||||
char cmd[1024];
|
||||
int selection;
|
||||
COMPONENT_INFO* Component;
|
||||
COMPONENT* Component;
|
||||
|
||||
if( m_components.empty() )
|
||||
if( m_netlist.IsEmpty() )
|
||||
return;
|
||||
|
||||
selection = m_ListCmp->GetSelection();
|
||||
|
@ -743,12 +744,12 @@ void CVPCB_MAINFRAME::SendMessageToEESCHEMA()
|
|||
if ( selection < 0 )
|
||||
selection = 0;
|
||||
|
||||
if( &m_components[ selection ] == NULL )
|
||||
if( m_netlist.GetComponent( selection ) == NULL )
|
||||
return;
|
||||
|
||||
Component = &m_components[ selection ];
|
||||
Component = m_netlist.GetComponent( selection );
|
||||
|
||||
sprintf( cmd, "$PART: \"%s\"", TO_UTF8( Component->m_Reference ) );
|
||||
sprintf( cmd, "$PART: \"%s\"", TO_UTF8( Component->GetReference() ) );
|
||||
|
||||
SendCommand( MSG_TO_SCH, cmd );
|
||||
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
|
||||
#define LISTB_STYLE (wxSUNKEN_BORDER | wxLC_NO_HEADER | wxLC_REPORT | wxLC_VIRTUAL)
|
||||
|
||||
#include <netlist_reader.h>
|
||||
|
||||
typedef boost::ptr_vector< COMPONENT_INFO > COMPONENT_LIST;
|
||||
|
||||
extern const wxString FootprintAliasFileExtension;
|
||||
extern const wxString RetroFileExtension;
|
||||
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2011 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 1992-2012 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 cvpcb_mainframe.h
|
||||
*/
|
||||
|
@ -7,6 +31,7 @@
|
|||
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/filename.h>
|
||||
#include <netlist_reader.h>
|
||||
|
||||
#include <wxBasePcbFrame.h>
|
||||
#include <param_config.h>
|
||||
|
@ -28,19 +53,19 @@ class CVPCB_MAINFRAME : public EDA_BASE_FRAME
|
|||
{
|
||||
public:
|
||||
|
||||
bool m_KeepCvpcbOpen;
|
||||
bool m_KeepCvpcbOpen;
|
||||
FOOTPRINTS_LISTBOX* m_FootprintList;
|
||||
COMPONENTS_LISTBOX* m_ListCmp;
|
||||
DISPLAY_FOOTPRINTS_FRAME* m_DisplayFootprintFrame;
|
||||
wxAuiToolBar* m_mainToolBar;
|
||||
wxFileName m_NetlistFileName;
|
||||
wxAuiToolBar* m_mainToolBar;
|
||||
wxFileName m_NetlistFileName;
|
||||
wxArrayString m_ModuleLibNames;
|
||||
wxArrayString m_AliasLibNames;
|
||||
wxString m_UserLibraryPath;
|
||||
wxString m_NetlistFileExtension;
|
||||
wxString m_DocModulesFileName;
|
||||
FOOTPRINT_LIST m_footprints;
|
||||
COMPONENT_LIST m_components;
|
||||
wxString m_UserLibraryPath;
|
||||
wxString m_NetlistFileExtension;
|
||||
wxString m_DocModulesFileName;
|
||||
FOOTPRINT_LIST m_footprints;
|
||||
NETLIST m_netlist;
|
||||
|
||||
protected:
|
||||
int m_undefinedComponentCnt;
|
||||
|
@ -60,7 +85,7 @@ public:
|
|||
/**
|
||||
* Function OnSelectComponent
|
||||
* Called when clicking on a component in component list window
|
||||
* * Updates the filtered foorprint list, if the filtered list option is selected
|
||||
* * Updates the filtered footprint list, if the filtered list option is selected
|
||||
* * Updates the current selected footprint in footprint list
|
||||
* * Updates the footprint shown in footprint display window (if opened)
|
||||
*/
|
||||
|
@ -141,22 +166,12 @@ public:
|
|||
* file name of the netlist or cmp file.
|
||||
* If aFullFileName is empty, a file name will be asked to the user
|
||||
* @return 0 if an error occurred saving the link file to \a aFullFileName.
|
||||
* -1 if cancelled
|
||||
* -1 if canceled
|
||||
* 1 if OK
|
||||
*/
|
||||
int SaveCmpLinkFile( const wxString& aFullFileName );
|
||||
|
||||
|
||||
/**
|
||||
* Function LoadComponentFile
|
||||
* loads the .cmp link file \a aCmpFileName which stores
|
||||
* the component/footprint association.
|
||||
*
|
||||
* @param aFileName The full filename of .cmp file to load
|
||||
* If empty, a filename will be asked to the user
|
||||
*/
|
||||
bool LoadComponentLinkFile( const wxString& aFileName );
|
||||
|
||||
/**
|
||||
* Function WriteComponentLinkFile
|
||||
* Writes the component footprint link file \a aFullFileName on disk.
|
||||
|
@ -166,16 +181,6 @@ public:
|
|||
*/
|
||||
bool WriteComponentLinkFile( const wxString& aFullFileName );
|
||||
|
||||
/**
|
||||
* Function ReadComponentLinkFile
|
||||
* Reads the component footprint link file \a aFullFileName.
|
||||
*
|
||||
* @param aFile = the opened the opened file to read.
|
||||
* ReadComponentLinkFile will close the file
|
||||
* @return true if OK, false if error.
|
||||
*/
|
||||
bool ReadComponentLinkFile( FILE * aFile );
|
||||
|
||||
/**
|
||||
* Function ReadNetList
|
||||
* reads the netlist (.net) file defined by #m_NetlistFileName.
|
||||
|
|
|
@ -1,6 +1,29 @@
|
|||
/*********************************************************/
|
||||
/* cvstruct.h */
|
||||
/*********************************************************/
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2012 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 cvstruct.h
|
||||
*/
|
||||
|
||||
#ifndef CVSTRUCT_H
|
||||
#define CVSTRUCT_H
|
||||
|
@ -10,6 +33,8 @@
|
|||
|
||||
/* Forward declarations of all top-level window classes. */
|
||||
class CVPCB_MAINFRAME;
|
||||
class COMPONENT;
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* ListBox (base class) to display lists of components or footprints */
|
||||
|
@ -53,10 +78,19 @@ public:
|
|||
void SetString( unsigned linecount, const wxString& text );
|
||||
void AppendLine( const wxString& text );
|
||||
void SetFootprintFullList( FOOTPRINT_LIST& list );
|
||||
void SetFootprintFilteredList( COMPONENT_INFO* Component,
|
||||
FOOTPRINT_LIST& list );
|
||||
void SetFootprintFilteredByPinCount( COMPONENT_INFO* Component,
|
||||
FOOTPRINT_LIST& list );
|
||||
void SetFootprintFilteredList( COMPONENT* aComponent,
|
||||
FOOTPRINT_LIST& aList );
|
||||
void SetFootprintFilteredByPinCount( COMPONENT* aComponent,
|
||||
FOOTPRINT_LIST& aList );
|
||||
|
||||
/**
|
||||
* Set the footprint list. We can have 2 footprint list:
|
||||
* The full footprint list
|
||||
* The filtered footprint list (if the current selected component has a
|
||||
* filter for footprints)
|
||||
* @param FullList true = full footprint list, false = filtered footprint list
|
||||
* @param Redraw = true to redraw the window
|
||||
*/
|
||||
void SetActiveFootprintList( bool FullList, bool Redraw = false );
|
||||
|
||||
wxString GetSelectedFootprint();
|
||||
|
@ -65,6 +99,19 @@ public:
|
|||
// Events functions:
|
||||
void OnLeftClick( wxListEvent& event );
|
||||
void OnLeftDClick( wxListEvent& event );
|
||||
|
||||
/**
|
||||
* Function OnChar
|
||||
* called on a key pressed
|
||||
* Call default handler for some special keys,
|
||||
* and for "ascii" keys, select the first footprint
|
||||
* that the name starts by the letter.
|
||||
* This is the default behavior of a listbox, but because we use
|
||||
* virtual lists, the listbox does not know anything to what is displayed,
|
||||
* we must handle this behavior here.
|
||||
* Furthermore the footprint name is not at the beginning of
|
||||
* displayed lines (the first word is the line number)
|
||||
*/
|
||||
void OnChar( wxKeyEvent& event );
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
@ -78,7 +125,7 @@ class COMPONENTS_LISTBOX : public ITEMS_LISTBOX_BASE
|
|||
{
|
||||
public:
|
||||
wxArrayString m_ComponentList;
|
||||
CVPCB_MAINFRAME* m_Parent;
|
||||
CVPCB_MAINFRAME* m_Parent;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2012 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 listboxes.cpp
|
||||
* @brief Implementation of class for displaying footprint list and component lists.
|
||||
|
@ -67,9 +90,10 @@ CVPCB_MAINFRAME* ITEMS_LISTBOX_BASE::GetParent()
|
|||
*/
|
||||
void CVPCB_MAINFRAME::BuildCmpListBox()
|
||||
{
|
||||
wxString msg;
|
||||
wxSize size( 10, 10 );
|
||||
wxFont guiFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
|
||||
COMPONENT* component;
|
||||
wxString msg;
|
||||
wxSize size( 10, 10 );
|
||||
wxFont guiFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
|
||||
|
||||
if( m_ListCmp == NULL )
|
||||
{
|
||||
|
@ -86,11 +110,14 @@ void CVPCB_MAINFRAME::BuildCmpListBox()
|
|||
|
||||
m_ListCmp->m_ComponentList.Clear();
|
||||
|
||||
BOOST_FOREACH( COMPONENT_INFO & component, m_components ) {
|
||||
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||
{
|
||||
component = m_netlist.GetComponent( i );
|
||||
|
||||
msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1,
|
||||
GetChars(component.m_Reference),
|
||||
GetChars(component.m_Value),
|
||||
GetChars(component.m_Footprint) );
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( component->GetValue() ),
|
||||
GetChars( component->GetFootprintLibName() ) );
|
||||
m_ListCmp->m_ComponentList.Add( msg );
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <pcbstruct.h>
|
||||
#include <class_module.h>
|
||||
#include <class_board.h>
|
||||
|
||||
#include <cvpcb.h>
|
||||
#include <cvpcb_mainframe.h>
|
||||
|
@ -45,9 +46,9 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
|
|||
|
||||
if( !libPath )
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_("PCB foot print library file <%s> could not be found in the default search paths." ),
|
||||
fn.GetFullName().GetData() );
|
||||
wxString msg = wxString::Format( _( "PCB footprint library file <%s> could not "
|
||||
"be found in the default search paths." ),
|
||||
fn.GetFullName().GetData() );
|
||||
|
||||
// @todo we should not be using wxMessageBox directly.
|
||||
wxMessageBox( msg, titleLibLoadError, wxOK | wxICON_ERROR, this );
|
||||
|
@ -58,7 +59,7 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
|
|||
|
||||
if( footprint )
|
||||
{
|
||||
footprint->SetParent( GetBoard() );
|
||||
footprint->SetParent( (EDA_ITEM*) GetBoard() );
|
||||
footprint->SetPosition( wxPoint( 0, 0 ) );
|
||||
return footprint;
|
||||
}
|
||||
|
@ -74,4 +75,3 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
|
|||
DisplayError( this, msg );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ static char HeaderLinkFile[] = { "Cmp-Mod V01" };
|
|||
|
||||
bool CVPCB_MAINFRAME::WriteComponentLinkFile( const wxString& aFullFileName )
|
||||
{
|
||||
COMPONENT* component;
|
||||
FILE* outputFile;
|
||||
wxFileName fn( aFullFileName );
|
||||
wxString Title = wxGetApp().GetTitle() + wxT( " " ) + GetBuildVersion();
|
||||
|
@ -69,13 +70,15 @@ bool CVPCB_MAINFRAME::WriteComponentLinkFile( const wxString& aFullFileName )
|
|||
retval |= fprintf( outputFile, " Created by %s", TO_UTF8( Title ) );
|
||||
retval |= fprintf( outputFile, " date = %s\n", TO_UTF8( DateAndTime() ) );
|
||||
|
||||
BOOST_FOREACH( COMPONENT_INFO& component, m_components )
|
||||
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||
{
|
||||
component = m_netlist.GetComponent( i );
|
||||
retval |= fprintf( outputFile, "\nBeginCmp\n" );
|
||||
retval |= fprintf( outputFile, "TimeStamp = %s;\n", TO_UTF8( component.m_TimeStamp ) );
|
||||
retval |= fprintf( outputFile, "Reference = %s;\n", TO_UTF8( component.m_Reference ) );
|
||||
retval |= fprintf( outputFile, "ValeurCmp = %s;\n", TO_UTF8( component.m_Value ) );
|
||||
retval |= fprintf( outputFile, "IdModule = %s;\n", TO_UTF8( component.m_Footprint ) );
|
||||
retval |= fprintf( outputFile, "TimeStamp = %s;\n", TO_UTF8( component->GetTimeStamp() ) );
|
||||
retval |= fprintf( outputFile, "Reference = %s;\n", TO_UTF8( component->GetReference() ) );
|
||||
retval |= fprintf( outputFile, "ValeurCmp = %s;\n", TO_UTF8( component->GetValue() ) );
|
||||
retval |= fprintf( outputFile, "IdModule = %s;\n",
|
||||
TO_UTF8( component->GetFootprintLibName() ) );
|
||||
retval |= fprintf( outputFile, "EndCmp\n" );
|
||||
}
|
||||
|
||||
|
@ -83,98 +86,3 @@ bool CVPCB_MAINFRAME::WriteComponentLinkFile( const wxString& aFullFileName )
|
|||
fclose( outputFile );
|
||||
return retval >= 0;
|
||||
}
|
||||
|
||||
bool CVPCB_MAINFRAME::ReadComponentLinkFile( FILE * aFile )
|
||||
{
|
||||
wxString timestamp, valeur, ilib, namecmp, msg;
|
||||
bool read_cmp_data = false, eof = false;
|
||||
char Line[1024], * ident, * data;
|
||||
|
||||
// Identification of the type of link file
|
||||
if( fgets( Line, sizeof(Line), aFile ) == 0 ||
|
||||
strnicmp( Line, HeaderLinkFile, 11 ) != 0 )
|
||||
{
|
||||
fclose( aFile );
|
||||
return false;
|
||||
}
|
||||
|
||||
while( !eof && fgets( Line, sizeof(Line), aFile ) != 0 )
|
||||
{
|
||||
if( strnicmp( Line, "EndListe", 8 ) == 0 )
|
||||
break;
|
||||
|
||||
/* Search the beginning of the component description. */
|
||||
if( strnicmp( Line, "BeginCmp", 8 ) != 0 )
|
||||
continue;
|
||||
|
||||
timestamp.Empty();
|
||||
valeur.Empty();
|
||||
ilib.Empty();
|
||||
namecmp.Empty();
|
||||
read_cmp_data = true;
|
||||
|
||||
while( !eof && read_cmp_data )
|
||||
{
|
||||
if( fgets( Line, 1024, aFile ) == 0 )
|
||||
{
|
||||
eof = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if( strnicmp( Line, "EndCmp", 6 ) == 0 )
|
||||
{
|
||||
read_cmp_data = true;
|
||||
break;
|
||||
}
|
||||
|
||||
ident = strtok( Line, "=;\n\r" );
|
||||
data = strtok( NULL, ";\n\r" );
|
||||
|
||||
if( strnicmp( ident, "TimeStamp", 9 ) == 0 )
|
||||
{
|
||||
timestamp = FROM_UTF8( data );
|
||||
timestamp.Trim( true );
|
||||
timestamp.Trim( false );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( strnicmp( ident, "Reference", 9 ) == 0 )
|
||||
{
|
||||
namecmp = FROM_UTF8( data );
|
||||
namecmp.Trim( true );
|
||||
namecmp.Trim( false );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( strnicmp( ident, "ValeurCmp", 9 ) == 0 )
|
||||
{
|
||||
valeur = FROM_UTF8( data );
|
||||
valeur.Trim( true );
|
||||
valeur.Trim( false );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( strnicmp( ident, "IdModule", 8 ) == 0 )
|
||||
{
|
||||
ilib = FROM_UTF8( data );
|
||||
ilib.Trim( true );
|
||||
ilib.Trim( false );
|
||||
continue;
|
||||
}
|
||||
} // End reading one component link block.
|
||||
|
||||
// Search corresponding component info in list and update its parameters.
|
||||
BOOST_FOREACH( COMPONENT_INFO& component, m_components )
|
||||
{
|
||||
if( namecmp != component.m_Reference )
|
||||
continue;
|
||||
|
||||
/* Copy the name of the corresponding module. */
|
||||
component.m_Footprint = ilib;
|
||||
}
|
||||
}
|
||||
|
||||
fclose( aFile );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* Read a nelist type Eeschema (New and Old format)
|
||||
/* Read a netlist type Eeschema (New and Old format)
|
||||
* or OrcadPCB2 and build the component list
|
||||
*/
|
||||
|
||||
|
@ -35,82 +35,56 @@
|
|||
#include <confirm.h>
|
||||
#include <kicad_string.h>
|
||||
#include <macros.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include <cvpcb_mainframe.h>
|
||||
#include <richio.h>
|
||||
|
||||
|
||||
#include <netlist_reader.h>
|
||||
|
||||
// COMPONENT_INFO object list sort function:
|
||||
bool operator < ( const COMPONENT_INFO& item1, const COMPONENT_INFO& item2 )
|
||||
{
|
||||
return StrNumCmp( item1.m_Reference, item2.m_Reference, INT_MAX, true ) < 0;
|
||||
}
|
||||
|
||||
|
||||
int CVPCB_MAINFRAME::ReadSchematicNetlist()
|
||||
{
|
||||
FILE* netfile = wxFopen( m_NetlistFileName.GetFullPath(), wxT( "rt" ) );
|
||||
wxBusyCursor dummy; // Shows an hourglass while loading.
|
||||
NETLIST_READER* netlistReader;
|
||||
wxString msg;
|
||||
wxString compFootprintLinkFileName;
|
||||
wxFileName fn = m_NetlistFileName;
|
||||
|
||||
if( netfile == NULL )
|
||||
// Load the footprint association file if it has already been created.
|
||||
fn.SetExt( ComponentFileExtension );
|
||||
|
||||
if( fn.FileExists() && fn.IsFileReadable() )
|
||||
compFootprintLinkFileName = fn.GetFullPath();
|
||||
|
||||
m_netlist.Clear();
|
||||
|
||||
try
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Could not open file <%>" ),
|
||||
GetChars( m_NetlistFileName.GetFullPath() ) );
|
||||
wxMessageBox( msg );
|
||||
return -1;
|
||||
netlistReader = NETLIST_READER::GetNetlistReader( &m_netlist,
|
||||
m_NetlistFileName.GetFullPath(),
|
||||
compFootprintLinkFileName );
|
||||
std::auto_ptr< NETLIST_READER > nlr( netlistReader );
|
||||
netlistReader->LoadNetlist();
|
||||
}
|
||||
catch( IO_ERROR& ioe )
|
||||
{
|
||||
msg = wxString::Format( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() );
|
||||
wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
|
||||
return 1;
|
||||
}
|
||||
|
||||
NETLIST_READER netList_Reader( NULL, NULL );
|
||||
netList_Reader.m_UseTimeStamp = false;
|
||||
netList_Reader.m_ChangeFootprints = false;
|
||||
netList_Reader.m_UseCmpFile = false;
|
||||
netList_Reader.SetFilesnames( m_NetlistFileName.GetFullPath(), wxEmptyString );
|
||||
|
||||
// True to read footprint filters section: true for CvPcb, false for Pcbnew
|
||||
netList_Reader.ReadLibpartSectionSetOpt( true );
|
||||
|
||||
// on OSX otherwise reloading a file you will see duplicates
|
||||
m_components.clear();
|
||||
|
||||
bool success = netList_Reader.ReadNetList( netfile );
|
||||
if( !success )
|
||||
// We also remove footprint name if it is "$noname" because this is a dummy name,
|
||||
// not the actual name of the footprint.
|
||||
for( unsigned ii = 0; ii < m_netlist.GetCount(); ii++ )
|
||||
{
|
||||
wxMessageBox( _("Netlist read error") );
|
||||
return false;
|
||||
if( m_netlist.GetComponent( ii )->GetFootprintLibName() == wxT( "$noname" ) )
|
||||
m_netlist.GetComponent( ii )->SetFootprintLibName( wxEmptyString );
|
||||
}
|
||||
|
||||
// Now copy footprints info into Cvpcb list:
|
||||
// We also remove footprint name if it is "$noname"
|
||||
// because this is a dummy name,, not an actual name
|
||||
COMPONENT_INFO_LIST& cmpInfo = netList_Reader.GetComponentInfoList();
|
||||
for( unsigned ii = 0; ii < cmpInfo.size(); ii++ )
|
||||
{
|
||||
m_components.push_back( cmpInfo[ii] );
|
||||
if( cmpInfo[ii]->m_Footprint == wxT( "$noname" ) )
|
||||
cmpInfo[ii]->m_Footprint.Empty();
|
||||
}
|
||||
cmpInfo.clear(); // cmpInfo is no more owner of the list.
|
||||
|
||||
// Sort components by reference:
|
||||
sort( m_components.begin(), m_components.end() );
|
||||
|
||||
// Now copy filters in m_components, if netlist type is KICAD
|
||||
// ( when the format is the "old" PCBNEW format, filters are already in
|
||||
// m_component list
|
||||
if( NETLIST_TYPE_KICAD == netList_Reader.GetNetlistType() )
|
||||
{
|
||||
for( unsigned ii = 0; ii < m_components.size(); ii++ )
|
||||
{
|
||||
LIPBART_INFO* libpart = netList_Reader.GetLibpart(m_components[ii].m_Libpart);
|
||||
if( libpart == NULL )
|
||||
continue;
|
||||
|
||||
// now copy filter list
|
||||
m_components[ii].m_FootprintFilter = libpart->m_FootprintFilter;
|
||||
}
|
||||
}
|
||||
m_netlist.SortByReference();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,17 +41,17 @@
|
|||
|
||||
void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
||||
{
|
||||
COMPONENT_INFO* component;
|
||||
COMPONENT* component;
|
||||
bool hasFootprint = false;
|
||||
int componentIndex;
|
||||
wxString description;
|
||||
|
||||
if( m_components.empty() )
|
||||
if( m_netlist.IsEmpty() )
|
||||
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;
|
||||
m_ListCmp->SetSelection( componentIndex, true );
|
||||
|
@ -61,28 +61,28 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
|||
|
||||
while( m_ListCmp->GetFirstSelected() != -1)
|
||||
{
|
||||
// get the component for the current iteration
|
||||
// Get the component for the current iteration
|
||||
|
||||
componentIndex = m_ListCmp->GetFirstSelected();
|
||||
component = &m_components[componentIndex];
|
||||
component = m_netlist.GetComponent( componentIndex );
|
||||
|
||||
if( component == NULL )
|
||||
return;
|
||||
|
||||
// check to see if the component has allready a footprint set.
|
||||
// Check to see if the component has already a footprint set.
|
||||
|
||||
hasFootprint = !(component->m_Footprint.IsEmpty());
|
||||
hasFootprint = !(component->GetFootprintLibName().IsEmpty());
|
||||
|
||||
component->m_Footprint = aFootprintName;
|
||||
component->SetFootprintLibName( aFootprintName );
|
||||
|
||||
// create the new component description
|
||||
|
||||
description.Printf( CMP_FORMAT, componentIndex + 1,
|
||||
GetChars( component->m_Reference ),
|
||||
GetChars( component->m_Value ),
|
||||
GetChars( component->m_Footprint ) );
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( component->GetValue() ),
|
||||
GetChars( component->GetFootprintLibName() ) );
|
||||
|
||||
// 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
|
||||
// a footprint assigned.
|
||||
|
||||
|
@ -92,12 +92,12 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
|||
m_undefinedComponentCnt -= 1;
|
||||
}
|
||||
|
||||
// set the new description and deselect the processed component
|
||||
// Set the new description and deselect the processed component
|
||||
m_ListCmp->SetString( componentIndex, description );
|
||||
m_ListCmp->SetSelection( componentIndex, false );
|
||||
}
|
||||
|
||||
// mark this "session" as modified
|
||||
// Mark this "session" as modified
|
||||
m_modified = true;
|
||||
|
||||
// select the next component, if there is one
|
||||
|
@ -113,22 +113,10 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
|||
|
||||
bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
|
||||
{
|
||||
COMPONENT* component;
|
||||
wxString msg;
|
||||
int error_level;
|
||||
|
||||
error_level = ReadSchematicNetlist();
|
||||
|
||||
if( error_level < 0 )
|
||||
{
|
||||
msg.Printf( _( "File <%s> does not appear to be a valid KiCad net list file." ),
|
||||
GetChars( m_NetlistFileName.GetFullPath() ) );
|
||||
wxMessageBox( msg, _( "File Error" ), wxOK | wxICON_ERROR, this );
|
||||
m_NetlistFileName.Clear();
|
||||
UpdateTitle();
|
||||
return false;
|
||||
}
|
||||
|
||||
LoadComponentLinkFile( m_NetlistFileName.GetFullPath() );
|
||||
ReadSchematicNetlist();
|
||||
|
||||
if( m_ListCmp == NULL )
|
||||
return false;
|
||||
|
@ -140,19 +128,21 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
|
|||
m_ListCmp->Clear();
|
||||
m_undefinedComponentCnt = 0;
|
||||
|
||||
BOOST_FOREACH( COMPONENT_INFO& component, m_components )
|
||||
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||
{
|
||||
component = m_netlist.GetComponent( i );
|
||||
|
||||
msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1,
|
||||
GetChars( component.m_Reference ),
|
||||
GetChars( component.m_Value ),
|
||||
GetChars( component.m_Footprint ) );
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( component->GetValue() ),
|
||||
GetChars( component->GetFootprintLibName() ) );
|
||||
m_ListCmp->AppendLine( msg );
|
||||
|
||||
if( component.m_Footprint.IsEmpty() )
|
||||
if( component->GetFootprintLibName().IsEmpty() )
|
||||
m_undefinedComponentCnt += 1;
|
||||
}
|
||||
|
||||
if( !m_components.empty() )
|
||||
if( !m_netlist.IsEmpty() )
|
||||
m_ListCmp->SetSelection( 0, true );
|
||||
|
||||
DisplayStatus();
|
||||
|
@ -165,37 +155,6 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
|
|||
}
|
||||
|
||||
|
||||
bool CVPCB_MAINFRAME::LoadComponentLinkFile( const wxString& aFileName )
|
||||
{
|
||||
FILE* linkfile;
|
||||
wxFileName fn = aFileName;
|
||||
|
||||
fn.SetExt( ComponentFileExtension );
|
||||
|
||||
linkfile = wxFopen( fn.GetFullPath(), wxT( "rt" ) );
|
||||
if( linkfile == NULL )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Cannot open CvPcb component file <%s>." ),
|
||||
GetChars( fn.GetFullPath() ) );
|
||||
msg << wxT( "\n" ) << _( "This is normal if you are opening a new netlist file" );
|
||||
wxMessageBox( msg, titleComponentLibErr, wxOK | wxICON_ERROR );
|
||||
return false;
|
||||
}
|
||||
|
||||
// read and close the file
|
||||
if( ! ReadComponentLinkFile( linkfile ) )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( " <%s> does not appear to be a valid KiCad component link file." ),
|
||||
GetChars( fn.GetFullPath() ) );
|
||||
wxMessageBox( msg, titleComponentLibErr, wxOK | wxICON_ERROR );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
|
||||
{
|
||||
wxFileName fn;
|
||||
|
@ -207,7 +166,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
|
|||
}
|
||||
else
|
||||
{
|
||||
wxFileDialog dlg( this, _( "Save Component/Footprint Link File" ), wxGetCwd(),
|
||||
wxFileDialog dlg( this, _( "Save Component Footprint Link File" ), wxGetCwd(),
|
||||
wxEmptyString, ComponentFileWildcard, wxFD_SAVE );
|
||||
|
||||
if( dlg.ShowModal() == wxID_CANCEL )
|
||||
|
@ -224,7 +183,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
|
|||
|
||||
if( WriteComponentLinkFile( fn.GetFullPath() ) == 0 )
|
||||
{
|
||||
DisplayError( this, _( "Unable to create component file (.cmp)" ) );
|
||||
DisplayError( this, _( "Unable to create component footprint link file (.cmp)" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ void CMP_LIBRARY::GetEntryNames( wxArrayString& aNames, bool aSort, bool aMakeUp
|
|||
* simple function used as comparator to sort a std::vector<wxArrayString>&.
|
||||
*
|
||||
* @param aItem1 is the first comparison parameter.
|
||||
* @param aItem1 is the second.
|
||||
* @param aItem2 is the second.
|
||||
* @return bool - which item should be put first in the sorted list.
|
||||
*/
|
||||
bool sortFunction( wxArrayString aItem1, wxArrayString aItem2 )
|
||||
|
|
|
@ -259,7 +259,7 @@ public:
|
|||
* true.
|
||||
* @param aList = array of PARAM_CFG_BASE pointers
|
||||
*/
|
||||
void SaveCurrentSetupValues( const PARAM_CFG_ARRAY& List );
|
||||
void SaveCurrentSetupValues( const PARAM_CFG_ARRAY& aList );
|
||||
|
||||
/**
|
||||
* Function ReadCurrentSetupValues
|
||||
|
@ -268,7 +268,7 @@ public:
|
|||
* true.
|
||||
* @param aList = array of PARAM_CFG_BASE pointers
|
||||
*/
|
||||
void ReadCurrentSetupValues( const PARAM_CFG_ARRAY& List );
|
||||
void ReadCurrentSetupValues( const PARAM_CFG_ARRAY& aList );
|
||||
|
||||
/**
|
||||
* Function ReadProjectConfig
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 1992-2012 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 dialog_helpers.h
|
||||
* @brief Helper dialog and control classes.
|
||||
|
@ -38,6 +62,7 @@ public:
|
|||
* Constructor:
|
||||
* @param aParent Pointer to the parent window.
|
||||
* @param aTitle = The title shown on top.
|
||||
* @param aItemHeaders is an array containing the column header names for the dialog.
|
||||
* @param aItemList = A wxArrayString of the list of elements.
|
||||
* @param aRefText = An item name if an item must be preselected.
|
||||
* @param aCallBackFunction = callback function to display comments
|
||||
|
|
|
@ -133,8 +133,31 @@ public:
|
|||
const std::string& aRevision )
|
||||
throw( PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function clear
|
||||
* clears the contents of the library nickname, footprint name, and revision strings.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Function empty
|
||||
* @return a boolean true value if the FPID is empty. Otherwise return false.
|
||||
*/
|
||||
bool empty() const { return nickname.empty() && footprint.empty() && revision.empty(); }
|
||||
|
||||
/**
|
||||
* Function Compare
|
||||
* compares the contents of FPID objects by performing a std::string comparison of the
|
||||
* library nickname, footprint name, and revision strings respectively.
|
||||
*
|
||||
* @param aFPID is the FPID to compare against.
|
||||
* @return -1 if less than \a aFPID, 1 if greater than \a aFPID, and 0 if equal to \a aFPID.
|
||||
*/
|
||||
int compare( const FPID& aFPID ) const;
|
||||
|
||||
bool operator <( const FPID& aFPID ) const { return this->compare( aFPID ) < 0; }
|
||||
bool operator ==( const FPID& aFPID ) const { return this->compare( aFPID ) == 0; }
|
||||
|
||||
#if defined(DEBUG)
|
||||
static void Test();
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
#ifndef _REPORTER_H_
|
||||
#define _REPORTER_H_
|
||||
|
||||
/**
|
||||
* @file reporter.h
|
||||
* @author Wayne Stambaugh
|
||||
* @note A special thanks to Dick Hollenbeck who came up with the idea that inspired
|
||||
* me to write this.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 1992-2013 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
|
||||
*/
|
||||
|
||||
|
||||
class wxString;
|
||||
class wxTextCtrl;
|
||||
|
||||
|
||||
/**
|
||||
* Class REPORTER
|
||||
* is a pure virtual class used to derive REPORTOR objects from.
|
||||
*
|
||||
* The purpose of the REPORTER object is to hide an object that take a string as an input
|
||||
* from other objects. This prevents objects such as wxWidgets UI control internals from
|
||||
* being exposed to low level KiCad objects dervice from #BOARD_ITEM and #SCH_ITEM.
|
||||
*/
|
||||
class REPORTER
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Function Report
|
||||
* is a pure virtual function to override in the derived object.
|
||||
*
|
||||
* @param aText is the string to report.
|
||||
*/
|
||||
virtual REPORTER& Report( const wxString& aText ) = 0;
|
||||
|
||||
REPORTER& Report( const char *aText );
|
||||
|
||||
REPORTER& operator <<( const wxString& aText ) { return Report( aText ); }
|
||||
|
||||
REPORTER& operator <<( const wxChar* aText ) { return Report( wxString( aText ) ); }
|
||||
|
||||
REPORTER& operator <<( wxChar aChar ) { return Report( wxString( aChar ) ); }
|
||||
|
||||
REPORTER& operator <<( const char* aText ) { return Report( aText ); }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class WX_TEXT_CTRL_REPORTER
|
||||
* is wrapper for reporting to a wxTextCtrl object.
|
||||
*/
|
||||
class WX_TEXT_CTRL_REPORTER : public REPORTER
|
||||
{
|
||||
wxTextCtrl* m_textCtrl;
|
||||
|
||||
public:
|
||||
WX_TEXT_CTRL_REPORTER( wxTextCtrl* aTextCtrl ) :
|
||||
REPORTER(),
|
||||
m_textCtrl( aTextCtrl )
|
||||
{
|
||||
}
|
||||
|
||||
REPORTER& Report( const wxString& aText );
|
||||
};
|
||||
|
||||
#endif // _REPORTER_H_
|
|
@ -98,6 +98,7 @@ extern const wxString KiCadFootprintLibFileWildcard;
|
|||
extern const wxString KiCadFootprintLibPathWildcard;
|
||||
extern const wxString GedaPcbFootprintLibFileWildcard;
|
||||
extern const wxString EagleFootprintLibPathWildcard;
|
||||
extern const wxString TextWildcard;
|
||||
|
||||
|
||||
#endif // INCLUDE_WILDCARDS_AND_FILES_EXT_H_
|
||||
|
|
|
@ -91,6 +91,19 @@ protected:
|
|||
void updateZoomSelectBox();
|
||||
virtual void unitsChangeRefresh();
|
||||
|
||||
/**
|
||||
* Function loadFootprint
|
||||
* attempts to load \a aFootprintName from the list of libraries.
|
||||
*
|
||||
* @param aFootprintName is the name of component footprint to load.
|
||||
* @return the #MODULE if found or NULL if \a aFootprintName not found in any of the
|
||||
* libraries.
|
||||
* @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error
|
||||
* occurs while reading footprint library files.
|
||||
*/
|
||||
MODULE* loadFootprint( const wxString& aFootprintName )
|
||||
throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
public:
|
||||
PCB_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
|
||||
const wxString& aTitle,
|
||||
|
|
|
@ -59,6 +59,10 @@ class PCB_LAYER_WIDGET;
|
|||
class MARKER_PCB;
|
||||
class BOARD_ITEM;
|
||||
class PCB_LAYER_BOX_SELECTOR;
|
||||
class NETLIST;
|
||||
class REPORTER;
|
||||
class PARSE_ERROR;
|
||||
class IO_ERROR;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -80,6 +84,18 @@ class PCB_EDIT_FRAME : public PCB_BASE_FRAME
|
|||
/// The auxiliary right vertical tool bar used to access the microwave tools.
|
||||
wxAuiToolBar* m_microWaveToolBar;
|
||||
|
||||
/**
|
||||
* Function loadFootprints
|
||||
* loads the footprints for each #COMPONENT in \a aNetlist from the list of libraries.
|
||||
*
|
||||
* @param aNetlist is the netlist of components to load the footprints into.
|
||||
* @param aReporter is the #REPORTER object to report to.
|
||||
* @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error
|
||||
* occurs while reading footprint library files.
|
||||
*/
|
||||
void loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
|
||||
throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
protected:
|
||||
|
||||
#ifdef KICAD_SCRIPTING_WXPYTHON
|
||||
|
@ -414,27 +430,6 @@ public:
|
|||
m_useCmpFileForFpNames = aUseCmpfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 aFilename = the full filename netlist
|
||||
* @param aDuplicate = the list of duplicate modules to populate
|
||||
* @param aMissing = the list of missing module references and values
|
||||
* to populate. For each missing item, the first string is the ref,
|
||||
* the second is the value.
|
||||
* @param aNotInNetlist = the list of not-in-netlist modules to populate
|
||||
* @return true if the netlist was read, or false
|
||||
*/
|
||||
bool Test_Duplicate_Missing_And_Extra_Footprints( const wxString& aFilename,
|
||||
std::vector <MODULE*>& aDuplicate,
|
||||
wxArrayString& aMissing,
|
||||
std::vector <MODULE*>& aNotInNetlist );
|
||||
|
||||
/**
|
||||
* Function OnHotKey.
|
||||
* ** Commands are case insensitive **
|
||||
|
@ -960,6 +955,11 @@ public:
|
|||
*/
|
||||
void Access_to_External_Tool( wxCommandEvent& event );
|
||||
|
||||
/**
|
||||
* Function ListAndSelectModuleName
|
||||
* builds and shows a list of existing modules on board that the user can select.
|
||||
* @return a pointer to the selected module or NULL.
|
||||
*/
|
||||
MODULE* ListAndSelectModuleName();
|
||||
|
||||
/**
|
||||
|
@ -1421,29 +1421,31 @@ public:
|
|||
|
||||
/**
|
||||
* Function ReadPcbNetlist
|
||||
* Update footprints (load missing footprints and delete on demand extra
|
||||
* footprints)
|
||||
* reads \a aNetlistFileName and ppdates the footprints (load missing footprints and
|
||||
* delete on demand extra footprints) on the board.
|
||||
* Update connectivity info, references, values and "TIME STAMP"
|
||||
* @param aNetlistFullFilename = netlist file name (*.net)
|
||||
* @param aCmpFullFileName = cmp/footprint link file name (*.cmp).
|
||||
* if not found or empty, only the netlist will be used
|
||||
* @param aMessageWindow = a reference to a wxTextCtrl where to display messages.
|
||||
* can be NULL
|
||||
*
|
||||
* @param aNetlistFileName = netlist file name (*.net)
|
||||
* @param aCmpFileName = cmp/footprint link file name (*.cmp).
|
||||
* if not found or empty, only the netlist will be used
|
||||
* @param aReporter is a pointer to a #REPORTER object to write display messages.
|
||||
* can be NULL.
|
||||
* @param aChangeFootprint if true, footprints that have changed in netlist will be changed
|
||||
* @param aDeleteBadTracks if true, erroneous tracks will be deleted
|
||||
* @param aDeleteExtraFootprints if true, remove unlocked footprints that are not in netlist
|
||||
* @param aSelect_By_Timestamp if true, use timestamp instead of reference to identify
|
||||
* footprints from components (use after reannotation of the
|
||||
* schematic)
|
||||
* @return true if Ok
|
||||
* @param aSelectByTimestamp if true, use timestamp instead of reference to identify
|
||||
* footprints from components (use after reannotation of the
|
||||
* schematic)
|
||||
* @param aIsDryRun performs a dry run without making any changes if true.
|
||||
*/
|
||||
bool ReadPcbNetlist( const wxString& aNetlistFullFilename,
|
||||
const wxString& aCmpFullFileName,
|
||||
wxTextCtrl* aMessageWindow,
|
||||
void ReadPcbNetlist( const wxString& aNetlistFileName,
|
||||
const wxString& aCmpFileName,
|
||||
REPORTER* aReporter,
|
||||
bool aChangeFootprint,
|
||||
bool aDeleteBadTracks,
|
||||
bool aDeleteExtraFootprints,
|
||||
bool aSelect_By_Timestamp );
|
||||
bool aSelectByTimestamp,
|
||||
bool aIsDryRun );
|
||||
|
||||
/**
|
||||
* Function RemoveMisConnectedTracks
|
||||
|
@ -1480,8 +1482,7 @@ public:
|
|||
* @param include_fixe = true to orient locked footprints
|
||||
* @return true if some footprints modified, false if no change
|
||||
*/
|
||||
bool ReOrientModules( const wxString& ModuleMask, int Orient,
|
||||
bool include_fixe );
|
||||
bool ReOrientModules( const wxString& ModuleMask, int Orient, bool include_fixe );
|
||||
void LockModule( MODULE* aModule, bool aLocked );
|
||||
void AutoMoveModulesOnPcb( bool PlaceModulesHorsPcb );
|
||||
|
||||
|
|
|
@ -181,9 +181,6 @@ set(PCBNEW_CLASS_SRCS
|
|||
muonde.cpp
|
||||
muwave_command.cpp
|
||||
netlist.cpp
|
||||
netlist_reader_common.cpp
|
||||
netlist_reader_firstformat.cpp
|
||||
netlist_reader_kicad.cpp
|
||||
onleftclick.cpp
|
||||
onrightclick.cpp
|
||||
pad_edition_functions.cpp
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include <pcbcommon.h>
|
||||
#include <wxBasePcbFrame.h>
|
||||
#include <msgpanel.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <reporter.h>
|
||||
|
||||
#include <pcbnew.h>
|
||||
#include <colors_selection.h>
|
||||
|
@ -1411,6 +1413,26 @@ MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const
|
|||
}
|
||||
|
||||
|
||||
MODULE* BOARD::FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp )
|
||||
{
|
||||
for( MODULE* module = m_Modules; module != NULL; module = module->Next() )
|
||||
{
|
||||
if( aSearchByTimeStamp )
|
||||
{
|
||||
if( aRefOrTimeStamp.CmpNoCase( module->GetPath() ) == 0 )
|
||||
return module;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aRefOrTimeStamp.CmpNoCase( module->GetReference() ) == 0 )
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Sort nets by decreasing pad count
|
||||
static bool s_SortByNodes( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
|
||||
{
|
||||
|
@ -2310,6 +2332,251 @@ bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAI
|
|||
}
|
||||
|
||||
|
||||
void BOARD::ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter )
|
||||
{
|
||||
unsigned i;
|
||||
wxPoint bestPosition;
|
||||
wxString msg;
|
||||
D_PAD* pad;
|
||||
MODULE* footprint;
|
||||
COMPONENT* component;
|
||||
COMPONENT_NET net;
|
||||
|
||||
if( !IsEmpty() )
|
||||
{
|
||||
// Position new components below any existing board features.
|
||||
EDA_RECT bbbox = ComputeBoundingBox( true );
|
||||
|
||||
if( bbbox.GetWidth() || bbbox.GetHeight() )
|
||||
{
|
||||
bestPosition.x = bbbox.Centre().x;
|
||||
bestPosition.y = bbbox.GetBottom() + DMils2iu( 5000 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Position new components in the center of the page when the board is empty.
|
||||
wxSize pageSize = m_paper.GetSizeIU();
|
||||
|
||||
bestPosition.x = pageSize.GetWidth() / 2;
|
||||
bestPosition.y = pageSize.GetHeight() / 2;
|
||||
}
|
||||
|
||||
m_Status_Pcb = 0;
|
||||
|
||||
for( i = 0; i < aNetlist.GetCount(); i++ )
|
||||
{
|
||||
component = aNetlist.GetComponent( i );
|
||||
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Checking netlist component footprint \"%s:%s:%s\".\n" ),
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( component->GetTimeStamp() ),
|
||||
GetChars( component->GetFootprintLibName() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
if( aNetlist.IsFindByTimeStamp() )
|
||||
footprint = FindModule( aNetlist.GetComponent( i )->GetTimeStamp(), true );
|
||||
else
|
||||
footprint = FindModule( aNetlist.GetComponent( i )->GetReference() );
|
||||
|
||||
if( footprint == NULL ) // A new footprint.
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Adding new component \"%s:%s\" footprint \"%s\".\n" ),
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( component->GetTimeStamp() ),
|
||||
GetChars( component->GetFootprintLibName() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
// Owned by NETLIST, can only copy and read it.
|
||||
footprint = component->GetModule();
|
||||
|
||||
wxCHECK2_MSG( footprint != NULL, continue,
|
||||
wxString::Format( wxT( "No footprint loaded for component \"%s\"." ),
|
||||
GetChars( component->GetReference() ) ) );
|
||||
|
||||
if( !aNetlist.IsDryRun() )
|
||||
{
|
||||
footprint = new MODULE( *footprint );
|
||||
footprint->SetParent( this );
|
||||
footprint->SetPosition( bestPosition );
|
||||
footprint->SetTimeStamp( GetNewTimeStamp() );
|
||||
Add( footprint, ADD_APPEND );
|
||||
}
|
||||
}
|
||||
else // An existing footprint.
|
||||
{
|
||||
// Test for footprint change.
|
||||
if( !component->GetFootprintLibName().IsEmpty() &&
|
||||
footprint->GetLibRef() != component->GetFootprintLibName() )
|
||||
{
|
||||
if( aNetlist.GetReplaceFootprints() )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Replacing component \"%s:%s\" footprint \"%s\" with \"%s\".\n" ),
|
||||
GetChars( footprint->GetReference() ),
|
||||
GetChars( footprint->GetPath() ),
|
||||
GetChars( footprint->GetLibRef() ),
|
||||
GetChars( component->GetFootprintLibName() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
if( !aNetlist.IsDryRun() )
|
||||
{
|
||||
wxASSERT( footprint != NULL );
|
||||
MODULE* newFootprint = new MODULE( *component->GetModule() );
|
||||
|
||||
if( aNetlist.IsFindByTimeStamp() )
|
||||
newFootprint->SetReference( footprint->GetReference() );
|
||||
else
|
||||
newFootprint->SetPath( footprint->GetPath() );
|
||||
|
||||
footprint->CopyNetlistSettings( newFootprint );
|
||||
Remove( footprint );
|
||||
Add( newFootprint, ADD_APPEND );
|
||||
footprint = newFootprint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test for reference designator field change.
|
||||
if( footprint->GetReference() != component->GetReference() )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Changing footprint \"%s:%s\" reference to \"%s\".\n" ),
|
||||
GetChars( footprint->GetReference() ),
|
||||
GetChars( footprint->GetPath() ),
|
||||
GetChars( component->GetReference() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
if( !aNetlist.IsDryRun() )
|
||||
footprint->SetReference( component->GetReference() );
|
||||
}
|
||||
|
||||
// Test for value field change.
|
||||
if( footprint->GetValue() != component->GetValue() )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Changing footprint \"%s:%s\" value from \"%s\" to \"%s\".\n" ),
|
||||
GetChars( footprint->GetReference() ),
|
||||
GetChars( footprint->GetPath() ),
|
||||
GetChars( footprint->GetValue() ),
|
||||
GetChars( component->GetValue() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
if( !aNetlist.IsDryRun() )
|
||||
footprint->SetValue( component->GetValue() );
|
||||
}
|
||||
|
||||
// Test for time stamp change.
|
||||
if( footprint->GetPath() != component->GetTimeStamp() )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Changing footprint path \"%s:%s\" to \"%s\".\n" ),
|
||||
GetChars( footprint->GetReference() ),
|
||||
GetChars( footprint->GetPath() ),
|
||||
GetChars( component->GetTimeStamp() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
if( !aNetlist.IsDryRun() )
|
||||
footprint->SetPath( component->GetTimeStamp() );
|
||||
}
|
||||
}
|
||||
|
||||
wxASSERT( component != NULL );
|
||||
|
||||
// At this point, the component footprint is updated. Now update the nets.
|
||||
for( pad = footprint->Pads(); pad; pad = pad->Next() )
|
||||
{
|
||||
net = component->GetNet( pad->GetPadName() );
|
||||
|
||||
if( !net.IsValid() ) // Footprint pad had no net.
|
||||
{
|
||||
if( !pad->GetNetname().IsEmpty() )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Clearing component \"%s:%s\" pin \"%s\" net name.\n" ),
|
||||
GetChars( footprint->GetReference() ),
|
||||
GetChars( footprint->GetPath() ),
|
||||
GetChars( pad->GetPadName() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
if( !aNetlist.IsDryRun() )
|
||||
pad->SetNetname( wxEmptyString );
|
||||
}
|
||||
}
|
||||
else // Footprint pad has a net.
|
||||
{
|
||||
if( net.GetNetName() != pad->GetNetname() )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Changing component \"%s:%s\" pin \"%s\" net name from "
|
||||
"\"%s\" to \"%s\".\n" ),
|
||||
GetChars( footprint->GetReference() ),
|
||||
GetChars( footprint->GetPath() ),
|
||||
GetChars( pad->GetPadName() ),
|
||||
GetChars( pad->GetNetname() ),
|
||||
GetChars( net.GetNetName() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
if( !aNetlist.IsDryRun() )
|
||||
pad->SetNetname( net.GetNetName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all components not in the netlist.
|
||||
if( aNetlist.GetDeleteExtraFootprints() )
|
||||
{
|
||||
MODULE* nextModule;
|
||||
|
||||
for( MODULE* module = m_Modules; module != NULL; module = nextModule )
|
||||
{
|
||||
nextModule = module->Next();
|
||||
|
||||
if( module->IsLocked() )
|
||||
continue;
|
||||
|
||||
if( aNetlist.IsFindByTimeStamp() )
|
||||
component = aNetlist.GetComponentByTimeStamp( module->GetPath() );
|
||||
else
|
||||
component = aNetlist.GetComponentByReference( module->GetReference() );
|
||||
|
||||
if( component == NULL )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Removing footprint \"%s:%s\".\n" ),
|
||||
GetChars( module->GetReference() ),
|
||||
GetChars( module->GetPath() ) );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
|
||||
if( !aNetlist.IsDryRun() )
|
||||
module->DeleteStructure();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
void BOARD::Show( int nestLevel, std::ostream& os ) const
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 1992-2012 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 class_board.h
|
||||
* @brief Class BOARD to handle a board.
|
||||
|
@ -30,6 +54,8 @@ class TRACK;
|
|||
class D_PAD;
|
||||
class MARKER_PCB;
|
||||
class MSG_PANEL_ITEM;
|
||||
class NETLIST;
|
||||
class REPORTER;
|
||||
|
||||
|
||||
// non-owning container of item candidates when searching for items on the same track.
|
||||
|
@ -282,6 +308,12 @@ public:
|
|||
BOARD();
|
||||
~BOARD();
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return m_Drawings.GetCount() == 0 && m_Modules.GetCount() == 0 &&
|
||||
m_Track.GetCount() == 0 && m_Zone.GetCount() == 0;
|
||||
}
|
||||
|
||||
void Move( const wxPoint& aMoveVector ); // overload
|
||||
|
||||
void SetFileFormatVersionAtLoad( int aVersion ) { m_fileFormatVersionAtLoad = aVersion; }
|
||||
|
@ -849,6 +881,47 @@ public:
|
|||
*/
|
||||
MODULE* FindModuleByReference( const wxString& aReference ) const;
|
||||
|
||||
/**
|
||||
* Function FindModule
|
||||
* searches for a module matching \a aRefOrTimeStamp depending on the state of
|
||||
* \a aSearchByTimeStamp.
|
||||
* @param aRefOrTimeStamp is the search string.
|
||||
* @param aSearchByTimeStamp searches by the module time stamp value if true. Otherwise
|
||||
* search by reference designator.
|
||||
* @return the module found or NULL if not module is found that meets the search criteria.
|
||||
*/
|
||||
MODULE* FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp = false );
|
||||
|
||||
/**
|
||||
* Function ReplaceNetlist
|
||||
* updates the #BOARD according to \a aNetlist.
|
||||
*
|
||||
* The changes are made to the board are as follows they are not disabled in the status
|
||||
* settings in the #NETLIST:
|
||||
* - If a new component is found in the #NETLIST and not in the #BOARD, it is added
|
||||
* to the #BOARD.
|
||||
* - If a the component in the #NETLIST is already on the #BOARD, then one or more of the
|
||||
* following actions can occur:
|
||||
* + If the footprint name in the #NETLIST does not match the footprint name on the
|
||||
* #BOARD, the footprint on the #BOARD is replaced with the footprint specified in
|
||||
* the #NETLIST and the proper parameters are copied from the existing footprint.
|
||||
* + If the reference designator in the #NETLIST does not match the reference designator
|
||||
* on the #BOARD, the reference designator is updated from the #NETLIST.
|
||||
* + If the value field in the #NETLIST does not match the value field on the #BOARD,
|
||||
* the value field is updated from the #NETLIST.
|
||||
* + If the time stamp in the #NETLIST does not match the time stamp on the #BOARD,
|
||||
* the time stamp is updated from the #NETLIST.
|
||||
* - After each footprint is added or update as described above, each footprint pad net
|
||||
* name is compared and updated to the value defined in the #NETLIST.
|
||||
* - After all of the footprints have been added, updated, and net names properly set,
|
||||
* any extra unlock footprints are removed from the #BOARD.
|
||||
*
|
||||
* @param aNetlist is the new netlist to revise the contents of the #BOARD with.
|
||||
* @param aReporter is a #REPORTER object to report the changes \a aNetlist makes to
|
||||
* the #BOARD. If NULL, no change reporting occurs.
|
||||
*/
|
||||
void ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter = NULL );
|
||||
|
||||
/**
|
||||
* Function ReturnSortedNetnamesList
|
||||
* @param aNames An array string to fill with net names.
|
||||
|
@ -1229,12 +1302,12 @@ public:
|
|||
|
||||
/**
|
||||
* Function GetPadFast
|
||||
* return pad found at \a aPosition on \a aLayer using the fast search method.
|
||||
* return pad found at \a aPosition on \a aLayerMask using the fast search method.
|
||||
* <p>
|
||||
* The fast search method only works if the pad list has already been built.
|
||||
* </p>
|
||||
* @param aPosition A wxPoint object containing the position to hit test.
|
||||
* @param aLayer A layer or layers to mask the hit test.
|
||||
* @param aLayerMask A layer or layers to mask the hit test.
|
||||
* @return A pointer to a D_PAD object if found or NULL if not found.
|
||||
*/
|
||||
D_PAD* GetPadFast( const wxPoint& aPosition, LAYER_MSK aLayerMask );
|
||||
|
|
|
@ -290,15 +290,45 @@ void MODULE::Copy( MODULE* aModule )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Draw
|
||||
* Draws the footprint to the current Device Context
|
||||
* @param aPanel = draw panel, Used to know the clip box
|
||||
* @param aDC = Current Device Context
|
||||
* @param aDrawMode = GR_OR, GR_XOR..
|
||||
* @param aOffset = draw offset (usually wxPoint(0,0)
|
||||
*/
|
||||
void MODULE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset )
|
||||
void MODULE::CopyNetlistSettings( MODULE* aModule )
|
||||
{
|
||||
// Don't do anything foolish like trying to copy to yourself.
|
||||
wxCHECK_RET( aModule != NULL && aModule != this, wxT( "Cannot copy to NULL or yourself." ) );
|
||||
|
||||
// Not sure what to do with the value field. Use netlist for now.
|
||||
aModule->SetPosition( GetPosition() );
|
||||
|
||||
if( aModule->GetLayer() != GetLayer() )
|
||||
aModule->Flip( aModule->GetPosition() );
|
||||
|
||||
if( aModule->GetOrientation() != GetOrientation() )
|
||||
aModule->Rotate( aModule->GetPosition(), GetOrientation() );
|
||||
|
||||
aModule->SetLocalSolderMaskMargin( GetLocalSolderMaskMargin() );
|
||||
aModule->SetLocalClearance( GetLocalClearance() );
|
||||
aModule->SetLocalSolderPasteMargin( GetLocalSolderPasteMargin() );
|
||||
aModule->SetLocalSolderPasteMarginRatio( GetLocalSolderPasteMarginRatio() );
|
||||
aModule->SetZoneConnection( GetZoneConnection() );
|
||||
aModule->SetThermalWidth( GetThermalWidth() );
|
||||
aModule->SetThermalGap( GetThermalGap() );
|
||||
|
||||
for( D_PAD* pad = Pads(); pad; pad = pad->Next() )
|
||||
{
|
||||
D_PAD* newPad = aModule->FindPadByName( pad->GetPadName() );
|
||||
|
||||
if( newPad )
|
||||
pad->CopyNetlistSettings( newPad );
|
||||
}
|
||||
|
||||
// Not sure about copying description, keywords, 3D models or any other
|
||||
// local user changes to footprint. Stick with the new footprint settings
|
||||
// called out in the footprint loaded in the netlist.
|
||||
aModule->CalculateBoundingBox();
|
||||
}
|
||||
|
||||
|
||||
void MODULE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
|
||||
const wxPoint& aOffset )
|
||||
{
|
||||
if( (m_Flags & DO_NOT_DRAW) || (IsMoving()) )
|
||||
return;
|
||||
|
@ -354,14 +384,6 @@ void MODULE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode, con
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function DrawEdgesOnly
|
||||
* Draws the footprint edges only to the current Device Context
|
||||
* @param panel = The active Draw Panel (used to know the clip box)
|
||||
* @param DC = current Device Context
|
||||
* @param offset = draw offset (usually wxPoint(0,0)
|
||||
* @param draw_mode = GR_OR, GR_XOR, GR_AND
|
||||
*/
|
||||
void MODULE::DrawEdgesOnly( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
|
||||
GR_DRAWMODE draw_mode )
|
||||
{
|
||||
|
@ -687,6 +709,7 @@ EDA_ITEM* MODULE::Clone() const
|
|||
return new MODULE( *this );
|
||||
}
|
||||
|
||||
|
||||
/* Test for validity of the name in a library of the footprint
|
||||
* ( no spaces, dir separators ... )
|
||||
* return true if the given name is valid
|
||||
|
@ -874,6 +897,7 @@ void MODULE::SetPosition( const wxPoint& newpos )
|
|||
CalculateBoundingBox();
|
||||
}
|
||||
|
||||
|
||||
void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector )
|
||||
{
|
||||
/* Move the reference point of the footprint
|
||||
|
@ -932,6 +956,7 @@ void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector )
|
|||
CalculateBoundingBox();
|
||||
}
|
||||
|
||||
|
||||
void MODULE::SetOrientation( double newangle )
|
||||
{
|
||||
double angleChange = newangle - m_Orient; // change in rotation
|
||||
|
|
|
@ -229,6 +229,14 @@ public:
|
|||
|
||||
/* drawing functions */
|
||||
|
||||
/**
|
||||
* Function Draw
|
||||
* draws the footprint to the \a aDC.
|
||||
* @param aPanel = draw panel, Used to know the clip box
|
||||
* @param aDC = Current Device Context
|
||||
* @param aDrawMode = GR_OR, GR_XOR..
|
||||
* @param aOffset = draw offset (usually wxPoint(0,0)
|
||||
*/
|
||||
void Draw( EDA_DRAW_PANEL* aPanel,
|
||||
wxDC* aDC,
|
||||
GR_DRAWMODE aDrawMode,
|
||||
|
@ -236,6 +244,14 @@ public:
|
|||
|
||||
void Draw3D( EDA_3D_CANVAS* glcanvas );
|
||||
|
||||
/**
|
||||
* Function DrawEdgesOnly
|
||||
* Draws the footprint edges only to the current Device Context
|
||||
* @param panel = The active Draw Panel (used to know the clip box)
|
||||
* @param DC = current Device Context
|
||||
* @param offset = draw offset (usually wxPoint(0,0)
|
||||
* @param draw_mode = GR_OR, GR_XOR, GR_AND
|
||||
*/
|
||||
void DrawEdgesOnly( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
|
||||
GR_DRAWMODE draw_mode );
|
||||
|
||||
|
@ -306,7 +322,7 @@ public:
|
|||
|
||||
/**
|
||||
* Function GetPad
|
||||
* get a pad at \a aPosition on \a aLayer in the footprint.
|
||||
* get a pad at \a aPosition on \a aLayerMask in the footprint.
|
||||
*
|
||||
* @param aPosition A wxPoint object containing the position to hit test.
|
||||
* @param aLayerMask A layer or layers to mask the hit test.
|
||||
|
@ -361,6 +377,19 @@ public:
|
|||
|
||||
EDA_ITEM* Clone() const;
|
||||
|
||||
/**
|
||||
* Function CopyNetlistSettings
|
||||
* copies the netlist settings to \a aModule.
|
||||
*
|
||||
* The netlist settings are all of the #MODULE settings not define by a #MODULE in
|
||||
* a netlist. These setting include position, orientation, local clearances, ets.
|
||||
* The reference designator, value, path, and physical geometry settings are not
|
||||
* copied.
|
||||
*
|
||||
* @param aModule is the #MODULE to copy the settings to.
|
||||
*/
|
||||
void CopyNetlistSettings( MODULE* aModule );
|
||||
|
||||
/**
|
||||
* static function IsLibNameValid
|
||||
* Test for validity of a name of a footprint to be used in a footprint library
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 1992-2012 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 class_netinfo.h
|
||||
*/
|
||||
|
@ -384,6 +408,13 @@ public:
|
|||
*/
|
||||
void SetNetname( const wxString& aNetname );
|
||||
|
||||
/**
|
||||
* Function GetMsgPanelInfo
|
||||
* returns the information about the #NETINFO_ITEM in \a aList to display in the
|
||||
* message panel.
|
||||
*
|
||||
* @param aList is the list in which to place the status information.
|
||||
*/
|
||||
void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
|
||||
};
|
||||
|
||||
|
|
|
@ -99,13 +99,6 @@ void NETINFO_ITEM::Draw( EDA_DRAW_PANEL* panel,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function DisplayInfo
|
||||
* has knowledge about the frame and how and where to put status information
|
||||
* about this object into the frame's message panel.
|
||||
* Is virtual from EDA_ITEM.
|
||||
* @param frame A EDA_DRAW_FRAME in which to print status information.
|
||||
*/
|
||||
void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
|
||||
{
|
||||
int count;
|
||||
|
|
|
@ -301,10 +301,6 @@ void D_PAD::SetPadName( const wxString& name )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function SetNetname
|
||||
* @param aNetname: the new netname
|
||||
*/
|
||||
void D_PAD::SetNetname( const wxString& aNetname )
|
||||
{
|
||||
m_Netname = aNetname;
|
||||
|
@ -348,14 +344,23 @@ void D_PAD::Copy( D_PAD* source )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function GetClearance (virtual)
|
||||
* returns the clearance in internal units. If \a aItem is not NULL then the
|
||||
* returned clearance is the greater of this object's clearance and
|
||||
* aItem's clearance. If \a aItem is NULL, then this object clearance is returned.
|
||||
* @param aItem is another BOARD_CONNECTED_ITEM or NULL
|
||||
* @return int - the clearance in internal units.
|
||||
*/
|
||||
void D_PAD::CopyNetlistSettings( D_PAD* aPad )
|
||||
{
|
||||
// Don't do anything foolish like trying to copy to yourself.
|
||||
wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) );
|
||||
|
||||
aPad->SetNetname( GetNetname() );
|
||||
|
||||
aPad->SetLocalClearance( m_LocalClearance );
|
||||
aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin );
|
||||
aPad->SetLocalSolderPasteMargin( m_LocalSolderPasteMargin );
|
||||
aPad->SetLocalSolderPasteMarginRatio( m_LocalSolderPasteMarginRatio );
|
||||
aPad->SetZoneConnection( m_ZoneConnection );
|
||||
aPad->SetThermalWidth( m_ThermalWidth );
|
||||
aPad->SetThermalGap( m_ThermalGap );
|
||||
}
|
||||
|
||||
|
||||
int D_PAD::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
|
||||
{
|
||||
// A pad can have specific clearance parameters that
|
||||
|
@ -387,15 +392,6 @@ int D_PAD::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
|
|||
|
||||
// Mask margins handling:
|
||||
|
||||
/**
|
||||
* Function GetSolderMaskMargin
|
||||
* @return the margin for the solder mask layer
|
||||
* usually > 0 (mask shape bigger than pad
|
||||
* value is
|
||||
* 1 - the local value
|
||||
* 2 - if null, the parent footprint value
|
||||
* 1 - if null, the global value
|
||||
*/
|
||||
int D_PAD::GetSolderMaskMargin()
|
||||
{
|
||||
int margin = m_LocalSolderMaskMargin;
|
||||
|
@ -429,15 +425,6 @@ int D_PAD::GetSolderMaskMargin()
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function GetSolderPasteMargin
|
||||
* @return the margin for the solder mask layer
|
||||
* usually < 0 (mask shape smaller than pad
|
||||
* value is
|
||||
* 1 - the local value
|
||||
* 2 - if null, the parent footprint value
|
||||
* 3 - if null, the global value
|
||||
*/
|
||||
wxSize D_PAD::GetSolderPasteMargin()
|
||||
{
|
||||
int margin = m_LocalSolderPasteMargin;
|
||||
|
@ -538,7 +525,7 @@ void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList )
|
|||
|
||||
board = GetBoard();
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Layer" ),
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Layer" ),
|
||||
LayerMaskDescribe( board, m_layerMask ), DARKGREEN ) );
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( ShowPadShape(), ShowPadAttr(), DARKGREEN ) );
|
||||
|
@ -754,6 +741,7 @@ wxString D_PAD::GetSelectMenuText() const
|
|||
return text;
|
||||
}
|
||||
|
||||
|
||||
EDA_ITEM* D_PAD::Clone() const
|
||||
{
|
||||
return new D_PAD( *this );
|
||||
|
|
|
@ -395,6 +395,18 @@ public:
|
|||
|
||||
EDA_ITEM* Clone() const;
|
||||
|
||||
/**
|
||||
* Function CopyNetlistSettings
|
||||
* copies the netlist settings to \a aPad.
|
||||
*
|
||||
* The netlist settings are all of the #D_PAD settings not define by a #D_PAD in
|
||||
* a netlist. These setting include local clearances, net names, etc. The pad
|
||||
* physical geometry settings are not copied.
|
||||
*
|
||||
* @param aPad is the #D_PAD to copy the settings to.
|
||||
*/
|
||||
void CopyNetlistSettings( D_PAD* aPad );
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const; // overload
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file dialog_edit_module_text.cpp.
|
||||
* @brief dialog editor for texts (fields) in footprints
|
||||
* @file dialog_edit_module_text.cpp
|
||||
* @brief dialog editor for texts (fields) in footprints.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include <base_units.h>
|
||||
#include <wxPcbStruct.h>
|
||||
#include <pcbcommon.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <reporter.h>
|
||||
|
||||
#include <pcbnew_config.h>
|
||||
#include <class_board_design_settings.h>
|
||||
|
@ -65,20 +67,20 @@ void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC )
|
|||
// Save project settings if needed.
|
||||
// Project settings are saved in the corresponding <board name>.pro file
|
||||
bool configChanged = lastNetlistName != GetLastNetListRead();
|
||||
|
||||
if( dlg.UseCmpFileForFpNames() != GetUseCmpFileForFpNames() )
|
||||
{
|
||||
SetUseCmpFileForFpNames( dlg.UseCmpFileForFpNames() );
|
||||
configChanged = true;
|
||||
}
|
||||
|
||||
if( configChanged &&
|
||||
!GetBoard()->GetFileName().IsEmpty() &&
|
||||
IsOK(NULL, _("Project config has changed. Save it ?") ) )
|
||||
if( configChanged
|
||||
&& !GetBoard()->GetFileName().IsEmpty()
|
||||
&& IsOK( NULL, _( "The project configuration has changed. Do you want to save it?" ) ) )
|
||||
{
|
||||
wxFileName fn = GetBoard()->GetFileName();
|
||||
fn.SetExt( ProjectFileExtension );
|
||||
wxGetApp().WriteProjectConfig( fn.GetFullPath(), GROUP,
|
||||
GetProjectFileParameters() );
|
||||
wxGetApp().WriteProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,20 +128,50 @@ void DIALOG_NETLIST::OnOpenNetlistClick( wxCommandEvent& event )
|
|||
|
||||
void DIALOG_NETLIST::OnReadNetlistFileClick( wxCommandEvent& event )
|
||||
{
|
||||
wxString fullNetfileName = m_NetlistFilenameCtrl->GetValue();
|
||||
wxString cmpFilename;
|
||||
wxString msg;
|
||||
wxString netlistFileName = m_NetlistFilenameCtrl->GetValue();
|
||||
wxString cmpFileName;
|
||||
|
||||
if( UseCmpFileForFpNames() )
|
||||
{
|
||||
wxFileName fn = m_NetlistFilenameCtrl->GetValue();
|
||||
fn.SetExt( ComponentFileExtension );
|
||||
cmpFilename = fn.GetFullPath();
|
||||
cmpFileName = fn.GetFullPath();
|
||||
}
|
||||
|
||||
m_parent->ReadPcbNetlist( fullNetfileName, cmpFilename, m_MessageWindow,
|
||||
m_ChangeExistingFootprintCtrl->GetSelection() == 1 ? true : false,
|
||||
m_DeleteBadTracks->GetSelection() == 1 ? true : false,
|
||||
m_RemoveExtraFootprintsCtrl->GetSelection() == 1 ? true : false,
|
||||
m_Select_By_Timestamp->GetSelection() == 1 ? true : false );
|
||||
// Give the user a chance to bail out when making changes from a netlist.
|
||||
if( !m_parent->GetBoard()->IsEmpty()
|
||||
&& !IsOK( NULL, _( "The changes made by reading the netlist cannot be undone. Are you "
|
||||
"sure you want to read the netlist?" ) ) )
|
||||
return;
|
||||
|
||||
wxBusyCursor busy();
|
||||
m_MessageWindow->Clear();
|
||||
|
||||
msg.Printf( _( "Reading netlist file \"%s\".\n" ), GetChars( netlistFileName ) );
|
||||
m_MessageWindow->AppendText( msg );
|
||||
|
||||
if( !cmpFileName.IsEmpty() )
|
||||
{
|
||||
msg.Printf( _( "Using component footprint link file \"%s\".\n" ), GetChars( cmpFileName ) );
|
||||
m_MessageWindow->AppendText( msg );
|
||||
}
|
||||
|
||||
if( m_Select_By_Timestamp->GetSelection() == 1 )
|
||||
{
|
||||
msg.Printf( _( "Using time stamps to select footprints in file \"%s\".\n" ),
|
||||
GetChars( cmpFileName ) );
|
||||
m_MessageWindow->AppendText( msg );
|
||||
}
|
||||
|
||||
WX_TEXT_CTRL_REPORTER reporter( m_MessageWindow );
|
||||
|
||||
m_parent->ReadPcbNetlist( netlistFileName, cmpFileName, &reporter,
|
||||
m_ChangeExistingFootprintCtrl->GetSelection() == 1,
|
||||
m_DeleteBadTracks->GetSelection() == 1,
|
||||
m_RemoveExtraFootprintsCtrl->GetSelection() == 1,
|
||||
m_Select_By_Timestamp->GetSelection() == 1,
|
||||
m_checkDryRun->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,14 +188,18 @@ void DIALOG_NETLIST::OnTestFootprintsClick( wxCommandEvent& event )
|
|||
wxArrayString missing;
|
||||
std::vector <MODULE*> notInNetlist;
|
||||
wxString netlistFilename = m_NetlistFilenameCtrl->GetValue();
|
||||
wxString cmpFilename;
|
||||
|
||||
if( ! m_parent->Test_Duplicate_Missing_And_Extra_Footprints(
|
||||
netlistFilename, duplicate, missing, notInNetlist ) )
|
||||
if( UseCmpFileForFpNames() )
|
||||
{
|
||||
wxMessageBox( _("Netlist file not found!") );
|
||||
return;
|
||||
wxFileName fn = m_NetlistFilenameCtrl->GetValue();
|
||||
fn.SetExt( ComponentFileExtension );
|
||||
cmpFilename = fn.GetFullPath();
|
||||
}
|
||||
|
||||
if( !verifyFootprints( netlistFilename, cmpFilename, duplicate, missing, notInNetlist ) )
|
||||
return;
|
||||
|
||||
#define ERR_CNT_MAX 100 // Max number of errors to output in dialog
|
||||
// to avoid a too long message list
|
||||
|
||||
|
@ -221,24 +257,24 @@ void DIALOG_NETLIST::OnTestFootprintsClick( wxCommandEvent& event )
|
|||
|
||||
// Search for modules found on board but not in net list.
|
||||
if( notInNetlist.size() == 0 )
|
||||
list << wxT("<p><b>") << _( "No extra modules." ) << wxT("</b></p>");
|
||||
list << wxT( "<p><b>" ) << _( "No extra modules." ) << wxT( "</b></p>" );
|
||||
else
|
||||
{
|
||||
list << wxT("<p><b>") << _( "Not in Netlist:" ) << wxT("</b></p>");
|
||||
list << wxT( "<p><b>" ) << _( "Not in Netlist:" ) << wxT( "</b></p>" );
|
||||
|
||||
for( unsigned ii = 0; ii < notInNetlist.size(); ii++ )
|
||||
{
|
||||
MODULE* module = notInNetlist[ii];
|
||||
|
||||
if( module->GetReference().IsEmpty() )
|
||||
list << wxT("<br>") << wxT("[noref)");
|
||||
list << wxT( "<br>" ) << wxT( "[noref)" );
|
||||
else
|
||||
list << wxT("<br>") << module->GetReference() ;
|
||||
list << wxT( "<br>" ) << module->GetReference() ;
|
||||
|
||||
list << wxT(" (<i>") << module->GetValue() << wxT("</i>)");
|
||||
list << wxT(" @ ");
|
||||
list << wxT( " (<i>" ) << module->GetValue() << wxT( "</i>)" );
|
||||
list << wxT( " @ " );
|
||||
list << CoordinateToString( module->GetPosition().x ),
|
||||
list << wxT(", ") << CoordinateToString( module->GetPosition().y ),
|
||||
list << wxT( ", " ) << CoordinateToString( module->GetPosition().y ),
|
||||
err_cnt++;
|
||||
|
||||
if( ERR_CNT_MAX < err_cnt )
|
||||
|
@ -248,13 +284,13 @@ void DIALOG_NETLIST::OnTestFootprintsClick( wxCommandEvent& event )
|
|||
|
||||
if( ERR_CNT_MAX < err_cnt )
|
||||
{
|
||||
list << wxT("<p><b>")
|
||||
list << wxT( "<p><b>" )
|
||||
<< _( "Too many errors: some are skipped" )
|
||||
<< wxT("</b></p>");
|
||||
<< wxT( "</b></p>" );
|
||||
}
|
||||
|
||||
HTML_MESSAGE_BOX dlg( this, _( "Check Modules" ) );
|
||||
dlg.AddHTML_Text(list);
|
||||
dlg.AddHTML_Text( list );
|
||||
dlg.ShowModal();
|
||||
}
|
||||
|
||||
|
@ -277,3 +313,148 @@ void DIALOG_NETLIST::OnCancelClick( wxCommandEvent& event )
|
|||
{
|
||||
EndModal( wxID_CANCEL );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_NETLIST::OnSaveMessagesToFile( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxFileName fn;
|
||||
|
||||
if( !m_parent->GetLastNetListRead().IsEmpty() )
|
||||
{
|
||||
fn = m_parent->GetLastNetListRead();
|
||||
fn.SetExt( wxT( "txt" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
fn.SetPath( wxFileName::GetCwd() );
|
||||
}
|
||||
|
||||
wxFileDialog dlg( this, _( "Save contents of message window" ), fn.GetPath(), fn.GetName(),
|
||||
TextWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
return;
|
||||
|
||||
fn = dlg.GetPath();
|
||||
|
||||
if( fn.GetExt().IsEmpty() )
|
||||
fn.SetExt( wxT( "txt" ) );
|
||||
|
||||
wxFile f( fn.GetFullPath(), wxFile::write );
|
||||
|
||||
if( !f.IsOpened() )
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "Cannot write message contents to file \"%s\"." ),
|
||||
GetChars( fn.GetFullPath() ) );
|
||||
wxMessageBox( msg, _( "File Write Error" ), wxOK | wxICON_ERROR, this );
|
||||
return;
|
||||
}
|
||||
|
||||
f.Write( m_MessageWindow->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_NETLIST::OnUpdateUISaveMessagesToFile( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
aEvent.Enable( !m_MessageWindow->IsEmpty() );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_NETLIST::OnUpdateUIValidNetlistFile( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
aEvent.Enable( !m_NetlistFilenameCtrl->GetValue().IsEmpty() );
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_NETLIST::verifyFootprints( const wxString& aNetlistFilename,
|
||||
const wxString & aCmpFilename,
|
||||
std::vector< MODULE* >& aDuplicates,
|
||||
wxArrayString& aMissing,
|
||||
std::vector< MODULE* >& aNotInNetlist )
|
||||
{
|
||||
wxString msg;
|
||||
MODULE* module;
|
||||
MODULE* nextModule;
|
||||
NETLIST netlist;
|
||||
wxBusyCursor dummy; // Shows an hourglass while calculating.
|
||||
NETLIST_READER* netlistReader;
|
||||
COMPONENT* component;
|
||||
|
||||
try
|
||||
{
|
||||
netlistReader = NETLIST_READER::GetNetlistReader( &netlist, aNetlistFilename,
|
||||
aCmpFilename );
|
||||
|
||||
if( netlistReader == NULL )
|
||||
{
|
||||
msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFilename ) );
|
||||
wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR );
|
||||
return false;
|
||||
}
|
||||
|
||||
std::auto_ptr< NETLIST_READER > nlr( netlistReader );
|
||||
netlistReader->LoadNetlist();
|
||||
}
|
||||
catch( IO_ERROR& ioe )
|
||||
{
|
||||
msg.Printf( _( "Error loading netlist file:\n%s" ), ioe.errorText.GetData() );
|
||||
wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#if defined( DEBUG )
|
||||
m_MessageWindow->Clear();
|
||||
WX_TEXT_CTRL_REPORTER rpt( m_MessageWindow );
|
||||
netlist.Show( 0, rpt );
|
||||
#endif
|
||||
|
||||
BOARD* pcb = m_parent->GetBoard();
|
||||
|
||||
// Search for duplicate footprints.
|
||||
module = pcb->m_Modules;
|
||||
|
||||
for( ; module != NULL; module = module->Next() )
|
||||
{
|
||||
nextModule = module->Next();
|
||||
|
||||
for( ; nextModule != NULL; nextModule = nextModule->Next() )
|
||||
{
|
||||
if( module->GetReference().CmpNoCase( nextModule->GetReference() ) == 0 )
|
||||
{
|
||||
aDuplicates.push_back( module );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search for component footprints in the netlist but not on the board.
|
||||
for( unsigned ii = 0; ii < netlist.GetCount(); ii++ )
|
||||
{
|
||||
component = netlist.GetComponent( ii );
|
||||
|
||||
module = pcb->FindModuleByReference( component->GetReference() );
|
||||
|
||||
if( module == NULL )
|
||||
{
|
||||
aMissing.Add( component->GetReference() );
|
||||
aMissing.Add( component->GetValue() );
|
||||
}
|
||||
}
|
||||
|
||||
// Search for component footprints found on board but not in netlist.
|
||||
module = pcb->m_Modules;
|
||||
|
||||
for( ; module != NULL; module = module->Next() )
|
||||
{
|
||||
|
||||
component = netlist.GetComponentByReference( module->GetReference() );
|
||||
|
||||
if( component == NULL )
|
||||
aNotInNetlist.push_back( module );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -31,31 +31,68 @@
|
|||
#include <dialog_netlist_fbp.h>
|
||||
|
||||
|
||||
class MODULE;
|
||||
class NETLIST;
|
||||
|
||||
|
||||
class DIALOG_NETLIST : public DIALOG_NETLIST_FBP
|
||||
{
|
||||
private:
|
||||
PCB_EDIT_FRAME * m_parent;
|
||||
wxDC * m_dc;
|
||||
PCB_EDIT_FRAME* m_parent;
|
||||
wxDC* m_dc;
|
||||
|
||||
public:
|
||||
DIALOG_NETLIST( PCB_EDIT_FRAME* aParent, wxDC * aDC,
|
||||
const wxString & aNetlistFullFilename );
|
||||
DIALOG_NETLIST( PCB_EDIT_FRAME* aParent, wxDC* aDC, const wxString & aNetlistFullFilename );
|
||||
~DIALOG_NETLIST() {};
|
||||
// return true if the user choice is tu use the .cmp file
|
||||
// created by CvPcb to know footprin names associated to components
|
||||
// and false tu use the netlist only
|
||||
|
||||
// return true if the user choice is to use the .cmp file
|
||||
// created by CvPcb to know footprint names associated to components
|
||||
// and false to use the netlist only
|
||||
bool UseCmpFileForFpNames()
|
||||
{
|
||||
return m_cmpNameSourceOpt->GetSelection() == 1;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Function verifyFootprints
|
||||
* compares the netlist to the board and builds a list of duplicate, missing, and
|
||||
* extra footprints.
|
||||
*
|
||||
* @param aNetlistFilename the netlist filename.
|
||||
* @param aCmpFilename the component link filename.
|
||||
* @param aDuplicate the list of duplicate modules to populate
|
||||
* @param aMissing the list of missing module references and values to populate. For
|
||||
* each missing item, the first string is the reference designator and
|
||||
* the second is the value.
|
||||
* @param aNotInNetlist is the list of component footprint found in the netlist but not on
|
||||
* the board.
|
||||
* @return true if no errors occurred while reading the netlist. Otherwise false.
|
||||
*/
|
||||
bool verifyFootprints( const wxString& aNetlistFilename,
|
||||
const wxString& aCmpFilename,
|
||||
std::vector< MODULE* >& aDuplicate,
|
||||
wxArrayString& aMissing,
|
||||
std::vector< MODULE* >& aNotInNetlist );
|
||||
|
||||
/**
|
||||
* Function loadFootprints
|
||||
* loads the footprints for each #COMPONENT in \a aNetlist from the list of libraries.
|
||||
*
|
||||
* @param aNetlist is the netlist of components to load the footprints into.
|
||||
*/
|
||||
void loadFootprints( NETLIST& aNetlist );
|
||||
|
||||
// Virtual event handlers:
|
||||
void OnOpenNetlistClick( wxCommandEvent& event );
|
||||
void OnReadNetlistFileClick( wxCommandEvent& event );
|
||||
void OnTestFootprintsClick( wxCommandEvent& event );
|
||||
void OnCompileRatsnestClick( wxCommandEvent& event );
|
||||
void OnCancelClick( wxCommandEvent& event );
|
||||
void OnSaveMessagesToFile( wxCommandEvent& aEvent );
|
||||
|
||||
void OnUpdateUISaveMessagesToFile( wxUpdateUIEvent& aEvent );
|
||||
void OnUpdateUIValidNetlistFile( wxUpdateUIEvent& aEvent );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const w
|
|||
|
||||
wxString m_Select_By_TimestampChoices[] = { _("Reference"), _("Timestamp") };
|
||||
int m_Select_By_TimestampNChoices = sizeof( m_Select_By_TimestampChoices ) / sizeof( wxString );
|
||||
m_Select_By_Timestamp = new wxRadioBox( this, wxID_ANY, _("Module Selection:"), wxDefaultPosition, wxDefaultSize, m_Select_By_TimestampNChoices, m_Select_By_TimestampChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_Select_By_Timestamp = new wxRadioBox( this, wxID_ANY, _("Module Selection"), wxDefaultPosition, wxDefaultSize, m_Select_By_TimestampNChoices, m_Select_By_TimestampChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_Select_By_Timestamp->SetSelection( 0 );
|
||||
m_Select_By_Timestamp->SetToolTip( _("Select how footprints are recognized:\nby their reference (U1, R3...) (normal setting)\nor their time stamp (special setting after a full schematic reannotation)") );
|
||||
|
||||
|
@ -32,7 +32,7 @@ DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const w
|
|||
|
||||
wxString m_cmpNameSourceOptChoices[] = { _("From netlist"), _("From separate .cmp file") };
|
||||
int m_cmpNameSourceOptNChoices = sizeof( m_cmpNameSourceOptChoices ) / sizeof( wxString );
|
||||
m_cmpNameSourceOpt = new wxRadioBox( this, wxID_ANY, _("Module Name Source:"), wxDefaultPosition, wxDefaultSize, m_cmpNameSourceOptNChoices, m_cmpNameSourceOptChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_cmpNameSourceOpt = new wxRadioBox( this, wxID_ANY, _("Module Name Source"), wxDefaultPosition, wxDefaultSize, m_cmpNameSourceOptNChoices, m_cmpNameSourceOptChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_cmpNameSourceOpt->SetSelection( 0 );
|
||||
m_cmpNameSourceOpt->SetToolTip( _("Source of footprints names for component:\n- the netlist (if you have filled the footprint field of each component in schematic)\n- the .cmp file created by CvPcb") );
|
||||
|
||||
|
@ -40,7 +40,7 @@ DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const w
|
|||
|
||||
wxString m_ChangeExistingFootprintCtrlChoices[] = { _("Keep"), _("Change") };
|
||||
int m_ChangeExistingFootprintCtrlNChoices = sizeof( m_ChangeExistingFootprintCtrlChoices ) / sizeof( wxString );
|
||||
m_ChangeExistingFootprintCtrl = new wxRadioBox( this, wxID_ANY, _("Exchange Module:"), wxDefaultPosition, wxDefaultSize, m_ChangeExistingFootprintCtrlNChoices, m_ChangeExistingFootprintCtrlChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_ChangeExistingFootprintCtrl = new wxRadioBox( this, wxID_ANY, _("Exchange Module"), wxDefaultPosition, wxDefaultSize, m_ChangeExistingFootprintCtrlNChoices, m_ChangeExistingFootprintCtrlChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_ChangeExistingFootprintCtrl->SetSelection( 0 );
|
||||
m_ChangeExistingFootprintCtrl->SetToolTip( _("Keep or change an existing footprint when the netlist gives a different footprint") );
|
||||
|
||||
|
@ -54,7 +54,7 @@ DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const w
|
|||
|
||||
wxString m_DeleteBadTracksChoices[] = { _("Keep"), _("Delete") };
|
||||
int m_DeleteBadTracksNChoices = sizeof( m_DeleteBadTracksChoices ) / sizeof( wxString );
|
||||
m_DeleteBadTracks = new wxRadioBox( this, wxID_ANY, _("Bad Tracks Deletion:"), wxDefaultPosition, wxDefaultSize, m_DeleteBadTracksNChoices, m_DeleteBadTracksChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_DeleteBadTracks = new wxRadioBox( this, wxID_ANY, _("Unconnected Tracks"), wxDefaultPosition, wxDefaultSize, m_DeleteBadTracksNChoices, m_DeleteBadTracksChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_DeleteBadTracks->SetSelection( 0 );
|
||||
m_DeleteBadTracks->SetToolTip( _("Keep or delete bad tracks after a netlist change") );
|
||||
|
||||
|
@ -74,7 +74,7 @@ DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const w
|
|||
wxBoxSizer* bRightSizerButtons;
|
||||
bRightSizerButtons = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_buttonBrowse = new wxButton( this, ID_OPEN_NELIST, _("Browse Netlist Files"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_buttonBrowse = new wxButton( this, ID_OPEN_NELIST, _("Open Netlist File"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bRightSizerButtons->Add( m_buttonBrowse, 0, wxEXPAND|wxALL, 5 );
|
||||
|
||||
m_buttonRead = new wxButton( this, ID_READ_NETLIST_FILE, _("Read Current Netlist"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
@ -83,7 +83,7 @@ DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const w
|
|||
|
||||
bRightSizerButtons->Add( m_buttonRead, 0, wxEXPAND|wxALL, 5 );
|
||||
|
||||
m_buttonFPTest = new wxButton( this, ID_TEST_NETLIST, _("Footprints Test"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_buttonFPTest = new wxButton( this, ID_TEST_NETLIST, _("Test Footprints"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_buttonFPTest->SetToolTip( _("Read the current neltist file and list missing and extra footprints") );
|
||||
|
||||
bRightSizerButtons->Add( m_buttonFPTest, 0, wxEXPAND|wxALL, 5 );
|
||||
|
@ -93,15 +93,27 @@ DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const w
|
|||
|
||||
bRightSizerButtons->Add( m_buttonRebild, 0, wxEXPAND|wxALL, 5 );
|
||||
|
||||
m_buttonSaveMessages = new wxButton( this, wxID_ANY, _("Save Messages to File"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bRightSizerButtons->Add( m_buttonSaveMessages, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_buttonClose = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bRightSizerButtons->Add( m_buttonClose, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bUpperSizer->Add( bRightSizerButtons, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
bUpperSizer->Add( bRightSizerButtons, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxTOP, 5 );
|
||||
|
||||
|
||||
bMainSizer->Add( bUpperSizer, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
wxBoxSizer* bCenterSizer;
|
||||
bCenterSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_checkDryRun = new wxCheckBox( this, wxID_ANY, _("Only report changes in message panel"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bCenterSizer->Add( m_checkDryRun, 0, wxALL, 5 );
|
||||
|
||||
|
||||
bMainSizer->Add( bCenterSizer, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
bMainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
|
||||
|
||||
|
@ -137,8 +149,13 @@ DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const w
|
|||
// Connect Events
|
||||
m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnOpenNetlistClick ), NULL, this );
|
||||
m_buttonRead->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnReadNetlistFileClick ), NULL, this );
|
||||
m_buttonRead->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
|
||||
m_buttonFPTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnTestFootprintsClick ), NULL, this );
|
||||
m_buttonFPTest->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
|
||||
m_buttonRebild->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnCompileRatsnestClick ), NULL, this );
|
||||
m_buttonRebild->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
|
||||
m_buttonSaveMessages->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnSaveMessagesToFile ), NULL, this );
|
||||
m_buttonSaveMessages->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUISaveMessagesToFile ), NULL, this );
|
||||
m_buttonClose->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnCancelClick ), NULL, this );
|
||||
}
|
||||
|
||||
|
@ -147,8 +164,13 @@ DIALOG_NETLIST_FBP::~DIALOG_NETLIST_FBP()
|
|||
// Disconnect Events
|
||||
m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnOpenNetlistClick ), NULL, this );
|
||||
m_buttonRead->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnReadNetlistFileClick ), NULL, this );
|
||||
m_buttonRead->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
|
||||
m_buttonFPTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnTestFootprintsClick ), NULL, this );
|
||||
m_buttonFPTest->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
|
||||
m_buttonRebild->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnCompileRatsnestClick ), NULL, this );
|
||||
m_buttonRebild->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
|
||||
m_buttonSaveMessages->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnSaveMessagesToFile ), NULL, this );
|
||||
m_buttonSaveMessages->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUISaveMessagesToFile ), NULL, this );
|
||||
m_buttonClose->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnCancelClick ), NULL, this );
|
||||
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Module Selection:</property>
|
||||
<property name="label">Module Selection</property>
|
||||
<property name="majorDimension">1</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
|
@ -232,7 +232,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Module Name Source:</property>
|
||||
<property name="label">Module Name Source</property>
|
||||
<property name="majorDimension">1</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
|
@ -322,7 +322,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Exchange Module:</property>
|
||||
<property name="label">Exchange Module</property>
|
||||
<property name="majorDimension">1</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
|
@ -423,7 +423,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Bad Tracks Deletion:</property>
|
||||
<property name="label">Unconnected Tracks</property>
|
||||
<property name="majorDimension">1</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
|
@ -574,7 +574,7 @@
|
|||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxTOP</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
|
@ -614,7 +614,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">ID_OPEN_NELIST</property>
|
||||
<property name="label">Browse Netlist Files</property>
|
||||
<property name="label">Open Netlist File</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
|
@ -754,7 +754,7 @@
|
|||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
<event name="OnUpdateUI">OnUpdateUIValidNetlistFile</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
|
@ -790,7 +790,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">ID_TEST_NETLIST</property>
|
||||
<property name="label">Footprints Test</property>
|
||||
<property name="label">Test Footprints</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
|
@ -842,7 +842,7 @@
|
|||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
<event name="OnUpdateUI">OnUpdateUIValidNetlistFile</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
|
@ -930,7 +930,95 @@
|
|||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
<event name="OnUpdateUI">OnUpdateUIValidNetlistFile</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default">0</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Save Messages to File</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_buttonSaveMessages</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">OnSaveMessagesToFile</event>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI">OnUpdateUISaveMessagesToFile</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
|
@ -1025,6 +1113,105 @@
|
|||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bCenterSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Only report changes in message panel</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_checkDryRun</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnCheckBox"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND | wxALL</property>
|
||||
|
|
|
@ -22,6 +22,7 @@ class DIALOG_SHIM;
|
|||
#include <wx/settings.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
@ -54,7 +55,9 @@ class DIALOG_NETLIST_FBP : public DIALOG_SHIM
|
|||
wxButton* m_buttonRead;
|
||||
wxButton* m_buttonFPTest;
|
||||
wxButton* m_buttonRebild;
|
||||
wxButton* m_buttonSaveMessages;
|
||||
wxButton* m_buttonClose;
|
||||
wxCheckBox* m_checkDryRun;
|
||||
wxStaticLine* m_staticline1;
|
||||
wxStaticText* m_staticTextNetfilename;
|
||||
wxTextCtrl* m_NetlistFilenameCtrl;
|
||||
|
@ -64,8 +67,11 @@ class DIALOG_NETLIST_FBP : public DIALOG_SHIM
|
|||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnOpenNetlistClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnReadNetlistFileClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnUpdateUIValidNetlistFile( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnTestFootprintsClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCompileRatsnestClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnSaveMessagesToFile( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnUpdateUISaveMessagesToFile( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file DIALOG_ORIENT_FOOTPRINTS.cpp
|
||||
* @file dialog_orient_footprints.cpp
|
||||
*/
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
|
@ -58,10 +58,12 @@ public:
|
|||
{
|
||||
return m_ApplyToLocked->IsChecked();
|
||||
}
|
||||
|
||||
int GetOrientation()
|
||||
{
|
||||
return newOrientation;
|
||||
}
|
||||
|
||||
wxString GetFilter()
|
||||
{
|
||||
return m_FilterPattern->GetValue();
|
||||
|
@ -73,6 +75,8 @@ private:
|
|||
void OnOkClick( wxCommandEvent& event );
|
||||
void OnCancelClick( wxCommandEvent& event );
|
||||
};
|
||||
|
||||
|
||||
int DIALOG_ORIENT_FOOTPRINTS::newOrientation = 0;
|
||||
|
||||
|
||||
|
@ -81,23 +85,18 @@ DIALOG_ORIENT_FOOTPRINTS::DIALOG_ORIENT_FOOTPRINTS( PCB_EDIT_FRAME* parent )
|
|||
{
|
||||
m_Parent = parent;
|
||||
wxString txt;
|
||||
txt.Printf(wxT("%g"), (double) newOrientation/10);
|
||||
m_OrientationCtrl->SetValue(txt);
|
||||
SetFocus( );
|
||||
GetSizer()->SetSizeHints(this);
|
||||
txt.Printf( wxT( "%g" ), (double) newOrientation/10 );
|
||||
m_OrientationCtrl->SetValue( txt );
|
||||
SetFocus();
|
||||
GetSizer()->SetSizeHints( this );
|
||||
Centre();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
void PCB_EDIT_FRAME::OnOrientFootprints( wxCommandEvent& event )
|
||||
/****************************************************************/
|
||||
/**
|
||||
* Function OnOrientFootprints
|
||||
* install the dialog box for the comman Orient Footprints
|
||||
*/
|
||||
{
|
||||
DIALOG_ORIENT_FOOTPRINTS dlg(this);
|
||||
DIALOG_ORIENT_FOOTPRINTS dlg( this );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
return;
|
||||
|
||||
|
@ -111,23 +110,13 @@ void PCB_EDIT_FRAME::OnOrientFootprints( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
bool PCB_EDIT_FRAME::ReOrientModules( const wxString& ModuleMask,
|
||||
int Orient, bool include_fixe )
|
||||
/*******************************************************************/
|
||||
/**
|
||||
* Function ReOrientModules
|
||||
* Set the orientation of footprints
|
||||
* @param ModuleMask = mask (wildcard allowed) selection
|
||||
* @param Orient = new orientation
|
||||
* @param include_fixe = true to orient locked footprints
|
||||
* @return true if some footprints modified, false if no change
|
||||
*/
|
||||
bool PCB_EDIT_FRAME::ReOrientModules( const wxString& ModuleMask, int Orient, bool include_fixe )
|
||||
{
|
||||
wxString line;
|
||||
bool modified = false;
|
||||
|
||||
line.Printf( _( "OK to set footprints orientation to %.1f degrees ?" ), (double)Orient / 10 );
|
||||
|
||||
if( !IsOK( this, line ) )
|
||||
return false;
|
||||
|
||||
|
@ -155,13 +144,13 @@ void DIALOG_ORIENT_FOOTPRINTS::OnOkClick( wxCommandEvent& event )
|
|||
double d_orient;
|
||||
wxString text = m_OrientationCtrl->GetValue();
|
||||
|
||||
if ( ! text.ToDouble(&d_orient) )
|
||||
if ( ! text.ToDouble( &d_orient ) )
|
||||
{
|
||||
DisplayError(this, _("Bad value for footprints orientation"));
|
||||
DisplayError( this, _( "Bad value for footprints orientation" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
newOrientation = KiROUND(d_orient * 10);
|
||||
newOrientation = KiROUND( d_orient * 10 );
|
||||
NORMALIZE_ANGLE_180( newOrientation );
|
||||
EndModal( wxID_OK );
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file dialog_pad_properties.cpp.
|
||||
* @brief Pad editing functions and dialog pad editor
|
||||
* @file dialog_pad_properties.cpp
|
||||
* @brief Pad editing functions and dialog pad editor.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -132,7 +132,7 @@ wxString PCB_BASE_FRAME::SelectFootprintFromLibBrowser( void )
|
|||
wxMilliSleep( 50 );
|
||||
}
|
||||
|
||||
// Returnd the full fp name, i.e. the lib name and th fp name,
|
||||
// Returns the full fp name, i.e. the lib name and th fp name,
|
||||
// separated by a '/'
|
||||
// (/ is now an illegal char in fp names)
|
||||
wxString fpname = viewer->GetSelectedLibraryFullName();
|
||||
|
@ -269,15 +269,6 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
|
|||
}
|
||||
|
||||
|
||||
/* scans active libraries to find and load aFootprintName.
|
||||
* If found the module is added to the BOARD, just for good measure.
|
||||
* aLibraryPath is the full/short name of the library.
|
||||
* if empty, search in all libraries
|
||||
* aFootprintName is the footprint to load
|
||||
* aDisplayError = true to display an error message if any.
|
||||
*
|
||||
* return a pointer to the new module, or NULL
|
||||
*/
|
||||
MODULE* PCB_BASE_FRAME::GetModuleLibrary( const wxString& aLibraryPath,
|
||||
const wxString& aFootprintName,
|
||||
bool aDisplayError )
|
||||
|
@ -289,12 +280,6 @@ MODULE* PCB_BASE_FRAME::GetModuleLibrary( const wxString& aLibraryPath,
|
|||
}
|
||||
|
||||
|
||||
/* loads aFootprintName from aLibraryPath.
|
||||
* If found the module is added to the BOARD, just for good measure.
|
||||
*
|
||||
* aLibraryPath - the full filename or the short name of the library to read.
|
||||
* if it is a short name, the file is searched in all library valid paths
|
||||
*/
|
||||
MODULE* PCB_BASE_FRAME::loadFootprintFromLibrary( const wxString& aLibraryPath,
|
||||
const wxString& aFootprintName,
|
||||
bool aDisplayError,
|
||||
|
@ -337,10 +322,6 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibrary( const wxString& aLibraryPath,
|
|||
}
|
||||
|
||||
|
||||
/* Explore the libraries list and
|
||||
* loads aFootprintName from the first library it is found
|
||||
* If found add the module is also added to the BOARD, just for good measure.
|
||||
*/
|
||||
MODULE* PCB_BASE_FRAME::loadFootprintFromLibraries(
|
||||
const wxString& aFootprintName, bool aDisplayError )
|
||||
{
|
||||
|
@ -399,6 +380,35 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibraries(
|
|||
{
|
||||
DisplayError( this, ioe.errorText );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
MODULE* PCB_BASE_FRAME::loadFootprint( const wxString& aFootprintName )
|
||||
throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
wxString libPath;
|
||||
wxFileName fn;
|
||||
MODULE* footprint;
|
||||
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
|
||||
|
||||
for( unsigned ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
|
||||
{
|
||||
fn = wxFileName( wxEmptyString, g_LibraryNames[ii], LegacyFootprintLibPathExtension );
|
||||
|
||||
libPath = wxGetApp().FindLibraryPath( fn );
|
||||
|
||||
if( !libPath )
|
||||
continue;
|
||||
|
||||
footprint = pi->FootprintLoad( libPath, aFootprintName );
|
||||
|
||||
if( footprint )
|
||||
return footprint;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -486,9 +496,6 @@ wxString PCB_BASE_FRAME::Select_1_Module_From_List( EDA_DRAW_FRAME* aWindow,
|
|||
}
|
||||
|
||||
|
||||
/* Find and display the doc Component Name
|
||||
* The list of doc is pointed to by mlist.
|
||||
*/
|
||||
static void DisplayCmpDoc( wxString& Name )
|
||||
{
|
||||
FOOTPRINT_INFO* module_info = MList.GetModuleInfo( Name );
|
||||
|
|
|
@ -688,40 +688,40 @@ MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type )
|
|||
break;
|
||||
|
||||
case 2: // Arc Stub created by a polygonal approach:
|
||||
{
|
||||
EDGE_MODULE* edge = new EDGE_MODULE( module );
|
||||
module->GraphicalItems().PushFront( edge );
|
||||
|
||||
edge->SetShape( S_POLYGON );
|
||||
edge->SetLayer( LAYER_N_FRONT );
|
||||
|
||||
int numPoints = angle / 50 + 3; // Note: angles are in 0.1 degrees
|
||||
std::vector<wxPoint> polyPoints = edge->GetPolyPoints();
|
||||
polyPoints.reserve( numPoints );
|
||||
|
||||
edge->m_Start0.y = -pad->GetSize().y / 2;
|
||||
|
||||
polyPoints.push_back( wxPoint( 0, 0 ) );
|
||||
|
||||
int theta = -angle / 2;
|
||||
|
||||
for( int ii = 1; ii<numPoints - 1; ii++ )
|
||||
{
|
||||
EDGE_MODULE* edge = new EDGE_MODULE( module );
|
||||
module->GraphicalItems().PushFront( edge );
|
||||
wxPoint pt( 0, -gap_size );
|
||||
|
||||
edge->SetShape( S_POLYGON );
|
||||
edge->SetLayer( LAYER_N_FRONT );
|
||||
RotatePoint( &pt.x, &pt.y, theta );
|
||||
|
||||
int numPoints = angle / 50 + 3; // Note: angles are in 0.1 degrees
|
||||
std::vector<wxPoint> polyPoints = edge->GetPolyPoints();
|
||||
polyPoints.reserve( numPoints );
|
||||
polyPoints.push_back( pt );
|
||||
|
||||
edge->m_Start0.y = -pad->GetSize().y / 2;
|
||||
theta += 50;
|
||||
|
||||
polyPoints.push_back( wxPoint( 0, 0 ) );
|
||||
|
||||
int theta = -angle / 2;
|
||||
|
||||
for( int ii = 1; ii<numPoints - 1; ii++ )
|
||||
{
|
||||
wxPoint pt( 0, -gap_size );
|
||||
|
||||
RotatePoint( &pt.x, &pt.y, theta );
|
||||
|
||||
polyPoints.push_back( pt );
|
||||
|
||||
theta += 50;
|
||||
|
||||
if( theta > angle / 2 )
|
||||
theta = angle / 2;
|
||||
}
|
||||
|
||||
// Close the polygon:
|
||||
polyPoints.push_back( polyPoints[0] );
|
||||
if( theta > angle / 2 )
|
||||
theta = angle / 2;
|
||||
}
|
||||
|
||||
// Close the polygon:
|
||||
polyPoints.push_back( polyPoints[0] );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -25,184 +25,96 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Functions to read a netlist:
|
||||
* - Load new footprints and initialize net info
|
||||
* - Test for missing or extra footprints
|
||||
* - Recalculate full connectivity info
|
||||
*
|
||||
* Important remark:
|
||||
* When reading a netlist, Pcbnew must identify existing footprints (link
|
||||
* between existing footprints an components in netlist)
|
||||
* This identification can be made from 2 fields:
|
||||
* - The reference (U2, R5 ..): this is the normal mode
|
||||
* - 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
|
||||
* to identify footprints on board and the corresponding component in schematic.
|
||||
* If we want to fully reannotate a schematic this sequence must be used
|
||||
* 1 - SAVE your board !!!
|
||||
* 2 - Create and read the netlist (to ensure all info is correct, mainly
|
||||
* references and time stamp)
|
||||
* 3 - Reannotate the schematic (references will be changed, but not time stamps )
|
||||
* 4 - Recreate and read the new netlist using the Time Stamp identification
|
||||
* (that reinit the new references)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <appl_wxstruct.h>
|
||||
#include <class_drawpanel.h>
|
||||
#include <confirm.h>
|
||||
#include <richio.h>
|
||||
#include <dialog_helpers.h>
|
||||
#include <wxPcbStruct.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <reporter.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
#include <pcbnew.h>
|
||||
#include <dialog_netlist.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <io_mgr.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
/**
|
||||
* Function OpenNetlistFile
|
||||
* used to open a netlist file
|
||||
*/
|
||||
static FILE* OpenNetlistFile( const wxString& aFullFileName )
|
||||
{
|
||||
if( aFullFileName.IsEmpty() )
|
||||
return NULL; // No filename: exit
|
||||
|
||||
FILE* file = wxFopen( aFullFileName, wxT( "rt" ) );
|
||||
|
||||
if( file == NULL )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Netlist file <%s> not found" ), GetChars( aFullFileName ) );
|
||||
wxMessageBox( msg );
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update footprints (load missing footprints and delete on request extra footprints)
|
||||
* Update connectivity info ( Net Name list )
|
||||
* Update Reference, value and "TIME STAMP"
|
||||
* param aNetlistFullFilename = netlist file name (*.net)
|
||||
* param aCmpFullFileName = cmp/footprint list file name (*.cmp) if not found,
|
||||
* 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.
|
||||
* param aDeleteExtraFootprints - true to remove unlocked footprints found on board but not
|
||||
* in netlist.
|
||||
* 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).
|
||||
* param aUseCmpFileForFootprintsNames = false to use only the netlist to know the
|
||||
* fontprint names of each component.
|
||||
* = true to use the .cmp file created by CvPcb
|
||||
* return true if Ok
|
||||
*/
|
||||
bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
|
||||
const wxString& aCmpFullFileName,
|
||||
wxTextCtrl* aMessageWindow,
|
||||
bool aChangeFootprint,
|
||||
bool aDeleteBadTracks,
|
||||
void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
|
||||
const wxString& aCmpFileName,
|
||||
REPORTER* aReporter,
|
||||
bool aChangeFootprints,
|
||||
bool aDeleteUnconnectedTracks,
|
||||
bool aDeleteExtraFootprints,
|
||||
bool aSelect_By_Timestamp )
|
||||
bool aSelectByTimeStamp,
|
||||
bool aIsDryRun )
|
||||
{
|
||||
FILE* netfile = OpenNetlistFile( aNetlistFullFilename );
|
||||
wxString msg;
|
||||
NETLIST netlist;
|
||||
NETLIST_READER* netlistReader;
|
||||
|
||||
if( !netfile )
|
||||
return false;
|
||||
|
||||
SetLastNetListRead( aNetlistFullFilename );
|
||||
bool useCmpfile = !aCmpFullFileName.IsEmpty() && wxFileExists( aCmpFullFileName );
|
||||
|
||||
if( aMessageWindow )
|
||||
try
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Reading Netlist <%s>" ), GetChars( aNetlistFullFilename ) );
|
||||
aMessageWindow->AppendText( msg + wxT( "\n" ) );
|
||||
netlistReader = NETLIST_READER::GetNetlistReader( &netlist, aNetlistFileName,
|
||||
aCmpFileName );
|
||||
|
||||
if( useCmpfile )
|
||||
if( netlistReader == NULL )
|
||||
{
|
||||
msg.Printf( _( "Using component/footprint link file <%s>" ),
|
||||
GetChars( aCmpFullFileName ) );
|
||||
aMessageWindow->AppendText( msg + wxT( "\n" ) );
|
||||
msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFileName ) );
|
||||
wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR, this );
|
||||
return;
|
||||
}
|
||||
|
||||
if( aSelect_By_Timestamp )
|
||||
{
|
||||
msg.Printf( _( "Using time stamp selection" ),
|
||||
GetChars( aCmpFullFileName ) );
|
||||
aMessageWindow->AppendText( msg + wxT( "\n" ) );
|
||||
}
|
||||
std::auto_ptr< NETLIST_READER > nlr( netlistReader );
|
||||
SetLastNetListRead( aNetlistFileName );
|
||||
netlistReader->LoadNetlist();
|
||||
loadFootprints( netlist, aReporter );
|
||||
}
|
||||
catch( IO_ERROR& ioe )
|
||||
{
|
||||
msg = wxString::Format( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() );
|
||||
wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
|
||||
return;
|
||||
}
|
||||
|
||||
netlist.SetIsDryRun( aIsDryRun );
|
||||
netlist.SetFindByTimeStamp( aSelectByTimeStamp );
|
||||
netlist.SetDeleteExtraFootprints( aDeleteExtraFootprints );
|
||||
netlist.SetReplaceFootprints( aChangeFootprints );
|
||||
|
||||
// Clear undo and redo lists to avoid inconsistencies between lists
|
||||
GetScreen()->ClearUndoRedoList();
|
||||
if( !netlist.IsDryRun() )
|
||||
GetScreen()->ClearUndoRedoList();
|
||||
|
||||
netlist.SortByReference();
|
||||
GetBoard()->ReplaceNetlist( netlist, aReporter );
|
||||
|
||||
// If it was a dry run, nothing has changed so we're done.
|
||||
if( netlist.IsDryRun() )
|
||||
return;
|
||||
|
||||
OnModify();
|
||||
|
||||
// Clear flags and pointers to avoid inconsistencies
|
||||
GetBoard()->m_Status_Pcb = 0;
|
||||
SetCurItem( NULL );
|
||||
|
||||
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;
|
||||
netList_Reader.m_UseCmpFile = useCmpfile;
|
||||
netList_Reader.SetFilesnames( aNetlistFullFilename, aCmpFullFileName );
|
||||
|
||||
// True to read footprint filters section: true for CvPcb, false for Pcbnew
|
||||
netList_Reader.ReadLibpartSectionSetOpt( false );
|
||||
|
||||
bool success = netList_Reader.ReadNetList( netfile );
|
||||
|
||||
if( !success )
|
||||
if( aDeleteUnconnectedTracks && GetBoard()->m_Track )
|
||||
{
|
||||
wxMessageBox( _("Netlist read error") );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delete footprints not found in netlist:
|
||||
if( aDeleteExtraFootprints )
|
||||
{
|
||||
if( IsOK( NULL,
|
||||
_( "OK to delete not locked footprints not found in netlist?" ) ) )
|
||||
netList_Reader.RemoveExtraFootprints();
|
||||
// Remove erroneous tracks. This should probably pushed down to the #BOARD object.
|
||||
RemoveMisConnectedTracks();
|
||||
}
|
||||
|
||||
// Rebuild the board connectivity:
|
||||
Compile_Ratsnest( NULL, true );
|
||||
|
||||
if( aDeleteBadTracks && GetBoard()->m_Track )
|
||||
{
|
||||
// Remove erroneous tracks
|
||||
if( RemoveMisConnectedTracks() )
|
||||
Compile_Ratsnest( NULL, true );
|
||||
}
|
||||
|
||||
SetMsgPanel( GetBoard() );
|
||||
m_canvas->Refresh();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* build and shows a list of existing modules on board
|
||||
* The user can select a module from this list
|
||||
* @return a pointer to the selected module or NULL
|
||||
*/
|
||||
MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName( void )
|
||||
MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName()
|
||||
{
|
||||
MODULE* Module;
|
||||
|
||||
|
@ -219,9 +131,9 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName( void )
|
|||
listnames.Add( Module->GetReference() );
|
||||
|
||||
wxArrayString headers;
|
||||
headers.Add( wxT("Module") );
|
||||
headers.Add( wxT( "Module" ) );
|
||||
std::vector<wxArrayString> itemsToDisplay;
|
||||
|
||||
|
||||
// Conversion from wxArrayString to vector of ArrayString
|
||||
for( unsigned i = 0; i < listnames.GetCount(); i++ )
|
||||
{
|
||||
|
@ -229,6 +141,7 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName( void )
|
|||
item.Add( listnames[i] );
|
||||
itemsToDisplay.push_back( item );
|
||||
}
|
||||
|
||||
EDA_LIST_DIALOG dlg( this, _( "Components" ), headers, itemsToDisplay, wxEmptyString );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
|
@ -247,84 +160,70 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName( void )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 aFilename = the full filename netlist
|
||||
* param aDuplicate = the list of duplicate modules to populate
|
||||
* param aMissing = the list of missing module references and values
|
||||
* to populate. For each missing item, the first string is the ref,
|
||||
* the second is the value.
|
||||
* param aNotInNetlist = the list of not-in-netlist modules to populate
|
||||
*/
|
||||
bool PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints(
|
||||
const wxString& aFilename,
|
||||
std::vector <MODULE*>& aDuplicate,
|
||||
wxArrayString& aMissing,
|
||||
std::vector <MODULE*>& aNotInNetlist )
|
||||
void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
|
||||
throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
FILE* netfile = OpenNetlistFile( aFilename );
|
||||
if( !netfile )
|
||||
return false;
|
||||
wxString msg;
|
||||
wxString lastFootprintLibName;
|
||||
COMPONENT* component;
|
||||
MODULE* module;
|
||||
|
||||
// Build the list of references of the net list modules.
|
||||
NETLIST_READER netList_Reader( this );
|
||||
netList_Reader.SetFilesnames( aFilename, wxEmptyString );
|
||||
netList_Reader.BuildModuleListOnlySetOpt( true );
|
||||
if( ! netList_Reader.ReadNetList( netfile ) )
|
||||
return false; // error
|
||||
if( aNetlist.IsEmpty() )
|
||||
return;
|
||||
|
||||
COMPONENT_INFO_LIST& moduleInfoList = netList_Reader.GetComponentInfoList();
|
||||
aNetlist.SortByFootprintLibName();
|
||||
|
||||
// Search for duplicate footprints.
|
||||
MODULE* module = GetBoard()->m_Modules;
|
||||
wxString libPath;
|
||||
wxFileName fn;
|
||||
|
||||
for( ; module != NULL; module = module->Next() )
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
|
||||
|
||||
for( unsigned ii = 0; ii < aNetlist.GetCount(); ii++ )
|
||||
{
|
||||
MODULE* altmodule = module->Next();
|
||||
component = aNetlist.GetComponent( ii );
|
||||
|
||||
for( ; altmodule != NULL; altmodule = altmodule->Next() )
|
||||
if( ii == 0 || component->GetFootprintLibName() != lastFootprintLibName )
|
||||
{
|
||||
if( module->GetReference().CmpNoCase( altmodule->GetReference() ) == 0 )
|
||||
module = NULL;
|
||||
|
||||
for( unsigned ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
|
||||
{
|
||||
aDuplicate.push_back( module );
|
||||
break;
|
||||
fn = wxFileName( wxEmptyString, g_LibraryNames[ii],
|
||||
LegacyFootprintLibPathExtension );
|
||||
|
||||
libPath = wxGetApp().FindLibraryPath( fn );
|
||||
|
||||
if( !libPath )
|
||||
continue;
|
||||
|
||||
module = pi->FootprintLoad( libPath, component->GetFootprintLibName() );
|
||||
|
||||
if( module )
|
||||
{
|
||||
lastFootprintLibName = component->GetFootprintLibName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( module == NULL )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Component `%s` footprint <%s> was not found in any libraries." ),
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( component->GetFootprintLibName() ) );
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search for missing modules on board.
|
||||
for( unsigned ii = 0; ii < moduleInfoList.size(); ii++ )
|
||||
{
|
||||
COMPONENT_INFO* cmp_info = moduleInfoList[ii];
|
||||
module = GetBoard()->FindModuleByReference( cmp_info->m_Reference );
|
||||
if( module == NULL ) // Module missing, not found in board
|
||||
else
|
||||
{
|
||||
aMissing.Add( cmp_info->m_Reference );
|
||||
aMissing.Add( cmp_info->m_Value );
|
||||
}
|
||||
}
|
||||
// Footprint already loaded from a library, duplicate it (faster)
|
||||
if( module == NULL )
|
||||
continue; // Module does not exist in any library.
|
||||
|
||||
// Search for modules found on board but not in net list.
|
||||
module = GetBoard()->m_Modules;
|
||||
for( ; module != NULL; module = module->Next() )
|
||||
{
|
||||
unsigned ii;
|
||||
for( ii = 0; ii < moduleInfoList.size(); ii++ )
|
||||
{
|
||||
COMPONENT_INFO* cmp_info = moduleInfoList[ii];
|
||||
if( module->GetReference().CmpNoCase( cmp_info->m_Reference ) == 0 )
|
||||
break; // Module is in net list.
|
||||
module = new MODULE( *module );
|
||||
}
|
||||
|
||||
if( ii == moduleInfoList.size() ) // Module not found in netlist
|
||||
aNotInNetlist.push_back( module );
|
||||
wxASSERT( module != NULL );
|
||||
component->SetModule( module );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef NETLIST_READER_H
|
||||
#define NETLIST_READER_H
|
||||
#define NETLIST_READER_H
|
||||
|
||||
/**
|
||||
* @file netlist_reader.h
|
||||
|
@ -9,6 +9,7 @@
|
|||
* 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
|
||||
|
@ -33,304 +34,472 @@
|
|||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <kicad_string.h>
|
||||
#include <wxPcbStruct.h>
|
||||
#include <richio.h>
|
||||
#include <macros.h>
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
#include <pcbnew.h>
|
||||
#include <netlist_lexer.h> // netlist_lexer is common to Eeschema and Pcbnew
|
||||
|
||||
/*
|
||||
* Helper class, to store for a footprint the footprint filter info,
|
||||
* found in new format KiCad netlist.
|
||||
* For CvPcb only
|
||||
* Note: features for CvPcb are for a temporary use.
|
||||
* They could be removed when CvPcb is modified
|
||||
* (perhaps when it does not use anumore a netlist to build the component to footprint link)
|
||||
|
||||
using namespace NL_T;
|
||||
|
||||
|
||||
class MODULE;
|
||||
class LINE_READER;
|
||||
class REPORTER;
|
||||
|
||||
|
||||
/**
|
||||
* Class COMPONENT_NET
|
||||
* is used to store the component pin name to net name associations stored in a netlist.
|
||||
*/
|
||||
class LIPBART_INFO
|
||||
class COMPONENT_NET
|
||||
{
|
||||
public:
|
||||
wxString m_Libpart; // the libpart name.
|
||||
wxArrayString m_FootprintFilter; // an array of footprint filters found in netlist,
|
||||
// for this footprint
|
||||
wxString m_pinName;
|
||||
wxString m_netNumber;
|
||||
wxString m_netName;
|
||||
|
||||
public:
|
||||
COMPONENT_NET() {}
|
||||
|
||||
LIPBART_INFO( const wxString& aLibpart )
|
||||
COMPONENT_NET( const wxString& aPinName, const wxString& aNetName )
|
||||
{
|
||||
m_Libpart = aLibpart;
|
||||
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 <LIPBART_INFO *> LIPBART_INFO_LIST;
|
||||
|
||||
typedef std::vector< COMPONENT_NET > COMPONENT_NETS;
|
||||
|
||||
|
||||
/*
|
||||
* Helper class, to store components and footprints info found in netlist.
|
||||
* (component reference and time stamp, footprint name ...
|
||||
/**
|
||||
* Class COMPONENT
|
||||
* is used to store components and all of their related information found in a netlist.
|
||||
*/
|
||||
class COMPONENT_INFO
|
||||
class COMPONENT
|
||||
{
|
||||
public:
|
||||
wxString m_Footprint; // the footprint name found in netlist, the in .cmp file
|
||||
wxString m_Reference; // the schematic reference found in netlist
|
||||
wxString m_Value; // the schematic value found in netlist
|
||||
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 schematic full time stamp found in netlist
|
||||
wxString m_Libpart; // the schematic libpart found in netlist
|
||||
wxArrayString m_FootprintFilter; // a footprint filters list found in old format netlist
|
||||
int m_pinCount; // the number of pins found in the netlist
|
||||
wxString m_timeStamp; ///< The component full time stamp found in netlist.
|
||||
wxString m_name; ///< The name of the component found in the netlist.
|
||||
|
||||
public: COMPONENT_INFO( const wxString& libname,
|
||||
const wxString& cmpname,
|
||||
const wxString& value,
|
||||
const wxString& timestamp )
|
||||
/// The name of the footprint in the library assigned to the component.
|
||||
wxString m_footprintLibName;
|
||||
|
||||
/// The lib part name used to look up the component library part information. This only has
|
||||
/// meaning in the new s-expression netlist file format.
|
||||
wxString m_libraryName;
|
||||
wxString m_libraryPartName;
|
||||
|
||||
/// The footprint loaded from the library for this component.
|
||||
std::auto_ptr< MODULE > m_footprint;
|
||||
|
||||
static COMPONENT_NET m_emptyNet;
|
||||
|
||||
public:
|
||||
COMPONENT( const wxString& aName,
|
||||
const wxString& aReference,
|
||||
const wxString& aValue,
|
||||
const wxString& aTimeStamp )
|
||||
{
|
||||
m_Footprint = libname;
|
||||
m_Reference = cmpname;
|
||||
m_Value = value;
|
||||
m_TimeStamp = timestamp;
|
||||
m_pinCount = 0;
|
||||
m_name = aName;
|
||||
m_reference = aReference;
|
||||
m_value = aValue;
|
||||
m_timeStamp = aTimeStamp;
|
||||
}
|
||||
|
||||
~COMPONENT_INFO() { };
|
||||
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() ); }
|
||||
|
||||
const wxString& GetReference() const { return m_reference; }
|
||||
|
||||
const wxString& GetValue() const { return m_value; }
|
||||
|
||||
void SetFootprintLibName( const wxString& aFootprintLibName )
|
||||
{
|
||||
m_footprintLibName = aFootprintLibName;
|
||||
}
|
||||
|
||||
const wxString& GetFootprintLibName() const { return m_footprintLibName; }
|
||||
|
||||
const wxString& GetTimeStamp() const { return m_timeStamp; }
|
||||
|
||||
const wxString& GetLibName() const { return m_name; }
|
||||
|
||||
void SetLibrarySource( const wxString& aLibName, const wxString& aCompName )
|
||||
{
|
||||
m_libraryName = aLibName;
|
||||
m_libraryPartName = aCompName;
|
||||
}
|
||||
|
||||
void SetFootprintFilters( const wxArrayString& aFilterList )
|
||||
{
|
||||
m_footprintFilters = aFilterList;
|
||||
}
|
||||
|
||||
const wxArrayString& GetFootprintFilters() const { return m_footprintFilters; }
|
||||
|
||||
MODULE* GetModule( bool aRelease = false )
|
||||
{
|
||||
return ( aRelease ) ? m_footprint.release() : m_footprint.get();
|
||||
}
|
||||
|
||||
void SetModule( MODULE* aModule );
|
||||
|
||||
bool IsLibSource( const wxString& aLibName, const wxString& aCompName ) const
|
||||
{
|
||||
return aLibName == m_libraryName && aCompName == m_libraryPartName;
|
||||
}
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
enum typenetlist
|
||||
|
||||
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
|
||||
{
|
||||
NETLIST_TYPE_UNSPECIFIED = 0,
|
||||
NETLIST_TYPE_ORCADPCB2, // the basic format used by pcbnew
|
||||
NETLIST_TYPE_PCBNEW, // the format used by pcbnew, basic format + more info
|
||||
NETLIST_TYPE_KICAD // new format using common S expression
|
||||
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 );
|
||||
|
||||
/*
|
||||
* Function GetComponentByLibName
|
||||
* returns a #COMPONENT by \a aLibName.
|
||||
*
|
||||
* @param aLibName is the component library name of the #COMPONENT.
|
||||
* @return a pointer to the #COMPONENT that matches \a aLibName if found. Otherwise NULL.
|
||||
*/
|
||||
COMPONENT* GetComponentByLibName( const wxString& aLibName );
|
||||
|
||||
void SortByFootprintLibName();
|
||||
|
||||
void SortByReference();
|
||||
|
||||
void 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; }
|
||||
|
||||
#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_INFO*> COMPONENT_INFO_LIST;
|
||||
/*
|
||||
* Helper class, to read a netlist.
|
||||
/**
|
||||
* Class CMP_READER
|
||||
* reads a component footprint link file (*.cmp) format.
|
||||
*/
|
||||
class CMP_READER
|
||||
{
|
||||
LINE_READER* m_lineReader; ///< The line reader to read.
|
||||
|
||||
public:
|
||||
CMP_READER( LINE_READER* aLineReader )
|
||||
{
|
||||
m_lineReader = aLineReader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Load
|
||||
* read the *.cmp file format contains the component footprint assignments created by CvPcb
|
||||
* into \a aNetlist.
|
||||
*
|
||||
* @param aNetlist is the #NETLIST to read into.
|
||||
*
|
||||
* @todo At some point in the future, use the footprint field in the new s-expression
|
||||
* netlist file to assign a footprint to a component instead of using a secondary
|
||||
* (*.cmp) file.
|
||||
*
|
||||
* Sample file footprint assignment entry:
|
||||
*
|
||||
* Cmp-Mod V01 Genere by CvPcb 29/10/2003-13: 11:6 *
|
||||
* BeginCmp
|
||||
* TimeStamp = /32307DE2/AA450F67;
|
||||
* Reference = C1;
|
||||
* ValeurCmp = 47uF;
|
||||
* IdModule = CP6;
|
||||
* EndCmp
|
||||
*
|
||||
* @throw IO_ERROR if a the #LINE_READER IO error occurs.
|
||||
* @throw PARSE_ERROR if an error occurs while parsing the file.
|
||||
*/
|
||||
void Load( NETLIST* aNetlist ) throw( IO_ERROR, PARSE_ERROR );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class NETLIST_READER
|
||||
* is a pure virtual class to derive a specific type of netlist reader from.
|
||||
*/
|
||||
class NETLIST_READER
|
||||
{
|
||||
private:
|
||||
PCB_EDIT_FRAME* m_pcbframe; // the main Pcbnew frame (or NULL for CvPcb)
|
||||
wxTextCtrl* m_messageWindow; // a textctrl to show messages (can be NULL)
|
||||
wxString m_netlistFullName; // The full netlist filename
|
||||
wxString m_cmplistFullName; // The full component/footprint association filename
|
||||
MODULE* m_currModule; // The footprint currently being read in netlist
|
||||
COMPONENT_INFO_LIST m_componentsInNetlist; // The list of footprints, found in netlist
|
||||
// (must be loaded from libraries)
|
||||
COMPONENT_INFO_LIST m_newModulesList; // The list of new footprints,
|
||||
// found in netlist, but not on board
|
||||
// (must be loaded from libraries)
|
||||
LIPBART_INFO_LIST m_libpartList; // For Kicad new netlist format:
|
||||
// list of libpart found in netlist
|
||||
// A libpart contains the footprint filters for CvPcb
|
||||
bool m_buildModuleListOnly; // if true read netlist, populates m_componentsInNetlist
|
||||
// but do not read and change nets and modules on board
|
||||
bool m_readLibpartSection; // if true read Libparts section,
|
||||
// and therefore the footprints filters
|
||||
enum typenetlist m_typeNetlist; // type opt the netlist currently read
|
||||
protected:
|
||||
NETLIST* m_netlist; ///< The net list to read the file(s) into.
|
||||
bool m_loadFootprintFilters; ///< Load the component footprint filters section if true.
|
||||
bool m_loadNets; ///< Load the nets section of the netlist file if true.
|
||||
LINE_READER* m_lineReader; ///< The line reader of the netlist.
|
||||
|
||||
public:
|
||||
bool m_UseCmpFile; // true to use .cmp files as component/footprint file link
|
||||
// false to use netlist only to know component/footprint link
|
||||
bool m_UseTimeStamp; // Set to true to identify footprints by time stamp
|
||||
// false to use schematic reference
|
||||
bool m_ChangeFootprints; // Set to true to change existing footprints to new ones
|
||||
// when netlist gives a different footprint name
|
||||
/// The reader used to load the footprint links. If NULL, footprint links are not read.
|
||||
CMP_READER* m_footprintReader;
|
||||
|
||||
public:
|
||||
|
||||
NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NULL )
|
||||
enum NETLIST_FILE_T
|
||||
{
|
||||
m_pcbframe = aFrame;
|
||||
m_messageWindow = aMessageWindow;
|
||||
m_UseTimeStamp = false;
|
||||
m_ChangeFootprints = false;
|
||||
m_UseCmpFile = true;
|
||||
m_buildModuleListOnly = false;
|
||||
m_readLibpartSection = false;
|
||||
m_typeNetlist = NETLIST_TYPE_UNSPECIFIED;
|
||||
UNKNOWN = -1,
|
||||
ORCAD,
|
||||
LEGACY,
|
||||
KICAD,
|
||||
|
||||
// Add new types here. Don't forget to create the appropriate class derived from
|
||||
// NETCLASS_READER and add the entry to the NETLIST_READER::GetNetlistReader()
|
||||
// function.
|
||||
};
|
||||
|
||||
NETLIST_READER( LINE_READER* aLineReader,
|
||||
NETLIST* aNetlist,
|
||||
CMP_READER* aFootprintLinkReader = NULL )
|
||||
{
|
||||
wxASSERT( aLineReader != NULL );
|
||||
|
||||
m_lineReader = aLineReader;
|
||||
m_footprintReader = aFootprintLinkReader;
|
||||
m_netlist = aNetlist;
|
||||
m_loadFootprintFilters = true;
|
||||
m_loadNets = true;
|
||||
}
|
||||
|
||||
~NETLIST_READER()
|
||||
{
|
||||
// Free modules info list:
|
||||
for( unsigned ii = 0; ii < m_newModulesList.size(); ii++ )
|
||||
delete m_componentsInNetlist[ii];
|
||||
|
||||
m_componentsInNetlist.clear();
|
||||
m_newModulesList.clear();
|
||||
|
||||
// Free libpart info list:
|
||||
for( unsigned ii = 0; ii < m_libpartList.size(); ii++ )
|
||||
delete m_libpartList[ii];
|
||||
m_libpartList.clear();
|
||||
}
|
||||
virtual ~NETLIST_READER();
|
||||
|
||||
/**
|
||||
* Function GetNetlistType
|
||||
* @return the type of netlist read:
|
||||
* NETLIST_TYPE_UNSPECIFIED: Unknown format
|
||||
* NETLIST_TYPE_ORCADPCB2: the basic format used by pcbnew
|
||||
* NETLIST_TYPE_PCBNEW: the format used by pcbnew, basic format + more info
|
||||
* NETLIST_TYPE_KICAD: the new format
|
||||
* Function GuessNetlistFileType
|
||||
* looks at \a aFileHeaderLine to see if it matches any of the netlist file types it
|
||||
* knows about.
|
||||
*
|
||||
* @param aLineReader is the #LINE_READER object containing lines from the netlist to test.
|
||||
* @return the #NETLIST_FILE_T of \a aLineReader.
|
||||
*/
|
||||
int GetNetlistType()
|
||||
{
|
||||
return m_typeNetlist;
|
||||
}
|
||||
static NETLIST_FILE_T GuessNetlistFileType( LINE_READER* aLineReader );
|
||||
|
||||
/**
|
||||
* Function GetComponentInfoList
|
||||
* @return the component info list built from the netlist
|
||||
* Function GetNetlistReader
|
||||
* attempts to determine the net list file type of \a aNetlistFileName and return the
|
||||
* appropriate NETLIST_READER type.
|
||||
*
|
||||
* @param aNetlist is the netlist to load \a aNetlistFileName into.
|
||||
* @param aNetlistFileName is the full path and file name of the net list to read.
|
||||
* @param aCompFootprintFileName is the full path and file name of the component footprint
|
||||
* associations to read. Set to wxEmptyString if loading the
|
||||
* footprint association file is not required.
|
||||
* @return the appropriate NETLIST_READER if \a aNetlistFileName is a valid netlist or
|
||||
* NULL if \a aNetlistFileName is not a valid netlist files.
|
||||
*/
|
||||
COMPONENT_INFO_LIST& GetComponentInfoList()
|
||||
{
|
||||
return m_componentsInNetlist;
|
||||
}
|
||||
static NETLIST_READER* GetNetlistReader( NETLIST* aNetlist,
|
||||
const wxString& aNetlistFileName,
|
||||
const wxString& aCompFootprintFileName = wxEmptyString )
|
||||
throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function GetComponentInfoList
|
||||
* @return a reference to the libpart info corresponding to a given part
|
||||
* @param aPartname = the name of the libpart
|
||||
* Function LoadNetlist
|
||||
* loads the contents of the netlist file into \a aNetlist.
|
||||
*
|
||||
* @throw IO_ERROR if a file IO error occurs.
|
||||
* @throw PARSE_ERROR if an error occurs while parsing the file.
|
||||
*/
|
||||
LIPBART_INFO* GetLibpart(const wxString & aPartname);
|
||||
virtual void LoadNetlist() throw ( IO_ERROR, PARSE_ERROR ) = 0;
|
||||
|
||||
/**
|
||||
* Function IsCvPcbMode
|
||||
* @return true if the netlist is read by CvPcb
|
||||
* In cvpcb mode, nets are stored in module info,
|
||||
* and the footprint filters list is read.
|
||||
* There is also no board in CvPcb
|
||||
* Function GetLineReader()
|
||||
* @return the #LINE_READER associated with the #NETLIST_READER.
|
||||
*/
|
||||
bool IsCvPcbMode() { return m_pcbframe == 0; }
|
||||
LINE_READER* GetLineReader();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class LEGACY_NETLIST_READER
|
||||
* reads the KiCad legacy and the old Orcad netlist formats.
|
||||
*
|
||||
* The KiCad legacy netlist format was derived directly from an old Orcad netlist format. The
|
||||
* primary difference is the header was changed so this reader can read both formats.
|
||||
*/
|
||||
class LEGACY_NETLIST_READER : public NETLIST_READER
|
||||
{
|
||||
/**
|
||||
* Function AddModuleInfo
|
||||
* Add a new module info to the main list of modules ifo
|
||||
* @param aModInfo = a reference to the item to add
|
||||
* Function loadComponent
|
||||
* read the \a aLine containing the description of a component from a legacy format
|
||||
* netlist and add it to the netlist.
|
||||
*
|
||||
* Analyze the first line of a component description in netlist:
|
||||
* ( /40C08647 $noname R20 4.7K {Lib=R}
|
||||
*
|
||||
* @param aText contains the first line of description
|
||||
* @return the new component created by parsing \a aLine
|
||||
* @throw PARSE_ERROR when \a aLine is not a valid component description.
|
||||
*/
|
||||
void AddModuleInfo( COMPONENT_INFO* aModInfo )
|
||||
{
|
||||
m_componentsInNetlist.push_back( aModInfo );
|
||||
}
|
||||
COMPONENT* loadComponent( char* aText ) throw( PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function AddLibpartInfo
|
||||
* LIPBART_INFO items (and therefore footprint filter strings) are stored in
|
||||
* m_libpartList
|
||||
* @param aPartInfo = a refernce to the LIPBART_INFO to add in list
|
||||
*/
|
||||
void AddLibpartInfo( LIPBART_INFO * aPartInfo )
|
||||
{
|
||||
m_libpartList.push_back( aPartInfo );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ReadLibpartSectionSetOpt
|
||||
* Set to true or false the read Partlists section.
|
||||
* footprint filters are found in this section
|
||||
* When this option is false, the Partlists section is ignored
|
||||
* When this option is true, the Partlists section is read,
|
||||
* Libpart items (and therefore footprint filter strings) are stored in
|
||||
* m_libpartList
|
||||
* @param aOpt = the value of option
|
||||
*/
|
||||
void ReadLibpartSectionSetOpt( bool aOpt )
|
||||
{
|
||||
m_readLibpartSection = aOpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ReadLibpartSectionOpt
|
||||
* @return the readPartlist option
|
||||
*/
|
||||
bool ReadLibpartSectionOpt() { return m_readLibpartSection; }
|
||||
|
||||
/**
|
||||
* Function BuildModuleListOnlySetOpt
|
||||
* Set to true or false the Build Module List Only option
|
||||
* When this option is false, a full netlist read is made,
|
||||
* and modules are added/modified
|
||||
* When this option is true, a partial netlist read is made
|
||||
* and only the list of modules found in netlist is built
|
||||
* @param aOpt = the value of option
|
||||
*/
|
||||
void BuildModuleListOnlySetOpt( bool aOpt )
|
||||
{
|
||||
m_buildModuleListOnly = aOpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function BuildModuleListOnlyOpt
|
||||
* Get the Build Module List Only option state
|
||||
* @return the state of option (true/false)
|
||||
*/
|
||||
bool BuildModuleListOnlyOpt()
|
||||
{
|
||||
return m_buildModuleListOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function InitializeModules
|
||||
* Called when reading a netlist and after the module info list is populated
|
||||
* Load new module and clear pads netnames
|
||||
* return true if all modules are loaded, false if some are missing
|
||||
*/
|
||||
bool InitializeModules();
|
||||
|
||||
/**
|
||||
* Function TestFootprintsMatchingAndExchange
|
||||
* Called when reading a netlist, after the module info list is populated
|
||||
* module reference updated (after a call to InitializeModules)
|
||||
* Test, for each module, if the current footprint matches the footprint
|
||||
* given by the netlist (or the cmp file, if used)
|
||||
* print a list of mismatches od exchange footprints i
|
||||
* m_ChangeFootprints == true
|
||||
*/
|
||||
void TestFootprintsMatchingAndExchange();
|
||||
|
||||
|
||||
/**
|
||||
* Function SetFilesnames
|
||||
* initialize filenames
|
||||
* @param aNetlistFileName = full filename of netlist
|
||||
* @param aCmplistFileName = full filename of components file (can be empty)
|
||||
* and the components file will be non used
|
||||
*/
|
||||
void SetFilesnames( const wxString& aNetlistFileName,
|
||||
const wxString& aCmplistFileName )
|
||||
{
|
||||
m_netlistFullName = aNetlistFileName;
|
||||
m_cmplistFullName = aCmplistFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ReadNetList
|
||||
* The main function to detect a netlist format, read the netlist,
|
||||
* and update the board
|
||||
* depending on the detected format, calls ReadOldFmtdNetList or ReadKicadNetList
|
||||
* @param aFile = the already opened file (will be closed by the netlist reader)
|
||||
* @return true if success
|
||||
*/
|
||||
bool ReadNetList( FILE* aFile );
|
||||
|
||||
/**
|
||||
* Function ReadOldFmtdNetList
|
||||
* The main function to read a netlist (old netlist format),
|
||||
* and update the board
|
||||
* @param aFile = the already opened file (will be closed by ReadOldFmtdNetList)
|
||||
* @return true if success
|
||||
*/
|
||||
bool ReadOldFmtdNetList( FILE* aFile );
|
||||
|
||||
/**
|
||||
* Function ReadOldFmtFootprintFilterList
|
||||
* Read the section "Allowed footprints" like:
|
||||
* Function loadFootprintFilters
|
||||
* loads the footprint filter section of netlist file.
|
||||
*
|
||||
* Sample legacy footprint filter section:
|
||||
* { Allowed footprints by component:
|
||||
* $component R11
|
||||
* R?
|
||||
|
@ -342,99 +511,168 @@ public:
|
|||
* $endfootprintlist
|
||||
* }
|
||||
*
|
||||
* And add the strings giving the footprint filter to m_FootprintFilter
|
||||
* @throw IO_ERROR if a file IO error occurs.
|
||||
* @throw PARSE_ERROR if an error occurs while parsing the file.
|
||||
*/
|
||||
void loadFootprintFilters() throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function loadNet
|
||||
* read a component net description from \a aText.
|
||||
*
|
||||
* @param aText is current line read from the netlist.
|
||||
* @param aComponent is the component to add the net to.
|
||||
* @throw PARSE_ERROR if a error occurs reading \a aText.
|
||||
*/
|
||||
void loadNet( char* aText, COMPONENT* aComponent ) throw( PARSE_ERROR );
|
||||
|
||||
public:
|
||||
|
||||
LEGACY_NETLIST_READER( LINE_READER* aLineReader,
|
||||
NETLIST* aNetlist,
|
||||
CMP_READER* aFootprintLinkReader = NULL ) :
|
||||
NETLIST_READER( aLineReader, aNetlist, aFootprintLinkReader )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Function LoadNetlist
|
||||
* read the netlist file in the legacy format into \a aNetlist.
|
||||
*
|
||||
* The legacy netlist format is:
|
||||
* \# EESchema Netlist Version 1.0 generee le 18/5/2005-12:30:22
|
||||
* (
|
||||
* ( 40C08647 $noname R20 4,7K {Lib=R}
|
||||
* ( 1 VCC )
|
||||
* ( 2 MODB_1 )
|
||||
* )
|
||||
* ( 40C0863F $noname R18 4,7_k {Lib=R}
|
||||
* ( 1 VCC )
|
||||
* ( 2 MODA_1 )
|
||||
* )
|
||||
* }
|
||||
* \#End
|
||||
*
|
||||
* @throw IO_ERROR if a file IO error occurs.
|
||||
* @throw PARSE_ERROR if an error occurs while parsing the file.
|
||||
*/
|
||||
virtual void LoadNetlist() throw ( IO_ERROR, PARSE_ERROR );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class KICAD_NETLIST_PARSER
|
||||
* is the parser for reading the KiCad s-expression netlist format.
|
||||
*/
|
||||
class KICAD_NETLIST_PARSER : public NETLIST_LEXER
|
||||
{
|
||||
private:
|
||||
T token;
|
||||
LINE_READER* m_lineReader; ///< The line reader used to parse the netlist. Not owned.
|
||||
NETLIST* m_netlist; ///< The netlist to parse into. Not owned.
|
||||
|
||||
/**
|
||||
* Function skipCurrent
|
||||
* Skip the current token level, i.e
|
||||
* search for the RIGHT parenthesis which closes the current description
|
||||
*/
|
||||
void skipCurrent() throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function parseComponent
|
||||
* parse a component description:
|
||||
* (comp (ref P1)
|
||||
* (value DB25FEMELLE)
|
||||
* (footprint DB25FC)
|
||||
* (libsource (lib conn) (part DB25))
|
||||
* (sheetpath (names /) (tstamps /))
|
||||
* (tstamp 3256759C))
|
||||
*/
|
||||
void parseComponent() throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function parseNet
|
||||
* Parses a section like
|
||||
* (net (code 20) (name /PC-A0)
|
||||
* (node (ref BUS1) (pin 62))
|
||||
* (node (ref U3) (pin 3))
|
||||
* (node (ref U9) (pin M6)))
|
||||
*
|
||||
* and set the corresponding pads netnames
|
||||
*/
|
||||
void parseNet() throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function parseLibPartList
|
||||
* reads the section "libparts" in the netlist:
|
||||
* (libparts
|
||||
* (libpart (lib device) (part C)
|
||||
* (description "Condensateur non polarise")
|
||||
* (footprints
|
||||
* (fp SM*)
|
||||
* (fp C?)
|
||||
* (fp C1-1))
|
||||
* (fields
|
||||
* (field (name Reference) C)
|
||||
* (field (name Value) C))
|
||||
* (pins
|
||||
* (pin (num 1) (name ~) (type passive))
|
||||
* (pin (num 2) (name ~) (type passive))))
|
||||
*
|
||||
* And add the strings giving the footprint filter (subsection footprints)
|
||||
* of the corresponding module info
|
||||
* <p>This section is used by CvPcb, and is not useful in Pcbnew,
|
||||
* therefore it it not always read </p>
|
||||
*/
|
||||
bool ReadOldFmtFootprintFilterList( FILE_LINE_READER& aNetlistReader );
|
||||
void parseLibPartList() throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
|
||||
public:
|
||||
KICAD_NETLIST_PARSER( LINE_READER* aReader, NETLIST* aNetlist );
|
||||
|
||||
void SetLineReader( LINE_READER* aLineReader );
|
||||
|
||||
void SetNetlist( NETLIST* aNetlist ) { m_netlist = aNetlist; }
|
||||
|
||||
/**
|
||||
* Function ReadKicadNetList
|
||||
* The main function to read a netlist (new netlist format, using S expressions),
|
||||
* and update the board
|
||||
* @param aFile = the already opened file (will be closed by ReadKicadNetList)
|
||||
* @return true if success
|
||||
* Function Parse
|
||||
* parse the full netlist
|
||||
*/
|
||||
bool ReadKicadNetList( FILE* aFile );
|
||||
void Parse() throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* function RemoveExtraFootprints
|
||||
* Remove (delete) not locked footprints found on board, but not in netlist
|
||||
* The netlist is expected to be read, and the main module list info up to date
|
||||
*/
|
||||
void RemoveExtraFootprints( );
|
||||
|
||||
/**
|
||||
* Function SetPadsNetName
|
||||
* Update pads netnames for a given module.
|
||||
* Because a pad name can be found more than once in this module,
|
||||
* all pads matching the pad name are updated
|
||||
* @param aModule = module reference
|
||||
* @param aPadname = pad name (pad num)
|
||||
* @param aNetname = new net name of the pad
|
||||
* @param aPadList = a std::vector<D_PAD*>& buffer where the updated pads can be stored
|
||||
* @return the pad count
|
||||
*/
|
||||
int SetPadsNetName( const wxString & aModule, const wxString & aPadname,
|
||||
const wxString & aNetname, std::vector<D_PAD*> & aPadList );
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Function FindModule
|
||||
* search for a module id the modules existing in the current BOARD.
|
||||
* @param aId = the key to identify the module to find:
|
||||
* The reference or the full time stamp, according to m_UseTimeStamp
|
||||
* @return the module found, or NULL.
|
||||
*/
|
||||
MODULE* FindModule( const wxString& aId );
|
||||
|
||||
/**
|
||||
* Function SetPadNetName
|
||||
* Update a pad netname using the current footprint
|
||||
* from the netlist (line format: ( \<pad number\> \<net name\> ) )
|
||||
* @param aText = current line read from netlist
|
||||
*/
|
||||
bool SetPadNetName( char* aText );
|
||||
|
||||
/**
|
||||
* Function ReadOldFmtNetlistModuleDescr
|
||||
* Read the full description of a footprint, from the netlist
|
||||
* and update the corresponding module.
|
||||
* @param aBuildList bool to switch between 2 modes:
|
||||
* aBuildList = true:
|
||||
* add module info added to m_newModulesList
|
||||
* aBuildList = false:
|
||||
* The module is searched in the board modules list
|
||||
* @param aText contains the first line of description
|
||||
* This function uses m_useFichCmp as a flag to know the footprint name:
|
||||
* If true: component file *.cmp is used
|
||||
* If false: the netlist only is used
|
||||
* This flag is reset to false if the .cmp file is not found
|
||||
* @return if aBuildList = true, a reference to the COMPONENT_INFO
|
||||
* if aBuildList = false, a reference to the corresponding MODULE on board (NULL if not found)
|
||||
*/
|
||||
void* ReadOldFmtNetlistModuleDescr( char* aText, bool aBuildList );
|
||||
|
||||
/**
|
||||
* Function loadNewModules
|
||||
* Load from libraries new modules found in netlist and add them to the current Board.
|
||||
* modules to load come from m_newModulesList
|
||||
* @return false if a footprint is not found, true if all footprints are loaded
|
||||
*/
|
||||
bool loadNewModules();
|
||||
|
||||
/**
|
||||
* function readModuleComponentLinkfile
|
||||
* read the *.cmp file ( filename in m_cmplistFullName )
|
||||
* and initialize the m_Footprint member of each item in m_componentsInNetlist,
|
||||
* when it is found in file, and with a non empty footprint value
|
||||
* giving the equivalence between footprint names and components
|
||||
* to find the footprint name corresponding to aCmpIdent
|
||||
* @return true and the file can be read
|
||||
*/
|
||||
bool readModuleComponentLinkfile();
|
||||
// Useful for debug only:
|
||||
const char* getTokenName( T aTok )
|
||||
{
|
||||
return NETLIST_LEXER::TokenName( aTok );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // NETLIST_READER_H
|
||||
|
||||
/**
|
||||
* Class KICAD_NETLIST_READER
|
||||
* read the new s-expression based KiCad netlist format.
|
||||
*/
|
||||
class KICAD_NETLIST_READER : public NETLIST_READER
|
||||
{
|
||||
KICAD_NETLIST_PARSER* m_parser; ///< The s-expression format parser.
|
||||
|
||||
public:
|
||||
KICAD_NETLIST_READER( LINE_READER* aLineReader,
|
||||
NETLIST* aNetlist,
|
||||
CMP_READER* aFootprintLinkReader = NULL ) :
|
||||
NETLIST_READER( aLineReader, aNetlist, aFootprintLinkReader ),
|
||||
m_parser( new KICAD_NETLIST_PARSER( aLineReader, aNetlist ) )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~KICAD_NETLIST_READER()
|
||||
{
|
||||
if( m_parser )
|
||||
delete m_parser;
|
||||
}
|
||||
|
||||
virtual void LoadNetlist() throw ( IO_ERROR, PARSE_ERROR );
|
||||
};
|
||||
|
||||
|
||||
#endif // NETLIST_READER_H
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 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
|
||||
|
@ -27,584 +28,392 @@
|
|||
|
||||
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <wxPcbStruct.h>
|
||||
#include <richio.h>
|
||||
#include <macros.h>
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
#include <pcbnew.h>
|
||||
#include <kicad_string.h>
|
||||
#include <reporter.h>
|
||||
|
||||
#include <netlist_reader.h>
|
||||
#include <class_module.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <wx/regex.h>
|
||||
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
bool NETLIST_READER::ReadNetList( FILE* aFile )
|
||||
{
|
||||
// Try to determine the netlist type:
|
||||
// Beginning of the first line of known formats, without spaces
|
||||
#define HEADERS_COUNT 3
|
||||
#define HEADER_ORCADPCB "({EESchemaNetlist"
|
||||
#define HEADER_PCBNEW "#EESchemaNetlist"
|
||||
#define HEADER_KICAD_NETFMT "(export"
|
||||
const std::string headers[HEADERS_COUNT] =
|
||||
{
|
||||
HEADER_ORCADPCB, HEADER_PCBNEW, HEADER_KICAD_NETFMT
|
||||
};
|
||||
|
||||
int format = -1;
|
||||
for ( int jj = 0; jj < HEADERS_COUNT; jj++ )
|
||||
{
|
||||
int imax = headers[jj].size();
|
||||
int ii = 0;
|
||||
for( ; ii < imax; ii++ )
|
||||
{
|
||||
int data;
|
||||
// Read header, and skip blanks to avoid errors if an header changes
|
||||
do
|
||||
{
|
||||
data = fgetc( aFile );
|
||||
} while ( ( data == ' ' ) &&( EOF != data ) ) ;
|
||||
|
||||
if( (int)headers[jj][ii] == data )
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if( ii == imax ) // header found
|
||||
{
|
||||
format = jj;
|
||||
break;
|
||||
}
|
||||
rewind( aFile );
|
||||
}
|
||||
|
||||
rewind( aFile );
|
||||
bool success = false;
|
||||
switch( format )
|
||||
{
|
||||
case 0:
|
||||
m_typeNetlist = NETLIST_TYPE_ORCADPCB2;
|
||||
success = ReadOldFmtdNetList( aFile );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_typeNetlist = NETLIST_TYPE_PCBNEW;
|
||||
success = ReadOldFmtdNetList( aFile );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_typeNetlist = NETLIST_TYPE_KICAD;
|
||||
success = ReadKicadNetList( aFile );
|
||||
break;
|
||||
|
||||
default: // Unrecognized format:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetComponentInfoList
|
||||
* @return a reference to the libpart info corresponding to a given part
|
||||
* @param aPartname = the name of the libpart
|
||||
*/
|
||||
LIPBART_INFO* NETLIST_READER::GetLibpart(const wxString & aPartname)
|
||||
* 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( unsigned ii = 0; ii < m_libpartList.size(); ii++ )
|
||||
{
|
||||
if( m_libpartList[ii]->m_Libpart == aPartname )
|
||||
return m_libpartList[ii];
|
||||
}
|
||||
for( int i = 0; i < aNestLevel; ++i )
|
||||
aReporter.Report( wxT( " " ) );
|
||||
|
||||
return NULL;
|
||||
return aReporter;
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST_READER::InitializeModules()
|
||||
#if defined(DEBUG)
|
||||
void COMPONENT_NET::Show( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
if( m_UseCmpFile ) // Try to get footprint name from .cmp file
|
||||
{
|
||||
readModuleComponentLinkfile();
|
||||
}
|
||||
|
||||
if( m_pcbframe == NULL )
|
||||
return true;
|
||||
|
||||
for( unsigned ii = 0; ii < m_componentsInNetlist.size(); ii++ )
|
||||
{
|
||||
COMPONENT_INFO* currcmp_info = m_componentsInNetlist[ii];
|
||||
// Test if module is already loaded.
|
||||
wxString * idMod = m_UseTimeStamp?
|
||||
&currcmp_info->m_TimeStamp : &currcmp_info->m_Reference;
|
||||
|
||||
MODULE* module = FindModule( *idMod );
|
||||
if( module == NULL ) // not existing, load it
|
||||
{
|
||||
m_newModulesList.push_back( currcmp_info );
|
||||
}
|
||||
}
|
||||
|
||||
bool success = loadNewModules();
|
||||
|
||||
// Update modules fields
|
||||
for( unsigned ii = 0; ii < m_componentsInNetlist.size(); ii++ )
|
||||
{
|
||||
COMPONENT_INFO* currcmp_info = m_componentsInNetlist[ii];
|
||||
// Test if module is already loaded.
|
||||
wxString * idMod = m_UseTimeStamp?
|
||||
&currcmp_info->m_TimeStamp : &currcmp_info->m_Reference;
|
||||
|
||||
MODULE* module = FindModule( *idMod );
|
||||
if( module )
|
||||
{
|
||||
// Update current module ( reference, value and "Time Stamp")
|
||||
module->SetReference( currcmp_info->m_Reference );
|
||||
module->SetValue(currcmp_info->m_Value );
|
||||
module->SetPath( currcmp_info->m_TimeStamp );
|
||||
}
|
||||
else // not existing
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// clear pads netnames
|
||||
#if 1
|
||||
// Clear only footprints found in netlist:
|
||||
// This allow to have some footprints added by hand to the board
|
||||
// left initialized
|
||||
for( unsigned ii = 0; ii < m_componentsInNetlist.size(); ii++ )
|
||||
{
|
||||
COMPONENT_INFO* currcmp_info = m_componentsInNetlist[ii];
|
||||
// We can used the reference to find the footprint, because
|
||||
// it is now updated
|
||||
wxString * idMod = &currcmp_info->m_Reference;
|
||||
|
||||
MODULE* module = FindModule( *idMod );
|
||||
if( module )
|
||||
{
|
||||
for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
|
||||
pad->SetNetname( wxEmptyString );
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
// Clear all footprints
|
||||
for( MODULE* module = m_pcbframe->GetBoard()->m_Modules; module; module = module->Next() )
|
||||
{
|
||||
for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
|
||||
pad->SetNetname( wxEmptyString );
|
||||
}
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( wxString::Format( wxT( "<pin_name=%s net_name=%s>\n" ),
|
||||
GetChars( m_pinName ), GetChars( m_netName ) ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
return success;
|
||||
|
||||
void COMPONENT::SetModule( MODULE* aModule )
|
||||
{
|
||||
m_footprint.reset( aModule );
|
||||
|
||||
if( aModule == NULL )
|
||||
return;
|
||||
|
||||
aModule->SetReference( m_reference );
|
||||
aModule->SetValue( m_value );
|
||||
aModule->SetLibRef( m_footprintLibName );
|
||||
aModule->SetPath( m_timeStamp );
|
||||
}
|
||||
|
||||
void NETLIST_READER::TestFootprintsMatchingAndExchange()
|
||||
|
||||
COMPONENT_NET COMPONENT::m_emptyNet;
|
||||
|
||||
|
||||
const COMPONENT_NET& COMPONENT::GetNet( const wxString& aPinName )
|
||||
{
|
||||
#ifdef PCBNEW
|
||||
|
||||
// If a module is "exchanged", the new module is added to the end of
|
||||
// module list.
|
||||
|
||||
// Calculates the module count
|
||||
int moduleCount = m_pcbframe->GetBoard()->m_Modules.GetCount();
|
||||
|
||||
MODULE* nextmodule;
|
||||
MODULE *module = m_pcbframe->GetBoard()->m_Modules;
|
||||
for( ; module && moduleCount; module = nextmodule, moduleCount-- )
|
||||
for( unsigned i = 0; i < m_nets.size(); i++ )
|
||||
{
|
||||
// Module can be deleted if exchanged, so store the next module.
|
||||
nextmodule = module->Next();
|
||||
if( m_nets[i].GetPinName() == aPinName )
|
||||
return m_nets[i];
|
||||
}
|
||||
|
||||
// Search for the corresponding module info
|
||||
COMPONENT_INFO * cmp_info = NULL;
|
||||
for( unsigned ii = 0; ii < m_componentsInNetlist.size(); ii++ )
|
||||
return m_emptyNet;
|
||||
}
|
||||
|
||||
|
||||
#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 fpid=%s timestamp=%s>\n" ),
|
||||
GetChars( m_reference ), GetChars( m_value ),
|
||||
GetChars( m_name ), GetChars( m_footprintLibName ),
|
||||
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++ )
|
||||
{
|
||||
COMPONENT_INFO * candidate = m_componentsInNetlist[ii];
|
||||
// Test if cmp_info matches the current module:
|
||||
if( candidate->m_Reference.CmpNoCase( module->GetReference() ) == 0 )
|
||||
{
|
||||
cmp_info = candidate;
|
||||
break;
|
||||
}
|
||||
NestedSpace( aNestLevel+2, aReporter );
|
||||
aReporter.Report( wxString::Format( wxT( "<%s>\n" ),
|
||||
GetChars( m_footprintFilters[i] ) ) );
|
||||
}
|
||||
|
||||
if( cmp_info == NULL ) // not found in netlist
|
||||
continue;
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( wxT( "</fp_filters>\n" ) );
|
||||
}
|
||||
|
||||
if( module->GetLibRef().CmpNoCase( cmp_info->m_Footprint ) != 0 )
|
||||
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 )
|
||||
{
|
||||
if( m_ChangeFootprints ) // footprint exchange allowed.
|
||||
{
|
||||
MODULE* newModule = m_pcbframe->GetModuleLibrary( wxEmptyString,
|
||||
cmp_info->m_Footprint,
|
||||
false );
|
||||
|
||||
if( newModule )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Module ref %s, change footprint %s to %s\n" ),
|
||||
GetChars( module->GetReference() ),
|
||||
GetChars( module->GetLibRef() ),
|
||||
GetChars( cmp_info->m_Footprint ) );
|
||||
m_messageWindow->AppendText( msg );
|
||||
// Change old module to the new module (and delete the old one)
|
||||
m_pcbframe->Exchange_Module( module, newModule, NULL );
|
||||
}
|
||||
else if( m_messageWindow )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Component %s: module %s not found\n" ),
|
||||
GetChars( cmp_info->m_Reference ),
|
||||
GetChars( cmp_info->m_Footprint ) );
|
||||
|
||||
m_messageWindow->AppendText( msg );
|
||||
}
|
||||
}
|
||||
else if( m_messageWindow )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Component %s: Mismatch! module is %s and netlist said %s\n" ),
|
||||
GetChars( cmp_info->m_Reference ),
|
||||
GetChars( module->GetLibRef() ),
|
||||
GetChars( cmp_info->m_Footprint ) );
|
||||
|
||||
m_messageWindow->AppendText( msg );
|
||||
}
|
||||
component = &m_components[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
COMPONENT* NETLIST::GetComponentByLibName( const wxString& aLibName )
|
||||
{
|
||||
COMPONENT* component = NULL;
|
||||
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
if( m_components[i].GetLibName() == aLibName )
|
||||
{
|
||||
component = &m_components[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function SetPadsNetName
|
||||
* Update pads netnames for a given module.
|
||||
* Because a pad name can be found more than once in this module,
|
||||
* all pads matching the pad name are updated
|
||||
* @param aModule = module reference
|
||||
* @param aPadname = pad name (pad num)
|
||||
* @param aNetname = new net name of the pad
|
||||
* @param aPadList = a std::vector<D_PAD*>& buffer where the updated pads can be stored
|
||||
* @return the pad count
|
||||
* Function SortByLibName
|
||||
* is a helper function used to sort the component list used by loadNewModules.
|
||||
*/
|
||||
int NETLIST_READER::SetPadsNetName( const wxString & aModule, const wxString & aPadname,
|
||||
const wxString & aNetname, std::vector<D_PAD*> & aPadList )
|
||||
static bool SortByLibName( const COMPONENT& ref, const COMPONENT& cmp )
|
||||
{
|
||||
if( m_pcbframe == NULL )
|
||||
return 0;
|
||||
|
||||
int padcount = 0;
|
||||
MODULE* module = m_pcbframe->GetBoard()->FindModuleByReference( aModule );
|
||||
|
||||
if( module )
|
||||
{
|
||||
D_PAD * pad = module->FindPadByName( aPadname );
|
||||
|
||||
if( pad )
|
||||
{
|
||||
padcount++;
|
||||
aPadList.push_back( pad );
|
||||
pad->SetNetname( aNetname );
|
||||
// Search for other pads having the same pad name/num
|
||||
for( D_PAD* curr_pad = pad->Next(); curr_pad; curr_pad = curr_pad->Next() )
|
||||
{
|
||||
if( pad->PadNameEqual( curr_pad ) )
|
||||
{
|
||||
padcount++;
|
||||
aPadList.push_back( curr_pad );
|
||||
curr_pad->SetNetname( aNetname );
|
||||
}
|
||||
}
|
||||
return padcount;
|
||||
}
|
||||
|
||||
if( m_messageWindow )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Module %s: Pad %s not found" ),
|
||||
GetChars( aModule ), GetChars( aPadname ) );
|
||||
m_messageWindow->AppendText( msg + wxT( "\n" ) );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ref.GetFootprintLibName().CmpNoCase( cmp.GetFootprintLibName() ) > 0;
|
||||
}
|
||||
|
||||
|
||||
/* function RemoveExtraFootprints
|
||||
* Remove (delete) not locked footprints found on board, but not in netlist
|
||||
*/
|
||||
void NETLIST_READER::RemoveExtraFootprints()
|
||||
void NETLIST::SortByFootprintLibName()
|
||||
{
|
||||
MODULE* nextModule;
|
||||
MODULE* module = m_pcbframe->GetBoard()->m_Modules;
|
||||
sort( m_components.begin(), m_components.end(), SortByLibName );
|
||||
}
|
||||
|
||||
for( ; module != NULL; module = nextModule )
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
sort( m_components.begin(), m_components.end() );
|
||||
}
|
||||
|
||||
|
||||
#if defined( DEBUG )
|
||||
void NETLIST::Show( int aNestLevel, REPORTER& aReporter )
|
||||
{
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( "<netlist>\n" );
|
||||
|
||||
if( !m_components.empty() )
|
||||
{
|
||||
unsigned ii;
|
||||
nextModule = module->Next();
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
aReporter.Report( "<components>\n" );
|
||||
|
||||
if( module->IsLocked() )
|
||||
continue;
|
||||
|
||||
for( ii = 0; ii < m_componentsInNetlist.size(); ii++ )
|
||||
for( unsigned i = 0; i < m_components.size(); i++ )
|
||||
{
|
||||
COMPONENT_INFO* cmp_info = m_componentsInNetlist[ii];
|
||||
|
||||
if( module->GetReference().CmpNoCase( cmp_info->m_Reference ) == 0 )
|
||||
break; // Module is found in net list.
|
||||
m_components[i].Show( aNestLevel+2, aReporter );
|
||||
}
|
||||
|
||||
if( ii == m_componentsInNetlist.size() ) // Module not found in netlist.
|
||||
module->DeleteStructure();
|
||||
NestedSpace( aNestLevel+1, aReporter );
|
||||
|
||||
aReporter.Report( "</components>\n" );
|
||||
}
|
||||
|
||||
NestedSpace( aNestLevel, aReporter );
|
||||
aReporter.Report( "</netlist>\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
NETLIST_READER::~NETLIST_READER()
|
||||
{
|
||||
if( m_lineReader )
|
||||
{
|
||||
delete m_lineReader;
|
||||
m_lineReader = NULL;
|
||||
}
|
||||
|
||||
if( m_footprintReader )
|
||||
{
|
||||
delete m_footprintReader;
|
||||
m_footprintReader = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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 )
|
||||
|
||||
NETLIST_READER::NETLIST_FILE_T NETLIST_READER::GuessNetlistFileType( LINE_READER* aLineReader )
|
||||
{
|
||||
MODULE* module = m_pcbframe->GetBoard()->m_Modules;
|
||||
for( ; module != NULL; module = module->Next() )
|
||||
wxRegEx reOrcad( wxT( "(?i)[ ]*\\({EESchema[ \t]+Netlist[ \t]+" ), wxRE_ADVANCED );
|
||||
wxASSERT( reOrcad.IsValid() );
|
||||
wxRegEx reLegacy( wxT( "(?i)#[ \t]+EESchema[ \t]+Netlist[ \t]+" ), wxRE_ADVANCED );
|
||||
wxASSERT( reLegacy.IsValid() );
|
||||
wxRegEx reKicad( wxT( "[ ]*\\(export[ ]+" ), wxRE_ADVANCED );
|
||||
wxASSERT( reKicad.IsValid() );
|
||||
|
||||
wxString line;
|
||||
|
||||
while( aLineReader->ReadLine() )
|
||||
{
|
||||
if( m_UseTimeStamp ) // identification by time stamp
|
||||
{
|
||||
if( aId.CmpNoCase( module->GetPath() ) == 0 )
|
||||
return module;
|
||||
}
|
||||
else // identification by Reference
|
||||
{
|
||||
if( aId.CmpNoCase( module->GetReference() ) == 0 )
|
||||
return module;
|
||||
}
|
||||
line = FROM_UTF8( aLineReader->Line() );
|
||||
|
||||
if( reOrcad.Matches( line ) )
|
||||
return ORCAD;
|
||||
else if( reLegacy.Matches( line ) )
|
||||
return LEGACY;
|
||||
else if( reKicad.Matches( line ) )
|
||||
return KICAD;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* function readModuleComponentLinkfile
|
||||
* read the *.cmp file ( filename in m_cmplistFullName )
|
||||
* giving the equivalence Footprint_names / components
|
||||
* to find the footprint name corresponding to aCmpIdent
|
||||
* return true if the file can be read
|
||||
*
|
||||
* Sample file:
|
||||
*
|
||||
* Cmp-Mod V01 Genere by CvPcb 29/10/2003-13: 11:6 *
|
||||
* BeginCmp
|
||||
* TimeStamp = /32307DE2/AA450F67;
|
||||
* Reference = C1;
|
||||
* ValeurCmp = 47uF;
|
||||
* IdModule = CP6;
|
||||
* EndCmp
|
||||
*
|
||||
*/
|
||||
|
||||
bool NETLIST_READER::readModuleComponentLinkfile()
|
||||
NETLIST_READER* NETLIST_READER::GetNetlistReader( NETLIST* aNetlist,
|
||||
const wxString& aNetlistFileName,
|
||||
const wxString& aCompFootprintFileName )
|
||||
throw( IO_ERROR )
|
||||
{
|
||||
wxString refcurrcmp; // Stores value read from line like Reference = BUS1;
|
||||
wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67;
|
||||
wxString footprint; // Stores value read from line like IdModule = CP6;
|
||||
wxASSERT( aNetlist != NULL );
|
||||
|
||||
FILE* cmpFile = wxFopen( m_cmplistFullName, wxT( "rt" ) );
|
||||
FILE* file = wxFopen( aNetlistFileName, wxT( "rt" ) );
|
||||
|
||||
if( cmpFile == NULL )
|
||||
if( file == NULL )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "File <%s> not found, use Netlist for footprints selection" ),
|
||||
GetChars( m_cmplistFullName ) );
|
||||
|
||||
if( m_messageWindow )
|
||||
m_messageWindow->AppendText( msg );
|
||||
return false;
|
||||
msg.Printf( _( "Cannot open file %s for reading." ), GetChars( aNetlistFileName ) );
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
// netlineReader dtor will close cmpFile
|
||||
FILE_LINE_READER netlineReader( cmpFile, m_cmplistFullName );
|
||||
FILE_LINE_READER* reader = new FILE_LINE_READER( file, aNetlistFileName );
|
||||
std::auto_ptr< FILE_LINE_READER > r( reader );
|
||||
|
||||
NETLIST_FILE_T type = GuessNetlistFileType( reader );
|
||||
reader->Rewind();
|
||||
|
||||
// The component footprint link reader is NULL if no file name was specified.
|
||||
CMP_READER* cmpFileReader = NULL;
|
||||
|
||||
if( !aCompFootprintFileName.IsEmpty() )
|
||||
{
|
||||
cmpFileReader = new CMP_READER( new FILE_LINE_READER( aCompFootprintFileName ) );
|
||||
}
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case LEGACY:
|
||||
case ORCAD:
|
||||
return new LEGACY_NETLIST_READER( r.release(), aNetlist, cmpFileReader );
|
||||
|
||||
case KICAD:
|
||||
return new KICAD_NETLIST_READER( r.release(), aNetlist, cmpFileReader );
|
||||
|
||||
default: // Unrecognized format:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void CMP_READER::Load( NETLIST* aNetlist ) throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
wxCHECK_RET( aNetlist != NULL, wxT( "No netlist passed to CMP_READER::Load()" ) );
|
||||
|
||||
wxString reference; // Stores value read from line like Reference = BUS1;
|
||||
wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67;
|
||||
wxString footprint; // Stores value read from line like IdModule = CP6;
|
||||
wxString buffer;
|
||||
wxString value;
|
||||
|
||||
while( netlineReader.ReadLine() )
|
||||
{
|
||||
buffer = FROM_UTF8( netlineReader.Line() );
|
||||
|
||||
if( ! buffer.StartsWith( wxT("BeginCmp") ) )
|
||||
while( m_lineReader->ReadLine() )
|
||||
{
|
||||
buffer = FROM_UTF8( m_lineReader->Line() );
|
||||
|
||||
if( !buffer.StartsWith( wxT( "BeginCmp" ) ) )
|
||||
continue;
|
||||
|
||||
// Begin component description.
|
||||
refcurrcmp.Empty();
|
||||
reference.Empty();
|
||||
footprint.Empty();
|
||||
timestamp.Empty();
|
||||
|
||||
while( netlineReader.ReadLine() )
|
||||
while( m_lineReader->ReadLine() )
|
||||
{
|
||||
buffer = FROM_UTF8( netlineReader.Line() );
|
||||
buffer = FROM_UTF8( m_lineReader->Line() );
|
||||
|
||||
if( buffer.StartsWith( wxT("EndCmp") ) )
|
||||
if( buffer.StartsWith( wxT( "EndCmp" ) ) )
|
||||
break;
|
||||
|
||||
// store string value, stored between '=' and ';' delimiters.
|
||||
value = buffer.AfterFirst( '=' );
|
||||
value = value.BeforeLast( ';');
|
||||
value.Trim(true);
|
||||
value.Trim(false);
|
||||
value = value.BeforeLast( ';' );
|
||||
value.Trim( true );
|
||||
value.Trim( false );
|
||||
|
||||
if( buffer.StartsWith( wxT("Reference") ) )
|
||||
if( buffer.StartsWith( wxT( "Reference" ) ) )
|
||||
{
|
||||
refcurrcmp = value;
|
||||
reference = value;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( buffer.StartsWith( wxT("IdModule =" ) ) )
|
||||
if( buffer.StartsWith( wxT( "IdModule =" ) ) )
|
||||
{
|
||||
footprint = value;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( buffer.StartsWith( wxT("TimeStamp =" ) ) )
|
||||
if( buffer.StartsWith( wxT( "TimeStamp =" ) ) )
|
||||
{
|
||||
timestamp = value;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the corresponding item in module info list:
|
||||
for( unsigned ii = 0; ii < m_componentsInNetlist.size(); ii++ )
|
||||
// Find the corresponding item in component list:
|
||||
COMPONENT* component = aNetlist->GetComponentByReference( reference );
|
||||
|
||||
// This cannot happen with a valid file.
|
||||
if( component == NULL )
|
||||
{
|
||||
COMPONENT_INFO * cmp_info = m_componentsInNetlist[ii];
|
||||
if( m_UseTimeStamp ) // Use schematic timestamp to locate the footprint
|
||||
{
|
||||
if( cmp_info->m_TimeStamp.CmpNoCase( timestamp ) == 0 &&
|
||||
!timestamp.IsEmpty() )
|
||||
{ // Found
|
||||
if( !footprint.IsEmpty() )
|
||||
cmp_info->m_Footprint = footprint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // Use schematic reference to locate the footprint
|
||||
{
|
||||
if( cmp_info->m_Reference.CmpNoCase( refcurrcmp ) == 0 ) // Found!
|
||||
{
|
||||
if( !footprint.IsEmpty() )
|
||||
cmp_info->m_Footprint = footprint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
wxString msg;
|
||||
msg.Printf( _( "Cannot find component \'%s\' in footprint assignment file." ),
|
||||
GetChars( reference ) );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), m_lineReader->Line(),
|
||||
m_lineReader->LineNumber(), m_lineReader->Length() );
|
||||
}
|
||||
|
||||
component->SetFootprintLibName( footprint );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Function to sort the footprint list, used by loadNewModules.
|
||||
* the given list is sorted by name
|
||||
*/
|
||||
#ifdef PCBNEW
|
||||
static bool SortByLibName( COMPONENT_INFO* ref, COMPONENT_INFO* cmp )
|
||||
{
|
||||
int ii = ref->m_Footprint.CmpNoCase( cmp->m_Footprint );
|
||||
return ii > 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Load new modules from library.
|
||||
* If a new module is already loaded it is duplicated, which avoid multiple
|
||||
* unnecessary disk or net access to read libraries.
|
||||
* return false if a footprint is not found, true if OK
|
||||
*/
|
||||
bool NETLIST_READER::loadNewModules()
|
||||
{
|
||||
bool success = true;
|
||||
#ifdef PCBNEW
|
||||
COMPONENT_INFO* ref_info, * cmp_info;
|
||||
MODULE* Module = NULL;
|
||||
wxPoint ModuleBestPosition;
|
||||
BOARD* pcb = m_pcbframe->GetBoard();
|
||||
|
||||
if( m_newModulesList.size() == 0 )
|
||||
return true;
|
||||
|
||||
sort( m_newModulesList.begin(), m_newModulesList.end(), SortByLibName );
|
||||
|
||||
// Calculate the footprint "best" position:
|
||||
EDA_RECT bbbox = pcb->ComputeBoundingBox( true );
|
||||
|
||||
if( bbbox.GetWidth() || bbbox.GetHeight() )
|
||||
{
|
||||
ModuleBestPosition = bbbox.GetEnd();
|
||||
ModuleBestPosition.y += 5000;
|
||||
}
|
||||
|
||||
ref_info = cmp_info = m_newModulesList[0];
|
||||
|
||||
for( unsigned ii = 0; ii < m_newModulesList.size(); ii++ )
|
||||
{
|
||||
cmp_info = m_newModulesList[ii];
|
||||
|
||||
if( (ii == 0) || ( ref_info->m_Footprint != cmp_info->m_Footprint) )
|
||||
{
|
||||
// New footprint : must be loaded from a library
|
||||
Module = m_pcbframe->GetModuleLibrary( wxEmptyString,
|
||||
cmp_info->m_Footprint, false );
|
||||
ref_info = cmp_info;
|
||||
|
||||
if( Module == NULL )
|
||||
{
|
||||
success = false;
|
||||
if( m_messageWindow )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Component %s: footprint %s not found" ),
|
||||
GetChars( cmp_info->m_Reference ),
|
||||
GetChars( cmp_info->m_Footprint ) );
|
||||
|
||||
msg += wxT("\n");
|
||||
m_messageWindow->AppendText( msg );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Module->SetPosition( ModuleBestPosition );
|
||||
|
||||
/* Update schematic links : reference "Time Stamp" and schematic
|
||||
* hierarchical path */
|
||||
Module->SetReference( cmp_info->m_Reference );
|
||||
Module->SetTimeStamp( GetNewTimeStamp() );
|
||||
Module->SetPath( cmp_info->m_TimeStamp );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Footprint already loaded from a library, duplicate it (faster)
|
||||
if( Module == NULL )
|
||||
continue; // Module does not exist in library.
|
||||
|
||||
MODULE* newmodule = new MODULE( *Module );
|
||||
newmodule->SetParent( pcb );
|
||||
|
||||
pcb->Add( newmodule, ADD_APPEND );
|
||||
|
||||
Module = newmodule;
|
||||
Module->SetReference( cmp_info->m_Reference );
|
||||
Module->SetTimeStamp( GetNewTimeStamp() );
|
||||
Module->SetPath( cmp_info->m_TimeStamp );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* 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
|
||||
|
@ -26,67 +27,23 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Netlist reader using the first format of pcbnew netlist.
|
||||
* This netlist reader build the list of modules found in netlist
|
||||
* (list in m_componentsInNetlist)
|
||||
* and update pads netnames
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <kicad_string.h>
|
||||
#include <wxPcbStruct.h>
|
||||
#include <richio.h>
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
#include <pcbnew.h>
|
||||
#include <kicad_string.h>
|
||||
|
||||
#include <netlist_reader.h>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// constants used by ReadOldFmtNetlistModuleDescr():
|
||||
#define BUILDLIST true
|
||||
#define READMODULE false
|
||||
|
||||
|
||||
/*
|
||||
* Function ReadOldFmtdNetList
|
||||
* Update footprints (load missing footprints and delete on request extra
|
||||
* footprints)
|
||||
* Update References, values, "TIME STAMP" and connectivity data
|
||||
* return true if Ok
|
||||
*
|
||||
* the format of the netlist is something like:
|
||||
* # EESchema Netlist Version 1.0 generee le 18/5/2005-12:30:22
|
||||
* (
|
||||
* ( 40C08647 $noname R20 4,7K {Lib=R}
|
||||
* ( 1 VCC )
|
||||
* ( 2 MODB_1 )
|
||||
* )
|
||||
* ( 40C0863F $noname R18 4,7_k {Lib=R}
|
||||
* ( 1 VCC )
|
||||
* ( 2 MODA_1 )
|
||||
* )
|
||||
* }
|
||||
* #End
|
||||
*/
|
||||
bool NETLIST_READER::ReadOldFmtdNetList( FILE* aFile )
|
||||
|
||||
void LEGACY_NETLIST_READER::LoadNetlist() throw ( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
int state = 0;
|
||||
bool is_comment = false;
|
||||
int state = 0;
|
||||
bool is_comment = false;
|
||||
COMPONENT* component = NULL;
|
||||
|
||||
/* First, read the netlist: Build the list of footprints found in netlist
|
||||
*/
|
||||
|
||||
// netlineReader dtor will close aFile
|
||||
FILE_LINE_READER netlineReader( aFile, m_netlistFullName );
|
||||
COMPONENT_INFO* curComponent = NULL;
|
||||
|
||||
while( netlineReader.ReadLine() )
|
||||
while( m_lineReader->ReadLine() )
|
||||
{
|
||||
char* line = StrPurge( netlineReader.Line() );
|
||||
char* line = StrPurge( m_lineReader->Line() );
|
||||
|
||||
if( is_comment ) // Comments in progress
|
||||
{
|
||||
|
@ -96,92 +53,17 @@ bool NETLIST_READER::ReadOldFmtdNetList( FILE* aFile )
|
|||
|
||||
is_comment = false;
|
||||
}
|
||||
|
||||
if( *line == '{' ) // Start Comment or Pcbnew info section
|
||||
{
|
||||
is_comment = true;
|
||||
if( ReadLibpartSectionOpt() && state == 0 &&
|
||||
(strnicmp( line, "{ Allowed footprints", 20 ) == 0) )
|
||||
|
||||
if( m_loadFootprintFilters && state == 0
|
||||
&& (strnicmp( line, "{ Allowed footprints", 20 ) == 0) )
|
||||
{
|
||||
ReadOldFmtFootprintFilterList( netlineReader );
|
||||
loadFootprintFilters();
|
||||
continue;
|
||||
}
|
||||
if( ( line = strchr( line, '}' ) ) == NULL )
|
||||
continue;
|
||||
}
|
||||
|
||||
if( *line == '(' )
|
||||
state++;
|
||||
|
||||
if( *line == ')' )
|
||||
state--;
|
||||
|
||||
if( state == 2 )
|
||||
{
|
||||
curComponent = (COMPONENT_INFO*) ReadOldFmtNetlistModuleDescr( line, BUILDLIST );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( state >= 3 ) // First pass: pad descriptions are not read here.
|
||||
{
|
||||
if( curComponent )
|
||||
curComponent->m_pinCount++;
|
||||
|
||||
state--;
|
||||
}
|
||||
}
|
||||
|
||||
if( IsCvPcbMode() )
|
||||
{
|
||||
for( ; ; )
|
||||
{
|
||||
/* Search the beginning of Allowed footprints section */
|
||||
|
||||
if( netlineReader.ReadLine( ) == 0 )
|
||||
break;
|
||||
char* line = StrPurge( netlineReader.Line() );
|
||||
if( strnicmp( line, "{ Allowed footprints", 20 ) == 0 )
|
||||
{
|
||||
ReadOldFmtFootprintFilterList( netlineReader );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if( BuildModuleListOnlyOpt() )
|
||||
return true; // at this point, the module list is read and built.
|
||||
|
||||
// Load new footprints
|
||||
bool success = InitializeModules();
|
||||
|
||||
if( !success )
|
||||
wxMessageBox( _( "Some footprints are not found in libraries" ) );
|
||||
|
||||
TestFootprintsMatchingAndExchange();
|
||||
|
||||
/* Second read , All footprints are on board.
|
||||
* Update the schematic info (pad netnames)
|
||||
*/
|
||||
netlineReader.Rewind();
|
||||
m_currModule = NULL;
|
||||
state = 0;
|
||||
is_comment = false;
|
||||
|
||||
while( netlineReader.ReadLine() )
|
||||
{
|
||||
char* line = StrPurge( netlineReader.Line() );
|
||||
|
||||
if( is_comment ) // we are reading a comment
|
||||
{
|
||||
// Test for end of the current comment
|
||||
if( ( line = strchr( line, '}' ) ) == NULL )
|
||||
continue;
|
||||
is_comment = false;
|
||||
}
|
||||
|
||||
if( *line == '{' ) // this is the beginning of a comment
|
||||
{
|
||||
is_comment = true;
|
||||
|
||||
if( ( line = strchr( line, '}' ) ) == NULL )
|
||||
continue;
|
||||
|
@ -195,190 +77,142 @@ bool NETLIST_READER::ReadOldFmtdNetList( FILE* aFile )
|
|||
|
||||
if( state == 2 )
|
||||
{
|
||||
m_currModule = (MODULE*) ReadOldFmtNetlistModuleDescr( line, READMODULE );
|
||||
component = loadComponent( line );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( state >= 3 )
|
||||
if( state >= 3 ) // Pad descriptions are read here.
|
||||
{
|
||||
if( m_currModule )
|
||||
SetPadNetName( line );
|
||||
wxASSERT( component != NULL );
|
||||
|
||||
loadNet( line, component );
|
||||
state--;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
if( m_footprintReader )
|
||||
{
|
||||
m_footprintReader->Load( m_netlist );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Function ReadOldFmtNetlistModuleDescr
|
||||
* Read the beginning of a footprint description, from the netlist
|
||||
* and add a module info to m_componentsInNetlist
|
||||
* Analyze the first line of a component description in netlist like:
|
||||
* ( /40C08647 $noname R20 4.7K {Lib=R}
|
||||
* (1 VCC)
|
||||
* (2 MODB_1)
|
||||
* )
|
||||
*/
|
||||
void* NETLIST_READER::ReadOldFmtNetlistModuleDescr( char* aText, bool aBuildList )
|
||||
COMPONENT* LEGACY_NETLIST_READER::loadComponent( char* aText ) throw( PARSE_ERROR )
|
||||
{
|
||||
char* text;
|
||||
wxString timeStampPath; // the full time stamp read from netlist
|
||||
wxString footprintName; // the footprint name read from netlist
|
||||
wxString cmpValue; // the component value read from netlist
|
||||
wxString cmpReference; // the component schematic reference read from netlist
|
||||
bool error = false;
|
||||
wxString msg;
|
||||
wxString timeStamp; // the full time stamp read from netlist
|
||||
wxString name; // the component name read from netlist
|
||||
wxString value; // the component value read from netlist
|
||||
wxString reference; // the component schematic reference designator read from netlist
|
||||
char line[1024];
|
||||
|
||||
strcpy( line, aText );
|
||||
|
||||
cmpValue = wxT( "~" );
|
||||
value = wxT( "~" );
|
||||
|
||||
// Read descr line like /40C08647 $noname R20 4.7K {Lib=R}
|
||||
// Sample component line: /40C08647 $noname R20 4.7K {Lib=R}
|
||||
|
||||
// Read time stamp (first word)
|
||||
if( ( text = strtok( line, " ()\t\n" ) ) == NULL )
|
||||
error = true;
|
||||
else
|
||||
timeStampPath = FROM_UTF8( text );
|
||||
{
|
||||
msg = _( "Cannot parse time stamp in component section of netlist." );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
|
||||
m_lineReader->Length() );
|
||||
}
|
||||
|
||||
timeStamp = FROM_UTF8( text );
|
||||
|
||||
// Read footprint name (second word)
|
||||
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
|
||||
error = true;
|
||||
else
|
||||
footprintName = FROM_UTF8( text );
|
||||
{
|
||||
msg = _( "Cannot parse name in component section of netlist." );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
|
||||
m_lineReader->Length() );
|
||||
}
|
||||
|
||||
// Read schematic reference (third word)
|
||||
name = FROM_UTF8( text );
|
||||
|
||||
// Read schematic reference designator (third word)
|
||||
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
|
||||
error = true;
|
||||
else
|
||||
cmpReference = FROM_UTF8( text );
|
||||
{
|
||||
msg = _( "Cannot parse reference designator in component section of netlist." );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
|
||||
m_lineReader->Length() );
|
||||
}
|
||||
|
||||
reference = FROM_UTF8( text );
|
||||
|
||||
// Read schematic value (forth word)
|
||||
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
|
||||
error = true;
|
||||
else
|
||||
cmpValue = FROM_UTF8( text );
|
||||
|
||||
if( error )
|
||||
return NULL;
|
||||
|
||||
if( aBuildList )
|
||||
{
|
||||
COMPONENT_INFO* cmp_info = new COMPONENT_INFO( footprintName, cmpReference,
|
||||
cmpValue, timeStampPath );
|
||||
AddModuleInfo( cmp_info );
|
||||
return cmp_info;
|
||||
msg = _( "Cannot parse value in component section of netlist." );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
|
||||
m_lineReader->Length() );
|
||||
}
|
||||
|
||||
// search the module loaded on board
|
||||
// reference and time stamps are already updated so we can use search by reference only
|
||||
MODULE* module = m_pcbframe->GetBoard()->FindModuleByReference( cmpReference );
|
||||
if( module == NULL )
|
||||
{
|
||||
if( m_messageWindow )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Component %s not found" ), GetChars( cmpReference ) );
|
||||
m_messageWindow->AppendText( msg + wxT( "\n" ) );
|
||||
}
|
||||
}
|
||||
value = FROM_UTF8( text );
|
||||
|
||||
return module;
|
||||
COMPONENT* component = new COMPONENT( name, reference, value, timeStamp );
|
||||
m_netlist->AddComponent( component );
|
||||
return component;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function SetPadNetName
|
||||
* Update a pad netname using the current footprint
|
||||
* Line format: ( <pad number> = <net name> )
|
||||
* Param aText = current line read from netlist
|
||||
*/
|
||||
bool NETLIST_READER::SetPadNetName( char* aText )
|
||||
void LEGACY_NETLIST_READER::loadNet( char* aText, COMPONENT* aComponent ) throw( PARSE_ERROR )
|
||||
{
|
||||
char* p;
|
||||
char line[256];
|
||||
wxString msg;
|
||||
char* p;
|
||||
char line[256];
|
||||
|
||||
if( m_currModule == NULL )
|
||||
return false;
|
||||
|
||||
strncpy( line, aText, sizeof(line) );
|
||||
strncpy( line, aText, sizeof( line ) );
|
||||
|
||||
if( ( p = strtok( line, " ()\t\n" ) ) == NULL )
|
||||
return false;
|
||||
{
|
||||
msg = _( "Cannot parse pin name in component net section of netlist." );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
|
||||
m_lineReader->Length() );
|
||||
}
|
||||
|
||||
wxString pinName = FROM_UTF8( p );
|
||||
|
||||
if( ( p = strtok( NULL, " ()\t\n" ) ) == NULL )
|
||||
return false;
|
||||
{
|
||||
msg = _( "Cannot parse net name in component net section of netlist." );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
|
||||
m_lineReader->Length() );
|
||||
}
|
||||
|
||||
wxString netName = FROM_UTF8( p );
|
||||
|
||||
bool found = false;
|
||||
for( D_PAD* pad = m_currModule->Pads(); pad; pad = pad->Next() )
|
||||
{
|
||||
wxString padName = pad->GetPadName();
|
||||
if( (char) netName[0] == '?' ) // ? indicates no net connected to pin.
|
||||
netName = wxEmptyString;
|
||||
|
||||
if( padName == pinName )
|
||||
{
|
||||
found = true;
|
||||
if( (char) netName[0] != '?' )
|
||||
pad->SetNetname( netName );
|
||||
else
|
||||
pad->SetNetname( wxEmptyString );
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
if( m_messageWindow )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Module %s: Pad %s not found" ),
|
||||
GetChars( m_currModule->GetReference() ),
|
||||
GetChars( pinName ) );
|
||||
m_messageWindow->AppendText( msg + wxT( "\n" ) );
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
aComponent->AddNet( pinName, netName );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read the section "Allowed footprints" like:
|
||||
* { Allowed footprints by component:
|
||||
* $component R11
|
||||
* R?
|
||||
* SM0603
|
||||
* SM0805
|
||||
* R?-*
|
||||
* SM1206
|
||||
* $endlist
|
||||
* $endfootprintlist
|
||||
* }
|
||||
*
|
||||
* And add the strings giving the footprint filter to m_FootprintFilter
|
||||
* of the corresponding module info
|
||||
* This section is used by CvPcb, and is not useful in Pcbnew,
|
||||
* therefore it it not always read
|
||||
*/
|
||||
bool NETLIST_READER::ReadOldFmtFootprintFilterList( FILE_LINE_READER& aNetlistReader )
|
||||
void LEGACY_NETLIST_READER::loadFootprintFilters() throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
wxString cmpRef;
|
||||
COMPONENT_INFO* cmp_info = NULL;
|
||||
char* line;
|
||||
wxArrayString filters;
|
||||
wxString cmpRef;
|
||||
char* line;
|
||||
COMPONENT* component;
|
||||
|
||||
while( ( line = aNetlistReader.ReadLine() ) != NULL )
|
||||
while( ( line = m_lineReader->ReadLine() ) != NULL )
|
||||
{
|
||||
if( strnicmp( line, "$endlist", 8 ) == 0 ) // end of list for the current component
|
||||
if( strnicmp( line, "$endlist", 8 ) == 0 ) // end of list for the current component
|
||||
{
|
||||
cmp_info = NULL;
|
||||
wxASSERT( component != NULL );
|
||||
component->SetFootprintFilters( filters );
|
||||
component = NULL;
|
||||
filters.Clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
if( strnicmp( line, "$endfootprintlist", 4 ) == 0 )
|
||||
// End of this section
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if( strnicmp( line, "$component", 10 ) == 0 ) // New component reference found
|
||||
{
|
||||
|
@ -386,25 +220,25 @@ bool NETLIST_READER::ReadOldFmtFootprintFilterList( FILE_LINE_READER& aNetlistR
|
|||
cmpRef.Trim( true );
|
||||
cmpRef.Trim( false );
|
||||
|
||||
// Search the current component in module info list:
|
||||
BOOST_FOREACH( COMPONENT_INFO * &component, m_componentsInNetlist )
|
||||
component = m_netlist->GetComponentByReference( cmpRef );
|
||||
|
||||
// Cannot happen if the netlist is valid.
|
||||
if( component == NULL )
|
||||
{
|
||||
if( component->m_Reference == cmpRef )
|
||||
{
|
||||
cmp_info = component;
|
||||
break;
|
||||
}
|
||||
wxString msg;
|
||||
msg.Printf( _( "Cannot find component \'%s\' in footprint filter section "
|
||||
"of netlist." ), GetChars( cmpRef ) );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
|
||||
m_lineReader->Length() );
|
||||
}
|
||||
}
|
||||
else if( cmp_info )
|
||||
else
|
||||
{
|
||||
// Add new filter to list
|
||||
wxString fp = FROM_UTF8( line + 1 );
|
||||
fp.Trim( false );
|
||||
fp.Trim( true );
|
||||
cmp_info->m_FootprintFilter.Add( fp );
|
||||
filters.Add( fp );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -27,142 +27,50 @@
|
|||
|
||||
#include <wx/wx.h>
|
||||
#include <netlist_lexer.h> // netlist_lexer is common to Eeschema and Pcbnew
|
||||
#include <macros.h>
|
||||
#include <netlist_reader.h>
|
||||
|
||||
using namespace NL_T;
|
||||
|
||||
/**
|
||||
* Class PCB_PLOT_PARAMS_PARSER
|
||||
* is the parser class for PCB_PLOT_PARAMS.
|
||||
*/
|
||||
class NETLIST_READER_KICAD_PARSER : public NETLIST_LEXER
|
||||
|
||||
void KICAD_NETLIST_READER::LoadNetlist() throw ( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
private:
|
||||
T token;
|
||||
NETLIST_READER * netlist_reader;
|
||||
m_parser->Parse();
|
||||
|
||||
public:
|
||||
NETLIST_READER_KICAD_PARSER( FILE_LINE_READER* aReader, NETLIST_READER *aNetlistReader );
|
||||
|
||||
/**
|
||||
* Function Parse
|
||||
* parse the full netlist
|
||||
*/
|
||||
void Parse( BOARD * aBrd ) throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function ParseComp
|
||||
* parse the comp description like
|
||||
* (comp (ref P1)
|
||||
* (value DB25FEMELLE)
|
||||
* (footprint DB25FC)
|
||||
* (libsource (lib conn) (part DB25))
|
||||
* (sheetpath (names /) (tstamps /))
|
||||
* (tstamp 3256759C))
|
||||
*/
|
||||
COMPONENT_INFO* ParseComp() throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
|
||||
/**
|
||||
* Function ParseKicadLibpartList
|
||||
* Read the section "libparts" like:
|
||||
* (libparts
|
||||
* (libpart (lib device) (part C)
|
||||
* (description "Condensateur non polarise")
|
||||
* (footprints
|
||||
* (fp SM*)
|
||||
* (fp C?)
|
||||
* (fp C1-1))
|
||||
* (fields
|
||||
* (field (name Reference) C)
|
||||
* (field (name Value) C))
|
||||
* (pins
|
||||
* (pin (num 1) (name ~) (type passive))
|
||||
* (pin (num 2) (name ~) (type passive))))
|
||||
*
|
||||
* And add the strings giving the footprint filter (subsection footprints)
|
||||
* of the corresponding module info
|
||||
* <p>This section is used by CvPcb, and is not useful in Pcbnew,
|
||||
* therefore it it not always read </p>
|
||||
*/
|
||||
void ParseKicadLibpartList() throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function ParseNet
|
||||
* Parses a section like
|
||||
* (net (code 20) (name /PC-A0)
|
||||
* (node (ref BUS1) (pin 62))
|
||||
* (node (ref U3) (pin 3))
|
||||
* (node (ref U9) (pin M6)))
|
||||
*
|
||||
* and set the corresponfings pads netnames
|
||||
*/
|
||||
void ParseNet( BOARD * aBrd ) throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
/**
|
||||
* Function SkipCurrent
|
||||
* Skip the current token level, i.e
|
||||
* search for the RIGHT parenthesis which closes the current description
|
||||
*/
|
||||
void SkipCurrent() throw( IO_ERROR, PARSE_ERROR );
|
||||
|
||||
// Useful for debug only:
|
||||
const char* getTokenName( T aTok )
|
||||
if( m_footprintReader )
|
||||
{
|
||||
return NETLIST_LEXER::TokenName( aTok );
|
||||
m_footprintReader->Load( m_netlist );
|
||||
|
||||
// Sort the component pins so they are in the same order as the legacy format. This
|
||||
// is useful for comparing legacy and s-expression netlist dumps.
|
||||
for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
|
||||
m_netlist->GetComponent( i )->SortPins();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
bool NETLIST_READER::ReadKicadNetList( FILE* aFile )
|
||||
{
|
||||
BOARD * brd = m_pcbframe ? m_pcbframe->GetBoard() : NULL;
|
||||
|
||||
// netlineReader dtor will close aFile
|
||||
FILE_LINE_READER netlineReader( aFile, m_netlistFullName );
|
||||
NETLIST_READER_KICAD_PARSER netlist_parser( &netlineReader, this );
|
||||
|
||||
try
|
||||
{
|
||||
netlist_parser.Parse( brd );
|
||||
}
|
||||
catch( IO_ERROR& ioe )
|
||||
{
|
||||
ioe.errorText += '\n';
|
||||
ioe.errorText += _("Netlist error.");
|
||||
|
||||
wxMessageBox( ioe.errorText );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// NETLIST_READER_KICAD_PARSER
|
||||
NETLIST_READER_KICAD_PARSER::NETLIST_READER_KICAD_PARSER( FILE_LINE_READER* aReader,
|
||||
NETLIST_READER *aNetlistReader ) :
|
||||
// KICAD_NETLIST_PARSER
|
||||
KICAD_NETLIST_PARSER::KICAD_NETLIST_PARSER( LINE_READER* aReader, NETLIST* aNetlist ) :
|
||||
NETLIST_LEXER( aReader )
|
||||
{
|
||||
netlist_reader = aNetlistReader;
|
||||
m_lineReader = aReader;
|
||||
m_netlist = aNetlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SkipCurrent
|
||||
* Skip the current token level, i.e
|
||||
* search for the RIGHT parenthesis which closes the current description
|
||||
*/
|
||||
void NETLIST_READER_KICAD_PARSER::SkipCurrent() throw( IO_ERROR, PARSE_ERROR )
|
||||
|
||||
void KICAD_NETLIST_PARSER::skipCurrent() throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
int curr_level = 0;
|
||||
|
||||
while( ( token = NextTok() ) != T_EOF )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
curr_level--;
|
||||
|
||||
if( token == T_RIGHT )
|
||||
{
|
||||
curr_level++;
|
||||
|
||||
if( curr_level > 0 )
|
||||
return;
|
||||
}
|
||||
|
@ -170,9 +78,10 @@ void NETLIST_READER_KICAD_PARSER::SkipCurrent() throw( IO_ERROR, PARSE_ERROR )
|
|||
}
|
||||
|
||||
|
||||
void NETLIST_READER_KICAD_PARSER::Parse( BOARD * aBrd )
|
||||
throw( IO_ERROR, PARSE_ERROR )
|
||||
void KICAD_NETLIST_PARSER::Parse() throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
wxString text;
|
||||
|
||||
int plevel = 0; // the count of ')' to read and end of file,
|
||||
// after parsing all sections
|
||||
|
||||
|
@ -183,98 +92,91 @@ void NETLIST_READER_KICAD_PARSER::Parse( BOARD * aBrd )
|
|||
|
||||
switch( token )
|
||||
{
|
||||
case T_export: // The netlist starts here.
|
||||
// nothing to do here,
|
||||
// just increment the count of ')' to read and end of file
|
||||
plevel++;
|
||||
break;
|
||||
case T_export: // The netlist starts here.
|
||||
// nothing to do here,
|
||||
// just increment the count of ')' to read and end of file
|
||||
plevel++;
|
||||
break;
|
||||
|
||||
case T_version: // The netlist starts here.
|
||||
// version id not yet used: read it but does not use it
|
||||
NextTok();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
case T_version: // The netlist starts here.
|
||||
// version id not yet used: read it but does not use it
|
||||
NextTok();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_components: // The section comp starts here.
|
||||
while( ( token = NextTok() ) != T_RIGHT )
|
||||
case T_components: // The section comp starts here.
|
||||
while( ( token = NextTok() ) != T_RIGHT )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
|
||||
if( token == T_comp ) // A component section found. Read it
|
||||
parseComponent();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case T_nets: // The section nets starts here.
|
||||
while( ( token = NextTok() ) != T_RIGHT )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
|
||||
if( token == T_net )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
if( token == T_comp ) // A comp section if found. Read it
|
||||
{
|
||||
COMPONENT_INFO* cmp_info = ParseComp();
|
||||
netlist_reader->AddModuleInfo( cmp_info );
|
||||
}
|
||||
// A net section if found. Read it
|
||||
parseNet();
|
||||
}
|
||||
if( netlist_reader->BuildModuleListOnlyOpt() )
|
||||
return; // at this point, the module list is read and built.
|
||||
// Load new footprints
|
||||
netlist_reader->InitializeModules();
|
||||
netlist_reader->TestFootprintsMatchingAndExchange();
|
||||
break;
|
||||
}
|
||||
|
||||
case T_nets: // The section nets starts here.
|
||||
while( ( token = NextTok() ) != T_RIGHT )
|
||||
break;
|
||||
|
||||
case T_libparts: // The section libparts starts here.
|
||||
while( ( token = NextTok() ) != T_RIGHT )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
|
||||
if( token == T_libpart )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
if( token == T_net )
|
||||
{
|
||||
// A net section if found. Read it
|
||||
ParseNet( aBrd );
|
||||
}
|
||||
// A libpart section if found. Read it
|
||||
parseLibPartList();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case T_libparts: // The section libparts starts here.
|
||||
if( netlist_reader->ReadLibpartSectionOpt() )
|
||||
{
|
||||
while( ( token = NextTok() ) != T_RIGHT )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
if( token == T_libpart )
|
||||
{
|
||||
// A libpart section if found. Read it
|
||||
ParseKicadLibpartList();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
SkipCurrent();
|
||||
break;
|
||||
break;
|
||||
|
||||
case T_libraries: // The section libraries starts here.
|
||||
// List of libraries in use.
|
||||
// Not used here, just skip it
|
||||
SkipCurrent();
|
||||
break;
|
||||
case T_libraries: // The section libraries starts here.
|
||||
// List of libraries in use.
|
||||
// Not used here, just skip it
|
||||
skipCurrent();
|
||||
break;
|
||||
|
||||
case T_design: // The section design starts here.
|
||||
// Not used (mainly thet are comments), just skip it
|
||||
SkipCurrent();
|
||||
break;
|
||||
case T_design: // The section design starts here.
|
||||
// Not used (mainly they are comments), just skip it
|
||||
skipCurrent();
|
||||
break;
|
||||
|
||||
case T_RIGHT: // The closing parenthesis of the file.
|
||||
// Not used (mainly thet are comments), just skip it
|
||||
plevel--;
|
||||
break;
|
||||
case T_RIGHT: // The closing parenthesis of the file.
|
||||
// Not used (mainly they are comments), just skip it
|
||||
plevel--;
|
||||
break;
|
||||
|
||||
default:
|
||||
SkipCurrent();
|
||||
break;
|
||||
default:
|
||||
skipCurrent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( plevel != 0 )
|
||||
{
|
||||
wxLogDebug(wxT("NETLIST_READER_KICAD_PARSER::Parse(): bad parenthesis count (count = %d"),
|
||||
wxLogDebug( wxT( "KICAD_NETLIST_PARSER::Parse(): bad parenthesis count (count = %d"),
|
||||
plevel );
|
||||
}
|
||||
}
|
||||
|
||||
void NETLIST_READER_KICAD_PARSER::ParseNet( BOARD * aBrd )
|
||||
throw( IO_ERROR, PARSE_ERROR )
|
||||
|
||||
void KICAD_NETLIST_PARSER::parseNet() throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
/* Parses a section like
|
||||
* (net (code 20) (name /PC-A0)
|
||||
|
@ -283,32 +185,35 @@ void NETLIST_READER_KICAD_PARSER::ParseNet( BOARD * aBrd )
|
|||
* (node (ref U9) (pin M6)))
|
||||
*/
|
||||
|
||||
wxString code;
|
||||
wxString name;
|
||||
wxString cmpref;
|
||||
wxString pin;
|
||||
int nodecount = 0;
|
||||
std::vector<D_PAD*> padList;
|
||||
COMPONENT* component = NULL;
|
||||
wxString code;
|
||||
wxString name;
|
||||
wxString reference;
|
||||
wxString pin;
|
||||
int nodecount = 0;
|
||||
|
||||
// The token net was read, so the next data is (code <number>)
|
||||
while( (token = NextTok()) != T_RIGHT )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_code:
|
||||
NeedSYMBOLorNUMBER();
|
||||
code = FROM_UTF8( CurText() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
break;
|
||||
|
||||
case T_name:
|
||||
NeedSYMBOLorNUMBER();
|
||||
name = FROM_UTF8( CurText() );
|
||||
NeedRIGHT();
|
||||
|
||||
if( name.IsEmpty() ) // Give a dummy net name like N-000109
|
||||
name = wxT("N-00000") + code;
|
||||
|
||||
break;
|
||||
|
||||
case T_node:
|
||||
|
@ -316,11 +221,12 @@ void NETLIST_READER_KICAD_PARSER::ParseNet( BOARD * aBrd )
|
|||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_ref:
|
||||
NeedSYMBOLorNUMBER();
|
||||
cmpref = FROM_UTF8( CurText() );
|
||||
reference = FROM_UTF8( CurText() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
|
@ -331,31 +237,37 @@ void NETLIST_READER_KICAD_PARSER::ParseNet( BOARD * aBrd )
|
|||
break;
|
||||
|
||||
default:
|
||||
SkipCurrent();
|
||||
skipCurrent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
netlist_reader->SetPadsNetName( cmpref, pin, name, padList );
|
||||
|
||||
|
||||
component = m_netlist->GetComponentByReference( reference );
|
||||
|
||||
// Cannot happen if the netlist is valid.
|
||||
if( component == NULL )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Cannot find component with reference \"%s\" in netlist." ),
|
||||
GetChars( reference ) );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), m_lineReader->Line(),
|
||||
m_lineReader->LineNumber(), m_lineReader->Length() );
|
||||
}
|
||||
|
||||
component->AddNet( pin, name );
|
||||
nodecount++;
|
||||
break;
|
||||
|
||||
default:
|
||||
SkipCurrent();
|
||||
skipCurrent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// When there is only one item in net, clear pad netname
|
||||
// Remember one can have more than one pad in list, because a footprint
|
||||
// can have many pads with the same pad name
|
||||
if( nodecount < 2 )
|
||||
for( unsigned ii = 0; ii < padList.size(); ii++ )
|
||||
padList[ii]->SetNetname( wxEmptyString );
|
||||
}
|
||||
|
||||
|
||||
COMPONENT_INFO* NETLIST_READER_KICAD_PARSER::ParseComp()
|
||||
throw( IO_ERROR, PARSE_ERROR )
|
||||
void KICAD_NETLIST_PARSER::parseComponent() throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
/* Parses a section like
|
||||
* (comp (ref P1)
|
||||
|
@ -366,13 +278,14 @@ COMPONENT_INFO* NETLIST_READER_KICAD_PARSER::ParseComp()
|
|||
* (tstamp 3256759C))
|
||||
*
|
||||
* other fields (unused) are skipped
|
||||
* A component need a reference, value, foorprint name and a full time stamp
|
||||
* A component need a reference, value, footprint name and a full time stamp
|
||||
* The full time stamp is the sheetpath time stamp + the component time stamp
|
||||
*/
|
||||
wxString ref;
|
||||
wxString value;
|
||||
wxString footprint;
|
||||
wxString libpart;
|
||||
wxString componentName;
|
||||
wxString libPartName;
|
||||
wxString libName;
|
||||
wxString pathtimestamp, timestamp;
|
||||
// The token comp was read, so the next data is (ref P1)
|
||||
|
||||
|
@ -380,6 +293,7 @@ COMPONENT_INFO* NETLIST_READER_KICAD_PARSER::ParseComp()
|
|||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_ref:
|
||||
|
@ -396,7 +310,7 @@ COMPONENT_INFO* NETLIST_READER_KICAD_PARSER::ParseComp()
|
|||
|
||||
case T_footprint:
|
||||
NeedSYMBOLorNUMBER();
|
||||
footprint = FROM_UTF8( CurText() );
|
||||
componentName = FROM_UTF8( CurText() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
|
@ -406,14 +320,23 @@ COMPONENT_INFO* NETLIST_READER_KICAD_PARSER::ParseComp()
|
|||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
if( token == T_part )
|
||||
|
||||
if( token == T_lib )
|
||||
{
|
||||
NeedSYMBOLorNUMBER();
|
||||
libpart = FROM_UTF8( CurText() );
|
||||
libName = FROM_UTF8( CurText() );
|
||||
NeedRIGHT();
|
||||
}
|
||||
else if( token == T_part )
|
||||
{
|
||||
NeedSYMBOLorNUMBER();
|
||||
libPartName = FROM_UTF8( CurText() );
|
||||
NeedRIGHT();
|
||||
}
|
||||
else
|
||||
SkipCurrent();
|
||||
{
|
||||
Expecting( "part or lib" );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -433,95 +356,92 @@ COMPONENT_INFO* NETLIST_READER_KICAD_PARSER::ParseComp()
|
|||
|
||||
default:
|
||||
// Skip not used data (i.e all other tokens)
|
||||
SkipCurrent();
|
||||
skipCurrent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
pathtimestamp += timestamp;
|
||||
COMPONENT_INFO* cmp_info = new COMPONENT_INFO( footprint, ref, value, pathtimestamp );
|
||||
cmp_info->m_Libpart = libpart;
|
||||
|
||||
return cmp_info;
|
||||
pathtimestamp += timestamp;
|
||||
COMPONENT* component = new COMPONENT( componentName, ref, value, pathtimestamp );
|
||||
component->SetLibrarySource( libName, libPartName );
|
||||
m_netlist->AddComponent( component );
|
||||
}
|
||||
|
||||
/* Read the section "libparts" like:
|
||||
* (libparts
|
||||
* (libpart (lib device) (part C)
|
||||
* (description "Condensateur non polarise")
|
||||
* (footprints
|
||||
* (fp SM*)
|
||||
* (fp C?)
|
||||
* (fp C1-1))
|
||||
* (fields
|
||||
* (field (name Reference) C)
|
||||
* (field (name Value) C))
|
||||
* (pins
|
||||
* (pin (num 1) (name ~) (type passive))
|
||||
* (pin (num 2) (name ~) (type passive))))
|
||||
*
|
||||
* And add the strings giving the footprint filter (subsection footprints)
|
||||
* of the corresponding module info
|
||||
*/
|
||||
void NETLIST_READER_KICAD_PARSER::ParseKicadLibpartList() throw( IO_ERROR, PARSE_ERROR )
|
||||
|
||||
void KICAD_NETLIST_PARSER::parseLibPartList() throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
/* Parses a section like
|
||||
* (libpart (lib device) (part C)
|
||||
* (description "Condensateur non polarise")
|
||||
* (footprints
|
||||
* (fp SM*)
|
||||
* (fp C?)
|
||||
* (fp C1-1))
|
||||
* (fields
|
||||
* (field (name Reference) C)
|
||||
* (field (name Value) C))
|
||||
* (pins
|
||||
* (pin (num 1) (name ~) (type passive))
|
||||
* (pin (num 2) (name ~) (type passive))))
|
||||
*
|
||||
* Currently footprints section/fp are read and data stored
|
||||
* other fields (unused) are skipped
|
||||
*/
|
||||
wxString device;
|
||||
wxString filter;
|
||||
LIPBART_INFO* libpart_info = NULL;
|
||||
* (libpart (lib device) (part C)
|
||||
* (description "Condensateur non polarise")
|
||||
* (footprints
|
||||
* (fp SM*)
|
||||
* (fp C?)
|
||||
* (fp C1-1))
|
||||
* (fields
|
||||
* (field (name Reference) C)
|
||||
* (field (name Value) C))
|
||||
* (pins
|
||||
* (pin (num 1) (name ~) (type passive))
|
||||
* (pin (num 2) (name ~) (type passive))))
|
||||
*
|
||||
* Currently footprints section/fp are read and data stored
|
||||
* other fields (unused) are skipped
|
||||
*/
|
||||
COMPONENT* component = NULL;
|
||||
wxString libName;
|
||||
wxString libPartName;
|
||||
wxArrayString footprintFilters;
|
||||
|
||||
// The last token read was libpart, so read the next token
|
||||
while( (token = NextTok()) != T_RIGHT )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_lib:
|
||||
NeedSYMBOLorNUMBER();
|
||||
libName = FROM_UTF8( CurText() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_part:
|
||||
NeedSYMBOLorNUMBER();
|
||||
device = FROM_UTF8( CurText() );
|
||||
libPartName = FROM_UTF8( CurText() );
|
||||
NeedRIGHT();
|
||||
libpart_info = new LIPBART_INFO( device );
|
||||
netlist_reader->AddLibpartInfo( libpart_info );
|
||||
break;
|
||||
|
||||
case T_footprints:
|
||||
// Ensure "(part C)" was already read
|
||||
if( libpart_info == NULL )
|
||||
Expecting( T_part );
|
||||
// Read all fp elements (footprint filter item)
|
||||
while( (token = NextTok()) != T_RIGHT )
|
||||
{
|
||||
if( token == T_LEFT )
|
||||
token = NextTok();
|
||||
|
||||
if( token != T_fp )
|
||||
Expecting( T_fp );
|
||||
|
||||
NeedSYMBOLorNUMBER();
|
||||
filter = FROM_UTF8( CurText() );
|
||||
footprintFilters.Add( FROM_UTF8( CurText() ) );
|
||||
NeedRIGHT();
|
||||
libpart_info->m_FootprintFilter.Add( filter );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// Skip not used data (i.e all other tokens)
|
||||
SkipCurrent();
|
||||
skipCurrent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Find all of the components that reference this component library part definition.
|
||||
for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
|
||||
{
|
||||
component = m_netlist->GetComponent( i );
|
||||
|
||||
if( component->IsLibSource( libName, libPartName ) )
|
||||
component->SetFootprintFilters( footprintFilters );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue