Commit 6c01c554 authored by charras's avatar charras

code cleanup, better comments and comments translation

parent 589873f3
/****************************************************************************/ /*********************************************/
/* string.cpp */ /* string.cpp */
/* ROLE: fonctions complementaires de traitement de chaines de caracteres */ /* some useful functions to handle strings */
/****************************************************************************/ /*********************************************/
#include "fctsys.h" #include "fctsys.h"
#include <time.h> #include <time.h>
...@@ -13,9 +13,9 @@ ...@@ -13,9 +13,9 @@
int ReadDelimitedText( char* dest, char* source, int NbMaxChar ) int ReadDelimitedText( char* dest, char* source, int NbMaxChar )
/*********************************************************************/ /*********************************************************************/
/* read a double-qute delimited text in source and put in in dest, /* read a double-quote delimited text from source and put it in in dest,
* read NbMaxChar bytes max * read NbMaxChar bytes max
* return the byte count read in source * return the char count read from source
*/ */
{ {
int ii, jj, flag = 0; int ii, jj, flag = 0;
......
...@@ -2,24 +2,27 @@ ...@@ -2,24 +2,27 @@
/* annotate.cpp: component annotation */ /* annotate.cpp: component annotation */
/**************************************/ /**************************************/
#include <algorithm> // to use sort vector
#include <vector>
#include "fctsys.h" #include "fctsys.h"
#include "common.h" #include "common.h"
#include "program.h" #include "program.h"
#include "libcmp.h" #include "libcmp.h"
#include "netlist.h"
#include "protos.h" #include "protos.h"
#include "netlist.h"
/* Local Functions*/ /* Local Functions*/
static int ListeComposants( CmpListStruct* BaseListeCmp, static int AddComponentsInSheetToList( std::vector <OBJ_CMP_TO_LIST>& aComponentsList,
DrawSheetPath* sheet ); DrawSheetPath* sheet );
static void BreakReference( CmpListStruct* BaseListeCmp, int NbOfCmp ); static void BreakReference( std::vector <OBJ_CMP_TO_LIST>& aComponentsList );
static void ReAnnotateComponents( CmpListStruct* BaseListeCmp, int NbOfCmp ); static void ReAnnotateComponents( std::vector <OBJ_CMP_TO_LIST>& aComponentsList );
static void ComputeReferenceNumber( CmpListStruct* BaseListeCmp, int NbOfCmp ); static void ComputeReferenceNumber( std::vector <OBJ_CMP_TO_LIST>& aComponentsList );
int GetLastReferenceNumber( CmpListStruct* Objet, int GetLastReferenceNumber( int aObjet,
CmpListStruct* BaseListeCmp, std::vector <OBJ_CMP_TO_LIST>& aComponentsList );
int NbOfCmp ); static int ExistUnit( int aObjet, int aUnit,
static int ExistUnit( CmpListStruct* Objet, int Unit, std::vector <OBJ_CMP_TO_LIST>& aComponentsList );
CmpListStruct* BaseListeCmp, int NbOfCmp );
/******************************************************/ /******************************************************/
...@@ -34,7 +37,7 @@ void WinEDA_SchematicFrame::UpdateSheetNumberAndDate() ...@@ -34,7 +37,7 @@ void WinEDA_SchematicFrame::UpdateSheetNumberAndDate()
EDA_ScreenList s_list; EDA_ScreenList s_list;
// Set the date // Set the date
for ( SCH_SCREEN * screen = s_list.GetFirst(); screen != NULL; screen = s_list.GetNext() ) for( SCH_SCREEN* screen = s_list.GetFirst(); screen != NULL; screen = s_list.GetNext() )
screen->m_Date = date; screen->m_Date = date;
// Set sheet counts // Set sheet counts
...@@ -55,13 +58,10 @@ void ReAnnotatePowerSymbolsOnly( void ) ...@@ -55,13 +58,10 @@ void ReAnnotatePowerSymbolsOnly( void )
/* Build the screen list (screen, not sheet) */ /* Build the screen list (screen, not sheet) */
EDA_SheetList SheetList( NULL ); EDA_SheetList SheetList( NULL );
DrawSheetPath* sheet; DrawSheetPath* sheet;
int CmpNumber = 1; int CmpNumber = 1;
for( sheet = SheetList.GetFirst(); for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
sheet != NULL;
sheet = SheetList.GetNext() )
{ {
EDA_BaseStruct* DrawList = sheet->LastDrawList(); EDA_BaseStruct* DrawList = sheet->LastDrawList();
for( ; DrawList != NULL; DrawList = DrawList->Next() ) for( ; DrawList != NULL; DrawList = DrawList->Next() )
...@@ -70,10 +70,8 @@ void ReAnnotatePowerSymbolsOnly( void ) ...@@ -70,10 +70,8 @@ void ReAnnotatePowerSymbolsOnly( void )
continue; continue;
SCH_COMPONENT* DrawLibItem = SCH_COMPONENT* DrawLibItem =
(SCH_COMPONENT*) DrawList; (SCH_COMPONENT*) DrawList;
EDA_LibComponentStruct* Entry = EDA_LibComponentStruct* Entry = FindLibPart(
FindLibPart( DrawLibItem->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
DrawLibItem->m_ChipName.GetData(), wxEmptyString,
FIND_ROOT );
if( (Entry == NULL) || (Entry->m_Options != ENTRY_POWER) ) if( (Entry == NULL) || (Entry->m_Options != ENTRY_POWER) )
continue; continue;
...@@ -94,59 +92,53 @@ void ReAnnotatePowerSymbolsOnly( void ) ...@@ -94,59 +92,53 @@ void ReAnnotatePowerSymbolsOnly( void )
} }
/* qsort function to annotate items by their position. /* sort function to annotate items by their position.
* Components are sorted * Components are sorted
* by reference * by reference
* if same reference: by sheet * if same reference: by sheet
* if same sheet, by X pos * if same sheet, by X pos
* if same X pos, by Y pos * if same X pos, by Y pos
* if same Y pos, by time stamp * if same Y pos, by time stamp
*/ */
int AnnotateBy_X_Position( const void* o1, const void* o2 ) static bool AnnotateBy_X_Position( const OBJ_CMP_TO_LIST& item1, const OBJ_CMP_TO_LIST& item2 )
{ {
CmpListStruct* item1 = (CmpListStruct*) o1; int ii = item1.CompareRef( item2 );
CmpListStruct* item2 = (CmpListStruct*) o2;
int ii = strnicmp( item1->m_TextRef, item2->m_TextRef, 32 );
if( ii == 0 ) if( ii == 0 )
ii = item1->m_SheetList.Cmp( item2->m_SheetList ); ii = item1.m_SheetPath.Cmp( item2.m_SheetPath );
if( ii == 0 ) if( ii == 0 )
ii = item1->m_Pos.x - item2->m_Pos.x; ii = item1.m_RootCmp->m_Pos.x - item2.m_RootCmp->m_Pos.x;
if( ii == 0 ) if( ii == 0 )
ii = item1->m_Pos.y - item2->m_Pos.y; ii = item1.m_RootCmp->m_Pos.y - item2.m_RootCmp->m_Pos.y;
if( ii == 0 ) if( ii == 0 )
ii = item1->m_TimeStamp - item2->m_TimeStamp; ii = item1.m_TimeStamp - item2.m_TimeStamp;
return ii; return ii < 0;
} }
/* qsort function to annotate items by their position. /* sort function to annotate items by their position.
* Components are sorted * Components are sorted
* by reference * by reference
* if same reference: by sheet * if same reference: by sheet
* if same sheet, by Y pos * if same sheet, by Y pos
* if same Y pos, by X pos * if same Y pos, by X pos
* if same X pos, by time stamp * if same X pos, by time stamp
*/ */
int AnnotateBy_Y_Position( const void* o1, const void* o2 ) static bool AnnotateBy_Y_Position( const OBJ_CMP_TO_LIST& item1, const OBJ_CMP_TO_LIST& item2 )
{ {
CmpListStruct* item1 = (CmpListStruct*) o1; int ii = item1.CompareRef( item2 );
CmpListStruct* item2 = (CmpListStruct*) o2;
int ii = strnicmp( item1->m_TextRef, item2->m_TextRef, 32 );
if( ii == 0 ) if( ii == 0 )
ii = item1->m_SheetList.Cmp( item2->m_SheetList ); ii = item1.m_SheetPath.Cmp( item2.m_SheetPath );
if( ii == 0 ) if( ii == 0 )
ii = item1->m_Pos.y - item2->m_Pos.y; ii = item1.m_RootCmp->m_Pos.y - item2.m_RootCmp->m_Pos.y;
if( ii == 0 ) if( ii == 0 )
ii = item1->m_Pos.x - item2->m_Pos.x; ii = item1.m_RootCmp->m_Pos.x - item2.m_RootCmp->m_Pos.x;
if( ii == 0 ) if( ii == 0 )
ii = item1->m_TimeStamp - item2->m_TimeStamp; ii = item1.m_TimeStamp - item2.m_TimeStamp;
return ii; return ii < 0;
} }
...@@ -159,27 +151,24 @@ int AnnotateBy_Y_Position( const void* o1, const void* o2 ) ...@@ -159,27 +151,24 @@ int AnnotateBy_Y_Position( const void* o1, const void* o2 )
* if same unit number, by sheet * if same unit number, by sheet
* if same sheet, by time stamp * if same sheet, by time stamp
*****************************************************************************/ *****************************************************************************/
int AnnotateByValue( const void* o1, const void* o2 ) static bool AnnotateByValue( const OBJ_CMP_TO_LIST& item1, const OBJ_CMP_TO_LIST& item2 )
{ {
CmpListStruct* item1 = (CmpListStruct*) o1; int ii = item1.CompareRef( item2 );
CmpListStruct* item2 = (CmpListStruct*) o2;
int ii = strnicmp( item1->m_TextRef, item2->m_TextRef, 32 );
if( ii == 0 ) if( ii == 0 )
ii = strnicmp( item1->m_TextValue, item2->m_TextValue, 32 ); ii = item1.CompareValue( item2 );
if( ii == 0 ) if( ii == 0 )
ii = item1->m_Unit - item2->m_Unit; ii = item1.m_Unit - item2.m_Unit;
if( ii == 0 ) if( ii == 0 )
ii = item1->m_SheetList.Cmp( item2->m_SheetList ); ii = item1.m_SheetPath.Cmp( item2.m_SheetPath );
if( ii == 0 ) if( ii == 0 )
ii = item1->m_Pos.x - item2->m_Pos.x; ii = item1.m_RootCmp->m_Pos.x - item2.m_RootCmp->m_Pos.x;
if( ii == 0 ) if( ii == 0 )
ii = item1->m_Pos.y - item2->m_Pos.y; ii = item1.m_RootCmp->m_Pos.y - item2.m_RootCmp->m_Pos.y;
if( ii == 0 ) if( ii == 0 )
ii = item1->m_TimeStamp - item2->m_TimeStamp; ii = item1.m_TimeStamp - item2.m_TimeStamp;
return ii; return ii < 0;
} }
...@@ -193,9 +182,9 @@ void WinEDA_SchematicFrame::DeleteAnnotation( bool aCurrentSheetOnly, bool aRedr ...@@ -193,9 +182,9 @@ void WinEDA_SchematicFrame::DeleteAnnotation( bool aCurrentSheetOnly, bool aRedr
* @param aRedraw : true to refresh display * @param aRedraw : true to refresh display
*/ */
{ {
EDA_BaseStruct* strct; SCH_ITEM* strct;
SCH_SCREEN* screen; SCH_SCREEN* screen;
EDA_ScreenList ScreenList; EDA_ScreenList ScreenList;
screen = ScreenList.GetFirst(); screen = ScreenList.GetFirst();
...@@ -251,11 +240,9 @@ void AnnotateComponents( WinEDA_SchematicFrame* parent, ...@@ -251,11 +240,9 @@ void AnnotateComponents( WinEDA_SchematicFrame* parent,
int sortOption, int sortOption,
bool resetAnnotation ) bool resetAnnotation )
{ {
int ii, NbOfCmp; std::vector <OBJ_CMP_TO_LIST> ComponentsList;
DrawSheetPath* sheet;
CmpListStruct* BaseListeCmp;
wxBusyCursor dummy; wxBusyCursor dummy;
/* If it is an annotation for all the components, reset previous /* If it is an annotation for all the components, reset previous
* annotation: */ * annotation: */
...@@ -268,87 +255,59 @@ void AnnotateComponents( WinEDA_SchematicFrame* parent, ...@@ -268,87 +255,59 @@ void AnnotateComponents( WinEDA_SchematicFrame* parent,
/* Update the sheet number, sheet count and date */ /* Update the sheet number, sheet count and date */
parent->UpdateSheetNumberAndDate(); parent->UpdateSheetNumberAndDate();
/* First pass: Component counting */ /* Build component list */
ii = 0;
sheet = parent->GetSheet();
if( annotateSchematic )
{
NbOfCmp = 0;
for( sheet = SheetList.GetFirst();
sheet != NULL;
sheet = SheetList.GetNext() )
NbOfCmp += ListeComposants( NULL, sheet );
}
else
NbOfCmp = ListeComposants( NULL, sheet );
if( NbOfCmp == 0 )
return;
BaseListeCmp = (CmpListStruct*) MyZMalloc( NbOfCmp * sizeof(CmpListStruct) );
/* Second pass : Init data tables */
if( annotateSchematic ) if( annotateSchematic )
{ {
ii = 0; DrawSheetPath* sheet;
for( sheet = SheetList.GetFirst(); for( sheet = SheetList.GetFirst();
sheet != NULL; sheet != NULL;
sheet = SheetList.GetNext() ) sheet = SheetList.GetNext() )
ii += ListeComposants( BaseListeCmp + ii, sheet ); AddComponentsInSheetToList( ComponentsList, sheet );
} }
else else
ii = ListeComposants( BaseListeCmp, sheet ); AddComponentsInSheetToList( ComponentsList, parent->GetSheet() );
if( ii != NbOfCmp )
DisplayError( parent, wxT( "Internal error in AnnotateComponents()" ) );
/* Break full components reference in name (prefix) and number: /* Break full components reference in name (prefix) and number:
* example: IC1 become IC, and 1 */ * example: IC1 become IC, and 1 */
BreakReference( BaseListeCmp, NbOfCmp ); BreakReference( ComponentsList );
switch( sortOption ) switch( sortOption )
{ {
case 0: case 0:
qsort( BaseListeCmp, NbOfCmp, sizeof(CmpListStruct), sort( ComponentsList.begin(), ComponentsList.end(), AnnotateBy_X_Position );
( int( * ) ( const void*, const void* ) )AnnotateBy_X_Position );
break; break;
case 1: case 1:
qsort( BaseListeCmp, NbOfCmp, sizeof(CmpListStruct), sort( ComponentsList.begin(), ComponentsList.end(), AnnotateBy_Y_Position );
( int( * ) ( const void*, const void* ) )AnnotateBy_Y_Position );
break; break;
case 2: case 2:
qsort( BaseListeCmp, NbOfCmp, sizeof(CmpListStruct), sort( ComponentsList.begin(), ComponentsList.end(), AnnotateByValue );
( int( * ) ( const void*, const void* ) )AnnotateByValue );
break; break;
} }
/* Recalculate reference numbers */ /* Recalculate reference numbers */
ComputeReferenceNumber( BaseListeCmp, NbOfCmp ); ComputeReferenceNumber( ComponentsList );
ReAnnotateComponents( BaseListeCmp, NbOfCmp ); ReAnnotateComponents( ComponentsList );
MyFree( BaseListeCmp );
BaseListeCmp = NULL;
/* Final control */ /* Final control (just in case ... )*/
CheckAnnotate( parent, !annotateSchematic ); CheckAnnotate( parent, !annotateSchematic );
parent->DrawPanel->Refresh( true ); parent->DrawPanel->Refresh( true );
} }
/***************************************************************************** /*****************************************************************************
* if BaseListeCmp == NULL : count components * Add a OBJ_CMP_TO_LIST object in aComponentsList for each component foun in sheet
* else update data table BaseListeCmp
*****************************************************************************/ *****************************************************************************/
int ListeComposants( CmpListStruct* BaseListeCmp, DrawSheetPath* sheet ) int AddComponentsInSheetToList( std::vector <OBJ_CMP_TO_LIST>& aComponentsList, DrawSheetPath* aSheet )
{ {
int NbrCmp = 0; int NbrCmp = 0;
EDA_BaseStruct* DrawList = sheet->LastDrawList(); EDA_BaseStruct* DrawList = aSheet->LastDrawList();
SCH_COMPONENT* DrawLibItem; SCH_COMPONENT* DrawLibItem;
EDA_LibComponentStruct* Entry; EDA_LibComponentStruct* Entry;
for( ; DrawList; DrawList = DrawList->Next() ) for( ; DrawList != NULL; DrawList = DrawList->Next() )
{ {
if( DrawList->Type() == TYPE_SCH_COMPONENT ) if( DrawList->Type() == TYPE_SCH_COMPONENT )
{ {
...@@ -359,34 +318,28 @@ int ListeComposants( CmpListStruct* BaseListeCmp, DrawSheetPath* sheet ) ...@@ -359,34 +318,28 @@ int ListeComposants( CmpListStruct* BaseListeCmp, DrawSheetPath* sheet )
if( Entry == NULL ) if( Entry == NULL )
continue; continue;
if( BaseListeCmp == NULL ) /* Items counting only */ OBJ_CMP_TO_LIST new_object;
{ new_object.m_RootCmp = DrawLibItem;
NbrCmp++; new_object.m_Entry = Entry;
continue; new_object.m_Unit = DrawLibItem->GetUnitSelection( aSheet );
} new_object.m_SheetPath = *aSheet;
new_object.m_IsNew = false;
new_object.m_Flag = 0;
new_object.m_TimeStamp = DrawLibItem->m_TimeStamp;
BaseListeCmp[NbrCmp].m_Cmp = DrawLibItem; if( DrawLibItem->GetRef( aSheet ).IsEmpty() )
BaseListeCmp[NbrCmp].m_NbParts = Entry->m_UnitCount; DrawLibItem->SetRef( aSheet, wxT( "DefRef?" ) );
BaseListeCmp[NbrCmp].m_Unit = DrawLibItem->GetUnitSelection( sheet ); // DrawLibItem->m_Multi;
BaseListeCmp[NbrCmp].m_PartsLocked = Entry->m_UnitSelectionLocked;
BaseListeCmp[NbrCmp].m_SheetList = *sheet;
BaseListeCmp[NbrCmp].m_IsNew = FALSE;
BaseListeCmp[NbrCmp].m_Pos = DrawLibItem->m_Pos;
BaseListeCmp[NbrCmp].m_TimeStamp = DrawLibItem->m_TimeStamp;
if( DrawLibItem->GetRef( sheet ).IsEmpty() ) strncpy( new_object.m_Reference, CONV_TO_UTF8( DrawLibItem->GetRef( aSheet ) ), 32 );
DrawLibItem->SetRef( sheet, wxT( "DefRef?" ) );
strncpy( BaseListeCmp[NbrCmp].m_TextRef, new_object.m_NumRef = -1;
CONV_TO_UTF8( DrawLibItem->GetRef( sheet ) ), 32 );
BaseListeCmp[NbrCmp].m_NumRef = -1; if( DrawLibItem->GetField( VALUE )->m_Text.IsEmpty() )
DrawLibItem->GetField( VALUE )->m_Text = wxT( "~" );
if( DrawLibItem->GetField(VALUE)->m_Text.IsEmpty() ) new_object.m_Value = &DrawLibItem->GetField( VALUE )->m_Text;
DrawLibItem->GetField(VALUE)->m_Text = wxT( "~" );
strncpy( BaseListeCmp[NbrCmp].m_TextValue, aComponentsList.push_back( new_object );
CONV_TO_UTF8( DrawLibItem->GetField(VALUE)->m_Text ), 32 );
NbrCmp++; NbrCmp++;
} }
} }
...@@ -399,27 +352,23 @@ int ListeComposants( CmpListStruct* BaseListeCmp, DrawSheetPath* sheet ) ...@@ -399,27 +352,23 @@ int ListeComposants( CmpListStruct* BaseListeCmp, DrawSheetPath* sheet )
* Update the reference component for the schematic project (or the current * Update the reference component for the schematic project (or the current
* sheet) * sheet)
*****************************************************************************/ *****************************************************************************/
static void ReAnnotateComponents( CmpListStruct* BaseListeCmp, int NbOfCmp ) static void ReAnnotateComponents( std::vector <OBJ_CMP_TO_LIST>& aComponentsList )
{ {
int ii; /* update the reference numbers */
char* Text; for( unsigned ii = 0; ii < aComponentsList.size(); ii++ )
SCH_COMPONENT* DrawLibItem;
/* Reattribution des numeros */
for( ii = 0; ii < NbOfCmp; ii++ )
{ {
Text = BaseListeCmp[ii].m_TextRef; char* Text = aComponentsList[ii].m_Reference;
DrawLibItem = BaseListeCmp[ii].m_Cmp; SCH_COMPONENT* component = aComponentsList[ii].m_RootCmp;
if( BaseListeCmp[ii].m_NumRef < 0 ) if( aComponentsList[ii].m_NumRef < 0 )
strcat( Text, "?" ); strcat( Text, "?" );
else else
sprintf( Text + strlen( Text ), "%d", BaseListeCmp[ii].m_NumRef ); sprintf( Text + strlen( Text ), "%d", aComponentsList[ii].m_NumRef );
DrawLibItem->SetRef( &(BaseListeCmp[ii].m_SheetList), component->SetRef( &(aComponentsList[ii].m_SheetPath), CONV_FROM_UTF8( Text ) );
CONV_FROM_UTF8( Text ) ); component->m_Multi = aComponentsList[ii].m_Unit;
DrawLibItem->m_Multi = BaseListeCmp[ii].m_Unit; component->SetUnitSelection( &(aComponentsList[ii].m_SheetPath),
DrawLibItem->SetUnitSelection( &(BaseListeCmp[ii].m_SheetList), DrawLibItem->m_Multi ); aComponentsList[ii].m_Unit );
} }
} }
...@@ -430,33 +379,32 @@ static void ReAnnotateComponents( CmpListStruct* BaseListeCmp, int NbOfCmp ) ...@@ -430,33 +379,32 @@ static void ReAnnotateComponents( CmpListStruct* BaseListeCmp, int NbOfCmp )
* For multi part per package components not already annotated, set .m_Unit * For multi part per package components not already annotated, set .m_Unit
* to a max value (0x7FFFFFFF). * to a max value (0x7FFFFFFF).
* *
* @param BaseListeCmp = list of component * @param aComponentsList = list of component
* @param NbOfCmp = item count in the list * @param NbOfCmp = item count in the list
*****************************************************************************/ *****************************************************************************/
void BreakReference( CmpListStruct* BaseListeCmp, int NbOfCmp ) void BreakReference( std::vector <OBJ_CMP_TO_LIST>& aComponentsList )
{ {
int ii, ll;
char* Text; char* Text;
for( ii = 0; ii < NbOfCmp; ii++ ) for( unsigned ii = 0; ii < aComponentsList.size(); ii++ )
{ {
BaseListeCmp[ii].m_NumRef = -1; aComponentsList[ii].m_NumRef = -1;
Text = BaseListeCmp[ii].m_TextRef; Text = aComponentsList[ii].m_Reference;
ll = strlen( Text ) - 1; int ll = strlen( Text ) - 1;
if( Text[ll] == '?' ) if( Text[ll] == '?' )
{ {
BaseListeCmp[ii].m_IsNew = true; aComponentsList[ii].m_IsNew = true;
if( !BaseListeCmp[ii].m_PartsLocked ) if( !aComponentsList[ii].IsPartsLocked() )
BaseListeCmp[ii].m_Unit = 0x7FFFFFFF; aComponentsList[ii].m_Unit = 0x7FFFFFFF;
Text[ll] = 0; Text[ll] = 0;
continue; continue;
} }
if( isdigit( Text[ll] ) == 0 ) if( isdigit( Text[ll] ) == 0 )
{ {
BaseListeCmp[ii].m_IsNew = true; aComponentsList[ii].m_IsNew = true;
if( !BaseListeCmp[ii].m_PartsLocked ) if( !aComponentsList[ii].IsPartsLocked() )
BaseListeCmp[ii].m_Unit = 0x7FFFFFFF; aComponentsList[ii].m_Unit = 0x7FFFFFFF;
continue; continue;
} }
...@@ -467,7 +415,7 @@ void BreakReference( CmpListStruct* BaseListeCmp, int NbOfCmp ) ...@@ -467,7 +415,7 @@ void BreakReference( CmpListStruct* BaseListeCmp, int NbOfCmp )
else else
{ {
if( isdigit( Text[ll + 1] ) ) if( isdigit( Text[ll + 1] ) )
BaseListeCmp[ii].m_NumRef = atoi( &Text[ll + 1] ); aComponentsList[ii].m_NumRef = atoi( &Text[ll + 1] );
Text[ll + 1] = 0; Text[ll + 1] = 0;
break; break;
} }
...@@ -480,103 +428,99 @@ void BreakReference( CmpListStruct* BaseListeCmp, int NbOfCmp ) ...@@ -480,103 +428,99 @@ void BreakReference( CmpListStruct* BaseListeCmp, int NbOfCmp )
* Compute the reference number for components without reference number * Compute the reference number for components without reference number
* Compute .m_NumRef member * Compute .m_NumRef member
*****************************************************************************/ *****************************************************************************/
static void ComputeReferenceNumber( CmpListStruct* BaseListeCmp, int NbOfCmp ) static void ComputeReferenceNumber( std::vector <OBJ_CMP_TO_LIST>& aComponentsList )
{ {
int ii, jj, LastReferenceNumber, NumberOfUnits, Unit; int LastReferenceNumber, NumberOfUnits, Unit;
const char* Text, * RefText, * ValText;
CmpListStruct* ObjRef, * ObjToTest;
/* Components with an invisible reference (power...) always are /* Components with an invisible reference (power...) always are re-annotated.
* re-annotated */ * So set theirs .m_IsNew member to true
for( ii = 0; ii < NbOfCmp; ii++ ) */
for( unsigned ii = 0; ii < aComponentsList.size(); ii++ )
{ {
Text = BaseListeCmp[ii].m_TextRef; if( aComponentsList[ii].m_Reference[0] == '#' )
if( *Text == '#' )
{ {
BaseListeCmp[ii].m_IsNew = true; aComponentsList[ii].m_IsNew = true;
BaseListeCmp[ii].m_NumRef = 0; aComponentsList[ii].m_NumRef = 0;
} }
} }
ValText = RefText = ""; LastReferenceNumber = 1; /* calculate index of the first component with the same reference prefix than the current component.
for( ii = 0; ii < NbOfCmp; ii++ ) * all of component having the same reference prefix will receive a reference number with consecutives values:
* IC .. will be set to IC4, IC4, IC5 ...
*/
unsigned first = 0;
/* calculate the last used number for this reference prefix: */
LastReferenceNumber = GetLastReferenceNumber( first, aComponentsList );
for( unsigned ii = 0; ii < aComponentsList.size(); ii++ )
{ {
ObjRef = &BaseListeCmp[ii]; if( aComponentsList[ii].m_Flag )
if( BaseListeCmp[ii].m_Flag )
continue; continue;
Text = BaseListeCmp[ii].m_TextRef; if( aComponentsList[first].CompareRef( aComponentsList[ii] ) != 0 ) /* New reference found: we need a new ref number for this reference */
if( strnicmp( RefText, Text, 32 ) != 0 ) /* Nouveau Identificateur */
{ {
RefText = BaseListeCmp[ii].m_TextRef; first = ii;
LastReferenceNumber = GetLastReferenceNumber( BaseListeCmp + ii, LastReferenceNumber = GetLastReferenceNumber( ii, aComponentsList );
BaseListeCmp,
NbOfCmp );
} }
/* Annotation of one part per package components (trivial case)*/ /* Annotation of one part per package components (trivial case)*/
if( BaseListeCmp[ii].m_NbParts <= 1 ) if( aComponentsList[ii].m_Entry->m_UnitCount <= 1 )
{ {
if( BaseListeCmp[ii].m_IsNew ) if( aComponentsList[ii].m_IsNew )
{ {
LastReferenceNumber++; LastReferenceNumber++;
BaseListeCmp[ii].m_NumRef = LastReferenceNumber; aComponentsList[ii].m_NumRef = LastReferenceNumber;
} }
BaseListeCmp[ii].m_Unit = 1; aComponentsList[ii].m_Unit = 1;
BaseListeCmp[ii].m_Flag = 1; aComponentsList[ii].m_Flag = 1;
BaseListeCmp[ii].m_IsNew = FALSE; aComponentsList[ii].m_IsNew = false;
continue; continue;
} }
/* Annotation of multi-part components ( n parts per package ) /* Annotation of multi-part components ( n parts per package )
* (complex case) */ * (complex case) */
ValText = BaseListeCmp[ii].m_TextValue; NumberOfUnits = aComponentsList[ii].m_Entry->m_UnitCount;
NumberOfUnits = BaseListeCmp[ii].m_NbParts;
if( BaseListeCmp[ii].m_IsNew ) if( aComponentsList[ii].m_IsNew )
{ {
LastReferenceNumber++; LastReferenceNumber++;
BaseListeCmp[ii].m_NumRef = LastReferenceNumber; aComponentsList[ii].m_NumRef = LastReferenceNumber;
if( !BaseListeCmp[ii].m_PartsLocked ) if( !aComponentsList[ii].IsPartsLocked() )
BaseListeCmp[ii].m_Unit = 1; aComponentsList[ii].m_Unit = 1;
BaseListeCmp[ii].m_Flag = 1; aComponentsList[ii].m_Flag = 1;
} }
/* search for others units of this component.
* we search for others parts that have the same value and the same reference prefix (ref without ref number)
*/
for( Unit = 1; Unit <= NumberOfUnits; Unit++ ) for( Unit = 1; Unit <= NumberOfUnits; Unit++ )
{ {
if( BaseListeCmp[ii].m_Unit == Unit ) if( aComponentsList[ii].m_Unit == Unit )
continue; continue;
jj = ExistUnit( BaseListeCmp + ii, Unit, BaseListeCmp, NbOfCmp ); int found = ExistUnit( ii, Unit, aComponentsList );
if( jj >= 0 ) if( found >= 0 )
continue; /* Unit exists for this reference */ continue; /* this unit exists for this reference (unit already annotated) */
/* Search a component to annotate ( same prefix, same value) */ /* Search a component to annotate ( same prefix, same value, not annotated) */
for( jj = ii + 1; jj < NbOfCmp; jj++ ) for( unsigned jj = ii + 1; jj < aComponentsList.size(); jj++ )
{ {
ObjToTest = &BaseListeCmp[jj]; if( aComponentsList[jj].m_Flag ) // already tested
if( BaseListeCmp[jj].m_Flag ) continue;
if( aComponentsList[ii].CompareRef( aComponentsList[jj] ) != 0 ) // references are different
continue; continue;
Text = BaseListeCmp[jj].m_TextRef; if( aComponentsList[jj].CompareValue( aComponentsList[ii] ) != 0 )
if( strnicmp( RefText, Text, 32 ) != 0 )
continue; // references are different
Text = BaseListeCmp[jj].m_TextValue;
if( strnicmp( ValText, Text, 32 ) != 0 )
continue; // values are different continue; // values are different
if( !BaseListeCmp[jj].m_IsNew ) if( !aComponentsList[jj].m_IsNew )
{
continue; continue;
}
/* Component without reference number found, annotate it if /* Component without reference number found, annotate it if possible */
* possible */ if( !aComponentsList[jj].IsPartsLocked() || (aComponentsList[jj].m_Unit == Unit) )
if( !BaseListeCmp[jj].m_PartsLocked
|| (BaseListeCmp[jj].m_Unit == Unit) )
{ {
BaseListeCmp[jj].m_NumRef = BaseListeCmp[ii].m_NumRef; aComponentsList[jj].m_NumRef = aComponentsList[ii].m_NumRef;
BaseListeCmp[jj].m_Unit = Unit; aComponentsList[jj].m_Unit = Unit;
BaseListeCmp[jj].m_Flag = 1; aComponentsList[jj].m_Flag = 1;
BaseListeCmp[jj].m_IsNew = FALSE; aComponentsList[jj].m_IsNew = false;
break; break;
} }
} }
...@@ -590,26 +534,20 @@ static void ComputeReferenceNumber( CmpListStruct* BaseListeCmp, int NbOfCmp ) ...@@ -590,26 +534,20 @@ static void ComputeReferenceNumber( CmpListStruct* BaseListeCmp, int NbOfCmp )
* for the prefix reference given by Objet * for the prefix reference given by Objet
* The component list must be sorted. * The component list must be sorted.
* *
* @param Objet = reference item ( Objet->m_TextRef is the search pattern) * @param aObjet = reference item ( aComponentsList[aObjet].m_TextRef is the search pattern)
* @param BaseListeCmp = list of items * @param aComponentsList = list of items
* @param NbOfCmp = items count in list of items
*****************************************************************************/ *****************************************************************************/
int GetLastReferenceNumber( CmpListStruct* Objet, int GetLastReferenceNumber( int aObjet, std::vector <OBJ_CMP_TO_LIST>& aComponentsList )
CmpListStruct* BaseListeCmp,
int NbOfCmp )
{ {
CmpListStruct* LastObjet = BaseListeCmp + NbOfCmp; int LastNumber = 0;
int LastNumber = 0;
const char* RefText;
RefText = Objet->m_TextRef; for( unsigned ii = 0; ii < aComponentsList.size(); ii++ )
for( ; Objet < LastObjet; Objet++ )
{ {
/* Nouveau Identificateur */ /* Nouveau Identificateur */
if( strnicmp( RefText, Objet->m_TextRef, 32 ) != 0 ) if( aComponentsList[aObjet].CompareRef( aComponentsList[ii] ) != 0 )
break; continue;
if( LastNumber < Objet->m_NumRef ) if( LastNumber < aComponentsList[ii].m_NumRef )
LastNumber = Objet->m_NumRef; LastNumber = aComponentsList[ii].m_NumRef;
} }
return LastNumber; return LastNumber;
...@@ -620,36 +558,28 @@ int GetLastReferenceNumber( CmpListStruct* Objet, ...@@ -620,36 +558,28 @@ int GetLastReferenceNumber( CmpListStruct* Objet,
* Search in the sorted list of components, for a given componen,t an other component * Search in the sorted list of components, for a given componen,t an other component
* with the same reference and a given part unit. * with the same reference and a given part unit.
* Mainly used to manage multiple parts per package components * Mainly used to manage multiple parts per package components
* @param Objet = the given CmpListStruct* item to test * @param aObjet = index in aComponentsList for the given OBJ_CMP_TO_LIST item to test
* @param Unit = the given unit number to search * @param Unit = the given unit number to search
* @param BaseListeCmp = list of items to examine * @param aComponentsList = list of items to examine
* @param NbOfCmp = size of list * @return index in aComponentsList if found or -1 if not found
* @return index in BaseListeCmp if found or -1 if not found
*****************************************************************************/ *****************************************************************************/
static int ExistUnit( CmpListStruct* Objet, int Unit, static int ExistUnit( int aObjet, int Unit,
CmpListStruct* BaseListeCmp, int NbOfCmp ) std::vector <OBJ_CMP_TO_LIST>& aComponentsList )
{ {
CmpListStruct* EndList = BaseListeCmp + NbOfCmp; int NumRef;
char* RefText, * ValText;
int NumRef, ii; NumRef = aComponentsList[aObjet].m_NumRef;
CmpListStruct* ItemToTest; for( unsigned ii = 0; ii < aComponentsList.size(); ii++ )
RefText = Objet->m_TextRef;
ValText = Objet->m_TextValue;
NumRef = Objet->m_NumRef;
for( ItemToTest = BaseListeCmp, ii = 0;
ItemToTest < EndList;
ItemToTest++, ii++ )
{ {
if( Objet == ItemToTest ) // Do not compare with itself ! if( aObjet == (int) ii ) // Do not compare with itself !
continue; continue;
if( ItemToTest->m_IsNew ) // Not already with an updated reference if( aComponentsList[ii].m_IsNew ) // Not already with an updated reference
continue; continue;
if( ItemToTest->m_NumRef != NumRef ) // Not the same reference number (like 35 in R35) if( aComponentsList[ii].m_NumRef != NumRef ) // Not the same reference number (like 35 in R35)
continue; continue;
if( strnicmp( RefText, ItemToTest->m_TextRef, 32 ) != 0 ) // Not the same reference prefix if( aComponentsList[aObjet].CompareRef( aComponentsList[ii] ) != 0 ) // Not the same reference prefix
continue; continue;
if( ItemToTest->m_Unit == Unit ) // A part with the same reference and the given unit is found if( aComponentsList[ii].m_Unit == Unit ) // A part with the same reference and the given unit is found
{ {
return ii; return ii;
} }
...@@ -659,109 +589,87 @@ static int ExistUnit( CmpListStruct* Objet, int Unit, ...@@ -659,109 +589,87 @@ static int ExistUnit( CmpListStruct* Objet, int Unit,
} }
/***************************************************************************** /*******************************************************************/
*
* Function CheckAnnotate
* @return component count ( which are not annotated or have the same
* reference (duplicates))
* @param oneSheetOnly : true = search is made only in the current sheet
* false = search in whole hierarchy (usual search).
*
*****************************************************************************/
int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly ) int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
/*******************************************************************/
/**
* Function CheckAnnotate
* @return component count ( which are not annotated or have the same reference (duplicates))
* @param oneSheetOnly : true = search is made only in the current sheet
* false = search in whole hierarchy (usual search).
*/
{ {
int ii, error, NbOfCmp; int error;
DrawSheetPath* sheet; wxString Buff;
CmpListStruct* ListeCmp = NULL; wxString msg, cmpref;
wxString Buff;
wxString msg, cmpref;
/* build the screen list */ /* build the screen list */
EDA_SheetList SheetList( NULL ); EDA_SheetList SheetList( NULL );
g_RootSheet->m_AssociatedScreen->SetModify(); std::vector <OBJ_CMP_TO_LIST> ComponentsList;
ii = 0;
/* first pass : count composents */ g_RootSheet->m_AssociatedScreen->SetModify();
if( !oneSheetOnly )
{
NbOfCmp = 0;
for( sheet = SheetList.GetFirst();
sheet != NULL;
sheet = SheetList.GetNext() )
NbOfCmp += ListeComposants( NULL, sheet );
}
else
NbOfCmp = ListeComposants( NULL, frame->GetSheet() );
if( NbOfCmp == 0 )
{
return 0;
}
/* Second pass : create the list of components */
ListeCmp = (CmpListStruct*) MyZMalloc( NbOfCmp * sizeof(CmpListStruct) );
/* Build the list of components */
if( !oneSheetOnly ) if( !oneSheetOnly )
{ {
ii = 0; DrawSheetPath* sheet;
for( sheet = SheetList.GetFirst(); for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
sheet != NULL; AddComponentsInSheetToList( ComponentsList, sheet );
sheet = SheetList.GetNext() )
ii += ListeComposants( ListeCmp + ii, sheet );
} }
else else
ListeComposants( ListeCmp, frame->GetSheet() ); AddComponentsInSheetToList( ComponentsList, frame->GetSheet() );
qsort( ListeCmp, NbOfCmp, sizeof(CmpListStruct), AnnotateByValue ); sort( ComponentsList.begin(), ComponentsList.end(), AnnotateByValue );
/* Break full components reference in name (prefix) and number: example: /* Break full components reference in name (prefix) and number: example:
* IC1 become IC, and 1 */ * IC1 become IC, and 1 */
BreakReference( ListeCmp, NbOfCmp ); BreakReference( ComponentsList );
/* count not yet annotated items */ /* count not yet annotated items */
error = 0; error = 0;
for( ii = 0; ii < NbOfCmp - 1; ii++ ) int imax = ComponentsList.size() - 1;
for( int ii = 0; ii < imax; ii++ )
{ {
msg.Empty(); msg.Empty();
Buff.Empty(); Buff.Empty();
if( ListeCmp[ii].m_IsNew ) if( ComponentsList[ii].m_IsNew )
{ {
if( ListeCmp[ii].m_NumRef >= 0 ) if( ComponentsList[ii].m_NumRef >= 0 )
Buff << ListeCmp[ii].m_NumRef; Buff << ComponentsList[ii].m_NumRef;
else else
Buff = wxT( "?" ); Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ListeCmp[ii].m_TextRef ); cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference );
msg.Printf( _( "item not annotated: %s%s" ), msg.Printf( _( "item not annotated: %s%s" ),
cmpref.GetData(), Buff.GetData() ); cmpref.GetData(), Buff.GetData() );
if( (ListeCmp[ii].m_Unit > 0) && (ListeCmp[ii].m_Unit < 0x7FFFFFFF) ) if( (ComponentsList[ii].m_Unit > 0) && (ComponentsList[ii].m_Unit < 0x7FFFFFFF) )
{ {
Buff.Printf( _( "( unit %d)" ), ListeCmp[ii].m_Unit ); Buff.Printf( _( "( unit %d)" ), ComponentsList[ii].m_Unit );
msg << Buff; msg << Buff;
} }
DisplayError( NULL, msg ); DisplayError( frame, msg );
error++; error++;
break; break;
} }
// Annotate error // Annotate error
if( MAX( ListeCmp[ii].m_NbParts, 1 ) < ListeCmp[ii].m_Unit ) if( MAX( ComponentsList[ii].m_Entry->m_UnitCount, 1 ) < ComponentsList[ii].m_Unit )
{ {
if( ListeCmp[ii].m_NumRef >= 0 ) if( ComponentsList[ii].m_NumRef >= 0 )
Buff << ListeCmp[ii].m_NumRef; Buff << ComponentsList[ii].m_NumRef;
else else
Buff = wxT( "?" ); Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ListeCmp[ii].m_TextRef ); cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference );
msg.Printf( _( "Error item %s%s" ), cmpref.GetData(), msg.Printf( _( "Error item %s%s" ), cmpref.GetData(),
Buff.GetData() ); Buff.GetData() );
Buff.Printf( _( " unit %d and no more than %d parts" ), Buff.Printf( _( " unit %d and no more than %d parts" ),
ListeCmp[ii].m_Unit, ListeCmp[ii].m_NbParts ); ComponentsList[ii].m_Unit, ComponentsList[ii].m_Entry->m_UnitCount );
msg << Buff; msg << Buff;
DisplayError( frame, msg ); DisplayError( frame, msg );
error++; error++;
...@@ -773,33 +681,31 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly ) ...@@ -773,33 +681,31 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
return error; return error;
// count the duplicated elements (if all are annotated) // count the duplicated elements (if all are annotated)
for( ii = 0; (ii < NbOfCmp - 1) && (error < 4); ii++ ) for( int ii = 0; (ii < imax) && (error < 4); ii++ )
{ {
msg.Empty(); msg.Empty();
Buff.Empty(); Buff.Empty();
if( (stricmp( ListeCmp[ii].m_TextRef, if( (ComponentsList[ii].CompareRef(ComponentsList[ii + 1]) != 0)
ListeCmp[ii + 1].m_TextRef ) != 0) || ( ComponentsList[ii].m_NumRef != ComponentsList[ii + 1].m_NumRef ) )
|| ( ListeCmp[ii].m_NumRef != ListeCmp[ii + 1].m_NumRef ) )
continue; continue;
/* Same reference found */ /* Same reference found. If same unit, error !
*/
/* If same unit, error ! */ if( ComponentsList[ii].m_Unit == ComponentsList[ii + 1].m_Unit )
if( ListeCmp[ii].m_Unit == ListeCmp[ii + 1].m_Unit )
{ {
if( ListeCmp[ii].m_NumRef >= 0 ) if( ComponentsList[ii].m_NumRef >= 0 )
Buff << ListeCmp[ii].m_NumRef; Buff << ComponentsList[ii].m_NumRef;
else else
Buff = wxT( "?" ); Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ListeCmp[ii].m_TextRef ); cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference );
msg.Printf( _( "Multiple item %s%s" ), msg.Printf( _( "Multiple item %s%s" ),
cmpref.GetData(), Buff.GetData() ); cmpref.GetData(), Buff.GetData() );
if( (ListeCmp[ii].m_Unit > 0) && (ListeCmp[ii].m_Unit < 0x7FFFFFFF) ) if( (ComponentsList[ii].m_Unit > 0) && (ComponentsList[ii].m_Unit < 0x7FFFFFFF) )
{ {
Buff.Printf( _( " (unit %d)" ), ListeCmp[ii].m_Unit ); Buff.Printf( _( " (unit %d)" ), ComponentsList[ii].m_Unit );
msg << Buff; msg << Buff;
} }
DisplayError( frame, msg ); DisplayError( frame, msg );
...@@ -808,21 +714,21 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly ) ...@@ -808,21 +714,21 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
} }
/* Test error if units are different but number of parts per package /* Test error if units are different but number of parts per package
* too hight (ex U3 ( 1 part) and we find U3B the is an error) */ * too hight (ex U3 ( 1 part) and we find U3B this is an error) */
if( ListeCmp[ii].m_NbParts != ListeCmp[ii + 1].m_NbParts ) if( ComponentsList[ii].m_Entry->m_UnitCount != ComponentsList[ii + 1].m_Entry->m_UnitCount )
{ {
if( ListeCmp[ii].m_NumRef >= 0 ) if( ComponentsList[ii].m_NumRef >= 0 )
Buff << ListeCmp[ii].m_NumRef; Buff << ComponentsList[ii].m_NumRef;
else else
Buff = wxT( "?" ); Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ListeCmp[ii].m_TextRef ); cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference );
msg.Printf( _( "Multiple item %s%s" ), msg.Printf( _( "Multiple item %s%s" ),
cmpref.GetData(), Buff.GetData() ); cmpref.GetData(), Buff.GetData() );
if( (ListeCmp[ii].m_Unit > 0) && (ListeCmp[ii].m_Unit < 0x7FFFFFFF) ) if( (ComponentsList[ii].m_Unit > 0) && (ComponentsList[ii].m_Unit < 0x7FFFFFFF) )
{ {
Buff.Printf( _( " (unit %d)" ), ListeCmp[ii].m_Unit ); Buff.Printf( _( " (unit %d)" ), ComponentsList[ii].m_Unit );
msg << Buff; msg << Buff;
} }
...@@ -831,32 +737,30 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly ) ...@@ -831,32 +737,30 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
} }
/* Error if values are different between units, for the same reference */ /* Error if values are different between units, for the same reference */
if( stricmp( ListeCmp[ii].m_TextValue, int next = ii+1;
ListeCmp[ii + 1].m_TextValue ) != 0 ) if( ComponentsList[ii].CompareValue( ComponentsList[next] ) != 0 )
{ {
wxString nextcmpref, cmpvalue, nextcmpvalue; wxString nextcmpref;
cmpref = CONV_FROM_UTF8( ListeCmp[ii].m_TextRef ); cmpref = CONV_FROM_UTF8( ComponentsList[ii].m_Reference );
nextcmpref = CONV_FROM_UTF8( ListeCmp[ii + 1].m_TextRef ); nextcmpref = CONV_FROM_UTF8( ComponentsList[next].m_Reference );
cmpvalue = CONV_FROM_UTF8( ListeCmp[ii].m_TextValue ); #if defined (KICAD_GOST)
nextcmpvalue = CONV_FROM_UTF8( ListeCmp[ii + 1].m_TextValue );
#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(),
ListeCmp[ii].m_NumRef, ComponentsList[ii].m_NumRef,
ListeCmp[ii].m_Unit + '1' - 1, ComponentsList[ii].m_Unit + '1' - 1,
cmpvalue.GetData(), nextcmpref.GetData(), ComponentsList[ii].m_Value->GetData(), nextcmpref.GetData(),
ListeCmp[ii + 1].m_NumRef, ComponentsList[next].m_NumRef,
ListeCmp[ii + 1].m_Unit + '1' - 1, ComponentsList[next].m_Unit + '1' - 1,
nextcmpvalue.GetData() ); ComponentsList[next].m_Value->GetData() );
#else #else
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(),
ListeCmp[ii].m_NumRef, ComponentsList[ii].m_NumRef,
ListeCmp[ii].m_Unit + 'A' - 1, ComponentsList[ii].m_Unit + 'A' - 1,
cmpvalue.GetData(), nextcmpref.GetData(), ComponentsList[ii].m_Value->GetData(), nextcmpref.GetData(),
ListeCmp[ii + 1].m_NumRef, ComponentsList[next].m_NumRef,
ListeCmp[ii + 1].m_Unit + 'A' - 1, ComponentsList[next].m_Unit + 'A' - 1,
nextcmpvalue.GetData() ); ComponentsList[next].m_Value->GetData() );
#endif #endif
DisplayError( frame, msg ); DisplayError( frame, msg );
...@@ -864,6 +768,5 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly ) ...@@ -864,6 +768,5 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
} }
} }
MyFree( ListeCmp );
return error; return error;
} }
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
// Licence: GPL license // Licence: GPL license
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#include <algorithm> // to use sort vector
#include <vector>
#include "fctsys.h" #include "fctsys.h"
...@@ -19,23 +22,43 @@ ...@@ -19,23 +22,43 @@
#include "protos.h" #include "protos.h"
/* object used in build BOM to handle the list of labels in schematic
* 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
*/
class LABEL_OBJECT
{
public:
int m_LabelType;
SCH_ITEM* m_Label;
//have to store it here since the object references will be duplicated.
DrawSheetPath m_SheetPath; //composed of UIDs
public:
LABEL_OBJECT()
{
m_Label = NULL;
m_LabelType = 0;
}
};
// Filename extension for BOM list // Filename extension for BOM list
#define EXT_LIST wxT( ".lst" ) #define EXT_LIST wxT( ".lst" )
// Exported functions // Exported functions
int BuildComponentsListFromSchematic( ListComponent* aList ); int BuildComponentsListFromSchematic( OBJ_CMP_TO_LIST * aList );
/* fonctions locales */ /* fonctions locales */
static int GenListeGLabels( ListLabel* aList ); static int GenListeGLabels( std::vector <LABEL_OBJECT>& aList );
static int ListTriComposantByRef( ListComponent* obj1, static int ListTriComposantByRef( OBJ_CMP_TO_LIST* obj1, OBJ_CMP_TO_LIST* obj2 );
ListComponent* obj2 ); static int ListTriComposantByVal( OBJ_CMP_TO_LIST* obj1, OBJ_CMP_TO_LIST* obj2 );
static int ListTriComposantByVal( ListComponent* obj1, static bool SortLabelsByValue( const LABEL_OBJECT& obj1, const LABEL_OBJECT& obj2 );
ListComponent* obj2 ); static bool SortLabelsBySheet( const LABEL_OBJECT& obj1, const LABEL_OBJECT& obj2 );
static int ListTriGLabelBySheet( ListLabel* obj1, ListLabel* obj2 ); static void DeleteSubCmp( OBJ_CMP_TO_LIST* aList, int aItemCount );
static int ListTriGLabelByVal( ListLabel* obj1, ListLabel* obj2 );
static void DeleteSubCmp( ListComponent* aList, int aItemCount );
static int PrintListeGLabel( FILE* f, ListLabel* aList, int aItemCount ); static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList );
int RefDesStringCompare( char* obj1, char* obj2 ); int RefDesStringCompare( char* obj1, char* obj2 );
int SplitString( wxString strToSplit, int SplitString( wxString strToSplit,
...@@ -69,14 +92,14 @@ void WinEDA_Build_BOM_Frame::Create_BOM_Lists( bool aTypeFileIsExport, ...@@ -69,14 +92,14 @@ void WinEDA_Build_BOM_Frame::Create_BOM_Lists( bool aTypeFileIsExport,
mask += EXT_LIST; mask += EXT_LIST;
filename = EDA_FileSelector( _( "Bill of materials:" ), filename = EDA_FileSelector( _( "Bill of materials:" ),
wxEmptyString, /* Chemin par defaut (ici dir courante) */ wxEmptyString, /* Chemin par defaut (ici dir courante) */
m_ListFileName, /* nom fichier par defaut, et resultat */ m_ListFileName, /* nom fichier par defaut, et resultat */
EXT_LIST, /* extension par defaut */ EXT_LIST, /* extension par defaut */
mask, /* Masque d'affichage */ mask, /* Masque d'affichage */
this, this,
wxFD_SAVE, wxFD_SAVE,
TRUE TRUE
); );
if( filename.IsEmpty() ) if( filename.IsEmpty() )
return; return;
else else
...@@ -112,7 +135,7 @@ void WinEDA_Build_BOM_Frame::CreateExportList( const wxString& aFullFileName, ...@@ -112,7 +135,7 @@ void WinEDA_Build_BOM_Frame::CreateExportList( const wxString& aFullFileName,
*/ */
{ {
FILE* f; FILE* f;
ListComponent* aList; OBJ_CMP_TO_LIST* aList;
int itemCount; int itemCount;
wxString msg; wxString msg;
...@@ -128,7 +151,7 @@ void WinEDA_Build_BOM_Frame::CreateExportList( const wxString& aFullFileName, ...@@ -128,7 +151,7 @@ void WinEDA_Build_BOM_Frame::CreateExportList( const wxString& aFullFileName,
itemCount = BuildComponentsListFromSchematic( NULL ); itemCount = BuildComponentsListFromSchematic( NULL );
if( itemCount ) if( itemCount )
{ {
aList = (ListComponent*) MyZMalloc( itemCount * sizeof(ListComponent) ); aList = (OBJ_CMP_TO_LIST*) MyZMalloc( itemCount * sizeof(OBJ_CMP_TO_LIST) );
if( aList == NULL ) if( aList == NULL )
{ {
fclose( f ); fclose( f );
...@@ -138,8 +161,8 @@ void WinEDA_Build_BOM_Frame::CreateExportList( const wxString& aFullFileName, ...@@ -138,8 +161,8 @@ void WinEDA_Build_BOM_Frame::CreateExportList( const wxString& aFullFileName,
BuildComponentsListFromSchematic( aList ); BuildComponentsListFromSchematic( aList );
/* sort component list */ /* sort component list */
qsort( aList, itemCount, sizeof( ListComponent ), qsort( aList, itemCount, sizeof( OBJ_CMP_TO_LIST ),
( int( * ) ( const void*, const void* ) )ListTriComposantByRef ); ( int( * ) ( const void*, const void* ) )ListTriComposantByRef );
if( !aIncludeSubComponents ) if( !aIncludeSubComponents )
DeleteSubCmp( aList, itemCount ); DeleteSubCmp( aList, itemCount );
...@@ -159,19 +182,17 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& aFullFileName, ...@@ -159,19 +182,17 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& aFullFileName,
bool aIncludeSubComponents ) bool aIncludeSubComponents )
/****************************************************************************/ /****************************************************************************/
/* /** GenereListeOfItems()
* Routine principale pour la creation des listings ( composants et/ou labels * Main function to create the list of components and/or labels
* globaux et "sheet labels" ) * (global labels and pin sheets" )
*/ */
{ {
FILE* f; FILE* f;
ListComponent* list; OBJ_CMP_TO_LIST* list;
ListLabel* listOfLabels;
int itemCount; int itemCount;
char Line[1024]; char Line[1024];
wxString msg; wxString msg;
/* Creation de la liste des elements */
if( ( f = wxFopen( aFullFileName, wxT( "wt" ) ) ) == NULL ) if( ( f = wxFopen( aFullFileName, wxT( "wt" ) ) ) == NULL )
{ {
msg = _( "Failed to open file " ); msg = _( "Failed to open file " );
...@@ -183,7 +204,7 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& aFullFileName, ...@@ -183,7 +204,7 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& aFullFileName,
itemCount = BuildComponentsListFromSchematic( NULL ); itemCount = BuildComponentsListFromSchematic( NULL );
if( itemCount ) if( itemCount )
{ {
list = (ListComponent*) MyZMalloc( itemCount * sizeof(ListComponent) ); list = (OBJ_CMP_TO_LIST*) MyZMalloc( itemCount * sizeof(OBJ_CMP_TO_LIST) );
if( list == NULL ) // Error memory alloc if( list == NULL ) // Error memory alloc
{ {
fclose( f ); fclose( f );
...@@ -199,71 +220,53 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& aFullFileName, ...@@ -199,71 +220,53 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& aFullFileName,
/* Tri et impression de la liste des composants */ /* Tri et impression de la liste des composants */
qsort( list, itemCount, sizeof( ListComponent ), qsort( list, itemCount, sizeof( OBJ_CMP_TO_LIST ),
( int( * ) ( const void*, const void* ) )ListTriComposantByRef ); ( int( * ) ( const void*, const void* ) )ListTriComposantByRef );
if( !aIncludeSubComponents ) if( !aIncludeSubComponents )
DeleteSubCmp( list, itemCount ); DeleteSubCmp( list, itemCount );
// if( s_ListByRef )
if( m_ListCmpbyRefItems->GetValue() ) if( m_ListCmpbyRefItems->GetValue() )
{ {
PrintComponentsListByRef( f, list, itemCount, false, aIncludeSubComponents ); PrintComponentsListByRef( f, list, itemCount, false, aIncludeSubComponents );
} }
// if( s_ListByValue )
if( m_ListCmpbyValItems->GetValue() ) if( m_ListCmpbyValItems->GetValue() )
{ {
qsort( list, itemCount, sizeof( ListComponent ), qsort( list, itemCount, sizeof( OBJ_CMP_TO_LIST ),
( int( * ) ( const void*, const void* ) )ListTriComposantByVal ); ( int( * ) ( const void*, const void* ) )ListTriComposantByVal );
PrintComponentsListByVal( f, list, itemCount, aIncludeSubComponents ); PrintComponentsListByVal( f, list, itemCount, aIncludeSubComponents );
} }
MyFree( list ); MyFree( list );
} }
/***************************************/ /*************************************************/
/* Generation liste des Labels globaux */ /* Create list of global labels and pins sheets */
/***************************************/ /*************************************************/
itemCount = GenListeGLabels( NULL ); std::vector <LABEL_OBJECT> listOfLabels;
if( itemCount ) GenListeGLabels( listOfLabels );
if( ( itemCount = listOfLabels.size() ) > 0 )
{ {
listOfLabels = (ListLabel*) MyZMalloc( itemCount * sizeof(ListLabel) );
if( listOfLabels == NULL )
{
fclose( f );
return;
}
GenListeGLabels( listOfLabels );
/* Tri de la liste */
// if( s_ListBySheet )
if( m_GenListLabelsbySheet->GetValue() ) if( m_GenListLabelsbySheet->GetValue() )
{ {
qsort( listOfLabels, itemCount, sizeof( ListLabel ), sort( listOfLabels.begin(), listOfLabels.end(), SortLabelsBySheet );
( int( * ) ( const void*, const void* ) )ListTriGLabelBySheet );
msg.Printf( _( msg.Printf( _(
"\n#Global, Hierarchical Labels and PinSheets ( order = Sheet Number ) count = %d\n" ), "\n#Global, Hierarchical Labels and PinSheets ( 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, itemCount ); PrintListeGLabel( f, listOfLabels );
} }
// if( s_ListHierarchicalPinByName )
if( m_GenListLabelsbyVal->GetValue() ) if( m_GenListLabelsbyVal->GetValue() )
{ {
qsort( listOfLabels, itemCount, sizeof( ListLabel ), sort( listOfLabels.begin(), listOfLabels.end(), SortLabelsByValue );
( int( * ) ( const void*, const void* ) )ListTriGLabelByVal );
msg.Printf( _( msg.Printf( _(
"\n#Global, Hierarchical Labels and PinSheets ( order = Alphab. ) count = %d\n\n" ), "\n#Global, Hierarchical Labels and PinSheets ( 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, itemCount ); PrintListeGLabel( f, listOfLabels );
} }
MyFree( listOfLabels );
} }
msg = _( "\n#End List\n" ); msg = _( "\n#End List\n" );
...@@ -273,7 +276,7 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& aFullFileName, ...@@ -273,7 +276,7 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& aFullFileName,
/*********************************************************/ /*********************************************************/
int BuildComponentsListFromSchematic( ListComponent* aList ) int BuildComponentsListFromSchematic( OBJ_CMP_TO_LIST* aList )
/*********************************************************/ /*********************************************************/
/* Creates the list of components found in the whole schematic /* Creates the list of components found in the whole schematic
...@@ -281,7 +284,7 @@ int BuildComponentsListFromSchematic( ListComponent* aList ) ...@@ -281,7 +284,7 @@ int BuildComponentsListFromSchematic( ListComponent* aList )
* if List == null, just returns the count. if not, fills the list. * 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 Initialise m_Father as pointer pointeur of the SCH_SCREN parent * Also Initialise m_Father as pointerof the SCH_SCREN parent
*/ */
{ {
int itemCount = 0; int itemCount = 0;
...@@ -304,16 +307,16 @@ int BuildComponentsListFromSchematic( ListComponent* aList ) ...@@ -304,16 +307,16 @@ int BuildComponentsListFromSchematic( ListComponent* aList )
DrawLibItem->SetParent( sheet->LastScreen() ); DrawLibItem->SetParent( sheet->LastScreen() );
if( aList ) if( aList )
{ {
aList->m_Comp = DrawLibItem; aList->m_RootCmp = DrawLibItem;
aList->m_SheetList = *sheet; aList->m_SheetPath = *sheet;
aList->m_Unit = DrawLibItem->GetUnitSelection( sheet ); aList->m_Unit = DrawLibItem->GetUnitSelection( sheet );
strncpy( aList->m_Ref, strncpy( aList->m_Reference,
CONV_TO_UTF8( DrawLibItem->GetRef( sheet ) ), CONV_TO_UTF8( DrawLibItem->GetRef( sheet ) ),
sizeof( aList->m_Ref ) ); sizeof( aList->m_Reference ) );
// Ensure always nul terminate m_Ref. // Ensure always nul terminate m_Ref.
aList->m_Ref[sizeof( aList->m_Ref ) - 1 ] = 0; aList->m_Reference[sizeof( aList->m_Reference ) - 1 ] = 0;
aList++; aList++;
} }
} }
...@@ -323,27 +326,26 @@ int BuildComponentsListFromSchematic( ListComponent* aList ) ...@@ -323,27 +326,26 @@ int BuildComponentsListFromSchematic( ListComponent* aList )
} }
/*********************************************/ /****************************************************************/
static int GenListeGLabels( ListLabel* list ) static int GenListeGLabels( std::vector <LABEL_OBJECT>& aList )
/*********************************************/ /****************************************************************/
/* Count the Glabels, or fill the list Listwith Glabel pointers /* Fill aList with Glabel info
* If List == NULL: Item count only
* Else fill list of Glabels
*/ */
{ {
int itemCount = 0; int itemCount = 0;
EDA_BaseStruct* DrawList; SCH_ITEM* DrawList;
Hierarchical_PIN_Sheet_Struct* SheetLabel; Hierarchical_PIN_Sheet_Struct* PinLabel;
DrawSheetPath* sheet; DrawSheetPath* sheet;
/* Build the screen list */ /* Build the screen list */
EDA_SheetList SheetList( NULL ); EDA_SheetList SheetList( NULL );
LABEL_OBJECT labet_object;
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{ {
DrawList = sheet->LastDrawList(); DrawList = (SCH_ITEM*) sheet->LastDrawList();
wxString path = sheet->PathHumanReadable();
while( DrawList ) while( DrawList )
{ {
switch( DrawList->Type() ) switch( DrawList->Type() )
...@@ -351,35 +353,26 @@ static int GenListeGLabels( ListLabel* list ) ...@@ -351,35 +353,26 @@ static int GenListeGLabels( ListLabel* list )
case TYPE_SCH_HIERLABEL: case TYPE_SCH_HIERLABEL:
case TYPE_SCH_GLOBALLABEL: case TYPE_SCH_GLOBALLABEL:
itemCount++; itemCount++;
if( list ) labet_object.m_LabelType = DrawList->Type();
{ labet_object.m_SheetPath = *sheet;
list->m_LabelType = DrawList->Type(); labet_object.m_Label = DrawList;
snprintf( list->m_SheetPath, sizeof(list->m_SheetPath), aList.push_back( labet_object );
"%s", CONV_TO_UTF8( path ) );
list->m_Label = DrawList;
list++;
}
break; break;
case DRAW_SHEET_STRUCT_TYPE: case DRAW_SHEET_STRUCT_TYPE:
{
PinLabel = ( (DrawSheetStruct*) DrawList )->m_Label;
while( PinLabel != NULL )
{ {
#define Sheet ( (DrawSheetStruct*) DrawList ) itemCount++;
SheetLabel = Sheet->m_Label; labet_object.m_LabelType = DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE;
while( SheetLabel != NULL ) labet_object.m_SheetPath = *sheet;
{ labet_object.m_Label = PinLabel;
if( list ) aList.push_back( labet_object );
{ PinLabel = PinLabel->Next();
list->m_LabelType = DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE;
snprintf( list->m_SheetPath, sizeof(list->m_SheetPath),
"%s", CONV_TO_UTF8( path ) );
list->m_Label = SheetLabel;
list++;
}
itemCount++;
SheetLabel = SheetLabel->Next();
}
} }
break; }
break;
default: default:
break; break;
...@@ -393,8 +386,7 @@ static int GenListeGLabels( ListLabel* list ) ...@@ -393,8 +386,7 @@ static int GenListeGLabels( ListLabel* list )
/**********************************************************/ /**********************************************************/
static int ListTriComposantByVal( ListComponent* obj1, static int ListTriComposantByVal( OBJ_CMP_TO_LIST* obj1, OBJ_CMP_TO_LIST* obj2 )
ListComponent* obj2 )
/**********************************************************/ /**********************************************************/
/* Routine de comparaison pour le tri du Tableau par qsort() /* Routine de comparaison pour le tri du Tableau par qsort()
...@@ -413,20 +405,20 @@ static int ListTriComposantByVal( ListComponent* obj1, ...@@ -413,20 +405,20 @@ static int ListTriComposantByVal( ListComponent* obj1,
return -1; return -1;
if( obj2 == NULL ) if( obj2 == NULL )
return 1; return 1;
if( ( obj1->m_Comp == NULL ) && ( obj2->m_Comp == NULL ) ) if( ( obj1->m_RootCmp == NULL ) && ( obj2->m_RootCmp == NULL ) )
return 0; return 0;
if( obj1->m_Comp == NULL ) if( obj1->m_RootCmp == NULL )
return -1; return -1;
if( obj2->m_Comp == NULL ) if( obj2->m_RootCmp == NULL )
return 1; return 1;
Text1 = &(obj1->m_Comp->GetField(VALUE)->m_Text); Text1 = &(obj1->m_RootCmp->GetField( VALUE )->m_Text);
Text2 = &(obj2->m_Comp->GetField(VALUE)->m_Text); Text2 = &(obj2->m_RootCmp->GetField( VALUE )->m_Text);
ii = Text1->CmpNoCase( *Text2 ); ii = Text1->CmpNoCase( *Text2 );
if( ii == 0 ) if( ii == 0 )
{ {
ii = RefDesStringCompare( obj1->m_Ref, obj2->m_Ref ); ii = RefDesStringCompare( obj1->m_Reference, obj2->m_Reference );
} }
if( ii == 0 ) if( ii == 0 )
...@@ -438,12 +430,11 @@ static int ListTriComposantByVal( ListComponent* obj1, ...@@ -438,12 +430,11 @@ static int ListTriComposantByVal( ListComponent* obj1,
} }
/**********************************************************/ /*******************************************************************/
static int ListTriComposantByRef( ListComponent* obj1, int ListTriComposantByRef( OBJ_CMP_TO_LIST* obj1, OBJ_CMP_TO_LIST* obj2 )
ListComponent* obj2 ) /*******************************************************************/
/**********************************************************/
/* Routine de comparaison pour le tri du Tableau par qsort() /* compare function for sorting
* Les composants sont tries * Les composants sont tries
* par reference * par reference
* si meme referenece: par valeur * si meme referenece: par valeur
...@@ -460,19 +451,19 @@ static int ListTriComposantByRef( ListComponent* obj1, ...@@ -460,19 +451,19 @@ static int ListTriComposantByRef( ListComponent* obj1,
if( obj2 == NULL ) if( obj2 == NULL )
return 1; return 1;
if( ( obj1->m_Comp == NULL ) && ( obj2->m_Comp == NULL ) ) if( ( obj1->m_RootCmp == NULL ) && ( obj2->m_RootCmp == NULL ) )
return 0; return 0;
if( obj1->m_Comp == NULL ) if( obj1->m_RootCmp == NULL )
return -1; return -1;
if( obj2->m_Comp == NULL ) if( obj2->m_RootCmp == NULL )
return 1; return 1;
ii = RefDesStringCompare( obj1->m_Ref, obj2->m_Ref ); ii = RefDesStringCompare( obj1->m_Reference, obj2->m_Reference );
if( ii == 0 ) if( ii == 0 )
{ {
Text1 = &( obj1->m_Comp->GetField(VALUE)->m_Text ); Text1 = &( obj1->m_RootCmp->GetField( VALUE )->m_Text );
Text2 = &( obj2->m_Comp->GetField(VALUE)->m_Text ); Text2 = &( obj2->m_RootCmp->GetField( VALUE )->m_Text );
ii = Text1->CmpNoCase( *Text2 ); ii = Text1->CmpNoCase( *Text2 );
} }
...@@ -486,76 +477,75 @@ static int ListTriComposantByRef( ListComponent* obj1, ...@@ -486,76 +477,75 @@ static int ListTriComposantByRef( ListComponent* obj1,
/******************************************************************/ /******************************************************************/
static int ListTriGLabelByVal( ListLabel* obj1, ListLabel* obj2 ) bool SortLabelsByValue( const LABEL_OBJECT& obj1, const LABEL_OBJECT& obj2 )
/*******************************************************************/ /*******************************************************************/
/* Routine de comparaison pour le tri du Tableau par qsort() /* compare function for sorting labels
* Les labels sont tries * sort by
* par comparaison ascii * value
* si meme valeur: par numero de sheet * if same value: by sheet
*/ */
{ {
int ii; int ii;
const wxString* Text1, * Text2; wxString *Text1, *Text2;
if( obj1->m_LabelType == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE ) if( obj1.m_LabelType == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE )
Text1 = &( (Hierarchical_PIN_Sheet_Struct*) obj1->m_Label )->m_Text; Text1 = &( (Hierarchical_PIN_Sheet_Struct*) (obj1.m_Label) )->m_Text;
else else
Text1 = &( (SCH_TEXT*) obj1->m_Label )->m_Text; Text1 = &( (SCH_TEXT*) (obj1.m_Label) )->m_Text;
if( obj2->m_LabelType == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE ) if( obj2.m_LabelType == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE )
Text2 = &( (Hierarchical_PIN_Sheet_Struct*) obj2->m_Label )->m_Text; Text2 = &( (Hierarchical_PIN_Sheet_Struct*) (obj2.m_Label) )->m_Text;
else else
Text2 = &( (SCH_TEXT*) obj2->m_Label )->m_Text; Text2 = &( (SCH_TEXT*) (obj2.m_Label) )->m_Text;
ii = Text1->CmpNoCase( *Text2 ); ii = Text1->CmpNoCase( *Text2 );
if( ii == 0 ) if( ii == 0 )
{ {
ii = strcmp( obj1->m_SheetPath, obj2->m_SheetPath ); ii = obj1.m_SheetPath.Cmp( obj2.m_SheetPath );
} }
return ii; return ii < 0;
} }
/*******************************************************************/ /*************************************************************************************/
static int ListTriGLabelBySheet( ListLabel* obj1, ListLabel* obj2 ) bool SortLabelsBySheet( const LABEL_OBJECT& obj1, const LABEL_OBJECT& obj2 )
/*******************************************************************/ /*************************************************************************************/
/* Routine de comparaison pour le tri du Tableau par qsort() /* compare function for sorting labels
* Les labels sont tries * by sheet
* par sheet number * in a sheet, by alphabetic order
* si meme valeur, par ordre alphabetique
*/ */
{ {
int ii; int ii;
const wxString* Text1, * Text2; wxString Text1, Text2;
ii = strcmp( obj1->m_SheetPath, obj2->m_SheetPath ); ii = obj1.m_SheetPath.Cmp( obj2.m_SheetPath );
if( ii == 0 ) if( ii == 0 )
{ {
if( obj1->m_LabelType == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE ) if( obj1.m_LabelType == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE )
Text1 = &( (Hierarchical_PIN_Sheet_Struct*) obj1->m_Label )->m_Text; Text1 = ( (Hierarchical_PIN_Sheet_Struct*) obj1.m_Label )->m_Text;
else else
Text1 = &( (SCH_TEXT*) obj1->m_Label )->m_Text; Text1 = ( (SCH_TEXT*) obj1.m_Label )->m_Text;
if( obj2->m_LabelType == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE ) if( obj2.m_LabelType == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE )
Text2 = &( (Hierarchical_PIN_Sheet_Struct*) obj2->m_Label )->m_Text; Text2 = ( (Hierarchical_PIN_Sheet_Struct*) obj2.m_Label )->m_Text;
else else
Text2 = &( (SCH_TEXT*) obj2->m_Label )->m_Text; Text2 = ( (SCH_TEXT*) obj2.m_Label )->m_Text;
ii = Text1->CmpNoCase( *Text2 ); ii = Text1.CmpNoCase( Text2 );
} }
return ii; return ii < 0;
} }
/**************************************************************/ /**************************************************************/
static void DeleteSubCmp( ListComponent* aList, int aItemCount ) static void DeleteSubCmp( OBJ_CMP_TO_LIST* aList, int aItemCount )
/**************************************************************/ /**************************************************************/
/* Remove sub components from the list, when multiples parts per package are found in this list /* Remove sub components from the list, when multiples parts per package are found in this list
...@@ -569,19 +559,19 @@ static void DeleteSubCmp( ListComponent* aList, int aItemCount ) ...@@ -569,19 +559,19 @@ static void DeleteSubCmp( ListComponent* aList, int aItemCount )
for( int ii = 0; ii < aItemCount; ii++ ) for( int ii = 0; ii < aItemCount; ii++ )
{ {
libItem = aList[ii].m_Comp; libItem = aList[ii].m_RootCmp;
if( libItem == NULL ) if( libItem == NULL )
continue; continue;
currName = CONV_FROM_UTF8( aList[ii].m_Ref ); currName = CONV_FROM_UTF8( aList[ii].m_Reference );
if( !oldName.IsEmpty() ) if( !oldName.IsEmpty() )
{ {
if( oldName == currName ) // currName is a subpart of oldName: remove it if( oldName == currName ) // currName is a subpart of oldName: remove it
{ {
aList[ii].m_Comp = NULL; aList[ii].m_RootCmp = NULL;
aList[ii].m_SheetList.Clear(); aList[ii].m_SheetPath.Clear();
aList[ii].m_Ref[0] = 0; aList[ii].m_Reference[0] = 0;
} }
} }
oldName = currName; oldName = currName;
...@@ -614,10 +604,10 @@ void WinEDA_Build_BOM_Frame::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem ...@@ -614,10 +604,10 @@ void WinEDA_Build_BOM_Frame::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem
if( CompactForm ) if( CompactForm )
{ {
fprintf( f, "%c%s", s_ExportSeparatorSymbol, fprintf( f, "%c%s", s_ExportSeparatorSymbol,
CONV_TO_UTF8( DrawLibItem->GetField(FOOTPRINT)->m_Text ) ); CONV_TO_UTF8( DrawLibItem->GetField( FOOTPRINT )->m_Text ) );
} }
else else
fprintf( f, "; %-12s", CONV_TO_UTF8( DrawLibItem->GetField(FOOTPRINT)->m_Text ) ); fprintf( f, "; %-12s", CONV_TO_UTF8( DrawLibItem->GetField( FOOTPRINT )->m_Text ) );
} }
for( ii = FIELD1; ii < DrawLibItem->GetFieldCount(); ii++ ) for( ii = FIELD1; ii < DrawLibItem->GetFieldCount(); ii++ )
...@@ -631,19 +621,19 @@ void WinEDA_Build_BOM_Frame::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem ...@@ -631,19 +621,19 @@ void WinEDA_Build_BOM_Frame::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem
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 ) );
else else
fprintf( f, "; %-12s", CONV_TO_UTF8( DrawLibItem->GetField(ii)->m_Text ) ); fprintf( f, "; %-12s", CONV_TO_UTF8( DrawLibItem->GetField( ii )->m_Text ) );
} }
} }
/*********************************************************************************************/ /*********************************************************************************************/
int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f, int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f,
ListComponent* aList, OBJ_CMP_TO_LIST* aList,
int aItemCount, int aItemCount,
bool CompactForm, bool CompactForm,
bool aIncludeSubComponents ) bool aIncludeSubComponents )
/*********************************************************************************************/ /*********************************************************************************************/
/* Print the B.O.M sorted by reference /* Print the B.O.M sorted by reference
...@@ -709,7 +699,7 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f, ...@@ -709,7 +699,7 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f,
// Print list of items // Print list of items
for( ii = 0; ii < aItemCount; ii++ ) for( ii = 0; ii < aItemCount; ii++ )
{ {
DrawList = aList[ii].m_Comp; DrawList = aList[ii].m_RootCmp;
if( DrawList == NULL ) if( DrawList == NULL )
continue; continue;
...@@ -717,7 +707,7 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f, ...@@ -717,7 +707,7 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f,
continue; continue;
DrawLibItem = (SCH_COMPONENT*) DrawList; DrawLibItem = (SCH_COMPONENT*) DrawList;
if( aList[ii].m_Ref[0] == '#' ) if( aList[ii].m_Reference[0] == '#' )
continue; continue;
Multi = 0; Multi = 0;
...@@ -728,35 +718,41 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f, ...@@ -728,35 +718,41 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f,
if( ( Multi > 1 ) && aIncludeSubComponents ) if( ( Multi > 1 ) && aIncludeSubComponents )
#if defined(KICAD_GOST) #if defined(KICAD_GOST)
Unit = aList[ii].m_Unit + '1' - 1; Unit = aList[ii].m_Unit + '1' - 1;
#else #else
Unit = aList[ii].m_Unit + 'A' - 1; Unit = aList[ii].m_Unit + 'A' - 1;
#endif #endif
sprintf( CmpName, "%s", aList[ii].m_Ref ); sprintf( CmpName, "%s", aList[ii].m_Reference );
if( !CompactForm || Unit != ' ' ) if( !CompactForm || Unit != ' ' )
sprintf( CmpName + strlen( CmpName ), "%c", Unit ); sprintf( CmpName + strlen( CmpName ), "%c", Unit );
if( CompactForm ) if( CompactForm )
fprintf( f, "%s%c%s", CmpName, s_ExportSeparatorSymbol, fprintf( f, "%s%c%s", CmpName, s_ExportSeparatorSymbol,
CONV_TO_UTF8( DrawLibItem->GetField(VALUE)->m_Text ) ); CONV_TO_UTF8( DrawLibItem->GetField( VALUE )->m_Text ) );
else else
fprintf( f, "| %-10s %-12s", CmpName, fprintf( f, "| %-10s %-12s", CmpName,
CONV_TO_UTF8( DrawLibItem->GetField(VALUE)->m_Text ) ); CONV_TO_UTF8( DrawLibItem->GetField( VALUE )->m_Text ) );
if( aIncludeSubComponents ) if( aIncludeSubComponents )
{ {
msg = aList[ii].m_SheetList.PathHumanReadable(); msg = aList[ii].m_SheetPath.PathHumanReadable();
if( CompactForm ) if( CompactForm )
{ {
fprintf( f, "%c%s", s_ExportSeparatorSymbol, CONV_TO_UTF8( msg ) ); fprintf( f, "%c%s", s_ExportSeparatorSymbol, CONV_TO_UTF8( msg ) );
msg = m_Parent->GetXYSheetReferences( (BASE_SCREEN*)DrawLibItem->GetParent(), DrawLibItem->m_Pos ); msg = m_Parent->GetXYSheetReferences(
(BASE_SCREEN*) DrawLibItem->GetParent(), DrawLibItem->m_Pos );
fprintf( f, "%c%s)", s_ExportSeparatorSymbol, CONV_TO_UTF8( msg ) ); fprintf( f, "%c%s)", s_ExportSeparatorSymbol, 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( (BASE_SCREEN*)DrawLibItem->GetParent(), DrawLibItem->m_Pos ); msg = m_Parent->GetXYSheetReferences(
(BASE_SCREEN*) DrawLibItem->GetParent(), DrawLibItem->m_Pos );
fprintf( f, " (loc %s)", CONV_TO_UTF8( msg ) ); fprintf( f, " (loc %s)", CONV_TO_UTF8( msg ) );
} }
} }
...@@ -776,10 +772,10 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f, ...@@ -776,10 +772,10 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByRef( FILE* f,
/*********************************************************************************************/ /*********************************************************************************************/
int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f, int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f,
ListComponent* aList, OBJ_CMP_TO_LIST* aList,
int aItemCount, int aItemCount,
bool aIncludeSubComponents ) bool aIncludeSubComponents )
/**********************************************************************************************/ /**********************************************************************************************/
{ {
int Multi; int Multi;
...@@ -799,7 +795,7 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f, ...@@ -799,7 +795,7 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f,
for( int ii = 0; ii < aItemCount; ii++ ) for( int ii = 0; ii < aItemCount; ii++ )
{ {
DrawList = aList[ii].m_Comp; DrawList = aList[ii].m_RootCmp;
if( DrawList == NULL ) if( DrawList == NULL )
continue; continue;
...@@ -808,7 +804,7 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f, ...@@ -808,7 +804,7 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f,
continue; continue;
DrawLibItem = (SCH_COMPONENT*) DrawList; DrawLibItem = (SCH_COMPONENT*) DrawList;
if( aList[ii].m_Ref[0] == '#' ) if( aList[ii].m_Reference[0] == '#' )
continue; continue;
Multi = 0; Multi = 0;
...@@ -828,16 +824,18 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f, ...@@ -828,16 +824,18 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f,
Unit = aList[ii].m_Unit + 'A' - 1; Unit = aList[ii].m_Unit + 'A' - 1;
} }
sprintf( CmpName, "%s%c", aList[ii].m_Ref, Unit ); sprintf( CmpName, "%s%c", aList[ii].m_Reference, Unit );
#endif #endif
fprintf( f, "| %-12s %-10s", CONV_TO_UTF8( DrawLibItem->GetField(VALUE)->m_Text ), CmpName ); fprintf( f, "| %-12s %-10s", CONV_TO_UTF8( DrawLibItem->GetField(
VALUE )->m_Text ), CmpName );
// print the sheet path // print the sheet path
if( aIncludeSubComponents ) if( aIncludeSubComponents )
{ {
msg = aList[ii].m_SheetList.PathHumanReadable(); msg = aList[ii].m_SheetPath.PathHumanReadable();
fprintf( f, " (Sheet %s)", CONV_TO_UTF8( msg ) ); fprintf( f, " (Sheet %s)", CONV_TO_UTF8( msg ) );
msg = m_Parent->GetXYSheetReferences( (BASE_SCREEN*)DrawLibItem->GetParent(), DrawLibItem->m_Pos ); msg = m_Parent->GetXYSheetReferences(
(BASE_SCREEN*) DrawLibItem->GetParent(), DrawLibItem->m_Pos );
fprintf( f, " (loc %s)", CONV_TO_UTF8( msg ) ); fprintf( f, " (loc %s)", CONV_TO_UTF8( msg ) );
} }
...@@ -852,33 +850,29 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f, ...@@ -852,33 +850,29 @@ int WinEDA_Build_BOM_Frame::PrintComponentsListByVal( FILE* f,
} }
/******************************************************************/ /************************************************************************/
static int PrintListeGLabel( FILE* f, ListLabel* aList, int aItemCount ) static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList )
/******************************************************************/ /************************************************************************/
{ {
int ii, jj;
SCH_LABEL* DrawTextItem; SCH_LABEL* DrawTextItem;
Hierarchical_PIN_Sheet_Struct* DrawSheetLabel; Hierarchical_PIN_Sheet_Struct* DrawSheetLabel;
ListLabel* LabelItem;
wxString msg, sheetpath; wxString msg, sheetpath;
wxString labeltype; wxString labeltype;
for( ii = 0; ii < aItemCount; ii++ ) for( unsigned ii = 0; ii < aList.size(); ii++ )
{ {
LabelItem = &aList[ii]; switch( aList[ii].m_LabelType )
switch( LabelItem->m_LabelType )
{ {
case TYPE_SCH_HIERLABEL: case TYPE_SCH_HIERLABEL:
case TYPE_SCH_GLOBALLABEL: case TYPE_SCH_GLOBALLABEL:
DrawTextItem = (SCH_LABEL*) (LabelItem->m_Label); DrawTextItem = (SCH_LABEL*)(aList[ii].m_Label);
if( LabelItem->m_LabelType == TYPE_SCH_HIERLABEL ) if( aList[ii].m_LabelType == TYPE_SCH_HIERLABEL )
labeltype = wxT( "Hierarchical" ); labeltype = wxT( "Hierarchical" );
else else
labeltype = wxT( "Global " ); labeltype = wxT( "Global " );
sheetpath = CONV_FROM_UTF8( LabelItem->m_SheetPath ); 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(), DrawTextItem->m_Text.GetData(),
...@@ -892,8 +886,8 @@ static int PrintListeGLabel( FILE* f, ListLabel* aList, int aItemCount ) ...@@ -892,8 +886,8 @@ static int PrintListeGLabel( FILE* f, ListLabel* aList, int aItemCount )
case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE: case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE:
{ {
DrawSheetLabel = (Hierarchical_PIN_Sheet_Struct*) LabelItem->m_Label; DrawSheetLabel = (Hierarchical_PIN_Sheet_Struct*) aList[ii].m_Label;
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 )
...@@ -903,12 +897,12 @@ static int PrintListeGLabel( FILE* f, ListLabel* aList, int aItemCount ) ...@@ -903,12 +897,12 @@ static int PrintListeGLabel( FILE* f, ListLabel* aList, int aItemCount )
_( "> %-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(), DrawSheetLabel->m_Text.GetData(),
labtype.GetData(), labtype.GetData(),
LabelItem->m_SheetPath, aList[ii].m_SheetPath.PathHumanReadable().GetData(),
(float) DrawSheetLabel->m_Pos.x / 1000, (float) DrawSheetLabel->m_Pos.x / 1000,
(float) DrawSheetLabel->m_Pos.y / 1000 ); (float) DrawSheetLabel->m_Pos.y / 1000 );
fprintf( f, CONV_TO_UTF8( msg ) ); fprintf( f, CONV_TO_UTF8( msg ) );
} }
break; break;
default: default:
break; break;
......
...@@ -371,9 +371,6 @@ int DrawSheetStruct::ComponentCount() ...@@ -371,9 +371,6 @@ int DrawSheetStruct::ComponentCount()
/*******************************************************************/ /*******************************************************************/
{ {
//count our own components, without the power components. //count our own components, without the power components.
/* Routine retournant le nombre de composants dans le schema,
* powers non comprises */
int n = 0; int n = 0;
if( m_AssociatedScreen ) if( m_AssociatedScreen )
...@@ -678,7 +675,7 @@ DrawSheetPath::DrawSheetPath() ...@@ -678,7 +675,7 @@ DrawSheetPath::DrawSheetPath()
} }
int DrawSheetPath::Cmp( DrawSheetPath& d ) int DrawSheetPath::Cmp( const DrawSheetPath& d ) const
{ {
if( m_numSheets > d.m_numSheets ) if( m_numSheets > d.m_numSheets )
return 1; return 1;
......
...@@ -66,7 +66,7 @@ public: ...@@ -66,7 +66,7 @@ public:
*/ */
WX_DEFINE_ARRAY( DrawSheetStruct *, SheetGrowArray ); WX_DEFINE_ARRAY( DrawSheetStruct *, SheetGrowArray );
class DrawSheetStruct : public SCH_ITEM /* Gestion de la hierarchie */ class DrawSheetStruct : public SCH_ITEM
{ {
public: public:
wxString m_SheetName; /*this is equivalent to C101 for components: wxString m_SheetName; /*this is equivalent to C101 for components:
...@@ -76,13 +76,13 @@ private: ...@@ -76,13 +76,13 @@ private:
* but need it here for loading after * but need it here for loading after
* reading the sheet description from file. */ * reading the sheet description from file. */
public: public:
int m_SheetNameSize; /* Size (height) of the text, used to draw the name */ int m_SheetNameSize; /* Size (height) of the text, used to draw the sheet name */
int m_FileNameSize; /* Size (height) of the text, used to draw the name */ int m_FileNameSize; /* Size (height) of the text, used to draw the file name */
wxPoint m_Pos; wxPoint m_Pos;
wxSize m_Size; /* Position and Size of sheet symbol */ wxSize m_Size; /* Position and Size of sheet symbol */
int m_Layer; int m_Layer;
Hierarchical_PIN_Sheet_Struct* m_Label; /* Points de connection, linked list.*/ Hierarchical_PIN_Sheet_Struct* m_Label; /* Points de connection, linked list.*/
int m_NbLabel; /* Nombre de points de connexion */ int m_NbLabel; /* Pins sheet (corresponding to hierarchical labels) count */
SCH_SCREEN* m_AssociatedScreen; /* Associated Screen which handle the physical data SCH_SCREEN* m_AssociatedScreen; /* Associated Screen which handle the physical data
* In complex hierarchies we can have many DrawSheetStruct using the same data * In complex hierarchies we can have many DrawSheetStruct using the same data
*/ */
...@@ -149,7 +149,7 @@ public: ...@@ -149,7 +149,7 @@ public:
DrawSheetPath(); DrawSheetPath();
~DrawSheetPath() { }; ~DrawSheetPath() { };
void Clear() { m_numSheets = 0; } void Clear() { m_numSheets = 0; }
int Cmp( DrawSheetPath& d ); int Cmp( const DrawSheetPath& d ) const;
DrawSheetStruct* Last(); DrawSheetStruct* Last();
SCH_SCREEN* LastScreen(); SCH_SCREEN* LastScreen();
EDA_BaseStruct* LastDrawList(); EDA_BaseStruct* LastDrawList();
......
...@@ -134,9 +134,9 @@ public: ...@@ -134,9 +134,9 @@ public:
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);
int PrintComponentsListByRef( FILE * f, ListComponent * List, int NbItems, int PrintComponentsListByRef( FILE * f, OBJ_CMP_TO_LIST * List, int NbItems,
bool CompactForm, bool aIncludeSubComponents ); bool CompactForm, bool aIncludeSubComponents );
int PrintComponentsListByVal( FILE *f, ListComponent * List, int NbItems, int PrintComponentsListByVal( FILE *f, OBJ_CMP_TO_LIST * List, int NbItems,
bool aIncludeSubComponents); bool aIncludeSubComponents);
void PrintFieldData(FILE * f, SCH_COMPONENT * DrawLibItem, bool CompactForm = FALSE); void PrintFieldData(FILE * f, SCH_COMPONENT * DrawLibItem, bool CompactForm = FALSE);
void SavePreferences(); void SavePreferences();
......
...@@ -319,7 +319,7 @@ void WinEDA_ErcFrame::TestErc( wxCommandEvent& event ) ...@@ -319,7 +319,7 @@ void WinEDA_ErcFrame::TestErc( wxCommandEvent& event )
/* Reset du flag m_FlagOfConnection, utilise par la suite */ /* Reset du flag m_FlagOfConnection, utilise par la suite */
for( NetItemRef = g_TabObjNet; NetItemRef < Lim; NetItemRef++ ) for( NetItemRef = g_TabObjNet; NetItemRef < Lim; NetItemRef++ )
NetItemRef->m_FlagOfConnection = (IsConnectType) 0; NetItemRef->m_FlagOfConnection = UNCONNECTED;
NetNbItems = 0; NetNbItems = 0;
MinConn = NOC; MinConn = NOC;
...@@ -692,7 +692,7 @@ static void TestOthersItems( WinEDA_DrawPanel* panel, wxDC* DC, ...@@ -692,7 +692,7 @@ static void TestOthersItems( WinEDA_DrawPanel* panel, wxDC* DC,
if( NetItemTst->m_FlagOfConnection == 0 ) if( NetItemTst->m_FlagOfConnection == 0 )
{ {
Diagnose( panel, DC, NetItemRef, NetItemTst, 0, erc ); Diagnose( panel, DC, NetItemRef, NetItemTst, 0, erc );
NetItemTst->m_FlagOfConnection = (IsConnectType) 1; NetItemTst->m_FlagOfConnection = NOCONNECT;
} }
} }
} }
......
/**************************************************************/ /**************************************************************/
/* libarch.cc */ /* libarch.cc */
/* Module de generation du fichier d'archivage des composants */ /* Module de generation du fichier d'archivage des composants */
/**************************************************************/ /**************************************************************/
#include <algorithm> // to use sort vector
#include <vector>
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h"
#include "common.h" #include "common.h"
#include "program.h" #include "program.h"
...@@ -14,132 +15,102 @@ ...@@ -14,132 +15,102 @@
#include "protos.h" #include "protos.h"
/* Imported functions */
int BuildComponentsListFromSchematic( ListComponent* List );
/* Local functions*/ /* Local functions*/
static int TriListEntry(EDA_LibComponentStruct **Objet1, EDA_LibComponentStruct **Objet2); static bool TriListEntry( const EDA_LibComponentStruct* Objet1,
const EDA_LibComponentStruct* Objet2 );
/*******************************************************************/ /*******************************************************************/
bool LibArchive(wxWindow * frame, const wxString & ArchFullFileName) bool LibArchive( wxWindow* frame, const wxString& ArchFullFileName )
/*******************************************************************/ /*******************************************************************/
/* /*
Creation du fichier librairie contenant tous les composants utilis�s dans * Creates a library that contains all components used in the whole hierarchy
le projet en cours * return true if success
retourne TRUE si fichier cr�� */
*/
{ {
wxString DocFileName, msg; wxString DocFileName, msg;
char Line[256]; char Line[256];
FILE *ArchiveFile, *DocFile; FILE* ArchiveFile, * DocFile;
ListComponent * List; EDA_LibComponentStruct* Entry;
EDA_LibComponentStruct ** ListEntry, *Entry;
int ii, NbItems; std::vector <EDA_LibComponentStruct*> ListEntry;
const wxChar * Text;
EDA_ScreenList s_list;
/* Creation de la liste des elements */ // examine all screens used and build the list of components found in lib
NbItems = BuildComponentsListFromSchematic(NULL ); // Comptage des composants for( SCH_SCREEN* screen = s_list.GetFirst(); screen != NULL; screen = s_list.GetNext() )
if ( NbItems == 0 ) return FALSE; {
for( SCH_ITEM* SchItem = screen->EEDrawList; SchItem; SchItem = SchItem->Next() )
List = (ListComponent *) MyZMalloc( NbItems * sizeof( ListComponent ) ); {
if (List == NULL ) return FALSE; if( SchItem->Type() != TYPE_SCH_COMPONENT )
continue;
/* Calcul de la liste des composants */
BuildComponentsListFromSchematic(List); SCH_COMPONENT* DrawLibItem = (SCH_COMPONENT*) SchItem;
Entry = FindLibPart( DrawLibItem->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
/* Calcul de la liste des Entrees de librairie if( Entry ) // if NULL : component not found
et Remplacement des alias par les composants "Root" */ ListEntry.push_back( Entry );
ListEntry = (EDA_LibComponentStruct ** )
MyZMalloc( NbItems * sizeof(EDA_LibComponentStruct *) );
if (ListEntry == NULL ) return FALSE;
for ( ii = 0; ii < NbItems; ii++ )
{
Text = List[ii].m_Comp->m_ChipName.GetData();
Entry = FindLibPart(Text, wxEmptyString, FIND_ROOT);
ListEntry[ii] = Entry; // = NULL component not found
}
MyFree(List);
qsort( ListEntry, NbItems, sizeof(EDA_LibComponentStruct *),
(int(*)(const void*, const void*))TriListEntry);
/* mise a jour extension fichier doc associe */
DocFileName = ArchFullFileName;
ChangeFileNameExt(DocFileName, wxT(".bck"));
if ((ArchiveFile = wxFopen(ArchFullFileName, wxT("wt"))) == NULL)
{
MyFree(ListEntry);
msg = _("Failed to create archive lib file ") + ArchFullFileName;
DisplayError(frame, msg);
return FALSE;
}
if ((DocFile = wxFopen(DocFileName, wxT("wt"))) == NULL)
{
msg = _("Failed to create doc lib file ") + DocFileName;
DisplayError(frame, msg);
}
fprintf(ArchiveFile,"%s %s\n#\n", LIBFILE_IDENT,DateAndTime(Line));
if( DocFile)
fprintf(DocFile,"%s %s\n", DOCFILE_IDENT, DateAndTime(Line));
/* Save components in file */
for ( ii = 0; ii < NbItems; ii++ )
{
if ( ListEntry[ii] == NULL ) // Not found in lib
{
continue;
} }
if ( (ii == 0) || ( ListEntry[ii-1] != ListEntry[ii] ) ) }
{
if ( ListEntry[ii]->Type == ROOT) // Must be always true, but just in case sort( ListEntry.begin(), ListEntry.end(), TriListEntry );
ListEntry[ii]->Save(ArchiveFile);
if( DocFile ) /* calculate the file name for the associated doc file */
ListEntry[ii]->SaveDoc(DocFile); DocFileName = ArchFullFileName;
} ChangeFileNameExt( DocFileName, DOC_EXT );
}
if( ( ArchiveFile = wxFopen( ArchFullFileName, wxT( "wt" ) ) ) == NULL )
fprintf(ArchiveFile,"#\n#EndLibrary\n"); {
fclose(ArchiveFile); msg = _( "Failed to create archive lib file " ) + ArchFullFileName;
DisplayError( frame, msg );
if( DocFile ) return FALSE;
{ }
fprintf(DocFile,"#\n#End Doc Library\n");
fclose(DocFile); if( ( DocFile = wxFopen( DocFileName, wxT( "wt" ) ) ) == NULL )
} {
msg = _( "Failed to create doc lib file " ) + DocFileName;
MyFree(ListEntry); DisplayError( frame, msg );
}
return TRUE;
} fprintf( ArchiveFile, "%s %s\n#\n", LIBFILE_IDENT, DateAndTime( Line ) );
if( DocFile )
/***********************************************************/ fprintf( DocFile, "%s %s\n", DOCFILE_IDENT, DateAndTime( Line ) );
static int TriListEntry(EDA_LibComponentStruct **Objet1,
EDA_LibComponentStruct **Objet2) /* Save components in file */
/***********************************************************/ for( unsigned ii = 0; ii < ListEntry.size(); ii++ )
/* Routine de comparaison pour le tri du Tableau par qsort() {
Les composants sont tries par LibName if( (ii == 0) || ( ListEntry[ii - 1] != ListEntry[ii] ) )
*/ {
{ if( ListEntry[ii]->Type == ROOT ) // Must be always true, but just in case
int ii; ListEntry[ii]->Save( ArchiveFile );
const wxString * Text1, *Text2; if( DocFile )
ListEntry[ii]->SaveDoc( DocFile );
}
}
if( (*Objet1 == NULL) && (*Objet2 == NULL ) ) return(0); fprintf( ArchiveFile, "#\n#EndLibrary\n" );
if( *Objet1 == NULL) return(-1); fclose( ArchiveFile );
if( *Objet2 == NULL) return(1);
Text1 = &(*Objet1)->m_Name.m_Text; if( DocFile )
Text2 = &(*Objet2)->m_Name.m_Text; {
fprintf( DocFile, "#\n#End Doc Library\n" );
fclose( DocFile );
}
ii = Text1->CmpNoCase(* Text2); return TRUE;
return(ii);
} }
/***********************************************************************************************/
bool TriListEntry( const EDA_LibComponentStruct* Objet1, const EDA_LibComponentStruct* Objet2 )
/***********************************************************************************************/
/* Compare function for sort()
* lib components are sorted by name
*/
{
int ii;
ii = Objet1->m_Name.m_Text.CmpNoCase( Objet2->m_Name.m_Text );
return ii < 0;
}
...@@ -539,7 +539,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -539,7 +539,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
EDA_BaseStruct* DrawList; EDA_BaseStruct* DrawList;
SCH_COMPONENT* Component; SCH_COMPONENT* Component;
int ii; int ii;
ListComponent* CmpList = NULL; OBJ_CMP_TO_LIST* CmpList = NULL;
int CmpListCount = 0, CmpListSize = 1000; int CmpListCount = 0, CmpListSize = 1000;
DateAndTime( Buf ); DateAndTime( Buf );
...@@ -571,18 +571,18 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -571,18 +571,18 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
{ {
if( CmpList == NULL ) if( CmpList == NULL )
{ {
CmpList = (ListComponent*) CmpList = (OBJ_CMP_TO_LIST*)
MyZMalloc( sizeof(ListComponent) * CmpListSize ); MyZMalloc( sizeof(OBJ_CMP_TO_LIST) * CmpListSize );
} }
if( CmpListCount >= CmpListSize ) if( CmpListCount >= CmpListSize )
{ {
CmpListSize += 1000; CmpListSize += 1000;
CmpList = (ListComponent*) realloc( CmpList = (OBJ_CMP_TO_LIST*) realloc(
CmpList, CmpList,
sizeof(ListComponent) * CmpListSize ); sizeof(OBJ_CMP_TO_LIST) * CmpListSize );
} }
CmpList[CmpListCount].m_Comp = Component; CmpList[CmpListCount].m_RootCmp = Component;
strcpy( CmpList[CmpListCount].m_Ref, Component->GetRef( sheet ).mb_str() ); strcpy( CmpList[CmpListCount].m_Reference, Component->GetRef( sheet ).mb_str() );
CmpListCount++; CmpListCount++;
} }
} }
...@@ -643,19 +643,19 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -643,19 +643,19 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
EDA_LibComponentStruct* Entry; EDA_LibComponentStruct* Entry;
for( ii = 0; ii < CmpListCount; ii++ ) for( ii = 0; ii < CmpListCount; ii++ )
{ {
Component = CmpList[ii].m_Comp; Component = CmpList[ii].m_RootCmp;
Entry = FindLibPart( Component->m_ChipName.GetData(), wxEmptyString, FIND_ROOT ); Entry = FindLibPart( Component->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
//Line.Printf(_("%s"), CmpList[ii].m_Ref); //Line.Printf(_("%s"), CmpList[ii].m_Ref);
//Line.Replace( wxT( " " ), wxT( "_" ) ); //Line.Replace( wxT( " " ), wxT( "_" ) );
unsigned int i; unsigned int i;
for( i = 0; i<sizeof(CmpList[ii].m_Ref) && CmpList[ii].m_Ref[i]; i++ ) for( i = 0; i<sizeof(CmpList[ii].m_Reference) && CmpList[ii].m_Reference[i]; i++ )
{ {
if( CmpList[ii].m_Ref[i] == ' ' ) if( CmpList[ii].m_Reference[i] == ' ' )
CmpList[ii].m_Ref[i] = '_'; CmpList[ii].m_Reference[i] = '_';
} }
fprintf( f, "$component %s\n", CmpList[ii].m_Ref ); fprintf( f, "$component %s\n", CmpList[ii].m_Reference );
/* Write the footprint list */ /* Write the footprint list */
for( unsigned int jj = 0; jj < Entry->m_FootprintList.GetCount(); jj++ ) for( unsigned int jj = 0; jj < Entry->m_FootprintList.GetCount(); jj++ )
{ {
......
...@@ -1200,13 +1200,13 @@ static void SetUnconnectedFlag( ObjetNetListStruct* ListObj, int NbItems ) ...@@ -1200,13 +1200,13 @@ static void SetUnconnectedFlag( ObjetNetListStruct* ListObj, int NbItems )
ObjetNetListStruct* NetItemRef, * NetItemTst, * ItemPtr; ObjetNetListStruct* NetItemRef, * NetItemTst, * ItemPtr;
ObjetNetListStruct* NetStart, * NetEnd, * Lim; ObjetNetListStruct* NetStart, * NetEnd, * Lim;
int Nb; int Nb;
IsConnectType StateFlag; ConnectType StateFlag;
NetStart = NetEnd = ListObj; NetStart = NetEnd = ListObj;
NetItemRef = NetStart; NetItemRef = NetStart;
Nb = 0; Nb = 0;
StateFlag = UNCONNECT; StateFlag = UNCONNECTED;
Lim = ListObj + NbItems; Lim = ListObj + NbItems;
for( ; NetItemRef < Lim; NetItemRef++ ) for( ; NetItemRef < Lim; NetItemRef++ )
...@@ -1233,7 +1233,7 @@ static void SetUnconnectedFlag( ObjetNetListStruct* ListObj, int NbItems ) ...@@ -1233,7 +1233,7 @@ static void SetUnconnectedFlag( ObjetNetListStruct* ListObj, int NbItems )
return; return;
/* Start Analyse Nouveau Net */ /* Start Analyse Nouveau Net */
StateFlag = UNCONNECT; StateFlag = UNCONNECTED;
NetStart = NetItemTst; NetStart = NetItemTst;
continue; continue;
} }
......
...@@ -52,8 +52,8 @@ enum NetObjetType { /* Type des objets de Net */ ...@@ -52,8 +52,8 @@ enum NetObjetType { /* Type des objets de Net */
}; };
enum IsConnectType { /* Valeur du Flag de connection */ enum ConnectType { /* Valeur du Flag de connection */
UNCONNECT, /* Pin ou Label non connecte */ UNCONNECTED = 0, /* Pin ou Label non connecte */
NOCONNECT, /* Pin volontairement non connectee (Symb. NoConnect utilise) */ NOCONNECT, /* Pin volontairement non connectee (Symb. NoConnect utilise) */
PAD_CONNECT /* connexion normale */ PAD_CONNECT /* connexion normale */
}; };
...@@ -76,7 +76,7 @@ public: ...@@ -76,7 +76,7 @@ public:
int m_BusNetCode; /* pour connexions type bus */ int m_BusNetCode; /* pour connexions type bus */
int m_Member; /* pour les labels type BUSWIRE ( labels de bus eclate ) int m_Member; /* pour les labels type BUSWIRE ( labels de bus eclate )
* numero de membre */ * numero de membre */
IsConnectType m_FlagOfConnection; ConnectType m_FlagOfConnection;
DrawSheetPath m_SheetListInclude; /* sheet that the hierarchal label connects to.*/ DrawSheetPath m_SheetListInclude; /* sheet that the hierarchal label connects to.*/
long m_PinNum; /* numero de pin( 4 octets -> 4 codes ascii) */ long m_PinNum; /* numero de pin( 4 octets -> 4 codes ascii) */
const wxString* m_Label; /* Tous types Labels:pointeur sur la wxString definissant le label */ const wxString* m_Label; /* Tous types Labels:pointeur sur la wxString definissant le label */
...@@ -92,45 +92,59 @@ public: ...@@ -92,45 +92,59 @@ public:
}; };
/* Structures pour memo et liste des elements */ /* object used in annotation to handle a list of components in schematic
struct ListLabel * because in a complex hierarchy, a component is used more than once,
* and its reference is depending on the sheet path
* for the same component, we must create a flat list of components
* used in nelist generation, BOM generation and annotation
*/
class OBJ_CMP_TO_LIST
{ {
int m_LabelType; public:
void* m_Label; SCH_COMPONENT* m_RootCmp; // the component in schematic
char m_SheetPath[256]; EDA_LibComponentStruct* m_Entry; // the source component in library
}; int m_Unit; /* Selected part (For multi parts per package) depending on sheet path */
DrawSheetPath m_SheetPath; /* the sheet path for this component */
unsigned long m_TimeStamp; /* unique identification number depending on sheet path */
bool m_IsNew; /* true for not yet annotated components */
wxString* m_Value; /* Component value (same for all instances) */
char m_Reference[32]; /* Component reference prefix, without number (for IC1, this is IC) ) */
int m_NumRef; /* Reference number (for IC1, this is 1) ) depending on sheet path*/
int m_Flag; /* flag for computations */
public:
// Used to create lists of components BOM, netlist generation) OBJ_CMP_TO_LIST()
struct ListComponent {
{ m_RootCmp = NULL;
SCH_COMPONENT* m_Comp; // pointer on the component in schematic m_Entry = NULL;
char m_Ref[32]; // component reference m_Unit = 0;
int m_Unit; // Unit value, for multiple parts per package m_TimeStamp = 0;
//have to store it here since the object references will be duplicated. m_IsNew = false;
DrawSheetPath m_SheetList; //composed of UIDs m_Value = NULL;
m_Reference[0] = 0;
m_NumRef = 0;
m_Flag = 0;
}
int CompareValue( const OBJ_CMP_TO_LIST& item ) const
{
return m_Value->CmpNoCase( *item.m_Value );
}
int CompareRef( const OBJ_CMP_TO_LIST& item ) const
{
return strnicmp( m_Reference, item.m_Reference, 32 );
}
bool IsPartsLocked( )
{
return m_Entry->m_UnitSelectionLocked;
}
}; };
/* Structure decrivant 1 composant de la schematique (for annotation ) */
struct CmpListStruct
{
public:
SCH_COMPONENT* m_Cmp; /* Pointeur sur le composant */
int m_NbParts; /* Nombre de parts par boitier */
bool m_PartsLocked; // For multi part components: True if the part cannot be changed
int m_Unit; /* Numero de part */
DrawSheetPath m_SheetList;
unsigned long m_TimeStamp; /* unique identification number */
int m_IsNew; /* != 0 pour composants non annotes */
char m_TextValue[32]; /* Valeur */
char m_TextRef[32]; /* Reference ( hors numero ) */
int m_NumRef; /* Numero de reference */
int m_Flag; /* flag pour calculs internes */
wxPoint m_Pos; /* position components */
char m_Path[256]; // the 'path' of the object in the sheet hierarchy.
};
/* Global Variables */ /* Global Variables */
eda_global int g_NbrObjNet; eda_global int g_NbrObjNet;
......
...@@ -40,7 +40,7 @@ void InstallCmpeditFrame(WinEDA_SchematicFrame * parent, wxPoint & pos, ...@@ -40,7 +40,7 @@ void InstallCmpeditFrame(WinEDA_SchematicFrame * parent, wxPoint & pos,
/******************************/ /******************************/
int LibraryEntryCompare(EDA_LibComponentStruct *LE1, EDA_LibComponentStruct *LE2); int LibraryEntryCompare(EDA_LibComponentStruct *LE1, EDA_LibComponentStruct *LE2);
int NumOfLibraries(); int NumOfLibraries();
EDA_LibComponentStruct *FindLibPart(const wxChar *Name, const wxString & LibName, int Alias); EDA_LibComponentStruct *FindLibPart(const wxChar *Name, const wxString & LibName, int Alias = FIND_ROOT);
void DrawingLibInGhost(WinEDA_DrawPanel * panel, wxDC * DC, EDA_LibComponentStruct *LibEntry, void DrawingLibInGhost(WinEDA_DrawPanel * panel, wxDC * DC, EDA_LibComponentStruct *LibEntry,
SCH_COMPONENT * DrawLibItem, int PartX, int PartY, SCH_COMPONENT * DrawLibItem, int PartX, int PartY,
......
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