diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index 2f2ac762b1..d39a51f1d7 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -283,6 +283,7 @@ void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event ) m_infoBar->Hide(); + m_parent->RecordERCExclusions(); deleteAllMarkers( true ); m_notebook->ChangeSelection( 0 ); // Display the "Tests Running..." tab @@ -418,6 +419,8 @@ void DIALOG_ERC::testErc() tester.TestLibSymbolIssues(); } + m_parent->ResolveERCExclusions(); + // Display diags: m_markerTreeModel->SetProvider( m_markerProvider ); diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index 397bd1cfd7..e0b887e6d4 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -285,6 +285,8 @@ void SCH_EDIT_FRAME::SaveProjectSettings() if( !fn.HasName() || !IsWritable( fn ) ) return; + RecordERCExclusions(); + GetSettingsManager()->SaveProject( fn.GetFullPath() ); } diff --git a/eeschema/erc_item.h b/eeschema/erc_item.h index f1434d9fd6..4a2862a13a 100644 --- a/eeschema/erc_item.h +++ b/eeschema/erc_item.h @@ -36,6 +36,17 @@ public: */ static std::shared_ptr Create( int aErrorCode ); + static std::shared_ptr Create( const wxString& aErrorKey ) + { + for( const RC_ITEM& item : allItemTypes ) + { + if( aErrorKey == item.GetSettingsKey() ) + return std::make_shared( static_cast( item ) ); + } + + return nullptr; + } + static std::vector> GetItemsWithSeverities() { return allItemTypes; diff --git a/eeschema/erc_settings.cpp b/eeschema/erc_settings.cpp index d606f8d1ce..f7a3b6b370 100644 --- a/eeschema/erc_settings.cpp +++ b/eeschema/erc_settings.cpp @@ -138,6 +138,33 @@ ERC_SETTINGS::ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : }, {} ) ); + m_params.emplace_back( new PARAM_LAMBDA( "erc_exclusions", + [&]() -> nlohmann::json + { + nlohmann::json js = nlohmann::json::array(); + + for( const auto& entry : m_ErcExclusions ) + js.push_back( entry ); + + return js; + }, + [&]( const nlohmann::json& aObj ) + { + m_ErcExclusions.clear(); + + if( !aObj.is_array() ) + return; + + for( const nlohmann::json& entry : aObj ) + { + if( entry.empty() ) + continue; + + m_ErcExclusions.insert( entry.get() ); + } + }, + {} ) ); + m_params.emplace_back( new PARAM_LAMBDA( "pin_map", [&]() -> nlohmann::json { diff --git a/eeschema/erc_settings.h b/eeschema/erc_settings.h index 24623d60ee..eb0270b697 100644 --- a/eeschema/erc_settings.h +++ b/eeschema/erc_settings.h @@ -155,6 +155,7 @@ public: public: std::map m_Severities; + std::set m_ErcExclusions; PIN_ERROR m_PinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL]; diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index cc10fca134..65b11debcd 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -696,6 +697,48 @@ void SCH_EDIT_FRAME::doCloseWindow() } +void SCH_EDIT_FRAME::RecordERCExclusions() +{ + SCH_SHEET_LIST sheetList = Schematic().GetSheets(); + ERC_SETTINGS& ercSettings = Schematic().ErcSettings(); + + ercSettings.m_ErcExclusions.clear(); + + for( unsigned i = 0; i < sheetList.size(); i++ ) + { + for( SCH_ITEM* item : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) ) + { + SCH_MARKER* marker = static_cast( item ); + + if( marker->IsExcluded() ) + ercSettings.m_ErcExclusions.insert( marker->Serialize() ); + } + } +} + + +void SCH_EDIT_FRAME::ResolveERCExclusions() +{ + for( SCH_MARKER* marker : Schematic().ResolveERCExclusions() ) + { + // JEY TODO: need to get the right screen.... + GetScreen()->Append( marker ); + } + + // Update the view for the current screen + for( SCH_ITEM* item : GetScreen()->Items().OfType( SCH_MARKER_T ) ) + { + SCH_MARKER* marker = static_cast( item ); + + if( marker->IsExcluded() ) + { + GetCanvas()->GetView()->Remove( marker ); + GetCanvas()->GetView()->Add( marker ); + } + } +} + + wxString SCH_EDIT_FRAME::GetUniqueFilenameForCurrentSheet() { // Filename is rootSheetName-sheetName-...-sheetName diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 030cd5dc3a..e14f08ba47 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -206,6 +206,16 @@ public: */ void OnModify() override; + /** + * Scan existing markers and record data from any that are Excluded. + */ + void RecordERCExclusions(); + + /** + * Update markers to match recorded exclusions. + */ + void ResolveERCExclusions(); + /** * Return a human-readable description of the current screen. */ diff --git a/eeschema/sch_marker.cpp b/eeschema/sch_marker.cpp index 8173e19d38..6af6a66e79 100644 --- a/eeschema/sch_marker.cpp +++ b/eeschema/sch_marker.cpp @@ -63,6 +63,34 @@ void SCH_MARKER::SwapData( SCH_ITEM* aItem ) } +wxString SCH_MARKER::Serialize() const +{ + return wxString::Format( wxT( "%s|%d|%d|%s|%s" ), + m_rcItem->GetSettingsKey(), + m_Pos.x, + m_Pos.y, + m_rcItem->GetMainItemID().AsString(), + m_rcItem->GetAuxItemID().AsString() ); +} + + +SCH_MARKER* SCH_MARKER::Deserialize( const wxString& data ) +{ + wxArrayString props = wxSplit( data, '|' ); + wxPoint markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ), + (int) strtol( props[2].c_str(), nullptr, 10 ) ); + + std::shared_ptr ercItem = ERC_ITEM::Create( props[0] ); + + if( !ercItem ) + return nullptr; + + ercItem->SetItems( KIID( props[3] ), KIID( props[4] ) ); + + return new SCH_MARKER( ercItem, markerPos ); +} + + #if defined(DEBUG) void SCH_MARKER::Show( int nestLevel, std::ostream& os ) const diff --git a/eeschema/sch_marker.h b/eeschema/sch_marker.h index 95c99c5c2d..4fe64249c8 100644 --- a/eeschema/sch_marker.h +++ b/eeschema/sch_marker.h @@ -51,6 +51,9 @@ public: void SwapData( SCH_ITEM* aItem ) override; + wxString Serialize() const; + static SCH_MARKER* Deserialize( const wxString& data ); + void ViewGetLayers( int aLayers[], int& aCount ) const override; SCH_LAYER_ID GetColorLayer() const; diff --git a/eeschema/schematic.cpp b/eeschema/schematic.cpp index 1540aa3828..f4e86d5d91 100644 --- a/eeschema/schematic.cpp +++ b/eeschema/schematic.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -135,6 +136,45 @@ ERC_SETTINGS& SCHEMATIC::ErcSettings() const } +std::vector SCHEMATIC::ResolveERCExclusions() +{ + SCH_SHEET_LIST sheetList = GetSheets(); + ERC_SETTINGS& settings = ErcSettings(); + + for( const SCH_SHEET_PATH& sheet : sheetList ) + { + for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_MARKER_T ) ) + { + SCH_MARKER* marker = static_cast( item ); + auto it = ErcSettings().m_ErcExclusions.find( marker->Serialize() ); + + if( it != ErcSettings().m_ErcExclusions.end() ) + { + marker->SetExcluded( true ); + settings.m_ErcExclusions.erase( it ); + } + } + } + + std::vector newMarkers; + + for( const wxString& exclusionData : settings.m_ErcExclusions ) + { + SCH_MARKER* marker = SCH_MARKER::Deserialize( exclusionData ); + + if( marker ) + { + marker->SetExcluded( true ); + newMarkers.push_back( marker ); + } + } + + settings.m_ErcExclusions.clear(); + + return newMarkers; +} + + std::shared_ptr SCHEMATIC::GetBusAlias( const wxString& aLabel ) const { for( const auto& sheet : GetSheets() ) diff --git a/eeschema/schematic.h b/eeschema/schematic.h index 5528c4d784..ddbf5ef3fe 100644 --- a/eeschema/schematic.h +++ b/eeschema/schematic.h @@ -143,6 +143,8 @@ public: ERC_SETTINGS& ErcSettings() const; + std::vector ResolveERCExclusions(); + /** * Returns a pointer to a bus alias object for the given label, or null if one * doesn't exist.