From 944c9eac7c7cf4077776c5ff5f5047968fae156c Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 16 Jul 2020 18:31:36 +0100 Subject: [PATCH] Allow Update Schematic from PCB to re-link based on refdes. Fixes https://gitlab.com/kicad/code/kicad/issues/4306 --- eeschema/component_references_lister.cpp | 12 ++ eeschema/dialogs/dialog_update_from_pcb.cpp | 52 ++++++- eeschema/dialogs/dialog_update_from_pcb.h | 1 + .../dialogs/dialog_update_from_pcb_base.cpp | 77 ++++++---- .../dialogs/dialog_update_from_pcb_base.fbp | 137 ++++++++++++++---- .../dialogs/dialog_update_from_pcb_base.h | 5 +- eeschema/sch_reference_list.h | 9 +- eeschema/tools/backannotate.cpp | 38 ++++- eeschema/tools/backannotate.h | 9 +- include/mail_type.h | 1 + pcbnew/cross-probing.cpp | 32 +++- 11 files changed, 292 insertions(+), 81 deletions(-) diff --git a/eeschema/component_references_lister.cpp b/eeschema/component_references_lister.cpp index 28ff8e675a..45872e7ac5 100644 --- a/eeschema/component_references_lister.cpp +++ b/eeschema/component_references_lister.cpp @@ -178,6 +178,18 @@ int SCH_REFERENCE_LIST::FindRefByPath( const wxString& aPath ) const } +int SCH_REFERENCE_LIST::FindRef( const wxString& aRef ) const +{ + for( size_t i = 0; i < flatList.size(); ++i ) + { + if( flatList[i].GetRef() == aRef ) + return i; + } + + return -1; +} + + void SCH_REFERENCE_LIST::GetRefsInUse( int aIndex, std::vector< int >& aIdList, int aMinRefId ) { aIdList.clear(); diff --git a/eeschema/dialogs/dialog_update_from_pcb.cpp b/eeschema/dialogs/dialog_update_from_pcb.cpp index f0854641ee..5c8d9a2812 100644 --- a/eeschema/dialogs/dialog_update_from_pcb.cpp +++ b/eeschema/dialogs/dialog_update_from_pcb.cpp @@ -42,7 +42,19 @@ DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB( SCH_EDIT_FRAME* aParent ) m_messagePanel->SetLazyUpdate( true ); m_messagePanel->GetSizer()->SetSizeHints( this ); - m_cbUpdateReferences->SetValue( s_savedDialogState.UpdateReferences ); + m_cbRelinkFootprints->SetValue( s_savedDialogState.MatchByReference ); + + if( m_cbRelinkFootprints->GetValue() ) + { + m_cbUpdateReferences->SetValue( false ); + m_cbUpdateReferences->Enable( false ); + } + else + { + m_cbUpdateReferences->SetValue( s_savedDialogState.UpdateReferences ); + m_cbUpdateReferences->Enable( true ); + } + m_cbUpdateFootprints->SetValue( s_savedDialogState.UpdateFootprints ); m_cbUpdateValues->SetValue( s_savedDialogState.UpdateValues ); m_cbUpdateNetNames->SetValue( s_savedDialogState.UpdateNetNames ); @@ -64,6 +76,7 @@ void DIALOG_UPDATE_FROM_PCB::updateData() m_messagePanel->Clear(); BACK_ANNOTATE backAnno( this->m_frame, m_messagePanel->Reporter(), + m_cbRelinkFootprints->GetValue(), m_cbUpdateFootprints->GetValue(), m_cbUpdateValues->GetValue(), m_cbUpdateReferences->GetValue(), @@ -91,12 +104,34 @@ DIALOG_UPDATE_FROM_PCB::~DIALOG_UPDATE_FROM_PCB() void DIALOG_UPDATE_FROM_PCB::OnOptionChanged( wxCommandEvent& event ) { + if( event.GetEventObject() == m_cbRelinkFootprints ) + { + if( m_cbRelinkFootprints->GetValue() ) + { + m_cbUpdateReferences->SetValue( false ); + m_cbUpdateReferences->Enable( false ); + } + else + { + m_cbUpdateReferences->SetValue( s_savedDialogState.UpdateReferences ); + m_cbUpdateReferences->Enable( true ); + } + } + updateData(); - s_savedDialogState.UpdateReferences = m_cbUpdateReferences->GetValue(); - s_savedDialogState.UpdateFootprints = m_cbUpdateFootprints->GetValue(); - s_savedDialogState.UpdateValues = m_cbUpdateValues->GetValue(); - s_savedDialogState.UpdateNetNames = m_cbUpdateNetNames->GetValue(); - s_savedDialogState.IgnoreOtherProjectsErrors = m_cbIgnoreOtherProjects->GetValue(); + + if( event.GetEventObject() == m_cbRelinkFootprints ) + s_savedDialogState.MatchByReference = m_cbRelinkFootprints->GetValue(); + else if( event.GetEventObject() == m_cbUpdateReferences ) + s_savedDialogState.UpdateReferences = m_cbUpdateReferences->GetValue(); + else if( event.GetEventObject() == m_cbUpdateFootprints ) + s_savedDialogState.UpdateFootprints = m_cbUpdateFootprints->GetValue(); + else if( event.GetEventObject() == m_cbUpdateValues ) + s_savedDialogState.UpdateValues = m_cbUpdateValues->GetValue(); + else if( event.GetEventObject() == m_cbUpdateNetNames ) + s_savedDialogState.UpdateNetNames = m_cbUpdateNetNames->GetValue(); + else if( event.GetEventObject() == m_cbIgnoreOtherProjects ) + s_savedDialogState.IgnoreOtherProjectsErrors = m_cbIgnoreOtherProjects->GetValue(); } void DIALOG_UPDATE_FROM_PCB::OnUpdateClick( wxCommandEvent& event ) @@ -105,6 +140,7 @@ void DIALOG_UPDATE_FROM_PCB::OnUpdateClick( wxCommandEvent& event ) m_messagePanel->Clear(); BACK_ANNOTATE backAnno( m_frame, m_messagePanel->Reporter(), + m_cbRelinkFootprints->GetValue(), m_cbUpdateFootprints->GetValue(), m_cbUpdateValues->GetValue(), m_cbUpdateReferences->GetValue(), @@ -119,6 +155,10 @@ void DIALOG_UPDATE_FROM_PCB::OnUpdateClick( wxCommandEvent& event ) m_frame->SyncView(); m_frame->OnModify(); m_frame->GetCanvas()->Refresh(); + + if( m_cbRelinkFootprints->GetValue() ) + backAnno.PushNewLinksToPCB(); } + m_messagePanel->Flush( true ); } diff --git a/eeschema/dialogs/dialog_update_from_pcb.h b/eeschema/dialogs/dialog_update_from_pcb.h index 69a792d0f7..0028a30a8f 100644 --- a/eeschema/dialogs/dialog_update_from_pcb.h +++ b/eeschema/dialogs/dialog_update_from_pcb.h @@ -40,6 +40,7 @@ class DIALOG_UPDATE_FROM_PCB : public DIALOG_UPDATE_FROM_PCB_BASE struct DIALOG_UPDATE_FROM_PCB_SAVED_STATE { // Flags to remember last checkboxes state + bool MatchByReference; bool UpdateReferences; bool UpdateFootprints; bool UpdateValues; diff --git a/eeschema/dialogs/dialog_update_from_pcb_base.cpp b/eeschema/dialogs/dialog_update_from_pcb_base.cpp index 1a0cc27552..c3de777df8 100644 --- a/eeschema/dialogs/dialog_update_from_pcb_base.cpp +++ b/eeschema/dialogs/dialog_update_from_pcb_base.cpp @@ -25,53 +25,68 @@ DIALOG_UPDATE_FROM_PCB_BASE::DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWi sbSizerOptions = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options") ), wxVERTICAL ); wxFlexGridSizer* fgSizer1; - fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 ); + fgSizer1 = new wxFlexGridSizer( 0, 1, 0, 0 ); fgSizer1->SetFlexibleDirection( wxVERTICAL ); fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - m_cbUpdateReferences = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Update reference designators"), wxDefaultPosition, wxDefaultSize, 0 ); - m_cbUpdateReferences->SetValue(true); - m_cbUpdateReferences->SetToolTip( _("Update references of symbols that have been changed in the PCB editor.") ); + m_cbRelinkFootprints = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Re-link footprints to schematic symbols based on their reference designators"), wxDefaultPosition, wxDefaultSize, 0 ); + m_cbRelinkFootprints->SetToolTip( _("Normally footprints are linked to their symbols via their Unique IDs. Select this option only if you want to reset the footprint linkages based on their reference designators.") ); - fgSizer1->Add( m_cbUpdateReferences, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + fgSizer1->Add( m_cbRelinkFootprints, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); m_cbIgnoreOtherProjects = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Ignore errors in shared schematic sheets"), wxDefaultPosition, wxDefaultSize, 0 ); m_cbIgnoreOtherProjects->SetToolTip( _("Shared schematic sheets used in complex hierarchies have constraints. They are not always compatible with back annotation when updating footprints and values . \nIf this option is selected, errors generated by sharing will be disabled.") ); fgSizer1->Add( m_cbIgnoreOtherProjects, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - m_cbUpdateValues = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Update values"), wxDefaultPosition, wxDefaultSize, 0 ); - m_cbUpdateValues->SetToolTip( _("Update symbols values that have been replaced in the PCB editor.") ); - fgSizer1->Add( m_cbUpdateValues, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - - fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_cbUpdateFootprints = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Update footprint assingments"), wxDefaultPosition, wxDefaultSize, 0 ); - m_cbUpdateFootprints->SetToolTip( _("Update footprint associations of symbols whose footprints have been replaced with different footprints in PCB.") ); - - fgSizer1->Add( m_cbUpdateFootprints, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - - fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_cbUpdateNetNames = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Update net names"), wxDefaultPosition, wxDefaultSize, 0 ); - fgSizer1->Add( m_cbUpdateNetNames, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - - sbSizerOptions->Add( fgSizer1, 1, wxEXPAND, 5 ); + sbSizerOptions->Add( fgSizer1, 1, wxEXPAND|wxBOTTOM, 5 ); bUpperSizer->Add( sbSizerOptions, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + wxStaticBoxSizer* sbSizer2; + sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Update") ), wxVERTICAL ); + + wxFlexGridSizer* fgSizer2; + fgSizer2 = new wxFlexGridSizer( 0, 2, 0, 0 ); + fgSizer2->AddGrowableCol( 0 ); + fgSizer2->AddGrowableCol( 1 ); + fgSizer2->SetFlexibleDirection( wxBOTH ); + fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_cbUpdateReferences = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, _("Reference designators"), wxDefaultPosition, wxDefaultSize, 0 ); + m_cbUpdateReferences->SetValue(true); + m_cbUpdateReferences->SetToolTip( _("Update references of symbols that have been changed in the PCB editor.") ); + + fgSizer2->Add( m_cbUpdateReferences, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_cbUpdateFootprints = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, _("Footprint assignments"), wxDefaultPosition, wxDefaultSize, 0 ); + m_cbUpdateFootprints->SetToolTip( _("Update footprint associations of symbols whose footprints have been replaced with different footprints in PCB.") ); + + fgSizer2->Add( m_cbUpdateFootprints, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_cbUpdateValues = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, _("Values"), wxDefaultPosition, wxDefaultSize, 0 ); + m_cbUpdateValues->SetToolTip( _("Update symbols values that have been replaced in the PCB editor.") ); + + fgSizer2->Add( m_cbUpdateValues, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_cbUpdateNetNames = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, _("Net names"), wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer2->Add( m_cbUpdateNetNames, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + sbSizer2->Add( fgSizer2, 1, wxEXPAND, 5 ); + + + bUpperSizer->Add( sbSizer2, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + bMainSizer->Add( bUpperSizer, 0, wxALL|wxEXPAND, 5 ); wxBoxSizer* bLowerSizer; bLowerSizer = new wxBoxSizer( wxVERTICAL ); - bLowerSizer->SetMinSize( wxSize( 660,300 ) ); + bLowerSizer->SetMinSize( wxSize( 600,260 ) ); m_messagePanel = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); bLowerSizer->Add( m_messagePanel, 1, wxEXPAND | wxALL, 5 ); @@ -93,10 +108,11 @@ DIALOG_UPDATE_FROM_PCB_BASE::DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWi bMainSizer->Fit( this ); // Connect Events - m_cbUpdateReferences->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); + m_cbRelinkFootprints->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbIgnoreOtherProjects->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); - m_cbUpdateValues->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); + m_cbUpdateReferences->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbUpdateFootprints->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); + m_cbUpdateValues->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbUpdateNetNames->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnUpdateClick ), NULL, this ); } @@ -104,10 +120,11 @@ DIALOG_UPDATE_FROM_PCB_BASE::DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWi DIALOG_UPDATE_FROM_PCB_BASE::~DIALOG_UPDATE_FROM_PCB_BASE() { // Disconnect Events - m_cbUpdateReferences->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); + m_cbRelinkFootprints->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbIgnoreOtherProjects->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); - m_cbUpdateValues->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); + m_cbUpdateReferences->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbUpdateFootprints->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); + m_cbUpdateValues->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbUpdateNetNames->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnUpdateClick ), NULL, this ); diff --git a/eeschema/dialogs/dialog_update_from_pcb_base.fbp b/eeschema/dialogs/dialog_update_from_pcb_base.fbp index 73732d57a3..8672124d80 100644 --- a/eeschema/dialogs/dialog_update_from_pcb_base.fbp +++ b/eeschema/dialogs/dialog_update_from_pcb_base.fbp @@ -81,10 +81,10 @@ none 5 - wxEXPAND + wxEXPAND|wxBOTTOM 1 - 2 + 1 wxVERTICAL @@ -99,7 +99,7 @@ 5 wxBOTTOM|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -113,7 +113,7 @@ 1 0 - 1 + 0 1 1 @@ -128,7 +128,7 @@ 0 0 wxID_ANY - Update reference designators + Re-link footprints to schematic symbols based on their reference designators 0 @@ -136,7 +136,7 @@ 0 1 - m_cbUpdateReferences + m_cbRelinkFootprints 1 @@ -149,7 +149,7 @@ ; ; forward_declare 0 - Update references of symbols that have been changed in the PCB editor. + Normally footprints are linked to their symbols via their Unique IDs. Select this option only if you want to reset the footprint linkages based on their reference designators. wxFILTER_NONE wxDefaultValidator @@ -225,6 +225,38 @@ OnOptionChanged + + + + + + 5 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 1 + + wxID_ANY + Update + + sbSizer2 + wxVERTICAL + 1 + none + + 5 + wxEXPAND + 1 + + 2 + wxBOTH + 0,1 + + 0 + + fgSizer2 + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 5 wxBOTTOM|wxRIGHT|wxLEFT @@ -243,7 +275,7 @@ 1 0 - 0 + 1 1 1 @@ -258,7 +290,7 @@ 0 0 wxID_ANY - Update values + Reference designators 0 @@ -266,7 +298,7 @@ 0 1 - m_cbUpdateValues + m_cbUpdateReferences 1 @@ -277,9 +309,9 @@ 1 - ; forward_declare + ; ; forward_declare 0 - Update symbols values that have been replaced in the PCB editor. + Update references of symbols that have been changed in the PCB editor. wxFILTER_NONE wxDefaultValidator @@ -290,16 +322,6 @@ OnOptionChanged - - 5 - wxEXPAND - 1 - - 0 - protected - 0 - - 5 wxBOTTOM|wxRIGHT|wxLEFT @@ -333,7 +355,7 @@ 0 0 wxID_ANY - Update footprint assingments + Footprint assignments 0 @@ -367,12 +389,67 @@ 5 - wxEXPAND - 1 - - 0 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Values + + 0 + + + 0 + + 1 + m_cbUpdateValues + 1 + + protected - 0 + 1 + + Resizable + 1 + + + ; forward_declare + 0 + Update symbols values that have been replaced in the PCB editor. + + wxFILTER_NONE + wxDefaultValidator + + + + + OnOptionChanged @@ -408,7 +485,7 @@ 0 0 wxID_ANY - Update net names + Net names 0 @@ -451,7 +528,7 @@ wxEXPAND|wxTOP|wxRIGHT|wxLEFT 1 - 660,300 + 600,260 bLowerSizer wxVERTICAL none diff --git a/eeschema/dialogs/dialog_update_from_pcb_base.h b/eeschema/dialogs/dialog_update_from_pcb_base.h index bec9f5d2db..11f23b64da 100644 --- a/eeschema/dialogs/dialog_update_from_pcb_base.h +++ b/eeschema/dialogs/dialog_update_from_pcb_base.h @@ -35,10 +35,11 @@ class DIALOG_UPDATE_FROM_PCB_BASE : public DIALOG_SHIM private: protected: - wxCheckBox* m_cbUpdateReferences; + wxCheckBox* m_cbRelinkFootprints; wxCheckBox* m_cbIgnoreOtherProjects; - wxCheckBox* m_cbUpdateValues; + wxCheckBox* m_cbUpdateReferences; wxCheckBox* m_cbUpdateFootprints; + wxCheckBox* m_cbUpdateValues; wxCheckBox* m_cbUpdateNetNames; WX_HTML_REPORT_PANEL* m_messagePanel; wxStdDialogButtonSizer* m_sdbSizer; diff --git a/eeschema/sch_reference_list.h b/eeschema/sch_reference_list.h index 9e0c12d347..f53378f929 100644 --- a/eeschema/sch_reference_list.h +++ b/eeschema/sch_reference_list.h @@ -422,6 +422,13 @@ public: sort( flatList.begin(), flatList.end(), sortByReferenceOnly ); } + /** + * searches the list for a component with a given reference. + * @param aPath + * @return + */ + int FindRef( const wxString& aPath ) const; + /** * searches the sorted list of components for a another component with the same * reference and a given part unit. Use this method to manage components with @@ -433,7 +440,7 @@ public: int FindUnit( size_t aIndex, int aUnit ); /** - * @brief Searches unit with designated path + * searches the list for a component with the given KIID path * @param aPath path to search * @return index in aComponentsList if found or -1 if not found */ diff --git a/eeschema/tools/backannotate.cpp b/eeschema/tools/backannotate.cpp index 48b457a3f6..e19dc801a6 100644 --- a/eeschema/tools/backannotate.cpp +++ b/eeschema/tools/backannotate.cpp @@ -35,11 +35,12 @@ #include #include -BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, +BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aRelinkFootprints, bool aProcessFootprints, bool aProcessValues, bool aProcessReferences, bool aProcessNetNames, bool aIgnoreOtherProjects, bool aDryRun ) : m_reporter( aReporter ), + m_matchByReference( aRelinkFootprints ), m_processFootprints( aProcessFootprints ), m_processValues( aProcessValues ), m_processReferences( aProcessReferences ), @@ -113,6 +114,14 @@ bool BACK_ANNOTATE::FetchNetlistFromPCB( std::string& aNetlist ) } +void BACK_ANNOTATE::PushNewLinksToPCB() +{ + std::string nullPayload; + + m_frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_PCB_UPDATE_LINKS, nullPayload ); +} + + void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload ) { auto getStr = []( const PTREE& pt ) -> wxString @@ -142,7 +151,10 @@ void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload ) try { - path = getStr( item.second.get_child( "timestamp" ) ); + if( m_matchByReference ) + path = ref; + else + path = getStr( item.second.get_child( "timestamp" ) ); if( path == "" ) { @@ -198,15 +210,20 @@ void BACK_ANNOTATE::getChangeList() { const wxString& pcbPath = module.first; auto& pcbData = module.second; + int refIndex; bool foundInMultiunit = false; - for( auto& item : m_multiUnitsRefs ) + for( std::pair& item : m_multiUnitsRefs ) { SCH_REFERENCE_LIST& refList = item.second; - if( refList.FindRefByPath( pcbPath ) >= 0 ) - { + if( m_matchByReference ) + refIndex = refList.FindRef( pcbPath ); + else + refIndex = refList.FindRefByPath( pcbPath ); + if( refIndex >= 0 ) + { // If module linked to multi unit symbol, we add all symbol's units to // the change list foundInMultiunit = true; @@ -224,7 +241,10 @@ void BACK_ANNOTATE::getChangeList() if( foundInMultiunit ) continue; - int refIndex = m_refs.FindRefByPath( pcbPath ); + if( m_matchByReference ) + refIndex = m_refs.FindRef( pcbPath ); + else + refIndex = m_refs.FindRefByPath( pcbPath ); if( refIndex >= 0 ) { @@ -266,6 +286,12 @@ void BACK_ANNOTATE::checkForUnusedSymbols() ++i; } + + if( m_matchByReference && !m_frame->ReadyToNetlist() ) + { + m_reporter.ReportTail( _( "Cannot relink footprints because schematic is not fully annotated" ), + RPT_SEVERITY_ERROR ); + } } diff --git a/eeschema/tools/backannotate.h b/eeschema/tools/backannotate.h index fbcd8cebab..06be4835ba 100644 --- a/eeschema/tools/backannotate.h +++ b/eeschema/tools/backannotate.h @@ -79,9 +79,9 @@ public: using CHANGELIST_ITEM = std::pair>; - BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aProcessFootprints, - bool aProcessValues, bool aProcessReferences, bool aProcessNetNames, - bool aIgnoreOtherProjects, bool aDryRun ); + BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aRelinkFootprints, + bool aProcessFootprints, bool aProcessValues, bool aProcessReferences, + bool aProcessNetNames, bool aIgnoreOtherProjects, bool aDryRun ); ~BACK_ANNOTATE(); /** @@ -91,6 +91,8 @@ public: */ bool FetchNetlistFromPCB( std::string& aNetlist ); + void PushNewLinksToPCB(); + /** * @brief Run back annotation algorithm. If any errors, back annotation doesn't run. * only report @@ -102,6 +104,7 @@ public: private: REPORTER& m_reporter; + bool m_matchByReference; bool m_processFootprints; bool m_processValues; bool m_processReferences; diff --git a/include/mail_type.h b/include/mail_type.h index 5c7a384ccc..e50caecc41 100644 --- a/include/mail_type.h +++ b/include/mail_type.h @@ -45,6 +45,7 @@ enum MAIL_T MAIL_IMPORT_FILE, // Import a different format file MAIL_SCH_GET_NETLIST, // Fetch a netlist from schematics MAIL_PCB_GET_NETLIST, // Fetch a netlist from PCB layout + MAIL_PCB_UPDATE_LINKS, // Update the schematic symbol paths in the PCB's footprints MAIL_SCH_REFRESH, // Tell the schematic editor to refresh the display. MAIL_SCH_CLEAN_NETCLASSES, // Tell the schematic editor to clean stale nets out of diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 5a6582b1a5..0faaa7247b 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -41,11 +41,13 @@ #include #include #include +#include #include #include #include #include #include +#include /* Execute a remote command send by Eeschema via a socket, * port KICAD_PCB_PORT_SERVICE_NUMBER @@ -416,8 +418,33 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) netlist.Format( "pcb_netlist", &sf, 0, CTL_OMIT_FILTERS ); payload = sf.GetString(); - break; } + break; + + case MAIL_PCB_UPDATE_LINKS: + try + { + NETLIST netlist; + FetchNetlistFromSchematic( netlist, NO_ANNOTATION ); + + BOARD_NETLIST_UPDATER updater( this, GetBoard() ); + updater.SetLookupByTimestamp( false ); + updater.SetDeleteUnusedComponents ( false ); + updater.SetReplaceFootprints( false ); + updater.SetDeleteSinglePadNets( false ); + updater.SetWarnPadNoNetInNetlist( false ); + updater.UpdateNetlist( netlist ); + + bool dummy; + OnNetlistChanged( updater, &dummy ); + } + catch( const IO_ERROR& ) + { + assert( false ); // should never happen + return; + } + break; + case MAIL_CROSS_PROBE: ExecuteRemoteCommand( payload.c_str() ); break; @@ -448,9 +475,8 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) if( importFormat >= 0 ) importFile( path, importFormat ); - - break; } + break; // many many others. default: