Commit 8d777fc6 authored by Dick Hollenbeck's avatar Dick Hollenbeck

Merge new generic netlist work, code cleaning, and BOM fixes

parents 217efaa8 4eb80203
...@@ -4,6 +4,20 @@ KiCad ChangeLog 2010 ...@@ -4,6 +4,20 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2010-Jul-30 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
++eeschema:
* Now link with XML support within wxWidgets.
* Start of export the generic netlist in XML. Still need to rework the chain
loaded netlist plugin.
* OBJ_CMP_TO_LIST class now uses a std::string to hold the 8 bit string m_Ref,
but hides this behind accessors which provide for both Unicode and 8 bit
set and get functions.
* build_BOM.cpp retains the selected filename on subsequent runs as a default.
* Code cleaning, especially in build_BOM.cpp.
* Will work tomorrow also.
2010-jul-27, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2010-jul-27, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================ ================================================================================
++all: ++all:
......
...@@ -134,9 +134,9 @@ check_find_package_result(OPENGL_FOUND "OpenGL") ...@@ -134,9 +134,9 @@ check_find_package_result(OPENGL_FOUND "OpenGL")
# On Apple only wxwidgets 2.9 or higher doesn't need to find aui part of base # On Apple only wxwidgets 2.9 or higher doesn't need to find aui part of base
if(APPLE) if(APPLE)
find_package(wxWidgets COMPONENTS gl adv html core net base QUIET) find_package(wxWidgets COMPONENTS gl adv html core net base xml QUIET)
else(APPLE) else(APPLE)
find_package(wxWidgets COMPONENTS gl aui adv html core net base QUIET) find_package(wxWidgets COMPONENTS gl aui adv html core net base xml QUIET)
endif(APPLE) endif(APPLE)
check_find_package_result(wxWidgets_FOUND "wxWidgets") check_find_package_result(wxWidgets_FOUND "wxWidgets")
......
...@@ -381,8 +381,7 @@ int AddComponentsInSheetToList( std::vector <OBJ_CMP_TO_LIST>& aComponentsList, ...@@ -381,8 +381,7 @@ int AddComponentsInSheetToList( std::vector <OBJ_CMP_TO_LIST>& aComponentsList,
if( DrawLibItem->GetRef( aSheet ).IsEmpty() ) if( DrawLibItem->GetRef( aSheet ).IsEmpty() )
DrawLibItem->SetRef( aSheet, wxT( "DefRef?" ) ); DrawLibItem->SetRef( aSheet, wxT( "DefRef?" ) );
strncpy( new_object.m_Reference, new_object.SetRef( DrawLibItem->GetRef( aSheet ) );
CONV_TO_UTF8( DrawLibItem->GetRef( aSheet ) ), 32 );
new_object.m_NumRef = -1; new_object.m_NumRef = -1;
...@@ -409,6 +408,7 @@ static void ReAnnotateComponents( std::vector <OBJ_CMP_TO_LIST>& aComponentsList ...@@ -409,6 +408,7 @@ static void ReAnnotateComponents( std::vector <OBJ_CMP_TO_LIST>& aComponentsList
/* update the reference numbers */ /* update the reference numbers */
for( unsigned ii = 0; ii < aComponentsList.size(); ii++ ) for( unsigned ii = 0; ii < aComponentsList.size(); ii++ )
{ {
#if 0
char* Text = aComponentsList[ii].m_Reference; char* Text = aComponentsList[ii].m_Reference;
SCH_COMPONENT* component = aComponentsList[ii].m_RootCmp; SCH_COMPONENT* component = aComponentsList[ii].m_RootCmp;
...@@ -419,8 +419,23 @@ static void ReAnnotateComponents( std::vector <OBJ_CMP_TO_LIST>& aComponentsList ...@@ -419,8 +419,23 @@ static void ReAnnotateComponents( std::vector <OBJ_CMP_TO_LIST>& aComponentsList
component->SetRef( &(aComponentsList[ii].m_SheetPath), component->SetRef( &(aComponentsList[ii].m_SheetPath),
CONV_FROM_UTF8( Text ) ); CONV_FROM_UTF8( Text ) );
#else
wxString ref = aComponentsList[ii].GetRef();
SCH_COMPONENT* component = aComponentsList[ii].m_RootCmp;
if( aComponentsList[ii].m_NumRef < 0 )
ref += wxChar( '?' );
else
ref << aComponentsList[ii].m_NumRef;
aComponentsList[ii].SetRef( ref );
component->SetRef( &aComponentsList[ii].m_SheetPath, ref );
#endif
component->m_Multi = aComponentsList[ii].m_Unit; component->m_Multi = aComponentsList[ii].m_Unit;
component->SetUnitSelection( &(aComponentsList[ii].m_SheetPath), component->SetUnitSelection( &aComponentsList[ii].m_SheetPath,
aComponentsList[ii].m_Unit ); aComponentsList[ii].m_Unit );
} }
} }
...@@ -437,41 +452,57 @@ static void ReAnnotateComponents( std::vector <OBJ_CMP_TO_LIST>& aComponentsList ...@@ -437,41 +452,57 @@ static void ReAnnotateComponents( std::vector <OBJ_CMP_TO_LIST>& aComponentsList
*/ */
void BreakReference( std::vector <OBJ_CMP_TO_LIST>& aComponentsList ) void BreakReference( std::vector <OBJ_CMP_TO_LIST>& aComponentsList )
{ {
char* Text; std::string refText; // construct once outside loop
for( unsigned ii = 0; ii < aComponentsList.size(); ii++ ) for( unsigned ii = 0; ii < aComponentsList.size(); ii++ )
{ {
aComponentsList[ii].m_NumRef = -1; aComponentsList[ii].m_NumRef = -1;
Text = aComponentsList[ii].m_Reference;
int ll = strlen( Text ) - 1; refText = aComponentsList[ii].GetRefStr();
if( Text[ll] == '?' )
int ll = refText.length() - 1;
if( refText[ll] == '?' )
{ {
aComponentsList[ii].m_IsNew = true; aComponentsList[ii].m_IsNew = true;
if( !aComponentsList[ii].IsPartsLocked() ) if( !aComponentsList[ii].IsPartsLocked() )
aComponentsList[ii].m_Unit = 0x7FFFFFFF; aComponentsList[ii].m_Unit = 0x7FFFFFFF;
Text[ll] = 0;
continue; refText.erase(ll); // delete last char
aComponentsList[ii].SetRefStr( refText );
} }
if( isdigit( Text[ll] ) == 0 ) else if( isdigit( refText[ll] ) == 0 )
{ {
aComponentsList[ii].m_IsNew = true; aComponentsList[ii].m_IsNew = true;
if( !aComponentsList[ii].IsPartsLocked() ) if( !aComponentsList[ii].IsPartsLocked() )
aComponentsList[ii].m_Unit = 0x7FFFFFFF; aComponentsList[ii].m_Unit = 0x7FFFFFFF;
continue;
} }
while( ll >= 0 ) else
{ {
if( (Text[ll] <= ' ' ) || isdigit( Text[ll] ) ) while( ll >= 0 )
ll--;
else
{ {
if( isdigit( Text[ll + 1] ) ) if( (refText[ll] <= ' ' ) || isdigit( refText[ll] ) )
aComponentsList[ii].m_NumRef = atoi( &Text[ll + 1] ); ll--;
Text[ll + 1] = 0; else
break; {
if( isdigit( refText[ll + 1] ) )
{
// nul terminated C string into cp
const char* cp = refText.c_str() + ll + 1;
aComponentsList[ii].m_NumRef = atoi( cp );
}
refText.erase( ll+1 ); // delete from ll+1 to end
break;
}
} }
aComponentsList[ii].SetRefStr( refText );
} }
} }
} }
...@@ -490,7 +521,7 @@ static void ComputeReferenceNumber( std::vector <OBJ_CMP_TO_LIST>& aComponentsLi ...@@ -490,7 +521,7 @@ static void ComputeReferenceNumber( std::vector <OBJ_CMP_TO_LIST>& aComponentsLi
*/ */
for( unsigned ii = 0; ii < aComponentsList.size(); ii++ ) for( unsigned ii = 0; ii < aComponentsList.size(); ii++ )
{ {
if( aComponentsList[ii].m_Reference[0] == '#' ) if( aComponentsList[ii].GetRefStr()[0] == '#' )
{ {
aComponentsList[ii].m_IsNew = true; aComponentsList[ii].m_IsNew = true;
aComponentsList[ii].m_NumRef = 0; aComponentsList[ii].m_NumRef = 0;
...@@ -716,9 +747,9 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList, ...@@ -716,9 +747,9 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList,
else else
Buff = wxT( "?" ); Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference ); cmpref = ComponentsList[ii].GetRef();
msg.Printf( _( "item not annotated: %s%s" ), msg.Printf( _( "item not annotated: %s%s" ),
cmpref.GetData(), Buff.GetData() ); GetChars( cmpref ), GetChars( Buff ) );
if( ( ComponentsList[ii].m_Unit > 0 ) if( ( ComponentsList[ii].m_Unit > 0 )
&& ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) ) && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) )
...@@ -748,9 +779,10 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList, ...@@ -748,9 +779,10 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList,
else else
Buff = wxT( "?" ); Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference ); cmpref = ComponentsList[ii].GetRef();
msg.Printf( _( "Error item %s%s" ), cmpref.GetData(),
Buff.GetData() ); msg.Printf( _( "Error item %s%s" ), GetChars( cmpref ),
GetChars( Buff ) );
Buff.Printf( _( " unit %d and no more than %d parts" ), Buff.Printf( _( " unit %d and no more than %d parts" ),
ComponentsList[ii].m_Unit, ComponentsList[ii].m_Unit,
...@@ -789,9 +821,10 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList, ...@@ -789,9 +821,10 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList,
else else
Buff = wxT( "?" ); Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference ); cmpref = ComponentsList[ii].GetRef();
msg.Printf( _( "Multiple item %s%s" ), msg.Printf( _( "Multiple item %s%s" ),
cmpref.GetData(), Buff.GetData() ); GetChars( cmpref ), GetChars( Buff ) );
if( ( ComponentsList[ii].m_Unit > 0 ) if( ( ComponentsList[ii].m_Unit > 0 )
&& ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) ) && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) )
...@@ -819,9 +852,9 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList, ...@@ -819,9 +852,9 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList,
else else
Buff = wxT( "?" ); Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference ); cmpref = ComponentsList[ii].GetRef();
msg.Printf( _( "Multiple item %s%s" ), msg.Printf( _( "Multiple item %s%s" ),
cmpref.GetData(), Buff.GetData() ); GetChars( cmpref ), GetChars( Buff ) );
if( ( ComponentsList[ii].m_Unit > 0 ) if( ( ComponentsList[ii].m_Unit > 0 )
&& ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) ) && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) )
...@@ -846,16 +879,17 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList, ...@@ -846,16 +879,17 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList,
int next = ii + 1; int next = ii + 1;
if( ComponentsList[ii].CompareValue( ComponentsList[next] ) != 0 ) if( ComponentsList[ii].CompareValue( ComponentsList[next] ) != 0 )
{ {
wxString nextcmpref; wxString nextcmpref = ComponentsList[next].GetRef();
cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference );
nextcmpref = CONV_FROM_UTF8( ComponentsList[next].m_Reference ); cmpref = ComponentsList[ii].GetRef();
#if defined(KICAD_GOST) #if defined(KICAD_GOST)
msg.Printf( _( "Diff values for %s%d.%c (%s) and %s%d.%c (%s)" ), msg.Printf( _( "Diff values for %s%d.%c (%s) and %s%d.%c (%s)" ),
cmpref.GetData(), cmpref.GetData(),
ComponentsList[ii].m_NumRef, ComponentsList[ii].m_NumRef,
ComponentsList[ii].m_Unit + '1' - 1, ComponentsList[ii].m_Unit + '1' - 1,
ComponentsList[ii].m_Value->GetData(), GetChars( *ComponentsList[ii].m_Value ),
nextcmpref.GetData(), GetChars( nextcmpref ),
ComponentsList[next].m_NumRef, ComponentsList[next].m_NumRef,
ComponentsList[next].m_Unit + '1' - 1, ComponentsList[next].m_Unit + '1' - 1,
ComponentsList[next].m_Value->GetData() ); ComponentsList[next].m_Value->GetData() );
...@@ -864,11 +898,11 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList, ...@@ -864,11 +898,11 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList,
cmpref.GetData(), cmpref.GetData(),
ComponentsList[ii].m_NumRef, ComponentsList[ii].m_NumRef,
ComponentsList[ii].m_Unit + 'A' - 1, ComponentsList[ii].m_Unit + 'A' - 1,
ComponentsList[ii].m_Value->GetData(), GetChars( *ComponentsList[ii].m_Value ),
nextcmpref.GetData(), GetChars( nextcmpref ),
ComponentsList[next].m_NumRef, ComponentsList[next].m_NumRef,
ComponentsList[next].m_Unit + 'A' - 1, ComponentsList[next].m_Unit + 'A' - 1,
ComponentsList[next].m_Value->GetData() ); GetChars( *ComponentsList[next].m_Value ) );
#endif #endif
if( aMessageList ) if( aMessageList )
...@@ -897,15 +931,19 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList, ...@@ -897,15 +931,19 @@ int WinEDA_SchematicFrame::CheckAnnotate( wxArrayString* aMessageList,
/* Same time stamp found. */ /* Same time stamp found. */
wxString nextcmpref; wxString nextcmpref;
wxString full_path; wxString full_path;
full_path.Printf( wxT( "%s%8.8X" ), full_path.Printf( wxT( "%s%8.8X" ),
ComponentsList[ii].m_SheetPath.Path().GetData(), GetChars( ComponentsList[ii].m_SheetPath.Path() ),
ComponentsList[ii].m_TimeStamp ); ComponentsList[ii].m_TimeStamp );
cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference );
nextcmpref = CONV_FROM_UTF8( ComponentsList[ii + 1].m_Reference ); cmpref = ComponentsList[ii].GetRef();
nextcmpref = ComponentsList[ii + 1].GetRef();
msg.Printf( _( "duplicate time stamp (%s) for %s%d and %s%d" ), msg.Printf( _( "duplicate time stamp (%s) for %s%d and %s%d" ),
full_path.GetData(), GetChars( full_path ),
cmpref.GetData(), ComponentsList[ii].m_NumRef, GetChars( cmpref ), ComponentsList[ii].m_NumRef,
nextcmpref.GetData(), ComponentsList[ii + 1].m_NumRef ); GetChars( nextcmpref ), ComponentsList[ii + 1].m_NumRef );
if( aMessageList ) if( aMessageList )
{ {
aMessageList->Add( msg + wxT( "\n" )); aMessageList->Add( msg + wxT( "\n" ));
......
...@@ -32,7 +32,10 @@ ...@@ -32,7 +32,10 @@
* the return value for an error. * the return value for an error.
*/ */
/* object used in build BOM to handle the list of labels in schematic
/**
* Class LABEL_OBJECT
* is used in build BOM to handle the list of labels in schematic
* because in a complex hierarchy, a label is used more than once, * because in a complex hierarchy, a label is used more than once,
* and had more than one sheet path, so we must create a flat list of labels * and had more than one sheet path, so we must create a flat list of labels
*/ */
...@@ -53,14 +56,9 @@ public: LABEL_OBJECT() ...@@ -53,14 +56,9 @@ public: LABEL_OBJECT()
}; };
// Filename extension for BOM list
static const wxString BomFileExtension( wxT( "lst" ) );
static const wxString CsvFileExtension( wxT( "csv" ) );
#define BomFileWildcard _( "Bill of Materials file (*.lst)|*.lst" )
static void BuildComponentsListFromSchematic( static void BuildComponentsListFromSchematic(
std::vector <OBJ_CMP_TO_LIST>& aList ); std::vector <OBJ_CMP_TO_LIST>& aList );
static void GenListeGLabels( std::vector <LABEL_OBJECT>& aList ); static void GenListeGLabels( std::vector <LABEL_OBJECT>& aList );
static bool SortComponentsByReference( const OBJ_CMP_TO_LIST& obj1, static bool SortComponentsByReference( const OBJ_CMP_TO_LIST& obj1,
const OBJ_CMP_TO_LIST& obj2 ); const OBJ_CMP_TO_LIST& obj2 );
...@@ -73,14 +71,14 @@ static bool SortLabelsBySheet( const LABEL_OBJECT& obj1, ...@@ -73,14 +71,14 @@ static bool SortLabelsBySheet( const LABEL_OBJECT& obj1,
static void DeleteSubCmp( std::vector <OBJ_CMP_TO_LIST>& aList ); static void DeleteSubCmp( std::vector <OBJ_CMP_TO_LIST>& aList );
static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList ); static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList );
int RefDesStringCompare( const char* obj1, const char* obj2 ); int RefDesStringCompare( const wxString& lhs, const wxString& rhs );
int SplitString( wxString strToSplit, int SplitString( wxString strToSplit,
wxString* strBeginning, wxString* strBeginning,
wxString* strDigits, wxString* strDigits,
wxString* strEnd ); wxString* strEnd );
/* separator used in bom export to spreadsheet */ // separator used in bom export to spreadsheet
static char s_ExportSeparatorSymbol; static char s_ExportSeparatorSymbol;
...@@ -89,27 +87,53 @@ void DIALOG_BUILD_BOM::Create_BOM_Lists( int aTypeFile, ...@@ -89,27 +87,53 @@ void DIALOG_BUILD_BOM::Create_BOM_Lists( int aTypeFile,
char aExportSeparatorSymbol, char aExportSeparatorSymbol,
bool aRunBrowser ) bool aRunBrowser )
{ {
wxFileName fn; wxString wildcard;
static wxFileName fn;
wxFileName current = g_RootSheet->m_AssociatedScreen->m_FileName;
s_ExportSeparatorSymbol = aExportSeparatorSymbol; s_ExportSeparatorSymbol = aExportSeparatorSymbol;
m_ListFileName = g_RootSheet->m_AssociatedScreen->m_FileName; if( !fn.HasName() || fn.GetName()==NAMELESS_PROJECT )
fn = m_ListFileName; {
if( aTypeFile == 2 ) fn.SetName( current.GetName() );
fn.SetExt( CsvFileExtension ); }
// else use a previous run's name, because fn was set before and user
// is probably just iteratively refining the BOM.
if( fn.GetPath().IsEmpty() )
{
fn.SetPath( current.GetPath() );
}
// else use a previous run's path, because fn was set before and user
// is probably just iteratively refining the BOM.
wxString bomDesc = _( "Bill of Materials" ); // translate once, use twice.
if( aTypeFile == 0 )
{
fn.SetExt( wxT( "lst" ) );
wildcard = bomDesc + wxT( " (*.lst)|*.lst" );
}
else else
fn.SetExt( BomFileExtension ); {
fn.SetExt( wxT( "csv" ) );
wildcard = bomDesc + wxT( " (*.csv)|*.csv" );
}
wxFileDialog dlg( this, _( "Bill of Materials" ), fn.GetPath(), wxFileDialog dlg( this, bomDesc, fn.GetPath(),
fn.GetFullName(), BomFileWildcard, fn.GetFullName(), wildcard,
wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
if( dlg.ShowModal() == wxID_CANCEL ) if( dlg.ShowModal() == wxID_CANCEL )
return; return;
fn = dlg.GetPath(); // remember path+filename+ext for subsequent runs.
m_ListFileName = dlg.GetPath(); m_ListFileName = dlg.GetPath();
/* Close dialog, then show the list (if so requested) */ // Close dialog, then show the list (if so requested)
switch( aTypeFile ) switch( aTypeFile )
{ {
...@@ -148,6 +172,7 @@ bool DIALOG_BUILD_BOM::IsFieldChecked(int aFieldId) ...@@ -148,6 +172,7 @@ bool DIALOG_BUILD_BOM::IsFieldChecked(int aFieldId)
{ {
if( m_AddAllFields->IsChecked() && (aFieldId>= FIELD1) ) if( m_AddAllFields->IsChecked() && (aFieldId>= FIELD1) )
return true; return true;
switch ( aFieldId ) switch ( aFieldId )
{ {
case FIELD1: case FIELD1:
...@@ -173,11 +198,7 @@ bool DIALOG_BUILD_BOM::IsFieldChecked(int aFieldId) ...@@ -173,11 +198,7 @@ bool DIALOG_BUILD_BOM::IsFieldChecked(int aFieldId)
return false; return false;
} }
/*
* Print a list of components, in a form which can be imported by a spreadsheet
* form is:
* cmp value; number of components; <footprint>; <field1>; ...; list of references having the same value
*/
void DIALOG_BUILD_BOM::CreatePartsList( const wxString& aFullFileName, bool aIncludeSubComponents ) void DIALOG_BUILD_BOM::CreatePartsList( const wxString& aFullFileName, bool aIncludeSubComponents )
{ {
FILE* f; FILE* f;
...@@ -192,16 +213,17 @@ void DIALOG_BUILD_BOM::CreatePartsList( const wxString& aFullFileName, bool aInc ...@@ -192,16 +213,17 @@ void DIALOG_BUILD_BOM::CreatePartsList( const wxString& aFullFileName, bool aInc
} }
std::vector <OBJ_CMP_TO_LIST> cmplist; std::vector <OBJ_CMP_TO_LIST> cmplist;
BuildComponentsListFromSchematic( cmplist ); BuildComponentsListFromSchematic( cmplist );
/* sort component list by ref and remove sub components*/ // sort component list by ref and remove sub components
if( !aIncludeSubComponents ) if( !aIncludeSubComponents )
{ {
sort( cmplist.begin(), cmplist.end(), SortComponentsByReference ); sort( cmplist.begin(), cmplist.end(), SortComponentsByReference );
DeleteSubCmp( cmplist ); DeleteSubCmp( cmplist );
} }
/* sort component list by value*/ // sort component list by value
sort( cmplist.begin(), cmplist.end(), SortComponentsByValue ); sort( cmplist.begin(), cmplist.end(), SortComponentsByValue );
PrintComponentsListByPart( f, cmplist,aIncludeSubComponents ); PrintComponentsListByPart( f, cmplist,aIncludeSubComponents );
...@@ -231,13 +253,13 @@ void DIALOG_BUILD_BOM::CreateExportList( const wxString& aFullFileName, ...@@ -231,13 +253,13 @@ void DIALOG_BUILD_BOM::CreateExportList( const wxString& aFullFileName,
std::vector <OBJ_CMP_TO_LIST> cmplist; std::vector <OBJ_CMP_TO_LIST> cmplist;
BuildComponentsListFromSchematic( cmplist ); BuildComponentsListFromSchematic( cmplist );
/* sort component list */ // sort component list
sort( cmplist.begin(), cmplist.end(), SortComponentsByReference ); sort( cmplist.begin(), cmplist.end(), SortComponentsByReference );
if( !aIncludeSubComponents ) if( !aIncludeSubComponents )
DeleteSubCmp( cmplist ); DeleteSubCmp( cmplist );
/* create the file */ // create the file
PrintComponentsListByRef( f, cmplist, TRUE, aIncludeSubComponents ); PrintComponentsListByRef( f, cmplist, TRUE, aIncludeSubComponents );
fclose( f ); fclose( f );
...@@ -270,13 +292,15 @@ void DIALOG_BUILD_BOM::GenereListeOfItems( const wxString& aFullFileName, ...@@ -270,13 +292,15 @@ void DIALOG_BUILD_BOM::GenereListeOfItems( const wxString& aFullFileName,
itemCount = cmplist.size(); itemCount = cmplist.size();
if( itemCount ) if( itemCount )
{ {
/* creates the list file */ // creates the list file
DateAndTime( Line ); DateAndTime( Line );
wxString Title = wxGetApp().GetAppName() + wxT( " " ) + wxString Title = wxGetApp().GetAppName() + wxT( " " ) +
GetBuildVersion(); GetBuildVersion();
fprintf( f, "%s >> Creation date: %s\n", CONV_TO_UTF8( Title ), Line ); fprintf( f, "%s >> Creation date: %s\n", CONV_TO_UTF8( Title ), Line );
/* sort component list */ // sort component list
sort( cmplist.begin(), cmplist.end(), SortComponentsByReference ); sort( cmplist.begin(), cmplist.end(), SortComponentsByReference );
if( !aIncludeSubComponents ) if( !aIncludeSubComponents )
...@@ -296,16 +320,19 @@ void DIALOG_BUILD_BOM::GenereListeOfItems( const wxString& aFullFileName, ...@@ -296,16 +320,19 @@ void DIALOG_BUILD_BOM::GenereListeOfItems( const wxString& aFullFileName,
/* Create list of global labels and pins sheets */ /* Create list of global labels and pins sheets */
/*************************************************/ /*************************************************/
std::vector <LABEL_OBJECT> listOfLabels; std::vector <LABEL_OBJECT> listOfLabels;
GenListeGLabels( listOfLabels ); GenListeGLabels( listOfLabels );
if( ( itemCount = listOfLabels.size() ) > 0 ) if( ( itemCount = listOfLabels.size() ) > 0 )
{ {
if( m_GenListLabelsbySheet->GetValue() ) if( m_GenListLabelsbySheet->GetValue() )
{ {
sort( listOfLabels.begin(), listOfLabels.end(), SortLabelsBySheet ); sort( listOfLabels.begin(), listOfLabels.end(), SortLabelsBySheet );
msg.Printf( _( msg.Printf( _(
"\n#Global, Hierarchical Labels and PinSheets \ "\n#Global, Hierarchical Labels and PinSheets "
( order = Sheet Number ) count = %d\n" ), "( order = Sheet Number ) count = %d\n" ),
itemCount ); itemCount );
fprintf( f, "%s", CONV_TO_UTF8( msg ) ); fprintf( f, "%s", CONV_TO_UTF8( msg ) );
PrintListeGLabel( f, listOfLabels ); PrintListeGLabel( f, listOfLabels );
} }
...@@ -315,9 +342,10 @@ void DIALOG_BUILD_BOM::GenereListeOfItems( const wxString& aFullFileName, ...@@ -315,9 +342,10 @@ void DIALOG_BUILD_BOM::GenereListeOfItems( const wxString& aFullFileName,
sort( listOfLabels.begin(), listOfLabels.end(), SortLabelsByValue ); sort( listOfLabels.begin(), listOfLabels.end(), SortLabelsByValue );
msg.Printf( _( msg.Printf( _(
"\n#Global, Hierarchical Labels and PinSheets ( \ "\n#Global, Hierarchical Labels and PinSheets ( "
order = Alphab. ) count = %d\n\n" ), "order = Alphab. ) count = %d\n\n" ),
itemCount ); itemCount );
fprintf( f, "%s", CONV_TO_UTF8( msg ) ); fprintf( f, "%s", CONV_TO_UTF8( msg ) );
PrintListeGLabel( f, listOfLabels ); PrintListeGLabel( f, listOfLabels );
} }
...@@ -329,47 +357,43 @@ order = Alphab. ) count = %d\n\n" ...@@ -329,47 +357,43 @@ order = Alphab. ) count = %d\n\n"
} }
/* Creates the list of components found in the whole schematic /**
* Function BuildComponentsListFromSchematic
* creates the list of components found in the whole schematic.
* *
* if List == null, just returns the count. if not, fills the list. * Goes through the 'sheets', not the screens, so that we account for
* goes through the sheets, not the screens, so that we account for
* multiple instances of a given screen. * multiple instances of a given screen.
* Also Initialize m_Father as pointer of the SCH_SCREEN parent
*/ */
void BuildComponentsListFromSchematic( std::vector <OBJ_CMP_TO_LIST>& aList ) void BuildComponentsListFromSchematic( std::vector <OBJ_CMP_TO_LIST>& aList )
{ {
EDA_BaseStruct* SchItem; // Build the sheet list (which is not screen a screen list)
SCH_COMPONENT* DrawLibItem; SCH_SHEET_LIST sheetList; // uses a global
SCH_SHEET_PATH* sheetPath;
/* Build the sheet (not screen) list */
SCH_SHEET_LIST SheetList;
for( sheetPath = SheetList.GetFirst(); sheetPath != NULL; sheetPath = SheetList.GetNext() ) for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext() )
{ {
for( SchItem = sheetPath->LastDrawList(); SchItem; SchItem = SchItem->Next() ) for( EDA_BaseStruct* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
{ {
if( SchItem->Type() != TYPE_SCH_COMPONENT ) if( schItem->Type() != TYPE_SCH_COMPONENT )
continue; continue;
DrawLibItem = (SCH_COMPONENT*) SchItem; SCH_COMPONENT* comp = (SCH_COMPONENT*) schItem;
DrawLibItem->SetParent( sheetPath->LastScreen() );
comp->SetParent( path->LastScreen() );
OBJ_CMP_TO_LIST item; OBJ_CMP_TO_LIST item;
item.m_RootCmp = DrawLibItem;
item.m_SheetPath = *sheetPath; item.m_RootCmp = comp;
item.m_Unit = DrawLibItem->GetUnitSelection( sheetPath ); item.m_SheetPath = *path;
item.m_Unit = comp->GetUnitSelection( path );
strncpy( item.m_Reference,
CONV_TO_UTF8( DrawLibItem->GetRef( sheetPath ) ), item.SetRef( comp->GetRef( path ) );
sizeof( item.m_Reference ) );
// skip pseudo components, which have a reference starting
// Ensure always null terminate m_Ref. // with #, mainly power symbols
item.m_Reference[sizeof( item.m_Reference ) - 1 ] = 0; if( item.GetRefStr()[0] == '#' )
// Skip pseudo components:
// pseudo components have a reference starting by #. Mainly power symbols
if( item.m_Reference[0] == '#' )
continue; continue;
// Real component found, push it in list
// Real component found, keep it
aList.push_back( item ); aList.push_back( item );
} }
} }
...@@ -380,40 +404,37 @@ void BuildComponentsListFromSchematic( std::vector <OBJ_CMP_TO_LIST>& aList ) ...@@ -380,40 +404,37 @@ void BuildComponentsListFromSchematic( std::vector <OBJ_CMP_TO_LIST>& aList )
*/ */
static void GenListeGLabels( std::vector <LABEL_OBJECT>& aList ) static void GenListeGLabels( std::vector <LABEL_OBJECT>& aList )
{ {
SCH_ITEM* DrawList; // Build the sheet list
SCH_SHEET_PATH* sheetPath; SCH_SHEET_LIST sheetList;
/* Build the sheet list */
SCH_SHEET_LIST SheetList;
LABEL_OBJECT labet_object; LABEL_OBJECT lable;
for( sheetPath = SheetList.GetFirst(); sheetPath != NULL; sheetPath = SheetList.GetNext() ) for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext() )
{ {
DrawList = (SCH_ITEM*) sheetPath->LastDrawList(); SCH_ITEM* schItem = (SCH_ITEM*) path->LastDrawList();
while( DrawList ) while( schItem )
{ {
switch( DrawList->Type() ) switch( schItem->Type() )
{ {
case TYPE_SCH_HIERLABEL: case TYPE_SCH_HIERLABEL:
case TYPE_SCH_GLOBALLABEL: case TYPE_SCH_GLOBALLABEL:
labet_object.m_LabelType = DrawList->Type(); lable.m_LabelType = schItem->Type();
labet_object.m_SheetPath = *sheetPath; lable.m_SheetPath = *path;
labet_object.m_Label = DrawList; lable.m_Label = schItem;
aList.push_back( labet_object ); aList.push_back( lable );
break; break;
case DRAW_SHEET_STRUCT_TYPE: case DRAW_SHEET_STRUCT_TYPE:
{ {
SCH_SHEET* sheet = (SCH_SHEET*) DrawList; SCH_SHEET* sheet = (SCH_SHEET*) schItem;
BOOST_FOREACH( SCH_SHEET_PIN sheetLabel, sheet->GetSheetPins() ) BOOST_FOREACH( SCH_SHEET_PIN sheetLabel, sheet->GetSheetPins() )
{ {
labet_object.m_LabelType = DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE; lable.m_LabelType = DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE;
labet_object.m_SheetPath = *sheetPath; lable.m_SheetPath = *path;
labet_object.m_Label = &sheetLabel; lable.m_Label = &sheetLabel;
aList.push_back( labet_object ); aList.push_back( lable );
} }
} }
break; break;
...@@ -422,7 +443,7 @@ static void GenListeGLabels( std::vector <LABEL_OBJECT>& aList ) ...@@ -422,7 +443,7 @@ static void GenListeGLabels( std::vector <LABEL_OBJECT>& aList )
break; break;
} }
DrawList = DrawList->Next(); schItem = schItem->Next();
} }
} }
} }
...@@ -446,7 +467,7 @@ bool SortComponentsByValue( const OBJ_CMP_TO_LIST& obj1, ...@@ -446,7 +467,7 @@ bool SortComponentsByValue( const OBJ_CMP_TO_LIST& obj1,
if( ii == 0 ) if( ii == 0 )
{ {
ii = RefDesStringCompare( obj1.m_Reference, obj2.m_Reference ); ii = RefDesStringCompare( obj1.GetRef(), obj2.GetRef() );
} }
if( ii == 0 ) if( ii == 0 )
...@@ -470,7 +491,7 @@ bool SortComponentsByReference( const OBJ_CMP_TO_LIST& obj1, ...@@ -470,7 +491,7 @@ bool SortComponentsByReference( const OBJ_CMP_TO_LIST& obj1,
int ii; int ii;
const wxString* Text1, * Text2; const wxString* Text1, * Text2;
ii = RefDesStringCompare( obj1.m_Reference, obj2.m_Reference ); ii = RefDesStringCompare( obj1.GetRef(), obj2.GetRef() );
if( ii == 0 ) if( ii == 0 )
{ {
...@@ -528,7 +549,6 @@ bool SortLabelsBySheet( const LABEL_OBJECT& obj1, const LABEL_OBJECT& obj2 ) ...@@ -528,7 +549,6 @@ bool SortLabelsBySheet( const LABEL_OBJECT& obj1, const LABEL_OBJECT& obj2 )
int ii; int ii;
wxString Text1, Text2; wxString Text1, Text2;
ii = obj1.m_SheetPath.Cmp( obj2.m_SheetPath ); ii = obj1.m_SheetPath.Cmp( obj2.m_SheetPath );
if( ii == 0 ) if( ii == 0 )
...@@ -567,7 +587,7 @@ static void DeleteSubCmp( std::vector <OBJ_CMP_TO_LIST>& aList ) ...@@ -567,7 +587,7 @@ static void DeleteSubCmp( std::vector <OBJ_CMP_TO_LIST>& aList )
if( libItem == NULL ) if( libItem == NULL )
continue; continue;
currName = CONV_FROM_UTF8( aList[ii].m_Reference ); currName = aList[ii].GetRef();
if( !oldName.IsEmpty() ) if( !oldName.IsEmpty() )
{ {
...@@ -606,6 +626,7 @@ void DIALOG_BUILD_BOM::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem, ...@@ -606,6 +626,7 @@ void DIALOG_BUILD_BOM::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem,
{ {
if( ! IsFieldChecked( ii ) ) if( ! IsFieldChecked( ii ) )
continue; continue;
if( CompactForm ) if( CompactForm )
fprintf( f, "%c%s", s_ExportSeparatorSymbol, fprintf( f, "%c%s", s_ExportSeparatorSymbol,
CONV_TO_UTF8( DrawLibItem->GetField( ii )->m_Text ) ); CONV_TO_UTF8( DrawLibItem->GetField( ii )->m_Text ) );
...@@ -624,10 +645,6 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef( ...@@ -624,10 +645,6 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef(
bool CompactForm, bool CompactForm,
bool aIncludeSubComponents ) bool aIncludeSubComponents )
{ {
EDA_BaseStruct* DrawList;
SCH_COMPONENT* DrawLibItem;
LIB_COMPONENT* Entry;
char CmpName[80];
wxString msg; wxString msg;
if( CompactForm ) if( CompactForm )
...@@ -654,6 +671,7 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef( ...@@ -654,6 +671,7 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef(
continue; continue;
msg = _( "Field" ); msg = _( "Field" );
fprintf( f, "%c%s%d", s_ExportSeparatorSymbol, CONV_TO_UTF8( fprintf( f, "%c%s%d", s_ExportSeparatorSymbol, CONV_TO_UTF8(
msg ), ii - FIELD1 + 1 ); msg ), ii - FIELD1 + 1 );
} }
...@@ -666,80 +684,91 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef( ...@@ -666,80 +684,91 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef(
if( aIncludeSubComponents ) if( aIncludeSubComponents )
msg << _( " (with SubCmp)" ); msg << _( " (with SubCmp)" );
fprintf( f, "%s\n", CONV_TO_UTF8( msg ) ); fprintf( f, "%s\n", CONV_TO_UTF8( msg ) );
} }
std::string CmpName;
wxString subRef;
// Print list of items // Print list of items
for( unsigned ii = 0; ii < aList.size(); ii++ ) for( unsigned ii = 0; ii < aList.size(); ii++ )
{ {
DrawList = aList[ii].m_RootCmp; EDA_BaseStruct* item = aList[ii].m_RootCmp;
if( item == NULL )
if( DrawList == NULL )
continue; continue;
if( DrawList->Type() != TYPE_SCH_COMPONENT )
if( item->Type() != TYPE_SCH_COMPONENT )
continue; continue;
DrawLibItem = (SCH_COMPONENT*) DrawList; SCH_COMPONENT* comp = (SCH_COMPONENT*) item;
bool isMulti = false; bool isMulti = false;
wxString subRef;
Entry = CMP_LIBRARY::FindLibraryComponent( DrawLibItem->m_ChipName ); LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( comp->m_ChipName );
if( Entry ) if( entry )
isMulti = Entry->IsMulti(); isMulti = entry->IsMulti();
if( isMulti && aIncludeSubComponents ) if( isMulti && aIncludeSubComponents )
subRef = LIB_COMPONENT::ReturnSubReference( aList[ii].m_Unit ); subRef = LIB_COMPONENT::ReturnSubReference( aList[ii].m_Unit );
else else
subRef.Empty(); subRef.Empty();
sprintf( CmpName, "%s", aList[ii].m_Reference ); CmpName = aList[ii].GetRefStr();
if( !CompactForm ) if( !CompactForm )
sprintf( CmpName + strlen( CmpName ), "%s", CONV_TO_UTF8(subRef) ); CmpName += CONV_TO_UTF8(subRef);
if( CompactForm ) if( CompactForm )
#if defined(KICAD_GOST) #if defined(KICAD_GOST)
fprintf( f, "%s%c%s%c%s", CmpName, s_ExportSeparatorSymbol, fprintf( f, "%s%c%s%c%s", CmpName.c_str(), s_ExportSeparatorSymbol,
CONV_TO_UTF8( DrawLibItem->GetField( CONV_TO_UTF8( comp->GetField(
VALUE )->m_Text ), s_ExportSeparatorSymbol, VALUE )->m_Text ), s_ExportSeparatorSymbol,
CONV_TO_UTF8( DrawLibItem->GetField( DATASHEET )->m_Text ) ); CONV_TO_UTF8( comp->GetField( DATASHEET )->m_Text ) );
#else #else
fprintf( f, "%s%c%s", CmpName, s_ExportSeparatorSymbol, fprintf( f, "%s%c%s", CmpName.c_str(), s_ExportSeparatorSymbol,
CONV_TO_UTF8( DrawLibItem->GetField( VALUE )->m_Text ) ); CONV_TO_UTF8( comp->GetField( VALUE )->m_Text ) );
#endif #endif
else else
#if defined(KICAD_GOST) #if defined(KICAD_GOST)
fprintf( f, "| %-10s %-12s %-20s", CmpName, fprintf( f, "| %-10s %-12s %-20s", CmpName.c_str(),
CONV_TO_UTF8( DrawLibItem->GetField( VALUE )->m_Text ), CONV_TO_UTF8( comp->GetField( VALUE )->m_Text ),
CONV_TO_UTF8( DrawLibItem->GetField( DATASHEET )->m_Text ) ); CONV_TO_UTF8( comp->GetField( DATASHEET )->m_Text ) );
#else #else
fprintf( f, "| %-10s %-12s", CmpName, fprintf( f, "| %-10s %-12s", CmpName.c_str(),
CONV_TO_UTF8( DrawLibItem->GetField( VALUE )->m_Text ) ); CONV_TO_UTF8( comp->GetField( VALUE )->m_Text ) );
#endif #endif
if( aIncludeSubComponents ) if( aIncludeSubComponents )
{ {
msg = aList[ii].m_SheetPath.PathHumanReadable(); msg = aList[ii].m_SheetPath.PathHumanReadable();
if( CompactForm ) if( CompactForm )
{ {
fprintf( f, "%c%s", s_ExportSeparatorSymbol, fprintf( f, "%c%s", s_ExportSeparatorSymbol,
CONV_TO_UTF8( msg ) ); CONV_TO_UTF8( msg ) );
msg = m_Parent->GetXYSheetReferences( msg = m_Parent->GetXYSheetReferences(
(BASE_SCREEN*) DrawLibItem->GetParent(), (BASE_SCREEN*) comp->GetParent(),
DrawLibItem->m_Pos ); comp->m_Pos );
fprintf( f, "%c%s)", s_ExportSeparatorSymbol, fprintf( f, "%c%s)", s_ExportSeparatorSymbol,
CONV_TO_UTF8( msg ) ); CONV_TO_UTF8( msg ) );
} }
else else
{ {
fprintf( f, " (Sheet %s)", CONV_TO_UTF8( msg ) ); fprintf( f, " (Sheet %s)", CONV_TO_UTF8( msg ) );
msg = m_Parent->GetXYSheetReferences( msg = m_Parent->GetXYSheetReferences(
(BASE_SCREEN*) DrawLibItem->GetParent(), (BASE_SCREEN*) comp->GetParent(),
DrawLibItem->m_Pos ); comp->m_Pos );
fprintf( f, " (loc %s)", CONV_TO_UTF8( msg ) ); fprintf( f, " (loc %s)", CONV_TO_UTF8( msg ) );
} }
} }
PrintFieldData( f, DrawLibItem, CompactForm ); PrintFieldData( f, comp, CompactForm );
fprintf( f, "\n" ); fprintf( f, "\n" );
} }
...@@ -771,18 +800,20 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart( ...@@ -771,18 +800,20 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart(
bool aIncludeSubComponents) bool aIncludeSubComponents)
{ {
int qty = 0; int qty = 0;
wxString RefName; wxString refName;
wxString fullRefName; // reference + part Id (for multiple parts per package wxString fullRefName; // reference + part Id (for multiple parts per package
wxString ValName; wxString valName;
wxString RNames; wxString refNames;
wxString lastRef; wxString lastRef;
wxString unitId; wxString unitId;
SCH_COMPONENT* currCmp, *nextCmp; SCH_COMPONENT* currCmp;
SCH_COMPONENT dummyCmp; // A dummy component, to store fields SCH_COMPONENT* nextCmp;
SCH_COMPONENT dummyCmp; // A dummy component, to store fields
for( unsigned ii = 0; ii < aList.size(); ii++ ) for( unsigned ii = 0; ii < aList.size(); ii++ )
{ {
currCmp = (SCH_COMPONENT*) aList[ii].m_RootCmp; currCmp = (SCH_COMPONENT*) aList[ii].m_RootCmp;
if( ii < aList.size() -1 ) if( ii < aList.size() -1 )
nextCmp = aList[ii+1].m_RootCmp; nextCmp = aList[ii+1].m_RootCmp;
else else
...@@ -791,48 +822,53 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart( ...@@ -791,48 +822,53 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart(
// Store fields. Store non empty fields only. // Store fields. Store non empty fields only.
for( int jj = FOOTPRINT; jj < currCmp->GetFieldCount(); jj++ ) for( int jj = FOOTPRINT; jj < currCmp->GetFieldCount(); jj++ )
{ {
//Ensure fields exists in dummy component // Ensure fields exists in dummy component
if( dummyCmp.GetFieldCount() <= jj ) if( dummyCmp.GetFieldCount() <= jj )
dummyCmp.AddField( *currCmp->GetField( jj ) ); dummyCmp.AddField( *currCmp->GetField( jj ) );
// store useful data // store useful data
if( !currCmp->GetField( jj )->m_Text.IsEmpty() ) if( !currCmp->GetField( jj )->m_Text.IsEmpty() )
dummyCmp.GetField( jj )->m_Text = currCmp->GetField( jj )->m_Text; dummyCmp.GetField( jj )->m_Text = currCmp->GetField( jj )->m_Text;
} }
RefName = CONV_FROM_UTF8( aList[ii].m_Reference ); refName = aList[ii].GetRef();
ValName = currCmp->GetField( VALUE )->m_Text; valName = currCmp->GetField( VALUE )->m_Text;
int multi = 0; int multi = 0;
if( aIncludeSubComponents ) if( aIncludeSubComponents )
{ {
LIB_COMPONENT* Entry = CMP_LIBRARY::FindLibraryComponent( currCmp->m_ChipName ); LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( currCmp->m_ChipName );
if( Entry ) if( entry )
multi = Entry->GetPartCount(); multi = entry->GetPartCount();
if ( multi <= 1 ) if ( multi <= 1 )
multi = 0; multi = 0;
} }
if ( multi && aList[ii].m_Unit > 0 ) if ( multi && aList[ii].m_Unit > 0 )
unitId.Printf(wxT("%c"), 'A' -1 + aList[ii].m_Unit); unitId.Printf( wxT("%c"), 'A' -1 + aList[ii].m_Unit );
else unitId.Empty(); else
fullRefName = RefName + unitId; unitId.Empty();
if( RNames.IsEmpty() ) fullRefName = refName + unitId;
RNames = fullRefName;
if( refNames.IsEmpty() )
refNames = fullRefName;
else else
RNames << wxT( ", " ) << fullRefName; refNames << wxT( ", " ) << fullRefName;
// In multi parts per package, we have the reference more than once // In multi parts per package, we have the reference more than once
// but we must count only one package // but we must count only one package
if( lastRef != RefName ) if( lastRef != refName )
qty++; qty++;
lastRef = RefName;
lastRef = refName;
// if the next cmoponent has same value the line will be printed after. // if the next cmoponent has same value the line will be printed after.
if( nextCmp && nextCmp->GetField( VALUE )->m_Text.CmpNoCase( ValName ) == 0 ) if( nextCmp && nextCmp->GetField( VALUE )->m_Text.CmpNoCase( valName ) == 0 )
continue; continue;
// Print line for the current component value: // Print line for the current component value:
fprintf( f, "%15s%c%3d", CONV_TO_UTF8( ValName ), s_ExportSeparatorSymbol, qty ); fprintf( f, "%15s%c%3d", CONV_TO_UTF8( valName ), s_ExportSeparatorSymbol, qty );
if( IsFieldChecked(FOOTPRINT ) ) if( IsFieldChecked(FOOTPRINT ) )
fprintf( f, "%c%15s", s_ExportSeparatorSymbol, fprintf( f, "%c%15s", s_ExportSeparatorSymbol,
...@@ -840,17 +876,20 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart( ...@@ -840,17 +876,20 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart(
#if defined(KICAD_GOST) #if defined(KICAD_GOST)
fprintf( f, "%c%20s", s_ExportSeparatorSymbol, fprintf( f, "%c%20s", s_ExportSeparatorSymbol,
CONV_TO_UTF8( currCmp->GetField( DATASHEET) ->m_Text ) ); CONV_TO_UTF8( currCmp->GetField( DATASHEET )->m_Text ) );
#endif #endif
fprintf( f, "%c%s", s_ExportSeparatorSymbol, // wrap the field in quotes, since it has commas in it.
CONV_TO_UTF8( RNames ) ); fprintf( f, "%c\"%s\"", s_ExportSeparatorSymbol,
CONV_TO_UTF8( refNames ) );
// print fields, on demand // print fields, on demand
int last_nonempty_field_idx = 0; int last_nonempty_field_idx = 0;
for( int jj = FOOTPRINT; jj < dummyCmp.GetFieldCount(); jj++ ) for( int jj = FOOTPRINT; jj < dummyCmp.GetFieldCount(); jj++ )
if ( !dummyCmp.GetField( jj )->m_Text.IsEmpty() ) if ( !dummyCmp.GetField( jj )->m_Text.IsEmpty() )
last_nonempty_field_idx = jj; last_nonempty_field_idx = jj;
for( int jj = FIELD1; jj <= last_nonempty_field_idx ; jj++ ) for( int jj = FIELD1; jj <= last_nonempty_field_idx ; jj++ )
{ {
if ( IsFieldChecked( jj ) ) if ( IsFieldChecked( jj ) )
...@@ -862,7 +901,8 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart( ...@@ -862,7 +901,8 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart(
// Clear strings and values, to prepare next component // Clear strings and values, to prepare next component
qty = 0; qty = 0;
RNames.Empty(); refNames.Empty();
for( int jj = FOOTPRINT; jj < dummyCmp.GetFieldCount(); jj++ ) for( int jj = FOOTPRINT; jj < dummyCmp.GetFieldCount(); jj++ )
dummyCmp.GetField( jj )->m_Text.Empty(); dummyCmp.GetField( jj )->m_Text.Empty();
} }
...@@ -876,10 +916,10 @@ int DIALOG_BUILD_BOM::PrintComponentsListByVal( ...@@ -876,10 +916,10 @@ int DIALOG_BUILD_BOM::PrintComponentsListByVal(
std::vector <OBJ_CMP_TO_LIST>& aList, std::vector <OBJ_CMP_TO_LIST>& aList,
bool aIncludeSubComponents ) bool aIncludeSubComponents )
{ {
EDA_BaseStruct* DrawList; EDA_BaseStruct* schItem;
SCH_COMPONENT* DrawLibItem; SCH_COMPONENT* DrawLibItem;
LIB_COMPONENT* Entry; LIB_COMPONENT* entry;
char CmpName[80]; std::string CmpName;
wxString msg; wxString msg;
msg = _( "\n#Cmp ( order = Value )" ); msg = _( "\n#Cmp ( order = Value )" );
...@@ -887,24 +927,25 @@ int DIALOG_BUILD_BOM::PrintComponentsListByVal( ...@@ -887,24 +927,25 @@ int DIALOG_BUILD_BOM::PrintComponentsListByVal(
if( aIncludeSubComponents ) if( aIncludeSubComponents )
msg << _( " (with SubCmp)" ); msg << _( " (with SubCmp)" );
msg << wxT( "\n" ); msg << wxT( "\n" );
fputs( CONV_TO_UTF8( msg ), f ); fputs( CONV_TO_UTF8( msg ), f );
for( unsigned ii = 0; ii < aList.size(); ii++ ) for( unsigned ii = 0; ii < aList.size(); ii++ )
{ {
DrawList = aList[ii].m_RootCmp; schItem = aList[ii].m_RootCmp;
if( DrawList == NULL ) if( schItem == NULL )
continue; continue;
if( DrawList->Type() != TYPE_SCH_COMPONENT ) if( schItem->Type() != TYPE_SCH_COMPONENT )
continue; continue;
DrawLibItem = (SCH_COMPONENT*) DrawList; DrawLibItem = (SCH_COMPONENT*) schItem;
bool isMulti = false; bool isMulti = false;
Entry = CMP_LIBRARY::FindLibraryComponent( DrawLibItem->m_ChipName ); entry = CMP_LIBRARY::FindLibraryComponent( DrawLibItem->m_ChipName );
if( Entry ) if( entry )
isMulti = Entry->IsMulti(); isMulti = entry->IsMulti();
wxString subRef; wxString subRef;
if( isMulti && aIncludeSubComponents ) if( isMulti && aIncludeSubComponents )
...@@ -912,11 +953,12 @@ int DIALOG_BUILD_BOM::PrintComponentsListByVal( ...@@ -912,11 +953,12 @@ int DIALOG_BUILD_BOM::PrintComponentsListByVal(
else else
subRef.Empty(); subRef.Empty();
sprintf( CmpName, "%s%s", aList[ii].m_Reference, CONV_TO_UTF8(subRef) ); CmpName = aList[ii].GetRefStr();
CmpName += CONV_TO_UTF8(subRef);
fprintf( f, "| %-12s %-10s", fprintf( f, "| %-12s %-10s",
CONV_TO_UTF8( DrawLibItem->GetField( VALUE )->m_Text ), CONV_TO_UTF8( DrawLibItem->GetField( VALUE )->m_Text ),
CmpName ); CmpName.c_str() );
// print the sheet path // print the sheet path
if( aIncludeSubComponents ) if( aIncludeSubComponents )
...@@ -962,9 +1004,9 @@ static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList ) ...@@ -962,9 +1004,9 @@ static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList )
sheetpath = aList[ii].m_SheetPath.PathHumanReadable(); sheetpath = aList[ii].m_SheetPath.PathHumanReadable();
msg.Printf( msg.Printf(
_( "> %-28.28s %s (Sheet %s) pos: %3.3f, %3.3f\n" ), _( "> %-28.28s %s (Sheet %s) pos: %3.3f, %3.3f\n" ),
DrawTextItem->m_Text.GetData(), GetChars( DrawTextItem->m_Text ),
labeltype.GetData(), GetChars( labeltype ),
sheetpath.GetData(), GetChars( sheetpath ),
(float) DrawTextItem->m_Pos.x / 1000, (float) DrawTextItem->m_Pos.x / 1000,
(float) DrawTextItem->m_Pos.y / 1000 ); (float) DrawTextItem->m_Pos.y / 1000 );
...@@ -975,18 +1017,23 @@ static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList ) ...@@ -975,18 +1017,23 @@ static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList )
{ {
DrawSheetLabel = (SCH_SHEET_PIN*) aList[ii].m_Label; DrawSheetLabel = (SCH_SHEET_PIN*) aList[ii].m_Label;
int jj = DrawSheetLabel->m_Shape; int jj = DrawSheetLabel->m_Shape;
if( jj < 0 ) if( jj < 0 )
jj = NET_TMAX; jj = NET_TMAX;
if( jj > NET_TMAX ) if( jj > NET_TMAX )
jj = 4; jj = 4;
wxString labtype = CONV_FROM_UTF8( SheetLabelType[jj] ); wxString labtype = CONV_FROM_UTF8( SheetLabelType[jj] );
msg.Printf( msg.Printf(
_( "> %-28.28s PinSheet %-7.7s (Sheet %s) pos: %3.3f, %3.3f\n" ), _( "> %-28.28s PinSheet %-7.7s (Sheet %s) pos: %3.3f, %3.3f\n" ),
DrawSheetLabel->m_Text.GetData(), GetChars( DrawSheetLabel->m_Text ),
labtype.GetData(), GetChars( labtype ),
aList[ii].m_SheetPath.PathHumanReadable().GetData(), GetChars( aList[ii].m_SheetPath.PathHumanReadable()),
(float) DrawSheetLabel->m_Pos.x / 1000, (float) DrawSheetLabel->m_Pos.x / 1000,
(float) DrawSheetLabel->m_Pos.y / 1000 ); (float) DrawSheetLabel->m_Pos.y / 1000 );
fputs( CONV_TO_UTF8( msg ), f ); fputs( CONV_TO_UTF8( msg ), f );
} }
break; break;
...@@ -1008,35 +1055,27 @@ static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList ) ...@@ -1008,35 +1055,27 @@ static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList )
* return 0 if the strings are equal * return 0 if the strings are equal
* return 1 if the first string is greater than the second * return 1 if the first string is greater than the second
*/ */
int RefDesStringCompare( const char* obj1, const char* obj2 ) int RefDesStringCompare( const wxString& strFWord, const wxString& strSWord )
{ {
/* The strings we are going to compare */ // The different sections of the first string
wxString strFWord;
wxString strSWord;
/* The different sections of the first string */
wxString strFWordBeg, strFWordMid, strFWordEnd; wxString strFWordBeg, strFWordMid, strFWordEnd;
/* The different sections of the second string */ // The different sections of the second string
wxString strSWordBeg, strSWordMid, strSWordEnd; wxString strSWordBeg, strSWordMid, strSWordEnd;
int isEqual = 0; /* The numerical results of a string compare */ int isEqual = 0; // The numerical results of a string compare
int iReturn = 0; /* The variable that is being returned */ int iReturn = 0; // The variable that is being returned
long lFirstDigit = 0; /* The converted middle section of the first long lFirstDigit = 0; /* The converted middle section of the first
*string */ *string */
long lSecondDigit = 0; /* The converted middle section of the second long lSecondDigit = 0; /* The converted middle section of the second
*string */ *string */
/* Since m_Ref is a char * it is ASCII */ // Split the two string into separate parts
strFWord = wxString::FromAscii( obj1 );
strSWord = wxString::FromAscii( obj2 );
/* Split the two string into separate parts */
SplitString( strFWord, &strFWordBeg, &strFWordMid, &strFWordEnd ); SplitString( strFWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
SplitString( strSWord, &strSWordBeg, &strSWordMid, &strSWordEnd ); SplitString( strSWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
/* Compare the Beginning section of the strings */ // Compare the Beginning section of the strings
isEqual = strFWordBeg.CmpNoCase( strSWordBeg ); isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
if( isEqual > 0 ) if( isEqual > 0 )
iReturn = 1; iReturn = 1;
...@@ -1044,17 +1083,19 @@ int RefDesStringCompare( const char* obj1, const char* obj2 ) ...@@ -1044,17 +1083,19 @@ int RefDesStringCompare( const char* obj1, const char* obj2 )
iReturn = -1; iReturn = -1;
else else
{ {
/* If the first sections are equal compare there digits */ // If the first sections are equal compare there digits
strFWordMid.ToLong( &lFirstDigit ); strFWordMid.ToLong( &lFirstDigit );
strSWordMid.ToLong( &lSecondDigit ); strSWordMid.ToLong( &lSecondDigit );
if( lFirstDigit > lSecondDigit ) if( lFirstDigit > lSecondDigit )
iReturn = 1; iReturn = 1;
else if( lFirstDigit < lSecondDigit ) else if( lFirstDigit < lSecondDigit )
iReturn = -1; iReturn = -1;
else else
{ {
/* If the first two sections are equal compare the endings */ // If the first two sections are equal compare the endings
isEqual = strFWordEnd.CmpNoCase( strSWordEnd ); isEqual = strFWordEnd.CmpNoCase( strSWordEnd );
if( isEqual > 0 ) if( isEqual > 0 )
iReturn = 1; iReturn = 1;
else if( isEqual < 0 ) else if( isEqual < 0 )
...@@ -1079,16 +1120,16 @@ int SplitString( wxString strToSplit, ...@@ -1079,16 +1120,16 @@ int SplitString( wxString strToSplit,
wxString* strDigits, wxString* strDigits,
wxString* strEnd ) wxString* strEnd )
{ {
/* Clear all the return strings */ // Clear all the return strings
strBeginning->Clear(); strBeginning->Clear();
strDigits->Clear(); strDigits->Clear();
strEnd->Clear(); strEnd->Clear();
/* There no need to do anything if the string is empty */ // There no need to do anything if the string is empty
if( strToSplit.length() == 0 ) if( strToSplit.length() == 0 )
return 0; return 0;
/* Starting at the end of the string look for the first digit */ // Starting at the end of the string look for the first digit
int ii; int ii;
for( ii = (strToSplit.length() - 1); ii >= 0; ii-- ) for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
{ {
...@@ -1096,15 +1137,15 @@ int SplitString( wxString strToSplit, ...@@ -1096,15 +1137,15 @@ int SplitString( wxString strToSplit,
break; break;
} }
/* If there were no digits then just set the single string */ // If there were no digits then just set the single string
if( ii < 0 ) if( ii < 0 )
*strBeginning = strToSplit; *strBeginning = strToSplit;
else else
{ {
/* Since there is at least one digit this is the trailing string */ // Since there is at least one digit this is the trailing string
*strEnd = strToSplit.substr( ii + 1 ); *strEnd = strToSplit.substr( ii + 1 );
/* Go to the end of the digits */ // Go to the end of the digits
int position = ii + 1; int position = ii + 1;
for( ; ii >= 0; ii-- ) for( ; ii >= 0; ii-- )
{ {
...@@ -1112,7 +1153,7 @@ int SplitString( wxString strToSplit, ...@@ -1112,7 +1153,7 @@ int SplitString( wxString strToSplit,
break; break;
} }
/* If all that was left was digits, then just set the digits string */ // If all that was left was digits, then just set the digits string
if( ii < 0 ) if( ii < 0 )
*strDigits = strToSplit.substr( 0, position ); *strDigits = strToSplit.substr( 0, position );
......
...@@ -477,12 +477,6 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( int aIndex ) ...@@ -477,12 +477,6 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( int aIndex )
} }
/** Function BuildSheetList
* Build the list of sheets and their sheet path from the aSheet sheet
* if aSheet = g_RootSheet, the full sheet path list (and full sheet list) is
* built
* @param aSheet = the starting sheet to build list
*/
void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet ) void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet )
{ {
if( m_List == NULL ) if( m_List == NULL )
......
...@@ -53,18 +53,15 @@ ...@@ -53,18 +53,15 @@
class SCH_MARKER; class SCH_MARKER;
/****************************************/ /**
/* class to handle and access to a sheet */ * Class SCH_SHEET_PATH
/* a 'path' so to speak.. */ * handles access to a sheet by way of a path.
/****************************************/ * <p>
/*
* The member m_sheets stores the list of sheets from the first (usually * The member m_sheets stores the list of sheets from the first (usually
* g_RootSheet) * g_RootSheet) to a given sheet in last position.
* to a given sheet in last position. * The _last_ sheet is usually the sheet we want to select or reach (which is
* The last sheet is usually the sheet we want to select or reach. So Last() * what the function Last() returns).
* return this last sheet * Others sheets constitute the "path" from the first to the last sheet.
* Others sheets are the "path" from the first to the last sheet
*/ */
class SCH_SHEET_PATH class SCH_SHEET_PATH
{ {
...@@ -77,7 +74,7 @@ public: ...@@ -77,7 +74,7 @@ public:
public: public:
SCH_SHEET_PATH(); SCH_SHEET_PATH();
~SCH_SHEET_PATH() { }; // ~SCH_SHEET_PATH() { };
void Clear() void Clear()
{ {
...@@ -137,7 +134,7 @@ public: ...@@ -137,7 +134,7 @@ public:
* Pop is used when leaving a sheet after a selection or analyze * Pop is used when leaving a sheet after a selection or analyze
* This is like cd .. in directories navigation * This is like cd .. in directories navigation
*/ */
SCH_SHEET* Pop(); SCH_SHEET* Pop();
/** Function Path /** Function Path
* the path uses the time stamps which do not changes even when editing * the path uses the time stamps which do not changes even when editing
...@@ -215,15 +212,14 @@ public: ...@@ -215,15 +212,14 @@ public:
}; };
/*******************************************************/ /**
/* Class to handle the list of *Sheets* in a hierarchy */ * Class SCH_SHEET_LIST
/*******************************************************/ * handles the list of Sheets in a hiearchy.
* Sheets are not unique, there can be many sheets with the same
/* sheets are not unique - can have many sheets with the same
* filename and the same SCH_SCREEN reference. * filename and the same SCH_SCREEN reference.
* the schematic (SCH_SCREEN) is shared between these sheets, * The schematic (SCH_SCREEN) is shared between these sheets,
* and component references are specific to a sheet path. * and component references are specific to a sheet path.
* When a sheet is entered, component references and sheet number are updated * When a sheet is entered, component references and sheet number are updated.
*/ */
class SCH_SHEET_LIST class SCH_SHEET_LIST
{ {
...@@ -243,9 +239,12 @@ private: ...@@ -243,9 +239,12 @@ private:
SCH_SHEET_PATH m_currList; SCH_SHEET_PATH m_currList;
public: public:
/* The constructor: build the list of sheets from aSheet.
* If aSheet == NULL (default) build the whole list of sheets in hierarchy /**
* So usually call it with no param. * Constructor
* builds the list of sheets from aSheet.
* If aSheet == NULL (default) build the whole list of sheets in hierarchy.
* So usually call it with no parameter.
*/ */
SCH_SHEET_LIST( SCH_SHEET* aSheet = NULL ); SCH_SHEET_LIST( SCH_SHEET* aSheet = NULL );
...@@ -256,48 +255,54 @@ public: ...@@ -256,48 +255,54 @@ public:
m_List = NULL; m_List = NULL;
} }
/**
/** Function GetCount() * Function GetCount()
* @return the number of sheets in list: * @return the number of sheets in list:
* usually the number of sheets found in the whole hierarchy * usually the number of sheets found in the whole hierarchy
*/ */
int GetCount() { return m_count; } int GetCount() { return m_count; }
/** Function GetFirst /**
* @return the first item (sheet) in m_List and prepare calls to GetNext() * Function GetFirst
* @return the first item (sheet) in m_List and prepare calls to GetNext()
*/ */
SCH_SHEET_PATH* GetFirst(); SCH_SHEET_PATH* GetFirst();
/** Function GetNext /**
* @return the next item (sheet) in m_List or NULL if no more item in * Function GetNext
* @return the next item (sheet) in m_List or NULL if no more item in
* sheet list * sheet list
*/ */
SCH_SHEET_PATH* GetNext(); SCH_SHEET_PATH* GetNext();
/** /**
* Get the last sheet in the sheet list. * Function GetLast
* returns the last sheet in the sheet list.
* *
* @return Last sheet in the list or NULL if sheet list is empty. * @return Last sheet in the list or NULL if sheet list is empty.
*/ */
SCH_SHEET_PATH* GetLast(); SCH_SHEET_PATH* GetLast();
/** /**
* Get the previous sheet in the sheet list. * Function GetPrevious
* returns the previous sheet in the sheet list.
* *
* @return The previous sheet in the sheet list or NULL if already at the * @return The previous sheet in the sheet list or NULL if already at the
* beginning of the list. * beginning of the list.
*/ */
SCH_SHEET_PATH* GetPrevious(); SCH_SHEET_PATH* GetPrevious();
/** Function GetSheet /**
* @return the item (sheet) in aIndex position in m_List or NULL if less * Function GetSheet
* @return the item (sheet) in aIndex position in m_List or NULL if less
* than index items * than index items
* @param aIndex = index in sheet list to get the sheet * @param aIndex = index in sheet list to get the sheet
*/ */
SCH_SHEET_PATH* GetSheet( int aIndex ); SCH_SHEET_PATH* GetSheet( int aIndex );
/** /**
* Search the entire schematic for the next schematic object. * Function FindNextItem
* searches the entire schematic for the next schematic object.
* *
* @param aType - The type of schematic item to find. * @param aType - The type of schematic item to find.
* @param aSheetFound - The sheet the item was found in. NULL if the next item * @param aSheetFound - The sheet the item was found in. NULL if the next item
...@@ -310,7 +315,8 @@ public: ...@@ -310,7 +315,8 @@ public:
SCH_ITEM* aLastItem = NULL, bool aWrap = true ); SCH_ITEM* aLastItem = NULL, bool aWrap = true );
/** /**
* Search the entire schematic for the previous schematic item. * Function FindPreviousItem
* searches the entire schematic for the previous schematic item.
* *
* @param aType - The type of schematic item to find. * @param aType - The type of schematic item to find.
* @param aSheetFound - The sheet the item was found in. NULL if the previous item * @param aSheetFound - The sheet the item was found in. NULL if the previous item
...@@ -323,7 +329,8 @@ public: ...@@ -323,7 +329,8 @@ public:
SCH_ITEM* aLastItem = NULL, bool aWrap = true ); SCH_ITEM* aLastItem = NULL, bool aWrap = true );
/** /**
* Search the entire schematic for the next item that matches the search criteria. * Function MatchNextItem
* searches the entire schematic for the next item that matches the search criteria.
* *
* @param aSearchData - Criteria to search item against. * @param aSearchData - Criteria to search item against.
* @param aSheetFound - The sheet the item was found in. NULL if the next item * @param aSheetFound - The sheet the item was found in. NULL if the next item
...@@ -337,12 +344,15 @@ public: ...@@ -337,12 +344,15 @@ public:
private: private:
/** Function BuildSheetList /**
* Build the list of sheets and their sheet path from the aSheet sheet * Function BuildSheetList
* if aSheet = g_RootSheet, the full sheet path and sheet list is built * builds the list of sheets and their sheet path from \a aSheet.
* @param aSheet = the starting sheet from the built is made * If aSheet = g_RootSheet, the full sheet path and sheet list is built
*
* @param aSheet is the starting sheet from which the list is built,
* or NULL indicating that g_RootSheet should be used.
*/ */
void BuildSheetList( SCH_SHEET* sheet ); void BuildSheetList( SCH_SHEET* sheet );
}; };
#endif /* CLASS_DRAWSHEET_PATH_H */ #endif // CLASS_DRAWSHEET_PATH_H
...@@ -216,18 +216,6 @@ void SCH_FIELD::SwapData( SCH_FIELD* copyitem ) ...@@ -216,18 +216,6 @@ void SCH_FIELD::SwapData( SCH_FIELD* copyitem )
} }
/**
* return True if the field is void, i.e.:
* contains "~" or ""
*/
bool SCH_FIELD::IsVoid()
{
if( m_Text.IsEmpty() || m_Text == wxT( "~" ) )
return true;
return false;
}
/** /**
* Function GetBoundaryBox() * Function GetBoundaryBox()
* @return an EDA_Rect contains the real (user coordinates) boundary box for * @return an EDA_Rect contains the real (user coordinates) boundary box for
......
...@@ -47,11 +47,20 @@ public: ...@@ -47,11 +47,20 @@ public:
return wxT( "SCH_FIELD" ); return wxT( "SCH_FIELD" );
} }
void Place( WinEDA_SchematicFrame* frame, wxDC* DC ); void Place( WinEDA_SchematicFrame* frame, wxDC* DC );
EDA_Rect GetBoundaryBox() const; EDA_Rect GetBoundaryBox() const;
bool IsVoid();
/**
* Function IsVoid
* returns true if the field is either empty or holds "~".
*/
bool IsVoid()
{
size_t len = m_Text.Len();
return len == 0 || ( len == 1 && m_Text[0] == wxChar( '~' ) );
}
void SwapData( SCH_FIELD* copyitem ); void SwapData( SCH_FIELD* copyitem );
/** Function ImportValues /** Function ImportValues
......
...@@ -78,7 +78,7 @@ private: ...@@ -78,7 +78,7 @@ private:
* multi = part selection in multi parts per package (0 or 1 for one part * multi = part selection in multi parts per package (0 or 1 for one part
* per package) * per package)
*/ */
wxArrayString m_PathsAndReferences; wxArrayString m_PathsAndReferences;
void Init( const wxPoint& pos = wxPoint( 0, 0 ) ); void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
......
...@@ -9,12 +9,13 @@ ...@@ -9,12 +9,13 @@
#include "dialog_build_BOM_base.h" #include "dialog_build_BOM_base.h"
class DIALOG_BUILD_BOM : public DIALOG_BUILD_BOM_BASE class DIALOG_BUILD_BOM : public DIALOG_BUILD_BOM_BASE
{ {
private: private:
WinEDA_DrawFrame * m_Parent; WinEDA_DrawFrame * m_Parent;
wxConfig* m_Config; wxConfig* m_Config;
wxString m_ListFileName; wxString m_ListFileName;
private: private:
void OnRadioboxSelectFormatSelected( wxCommandEvent& event ); void OnRadioboxSelectFormatSelected( wxCommandEvent& event );
...@@ -22,30 +23,41 @@ private: ...@@ -22,30 +23,41 @@ private:
void OnCancelClick( wxCommandEvent& event ); void OnCancelClick( wxCommandEvent& event );
void SavePreferences(); void SavePreferences();
void Init( ); void Init();
void Create_BOM_Lists(int aTypeFile, void Create_BOM_Lists(int aTypeFile,
bool aIncludeSubComponents, bool aIncludeSubComponents,
char aExportSeparatorSymbol, char aExportSeparatorSymbol,
bool aRunBrowser); bool aRunBrowser);
void GenereListeOfItems(const wxString & FullFileName, bool aIncludeSubComponents ); void GenereListeOfItems(const wxString & FullFileName, bool aIncludeSubComponents );
void CreateExportList(const wxString & FullFileName, bool aIncludeSubComponents); void CreateExportList(const wxString & FullFileName, bool aIncludeSubComponents);
void CreatePartsList(const wxString & FullFileName, bool aIncludeSubComponents);
/**
* Function CreateParstList
* prints a list of components, in a form which can be imported by a
* spreadsheet. Form is:
* cmp value; number of components; <footprint>; <field1>; ...;
* list of references having the same value
*/
void CreatePartsList( const wxString& aFullFileName, bool aIncludeSubComponents );
int PrintComponentsListByRef( FILE * f, std::vector <OBJ_CMP_TO_LIST>& aList, int PrintComponentsListByRef( FILE * f, std::vector <OBJ_CMP_TO_LIST>& aList,
bool CompactForm, bool aIncludeSubComponents ); bool CompactForm, bool aIncludeSubComponents );
int PrintComponentsListByVal( FILE *f, std::vector <OBJ_CMP_TO_LIST>& aList, int PrintComponentsListByVal( FILE *f, std::vector <OBJ_CMP_TO_LIST>& aList,
bool aIncludeSubComponents); bool aIncludeSubComponents);
int PrintComponentsListByPart( FILE *f, std::vector <OBJ_CMP_TO_LIST>& aList, int PrintComponentsListByPart( FILE *f, std::vector <OBJ_CMP_TO_LIST>& aList,
bool aIncludeSubComponents); bool aIncludeSubComponents);
void PrintFieldData(FILE * f, SCH_COMPONENT * DrawLibItem, bool CompactForm = FALSE); void PrintFieldData(FILE * f, SCH_COMPONENT * DrawLibItem, bool CompactForm = FALSE);
bool IsFieldChecked(int aFieldId);
bool IsFieldChecked(int aFieldId);
public: public:
DIALOG_BUILD_BOM( WinEDA_DrawFrame* parent ); DIALOG_BUILD_BOM( WinEDA_DrawFrame* parent );
~DIALOG_BUILD_BOM() {}; // ~DIALOG_BUILD_BOM() {};
}; };
#endif // _DIALOG_BUILD_BOM_H_
#endif
// _DIALOG_BUILD_BOM_H_
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
/*****************************/ /*****************************/
#include "fctsys.h" #include "fctsys.h"
#include <wx/xml/xml.h>
#include "gr_basic.h" #include "gr_basic.h"
#include "common.h" #include "common.h"
#include "confirm.h" #include "confirm.h"
...@@ -25,37 +28,77 @@ ...@@ -25,37 +28,77 @@
* returns a value less than 0 when it does. * returns a value less than 0 when it does.
*/ */
static void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, static bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName );
const wxString& FullFileName );
static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f,
bool with_pcbnew ); bool with_pcbnew );
static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f ); static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f );
static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ); static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f,
bool use_netnames ); bool use_netnames );
static void WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ); static bool WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
static void AddPinToComponentPinList( SCH_COMPONENT* Component, static void AddPinToComponentPinList( SCH_COMPONENT* Component,
SCH_SHEET_PATH* sheet, SCH_SHEET_PATH* sheet,
LIB_PIN* PinEntry ); LIB_PIN* PinEntry );
static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component, static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component,
LIB_COMPONENT* Entry, LIB_COMPONENT* aEntry,
SCH_SHEET_PATH* Sheet_in ); SCH_SHEET_PATH* Sheet_in );
static bool SortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 ); static bool SortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 );
static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList ); static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList );
static void ClearUsedFlags( void );
static NETLIST_OBJECT_LIST s_SortedComponentPinList; static NETLIST_OBJECT_LIST s_SortedComponentPinList;
// list of references already found for multi part per packages components
// (used to avoid to used more than one time a component) #include <set>
static wxArrayString s_ReferencesAlreadyFound;
/**
* Class UNIQUE_STRINGS
* will keep track of unique wxStrings and is useful in telling if a string
* has been seen before.
*/
class UNIQUE_STRINGS
{
private:
std::set<wxString> m_set; ///< set of wxStrings already found
public:
/**
* Function Clear
* erases the record.
*/
void Clear() { m_set.clear(); }
/**
* Function Lookup
* returns true if \a aString already exists in the set, otherwise returns
* false and adds \a aString to the set for next time.
*/
bool Lookup( const wxString& aString );
};
bool UNIQUE_STRINGS::Lookup( const wxString& aString )
{
bool ret = ( m_set.find( aString ) != m_set.end() );
if( !ret )
m_set.insert( aString );
return ret;
}
/// Used for multi part per package components, avoids using a component more than once.
static UNIQUE_STRINGS s_ReferencesAlreadyFound;
/** function WriteNetListFile /**
* Create the netlist file. Netlist info must be existing * Function WriteNetListFile
* creates the netlist file. Netlist info must be existing
* @param aFormat = netlist format (NET_TYPE_PCBNEW ...) * @param aFormat = netlist format (NET_TYPE_PCBNEW ...)
* @param aFullFileName = full netlist file name * @param aFullFileName = full netlist file name
* @param aUse_netnames = bool. if true, use net names from labels in schematic * @param aUse_netnames = bool. if true, use net names from labels in schematic
...@@ -66,7 +109,8 @@ static wxArrayString s_ReferencesAlreadyFound; ...@@ -66,7 +109,8 @@ static wxArrayString s_ReferencesAlreadyFound;
bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFullFileName, bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFullFileName,
bool aUse_netnames ) bool aUse_netnames )
{ {
FILE* f = NULL; bool ret = true;
FILE* f = NULL;
if( aFormat < NET_TYPE_CUSTOM1 ) if( aFormat < NET_TYPE_CUSTOM1 )
{ {
...@@ -83,12 +127,12 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull ...@@ -83,12 +127,12 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull
switch( aFormat ) switch( aFormat )
{ {
case NET_TYPE_PCBNEW: case NET_TYPE_PCBNEW:
WriteNetListPCBNEW( this, f, TRUE ); ret = WriteNetListPCBNEW( this, f, TRUE );
fclose( f ); fclose( f );
break; break;
case NET_TYPE_ORCADPCB2: case NET_TYPE_ORCADPCB2:
WriteNetListPCBNEW( this, f, FALSE ); ret = WriteNetListPCBNEW( this, f, FALSE );
fclose( f ); fclose( f );
break; break;
...@@ -103,11 +147,39 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull ...@@ -103,11 +147,39 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull
break; break;
default: default:
Write_GENERIC_NetList( this, aFullFileName ); {
wxFileName tmpFile = aFullFileName;
tmpFile.SetExt( wxT( "tmp" ) );
ret = Write_GENERIC_NetList( this, tmpFile.GetFullPath() );
if( !ret )
break;
// Call the external module (plug in )
if( g_NetListerCommandLine.IsEmpty() )
break;
wxString commandLine;
if( wxIsAbsolutePath( g_NetListerCommandLine ) )
commandLine = g_NetListerCommandLine;
else
commandLine = FindKicadFile( g_NetListerCommandLine );
// this is the input file to the plugin
commandLine += wxT( " " ) + tmpFile.GetFullPath();
// this is the output file to the plugin
commandLine += wxT( " " ) + aFullFileName;
ProcessExecute( commandLine, wxEXEC_SYNC );
// ::wxRemoveFile( tmpFile.GetFullPath() );
}
break; break;
} }
return true; return ret;
} }
...@@ -118,87 +190,70 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull ...@@ -118,87 +190,70 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull
* considered) * considered)
* Must be deallocated by the user * Must be deallocated by the user
*/ */
static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* DrawList, static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item,
SCH_SHEET_PATH* sheet ) SCH_SHEET_PATH* path )
{ {
SCH_COMPONENT* Component = NULL;
LIB_COMPONENT* Entry;
LIB_PIN* Pin;
s_SortedComponentPinList.clear(); s_SortedComponentPinList.clear();
for( ; DrawList != NULL; DrawList = DrawList->Next() )
// continue searching from the middle of a linked list
for( ; item; item = item->Next() )
{ {
if( DrawList->Type() != TYPE_SCH_COMPONENT ) if( item->Type() != TYPE_SCH_COMPONENT )
continue; continue;
Component = (SCH_COMPONENT*) DrawList;
/* Power symbol and other component which have the reference starting // found next component
* by "#" are not included in netlist (pseudo or virtual components) */ SCH_COMPONENT* comp = (SCH_COMPONENT*) item;
wxString str = Component->GetRef( sheet );
if( str[0] == '#' ) // ignore it // Power symbols and other components which have the reference starting
// with "#" are not included in netlist (pseudo or virtual components)
wxString ref = comp->GetRef( path );
if( ref[0] == wxChar( '#' ) ) // ignore it
continue; continue;
//if( Component->m_FlagControlMulti == 1 ) // if( Component->m_FlagControlMulti == 1 )
// continue; /* yes */ // continue; /* yes */
// removed because with multiple instances of one schematic // removed because with multiple instances of one schematic
// (several sheets pointing to 1 screen), this will be erroneously be // (several sheets pointing to 1 screen), this will be erroneously be
// toggled. // toggled.
Entry = CMP_LIBRARY::FindLibraryComponent( Component->m_ChipName ); LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( comp->m_ChipName );
if( !entry )
if( Entry == NULL )
continue; continue;
// Multi parts per package: test if already visited: // Multi parts per package: test if already visited:
if( Entry->GetPartCount() > 1 ) if( entry->GetPartCount() > 1 )
{ {
bool found = false; if( s_ReferencesAlreadyFound.Lookup( ref ) )
for( unsigned jj = 0;
jj < s_ReferencesAlreadyFound.GetCount();
jj++ )
{
if( str == s_ReferencesAlreadyFound[jj] ) // Already visited
{
found = true;
break;
}
}
if( found )
continue; continue;
else
{
s_ReferencesAlreadyFound.Add( str ); // Mark as visited
}
} }
if( Entry->GetPartCount() <= 1 ) // One part per package if( entry->GetPartCount() <= 1 ) // One part per package
{ {
LIB_PIN_LIST pins; LIB_PIN_LIST pins;
Entry->GetPins( pins, Component->GetUnitSelection( sheet ), Component->m_Convert ); entry->GetPins( pins, comp->GetUnitSelection( path ), comp->m_Convert );
for( size_t i = 0; i < pins.size(); i++ ) for( size_t i = 0; i < pins.size(); i++ )
{ {
Pin = pins[i]; LIB_PIN* pin = pins[i];
wxASSERT( Pin->Type() == COMPONENT_PIN_DRAW_TYPE ); wxASSERT( pin->Type() == COMPONENT_PIN_DRAW_TYPE );
AddPinToComponentPinList( Component, sheet, Pin ); AddPinToComponentPinList( comp, path, pin );
} }
} }
else // Multiple parts per package: Collect all parts ans pins for else // Multiple parts per package: Collect all parts and pins for
// this reference // this reference
FindAllsInstancesOfComponent( Component, Entry, sheet ); FindAllsInstancesOfComponent( comp, entry, path );
/* Sort Pins in s_SortedComponentPinList by pin number */ // Sort pins in s_SortedComponentPinList by pin number
sort( s_SortedComponentPinList.begin(), sort( s_SortedComponentPinList.begin(),
s_SortedComponentPinList.end(), SortPinsByNum ); s_SortedComponentPinList.end(), SortPinsByNum );
/* Remove duplicate Pins in s_SortedComponentPinList */ // Remove duplicate Pins in s_SortedComponentPinList
EraseDuplicatePins( s_SortedComponentPinList ); EraseDuplicatePins( s_SortedComponentPinList );
return Component; return comp;
} }
return NULL; return NULL;
...@@ -247,115 +302,205 @@ static wxString ReturnPinNetName( NETLIST_OBJECT* Pin, const wxString& DefaultFo ...@@ -247,115 +302,205 @@ static wxString ReturnPinNetName( NETLIST_OBJECT* Pin, const wxString& DefaultFo
} }
static wxXmlNode* Node( const wxString& name, const wxString& content=wxEmptyString )
{
wxXmlNode* n = new wxXmlNode( 0, wxXML_ELEMENT_NODE, name );
if( content.Len() > 0 ) // excludes wxEmptyString
n->AddChild( new wxXmlNode( 0, wxXML_TEXT_NODE, wxEmptyString, content ) );
return n;
}
/* Create a generic netlist, and call an external netlister /* Create a generic netlist, and call an external netlister
* to change the netlist syntax and create the file * to change the netlist syntax and create the file
*/ */
void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& FullFileName ) bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName )
{ {
wxString Line, FootprintName; #if 1
SCH_SHEET_PATH* sheet; // output the XML format netlist.
EDA_BaseStruct* SchItem; wxXmlDocument xdoc;
SCH_COMPONENT* Component; // tree markers or walkers
wxString netname; wxXmlNode* xroot; // root node
FILE* tmpfile; wxXmlNode* xcomps; // start of components
wxFileName fn = FullFileName;
wxString timeStamp;
// some strings we need many times, but don't want to construct more
// than once for performance. These are used within loops so the
// enclosing wxString constructor would fire on each usage.
const wxString sFields = wxT("fields");
const wxString sField = wxT("field");
const wxString sComponent = wxT("comp"); // use "part" ?
const wxString sName = wxT("name");
const wxString sRef = wxT("ref");
const wxString sPins = wxT("pins");
const wxString sPin = wxT("pin");
const wxString sValue = wxT("value");
const wxString sFootprint = wxT("footprint");
const wxString sDatasheet = wxT("datasheet");
const wxString sTStamp = wxT("tstamp");
const wxString sTSFmt = wxT("%8.8lX"); // comp->m_TimeStamp
s_ReferencesAlreadyFound.Clear();
xdoc.SetRoot( xroot = Node( wxT("netlist") ) );
xroot->AddProperty( wxT("version"), wxT("B") );
xroot->AddChild( xcomps = Node( wxT("components") ) );
SCH_SHEET_LIST sheetList;
// output is xml, so there is no reason to remove spaces from the field values.
for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext() )
{
for( EDA_BaseStruct* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
{
SCH_COMPONENT* comp = FindNextComponentAndCreatPinList( schItem, path );
if( !comp )
break; // No component left
schItem = comp;
// current component being constructed
wxXmlNode* xcomp = Node( sComponent );
xcomps->AddChild( xcomp );
xcomp->AddProperty( sRef, comp->GetRef( path ) );
xcomp->AddChild( Node( sValue, comp->GetField( VALUE )->m_Text ) );
timeStamp.Printf( sTSFmt, comp->m_TimeStamp );
xcomp->AddChild( Node( sTStamp, timeStamp ) );
if( !comp->GetField( FOOTPRINT )->m_Text.IsEmpty() )
xcomp->AddChild( Node( sFootprint, comp->GetField( FOOTPRINT )->m_Text ) );
if( !comp->GetField( DATASHEET )->m_Text.IsEmpty() )
xcomp->AddChild( Node( sDatasheet, comp->GetField( DATASHEET )->m_Text ) );
// all fields within the component, starting with the MANDATORY_FIELDS
if( comp->GetFieldCount() > MANDATORY_FIELDS )
{
wxXmlNode* xfields = Node( sFields );
xcomp->AddChild( xfields );
for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp->GetFieldCount(); ++fldNdx )
{
SCH_FIELD* f = comp->GetField( fldNdx );
wxXmlNode* xfield = Node( sField, f->m_Text );
xfield->AddProperty( sName, f->m_Name );
xfields->AddChild( xfield );
}
}
// @todo add: libsource + sheetpath
}
}
// @todo generate the nested <libpart> s
xroot->AddChild( Node( wxT("libparts") ) );
fn.SetExt( wxT( "tmp" ) ); // @todo generate the nested <net>s
xroot->AddChild( Node( wxT("nets") ) );
if( ( tmpfile = wxFopen( fn.GetFullPath(), wxT( "wt" ) ) ) == NULL ) return xdoc.Save( aOutFileName, 2 /* indent bug, today was ignored by wxXml lib */ );
#else
// ouput the well established/old net list format
wxString field;
wxString footprint;
wxString netname;
FILE* out;
int ret = 0; // OR on each call, test sign bit at very end.
if( ( out = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL )
{ {
wxString msg = _( "Failed to create file " ) + fn.GetFullPath(); wxString msg = _( "Failed to create file " ) + aOutFileName;
DisplayError( frame, msg ); DisplayError( frame, msg );
return; return false;
} }
ClearUsedFlags(); /* Reset the flags FlagControlMulti in all schematic s_ReferencesAlreadyFound.Clear();
* files*/
fprintf( tmpfile, "$BeginNetlist\n" );
/* Create netlist module section */ ret |= fprintf( out, "$BeginNetlist\n" );
fprintf( tmpfile, "$BeginComponentList\n" );
SCH_SHEET_LIST SheetList;
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) // Create netlist module section
ret |= fprintf( out, "$BeginComponentList\n" );
SCH_SHEET_LIST sheetList;
for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext() )
{ {
for( SchItem = sheet->LastDrawList(); SchItem != NULL; SchItem = SchItem->Next() ) for( EDA_BaseStruct* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
{ {
SchItem = Component = FindNextComponentAndCreatPinList( SchItem, sheet ); SCH_COMPONENT* comp = FindNextComponentAndCreatPinList( schItem, path );
if( !comp )
if( Component == NULL )
break; // No component left break; // No component left
FootprintName.Empty(); schItem = comp;
if( !Component->GetField( FOOTPRINT )->IsVoid() )
footprint.Empty();
if( !comp->GetField( FOOTPRINT )->IsVoid() )
{ {
FootprintName = Component->GetField( FOOTPRINT )->m_Text; footprint = comp->GetField( FOOTPRINT )->m_Text;
FootprintName.Replace( wxT( " " ), wxT( "_" ) ); footprint.Replace( wxT( " " ), wxT( "_" ) );
} }
fprintf( tmpfile, "\n$BeginComponent\n" ); ret |= fprintf( out, "\n$BeginComponent\n" );
fprintf( tmpfile, "TimeStamp=%8.8lX\n", Component->m_TimeStamp ); ret |= fprintf( out, "TimeStamp=%8.8lX\n", comp->m_TimeStamp );
fprintf( tmpfile, "Footprint=%s\n", CONV_TO_UTF8( FootprintName ) ); ret |= fprintf( out, "Footprint=%s\n", CONV_TO_UTF8( footprint ) );
Line = wxT( "Reference=" ) + Component->GetRef( sheet ) + wxT( "\n" );
Line.Replace( wxT( " " ), wxT( "_" ) );
fputs( CONV_TO_UTF8( Line ), tmpfile );
Line = Component->GetField( VALUE )->m_Text; field = wxT( "Reference=" ) + comp->GetRef( path ) + wxT( "\n" );
Line.Replace( wxT( " " ), wxT( "_" ) ); field.Replace( wxT( " " ), wxT( "_" ) );
fprintf( tmpfile, "Value=%s\n", CONV_TO_UTF8( Line ) ); ret |= fputs( CONV_TO_UTF8( field ), out );
Line = Component->m_ChipName; field = comp->GetField( VALUE )->m_Text;
Line.Replace( wxT( " " ), wxT( "_" ) ); field.Replace( wxT( " " ), wxT( "_" ) );
fprintf( tmpfile, "Libref=%s\n", CONV_TO_UTF8( Line ) ); ret |= fprintf( out, "Value=%s\n", CONV_TO_UTF8( field ) );
field = comp->m_ChipName;
field.Replace( wxT( " " ), wxT( "_" ) );
ret |= fprintf( out, "Libref=%s\n", CONV_TO_UTF8( field ) );
// Write pin list: // Write pin list:
fprintf( tmpfile, "$BeginPinList\n" ); ret |= fprintf( out, "$BeginPinList\n" );
for( unsigned ii = 0; ii < s_SortedComponentPinList.size(); ii++ ) for( unsigned ii = 0; ii < s_SortedComponentPinList.size(); ii++ )
{ {
NETLIST_OBJECT* Pin = s_SortedComponentPinList[ii]; NETLIST_OBJECT* Pin = s_SortedComponentPinList[ii];
if( !Pin ) if( !Pin )
continue; continue;
netname = ReturnPinNetName( Pin, wxT( "$-%.6d" ) ); netname = ReturnPinNetName( Pin, wxT( "$-%.6d" ) );
if( netname.IsEmpty() ) if( netname.IsEmpty() )
netname = wxT( "?" ); netname = wxT( "?" );
fprintf( tmpfile, "%.4s=%s\n", (char*) &Pin->m_PinNum, CONV_TO_UTF8( netname ) );
ret |= fprintf( out, "%.4s=%s\n", (char*) &Pin->m_PinNum, CONV_TO_UTF8( netname ) );
} }
fprintf( tmpfile, "$EndPinList\n" ); ret |= fprintf( out, "$EndPinList\n" );
fprintf( tmpfile, "$EndComponent\n" ); ret |= fprintf( out, "$EndComponent\n" );
} }
} }
fprintf( tmpfile, "$EndComponentList\n" ); ret |= fprintf( out, "$EndComponentList\n" );
fprintf( tmpfile, "\n$BeginNets\n" ); ret |= fprintf( out, "\n$BeginNets\n" );
WriteGENERICListOfNets( tmpfile, g_NetObjectslist );
fprintf( tmpfile, "$EndNets\n" );
fprintf( tmpfile, "\n$EndNetlist\n" );
fclose( tmpfile );
// Call the external module (plug in ) if( !WriteGENERICListOfNets( out, g_NetObjectslist ) )
ret = -1;
if( g_NetListerCommandLine.IsEmpty() ) ret |= fprintf( out, "$EndNets\n" );
return;
wxString CommandFile;
if( wxIsAbsolutePath( g_NetListerCommandLine ) )
CommandFile = g_NetListerCommandLine;
else
CommandFile = FindKicadFile( g_NetListerCommandLine );
CommandFile += wxT( " " ) + fn.GetFullPath(); ret |= fprintf( out, "\n$EndNetlist\n" );
CommandFile += wxT( " " ) + FullFileName; ret |= fclose( out );
ProcessExecute( CommandFile, wxEXEC_SYNC ); return ret >= 0;
} #endif
/* Clear flag list, used in netlist generation */
static void ClearUsedFlags( void )
{
s_ReferencesAlreadyFound.Clear();
} }
...@@ -454,10 +599,10 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_ ...@@ -454,10 +599,10 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
} }
fprintf( f, "\n" ); fprintf( f, "\n" );
// Create component list
s_ReferencesAlreadyFound.Clear();
/* Create component list */
ClearUsedFlags(); /* Reset the flags FlagControlMulti in all schematic
* files*/
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{ {
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() ) for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() )
...@@ -522,159 +667,150 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_ ...@@ -522,159 +667,150 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
* = FALSE if with_pcbnew * = FALSE if with_pcbnew
* Format ORCADPCB2 strict * Format ORCADPCB2 strict
*/ */
static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with_pcbnew ) static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with_pcbnew )
{ {
wxString Line, FootprintName; wxString Line;
char Buf[256]; wxString footprint;
SCH_SHEET_PATH* sheet; char dateBuf[256];
EDA_BaseStruct* DrawList; int ret = 0; // zero now, OR in the sign bit on error
SCH_COMPONENT* Component;
OBJ_CMP_TO_LIST* CmpList = NULL; std::vector<OBJ_CMP_TO_LIST> cmpList;
int CmpListCount = 0, CmpListSize = 1000;
DateAndTime( dateBuf );
DateAndTime( Buf );
if( with_pcbnew ) if( with_pcbnew )
fprintf( f, "# %s created %s\n(\n", NETLIST_HEAD_STRING, Buf ); ret |= fprintf( f, "# %s created %s\n(\n", NETLIST_HEAD_STRING, dateBuf );
else else
fprintf( f, "( { %s created %s }\n", NETLIST_HEAD_STRING, Buf ); ret |= fprintf( f, "( { %s created %s }\n", NETLIST_HEAD_STRING, dateBuf );
// Create netlist module section
/* Create netlist module section */ s_ReferencesAlreadyFound.Clear();
ClearUsedFlags(); /* Reset the flags FlagControlMulti in all schematic
* files*/
SCH_SHEET_LIST SheetList; SCH_SHEET_LIST sheetList;
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext() )
{ {
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() ) for( EDA_BaseStruct* item = path->LastDrawList(); item; item = item->Next() )
{ {
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet ); SCH_COMPONENT* comp = FindNextComponentAndCreatPinList( item, path );
if( Component == NULL ) if( !comp )
break; break;
/* Get the Component FootprintFilter and put the component in item = comp;
* CmpList if filter is not void */
LIB_COMPONENT* Entry = // Get the Component FootprintFilter and put the component in
CMP_LIBRARY::FindLibraryComponent( Component->m_ChipName ); // cmpList if filter is present
LIB_COMPONENT* entry =
CMP_LIBRARY::FindLibraryComponent( comp->m_ChipName );
if( Entry != NULL ) if( entry )
{ {
if( Entry->m_FootprintList.GetCount() != 0 ) /* Put in list */ if( entry->m_FootprintList.GetCount() != 0 ) // Put in list
{ {
if( CmpList == NULL ) cmpList.push_back( OBJ_CMP_TO_LIST() );
{
CmpList = (OBJ_CMP_TO_LIST*) cmpList.back().m_RootCmp = comp;
MyZMalloc( sizeof(OBJ_CMP_TO_LIST) * CmpListSize ); cmpList.back().SetRef( comp->GetRef( path ) );
}
if( CmpListCount >= CmpListSize )
{
CmpListSize += 1000;
CmpList =
(OBJ_CMP_TO_LIST*) realloc( CmpList,
sizeof(OBJ_CMP_TO_LIST)
* CmpListSize );
}
CmpList[CmpListCount].m_RootCmp = Component;
strcpy( CmpList[CmpListCount].m_Reference,
Component->GetRef( sheet ).mb_str() );
CmpListCount++;
} }
} }
if( !Component->GetField( FOOTPRINT )->IsVoid() ) if( !comp->GetField( FOOTPRINT )->IsVoid() )
{ {
FootprintName = Component->GetField( FOOTPRINT )->m_Text; footprint = comp->GetField( FOOTPRINT )->m_Text;
FootprintName.Replace( wxT( " " ), wxT( "_" ) ); footprint.Replace( wxT( " " ), wxT( "_" ) );
} }
else else
FootprintName = wxT( "$noname" ); footprint = wxT( "$noname" );
Line = Component->GetRef( sheet ); Line = comp->GetRef( path );
fprintf( f, " ( %s %s",
CONV_TO_UTF8( Component->GetPath( sheet ) ),
CONV_TO_UTF8( FootprintName ) );
fprintf( f, " %s", CONV_TO_UTF8( Line ) );
Line = Component->GetField( VALUE )->m_Text; ret |= fprintf( f, " ( %s %s",
CONV_TO_UTF8( comp->GetPath( path ) ),
CONV_TO_UTF8( footprint ) );
ret |= fprintf( f, " %s", CONV_TO_UTF8( Line ) );
Line = comp->GetField( VALUE )->m_Text;
Line.Replace( wxT( " " ), wxT( "_" ) ); Line.Replace( wxT( " " ), wxT( "_" ) );
fprintf( f, " %s", CONV_TO_UTF8( Line ) ); ret |= fprintf( f, " %s", CONV_TO_UTF8( Line ) );
if( with_pcbnew ) // Add the lib name for this component if( with_pcbnew ) // Add the lib name for this component
{ {
Line = Component->m_ChipName; Line = comp->m_ChipName;
Line.Replace( wxT( " " ), wxT( "_" ) ); Line.Replace( wxT( " " ), wxT( "_" ) );
fprintf( f, " {Lib=%s}", CONV_TO_UTF8( Line ) ); ret |= fprintf( f, " {Lib=%s}", CONV_TO_UTF8( Line ) );
} }
fprintf( f, "\n" ); ret |= fprintf( f, "\n" );
// Write pin list: // Write pin list:
for( unsigned ii = 0; ii < s_SortedComponentPinList.size(); ii++ ) for( unsigned ii = 0; ii < s_SortedComponentPinList.size(); ii++ )
{ {
NETLIST_OBJECT* Pin = s_SortedComponentPinList[ii]; NETLIST_OBJECT* pin = s_SortedComponentPinList[ii];
if( !Pin ) if( !pin )
continue; continue;
wxString netname = ReturnPinNetName( Pin, wxT( "N-%.6d" ) );
wxString netname = ReturnPinNetName( pin, wxT( "N-%.6d" ) );
if( netname.IsEmpty() ) if( netname.IsEmpty() )
netname = wxT( "?" ); netname = wxT( "?" );
netname.Replace( wxT( " " ), wxT( "_" ) ); netname.Replace( wxT( " " ), wxT( "_" ) );
fprintf( f, " ( %4.4s %s )\n", (char*) &Pin->m_PinNum, ret |= fprintf( f, " ( %4.4s %s )\n", (char*) &pin->m_PinNum,
CONV_TO_UTF8( netname ) ); CONV_TO_UTF8( netname ) );
} }
fprintf( f, " )\n" ); ret |= fprintf( f, " )\n" );
} }
} }
fprintf( f, ")\n*\n" ); ret |= fprintf( f, ")\n*\n" );
s_SortedComponentPinList.clear(); s_SortedComponentPinList.clear();
/* Write the allowed footprint list for each component */ // Write the allowed footprint list for each component
if( with_pcbnew && CmpList ) if( with_pcbnew && cmpList.size() )
{ {
fprintf( f, "{ Allowed footprints by component:\n" ); wxString ref;
LIB_COMPONENT* Entry;
for( int ii = 0; ii < CmpListCount; ii++ ) ret |= fprintf( f, "{ Allowed footprints by component:\n" );
for( unsigned ii = 0; ii < cmpList.size(); ii++ )
{ {
Component = CmpList[ii].m_RootCmp; SCH_COMPONENT* comp = cmpList[ii].m_RootCmp;
Entry = CMP_LIBRARY::FindLibraryComponent( Component->m_ChipName );
//Line.Printf(_("%s"), CmpList[ii].m_Ref);
//Line.Replace( wxT( " " ), wxT( "_" ) );
for( unsigned nn = 0;
nn<sizeof(CmpList[ii].m_Reference)
&& CmpList[ii].m_Reference[nn];
nn++ )
{
if( CmpList[ii].m_Reference[nn] == ' ' )
CmpList[ii].m_Reference[nn] = '_';
}
fprintf( f, "$component %s\n", CmpList[ii].m_Reference ); LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( comp->m_ChipName );
/* Write the footprint list */
for( unsigned jj = 0; jj < Entry->m_FootprintList.GetCount(); jj++ ) ref = cmpList[ii].GetRef();
ref.Replace( wxT( " " ), wxT( "_" ) );
ret |= fprintf( f, "$component %s\n", CONV_TO_UTF8( ref ) );
// Write the footprint list
for( unsigned jj = 0; jj < entry->m_FootprintList.GetCount(); jj++ )
{ {
fprintf( f, " %s\n", ret |= fprintf( f, " %s\n",
CONV_TO_UTF8( Entry->m_FootprintList[jj] ) ); CONV_TO_UTF8( entry->m_FootprintList[jj] ) );
} }
fprintf( f, "$endlist\n" ); ret |= fprintf( f, "$endlist\n" );
} }
fprintf( f, "$endfootprintlist\n}\n" ); ret |= fprintf( f, "$endfootprintlist\n}\n" );
} }
if( CmpList )
free( CmpList );
if( with_pcbnew ) if( with_pcbnew )
{ {
fprintf( f, "{ Pin List by Nets\n" ); ret |= fprintf( f, "{ Pin List by Nets\n" );
WriteGENERICListOfNets( f, g_NetObjectslist );
fprintf( f, "}\n" ); if( !WriteGENERICListOfNets( f, g_NetObjectslist ) )
fprintf( f, "#End\n" ); ret = -1;
ret |= fprintf( f, "}\n" );
ret |= fprintf( f, "#End\n" );
} }
return ret >= 0;
} }
...@@ -686,7 +822,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -686,7 +822,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
static void AddPinToComponentPinList( SCH_COMPONENT* Component, static void AddPinToComponentPinList( SCH_COMPONENT* Component,
SCH_SHEET_PATH* sheetlist, LIB_PIN* Pin ) SCH_SHEET_PATH* sheetlist, LIB_PIN* Pin )
{ {
/* Search the PIN description for Pin in g_NetObjectslist*/ // Search the PIN description for Pin in g_NetObjectslist
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ ) for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
{ {
if( g_NetObjectslist[ii]->m_Type != NET_PIN ) if( g_NetObjectslist[ii]->m_Type != NET_PIN )
...@@ -699,9 +835,10 @@ static void AddPinToComponentPinList( SCH_COMPONENT* Component, ...@@ -699,9 +835,10 @@ static void AddPinToComponentPinList( SCH_COMPONENT* Component,
continue; continue;
s_SortedComponentPinList.push_back( g_NetObjectslist[ii] ); s_SortedComponentPinList.push_back( g_NetObjectslist[ii] );
if( s_SortedComponentPinList.size() >= MAXPIN ) if( s_SortedComponentPinList.size() >= MAXPIN )
{ {
/* Log message for Internal error */ // Log message for Internal error
DisplayError( NULL, wxT( "AddPinToComponentPinList err: MAXPIN reached" ) ); DisplayError( NULL, wxT( "AddPinToComponentPinList err: MAXPIN reached" ) );
return; return;
} }
...@@ -777,7 +914,7 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList ) ...@@ -777,7 +914,7 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
* component pin list * component pin list
*/ */
static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component_in, static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component_in,
LIB_COMPONENT* Entry, LIB_COMPONENT* aEntry,
SCH_SHEET_PATH* Sheet_in ) SCH_SHEET_PATH* Sheet_in )
{ {
EDA_BaseStruct* SchItem; EDA_BaseStruct* SchItem;
...@@ -801,10 +938,10 @@ static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component_in, ...@@ -801,10 +938,10 @@ static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component_in,
if( str.CmpNoCase( Reference ) != 0 ) if( str.CmpNoCase( Reference ) != 0 )
continue; continue;
if( Entry == NULL ) if( aEntry == NULL )
continue; continue;
for( pin = Entry->GetNextPin(); pin != NULL; pin = Entry->GetNextPin( pin ) ) for( pin = aEntry->GetNextPin(); pin != NULL; pin = aEntry->GetNextPin( pin ) )
{ {
wxASSERT( pin->Type() == COMPONENT_PIN_DRAW_TYPE ); wxASSERT( pin->Type() == COMPONENT_PIN_DRAW_TYPE );
...@@ -844,81 +981,89 @@ static bool SortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 ) ...@@ -844,81 +981,89 @@ static bool SortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 )
/* Written in the file / net list (ranked by Netcode), and elements that are /* Written in the file / net list (ranked by Netcode), and elements that are
* connected * connected
*/ */
static void WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) static bool WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
{ {
int NetCode, LastNetCode = -1; int ret = 0;
int SameNetcodeCount = 0; int netCode;
SCH_COMPONENT* Cmp; int lastNetCode = -1;
wxString NetName, CmpRef; int sameNetcodeCount = 0;
wxString NetcodeName; wxString netName;
char FirstItemInNet[1024]; wxString ref;
wxString netcodeName;
char firstItemInNet[256];
for( unsigned ii = 0; ii < aObjectsList.size(); ii++ ) for( unsigned ii = 0; ii < aObjectsList.size(); ii++ )
{ {
SCH_COMPONENT* comp;
// New net found, write net id; // New net found, write net id;
if( ( NetCode = aObjectsList[ii]->GetNet() ) != LastNetCode ) if( ( netCode = aObjectsList[ii]->GetNet() ) != lastNetCode )
{ {
SameNetcodeCount = 0; // Items count for this net sameNetcodeCount = 0; // Items count for this net
NetName.Empty(); netName.Empty();
// Find a label (if exists) for this net. // Find a label (if exists) for this net.
NETLIST_OBJECT* netref; NETLIST_OBJECT* netref;
netref = aObjectsList[ii]->m_NetNameCandidate; netref = aObjectsList[ii]->m_NetNameCandidate;
if( netref ) if( netref )
NetName = netref->m_Label; netName = netref->m_Label;
NetcodeName.Printf( wxT( "Net %d " ), NetCode ); netcodeName.Printf( wxT( "Net %d " ), netCode );
NetcodeName += wxT( "\"" ); netcodeName += wxT( "\"" );
if( !NetName.IsEmpty() ) if( !netName.IsEmpty() )
{ {
if( ( netref->m_Type != NET_PINLABEL ) if( ( netref->m_Type != NET_PINLABEL )
&& ( netref->m_Type != NET_GLOBLABEL ) ) && ( netref->m_Type != NET_GLOBLABEL ) )
{ {
// usual net name, prefix it by the sheet path // usual net name, prefix it by the sheet path
NetcodeName += netref->m_SheetList.PathHumanReadable(); netcodeName += netref->m_SheetList.PathHumanReadable();
} }
NetcodeName += NetName; netcodeName += netName;
} }
NetcodeName += wxT( "\"" ); netcodeName += wxT( "\"" );
// Add the netname without prefix, in cases we need only the // Add the netname without prefix, in cases we need only the
// "short" netname // "short" netname
NetcodeName += wxT( " \"" ) + NetName + wxT( "\"" ); netcodeName += wxT( " \"" ) + netName + wxT( "\"" );
LastNetCode = NetCode; lastNetCode = netCode;
} }
if( aObjectsList[ii]->m_Type != NET_PIN ) if( aObjectsList[ii]->m_Type != NET_PIN )
continue; continue;
Cmp = (SCH_COMPONENT*) aObjectsList[ii]->m_Link; comp = (SCH_COMPONENT*) aObjectsList[ii]->m_Link;
// Get the reference for the net name and the main parent component // Get the reference for the net name and the main parent component
CmpRef = Cmp->GetRef( &aObjectsList[ii]->m_SheetList ); ref = comp->GetRef( &aObjectsList[ii]->m_SheetList );
if( CmpRef.StartsWith( wxT( "#" ) ) ) if( ref[0] == wxChar( '#' ) )
continue; // Pseudo component (Like Power symbol) continue; // Pseudo component (Like Power symbol)
// Print the pin list for this net, if 2 or more items are connected: // Print the pin list for this net, use special handling if
SameNetcodeCount++; // 2 or more items are connected:
if( SameNetcodeCount == 1 ) /* first item for this net found,
* Print this connection, when a // if first item for this net found, defer printing this connection
* second item will be found */ // until a second item will is found
if( ++sameNetcodeCount == 1 )
{ {
sprintf( FirstItemInNet, " %s %.4s\n", CONV_TO_UTF8( CmpRef ), snprintf( firstItemInNet, sizeof(firstItemInNet), " %s %.4s\n",
(const char*) &aObjectsList[ii]->m_PinNum ); CONV_TO_UTF8( ref ),
(const char*) &aObjectsList[ii]->m_PinNum );
} }
// Second item for this net found, Print the Net name, and the // Second item for this net found, print the Net name, and the
// first item // first item
if( SameNetcodeCount == 2 ) if( sameNetcodeCount == 2 )
{ {
fprintf( f, "%s\n", CONV_TO_UTF8( NetcodeName ) ); ret |= fprintf( f, "%s\n", CONV_TO_UTF8( netcodeName ) );
fputs( FirstItemInNet, f ); ret |= fputs( firstItemInNet, f );
} }
if( SameNetcodeCount >= 2 ) if( sameNetcodeCount >= 2 )
fprintf( f, " %s %.4s\n", CONV_TO_UTF8( CmpRef ), ret |= fprintf( f, " %s %.4s\n", CONV_TO_UTF8( ref ),
(const char*) &aObjectsList[ii]->m_PinNum ); (const char*) &aObjectsList[ii]->m_PinNum );
} }
return ret >= 0;
} }
...@@ -956,7 +1101,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f ) ...@@ -956,7 +1101,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
{ {
wxString StartCmpDesc = StartLine + wxT( "ADD_COM" ); wxString StartCmpDesc = StartLine + wxT( "ADD_COM" );
wxString msg; wxString msg;
wxString FootprintName; wxString footprint;
char Line[1024]; char Line[1024];
SCH_SHEET_PATH* sheet; SCH_SHEET_PATH* sheet;
EDA_BaseStruct* DrawList; EDA_BaseStruct* DrawList;
...@@ -970,9 +1115,9 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f ) ...@@ -970,9 +1115,9 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
fprintf( f, "\"%s\"\n", CONV_TO_UTF8( Title ) ); fprintf( f, "\"%s\"\n", CONV_TO_UTF8( Title ) );
fprintf( f, "\n" ); fprintf( f, "\n" );
/* Create netlist module section */ // Create netlist module section
ClearUsedFlags(); /* Reset the flags FlagControlMulti in all schematic s_ReferencesAlreadyFound.Clear();
*files*/
SCH_SHEET_LIST SheetList; SCH_SHEET_LIST SheetList;
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
...@@ -983,13 +1128,16 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f ) ...@@ -983,13 +1128,16 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
if( Component == NULL ) if( Component == NULL )
break; break;
/*
doing nothing with footprint
if( !Component->GetField( FOOTPRINT )->IsVoid() ) if( !Component->GetField( FOOTPRINT )->IsVoid() )
{ {
FootprintName = Component->GetField( FOOTPRINT )->m_Text; footprint = Component->GetField( FOOTPRINT )->m_Text;
FootprintName.Replace( wxT( " " ), wxT( "_" ) ); footprint.Replace( wxT( " " ), wxT( "_" ) );
} }
else else
FootprintName = wxT( "$noname" ); footprint = wxT( "$noname" );
*/
msg = Component->GetRef( sheet ); msg = Component->GetRef( sheet );
fprintf( f, "%s ", CONV_TO_UTF8( StartCmpDesc ) ); fprintf( f, "%s ", CONV_TO_UTF8( StartCmpDesc ) );
...@@ -1024,10 +1172,10 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) ...@@ -1024,10 +1172,10 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
{ {
wxString InitNetDesc = StartLine + wxT( "ADD_TER" ); wxString InitNetDesc = StartLine + wxT( "ADD_TER" );
wxString StartNetDesc = StartLine + wxT( "TER" ); wxString StartNetDesc = StartLine + wxT( "TER" );
wxString NetcodeName, InitNetDescLine; wxString netcodeName, InitNetDescLine;
unsigned ii; unsigned ii;
int print_ter = 0; int print_ter = 0;
int NetCode, LastNetCode = -1; int NetCode, lastNetCode = -1;
SCH_COMPONENT* Cmp; SCH_COMPONENT* Cmp;
wxString NetName; wxString NetName;
...@@ -1037,7 +1185,7 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) ...@@ -1037,7 +1185,7 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
for( ii = 0; ii < g_NetObjectslist.size(); ii++ ) for( ii = 0; ii < g_NetObjectslist.size(); ii++ )
{ {
// Get the NetName of the current net : // Get the NetName of the current net :
if( ( NetCode = aObjectsList[ii]->GetNet() ) != LastNetCode ) if( ( NetCode = aObjectsList[ii]->GetNet() ) != lastNetCode )
{ {
NetName.Empty(); NetName.Empty();
...@@ -1046,22 +1194,22 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) ...@@ -1046,22 +1194,22 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
if( netref ) if( netref )
NetName = netref->m_Label; NetName = netref->m_Label;
NetcodeName = wxT( "\"" ); netcodeName = wxT( "\"" );
if( !NetName.IsEmpty() ) if( !NetName.IsEmpty() )
{ {
if( ( netref->m_Type != NET_PINLABEL ) if( ( netref->m_Type != NET_PINLABEL )
&& ( netref->m_Type != NET_GLOBLABEL ) ) && ( netref->m_Type != NET_GLOBLABEL ) )
{ {
// usual net name, prefix it by the sheet path // usual net name, prefix it by the sheet path
NetcodeName += netcodeName +=
netref->m_SheetList.PathHumanReadable(); netref->m_SheetList.PathHumanReadable();
} }
NetcodeName += NetName; netcodeName += NetName;
} }
else // this net has no name: create a default name $<net number> else // this net has no name: create a default name $<net number>
NetcodeName << wxT( "$" ) << NetCode; netcodeName << wxT( "$" ) << NetCode;
NetcodeName += wxT( "\"" ); netcodeName += wxT( "\"" );
LastNetCode = NetCode; lastNetCode = NetCode;
print_ter = 0; print_ter = 0;
} }
...@@ -1090,7 +1238,7 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) ...@@ -1090,7 +1238,7 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
GetChars( InitNetDesc ), GetChars( InitNetDesc ),
GetChars( refstr ), GetChars( refstr ),
GetChars( str_pinnum ), GetChars( str_pinnum ),
GetChars( NetcodeName ) ); GetChars( netcodeName ) );
} }
print_ter++; print_ter++;
break; break;
......
...@@ -45,6 +45,11 @@ enum TypeNetForm { ...@@ -45,6 +45,11 @@ enum TypeNetForm {
*/ */
class OBJ_CMP_TO_LIST class OBJ_CMP_TO_LIST
{ {
private:
/// Component reference prefix, without number (for IC1, this is IC) )
std::string m_Ref; // it's private, use the accessors please
public: public:
SCH_COMPONENT* m_RootCmp; // the component in schematic SCH_COMPONENT* m_RootCmp; // the component in schematic
LIB_COMPONENT* m_Entry; // the source component in library LIB_COMPONENT* m_Entry; // the source component in library
...@@ -57,8 +62,6 @@ public: ...@@ -57,8 +62,6 @@ public:
* components */ * components */
wxString* m_Value; /* Component value (same for all wxString* m_Value; /* Component value (same for all
* instances) */ * instances) */
char m_Reference[32]; /* Component reference prefix, without
* number (for IC1, this is IC) ) */
int m_NumRef; /* Reference number (for IC1, this is int m_NumRef; /* Reference number (for IC1, this is
* 1) ) depending on sheet path*/ * 1) ) depending on sheet path*/
int m_Flag; /* flag for computations */ int m_Flag; /* flag for computations */
...@@ -73,11 +76,32 @@ public: ...@@ -73,11 +76,32 @@ public:
m_TimeStamp = 0; m_TimeStamp = 0;
m_IsNew = false; m_IsNew = false;
m_Value = NULL; m_Value = NULL;
m_Reference[0] = 0;
m_NumRef = 0; m_NumRef = 0;
m_Flag = 0; m_Flag = 0;
} }
/* Some accessors which hide the strategy of how the reference is stored,
thereby making it easy to change that strategy.
*/
void SetRef( const wxString& aReference )
{
m_Ref = CONV_TO_UTF8( aReference );
}
wxString GetRef() const
{
return CONV_FROM_UTF8( m_Ref.c_str() );
}
void SetRefStr( const std::string& aReference )
{
m_Ref = aReference;
}
const char* GetRefStr() const
{
return m_Ref.c_str();
}
int CompareValue( const OBJ_CMP_TO_LIST& item ) const int CompareValue( const OBJ_CMP_TO_LIST& item ) const
{ {
...@@ -87,7 +111,7 @@ public: ...@@ -87,7 +111,7 @@ public:
int CompareRef( const OBJ_CMP_TO_LIST& item ) const int CompareRef( const OBJ_CMP_TO_LIST& item ) const
{ {
return strnicmp( m_Reference, item.m_Reference, 32 ); return m_Ref.compare( item.m_Ref );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment