Commit 6c01c554 authored by charras's avatar charras

code cleanup, better comments and comments translation

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