Finish work to enhance annotation algorithm.
Fix a minor warning when starting Kicad in debug mode (wxWidgets 2.9.1 specific)
This commit is contained in:
parent
92c69a9c96
commit
784c04203e
|
@ -680,7 +680,11 @@ bool WinEDA_App::SetLanguage( bool first_time )
|
|||
delete m_Locale;
|
||||
m_Locale = new wxLocale;
|
||||
|
||||
#if wxCHECK_VERSION( 2, 9, 0 )
|
||||
if( !m_Locale->Init( m_LanguageId ) )
|
||||
#else
|
||||
if( !m_Locale->Init( m_LanguageId, wxLOCALE_CONV_ENCODING ) )
|
||||
#endif
|
||||
{
|
||||
wxLogDebug( wxT("This language is not supported by the system.") );
|
||||
|
||||
|
|
|
@ -19,14 +19,11 @@
|
|||
#include "sch_component.h"
|
||||
#include "lib_pin.h"
|
||||
|
||||
//#define USE_OLD_ALGO
|
||||
|
||||
static void BreakReference( SCH_REFERENCE_LIST& aComponentsList );
|
||||
static void ReAnnotateComponents( SCH_REFERENCE_LIST& aComponentsList );
|
||||
static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList, bool aUseSheetNum );
|
||||
static int GetLastReferenceNumber( int aObjet,SCH_REFERENCE_LIST& aComponentsList );
|
||||
static int ExistUnit( int aObjet, int aUnit, SCH_REFERENCE_LIST& aComponentList );
|
||||
|
||||
|
||||
/**
|
||||
* Function DeleteAnnotation
|
||||
* Remove current component annotations
|
||||
|
@ -109,7 +106,7 @@ void SCH_EDIT_FRAME::AnnotateComponents(
|
|||
// Update the screen date.
|
||||
screens.SetDate( GenDate() );
|
||||
|
||||
// Set sheet number and total sheet counts.
|
||||
// Set sheet number and number of sheets.
|
||||
SetSheetNumberAndCount();
|
||||
|
||||
/* Build component list */
|
||||
|
@ -124,7 +121,7 @@ void SCH_EDIT_FRAME::AnnotateComponents(
|
|||
|
||||
/* Break full components reference in name (prefix) and number:
|
||||
* example: IC1 become IC, and 1 */
|
||||
BreakReference( references );
|
||||
references.SplitReferences( );
|
||||
|
||||
bool useSheetNum = false;
|
||||
switch( sortOption )
|
||||
|
@ -152,36 +149,126 @@ void SCH_EDIT_FRAME::AnnotateComponents(
|
|||
break;
|
||||
}
|
||||
|
||||
/* Recalculate reference numbers */
|
||||
// Recalculate and update reference numbers in schematic
|
||||
ComputeReferenceNumber( references, useSheetNum );
|
||||
ReAnnotateComponents( references );
|
||||
references.UpdateAnnotation();
|
||||
|
||||
/* Final control (just in case ... )*/
|
||||
CheckAnnotate( NULL, !annotateSchematic );
|
||||
OnModify();
|
||||
|
||||
// Update on screen refences, that can be modified by previous calculations:
|
||||
m_CurrentSheet->UpdateAllScreenReferences();
|
||||
SetSheetNumberAndCount();
|
||||
|
||||
DrawPanel->Refresh( true );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update the reference component for the schematic project (or the current sheet)
|
||||
#ifdef USE_OLD_ALGO
|
||||
/** helper function
|
||||
* Search the last used (greatest) reference number in the component list
|
||||
* for the prefix reference given by Objet
|
||||
* The component list must be sorted.
|
||||
*
|
||||
* @param aObjet = reference item ( aComponentsList[aObjet].m_TextRef is
|
||||
* the search pattern)
|
||||
* @param aComponentsList = list of items
|
||||
* @param aMinValue = min value for the current search
|
||||
*/
|
||||
static void ReAnnotateComponents( SCH_REFERENCE_LIST& aComponentList )
|
||||
static int GetLastNumberInReference( int aObjet,SCH_REFERENCE_LIST& aComponentsList,
|
||||
int aMinValue )
|
||||
{
|
||||
/* update the reference numbers */
|
||||
for( unsigned ii = 0; ii < aComponentList.GetCount(); ii++ )
|
||||
int lastNumber = aMinValue;
|
||||
|
||||
for( unsigned ii = 0; ii < aComponentsList.GetCount(); ii++ )
|
||||
{
|
||||
aComponentList[ii].Annotate();
|
||||
// search only for the current reference prefix:
|
||||
if( aComponentsList[aObjet].CompareRef( aComponentsList[ii] ) != 0 )
|
||||
continue;
|
||||
|
||||
// update max value for the current reference prefix
|
||||
if( lastNumber < aComponentsList[ii].m_NumRef )
|
||||
lastNumber = aComponentsList[ii].m_NumRef;
|
||||
}
|
||||
|
||||
return lastNumber;
|
||||
}
|
||||
|
||||
#else
|
||||
/**
|
||||
* helper function BuildRefIdInUseList
|
||||
* creates the list of reference numbers in use for a given reference prefix.
|
||||
* @param aObjet = the current component index to use for reference prefix filtering.
|
||||
* @param aComponentsList = the full list of components
|
||||
* @param aIdList = the buffer to fill
|
||||
* @param aMinRefId = the min id value to store. all values < aMinRefId are ignored
|
||||
*/
|
||||
static void BuildRefIdInUseList( int aObjet,SCH_REFERENCE_LIST& aComponentsList,
|
||||
std::vector<int>& aIdList, int aMinRefId )
|
||||
{
|
||||
aIdList.clear();
|
||||
|
||||
for( unsigned ii = 0; ii < aComponentsList.GetCount(); ii++ )
|
||||
{
|
||||
if( ( aComponentsList[aObjet].CompareRef( aComponentsList[ii] ) == 0 )
|
||||
&& ( aComponentsList[ii].m_NumRef >= aMinRefId ) )
|
||||
aIdList.push_back( aComponentsList[ii].m_NumRef );
|
||||
}
|
||||
sort( aIdList.begin(), aIdList.end() );
|
||||
|
||||
// Ensure each reference Id appears only once
|
||||
// If there are multiple parts per package the same Id will be stored for each part.
|
||||
for( unsigned ii = 1; ii < aIdList.size(); ii++ )
|
||||
{
|
||||
if( aIdList[ii] != aIdList[ii-1] )
|
||||
continue;
|
||||
aIdList.erase(aIdList.begin() + ii );
|
||||
ii--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BreakReference( SCH_REFERENCE_LIST& aComponentsList )
|
||||
/**
|
||||
* helper function CreateFirstFreeRefId
|
||||
* Search for a free ref Id inside a list of reference numbers in use.
|
||||
* This list is expected 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 )
|
||||
{
|
||||
for( unsigned ii = 0; ii < aComponentsList.GetCount(); ii++ )
|
||||
aComponentsList[ii].Split();
|
||||
}
|
||||
int expectedId = aFirstValue;
|
||||
|
||||
// We search for expectedId 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
|
||||
|
||||
/*
|
||||
* Compute the reference number for components without reference number
|
||||
|
@ -189,7 +276,11 @@ void BreakReference( SCH_REFERENCE_LIST& aComponentsList )
|
|||
*/
|
||||
static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList, bool aUseSheetNum )
|
||||
{
|
||||
int LastReferenceNumber, NumberOfUnits, Unit;
|
||||
if ( aComponentsList.GetCount() == 0 )
|
||||
return;
|
||||
|
||||
int LastReferenceNumber = 0;
|
||||
int NumberOfUnits, Unit;
|
||||
|
||||
/* Components with an invisible reference (power...) always are
|
||||
* re-annotated. So set their .m_IsNew member to true
|
||||
|
@ -209,33 +300,59 @@ static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList, bool aU
|
|||
* IC .. will be set to IC4, IC4, IC5 ...
|
||||
*/
|
||||
unsigned first = 0;
|
||||
|
||||
/* calculate the last used number for this reference prefix: */
|
||||
LastReferenceNumber = GetLastReferenceNumber( first, aComponentsList );
|
||||
#ifdef USE_OLD_ALGO
|
||||
int minRefId = 0;
|
||||
// when using sheet number, ensure ref number >= sheet number* 100
|
||||
if( aUseSheetNum )
|
||||
minRefId = aComponentsList[first].m_SheetNum * 100;
|
||||
LastReferenceNumber = GetLastNumberInReference( first, aComponentsList, minRefId );
|
||||
#else
|
||||
int minRefId = 1;
|
||||
// when using sheet number, ensure ref number >= sheet number* 100
|
||||
if( aUseSheetNum )
|
||||
minRefId = aComponentsList[first].m_SheetNum * 100 + 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;
|
||||
BuildRefIdInUseList( first, aComponentsList, idList, minRefId );
|
||||
#endif
|
||||
for( unsigned ii = 0; ii < aComponentsList.GetCount(); ii++ )
|
||||
{
|
||||
if( aComponentsList[ii].m_Flag )
|
||||
continue;
|
||||
|
||||
if( aComponentsList[first].CompareRef( aComponentsList[ii] ) != 0 )
|
||||
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;
|
||||
LastReferenceNumber = GetLastReferenceNumber( ii, aComponentsList );
|
||||
}
|
||||
// when using sheet number, ensure annot number >= sheet number* 100
|
||||
if( aUseSheetNum )
|
||||
{
|
||||
int min_num = aComponentsList[ii].m_SheetNum * 100;
|
||||
if( LastReferenceNumber < min_num )
|
||||
LastReferenceNumber = min_num;
|
||||
#ifdef USE_OLD_ALGO
|
||||
minRefId = 0;
|
||||
// when using sheet number, ensure ref number >= sheet number* 100
|
||||
if( aUseSheetNum )
|
||||
minRefId = aComponentsList[ii].m_SheetNum * 100;
|
||||
LastReferenceNumber = GetLastNumberInReference( ii, aComponentsList, minRefId);
|
||||
#else
|
||||
minRefId = 1;
|
||||
// when using sheet number, ensure ref number >= sheet number* 100
|
||||
if( aUseSheetNum )
|
||||
minRefId = aComponentsList[ii].m_SheetNum * 100 + 1;
|
||||
BuildRefIdInUseList( first, aComponentsList, idList, minRefId );
|
||||
#endif
|
||||
}
|
||||
/* Annotation of one part per package components (trivial case)*/
|
||||
if( aComponentsList[ii].m_Entry->GetPartCount() <= 1 )
|
||||
{
|
||||
if( aComponentsList[ii].m_IsNew )
|
||||
{
|
||||
#ifdef USE_OLD_ALGO
|
||||
LastReferenceNumber++;
|
||||
#else
|
||||
LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
|
||||
#endif
|
||||
aComponentsList[ii].m_NumRef = LastReferenceNumber;
|
||||
}
|
||||
|
||||
|
@ -251,7 +368,11 @@ static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList, bool aU
|
|||
|
||||
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() )
|
||||
|
@ -307,33 +428,6 @@ static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList, bool aU
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search the last used (greatest) reference number in the component list
|
||||
* for the prefix reference given by Objet
|
||||
* The component list must be sorted.
|
||||
*
|
||||
* @param aObjet = reference item ( aComponentsList[aObjet].m_TextRef is
|
||||
* the search pattern)
|
||||
* @param aComponentsList = list of items
|
||||
*/
|
||||
int GetLastReferenceNumber( int aObjet,SCH_REFERENCE_LIST& aComponentsList )
|
||||
{
|
||||
int LastNumber = 0;
|
||||
|
||||
for( unsigned ii = 0; ii < aComponentsList.GetCount(); ii++ )
|
||||
{
|
||||
/* New identifier. */
|
||||
if( aComponentsList[aObjet].CompareRef( aComponentsList[ii] ) != 0 )
|
||||
continue;
|
||||
|
||||
if( LastNumber < aComponentsList[ii].m_NumRef )
|
||||
LastNumber = aComponentsList[ii].m_NumRef;
|
||||
}
|
||||
|
||||
return LastNumber;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search in the sorted list of components, for a given component an other
|
||||
* component with the same reference and a given part unit. Mainly used to
|
||||
|
@ -391,7 +485,7 @@ static int ExistUnit( int aObjet, int Unit, SCH_REFERENCE_LIST& aComponentsList
|
|||
*/
|
||||
int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly )
|
||||
{
|
||||
int error;
|
||||
int error = 0;
|
||||
wxString Buff;
|
||||
wxString msg, cmpref;
|
||||
|
||||
|
@ -410,18 +504,15 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn
|
|||
|
||||
/* Break full components reference in name (prefix) and number: example:
|
||||
* IC1 become IC, and 1 */
|
||||
BreakReference( ComponentsList );
|
||||
ComponentsList.SplitReferences();
|
||||
|
||||
/* count not yet annotated items */
|
||||
error = 0;
|
||||
int imax = ComponentsList.GetCount() - 1;
|
||||
|
||||
for( int ii = 0; ii < imax; ii++ )
|
||||
/* count not yet annotated items or annottaion error*/
|
||||
for( unsigned ii = 0; ii < ComponentsList.GetCount(); ii++ )
|
||||
{
|
||||
msg.Empty();
|
||||
Buff.Empty();
|
||||
|
||||
if( ComponentsList[ii].m_IsNew )
|
||||
if( ComponentsList[ii].m_IsNew ) // Not yet annotated
|
||||
{
|
||||
if( ComponentsList[ii].m_NumRef >= 0 )
|
||||
Buff << ComponentsList[ii].m_NumRef;
|
||||
|
@ -446,7 +537,8 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn
|
|||
break;
|
||||
}
|
||||
|
||||
// Annotate error
|
||||
// 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].m_Entry->GetPartCount(), 1 ) < ComponentsList[ii].m_Unit )
|
||||
{
|
||||
if( ComponentsList[ii].m_NumRef >= 0 )
|
||||
|
@ -477,6 +569,7 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn
|
|||
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();
|
||||
|
|
|
@ -226,6 +226,39 @@ public:
|
|||
* When annotating, some or all components are not annotated,
|
||||
* i.e. ref is only U or R, with no number.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Function SplitReferences
|
||||
* attempts to split all reference designators into a name (U) and number (1). If the
|
||||
* last character is '?' or not a digit, the reference is tagged as not annotated.
|
||||
* For components with multiple parts per package that are not already annotated, set
|
||||
* m_Unit to a max value (0x7FFFFFFF).
|
||||
* @see SCH_REFERENCE::Split()
|
||||
*/
|
||||
void SplitReferences()
|
||||
{
|
||||
for( unsigned ii = 0; ii < GetCount(); ii++ )
|
||||
componentFlatList[ii].Split();
|
||||
}
|
||||
|
||||
/**
|
||||
* function UpdateAnnotation
|
||||
* Update the reference components for the schematic project (or the current sheet)
|
||||
* Note: this function does not calculate the reference numbers
|
||||
* stored in m_NumRef
|
||||
* So, it must be called after calcultaion of new reference numbers
|
||||
* @see SCH_REFERENCE::Annotate()
|
||||
*/
|
||||
void UpdateAnnotation()
|
||||
{
|
||||
/* update the reference numbers */
|
||||
for( unsigned ii = 0; ii < GetCount(); ii++ )
|
||||
{
|
||||
componentFlatList[ii].Annotate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SortCmpByXCoordinate
|
||||
* sort the flat list by X coordinates.
|
||||
|
|
Loading…
Reference in New Issue