kicad/eeschema/annotate.cpp

800 lines
26 KiB
C++
Raw Normal View History

2007-09-20 21:06:49 +00:00
/**************************************/
/* annotate.cpp: component annotation */
/**************************************/
2007-05-06 16:03:28 +00:00
#include "annotate_dialog.cpp"
2007-05-06 16:03:28 +00:00
#include "netlist.h"
#include "protos.h"
/* fonctions exportees */
2007-09-20 21:06:49 +00:00
int ListeComposants( CmpListStruct* BaseListeCmp, SCH_SCREEN* screen, int NumSheet );
2007-09-21 04:40:12 +00:00
int AnnotTriComposant( const void* o1, const void* o2 );
2007-09-20 21:06:49 +00:00
void BreakReference( CmpListStruct* BaseListeCmp, int NbOfCmp );
2007-05-06 16:03:28 +00:00
/* fonctions locales */
2007-09-20 21:06:49 +00:00
static void ReAnnotateComponents( CmpListStruct* BaseListeCmp, int NbOfCmp );
static void ComputeReferenceNumber( CmpListStruct* BaseListeCmp, int NbOfCmp );
static int GetLastReferenceNumber( CmpListStruct* Objet, CmpListStruct* BaseListeCmp,
int NbOfCmp );
static int ExistUnit( CmpListStruct* Objet, int Unit,
CmpListStruct* BaseListeCmp, int NbOfCmp );
2007-05-06 16:03:28 +00:00
/* Variable locales */
2007-09-20 21:06:49 +00:00
static bool AnnotProject = TRUE;
static bool SortByPosition = TRUE;
/**************************************/
2007-09-01 12:00:30 +00:00
void ReAnnotatePowerSymbolsOnly()
/**************************************/
2007-05-06 16:03:28 +00:00
2007-09-20 21:06:49 +00:00
/* Used to reannotate the power symbols, before testing erc or computing netlist
* when a true component reannotation is not necessary
*
* In order to avoid conflicts the ref number start with a 0:
* PWR with id 12 is named PWR12 in global annotation and PWR012 by the Power annotation
*/
{
2007-09-20 21:06:49 +00:00
/* Build the screen list */
EDA_ScreenList ScreenList( NULL );
/* Update the sheet number, sheet count and date */
ScreenList.UpdateSheetNumberAndDate();
SCH_SCREEN* screen;
int CmpNumber = 1;
for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
{
EDA_BaseStruct* DrawList = screen->EEDrawList;
for( ; DrawList != NULL; DrawList = DrawList->Pnext )
{
if( DrawList->Type() != DRAW_LIB_ITEM_STRUCT_TYPE )
continue;
EDA_SchComponentStruct* DrawLibItem = (EDA_SchComponentStruct*) DrawList;
EDA_LibComponentStruct* Entry =
FindLibPart( DrawLibItem->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
if( (Entry == NULL) || (Entry->m_Options != ENTRY_POWER) )
continue;
DrawLibItem->ClearAnnotation();
DrawLibItem->m_RefIdNumber = CmpNumber;
DrawLibItem->m_Field[REFERENCE].m_Text.RemoveLast(); // Remove the '?'
DrawLibItem->m_Field[REFERENCE].m_Text << wxT( "0" ) << CmpNumber;
CmpNumber++;
}
}
2007-05-06 16:03:28 +00:00
}
2007-05-06 16:03:28 +00:00
/******************************************************************/
2007-09-20 21:06:49 +00:00
void InstallAnnotateFrame( WinEDA_SchematicFrame* parent, wxPoint& pos )
2007-05-06 16:03:28 +00:00
/******************************************************************/
{
2007-09-20 21:06:49 +00:00
WinEDA_AnnotateFrame* frame = new WinEDA_AnnotateFrame( parent );
frame->ShowModal(); frame->Destroy();
2007-05-06 16:03:28 +00:00
}
/******************************************************************/
2007-09-20 21:06:49 +00:00
void WinEDA_AnnotateFrame::AnnotateComponents( wxCommandEvent& event )
2007-05-06 16:03:28 +00:00
/******************************************************************/
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/*
2007-09-20 21:06:49 +00:00
* Compute the annotation of the components for the whole projeect, or the current sheet only.
* All the components or the new ones only will be annotated.
*/
2007-05-06 16:03:28 +00:00
{
2007-09-20 21:06:49 +00:00
int NbSheet, ii, NbOfCmp;
SCH_SCREEN* screen;
CmpListStruct* BaseListeCmp;
wxBusyCursor dummy;
AnnotProject = (m_AnnotProjetCtrl->GetSelection() == 0) ? TRUE : FALSE;
SortByPosition = (m_AnnotSortCmpCtrl->GetSelection() == 0) ? TRUE : FALSE;
/* If it is an annotation for all the components, reset previous annotation: */
if( m_AnnotNewCmpCtrl->GetSelection() == 0 )
DeleteAnnotation( event );
if( m_Abort )
return;
/* Build the screen list */
EDA_ScreenList ScreenList( NULL );
NbSheet = ScreenList.GetCount();
/* Update the sheet number, sheet count and date */
ScreenSch->SetModify();
ScreenList.UpdateSheetNumberAndDate();
/* First pass: Component counting */
screen = (SCH_SCREEN*) m_Parent->m_CurrentScreen;
if( AnnotProject == TRUE )
{
NbOfCmp = 0;
for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
{
NbOfCmp += ListeComposants( NULL, screen, screen->m_SheetNumber );
}
}
else
NbOfCmp = ListeComposants( NULL, screen, screen->m_SheetNumber );
if( NbOfCmp == 0 )
return;
ii = sizeof(CmpListStruct) * NbOfCmp;
BaseListeCmp = (CmpListStruct*) MyZMalloc( ii );
/* Second pass : Int data tables */
screen = (SCH_SCREEN*) m_Parent->m_CurrentScreen;
if( AnnotProject == TRUE )
{
ii = 0;
for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
{
ii += ListeComposants( BaseListeCmp + ii,
screen, screen->m_SheetNumber );
}
}
else
ii = ListeComposants( BaseListeCmp, screen, screen->m_SheetNumber );
if( ii != NbOfCmp )
DisplayError( this, wxT( "Internal error in AnnotateComponents()" ) );
/* Separation des Numeros de la reference: IC1 -> IC, et 1 dans .m_NumRef */
BreakReference( BaseListeCmp, NbOfCmp );
qsort( BaseListeCmp, NbOfCmp, sizeof(CmpListStruct),
( int( * ) ( const void*, const void* ) )AnnotTriComposant );
/* Recalcul des numeros de reference */
ComputeReferenceNumber( BaseListeCmp, NbOfCmp );
ReAnnotateComponents( BaseListeCmp, NbOfCmp );
MyFree( BaseListeCmp ); BaseListeCmp = NULL;
/* Final control */
CheckAnnotate( m_Parent, AnnotProject ? FALSE : TRUE );
m_Parent->DrawPanel->Refresh( TRUE ); /* Refresh screen */
Close();
2007-05-06 16:03:28 +00:00
}
/********************************************************************/
2007-09-20 21:06:49 +00:00
void WinEDA_AnnotateFrame::DeleteAnnotation( wxCommandEvent& event )
2007-05-06 16:03:28 +00:00
/********************************************************************/
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/* Clear the current annotation for the whole project or only for the current sheet
2007-09-20 21:06:49 +00:00
* Update sheet number and number of sheets
*/
2007-05-06 16:03:28 +00:00
{
2007-09-20 21:06:49 +00:00
int NbSheet;
SCH_SCREEN* screen;
EDA_SchComponentStruct* DrawLibItem;
if( !IsOK( this, _( "Previous Annotation will be deleted. Continue ?" ) ) )
{
m_Abort = TRUE; return;
}
AnnotProject = (m_AnnotProjetCtrl->GetSelection() == 0) ? TRUE : FALSE;
m_Abort = FALSE;
/* Build the screen list */
EDA_ScreenList ScreenList( NULL );
NbSheet = ScreenList.GetCount();
/* Update the sheet number, sheet count and date */
ScreenList.UpdateSheetNumberAndDate();
ScreenSch->SetModify();
if( AnnotProject == TRUE )
screen = ScreenList.GetFirst();
else
screen = (SCH_SCREEN*) m_Parent->m_CurrentScreen;
for( ; screen != NULL; screen = ScreenList.GetNext() )
{
EDA_BaseStruct* DrawList = screen->EEDrawList;
for( ; DrawList != NULL; DrawList = DrawList->Pnext )
{
if( DrawList->Type() == DRAW_LIB_ITEM_STRUCT_TYPE )
{
DrawLibItem = (EDA_SchComponentStruct*) DrawList;
DrawLibItem->ClearAnnotation();
}
}
if( !AnnotProject )
break;
}
m_Parent->DrawPanel->Refresh( TRUE );
Close();
2007-05-06 16:03:28 +00:00
}
/************************************************************************************/
2007-09-20 21:06:49 +00:00
int ListeComposants( CmpListStruct* BaseListeCmp, SCH_SCREEN* screen, int NumSheet )
2007-05-06 16:03:28 +00:00
/***********************************************************************************/
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/* if BaseListeCmp == NULL : Components counting
2007-09-20 21:06:49 +00:00
* else update data table BaseListeCmp
*/
2007-05-06 16:03:28 +00:00
{
2007-09-20 21:06:49 +00:00
int NbrCmp = 0;
EDA_BaseStruct* DrawList = screen->EEDrawList;
EDA_SchComponentStruct* DrawLibItem;
EDA_LibComponentStruct* Entry;
DrawList = screen->EEDrawList;
2007-09-21 04:40:12 +00:00
for( ; DrawList; DrawList = DrawList->Pnext )
2007-09-20 21:06:49 +00:00
{
switch( DrawList->Type() )
{
case DRAW_SEGMENT_STRUCT_TYPE:
case DRAW_JUNCTION_STRUCT_TYPE:
case DRAW_TEXT_STRUCT_TYPE:
case DRAW_LABEL_STRUCT_TYPE:
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
break;
case DRAW_LIB_ITEM_STRUCT_TYPE:
DrawLibItem = (EDA_SchComponentStruct*) DrawList;
Entry = FindLibPart( DrawLibItem->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
if( Entry == NULL )
break;
2007-09-21 04:40:12 +00:00
2007-09-20 21:06:49 +00:00
if( BaseListeCmp == NULL ) /* Items counting only */
{
2007-09-21 04:40:12 +00:00
NbrCmp++;
break;
2007-09-20 21:06:49 +00:00
}
2007-09-21 04:40:12 +00:00
2007-09-20 21:06:49 +00:00
BaseListeCmp[NbrCmp].m_Cmp = DrawLibItem;
BaseListeCmp[NbrCmp].m_NbParts = Entry->m_UnitCount;
BaseListeCmp[NbrCmp].m_Unit = DrawLibItem->m_Multi;
BaseListeCmp[NbrCmp].m_PartsLocked = Entry->m_UnitSelectionLocked;
BaseListeCmp[NbrCmp].m_Sheet = NumSheet;
BaseListeCmp[NbrCmp].m_IsNew = FALSE;
2007-09-21 04:40:12 +00:00
BaseListeCmp[NbrCmp].m_Pos = DrawLibItem->m_Pos;
BaseListeCmp[NbrCmp].m_TimeStamp = DrawLibItem->m_TimeStamp;
2007-09-20 21:06:49 +00:00
if( DrawLibItem->m_Field[REFERENCE].m_Text.IsEmpty() )
DrawLibItem->m_Field[REFERENCE].m_Text = wxT( "DefRef?" );
2007-09-21 04:40:12 +00:00
2007-09-20 21:06:49 +00:00
strncpy( BaseListeCmp[NbrCmp].m_TextRef,
CONV_TO_UTF8( DrawLibItem->m_Field[REFERENCE].m_Text ), 32 );
BaseListeCmp[NbrCmp].m_NumRef = -1;
if( DrawLibItem->m_Field[VALUE].m_Text.IsEmpty() )
DrawLibItem->m_Field[VALUE].m_Text = wxT( "~" );
2007-09-21 04:40:12 +00:00
2007-09-20 21:06:49 +00:00
strncpy( BaseListeCmp[NbrCmp].m_TextValue,
CONV_TO_UTF8( DrawLibItem->m_Field[VALUE].m_Text ), 32 );
NbrCmp++;
break;
case DRAW_PICK_ITEM_STRUCT_TYPE:
case DRAW_POLYLINE_STRUCT_TYPE:
case DRAW_BUSENTRY_STRUCT_TYPE:
case DRAW_SHEET_STRUCT_TYPE:
case DRAW_SHEETLABEL_STRUCT_TYPE:
case DRAW_MARKER_STRUCT_TYPE:
case DRAW_NOCONNECT_STRUCT_TYPE:
break;
default:
break;
}
}
return NbrCmp;
2007-05-06 16:03:28 +00:00
}
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/*****************************************************************/
2007-09-21 04:40:12 +00:00
int AnnotTriComposant( const void* o1, const void* o2 )
2007-05-06 16:03:28 +00:00
/****************************************************************/
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/* function used par qsort() for sorting the list
2007-09-20 21:06:49 +00:00
* Composants are sorted
* by reference
* if same reference: by value
* if same value: by unit number
* if same unit number, by sheet
* if same sheet, by time stamp
**/
2007-05-06 16:03:28 +00:00
{
2007-09-21 04:40:12 +00:00
CmpListStruct* Objet1 = (CmpListStruct*) o1;
CmpListStruct* Objet2 = (CmpListStruct*) o2;
2007-09-20 21:06:49 +00:00
2007-09-21 04:40:12 +00:00
int ii = strnicmp( Objet1->m_TextRef, Objet2->m_TextRef, 32 );
2007-09-20 21:06:49 +00:00
if( SortByPosition == TRUE )
{
if( ii == 0 )
ii = Objet1->m_Sheet - Objet2->m_Sheet;
if( ii == 0 )
ii = Objet1->m_Unit - Objet2->m_Unit;
if( ii == 0 )
ii = Objet1->m_Pos.x - Objet2->m_Pos.x;
if( ii == 0 )
ii = Objet1->m_Pos.y - Objet2->m_Pos.y;
}
else
{
if( ii == 0 )
ii = strnicmp( Objet1->m_TextValue, Objet2->m_TextValue, 32 );
if( ii == 0 )
ii = Objet1->m_Unit - Objet2->m_Unit;
if( ii == 0 )
ii = Objet1->m_Sheet - Objet2->m_Sheet;
}
if( ii == 0 )
ii = Objet1->m_TimeStamp - Objet2->m_TimeStamp;
return ii;
2007-05-06 16:03:28 +00:00
}
/********************************************************************/
2007-09-20 21:06:49 +00:00
static void ReAnnotateComponents( CmpListStruct* BaseListeCmp, int NbOfCmp )
2007-05-06 16:03:28 +00:00
/********************************************************************/
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/* Update the reference component for the schematic project (or the current sheet)
2007-09-20 21:06:49 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-09-20 21:06:49 +00:00
int ii;
char* Text;
EDA_SchComponentStruct* DrawLibItem;
/* Reattribution des numeros */
for( ii = 0; ii < NbOfCmp; ii++ )
{
Text = BaseListeCmp[ii].m_TextRef;
DrawLibItem = BaseListeCmp[ii].m_Cmp;
if( BaseListeCmp[ii].m_NumRef < 0 )
strcat( Text, "?" );
else
sprintf( Text + strlen( Text ), "%d", BaseListeCmp[ii].m_NumRef );
DrawLibItem->m_Field[REFERENCE].m_Text = CONV_FROM_UTF8( Text );
DrawLibItem->m_Multi = BaseListeCmp[ii].m_Unit;
DrawLibItem->m_RefIdNumber = BaseListeCmp[ii].m_NumRef;
if( DrawLibItem->m_RefIdNumber < 0 )
DrawLibItem->m_RefIdNumber = 0;
}
2007-05-06 16:03:28 +00:00
}
/**************************************************************/
2007-09-20 21:06:49 +00:00
void BreakReference( CmpListStruct* BaseListeCmp, int NbOfCmp )
2007-05-06 16:03:28 +00:00
/**************************************************************/
/* Modifie dans BaseListeCmp la reference des composants en supprimant la
2007-09-20 21:06:49 +00:00
* partie nombre de la partie texte.
* Place le nombre dans .m_NumRef
* Pour les composants multiples non encore annotes, met .m_Unit a sa valeur max
* Utilise:
* BaseListeCmp
* NbOfCmp
*/
2007-05-06 16:03:28 +00:00
{
2007-09-20 21:06:49 +00:00
int ii, ll;
char* Text;
/* Separation des Numeros de la reference: IC1 -> IC, et 1 dans .m_NumRef */
for( ii = 0; ii < NbOfCmp; ii++ )
{
BaseListeCmp[ii].m_NumRef = -1;
Text = BaseListeCmp[ii].m_TextRef;
ll = strlen( Text ) - 1;
if( Text[ll] == '?' )
{
BaseListeCmp[ii].m_IsNew = TRUE;
if( !BaseListeCmp[ii].m_PartsLocked )
BaseListeCmp[ii].m_Unit = 0x7FFFFFFF;
2007-09-21 04:40:12 +00:00
Text[ll] = 0;
continue;
2007-09-20 21:06:49 +00:00
}
if( isdigit( Text[ll] ) == 0 )
{
BaseListeCmp[ii].m_IsNew = TRUE;
if( !BaseListeCmp[ii].m_PartsLocked )
BaseListeCmp[ii].m_Unit = 0x7FFFFFFF;
continue;
}
while( ll >= 0 )
{
if( (Text[ll] <= ' ' ) || isdigit( Text[ll] ) )
ll--;
else
{
if( isdigit( Text[ll + 1] ) )
BaseListeCmp[ii].m_NumRef = atoi( &Text[ll + 1] );
Text[ll + 1] = 0;
break;
}
}
}
2007-05-06 16:03:28 +00:00
}
/*****************************************************************************/
2007-09-20 21:06:49 +00:00
static void ComputeReferenceNumber( CmpListStruct* BaseListeCmp, int NbOfCmp )
2007-05-06 16:03:28 +00:00
/*****************************************************************************/
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/* Compute the reference number for components without reference number
2007-09-20 21:06:49 +00:00
* Compute .m_NumRef member
*/
2007-05-06 16:03:28 +00:00
{
2007-09-20 21:06:49 +00:00
int ii, jj, LastReferenceNumber, NumberOfUnits, Unit;
char* Text, * RefText, * ValText;
CmpListStruct* ObjRef, * ObjToTest;
/* Components with an invisible reference (power...) always are re-annotated*/
for( ii = 0; ii < NbOfCmp; ii++ )
{
Text = BaseListeCmp[ii].m_TextRef;
if( *Text == '#' )
{
BaseListeCmp[ii].m_IsNew = TRUE;
BaseListeCmp[ii].m_NumRef = 0;
}
}
ValText = RefText = ""; LastReferenceNumber = 1;
for( ii = 0; ii < NbOfCmp; ii++ )
{
ObjRef = &BaseListeCmp[ii];
if( BaseListeCmp[ii].m_Flag )
continue;
Text = BaseListeCmp[ii].m_TextRef;
if( strnicmp( RefText, Text, 32 ) != 0 ) /* Nouveau Identificateur */
{
RefText = BaseListeCmp[ii].m_TextRef;
LastReferenceNumber = GetLastReferenceNumber( BaseListeCmp + ii, BaseListeCmp, NbOfCmp );
}
/* Annotation of mono-part components ( 1 part per package ) (trivial case)*/
if( BaseListeCmp[ii].m_NbParts <= 1 )
{
if( BaseListeCmp[ii].m_IsNew )
{
LastReferenceNumber++;
BaseListeCmp[ii].m_NumRef = LastReferenceNumber;
}
BaseListeCmp[ii].m_Unit = 1;
BaseListeCmp[ii].m_Flag = 1;
BaseListeCmp[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;
if( BaseListeCmp[ii].m_IsNew )
{
LastReferenceNumber++; BaseListeCmp[ii].m_NumRef = LastReferenceNumber;
if( !BaseListeCmp[ii].m_PartsLocked )
BaseListeCmp[ii].m_Unit = 1;
BaseListeCmp[ii].m_Flag = 1;
}
for( Unit = 1; Unit <= NumberOfUnits; Unit++ )
{
if( BaseListeCmp[ii].m_Unit == Unit )
continue;
jj = ExistUnit( BaseListeCmp + ii, Unit, BaseListeCmp, NbOfCmp );
if( jj >= 0 )
continue; /* Unit exists for this reference */
/* Search a component to annotate ( same prefix, same value) */
for( jj = ii + 1; jj < NbOfCmp; jj++ )
{
ObjToTest = &BaseListeCmp[jj];
if( BaseListeCmp[jj].m_Flag )
continue;
Text = BaseListeCmp[jj].m_TextRef;
if( strnicmp( RefText, Text, 32 ) != 0 )
break; // references are different
Text = BaseListeCmp[jj].m_TextValue;
if( strnicmp( ValText, Text, 32 ) != 0 )
break; // values are different
if( !BaseListeCmp[jj].m_IsNew )
{
//BaseListeCmp[jj].m_Flag = 1;
continue;
}
/* Component without reference number found, annotate it if possible */
if( !BaseListeCmp[jj].m_PartsLocked || (BaseListeCmp[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;
break;
}
}
}
}
2007-05-06 16:03:28 +00:00
}
/*************************************************************************************************/
2007-09-20 21:06:49 +00:00
static int GetLastReferenceNumber( CmpListStruct* Objet, CmpListStruct* BaseListeCmp, int NbOfCmp )
2007-05-06 16:03:28 +00:00
/*************************************************************************************************/
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/* Recherche le plus grand numero de reference dans les composants
2007-09-20 21:06:49 +00:00
* de meme prefixe de reference que celui pointe par Objet
* la liste des composants est supposee triee
*/
2007-05-06 16:03:28 +00:00
{
2007-09-20 21:06:49 +00:00
CmpListStruct* LastObjet = BaseListeCmp + NbOfCmp;
int LastNumber = 0;
const char* RefText;
RefText = Objet->m_TextRef;
for( ; Objet < LastObjet; Objet++ )
{
if( strnicmp( RefText, Objet->m_TextRef, 32 ) != 0 ) /* Nouveau Identificateur */
break;
if( LastNumber < Objet->m_NumRef )
LastNumber = Objet->m_NumRef;
}
return LastNumber;
2007-05-06 16:03:28 +00:00
}
/*****************************************************************/
2007-09-20 21:06:49 +00:00
static int ExistUnit( CmpListStruct* Objet, int Unit,
CmpListStruct* BaseListeCmp, int NbOfCmp )
2007-05-06 16:03:28 +00:00
/****************************************************************/
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/* Recherche dans la liste triee des composants, pour les composants
2007-09-20 21:06:49 +00:00
* multiples s'il existe pour le composant de reference Objet,
* une unite de numero Unit
* Retourne index dans BaseListeCmp si oui
* retourne -1 si non
*/
2007-05-06 16:03:28 +00:00
{
2007-09-20 21:06:49 +00:00
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++ )
{
if( Objet == ItemToTest )
continue;
if( ItemToTest->m_IsNew )
continue; /* non affecte */
if( ItemToTest->m_NumRef != NumRef )
continue;
if( strnicmp( RefText, ItemToTest->m_TextRef, 32 ) != 0 ) /* Nouveau Identificateur */
continue;
if( ItemToTest->m_Unit == Unit )
{
return ii;
}
}
return -1;
2007-05-06 16:03:28 +00:00
}
2007-09-20 21:06:49 +00:00
2007-05-06 16:03:28 +00:00
/******************************************************************/
2007-09-20 21:06:49 +00:00
int CheckAnnotate( WinEDA_SchematicFrame* frame, bool OneSheetOnly )
2007-05-06 16:03:28 +00:00
/******************************************************************/
/* Retourne le nombre de composants non annot<6F>s ou de meme r<>f<EFBFBD>rence (doubl<62>s)
2007-09-20 21:06:49 +00:00
* Si OneSheetOnly : recherche sur le schema courant
* sinon: recherche sur toute la hierarchie
*/
2007-05-06 16:03:28 +00:00
{
2007-09-20 21:06:49 +00:00
int NbSheet, ii, NumSheet = 1, error, NbOfCmp;
SCH_SCREEN* screen;
CmpListStruct* ListeCmp = NULL;
wxString Buff;
wxString msg, cmpref;
/* build tje screen list */
EDA_ScreenList ScreenList( NULL );
NbSheet = ScreenList.GetCount();
/* Update the sheet number, sheet count and date */
ScreenSch->SetModify();
ScreenList.UpdateSheetNumberAndDate();
/* 1ere passe : Comptage du nombre de composants */
screen = (SCH_SCREEN*) frame->m_CurrentScreen;
if( !OneSheetOnly )
{
NbOfCmp = 0;
for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
{
NbOfCmp += ListeComposants( NULL, screen, NumSheet );
}
}
else
NbOfCmp = ListeComposants( NULL, screen, NumSheet );
if( NbOfCmp == 0 )
{
wxBell();
return 0;
}
ii = sizeof(CmpListStruct) * NbOfCmp;
ListeCmp = (CmpListStruct*) MyZMalloc( ii );
/* 2eme passe : Remplissage du tableau des caracteristiques */
if( OneSheetOnly == 0 )
{
2007-09-21 04:40:12 +00:00
ii = 0;
screen = ScreenSch;
2007-09-20 21:06:49 +00:00
for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
{
ii += ListeComposants( ListeCmp + ii, screen, NumSheet );
}
}
else
{
screen = (SCH_SCREEN*) frame->m_CurrentScreen;
ListeComposants( ListeCmp, screen, NumSheet );
}
2007-09-21 04:40:12 +00:00
qsort( ListeCmp, NbOfCmp, sizeof(CmpListStruct), AnnotTriComposant );
2007-09-20 21:06:49 +00:00
/* Separation des Numeros de la reference: IC1 -> IC, et 1 dans .m_NumRef */
BreakReference( ListeCmp, NbOfCmp );
/* comptage des elements non annotes */
error = 0;
for( ii = 0; ii < NbOfCmp - 1; ii++ )
{
2007-09-21 04:40:12 +00:00
msg.Empty();
Buff.Empty();
2007-09-20 21:06:49 +00:00
if( ListeCmp[ii].m_IsNew )
{
if( ListeCmp[ii].m_NumRef >= 0 )
Buff << ListeCmp[ii].m_NumRef;
else
Buff = wxT( "?" );
2007-09-21 04:40:12 +00:00
2007-09-20 21:06:49 +00:00
cmpref = CONV_FROM_UTF8( ListeCmp[ii].m_TextRef );
msg.Printf( _( "item not annotated: %s%s" ), cmpref.GetData(), Buff.GetData() );
if( (ListeCmp[ii].m_Unit > 0) && (ListeCmp[ii].m_Unit < 0x7FFFFFFF) )
{
Buff.Printf( _( "( unit %d)" ), ListeCmp[ii].m_Unit );
msg << Buff;
}
DisplayError( NULL, msg );
2007-09-21 04:40:12 +00:00
error++;
break;
2007-09-20 21:06:49 +00:00
}
if( MAX( ListeCmp[ii].m_NbParts, 1 ) < ListeCmp[ii].m_Unit ) // Annotate error
{
if( ListeCmp[ii].m_NumRef >= 0 )
Buff << ListeCmp[ii].m_NumRef;
else
Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ListeCmp[ii].m_TextRef );
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 );
msg << Buff;
DisplayError( frame, msg );
2007-09-21 04:40:12 +00:00
error++;
break;
2007-09-20 21:06:49 +00:00
}
}
if( error )
return error;
2007-09-21 04:40:12 +00:00
// count the duplicated elements (if all are annotated)
2007-09-20 21:06:49 +00:00
for( ii = 0; (ii < NbOfCmp - 1) && (error < 4); ii++ )
{
2007-09-21 04:40:12 +00:00
msg.Empty();
Buff.Empty();
2007-09-20 21:06:49 +00:00
if( (stricmp( ListeCmp[ii].m_TextRef, ListeCmp[ii + 1].m_TextRef ) != 0)
|| ( ListeCmp[ii].m_NumRef != ListeCmp[ii + 1].m_NumRef ) )
continue;
/* Meme reference trouv<75>e */
/* Il y a erreur si meme unite */
2007-09-21 04:40:12 +00:00
if( ListeCmp[ii].m_Unit == ListeCmp[ii+1].m_Unit )
2007-09-20 21:06:49 +00:00
{
if( ListeCmp[ii].m_NumRef >= 0 )
Buff << ListeCmp[ii].m_NumRef;
else
Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ListeCmp[ii].m_TextRef );
msg.Printf( _( "Multiple item %s%s" ),
cmpref.GetData(), Buff.GetData() );
if( (ListeCmp[ii].m_Unit > 0) && (ListeCmp[ii].m_Unit < 0x7FFFFFFF) )
{
Buff.Printf( _( " (unit %d)" ), ListeCmp[ii].m_Unit );
msg << Buff;
}
DisplayError( frame, msg );
2007-09-21 04:40:12 +00:00
error++;
continue;
2007-09-20 21:06:49 +00:00
}
/* Il y a erreur si unites differentes mais nombre de parts differentes
* par boitier (ex U3 ( 1 part) et U3B sont incompatibles) */
if( ListeCmp[ii].m_NbParts != ListeCmp[ii + 1].m_NbParts )
{
if( ListeCmp[ii].m_NumRef >= 0 )
Buff << ListeCmp[ii].m_NumRef;
else
Buff = wxT( "?" );
cmpref = CONV_FROM_UTF8( ListeCmp[ii].m_TextRef );
msg.Printf( _( "Multiple item %s%s" ), cmpref.GetData(), Buff.GetData() );
if( (ListeCmp[ii].m_Unit > 0) && (ListeCmp[ii].m_Unit < 0x7FFFFFFF) )
{
Buff.Printf( _( " (unit %d)" ), ListeCmp[ii].m_Unit );
msg << Buff;
}
DisplayError( frame, msg );
error++;
}
/* Il y a erreur si unites differentes ET valeurs diff<66>rentes */
if( stricmp( ListeCmp[ii].m_TextValue, ListeCmp[ii + 1].m_TextValue ) != 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 );
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,
2007-09-21 04:40:12 +00:00
cmpvalue.GetData(), nextcmpref.GetData(),
ListeCmp[ii + 1].m_NumRef,
ListeCmp[ii + 1].m_Unit + 'A' - 1,
2007-09-20 21:06:49 +00:00
nextcmpvalue.GetData() );
DisplayError( frame, msg );
error++;
}
}
MyFree( ListeCmp );
return error;
2007-05-06 16:03:28 +00:00
}