diff --git a/eeschema/dialogs/dialog_fields_editor_global.cpp b/eeschema/dialogs/dialog_fields_editor_global.cpp index c051827f7d..2fa584bffb 100644 --- a/eeschema/dialogs/dialog_fields_editor_global.cpp +++ b/eeschema/dialogs/dialog_fields_editor_global.cpp @@ -648,7 +648,7 @@ public: for( unsigned compRef = 0; compRef < m_componentRefs.GetCount(); ++ compRef ) { const KIID& compId = m_componentRefs[ compRef ].GetComp()->m_Uuid; - wxString text = m_dataStore[ compId ][ column_label ]; + wxString text = m_dataStore[ compId ][ column_label ]; width = std::max( width, GetTextSize( text, GetView() ).x ); } diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp index 049f81d8d8..0d00e94fb4 100644 --- a/eeschema/erc.cpp +++ b/eeschema/erc.cpp @@ -643,8 +643,8 @@ struct compare_labels { bool operator() ( const NETLIST_OBJECT* lab1, const NETLIST_OBJECT* lab2 ) const { - wxString str1 = lab1->m_SheetPath.Path() + lab1->m_Label; - wxString str2 = lab2->m_SheetPath.Path() + lab2->m_Label; + wxString str1 = lab1->m_SheetPath.PathAsString() + lab1->m_Label; + wxString str2 = lab2->m_SheetPath.PathAsString() + lab2->m_Label; return str1.Cmp( str2 ) < 0; } @@ -662,7 +662,7 @@ struct compare_paths { 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(); } }; @@ -756,7 +756,7 @@ void NETLIST_OBJECT_LIST::TestforSimilarLabels() for( ; it_uniq != uniqueLabelList.end(); ++it_uniq ) { - if( ( *it )->m_SheetPath.Path() == ( *it_uniq )->m_SheetPath.Path() ) + if(( *it )->m_SheetPath.Path() == ( *it_uniq )->m_SheetPath.Path() ) loc_labelList.insert( *it_uniq ); } diff --git a/eeschema/netlist_exporters/netlist_exporter_generic.cpp b/eeschema/netlist_exporters/netlist_exporter_generic.cpp index 74254b6f96..7d984df2bb 100644 --- a/eeschema/netlist_exporters/netlist_exporter_generic.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_generic.cpp @@ -270,7 +270,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents() xcomp->AddChild( xsheetpath = node( "sheetpath" ) ); 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() ) ); } } @@ -314,7 +314,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeDesignHeader() sheetTxt.Printf( "%u", i + 1 ); xsheet->AddAttribute( "number", sheetTxt ); xsheet->AddAttribute( "name", sheetList[i].PathHumanReadable() ); - xsheet->AddAttribute( "tstamps", sheetList[i].Path() ); + xsheet->AddAttribute( "tstamps", sheetList[i].PathAsString() ); TITLE_BLOCK tb = screen->GetTitleBlock(); diff --git a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp index 9a998fc6eb..04f5f77241 100644 --- a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp @@ -102,7 +102,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName, field = comp->GetRef( &sheetList[i] ); ret |= fprintf( f, " ( %s %s", - TO_UTF8( comp->GetPath( &sheetList[i] ) ), + TO_UTF8( sheetList[i].PathAsString() + comp->m_Uuid.AsString() ), TO_UTF8( footprint ) ); ret |= fprintf( f, " %s", TO_UTF8( field ) ); diff --git a/eeschema/netlist_object_list.cpp b/eeschema/netlist_object_list.cpp index 7a3adf2899..b4aa88c0f3 100644 --- a/eeschema/netlist_object_list.cpp +++ b/eeschema/netlist_object_list.cpp @@ -312,14 +312,12 @@ static bool evalLabelsPriority( const NETLIST_OBJECT* aLabel1, const NETLIST_OBJ // Global labels have the highest prioriy. // For local labels: names are prefixed by their sheetpath // use name defined in the more top level hierarchical sheet - // (i.e. shorter timestamp path because paths are ///... - // and timestamp = 8 letters. // Note: the final net name uses human sheetpath name, not timestamp sheetpath name // They are equivalent, but not for human readers. if( ! aLabel1->IsLabelGlobal() && ! aLabel2->IsLabelGlobal() ) { - if( aLabel1->m_SheetPath.Path().Length() != aLabel2->m_SheetPath.Path().Length() ) - return aLabel1->m_SheetPath.Path().Length() < aLabel2->m_SheetPath.Path().Length(); + if( aLabel1->m_SheetPath.size() != aLabel2->m_SheetPath.size() ) + return aLabel1->m_SheetPath.size() < aLabel2->m_SheetPath.size(); } int priority1 = getPriority( aLabel1 ); diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index bc78499d27..1d037ec90f 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -183,7 +183,7 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) : m_transform = aComponent.m_transform; m_prefix = aComponent.m_prefix; - m_PathsAndReferences = aComponent.m_PathsAndReferences; + m_instanceReferences = aComponent.m_instanceReferences; m_Fields = aComponent.m_Fields; // 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, - int aMulti ) +void SCH_COMPONENT::AddHierarchicalReference( const KIID_PATH& aPath, const wxString& aRef, + 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) - for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ ) + for( unsigned ii = 0; ii < m_instanceReferences.size(); ii++ ) { - tokenizer.SetString( m_PathsAndReferences[ii], separators ); - h_path = tokenizer.GetNextToken(); - - if( h_path.Cmp( aPath ) == 0 ) + if( m_instanceReferences[ii].m_Path == aPath ) { - m_PathsAndReferences.RemoveAt( ii ); + m_instanceReferences.erase( m_instanceReferences.begin() + ii ); ii--; } } - h_ref = aPath + wxT( " " ) + aRef; - h_ref << wxT( " " ) << aMulti; - m_PathsAndReferences.Add( h_ref ); -} - - -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(); + COMPONENT_INSTANCE_REFERENCE instance; + instance.m_Path = aPath; + instance.m_Reference = aRef; + instance.m_Unit = aUnit; + m_instanceReferences.push_back( instance ); } const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet ) { - wxString path = GetPath( sheet ); - wxString h_path; - wxStringTokenizer tokenizer; - wxString separators( wxT( " " ) ); + KIID_PATH path = sheet->Path(); - for( const wxString& entry : m_PathsAndReferences ) + for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences ) { - tokenizer.SetString( entry, separators ); - h_path = tokenizer.GetNextToken(); - - if( h_path.Cmp( path ) == 0 ) - return tokenizer.GetNextToken(); + if( instance.m_Path == path ) + return instance.m_Reference; } // 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 ) { - wxString path = GetPath( sheet ); - - bool notInArray = true; - - wxString h_path, h_ref; - wxStringTokenizer tokenizer; - wxString separators( wxT( " " ) ); + KIID_PATH path = sheet->Path(); + bool notInArray = true; // 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 ); - h_path = tokenizer.GetNextToken(); - - if( h_path.Cmp( path ) == 0 ) + if( instance.m_Path == path ) { - // just update the reference text, not the timestamp. - 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; + instance.m_Reference = ref; 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 ) { - wxString path = GetPath( aSheet ); - wxString h_path; - wxStringTokenizer tokenizer; - wxString separators( wxT( " " ) ); + KIID_PATH path = aSheet->Path(); - for( const wxString& entry : m_PathsAndReferences ) + for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences ) { - tokenizer.SetString( entry, separators ); - h_path = tokenizer.GetNextToken(); - - if( h_path.Cmp( path ) == 0 ) - { - wxString ref = tokenizer.GetNextToken(); - return ref.Last() != '?'; - } + if( instance.m_Path == path ) + return instance.m_Reference.Last() != '?'; } 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 { - wxString path = GetPath( aSheet ); - wxString h_path, h_multi; - wxStringTokenizer tokenizer; - wxString separators( wxT( " " ) ); + KIID_PATH path = aSheet->Path(); - for( const wxString& entry : m_PathsAndReferences ) + for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences ) { - tokenizer.SetString( entry, separators ); - h_path = tokenizer.GetNextToken(); - - if( h_path.Cmp( path ) == 0 ) - { - tokenizer.GetNextToken(); // Skip reference - h_multi = tokenizer.GetNextToken(); - long imulti = 1; - h_multi.ToLong( &imulti ); - return imulti; - } + if( instance.m_Path == path ) + return instance.m_Unit; } // 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 ) { - 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 - for( wxString& entry : m_PathsAndReferences ) + // check to see if it is already there before inserting it + for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences ) { - tokenizer.SetString( entry, separators ); - h_path = tokenizer.GetNextToken(); - - if( h_path.Cmp( path ) == 0 ) + if( instance.m_Path == path ) { - //just update the unit selection. - 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; + instance.m_Unit = aUnitSelection; notInArray = false; } } @@ -1021,15 +950,12 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem ) m_transform = component->m_transform; 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 ) { - wxArrayString reference_fields; - static const wxChar separators[] = wxT( " " ); - // Build a reference with no annotation, // i.e. a reference ended by only one '?' wxString defRef = m_prefix; @@ -1044,25 +970,21 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) defRef.Append( wxT( "?" ) ); - wxString path; - if( aSheetPath ) - path = GetPath( aSheetPath ); - - for( wxString& entry : m_PathsAndReferences ) { - // Break hierarchical reference in path, ref and multi selection: - reference_fields = wxStringTokenize( entry, separators ); + KIID_PATH path = aSheetPath->Path(); - // For all components: if aSheetPath is not NULL, - // remove annotation only for the given path - if( aSheetPath == NULL || reference_fields[0].Cmp( path ) == 0 ) + for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences ) { - wxString newHref = reference_fields[0]; - newHref << wxT( " " ) << defRef << wxT( " " ) << reference_fields[2]; - entry = newHref; + if( instance.m_Path == path ) + instance.m_Reference = defRef; } } + else + { + for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences ) + instance.m_Reference = defRef; + } // These 2 changes do not work in complex hierarchy. // 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: - wxCHECK( !aSheetPathName.IsEmpty(), false ); + wxCHECK( aSheetPath.size() > 0, false ); wxString reference_path; - // The full component reference path is aSheetPathName + the component time stamp itself - // 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++ ) + for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences ) { - // Break hierarchical reference in path, ref and multi selection: - reference_path = m_PathsAndReferences[ii].BeforeFirst( ' ' ); - // if aSheetPath is found, nothing to do: - if( reference_path.Cmp( full_AR_path ) == 0 ) + if( instance.m_Path == aSheetPath ) return false; } - // This entry does not exist: add it, with a (temporary?) reference (last ref used for display) - AddHierarchicalReference( full_AR_path, m_Fields[REFERENCE].GetText(), m_unit ); + // This entry does not exist: add it, with its last-used reference + AddHierarchicalReference( aSheetPath, m_Fields[REFERENCE].GetText(), m_unit ); return true; } @@ -1785,7 +1700,7 @@ SCH_COMPONENT& SCH_COMPONENT::operator=( const SCH_ITEM& aItem ) m_convert = c->m_convert; 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 diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index fa12f5bcbf..42acf02fab 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -84,6 +84,14 @@ typedef std::weak_ptr PART_REF; extern std::string toUTFTildaText( const wxString& txt ); +struct COMPONENT_INSTANCE_REFERENCE +{ + KIID_PATH m_Path; + wxString m_Reference; + int m_Unit; +}; + + /** * SCH_COMPONENT * describes a real schematic component @@ -121,13 +129,9 @@ private: bool m_isInNetlist; ///< True if the component should appear in the netlist - /** - * Defines the hierarchical path and reference of the component. This allows support - * for hierarchical sheets that reference the same schematic. The format for the path - * is /<sheet time stamp>/<sheet time stamp>/.../&lscomponent time stamp>. - * A single / denotes the root sheet. - */ - wxArrayString m_PathsAndReferences; + // Defines the hierarchical path and reference of the component. This allows support + // for multiple references to a single sub-sheet. + std::vector m_instanceReferences; void Init( const wxPoint& pos = wxPoint( 0, 0 ) ); @@ -176,7 +180,10 @@ public: return wxT( "SCH_COMPONENT" ); } - const wxArrayString& GetPathsAndReferences() const { return m_PathsAndReferences; } + const std::vector& GetInstanceReferences() + { + return m_instanceReferences; + } void ViewGetLayers( int aLayers[], int& aCount ) const override; @@ -314,8 +321,8 @@ public: void ClearAnnotation( SCH_SHEET_PATH* aSheetPath ); /** - * Add aSheetPath in m_PathsAndReferences alternate references list, - * if this entry does not exist + * Add an instance to the alternate references list (m_instanceReferences), if this entry + * does not already exist. * Do nothing if already exists. * In component lists shared by more than one sheet path, an entry for each * sheet path must exist to manage references @@ -324,7 +331,7 @@ public: * not the full component sheet path * @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 ...) @@ -492,9 +499,6 @@ public: 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. * @@ -534,11 +538,11 @@ public: * @param aPath is the hierarchical path (/<sheet timestamp>/<component * timestamp> like /05678E50/A23EF560) * @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, - const wxString& aRef, - int aMulti ); + void AddHierarchicalReference( const KIID_PATH& aPath, + const wxString& aRef, + int aUnit ); // returns the unit selection, for the given sheet path. int GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const; diff --git a/eeschema/sch_eagle_plugin.cpp b/eeschema/sch_eagle_plugin.cpp index 3a360cd3c3..57e5d3ae39 100644 --- a/eeschema/sch_eagle_plugin.cpp +++ b/eeschema/sch_eagle_plugin.cpp @@ -1154,8 +1154,7 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode ) SCH_SHEET_PATH sheetpath; m_rootSheet->LocatePathOfScreen( screen, &sheetpath ); - wxString current_sheetpath = sheetpath.Path(); - current_sheetpath += component->m_Uuid.AsString(); + wxString current_sheetpath = sheetpath.PathAsString() + component->m_Uuid.AsString(); component->GetField( REFERENCE )->SetText( reference ); component->AddHierarchicalReference( current_sheetpath, reference, unit ); diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 29d694f022..047b8f663e 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -368,20 +368,17 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount() SCH_SCREEN* screen; SCH_SCREENS s_list; - /* Set the sheet count, and the sheet number (1 for root sheet) - */ - int sheet_count = g_RootSheet->CountSheets(); - int SheetNumber = 1; - wxString current_sheetpath = g_CurrentSheet->Path(); - SCH_SHEET_LIST sheetList( g_RootSheet ); + // Set the sheet count, and the sheet number (1 for root sheet) + int sheet_count = g_RootSheet->CountSheets(); + int SheetNumber = 1; + const KIID_PATH& current_sheetpath = g_CurrentSheet->Path(); + SCH_SHEET_LIST sheetList( g_RootSheet ); // Examine all sheets path to find the current sheets path, // and count them from root to the current sheet path: for( const SCH_SHEET_PATH& sheet : sheetList ) { - wxString sheetpath = sheet.Path(); - - if( sheetpath == current_sheetpath ) // Current sheet path found + if( sheet.Path() == current_sheetpath ) // Current sheet path found break; SheetNumber++; // Not found, increment before this current path diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp index 9533af5700..d6a85032f3 100644 --- a/eeschema/sch_legacy_plugin.cpp +++ b/eeschema/sch_legacy_plugin.cpp @@ -1583,9 +1583,23 @@ SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( LINE_READER& aReader ) SCH_PARSE_ERROR( "missing 'Path=' token", aReader, line ); 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="; len = strlen( strCompare ); @@ -1968,10 +1982,10 @@ void SCH_LEGACY_PLUGIN::saveComponent( SCH_COMPONENT* aComponent ) static wxString delimiters( wxT( " " ) ); // 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 ); - name1 = toUTFTildaText( reference_fields[1] ); + const COMPONENT_INSTANCE_REFERENCE& instance = aComponent->GetInstanceReferences()[0]; + name1 = toUTFTildaText( instance.m_Reference ); } else { @@ -2011,9 +2025,9 @@ void SCH_LEGACY_PLUGIN::saveComponent( SCH_COMPONENT* aComponent ) * the reference inf is already saved * 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: * 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' * Part is the conventional component part selection for this 'path' */ - reference_fields = wxStringTokenize( aComponent->GetPathsAndReferences()[ii], - delimiters ); + wxString path = "/"; - // Convert Alternate Reference paths back to legacy timestamps: - wxArrayString pathParts = wxSplit( reference_fields[0], '/' ); - wxString path; + // Skip root sheet + for( int i = 1; i < instance.m_Path.size(); ++i ) + path += instance.m_Path[i].AsLegacyTimestampString() + "/"; - for( const wxString& pathPart : pathParts ) - { - if( !pathPart.IsEmpty() ) - path += "/" + KIID( pathPart ).AsLegacyTimestampString(); - } - - 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] ) ); + m_out->Print( 0, "AR Path=\"%s\" Ref=\"%s\" Part=\"%d\" \n", + TO_UTF8( path + aComponent->m_Uuid.AsLegacyTimestampString() ), + TO_UTF8( instance.m_Reference ), + instance.m_Unit ); } } diff --git a/eeschema/sch_reference_list.h b/eeschema/sch_reference_list.h index 6f24198205..2bf48b59c8 100644 --- a/eeschema/sch_reference_list.h +++ b/eeschema/sch_reference_list.h @@ -60,7 +60,7 @@ class SCH_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. - KIID m_Uuid; ///< UUID of the component. + KIID m_Uuid; ///< UUID of the component. EDA_TEXT* m_Value; ///< The component value of the reference. It is the ///< same for all instances. int m_NumRef; ///< The numeric part of the reference designator. @@ -101,7 +101,7 @@ public: 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 { - 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() diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index ea215047ec..c8dfae1a44 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -1308,7 +1308,7 @@ void SCH_SCREENS::BuildClientSheetPathList() { if( used_screen == curr_screen ) { - curr_screen->GetClientSheetPaths().Add( sheetpath.Path() ); + curr_screen->GetClientSheetPaths().Add( sheetpath.PathAsString() ); break; } } diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index d4c5485182..66d4efa6e9 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -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; @@ -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 ) { // return a PathName for the root sheet (like "/" or "" diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index 6a2ac38e15..db9e08d796 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -194,12 +194,18 @@ public: SCH_SCREEN* LastScreen() const; /** - * Function Path + * Function PathAsString * the path uses the time stamps which do not changes even when editing * sheet parameters * 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 diff --git a/eeschema/tools/backannotate.cpp b/eeschema/tools/backannotate.cpp index 258cefb210..0879ecafa9 100644 --- a/eeschema/tools/backannotate.cpp +++ b/eeschema/tools/backannotate.cpp @@ -290,9 +290,10 @@ int BACK_ANNOTATE::checkSharedSchematicErrors() // 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 int usageCount = 1; + 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 ) continue; diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 6c6e526b04..612a0678ff 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -705,10 +705,10 @@ private: wxString m_Doc; // File name and path for documentation file. wxString m_KeyWord; // Search keywords to find module in library. - KIID_PATH m_Path; // Path to associated symbol ([sheetUUID, .., symbolUUID]). + KIID_PATH m_Path; // Path to associated symbol ([sheetUUID, .., symbolUUID]). timestamp_t m_LastEditTime; int m_arflag; // Use to trace ratsnest and auto routing. - KIID m_Link; // Temporary logical link used during editing + KIID m_Link; // Temporary logical link used during editing int m_CntRot90; // Horizontal automatic placement cost ( 0..10 ). int m_CntRot180; // Vertical automatic placement cost ( 0..10 ). diff --git a/pcbnew/netlist_reader/kicad_netlist_reader.cpp b/pcbnew/netlist_reader/kicad_netlist_reader.cpp index 9a61b60766..d4ff317e86 100644 --- a/pcbnew/netlist_reader/kicad_netlist_reader.cpp +++ b/pcbnew/netlist_reader/kicad_netlist_reader.cpp @@ -298,8 +298,8 @@ void KICAD_NETLIST_PARSER::parseComponent() wxString value; wxString library; wxString name; - KIID_PATH path; - KIID uuid; + KIID_PATH path; + KIID uuid; // The token comp was read, so the next data is (ref P1) while( (token = NextTok()) != T_RIGHT ) diff --git a/pcbnew/netlist_reader/pcb_netlist.h b/pcbnew/netlist_reader/pcb_netlist.h index a4bdc53223..11218dbea7 100644 --- a/pcbnew/netlist_reader/pcb_netlist.h +++ b/pcbnew/netlist_reader/pcb_netlist.h @@ -86,7 +86,7 @@ class COMPONENT wxString m_value; ///< The component value found in netlist. /// A fully specified path to the component: [ sheetUUID, sheetUUID, .., componentUUID ] - KIID_PATH m_path; + KIID_PATH m_path; /// The name of the component in #m_library used when it was placed on the schematic.. wxString m_name; diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_component.h b/pcbnew/pcad2kicadpcb_plugin/pcb_component.h index 2ac279ef7f..8f8d8eebe2 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_component.h +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_component.h @@ -52,7 +52,7 @@ public: char m_objType; int m_PCadLayer; PCB_LAYER_ID m_KiCadLayer; - KIID m_uuid; + KIID m_uuid; int m_positionX; int m_positionY; int m_rotation; diff --git a/qa/eeschema/test_sch_sheet_path.cpp b/qa/eeschema/test_sch_sheet_path.cpp index 64767c7a14..37c3b05aef 100644 --- a/qa/eeschema/test_sch_sheet_path.cpp +++ b/qa/eeschema/test_sch_sheet_path.cpp @@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE( Empty ) BOOST_CHECK_EQUAL( m_empty_path.Last(), 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(), "/" ); } @@ -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>/ 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 BOOST_CHECK_EQUAL( m_linear.PathHumanReadable(), "/Sheet1/Sheet2/" );