Schematic reference object refactoring and minor dialog fix.
* Schematic reference object now completely encapsulated. * Schematic reference list object refactoring complete. * Make OK default button in PCBNew block operation dialog.
This commit is contained in:
parent
c42af9387d
commit
1e2e144231
|
@ -19,29 +19,6 @@
|
||||||
#include "sch_component.h"
|
#include "sch_component.h"
|
||||||
#include "lib_pin.h"
|
#include "lib_pin.h"
|
||||||
|
|
||||||
//#define USE_OLD_ALGO
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function ComputeReferenceNumber
|
|
||||||
* Compute the reference number for components without reference number
|
|
||||||
* i.e. .m_NumRef member of each SCH_REFERENCE_LIST item not yet annotated
|
|
||||||
* in aComponentsList.
|
|
||||||
* if aUseSheetNum is false, this number starts from 1
|
|
||||||
* if aUseSheetNum is false, this number starts from from SheetNumber * aSheetIntervalId
|
|
||||||
* @param aComponentsList = the SCH_REFERENCE_LIST to fill
|
|
||||||
* @param aUseSheetNum = false to start Ids from 0,
|
|
||||||
* true to start each sheet annotation from SheetNumber * aSheetIntervalId
|
|
||||||
* @param aSheetIntervalId = number of allowed Id by sheet and by reference prefix
|
|
||||||
* if There are more than aSheetIntervalId of reference prefix in a given sheet
|
|
||||||
* number overlap next sheet inveral, but there is no annotation problem.
|
|
||||||
* Useful values are only 100 or 1000
|
|
||||||
* For instance for a sheet number = 2, and aSheetIntervalId = 100, the first Id = 101
|
|
||||||
* and the last Id is 199 when no overlap occurs with sheet number 2.
|
|
||||||
* Rf there are 150 items in sheet number 2, items are referenced U201 to U351,
|
|
||||||
* and items in sheet 3 start from U352
|
|
||||||
*/
|
|
||||||
static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList,
|
|
||||||
bool aUseSheetNum, int aSheetIntervalId );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function DeleteAnnotation
|
* Function DeleteAnnotation
|
||||||
|
@ -179,11 +156,25 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculate and update reference numbers in schematic
|
// Recalculate and update reference numbers in schematic
|
||||||
ComputeReferenceNumber( references, useSheetNum, idStep );
|
references.Annotate( useSheetNum, idStep );
|
||||||
references.UpdateAnnotation();
|
references.UpdateAnnotation();
|
||||||
|
|
||||||
|
wxArrayString errors;
|
||||||
|
|
||||||
/* Final control (just in case ... )*/
|
/* Final control (just in case ... )*/
|
||||||
CheckAnnotate( NULL, !aAnnotateSchematic );
|
if( CheckAnnotate( &errors, !aAnnotateSchematic ) )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < errors.GetCount(); i++ )
|
||||||
|
msg += errors[i];
|
||||||
|
|
||||||
|
// wxLogWarning is a cheap and dirty way to dump a potentially long list of
|
||||||
|
// strings to a dialog that can be saved to a file. This should be replaced
|
||||||
|
// by a more elegant solution.
|
||||||
|
wxLogWarning( msg );
|
||||||
|
}
|
||||||
|
|
||||||
OnModify();
|
OnModify();
|
||||||
|
|
||||||
// Update on screen references, that can be modified by previous calculations:
|
// Update on screen references, that can be modified by previous calculations:
|
||||||
|
@ -194,215 +185,6 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef USE_OLD_ALGO
|
|
||||||
/**
|
|
||||||
* helper function CreateFirstFreeRefId
|
|
||||||
* Search for a free ref Id inside a list of reference numbers in use.
|
|
||||||
* Because this function just search for a hole in a list of incremented numbers,
|
|
||||||
* this list must be:
|
|
||||||
* sorted by increasing values.
|
|
||||||
* and each value stored only once
|
|
||||||
* @see BuildRefIdInUseList to prepare this list
|
|
||||||
* @param aIdList = the buffer that contains Ids in use
|
|
||||||
* @param aFirstValue = the first expected free value
|
|
||||||
* @return a free (not yet used) Id
|
|
||||||
* and this new id is added in list
|
|
||||||
*/
|
|
||||||
static int CreateFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue )
|
|
||||||
{
|
|
||||||
int expectedId = aFirstValue;
|
|
||||||
|
|
||||||
// We search for expected Id a value >= aFirstValue.
|
|
||||||
// Skip existing Id < aFirstValue
|
|
||||||
unsigned ii = 0;
|
|
||||||
|
|
||||||
for( ; ii < aIdList.size(); ii++ )
|
|
||||||
{
|
|
||||||
if( expectedId <= aIdList[ii] )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ids are sorted by increasing value, from aFirstValue
|
|
||||||
// So we search from aFirstValue the first not used value, i.e. the first hole in list.
|
|
||||||
for(; ii < aIdList.size(); ii++ )
|
|
||||||
{
|
|
||||||
if( expectedId != aIdList[ii] ) // This id is not yet used.
|
|
||||||
{
|
|
||||||
// Insert this free Id, in order to keep list sorted
|
|
||||||
aIdList.insert(aIdList.begin() + ii, expectedId);
|
|
||||||
return expectedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// All existing Id are tested, and all values are found in use.
|
|
||||||
// So Create a new one.
|
|
||||||
aIdList.push_back( expectedId );
|
|
||||||
return expectedId;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function ComputeReferenceNumber
|
|
||||||
* Compute the reference number for components without reference number
|
|
||||||
* i.e. .m_NumRef member of each SCH_REFERENCE_LIST item not yet annotated
|
|
||||||
* in aComponentsList.
|
|
||||||
* if aUseSheetNum is false, this number starts from 1
|
|
||||||
* if aUseSheetNum is false, this number starts from from SheetNumber * aSheetIntervalId
|
|
||||||
*/
|
|
||||||
static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList,
|
|
||||||
bool aUseSheetNum, int aSheetIntervalId )
|
|
||||||
{
|
|
||||||
if ( aComponentsList.GetCount() == 0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
int LastReferenceNumber = 0;
|
|
||||||
int NumberOfUnits, Unit;
|
|
||||||
|
|
||||||
/* Components with an invisible reference (power...) always are re-annotated. */
|
|
||||||
aComponentsList.ResetHiddenReferences();
|
|
||||||
|
|
||||||
/* calculate index of the first component with the same reference prefix
|
|
||||||
* than the current component. All components having the same reference
|
|
||||||
* prefix will receive a reference number with consecutive values:
|
|
||||||
* IC .. will be set to IC4, IC4, IC5 ...
|
|
||||||
*/
|
|
||||||
unsigned first = 0;
|
|
||||||
|
|
||||||
/* calculate the last used number for this reference prefix: */
|
|
||||||
#ifdef USE_OLD_ALGO
|
|
||||||
int minRefId = 0;
|
|
||||||
|
|
||||||
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
|
|
||||||
if( aUseSheetNum )
|
|
||||||
minRefId = aComponentsList[first].m_SheetNum * aSheetIntervalId;
|
|
||||||
|
|
||||||
LastReferenceNumber = aComponentsList.GetLastReference( first, minRefId );
|
|
||||||
#else
|
|
||||||
int minRefId = 1;
|
|
||||||
|
|
||||||
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
|
|
||||||
if( aUseSheetNum )
|
|
||||||
minRefId = aComponentsList[first].m_SheetNum * aSheetIntervalId + 1;
|
|
||||||
|
|
||||||
// This is the list of all Id already in use for a given reference prefix.
|
|
||||||
// Will be refilled for each new reference prefix.
|
|
||||||
std::vector<int>idList;
|
|
||||||
aComponentsList.GetRefsInUse( first, idList, minRefId );
|
|
||||||
#endif
|
|
||||||
for( unsigned ii = 0; ii < aComponentsList.GetCount(); ii++ )
|
|
||||||
{
|
|
||||||
if( aComponentsList[ii].m_Flag )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( ( aComponentsList[first].CompareRef( aComponentsList[ii] ) != 0 )
|
|
||||||
|| ( aUseSheetNum
|
|
||||||
&& ( aComponentsList[first].m_SheetNum != aComponentsList[ii].m_SheetNum ) ) )
|
|
||||||
{
|
|
||||||
/* New reference found: we need a new ref number for this reference */
|
|
||||||
first = ii;
|
|
||||||
#ifdef USE_OLD_ALGO
|
|
||||||
minRefId = 0;
|
|
||||||
|
|
||||||
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
|
|
||||||
if( aUseSheetNum )
|
|
||||||
minRefId = aComponentsList[ii].m_SheetNum * aSheetIntervalId;
|
|
||||||
|
|
||||||
LastReferenceNumber = aComponentsList.GetLastReference( ii, minRefId );
|
|
||||||
#else
|
|
||||||
minRefId = 1;
|
|
||||||
|
|
||||||
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
|
|
||||||
if( aUseSheetNum )
|
|
||||||
minRefId = aComponentsList[ii].m_SheetNum * aSheetIntervalId + 1;
|
|
||||||
|
|
||||||
aComponentsList.GetRefsInUse( first, idList, minRefId );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Annotation of one part per package components (trivial case).
|
|
||||||
if( aComponentsList[ii].GetLibComponent()->GetPartCount() <= 1 )
|
|
||||||
{
|
|
||||||
if( aComponentsList[ii].m_IsNew )
|
|
||||||
{
|
|
||||||
#ifdef USE_OLD_ALGO
|
|
||||||
LastReferenceNumber++;
|
|
||||||
#else
|
|
||||||
LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
|
|
||||||
#endif
|
|
||||||
aComponentsList[ii].m_NumRef = LastReferenceNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) */
|
|
||||||
NumberOfUnits = aComponentsList[ii].GetLibComponent()->GetPartCount();
|
|
||||||
|
|
||||||
if( aComponentsList[ii].m_IsNew )
|
|
||||||
{
|
|
||||||
#ifdef USE_OLD_ALGO
|
|
||||||
LastReferenceNumber++;
|
|
||||||
#else
|
|
||||||
LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
|
|
||||||
#endif
|
|
||||||
aComponentsList[ii].m_NumRef = LastReferenceNumber;
|
|
||||||
|
|
||||||
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( aComponentsList[ii].m_Unit == Unit )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int found = aComponentsList.FindUnit( ii, Unit );
|
|
||||||
|
|
||||||
if( found >= 0 )
|
|
||||||
continue; /* this unit exists for this reference (unit already annotated) */
|
|
||||||
|
|
||||||
/* Search a component to annotate ( same prefix, same value, not annotated) */
|
|
||||||
for( unsigned jj = ii + 1; jj < aComponentsList.GetCount(); jj++ )
|
|
||||||
{
|
|
||||||
if( aComponentsList[jj].m_Flag ) // already tested
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( aComponentsList[ii].CompareRef( aComponentsList[jj] ) != 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( aComponentsList[jj].CompareValue( aComponentsList[ii] ) != 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( !aComponentsList[jj].m_IsNew )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Component without reference number found, annotate it if possible */
|
|
||||||
if( !aComponentsList[jj].IsPartsLocked()
|
|
||||||
|| ( aComponentsList[jj].m_Unit == Unit ) )
|
|
||||||
{
|
|
||||||
aComponentsList[jj].m_NumRef = aComponentsList[ii].m_NumRef;
|
|
||||||
aComponentsList[jj].m_Unit = Unit;
|
|
||||||
aComponentsList[jj].m_Flag = 1;
|
|
||||||
aComponentsList[jj].m_IsNew = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CheckAnnotate
|
* Function CheckAnnotate
|
||||||
* Check errors relatives to annotation:
|
* Check errors relatives to annotation:
|
||||||
|
@ -411,21 +193,15 @@ static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList,
|
||||||
* for multiple parts per package components :
|
* for multiple parts per package components :
|
||||||
* part number > number of parts
|
* part number > number of parts
|
||||||
* different values between parts
|
* different values between parts
|
||||||
* @param aMessageList = a wxArrayString to store messages. If NULL, they
|
* @param aMessageList = a wxArrayString to store messages.
|
||||||
* are displayed in a wxMessageBox
|
|
||||||
* @param aOneSheetOnly : true = search is made only in the current sheet
|
* @param aOneSheetOnly : true = search is made only in the current sheet
|
||||||
* false = search in whole hierarchy (usual search).
|
* false = search in whole hierarchy (usual search).
|
||||||
* @return errors count
|
* @return errors count
|
||||||
*/
|
*/
|
||||||
int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly )
|
int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly )
|
||||||
{
|
{
|
||||||
int error = 0;
|
|
||||||
wxString Buff;
|
|
||||||
wxString msg, cmpref;
|
|
||||||
|
|
||||||
/* build the screen list */
|
/* build the screen list */
|
||||||
SCH_SHEET_LIST SheetList;
|
SCH_SHEET_LIST SheetList;
|
||||||
|
|
||||||
SCH_REFERENCE_LIST ComponentsList;
|
SCH_REFERENCE_LIST ComponentsList;
|
||||||
|
|
||||||
/* Build the list of components */
|
/* Build the list of components */
|
||||||
|
@ -434,212 +210,5 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn
|
||||||
else
|
else
|
||||||
GetSheet()->GetComponents( ComponentsList );
|
GetSheet()->GetComponents( ComponentsList );
|
||||||
|
|
||||||
ComponentsList.SortByRefAndValue();
|
return ComponentsList.CheckAnnotation( aMessageList );
|
||||||
|
|
||||||
/* Break full components reference in name (prefix) and number: example:
|
|
||||||
* IC1 become IC, and 1 */
|
|
||||||
ComponentsList.SplitReferences();
|
|
||||||
|
|
||||||
/* count not yet annotated items or annotation error*/
|
|
||||||
for( unsigned ii = 0; ii < ComponentsList.GetCount(); ii++ )
|
|
||||||
{
|
|
||||||
msg.Empty();
|
|
||||||
Buff.Empty();
|
|
||||||
|
|
||||||
if( ComponentsList[ii].m_IsNew ) // Not yet annotated
|
|
||||||
{
|
|
||||||
if( ComponentsList[ii].m_NumRef >= 0 )
|
|
||||||
Buff << ComponentsList[ii].m_NumRef;
|
|
||||||
else
|
|
||||||
Buff = wxT( "?" );
|
|
||||||
|
|
||||||
cmpref = ComponentsList[ii].GetRef();
|
|
||||||
msg.Printf( _( "item not annotated: %s%s" ), GetChars( cmpref ), GetChars( Buff ) );
|
|
||||||
|
|
||||||
if( ( ComponentsList[ii].m_Unit > 0 ) && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) )
|
|
||||||
{
|
|
||||||
Buff.Printf( _( "( unit %d)" ), ComponentsList[ii].m_Unit );
|
|
||||||
msg << Buff;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aMessageList )
|
|
||||||
aMessageList->Add( msg + wxT( "\n" ) );
|
|
||||||
else
|
|
||||||
DisplayError( NULL, msg );
|
|
||||||
|
|
||||||
error++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Annotate error if unit selected does not exist ( i.e. > number of parts )
|
|
||||||
// Can happen if a component has changed in a lib, after a previous annotation
|
|
||||||
if( MAX( ComponentsList[ii].GetLibComponent()->GetPartCount(), 1 ) < ComponentsList[ii].m_Unit )
|
|
||||||
{
|
|
||||||
if( ComponentsList[ii].m_NumRef >= 0 )
|
|
||||||
Buff << ComponentsList[ii].m_NumRef;
|
|
||||||
else
|
|
||||||
Buff = wxT( "?" );
|
|
||||||
|
|
||||||
cmpref = ComponentsList[ii].GetRef();
|
|
||||||
|
|
||||||
msg.Printf( _( "Error item %s%s" ), GetChars( cmpref ), GetChars( Buff ) );
|
|
||||||
|
|
||||||
Buff.Printf( _( " unit %d and no more than %d parts" ),
|
|
||||||
ComponentsList[ii].m_Unit,
|
|
||||||
ComponentsList[ii].GetLibComponent()->GetPartCount() );
|
|
||||||
msg << Buff;
|
|
||||||
|
|
||||||
if( aMessageList )
|
|
||||||
aMessageList->Add( msg + wxT( "\n" ));
|
|
||||||
else
|
|
||||||
DisplayError( NULL, msg );
|
|
||||||
|
|
||||||
error++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( error )
|
|
||||||
return error;
|
|
||||||
|
|
||||||
// count the duplicated elements (if all are annotated)
|
|
||||||
int imax = ComponentsList.GetCount() - 1;
|
|
||||||
for( int ii = 0; (ii < imax) && (error < 4); ii++ )
|
|
||||||
{
|
|
||||||
msg.Empty();
|
|
||||||
Buff.Empty();
|
|
||||||
|
|
||||||
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( ComponentsList[ii].m_Unit == ComponentsList[ii + 1].m_Unit )
|
|
||||||
{
|
|
||||||
if( ComponentsList[ii].m_NumRef >= 0 )
|
|
||||||
Buff << ComponentsList[ii].m_NumRef;
|
|
||||||
else
|
|
||||||
Buff = wxT( "?" );
|
|
||||||
|
|
||||||
cmpref = ComponentsList[ii].GetRef();
|
|
||||||
|
|
||||||
msg.Printf( _( "Multiple item %s%s" ), GetChars( cmpref ), GetChars( Buff ) );
|
|
||||||
|
|
||||||
if( ( ComponentsList[ii].m_Unit > 0 )&& ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) )
|
|
||||||
{
|
|
||||||
Buff.Printf( _( " (unit %d)" ), ComponentsList[ii].m_Unit );
|
|
||||||
msg << Buff;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aMessageList )
|
|
||||||
aMessageList->Add( msg + wxT( "\n" ));
|
|
||||||
else
|
|
||||||
DisplayError( NULL, msg );
|
|
||||||
|
|
||||||
error++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test error if units are different but number of parts per package
|
|
||||||
* too high (ex U3 ( 1 part) and we find U3B this is an error) */
|
|
||||||
if( ComponentsList[ii].GetLibComponent()->GetPartCount()
|
|
||||||
!= ComponentsList[ii + 1].GetLibComponent()->GetPartCount() )
|
|
||||||
{
|
|
||||||
if( ComponentsList[ii].m_NumRef >= 0 )
|
|
||||||
Buff << ComponentsList[ii].m_NumRef;
|
|
||||||
else
|
|
||||||
Buff = wxT( "?" );
|
|
||||||
|
|
||||||
cmpref = ComponentsList[ii].GetRef();
|
|
||||||
msg.Printf( _( "Multiple item %s%s" ), GetChars( cmpref ), GetChars( Buff ) );
|
|
||||||
|
|
||||||
if( ( ComponentsList[ii].m_Unit > 0 ) && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) )
|
|
||||||
{
|
|
||||||
Buff.Printf( _( " (unit %d)" ), ComponentsList[ii].m_Unit );
|
|
||||||
msg << Buff;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aMessageList )
|
|
||||||
aMessageList->Add( msg + wxT( "\n" ));
|
|
||||||
else
|
|
||||||
DisplayError( NULL, msg );
|
|
||||||
|
|
||||||
error++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Error if values are different between units, for the same reference */
|
|
||||||
int next = ii + 1;
|
|
||||||
|
|
||||||
if( ComponentsList[ii].CompareValue( ComponentsList[next] ) != 0 )
|
|
||||||
{
|
|
||||||
wxString nextcmpref = ComponentsList[next].GetRef();
|
|
||||||
|
|
||||||
cmpref = ComponentsList[ii].GetRef();
|
|
||||||
|
|
||||||
#if defined(KICAD_GOST)
|
|
||||||
msg.Printf( _( "Diff values for %s%d.%c (%s) and %s%d.%c (%s)" ),
|
|
||||||
cmpref.GetData(),
|
|
||||||
ComponentsList[ii].m_NumRef,
|
|
||||||
ComponentsList[ii].m_Unit + '1' - 1,
|
|
||||||
GetChars( *ComponentsList[ii].m_Value ),
|
|
||||||
GetChars( nextcmpref ),
|
|
||||||
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(),
|
|
||||||
ComponentsList[ii].m_NumRef,
|
|
||||||
ComponentsList[ii].m_Unit + 'A' - 1,
|
|
||||||
GetChars( *ComponentsList[ii].m_Value ),
|
|
||||||
GetChars( nextcmpref ),
|
|
||||||
ComponentsList[next].m_NumRef,
|
|
||||||
ComponentsList[next].m_Unit + 'A' - 1,
|
|
||||||
GetChars( *ComponentsList[next].m_Value ) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( aMessageList )
|
|
||||||
aMessageList->Add( msg + wxT( "\n" ));
|
|
||||||
else
|
|
||||||
DisplayError( NULL, msg );
|
|
||||||
|
|
||||||
error++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// count the duplicated time stamps
|
|
||||||
ComponentsList.SortComponentsByTimeStamp();
|
|
||||||
|
|
||||||
for( int ii = 0; ( ii < imax ) && ( error < 4 ); ii++ )
|
|
||||||
{
|
|
||||||
if( ( ComponentsList[ii].m_TimeStamp != ComponentsList[ii + 1].m_TimeStamp )
|
|
||||||
|| ( ComponentsList[ii].GetSheetPath() != ComponentsList[ii + 1].GetSheetPath() ) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Same time stamp found. */
|
|
||||||
wxString nextcmpref;
|
|
||||||
wxString full_path;
|
|
||||||
|
|
||||||
full_path.Printf( wxT( "%s%8.8X" ),
|
|
||||||
GetChars( ComponentsList[ii].GetSheetPath().Path() ),
|
|
||||||
ComponentsList[ii].m_TimeStamp );
|
|
||||||
|
|
||||||
cmpref = ComponentsList[ii].GetRef();
|
|
||||||
nextcmpref = ComponentsList[ii + 1].GetRef();
|
|
||||||
|
|
||||||
msg.Printf( _( "duplicate time stamp (%s) for %s%d and %s%d" ),
|
|
||||||
GetChars( full_path ),
|
|
||||||
GetChars( cmpref ), ComponentsList[ii].m_NumRef,
|
|
||||||
GetChars( nextcmpref ), ComponentsList[ii + 1].m_NumRef );
|
|
||||||
|
|
||||||
if( aMessageList )
|
|
||||||
aMessageList->Add( msg + wxT( "\n" ));
|
|
||||||
else
|
|
||||||
DisplayError( NULL, msg );
|
|
||||||
|
|
||||||
error++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#include "sch_component.h"
|
#include "sch_component.h"
|
||||||
|
|
||||||
|
|
||||||
|
//#define USE_OLD_ALGO
|
||||||
|
|
||||||
|
|
||||||
bool SCH_REFERENCE_LIST::sortByXPosition( const SCH_REFERENCE& item1,
|
bool SCH_REFERENCE_LIST::sortByXPosition( const SCH_REFERENCE& item1,
|
||||||
const SCH_REFERENCE& item2 )
|
const SCH_REFERENCE& item2 )
|
||||||
|
@ -182,9 +184,6 @@ int SCH_REFERENCE_LIST::FindUnit( size_t aIndex, int aUnit )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Remove sub components from the list, when multiples parts per package are
|
|
||||||
* found in this list
|
|
||||||
*/
|
|
||||||
void SCH_REFERENCE_LIST::RemoveSubComponentsFromList()
|
void SCH_REFERENCE_LIST::RemoveSubComponentsFromList()
|
||||||
{
|
{
|
||||||
SCH_COMPONENT* libItem;
|
SCH_COMPONENT* libItem;
|
||||||
|
@ -197,6 +196,7 @@ void SCH_REFERENCE_LIST::RemoveSubComponentsFromList()
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
|
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
|
||||||
{
|
{
|
||||||
|
|
||||||
libItem = componentFlatList[ii].m_RootCmp;
|
libItem = componentFlatList[ii].m_RootCmp;
|
||||||
if( libItem == NULL )
|
if( libItem == NULL )
|
||||||
continue;
|
continue;
|
||||||
|
@ -236,8 +236,8 @@ void SCH_REFERENCE_LIST::GetRefsInUse( int aIndex, std::vector< int >& aIdList,
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
|
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
|
||||||
{
|
{
|
||||||
if( ( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) == 0 )
|
if( ( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) == 0 )
|
||||||
&& ( componentFlatList[ii].m_NumRef >= aMinRefId ) )
|
&& ( componentFlatList[ii].m_NumRef >= aMinRefId ) )
|
||||||
aIdList.push_back( componentFlatList[ii].m_NumRef );
|
aIdList.push_back( componentFlatList[ii].m_NumRef );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +272,391 @@ int SCH_REFERENCE_LIST::GetLastReference( int aIndex, int aMinValue )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SCH_REFERENCE_LIST::CreateFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue )
|
||||||
|
{
|
||||||
|
int expectedId = aFirstValue;
|
||||||
|
|
||||||
|
// We search for expected Id a value >= aFirstValue.
|
||||||
|
// Skip existing Id < aFirstValue
|
||||||
|
unsigned ii = 0;
|
||||||
|
|
||||||
|
for( ; ii < aIdList.size(); ii++ )
|
||||||
|
{
|
||||||
|
if( expectedId <= aIdList[ii] )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ids are sorted by increasing value, from aFirstValue
|
||||||
|
// So we search from aFirstValue the first not used value, i.e. the first hole in list.
|
||||||
|
for( ; ii < aIdList.size(); ii++ )
|
||||||
|
{
|
||||||
|
if( expectedId != aIdList[ii] ) // This id is not yet used.
|
||||||
|
{
|
||||||
|
// Insert this free Id, in order to keep list sorted
|
||||||
|
aIdList.insert( aIdList.begin() + ii, expectedId );
|
||||||
|
return expectedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All existing Id are tested, and all values are found in use.
|
||||||
|
// So Create a new one.
|
||||||
|
aIdList.push_back( expectedId );
|
||||||
|
return expectedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId )
|
||||||
|
{
|
||||||
|
if ( componentFlatList.size() == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int LastReferenceNumber = 0;
|
||||||
|
int NumberOfUnits, Unit;
|
||||||
|
|
||||||
|
/* Components with an invisible reference (power...) always are re-annotated. */
|
||||||
|
ResetHiddenReferences();
|
||||||
|
|
||||||
|
/* calculate index of the first component with the same reference prefix
|
||||||
|
* than the current component. All components having the same reference
|
||||||
|
* prefix will receive a reference number with consecutive values:
|
||||||
|
* IC .. will be set to IC4, IC4, IC5 ...
|
||||||
|
*/
|
||||||
|
unsigned first = 0;
|
||||||
|
|
||||||
|
/* calculate the last used number for this reference prefix: */
|
||||||
|
#ifdef USE_OLD_ALGO
|
||||||
|
int minRefId = 0;
|
||||||
|
|
||||||
|
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
|
||||||
|
if( aUseSheetNum )
|
||||||
|
minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId;
|
||||||
|
|
||||||
|
LastReferenceNumber = GetLastReference( first, minRefId );
|
||||||
|
#else
|
||||||
|
int minRefId = 1;
|
||||||
|
|
||||||
|
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
|
||||||
|
if( aUseSheetNum )
|
||||||
|
minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId + 1;
|
||||||
|
|
||||||
|
// This is the list of all Id already in use for a given reference prefix.
|
||||||
|
// Will be refilled for each new reference prefix.
|
||||||
|
std::vector<int>idList;
|
||||||
|
GetRefsInUse( first, idList, minRefId );
|
||||||
|
#endif
|
||||||
|
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
|
||||||
|
{
|
||||||
|
if( componentFlatList[ii].m_Flag )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( ( componentFlatList[first].CompareRef( componentFlatList[ii] ) != 0 )
|
||||||
|
|| ( aUseSheetNum && ( componentFlatList[first].m_SheetNum != componentFlatList[ii].m_SheetNum ) ) )
|
||||||
|
{
|
||||||
|
/* New reference found: we need a new ref number for this reference */
|
||||||
|
first = ii;
|
||||||
|
#ifdef USE_OLD_ALGO
|
||||||
|
minRefId = 0;
|
||||||
|
|
||||||
|
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
|
||||||
|
if( aUseSheetNum )
|
||||||
|
minRefId = componentFlatList[ii].m_SheetNum * aSheetIntervalId;
|
||||||
|
|
||||||
|
LastReferenceNumber = componentFlatList.GetLastReference( ii, minRefId );
|
||||||
|
#else
|
||||||
|
minRefId = 1;
|
||||||
|
|
||||||
|
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
|
||||||
|
if( aUseSheetNum )
|
||||||
|
minRefId = componentFlatList[ii].m_SheetNum * aSheetIntervalId + 1;
|
||||||
|
|
||||||
|
GetRefsInUse( first, idList, minRefId );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Annotation of one part per package components (trivial case).
|
||||||
|
if( componentFlatList[ii].GetLibComponent()->GetPartCount() <= 1 )
|
||||||
|
{
|
||||||
|
if( componentFlatList[ii].m_IsNew )
|
||||||
|
{
|
||||||
|
#ifdef USE_OLD_ALGO
|
||||||
|
LastReferenceNumber++;
|
||||||
|
#else
|
||||||
|
LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
|
||||||
|
#endif
|
||||||
|
componentFlatList[ii].m_NumRef = LastReferenceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentFlatList[ii].m_Unit = 1;
|
||||||
|
componentFlatList[ii].m_Flag = 1;
|
||||||
|
componentFlatList[ii].m_IsNew = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Annotation of multi-part components ( n parts per package ) (complex case) */
|
||||||
|
NumberOfUnits = componentFlatList[ii].GetLibComponent()->GetPartCount();
|
||||||
|
|
||||||
|
if( componentFlatList[ii].m_IsNew )
|
||||||
|
{
|
||||||
|
#ifdef USE_OLD_ALGO
|
||||||
|
LastReferenceNumber++;
|
||||||
|
#else
|
||||||
|
LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
|
||||||
|
#endif
|
||||||
|
componentFlatList[ii].m_NumRef = LastReferenceNumber;
|
||||||
|
|
||||||
|
if( !componentFlatList[ii].IsPartsLocked() )
|
||||||
|
componentFlatList[ii].m_Unit = 1;
|
||||||
|
|
||||||
|
componentFlatList[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( componentFlatList[ii].m_Unit == Unit )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int found = FindUnit( ii, Unit );
|
||||||
|
|
||||||
|
if( found >= 0 )
|
||||||
|
continue; /* this unit exists for this reference (unit already annotated) */
|
||||||
|
|
||||||
|
/* Search a component to annotate ( same prefix, same value, not annotated) */
|
||||||
|
for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ )
|
||||||
|
{
|
||||||
|
if( componentFlatList[jj].m_Flag ) // already tested
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( componentFlatList[ii].CompareRef( componentFlatList[jj] ) != 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( componentFlatList[jj].CompareValue( componentFlatList[ii] ) != 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( !componentFlatList[jj].m_IsNew )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Component without reference number found, annotate it if possible */
|
||||||
|
if( !componentFlatList[jj].IsPartsLocked()
|
||||||
|
|| ( componentFlatList[jj].m_Unit == Unit ) )
|
||||||
|
{
|
||||||
|
componentFlatList[jj].m_NumRef = componentFlatList[ii].m_NumRef;
|
||||||
|
componentFlatList[jj].m_Unit = Unit;
|
||||||
|
componentFlatList[jj].m_Flag = 1;
|
||||||
|
componentFlatList[jj].m_IsNew = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SCH_REFERENCE_LIST::CheckAnnotation( wxArrayString* aMessageList )
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
wxString tmp;
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
SortByRefAndValue();
|
||||||
|
|
||||||
|
// Spiit reference designators into name (prefix) and number: IC1 becomes IC, and 1.
|
||||||
|
SplitReferences();
|
||||||
|
|
||||||
|
// count not yet annotated items or annotation error.
|
||||||
|
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
|
||||||
|
{
|
||||||
|
msg.Empty();
|
||||||
|
tmp.Empty();
|
||||||
|
|
||||||
|
if( componentFlatList[ii].m_IsNew ) // Not yet annotated
|
||||||
|
{
|
||||||
|
if( componentFlatList[ii].m_NumRef >= 0 )
|
||||||
|
tmp << componentFlatList[ii].m_NumRef;
|
||||||
|
else
|
||||||
|
tmp = wxT( "?" );
|
||||||
|
|
||||||
|
msg.Printf( _( "Item not annotated: %s%s" ),
|
||||||
|
GetChars( componentFlatList[ii].GetRef() ), GetChars( tmp ) );
|
||||||
|
|
||||||
|
if( ( componentFlatList[ii].m_Unit > 0 )
|
||||||
|
&& ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) )
|
||||||
|
{
|
||||||
|
tmp.Printf( _( " (unit %d)" ), componentFlatList[ii].m_Unit );
|
||||||
|
msg << tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aMessageList )
|
||||||
|
aMessageList->Add( msg + wxT( "\n" ) );
|
||||||
|
|
||||||
|
error++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error if unit number selected does not exist ( greater than the number of
|
||||||
|
// parts in the component ). This can happen if a component has changed in a
|
||||||
|
// library after a previous annotation.
|
||||||
|
if( MAX( componentFlatList[ii].GetLibComponent()->GetPartCount(), 1 )
|
||||||
|
< componentFlatList[ii].m_Unit )
|
||||||
|
{
|
||||||
|
if( componentFlatList[ii].m_NumRef >= 0 )
|
||||||
|
tmp << componentFlatList[ii].m_NumRef;
|
||||||
|
else
|
||||||
|
tmp = wxT( "?" );
|
||||||
|
|
||||||
|
msg.Printf( _( "Error item %s%s" ), GetChars( componentFlatList[ii].GetRef() ),
|
||||||
|
GetChars( tmp ) );
|
||||||
|
|
||||||
|
tmp.Printf( _( " unit %d and no more than %d parts" ),
|
||||||
|
componentFlatList[ii].m_Unit,
|
||||||
|
componentFlatList[ii].GetLibComponent()->GetPartCount() );
|
||||||
|
msg << tmp;
|
||||||
|
|
||||||
|
if( aMessageList )
|
||||||
|
aMessageList->Add( msg + wxT( "\n" ) );
|
||||||
|
|
||||||
|
error++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( error )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// count the duplicated elements (if all are annotated)
|
||||||
|
int imax = componentFlatList.size() - 1;
|
||||||
|
|
||||||
|
for( int ii = 0; (ii < imax) && (error < 4); ii++ )
|
||||||
|
{
|
||||||
|
msg.Empty();
|
||||||
|
tmp.Empty();
|
||||||
|
|
||||||
|
if( ( componentFlatList[ii].CompareRef( componentFlatList[ii + 1] ) != 0 )
|
||||||
|
|| ( componentFlatList[ii].m_NumRef != componentFlatList[ii + 1].m_NumRef ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Same reference found. If same unit, error!
|
||||||
|
if( componentFlatList[ii].m_Unit == componentFlatList[ii + 1].m_Unit )
|
||||||
|
{
|
||||||
|
if( componentFlatList[ii].m_NumRef >= 0 )
|
||||||
|
tmp << componentFlatList[ii].m_NumRef;
|
||||||
|
else
|
||||||
|
tmp = wxT( "?" );
|
||||||
|
|
||||||
|
msg.Printf( _( "Multiple item %s%s" ),
|
||||||
|
GetChars( componentFlatList[ii].GetRef() ), GetChars( tmp ) );
|
||||||
|
|
||||||
|
if( ( componentFlatList[ii].m_Unit > 0 )
|
||||||
|
&& ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) )
|
||||||
|
{
|
||||||
|
tmp.Printf( _( " (unit %d)" ), componentFlatList[ii].m_Unit );
|
||||||
|
msg << tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aMessageList )
|
||||||
|
aMessageList->Add( msg + wxT( "\n" ) );
|
||||||
|
|
||||||
|
error++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test error if units are different but number of parts per package
|
||||||
|
* too high (ex U3 ( 1 part) and we find U3B this is an error) */
|
||||||
|
if( componentFlatList[ii].GetLibComponent()->GetPartCount()
|
||||||
|
!= componentFlatList[ii + 1].GetLibComponent()->GetPartCount() )
|
||||||
|
{
|
||||||
|
if( componentFlatList[ii].m_NumRef >= 0 )
|
||||||
|
tmp << componentFlatList[ii].m_NumRef;
|
||||||
|
else
|
||||||
|
tmp = wxT( "?" );
|
||||||
|
|
||||||
|
msg.Printf( _( "Multiple item %s%s" ),
|
||||||
|
GetChars( componentFlatList[ii].GetRef() ), GetChars( tmp ) );
|
||||||
|
|
||||||
|
if( ( componentFlatList[ii].m_Unit > 0 )
|
||||||
|
&& ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) )
|
||||||
|
{
|
||||||
|
tmp.Printf( _( " (unit %d)" ), componentFlatList[ii].m_Unit );
|
||||||
|
msg << tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aMessageList )
|
||||||
|
aMessageList->Add( msg + wxT( "\n" ));
|
||||||
|
|
||||||
|
error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error if values are different between units, for the same reference */
|
||||||
|
int next = ii + 1;
|
||||||
|
|
||||||
|
if( componentFlatList[ii].CompareValue( componentFlatList[next] ) != 0 )
|
||||||
|
{
|
||||||
|
#if defined(KICAD_GOST)
|
||||||
|
msg.Printf( _( "Different values for %s%d.%c (%s) and %s%d.%c (%s)" ),
|
||||||
|
GetChars( componentFlatList[ii].GetRef() ),
|
||||||
|
componentFlatList[ii].m_NumRef,
|
||||||
|
componentFlatList[ii].m_Unit + '1' - 1,
|
||||||
|
GetChars( *componentFlatList[ii].m_Value ),
|
||||||
|
GetChars( componentFlatList[next].GetRef() ),
|
||||||
|
componentFlatList[next].m_NumRef,
|
||||||
|
componentFlatList[next].m_Unit + '1' - 1,
|
||||||
|
componentFlatList[next].m_Value->GetData() );
|
||||||
|
#else
|
||||||
|
msg.Printf( _( "Different values for %s%d%c (%s) and %s%d%c (%s)" ),
|
||||||
|
GetChars( componentFlatList[ii].GetRef() ),
|
||||||
|
componentFlatList[ii].m_NumRef,
|
||||||
|
componentFlatList[ii].m_Unit + 'A' - 1,
|
||||||
|
GetChars( *componentFlatList[ii].m_Value ),
|
||||||
|
GetChars( componentFlatList[next].GetRef() ),
|
||||||
|
componentFlatList[next].m_NumRef,
|
||||||
|
componentFlatList[next].m_Unit + 'A' - 1,
|
||||||
|
GetChars( *componentFlatList[next].m_Value ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( aMessageList )
|
||||||
|
aMessageList->Add( msg + wxT( "\n" ));
|
||||||
|
|
||||||
|
error++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// count the duplicated time stamps
|
||||||
|
SortByTimeStamp();
|
||||||
|
|
||||||
|
for( int ii = 0; ( ii < imax ) && ( error < 4 ); ii++ )
|
||||||
|
{
|
||||||
|
if( ( componentFlatList[ii].m_TimeStamp != componentFlatList[ii + 1].m_TimeStamp )
|
||||||
|
|| ( componentFlatList[ii].GetSheetPath() != componentFlatList[ii + 1].GetSheetPath() ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Same time stamp found. */
|
||||||
|
wxString full_path;
|
||||||
|
|
||||||
|
full_path.Printf( wxT( "%s%8.8X" ),
|
||||||
|
GetChars( componentFlatList[ii].GetSheetPath().Path() ),
|
||||||
|
componentFlatList[ii].m_TimeStamp );
|
||||||
|
|
||||||
|
msg.Printf( _( "Duplicate time stamp (%s) for %s%d and %s%d" ),
|
||||||
|
GetChars( full_path ),
|
||||||
|
GetChars( componentFlatList[ii].GetRef() ), componentFlatList[ii].m_NumRef,
|
||||||
|
GetChars( componentFlatList[ii + 1].GetRef() ),
|
||||||
|
componentFlatList[ii + 1].m_NumRef );
|
||||||
|
|
||||||
|
if( aMessageList )
|
||||||
|
aMessageList->Add( msg + wxT( "\n" ));
|
||||||
|
|
||||||
|
error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SCH_REFERENCE::SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_COMPONENT* aLibComponent,
|
SCH_REFERENCE::SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_COMPONENT* aLibComponent,
|
||||||
SCH_SHEET_PATH& aSheetPath )
|
SCH_SHEET_PATH& aSheetPath )
|
||||||
{
|
{
|
||||||
|
@ -364,4 +749,3 @@ void SCH_REFERENCE::Split()
|
||||||
SetRefStr( refText );
|
SetRefStr( refText );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -649,7 +649,7 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef( FILE* f,
|
||||||
isMulti = entry->IsMulti();
|
isMulti = entry->IsMulti();
|
||||||
|
|
||||||
if( isMulti && aIncludeSubComponents )
|
if( isMulti && aIncludeSubComponents )
|
||||||
subRef = LIB_COMPONENT::ReturnSubReference( aList[ii].m_Unit );
|
subRef = LIB_COMPONENT::ReturnSubReference( aList[ii].GetUnit() );
|
||||||
else
|
else
|
||||||
subRef.Empty();
|
subRef.Empty();
|
||||||
|
|
||||||
|
@ -786,8 +786,8 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart( FILE* f, SCH_REFERENCE_LIST& aL
|
||||||
multi = 0;
|
multi = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( multi && aList[ii].m_Unit > 0 )
|
if ( multi && aList[ii].GetUnit() > 0 )
|
||||||
unitId.Printf( wxT("%c"), 'A' -1 + aList[ii].m_Unit );
|
unitId.Printf( wxT("%c"), 'A' -1 + aList[ii].GetUnit() );
|
||||||
else
|
else
|
||||||
unitId.Empty();
|
unitId.Empty();
|
||||||
|
|
||||||
|
@ -901,7 +901,7 @@ int DIALOG_BUILD_BOM::PrintComponentsListByVal( FILE* f,
|
||||||
wxString subRef;
|
wxString subRef;
|
||||||
|
|
||||||
if( isMulti && aIncludeSubComponents )
|
if( isMulti && aIncludeSubComponents )
|
||||||
subRef = LIB_COMPONENT::ReturnSubReference( aList[ii].m_Unit );
|
subRef = LIB_COMPONENT::ReturnSubReference( aList[ii].GetUnit() );
|
||||||
else
|
else
|
||||||
subRef.Empty();
|
subRef.Empty();
|
||||||
|
|
||||||
|
|
|
@ -66,24 +66,19 @@ private:
|
||||||
LIB_COMPONENT* m_Entry; ///< The source component from a library.
|
LIB_COMPONENT* m_Entry; ///< The source component from a library.
|
||||||
wxPoint m_CmpPos; ///< The physical position of the component in schematic
|
wxPoint m_CmpPos; ///< The physical position of the component in schematic
|
||||||
///< used to annotate by X or Y position
|
///< used to annotate by X or Y position
|
||||||
|
int m_Unit; ///< The unit number for components with multiple parts
|
||||||
|
///< per package.
|
||||||
SCH_SHEET_PATH m_SheetPath; ///< The sheet path for this reference.
|
SCH_SHEET_PATH m_SheetPath; ///< The sheet path for this reference.
|
||||||
|
bool m_IsNew; ///< True if not yet annotated.
|
||||||
|
int m_SheetNum; ///< The sheet number for the reference.
|
||||||
|
unsigned long m_TimeStamp; ///< The time stamp for the reference.
|
||||||
|
wxString* m_Value; ///< The component value of the refernce. It is the
|
||||||
|
///< same for all instances.
|
||||||
|
int m_NumRef; ///< The numeric part of the reference designator.
|
||||||
|
int m_Flag;
|
||||||
|
|
||||||
friend class SCH_REFERENCE_LIST;
|
friend class SCH_REFERENCE_LIST;
|
||||||
|
|
||||||
public:
|
|
||||||
int m_Unit; /* Selected part (For multi parts per
|
|
||||||
* package) depending on sheet path */
|
|
||||||
int m_SheetNum; // the sheet num 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) */
|
|
||||||
int m_NumRef; /* Reference number (for IC1, this is
|
|
||||||
* 1) ) depending on sheet path*/
|
|
||||||
int m_Flag; /* flag for computations */
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SCH_REFERENCE()
|
SCH_REFERENCE()
|
||||||
|
@ -108,6 +103,10 @@ public:
|
||||||
|
|
||||||
SCH_SHEET_PATH GetSheetPath() const { return m_SheetPath; }
|
SCH_SHEET_PATH GetSheetPath() const { return m_SheetPath; }
|
||||||
|
|
||||||
|
int GetUnit() const { return m_Unit; }
|
||||||
|
|
||||||
|
void SetSheetNumber( int aSheetNumber ) { m_SheetNum = aSheetNumber; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Annotate
|
* Function Annotate
|
||||||
* updates the annotation of the component according the the current object state.
|
* updates the annotation of the component according the the current object state.
|
||||||
|
@ -165,9 +164,9 @@ public:
|
||||||
/**
|
/**
|
||||||
* Class SCH_REFERENCE_LIST
|
* Class SCH_REFERENCE_LIST
|
||||||
* is used create a flattened list of components because in a complex hierarchy, a component
|
* is used create a flattened list of components because in a complex hierarchy, a component
|
||||||
* can used more than once and its reference designator is dependent on the sheet path for the
|
* can be used more than once and its reference designator is dependent on the sheet path for
|
||||||
* same component. This flattened list is used for netlist generation, BOM generation, and
|
* the same component. This flattened list is used for netlist generation, BOM generation,
|
||||||
* schematic annotation.
|
* and schematic annotation.
|
||||||
*/
|
*/
|
||||||
class SCH_REFERENCE_LIST
|
class SCH_REFERENCE_LIST
|
||||||
{
|
{
|
||||||
|
@ -262,6 +261,38 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Annotate
|
||||||
|
* set the reference designators in the list that have not been annotated.
|
||||||
|
* @param aUseSheetNum Set to true to start annotation for each sheet at the sheet number
|
||||||
|
* times \a aSheetIntervalId. Otherwise annotate incrementally.
|
||||||
|
* @param aSheetIntervalId The per sheet reference designator multiplier.
|
||||||
|
* <p>
|
||||||
|
* If a the sheet number is 2 and \a aSheetIntervalId is 100, then the first reference
|
||||||
|
* designator would be 201 and the last reference designator would be 299 when no overlap
|
||||||
|
* occurs with sheet number 3. If there are 150 items in sheet number 2, then items are
|
||||||
|
* referenced U201 to U351, and items in sheet 3 start from U352
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
void Annotate( bool aUseSheetNum, int aSheetIntervalId );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CheckAnnotation
|
||||||
|
* check for annotations errors.
|
||||||
|
* <p>
|
||||||
|
* The following annotation error conditions are tested:
|
||||||
|
* <ul>
|
||||||
|
* <li>Components not annotated.</li>
|
||||||
|
* <li>Components having the same reference designator (duplicates).</li>
|
||||||
|
* <li>Components with multiple parts per package having different reference designators.</li>
|
||||||
|
* <li>Components with multiple parts per package with invalid part count.</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
* @param aMessageList A wxArrayString to store error messages.
|
||||||
|
* @return The number of errors found.
|
||||||
|
*/
|
||||||
|
int CheckAnnotation( wxArrayString* aMessageList );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function sortByXCoordinate
|
* Function sortByXCoordinate
|
||||||
* sorts the list of references by X position.
|
* sorts the list of references by X position.
|
||||||
|
@ -305,7 +336,7 @@ public:
|
||||||
* sort the flat list by Time Stamp.
|
* sort the flat list by Time Stamp.
|
||||||
* Useful to detect duplicate Time Stamps
|
* Useful to detect duplicate Time Stamps
|
||||||
*/
|
*/
|
||||||
void SortComponentsByTimeStamp()
|
void SortByTimeStamp()
|
||||||
{
|
{
|
||||||
sort( componentFlatList.begin(), componentFlatList.end(), sortByTimeStamp );
|
sort( componentFlatList.begin(), componentFlatList.end(), sortByTimeStamp );
|
||||||
}
|
}
|
||||||
|
@ -417,6 +448,19 @@ private:
|
||||||
static bool sortByValueOnly( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
|
static bool sortByValueOnly( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
|
||||||
|
|
||||||
static bool sortByReferenceOnly( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
|
static bool sortByReferenceOnly( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CreateFirstFreeRefId
|
||||||
|
* searches for the first free reference number in \a aListId of reference numbers in use.
|
||||||
|
* This function just searches for a hole in a list of incremented numbers, this list must
|
||||||
|
* be sorted by increasing values and each value can be stored only once. The new value
|
||||||
|
* is added to the list.
|
||||||
|
* @see BuildRefIdInUseList to prepare this list
|
||||||
|
* @param aIdList The buffer that contains the reference numbers in use.
|
||||||
|
* @param aFirstValue The first expected free value
|
||||||
|
* @return The first free (not yet used) value.
|
||||||
|
*/
|
||||||
|
int CreateFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -341,7 +341,7 @@ void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SCH_REFERENCE reference = SCH_REFERENCE( component, entry, *this );
|
SCH_REFERENCE reference = SCH_REFERENCE( component, entry, *this );
|
||||||
reference.m_SheetNum = sheetnumber;
|
reference.SetSheetNumber( sheetnumber );
|
||||||
aReferences.AddItem( reference );
|
aReferences.AddItem( reference );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,7 @@ DIALOG_BLOCK_OPTIONS::DIALOG_BLOCK_OPTIONS( WinEDA_BasePcbFrame* aParent,
|
||||||
m_Include_Edges_Items->SetValue( blockIncludeBoardOutlineLayer );
|
m_Include_Edges_Items->SetValue( blockIncludeBoardOutlineLayer );
|
||||||
m_Include_PcbTextes->SetValue( blockIncludePcbTexts );
|
m_Include_PcbTextes->SetValue( blockIncludePcbTexts );
|
||||||
m_DrawBlockItems->SetValue( blockDrawItems );
|
m_DrawBlockItems->SetValue( blockDrawItems );
|
||||||
|
m_sdbSizer1OK->SetDefault();
|
||||||
SetFocus();
|
SetFocus();
|
||||||
GetSizer()->SetSizeHints( this );
|
GetSizer()->SetSizeHints( this );
|
||||||
Centre();
|
Centre();
|
||||||
|
|
Loading…
Reference in New Issue