Promote PathsAndReferences from wxArrayString to first-class-citizen.
Keeping the data in an un-serialized format greatly simplifies usage, and should make it more robust.
This commit is contained in:
parent
b4786e4121
commit
c68b554c8e
|
@ -643,8 +643,8 @@ struct compare_labels
|
||||||
{
|
{
|
||||||
bool operator() ( const NETLIST_OBJECT* lab1, const NETLIST_OBJECT* lab2 ) const
|
bool operator() ( const NETLIST_OBJECT* lab1, const NETLIST_OBJECT* lab2 ) const
|
||||||
{
|
{
|
||||||
wxString str1 = lab1->m_SheetPath.Path() + lab1->m_Label;
|
wxString str1 = lab1->m_SheetPath.PathAsString() + lab1->m_Label;
|
||||||
wxString str2 = lab2->m_SheetPath.Path() + lab2->m_Label;
|
wxString str2 = lab2->m_SheetPath.PathAsString() + lab2->m_Label;
|
||||||
|
|
||||||
return str1.Cmp( str2 ) < 0;
|
return str1.Cmp( str2 ) < 0;
|
||||||
}
|
}
|
||||||
|
@ -662,7 +662,7 @@ struct compare_paths
|
||||||
{
|
{
|
||||||
bool operator() ( const NETLIST_OBJECT* lab1, const NETLIST_OBJECT* lab2 ) const
|
bool operator() ( const NETLIST_OBJECT* lab1, const NETLIST_OBJECT* lab2 ) const
|
||||||
{
|
{
|
||||||
return lab1->m_SheetPath.Path().Cmp( lab2->m_SheetPath.Path() ) < 0;
|
return lab1->m_SheetPath.Path() < lab2->m_SheetPath.Path();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -270,7 +270,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents()
|
||||||
|
|
||||||
xcomp->AddChild( xsheetpath = node( "sheetpath" ) );
|
xcomp->AddChild( xsheetpath = node( "sheetpath" ) );
|
||||||
xsheetpath->AddAttribute( "names", sheetList[i].PathHumanReadable() );
|
xsheetpath->AddAttribute( "names", sheetList[i].PathHumanReadable() );
|
||||||
xsheetpath->AddAttribute( "tstamps", sheetList[i].Path() );
|
xsheetpath->AddAttribute( "tstamps", sheetList[i].PathAsString() );
|
||||||
xcomp->AddChild( node( "tstamp", comp->m_Uuid.AsString() ) );
|
xcomp->AddChild( node( "tstamp", comp->m_Uuid.AsString() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeDesignHeader()
|
||||||
sheetTxt.Printf( "%u", i + 1 );
|
sheetTxt.Printf( "%u", i + 1 );
|
||||||
xsheet->AddAttribute( "number", sheetTxt );
|
xsheet->AddAttribute( "number", sheetTxt );
|
||||||
xsheet->AddAttribute( "name", sheetList[i].PathHumanReadable() );
|
xsheet->AddAttribute( "name", sheetList[i].PathHumanReadable() );
|
||||||
xsheet->AddAttribute( "tstamps", sheetList[i].Path() );
|
xsheet->AddAttribute( "tstamps", sheetList[i].PathAsString() );
|
||||||
|
|
||||||
|
|
||||||
TITLE_BLOCK tb = screen->GetTitleBlock();
|
TITLE_BLOCK tb = screen->GetTitleBlock();
|
||||||
|
|
|
@ -102,7 +102,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
||||||
field = comp->GetRef( &sheetList[i] );
|
field = comp->GetRef( &sheetList[i] );
|
||||||
|
|
||||||
ret |= fprintf( f, " ( %s %s",
|
ret |= fprintf( f, " ( %s %s",
|
||||||
TO_UTF8( comp->GetPath( &sheetList[i] ) ),
|
TO_UTF8( sheetList[i].PathAsString() + comp->m_Uuid.AsString() ),
|
||||||
TO_UTF8( footprint ) );
|
TO_UTF8( footprint ) );
|
||||||
|
|
||||||
ret |= fprintf( f, " %s", TO_UTF8( field ) );
|
ret |= fprintf( f, " %s", TO_UTF8( field ) );
|
||||||
|
|
|
@ -312,14 +312,12 @@ static bool evalLabelsPriority( const NETLIST_OBJECT* aLabel1, const NETLIST_OBJ
|
||||||
// Global labels have the highest prioriy.
|
// Global labels have the highest prioriy.
|
||||||
// For local labels: names are prefixed by their sheetpath
|
// For local labels: names are prefixed by their sheetpath
|
||||||
// use name defined in the more top level hierarchical sheet
|
// use name defined in the more top level hierarchical sheet
|
||||||
// (i.e. shorter timestamp path because paths are /<timestamp1>/<timestamp2>/...
|
|
||||||
// and timestamp = 8 letters.
|
|
||||||
// Note: the final net name uses human sheetpath name, not timestamp sheetpath name
|
// Note: the final net name uses human sheetpath name, not timestamp sheetpath name
|
||||||
// They are equivalent, but not for human readers.
|
// They are equivalent, but not for human readers.
|
||||||
if( ! aLabel1->IsLabelGlobal() && ! aLabel2->IsLabelGlobal() )
|
if( ! aLabel1->IsLabelGlobal() && ! aLabel2->IsLabelGlobal() )
|
||||||
{
|
{
|
||||||
if( aLabel1->m_SheetPath.Path().Length() != aLabel2->m_SheetPath.Path().Length() )
|
if( aLabel1->m_SheetPath.size() != aLabel2->m_SheetPath.size() )
|
||||||
return aLabel1->m_SheetPath.Path().Length() < aLabel2->m_SheetPath.Path().Length();
|
return aLabel1->m_SheetPath.size() < aLabel2->m_SheetPath.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int priority1 = getPriority( aLabel1 );
|
int priority1 = getPriority( aLabel1 );
|
||||||
|
|
|
@ -183,7 +183,7 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
|
||||||
|
|
||||||
m_transform = aComponent.m_transform;
|
m_transform = aComponent.m_transform;
|
||||||
m_prefix = aComponent.m_prefix;
|
m_prefix = aComponent.m_prefix;
|
||||||
m_PathsAndReferences = aComponent.m_PathsAndReferences;
|
m_instanceReferences = aComponent.m_instanceReferences;
|
||||||
m_Fields = aComponent.m_Fields;
|
m_Fields = aComponent.m_Fields;
|
||||||
|
|
||||||
// Re-parent the fields, which before this had aComponent as parent
|
// Re-parent the fields, which before this had aComponent as parent
|
||||||
|
@ -563,55 +563,35 @@ void SCH_COMPONENT::Print( wxDC* aDC, const wxPoint& aOffset )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath, const wxString& aRef,
|
void SCH_COMPONENT::AddHierarchicalReference( const KIID_PATH& aPath, const wxString& aRef,
|
||||||
int aMulti )
|
int aUnit )
|
||||||
{
|
{
|
||||||
wxString h_path, h_ref;
|
|
||||||
wxStringTokenizer tokenizer;
|
|
||||||
wxString separators( wxT( " " ) );
|
|
||||||
|
|
||||||
// Search for an existing path and remove it if found (should not occur)
|
// Search for an existing path and remove it if found (should not occur)
|
||||||
for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
|
for( unsigned ii = 0; ii < m_instanceReferences.size(); ii++ )
|
||||||
{
|
{
|
||||||
tokenizer.SetString( m_PathsAndReferences[ii], separators );
|
if( m_instanceReferences[ii].m_Path == aPath )
|
||||||
h_path = tokenizer.GetNextToken();
|
|
||||||
|
|
||||||
if( h_path.Cmp( aPath ) == 0 )
|
|
||||||
{
|
{
|
||||||
m_PathsAndReferences.RemoveAt( ii );
|
m_instanceReferences.erase( m_instanceReferences.begin() + ii );
|
||||||
ii--;
|
ii--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h_ref = aPath + wxT( " " ) + aRef;
|
COMPONENT_INSTANCE_REFERENCE instance;
|
||||||
h_ref << wxT( " " ) << aMulti;
|
instance.m_Path = aPath;
|
||||||
m_PathsAndReferences.Add( h_ref );
|
instance.m_Reference = aRef;
|
||||||
}
|
instance.m_Unit = aUnit;
|
||||||
|
m_instanceReferences.push_back( instance );
|
||||||
|
|
||||||
wxString SCH_COMPONENT::GetPath( const SCH_SHEET_PATH* sheet ) const
|
|
||||||
{
|
|
||||||
wxCHECK_MSG( sheet != NULL, wxEmptyString,
|
|
||||||
wxT( "Cannot get component path with invalid sheet object." ) );
|
|
||||||
|
|
||||||
return sheet->Path() + m_Uuid.AsString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet )
|
const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet )
|
||||||
{
|
{
|
||||||
wxString path = GetPath( sheet );
|
KIID_PATH path = sheet->Path();
|
||||||
wxString h_path;
|
|
||||||
wxStringTokenizer tokenizer;
|
|
||||||
wxString separators( wxT( " " ) );
|
|
||||||
|
|
||||||
for( const wxString& entry : m_PathsAndReferences )
|
for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||||
{
|
{
|
||||||
tokenizer.SetString( entry, separators );
|
if( instance.m_Path == path )
|
||||||
h_path = tokenizer.GetNextToken();
|
return instance.m_Reference;
|
||||||
|
|
||||||
if( h_path.Cmp( path ) == 0 )
|
|
||||||
return tokenizer.GetNextToken();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it was not found in m_Paths array, then see if it is in m_Field[REFERENCE] -- if so,
|
// If it was not found in m_Paths array, then see if it is in m_Field[REFERENCE] -- if so,
|
||||||
|
@ -646,30 +626,15 @@ bool SCH_COMPONENT::IsReferenceStringValid( const wxString& aReferenceString )
|
||||||
|
|
||||||
void SCH_COMPONENT::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
|
void SCH_COMPONENT::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
|
||||||
{
|
{
|
||||||
wxString path = GetPath( sheet );
|
KIID_PATH path = sheet->Path();
|
||||||
|
|
||||||
bool notInArray = true;
|
bool notInArray = true;
|
||||||
|
|
||||||
wxString h_path, h_ref;
|
|
||||||
wxStringTokenizer tokenizer;
|
|
||||||
wxString separators( wxT( " " ) );
|
|
||||||
|
|
||||||
// check to see if it is already there before inserting it
|
// check to see if it is already there before inserting it
|
||||||
for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
|
for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||||
{
|
{
|
||||||
tokenizer.SetString( m_PathsAndReferences[ii], separators );
|
if( instance.m_Path == path )
|
||||||
h_path = tokenizer.GetNextToken();
|
|
||||||
|
|
||||||
if( h_path.Cmp( path ) == 0 )
|
|
||||||
{
|
{
|
||||||
// just update the reference text, not the timestamp.
|
instance.m_Reference = ref;
|
||||||
h_ref = h_path + wxT( " " ) + ref;
|
|
||||||
h_ref += wxT( " " );
|
|
||||||
tokenizer.GetNextToken(); // Skip old reference
|
|
||||||
h_ref += tokenizer.GetNextToken(); // Add part selection
|
|
||||||
|
|
||||||
// Add the part selection
|
|
||||||
m_PathsAndReferences[ii] = h_ref;
|
|
||||||
notInArray = false;
|
notInArray = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -713,21 +678,12 @@ void SCH_COMPONENT::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
|
||||||
|
|
||||||
bool SCH_COMPONENT::IsAnnotated( const SCH_SHEET_PATH* aSheet )
|
bool SCH_COMPONENT::IsAnnotated( const SCH_SHEET_PATH* aSheet )
|
||||||
{
|
{
|
||||||
wxString path = GetPath( aSheet );
|
KIID_PATH path = aSheet->Path();
|
||||||
wxString h_path;
|
|
||||||
wxStringTokenizer tokenizer;
|
|
||||||
wxString separators( wxT( " " ) );
|
|
||||||
|
|
||||||
for( const wxString& entry : m_PathsAndReferences )
|
for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||||
{
|
{
|
||||||
tokenizer.SetString( entry, separators );
|
if( instance.m_Path == path )
|
||||||
h_path = tokenizer.GetNextToken();
|
return instance.m_Reference.Last() != '?';
|
||||||
|
|
||||||
if( h_path.Cmp( path ) == 0 )
|
|
||||||
{
|
|
||||||
wxString ref = tokenizer.GetNextToken();
|
|
||||||
return ref.Last() != '?';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -736,24 +692,12 @@ bool SCH_COMPONENT::IsAnnotated( const SCH_SHEET_PATH* aSheet )
|
||||||
|
|
||||||
int SCH_COMPONENT::GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const
|
int SCH_COMPONENT::GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const
|
||||||
{
|
{
|
||||||
wxString path = GetPath( aSheet );
|
KIID_PATH path = aSheet->Path();
|
||||||
wxString h_path, h_multi;
|
|
||||||
wxStringTokenizer tokenizer;
|
|
||||||
wxString separators( wxT( " " ) );
|
|
||||||
|
|
||||||
for( const wxString& entry : m_PathsAndReferences )
|
for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||||
{
|
{
|
||||||
tokenizer.SetString( entry, separators );
|
if( instance.m_Path == path )
|
||||||
h_path = tokenizer.GetNextToken();
|
return instance.m_Unit;
|
||||||
|
|
||||||
if( h_path.Cmp( path ) == 0 )
|
|
||||||
{
|
|
||||||
tokenizer.GetNextToken(); // Skip reference
|
|
||||||
h_multi = tokenizer.GetNextToken();
|
|
||||||
long imulti = 1;
|
|
||||||
h_multi.ToLong( &imulti );
|
|
||||||
return imulti;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it was not found in m_Paths array, then use m_unit. This will happen if we load a
|
// If it was not found in m_Paths array, then use m_unit. This will happen if we load a
|
||||||
|
@ -764,30 +708,15 @@ int SCH_COMPONENT::GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const
|
||||||
|
|
||||||
void SCH_COMPONENT::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection )
|
void SCH_COMPONENT::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection )
|
||||||
{
|
{
|
||||||
wxString path = GetPath( aSheet );
|
KIID_PATH path = aSheet->Path();
|
||||||
|
|
||||||
bool notInArray = true;
|
bool notInArray = true;
|
||||||
|
|
||||||
wxString h_path, h_ref;
|
|
||||||
wxStringTokenizer tokenizer;
|
|
||||||
wxString separators( wxT( " " ) );
|
|
||||||
|
|
||||||
// check to see if it is already there before inserting it
|
// check to see if it is already there before inserting it
|
||||||
for( wxString& entry : m_PathsAndReferences )
|
for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||||
{
|
{
|
||||||
tokenizer.SetString( entry, separators );
|
if( instance.m_Path == path )
|
||||||
h_path = tokenizer.GetNextToken();
|
|
||||||
|
|
||||||
if( h_path.Cmp( path ) == 0 )
|
|
||||||
{
|
{
|
||||||
//just update the unit selection.
|
instance.m_Unit = aUnitSelection;
|
||||||
h_ref = h_path + wxT( " " );
|
|
||||||
h_ref += tokenizer.GetNextToken(); // Add reference
|
|
||||||
h_ref += wxT( " " );
|
|
||||||
h_ref << aUnitSelection; // Add part selection
|
|
||||||
|
|
||||||
// Ann the part selection
|
|
||||||
entry = h_ref;
|
|
||||||
notInArray = false;
|
notInArray = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1021,15 +950,12 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
|
||||||
m_transform = component->m_transform;
|
m_transform = component->m_transform;
|
||||||
component->m_transform = tmp;
|
component->m_transform = tmp;
|
||||||
|
|
||||||
std::swap( m_PathsAndReferences, component->m_PathsAndReferences );
|
std::swap( m_instanceReferences, component->m_instanceReferences );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
|
void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
|
||||||
{
|
{
|
||||||
wxArrayString reference_fields;
|
|
||||||
static const wxChar separators[] = wxT( " " );
|
|
||||||
|
|
||||||
// Build a reference with no annotation,
|
// Build a reference with no annotation,
|
||||||
// i.e. a reference ended by only one '?'
|
// i.e. a reference ended by only one '?'
|
||||||
wxString defRef = m_prefix;
|
wxString defRef = m_prefix;
|
||||||
|
@ -1044,25 +970,21 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
|
||||||
|
|
||||||
defRef.Append( wxT( "?" ) );
|
defRef.Append( wxT( "?" ) );
|
||||||
|
|
||||||
wxString path;
|
|
||||||
|
|
||||||
if( aSheetPath )
|
if( aSheetPath )
|
||||||
path = GetPath( aSheetPath );
|
|
||||||
|
|
||||||
for( wxString& entry : m_PathsAndReferences )
|
|
||||||
{
|
{
|
||||||
// Break hierarchical reference in path, ref and multi selection:
|
KIID_PATH path = aSheetPath->Path();
|
||||||
reference_fields = wxStringTokenize( entry, separators );
|
|
||||||
|
|
||||||
// For all components: if aSheetPath is not NULL,
|
for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||||
// remove annotation only for the given path
|
|
||||||
if( aSheetPath == NULL || reference_fields[0].Cmp( path ) == 0 )
|
|
||||||
{
|
{
|
||||||
wxString newHref = reference_fields[0];
|
if( instance.m_Path == path )
|
||||||
newHref << wxT( " " ) << defRef << wxT( " " ) << reference_fields[2];
|
instance.m_Reference = defRef;
|
||||||
entry = newHref;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||||
|
instance.m_Reference = defRef;
|
||||||
|
}
|
||||||
|
|
||||||
// These 2 changes do not work in complex hierarchy.
|
// These 2 changes do not work in complex hierarchy.
|
||||||
// When a clear annotation is made, the calling function must call a
|
// When a clear annotation is made, the calling function must call a
|
||||||
|
@ -1074,29 +996,22 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_COMPONENT::AddSheetPathReferenceEntryIfMissing( const wxString& aSheetPathName )
|
bool SCH_COMPONENT::AddSheetPathReferenceEntryIfMissing( const KIID_PATH& aSheetPath )
|
||||||
{
|
{
|
||||||
// a empty sheet path is illegal:
|
// a empty sheet path is illegal:
|
||||||
wxCHECK( !aSheetPathName.IsEmpty(), false );
|
wxCHECK( aSheetPath.size() > 0, false );
|
||||||
|
|
||||||
wxString reference_path;
|
wxString reference_path;
|
||||||
|
|
||||||
// The full component reference path is aSheetPathName + the component time stamp itself
|
for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||||
// full_AR_path is the alternate reference path to search
|
|
||||||
wxString full_AR_path = aSheetPathName + m_Uuid.AsString();
|
|
||||||
|
|
||||||
for( unsigned int ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
|
|
||||||
{
|
{
|
||||||
// Break hierarchical reference in path, ref and multi selection:
|
|
||||||
reference_path = m_PathsAndReferences[ii].BeforeFirst( ' ' );
|
|
||||||
|
|
||||||
// if aSheetPath is found, nothing to do:
|
// if aSheetPath is found, nothing to do:
|
||||||
if( reference_path.Cmp( full_AR_path ) == 0 )
|
if( instance.m_Path == aSheetPath )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This entry does not exist: add it, with a (temporary?) reference (last ref used for display)
|
// This entry does not exist: add it, with its last-used reference
|
||||||
AddHierarchicalReference( full_AR_path, m_Fields[REFERENCE].GetText(), m_unit );
|
AddHierarchicalReference( aSheetPath, m_Fields[REFERENCE].GetText(), m_unit );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1785,7 +1700,7 @@ SCH_COMPONENT& SCH_COMPONENT::operator=( const SCH_ITEM& aItem )
|
||||||
m_convert = c->m_convert;
|
m_convert = c->m_convert;
|
||||||
m_transform = c->m_transform;
|
m_transform = c->m_transform;
|
||||||
|
|
||||||
m_PathsAndReferences = c->m_PathsAndReferences;
|
m_instanceReferences = c->m_instanceReferences;
|
||||||
|
|
||||||
m_Fields = c->m_Fields; // std::vector's assignment operator
|
m_Fields = c->m_Fields; // std::vector's assignment operator
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,14 @@ typedef std::weak_ptr<LIB_PART> PART_REF;
|
||||||
extern std::string toUTFTildaText( const wxString& txt );
|
extern std::string toUTFTildaText( const wxString& txt );
|
||||||
|
|
||||||
|
|
||||||
|
struct COMPONENT_INSTANCE_REFERENCE
|
||||||
|
{
|
||||||
|
KIID_PATH m_Path;
|
||||||
|
wxString m_Reference;
|
||||||
|
int m_Unit;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SCH_COMPONENT
|
* SCH_COMPONENT
|
||||||
* describes a real schematic component
|
* describes a real schematic component
|
||||||
|
@ -121,13 +129,9 @@ private:
|
||||||
|
|
||||||
bool m_isInNetlist; ///< True if the component should appear in the netlist
|
bool m_isInNetlist; ///< True if the component should appear in the netlist
|
||||||
|
|
||||||
/**
|
// Defines the hierarchical path and reference of the component. This allows support
|
||||||
* Defines the hierarchical path and reference of the component. This allows support
|
// for multiple references to a single sub-sheet.
|
||||||
* for hierarchical sheets that reference the same schematic. The format for the path
|
std::vector<COMPONENT_INSTANCE_REFERENCE> m_instanceReferences;
|
||||||
* is /<sheet time stamp>/<sheet time stamp>/.../&lscomponent time stamp>.
|
|
||||||
* A single / denotes the root sheet.
|
|
||||||
*/
|
|
||||||
wxArrayString m_PathsAndReferences;
|
|
||||||
|
|
||||||
void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
|
void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
|
||||||
|
|
||||||
|
@ -176,7 +180,10 @@ public:
|
||||||
return wxT( "SCH_COMPONENT" );
|
return wxT( "SCH_COMPONENT" );
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxArrayString& GetPathsAndReferences() const { return m_PathsAndReferences; }
|
const std::vector<COMPONENT_INSTANCE_REFERENCE>& GetInstanceReferences()
|
||||||
|
{
|
||||||
|
return m_instanceReferences;
|
||||||
|
}
|
||||||
|
|
||||||
void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||||
|
|
||||||
|
@ -314,8 +321,8 @@ public:
|
||||||
void ClearAnnotation( SCH_SHEET_PATH* aSheetPath );
|
void ClearAnnotation( SCH_SHEET_PATH* aSheetPath );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add aSheetPath in m_PathsAndReferences alternate references list,
|
* Add an instance to the alternate references list (m_instanceReferences), if this entry
|
||||||
* if this entry does not exist
|
* does not already exist.
|
||||||
* Do nothing if already exists.
|
* Do nothing if already exists.
|
||||||
* In component lists shared by more than one sheet path, an entry for each
|
* In component lists shared by more than one sheet path, an entry for each
|
||||||
* sheet path must exist to manage references
|
* sheet path must exist to manage references
|
||||||
|
@ -324,7 +331,7 @@ public:
|
||||||
* not the full component sheet path
|
* not the full component sheet path
|
||||||
* @return false if the alternate reference was existing, true if added.
|
* @return false if the alternate reference was existing, true if added.
|
||||||
*/
|
*/
|
||||||
bool AddSheetPathReferenceEntryIfMissing( const wxString& aSheetPathName );
|
bool AddSheetPathReferenceEntryIfMissing( const KIID_PATH& aSheetPath );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the HIGHLIGHTED flag of all items of the component (fields, pins ...)
|
* Clear the HIGHLIGHTED flag of all items of the component (fields, pins ...)
|
||||||
|
@ -492,9 +499,6 @@ public:
|
||||||
|
|
||||||
void SwapData( SCH_ITEM* aItem ) override;
|
void SwapData( SCH_ITEM* aItem ) override;
|
||||||
|
|
||||||
// returns a unique ID, in the form of a path.
|
|
||||||
wxString GetPath( const SCH_SHEET_PATH* sheet ) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for an acceptable reference string.
|
* Tests for an acceptable reference string.
|
||||||
*
|
*
|
||||||
|
@ -534,11 +538,11 @@ public:
|
||||||
* @param aPath is the hierarchical path (/<sheet timestamp>/<component
|
* @param aPath is the hierarchical path (/<sheet timestamp>/<component
|
||||||
* timestamp> like /05678E50/A23EF560)
|
* timestamp> like /05678E50/A23EF560)
|
||||||
* @param aRef is the local reference like C45, R56
|
* @param aRef is the local reference like C45, R56
|
||||||
* @param aMulti is the unit selection used for symbols with multiple units per package.
|
* @param aUnit is the unit selection used for symbols with multiple units per package.
|
||||||
*/
|
*/
|
||||||
void AddHierarchicalReference( const wxString& aPath,
|
void AddHierarchicalReference( const KIID_PATH& aPath,
|
||||||
const wxString& aRef,
|
const wxString& aRef,
|
||||||
int aMulti );
|
int aUnit );
|
||||||
|
|
||||||
// returns the unit selection, for the given sheet path.
|
// returns the unit selection, for the given sheet path.
|
||||||
int GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const;
|
int GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const;
|
||||||
|
|
|
@ -1154,8 +1154,7 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
|
||||||
|
|
||||||
SCH_SHEET_PATH sheetpath;
|
SCH_SHEET_PATH sheetpath;
|
||||||
m_rootSheet->LocatePathOfScreen( screen, &sheetpath );
|
m_rootSheet->LocatePathOfScreen( screen, &sheetpath );
|
||||||
wxString current_sheetpath = sheetpath.Path();
|
wxString current_sheetpath = sheetpath.PathAsString() + component->m_Uuid.AsString();
|
||||||
current_sheetpath += component->m_Uuid.AsString();
|
|
||||||
|
|
||||||
component->GetField( REFERENCE )->SetText( reference );
|
component->GetField( REFERENCE )->SetText( reference );
|
||||||
component->AddHierarchicalReference( current_sheetpath, reference, unit );
|
component->AddHierarchicalReference( current_sheetpath, reference, unit );
|
||||||
|
|
|
@ -368,20 +368,17 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount()
|
||||||
SCH_SCREEN* screen;
|
SCH_SCREEN* screen;
|
||||||
SCH_SCREENS s_list;
|
SCH_SCREENS s_list;
|
||||||
|
|
||||||
/* Set the sheet count, and the sheet number (1 for root sheet)
|
// Set the sheet count, and the sheet number (1 for root sheet)
|
||||||
*/
|
|
||||||
int sheet_count = g_RootSheet->CountSheets();
|
int sheet_count = g_RootSheet->CountSheets();
|
||||||
int SheetNumber = 1;
|
int SheetNumber = 1;
|
||||||
wxString current_sheetpath = g_CurrentSheet->Path();
|
const KIID_PATH& current_sheetpath = g_CurrentSheet->Path();
|
||||||
SCH_SHEET_LIST sheetList( g_RootSheet );
|
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||||
|
|
||||||
// Examine all sheets path to find the current sheets path,
|
// Examine all sheets path to find the current sheets path,
|
||||||
// and count them from root to the current sheet path:
|
// and count them from root to the current sheet path:
|
||||||
for( const SCH_SHEET_PATH& sheet : sheetList )
|
for( const SCH_SHEET_PATH& sheet : sheetList )
|
||||||
{
|
{
|
||||||
wxString sheetpath = sheet.Path();
|
if( sheet.Path() == current_sheetpath ) // Current sheet path found
|
||||||
|
|
||||||
if( sheetpath == current_sheetpath ) // Current sheet path found
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SheetNumber++; // Not found, increment before this current path
|
SheetNumber++; // Not found, increment before this current path
|
||||||
|
|
|
@ -1583,9 +1583,23 @@ SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( LINE_READER& aReader )
|
||||||
SCH_PARSE_ERROR( "missing 'Path=' token", aReader, line );
|
SCH_PARSE_ERROR( "missing 'Path=' token", aReader, line );
|
||||||
|
|
||||||
line += len;
|
line += len;
|
||||||
wxString path, reference, unit;
|
wxString pathStr, reference, unit;
|
||||||
|
|
||||||
parseQuotedString( path, aReader, line, &line );
|
parseQuotedString( pathStr, aReader, line, &line );
|
||||||
|
|
||||||
|
// Note: AR path excludes root sheet, but includes component. Normalize to
|
||||||
|
// internal format by shifting everything down one and adding the root sheet.
|
||||||
|
KIID_PATH path( pathStr );
|
||||||
|
|
||||||
|
if( path.size() > 0 )
|
||||||
|
{
|
||||||
|
for( size_t i = path.size() - 1; i > 0; --i )
|
||||||
|
path[i] = path[i-1];
|
||||||
|
|
||||||
|
path[0] = m_rootSheet->m_Uuid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
path.push_back( m_rootSheet->m_Uuid );
|
||||||
|
|
||||||
strCompare = "Ref=";
|
strCompare = "Ref=";
|
||||||
len = strlen( strCompare );
|
len = strlen( strCompare );
|
||||||
|
@ -1968,10 +1982,10 @@ void SCH_LEGACY_PLUGIN::saveComponent( SCH_COMPONENT* aComponent )
|
||||||
static wxString delimiters( wxT( " " ) );
|
static wxString delimiters( wxT( " " ) );
|
||||||
|
|
||||||
// This is redundant with the AR entries below, but it makes the files backwards-compatible.
|
// This is redundant with the AR entries below, but it makes the files backwards-compatible.
|
||||||
if( aComponent->GetPathsAndReferences().GetCount() > 0 )
|
if( aComponent->GetInstanceReferences().size() > 0 )
|
||||||
{
|
{
|
||||||
reference_fields = wxStringTokenize( aComponent->GetPathsAndReferences()[0], delimiters );
|
const COMPONENT_INSTANCE_REFERENCE& instance = aComponent->GetInstanceReferences()[0];
|
||||||
name1 = toUTFTildaText( reference_fields[1] );
|
name1 = toUTFTildaText( instance.m_Reference );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2011,9 +2025,9 @@ void SCH_LEGACY_PLUGIN::saveComponent( SCH_COMPONENT* aComponent )
|
||||||
* the reference inf is already saved
|
* the reference inf is already saved
|
||||||
* this is useful for old Eeschema version compatibility
|
* this is useful for old Eeschema version compatibility
|
||||||
*/
|
*/
|
||||||
if( aComponent->GetPathsAndReferences().GetCount() > 1 )
|
if( aComponent->GetInstanceReferences().size() > 1 )
|
||||||
{
|
{
|
||||||
for( unsigned int ii = 0; ii < aComponent->GetPathsAndReferences().GetCount(); ii++ )
|
for( const COMPONENT_INSTANCE_REFERENCE& instance : aComponent->GetInstanceReferences() )
|
||||||
{
|
{
|
||||||
/*format:
|
/*format:
|
||||||
* AR Path="/140/2" Ref="C99" Part="1"
|
* AR Path="/140/2" Ref="C99" Part="1"
|
||||||
|
@ -2023,23 +2037,16 @@ void SCH_LEGACY_PLUGIN::saveComponent( SCH_COMPONENT* aComponent )
|
||||||
* Ref is the conventional component reference for this 'path'
|
* Ref is the conventional component reference for this 'path'
|
||||||
* Part is the conventional component part selection for this 'path'
|
* Part is the conventional component part selection for this 'path'
|
||||||
*/
|
*/
|
||||||
reference_fields = wxStringTokenize( aComponent->GetPathsAndReferences()[ii],
|
wxString path = "/";
|
||||||
delimiters );
|
|
||||||
|
|
||||||
// Convert Alternate Reference paths back to legacy timestamps:
|
// Skip root sheet
|
||||||
wxArrayString pathParts = wxSplit( reference_fields[0], '/' );
|
for( int i = 1; i < instance.m_Path.size(); ++i )
|
||||||
wxString path;
|
path += instance.m_Path[i].AsLegacyTimestampString() + "/";
|
||||||
|
|
||||||
for( const wxString& pathPart : pathParts )
|
m_out->Print( 0, "AR Path=\"%s\" Ref=\"%s\" Part=\"%d\" \n",
|
||||||
{
|
TO_UTF8( path + aComponent->m_Uuid.AsLegacyTimestampString() ),
|
||||||
if( !pathPart.IsEmpty() )
|
TO_UTF8( instance.m_Reference ),
|
||||||
path += "/" + KIID( pathPart ).AsLegacyTimestampString();
|
instance.m_Unit );
|
||||||
}
|
|
||||||
|
|
||||||
m_out->Print( 0, "AR Path=\"%s\" Ref=\"%s\" Part=\"%s\" \n",
|
|
||||||
TO_UTF8( path ),
|
|
||||||
TO_UTF8( reference_fields[1] ),
|
|
||||||
TO_UTF8( reference_fields[2] ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ public:
|
||||||
|
|
||||||
const wxString GetPath() const
|
const wxString GetPath() const
|
||||||
{
|
{
|
||||||
return m_RootCmp ? m_RootCmp->GetPath( &m_SheetPath ) : "";
|
return m_RootCmp ? m_SheetPath.PathAsString() + m_RootCmp->m_Uuid.AsString() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,7 +189,9 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsSameInstance( const SCH_REFERENCE& other ) const
|
bool IsSameInstance( const SCH_REFERENCE& other ) const
|
||||||
{
|
{
|
||||||
return GetComp() == other.GetComp() && GetSheetPath().Path() == other.GetSheetPath().Path();
|
// JEY TODO: should this be checking unit as well?
|
||||||
|
return GetComp() == other.GetComp()
|
||||||
|
&& GetSheetPath().Path() == other.GetSheetPath().Path();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsUnitsLocked()
|
bool IsUnitsLocked()
|
||||||
|
|
|
@ -1308,7 +1308,7 @@ void SCH_SCREENS::BuildClientSheetPathList()
|
||||||
{
|
{
|
||||||
if( used_screen == curr_screen )
|
if( used_screen == curr_screen )
|
||||||
{
|
{
|
||||||
curr_screen->GetClientSheetPaths().Add( sheetpath.Path() );
|
curr_screen->GetClientSheetPaths().Add( sheetpath.PathAsString() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ SCH_SCREEN* SCH_SHEET_PATH::LastScreen() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString SCH_SHEET_PATH::Path() const
|
wxString SCH_SHEET_PATH::PathAsString() const
|
||||||
{
|
{
|
||||||
wxString s;
|
wxString s;
|
||||||
|
|
||||||
|
@ -131,6 +131,17 @@ wxString SCH_SHEET_PATH::Path() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KIID_PATH SCH_SHEET_PATH::Path() const
|
||||||
|
{
|
||||||
|
KIID_PATH path;
|
||||||
|
|
||||||
|
for( const SCH_SHEET* sheet : m_sheets )
|
||||||
|
path.push_back( sheet->m_Uuid );
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString SCH_SHEET_PATH::GetRootPathName( bool aUseShortName )
|
wxString SCH_SHEET_PATH::GetRootPathName( bool aUseShortName )
|
||||||
{
|
{
|
||||||
// return a PathName for the root sheet (like "/" or "<root>"
|
// return a PathName for the root sheet (like "/" or "<root>"
|
||||||
|
|
|
@ -194,12 +194,18 @@ public:
|
||||||
SCH_SCREEN* LastScreen() const;
|
SCH_SCREEN* LastScreen() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Path
|
* Function PathAsString
|
||||||
* the path uses the time stamps which do not changes even when editing
|
* the path uses the time stamps which do not changes even when editing
|
||||||
* sheet parameters
|
* sheet parameters
|
||||||
* a path is something like / (root) or /34005677 or /34005677/00AE4523
|
* a path is something like / (root) or /34005677 or /34005677/00AE4523
|
||||||
*/
|
*/
|
||||||
wxString Path() const;
|
wxString PathAsString() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the sheet path as an KIID_PATH.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
KIID_PATH Path() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function PathHumanReadable
|
* Function PathHumanReadable
|
||||||
|
|
|
@ -290,9 +290,10 @@ int BACK_ANNOTATE::checkSharedSchematicErrors()
|
||||||
// We will count how many times every component used in our changelist
|
// We will count how many times every component used in our changelist
|
||||||
// Component in this case is SCH_COMPONENT which can be used by more than one symbol
|
// Component in this case is SCH_COMPONENT which can be used by more than one symbol
|
||||||
int usageCount = 1;
|
int usageCount = 1;
|
||||||
|
|
||||||
for( auto it = m_changelist.begin(); it != m_changelist.end(); ++it )
|
for( auto it = m_changelist.begin(); it != m_changelist.end(); ++it )
|
||||||
{
|
{
|
||||||
int compUsage = it->first.GetComp()->GetPathsAndReferences().Count();
|
int compUsage = it->first.GetComp()->GetInstanceReferences().size();
|
||||||
|
|
||||||
if( compUsage == 1 )
|
if( compUsage == 1 )
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE( Empty )
|
||||||
BOOST_CHECK_EQUAL( m_empty_path.Last(), nullptr );
|
BOOST_CHECK_EQUAL( m_empty_path.Last(), nullptr );
|
||||||
BOOST_CHECK_EQUAL( m_empty_path.LastScreen(), nullptr );
|
BOOST_CHECK_EQUAL( m_empty_path.LastScreen(), nullptr );
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL( m_empty_path.Path(), "/" );
|
BOOST_CHECK_EQUAL( m_empty_path.PathAsString(), "/" );
|
||||||
BOOST_CHECK_EQUAL( m_empty_path.PathHumanReadable(), "/" );
|
BOOST_CHECK_EQUAL( m_empty_path.PathHumanReadable(), "/" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ BOOST_AUTO_TEST_CASE( NonEmpty )
|
||||||
|
|
||||||
// don't know what the timestamps will be, but we know the format: /<8 chars>/<8 chars>/
|
// don't know what the timestamps will be, but we know the format: /<8 chars>/<8 chars>/
|
||||||
BOOST_CHECK_PREDICATE(
|
BOOST_CHECK_PREDICATE(
|
||||||
KI_TEST::IsTimestampStringWithLevels, ( m_linear.Path().ToStdString() )( 2 ) );
|
KI_TEST::IsTimestampStringWithLevels, ( m_linear.PathAsString().ToStdString() )( 2 ) );
|
||||||
|
|
||||||
// Sheet0 is the root sheet and isn't in the path
|
// Sheet0 is the root sheet and isn't in the path
|
||||||
BOOST_CHECK_EQUAL( m_linear.PathHumanReadable(), "/Sheet1/Sheet2/" );
|
BOOST_CHECK_EQUAL( m_linear.PathHumanReadable(), "/Sheet1/Sheet2/" );
|
||||||
|
|
Loading…
Reference in New Issue