diff --git a/api/proto/board/board_commands.proto b/api/proto/board/board_commands.proto index a24a787fcf..bb0dc75664 100644 --- a/api/proto/board/board_commands.proto +++ b/api/proto/board/board_commands.proto @@ -258,6 +258,34 @@ message PadstackPresenceResponse repeated PadstackPresenceEntry entries = 1; } +// DRC markers + +enum DrcSeverity // Since 10.0 +{ + DRS_UNKNOWN = 0; + DRS_WARNING = 1; + DRS_ERROR = 2; +} + +// Returns InjectDrcErrorResponse +message InjectDrcError +{ + kiapi.common.types.DocumentSpecifier board = 1; + + DrcSeverity severity = 2; + + string message = 3; + + kiapi.common.types.Vector2 position = 4; + + repeated kiapi.common.types.KIID items = 5; +} + +message InjectDrcErrorResponse +{ + kiapi.common.types.KIID marker = 1; +} + // PCB editor commands // returns BoardLayers diff --git a/pcbnew/api/api_handler_pcb.cpp b/pcbnew/api/api_handler_pcb.cpp index 584ebb9789..998f28828f 100644 --- a/pcbnew/api/api_handler_pcb.cpp +++ b/pcbnew/api/api_handler_pcb.cpp @@ -38,6 +38,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -46,6 +49,7 @@ #include #include +#include using namespace kiapi::common::commands; using types::CommandStatus; @@ -112,6 +116,8 @@ API_HANDLER_PCB::API_HANDLER_PCB( PCB_EDIT_FRAME* aFrame ) : &API_HANDLER_PCB::handleGetBoardEditorAppearanceSettings ); registerHandler( &API_HANDLER_PCB::handleSetBoardEditorAppearanceSettings ); + registerHandler( + &API_HANDLER_PCB::handleInjectDrcError ); } @@ -1687,3 +1693,46 @@ HANDLER_RESULT API_HANDLER_PCB::handleSetBoardEditorAppearanceSettings( return Empty(); } + + +HANDLER_RESULT API_HANDLER_PCB::handleInjectDrcError( + const HANDLER_CONTEXT& aCtx ) +{ + if( std::optional busy = checkForBusy() ) + return tl::unexpected( *busy ); + + HANDLER_RESULT documentValidation = validateDocument( aCtx.Request.board() ); + + if( !documentValidation ) + return tl::unexpected( documentValidation.error() ); + + SEVERITY severity = FromProtoEnum( aCtx.Request.severity() ); + int layer = severity == RPT_SEVERITY_WARNING ? LAYER_DRC_WARNING : LAYER_DRC_ERROR; + int code = severity == RPT_SEVERITY_WARNING ? DRCE_GENERIC_WARNING : DRCE_GENERIC_ERROR; + + std::shared_ptr drcItem = DRC_ITEM::Create( code ); + + drcItem->SetErrorMessage( wxString::FromUTF8( aCtx.Request.message() ) ); + + RC_ITEM::KIIDS ids; + + for( const auto& id : aCtx.Request.items() ) + ids.emplace_back( KIID( id.value() ) ); + + if( !ids.empty() ) + drcItem->SetItems( ids ); + + const auto& pos = aCtx.Request.position(); + VECTOR2I position( static_cast( pos.x_nm() ), static_cast( pos.y_nm() ) ); + + PCB_MARKER* marker = new PCB_MARKER( drcItem, position, layer ); + + COMMIT* commit = getCurrentCommit( aCtx.ClientName ); + commit->Add( marker ); + commit->Push( wxS( "API injected DRC marker" ) ); + + InjectDrcErrorResponse response; + response.mutable_marker()->set_value( marker->GetUUID().AsStdString() ); + + return response; +} diff --git a/pcbnew/api/api_handler_pcb.h b/pcbnew/api/api_handler_pcb.h index 4f2c5cbd0e..7f568ca566 100644 --- a/pcbnew/api/api_handler_pcb.h +++ b/pcbnew/api/api_handler_pcb.h @@ -151,6 +151,9 @@ private: HANDLER_RESULT handleSetBoardEditorAppearanceSettings( const HANDLER_CONTEXT& aCtx ); + HANDLER_RESULT handleInjectDrcError( + const HANDLER_CONTEXT& aCtx ); + protected: std::unique_ptr createCommit() override; diff --git a/pcbnew/api/api_pcb_enums.cpp b/pcbnew/api/api_pcb_enums.cpp index 1c87dee508..4e7b6addc5 100644 --- a/pcbnew/api/api_pcb_enums.cpp +++ b/pcbnew/api/api_pcb_enums.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ // Adding something new here? Add it to test_api_enums.cpp! using namespace kiapi::board; +using namespace kiapi::board::commands; template<> types::PadType ToProtoEnum( PAD_ATTRIB aValue ) @@ -826,4 +828,31 @@ BOARD_STACKUP_ITEM_TYPE FromProtoEnum( BoardStackupLayerType aValue ) } } + +template<> +DrcSeverity ToProtoEnum( SEVERITY aValue ) +{ + switch( aValue ) + { + case RPT_SEVERITY_WARNING: return DrcSeverity::DRS_WARNING; + case RPT_SEVERITY_ERROR: return DrcSeverity::DRS_ERROR; + + default: + return DrcSeverity::DRS_UNKNOWN; + } +} + + +template<> +SEVERITY FromProtoEnum( DrcSeverity aValue ) +{ + switch( aValue ) + { + case DrcSeverity::DRS_WARNING: return RPT_SEVERITY_WARNING; + case DrcSeverity::DRS_ERROR: return RPT_SEVERITY_ERROR; + case DrcSeverity::DRS_UNKNOWN: + default: return RPT_SEVERITY_ERROR; + } +} + // Adding something new here? Add it to test_api_enums.cpp! diff --git a/qa/tests/api/test_api_enums.cpp b/qa/tests/api/test_api_enums.cpp index 7833e9cdda..c90b8f6b96 100644 --- a/qa/tests/api/test_api_enums.cpp +++ b/qa/tests/api/test_api_enums.cpp @@ -30,6 +30,7 @@ #include #include #include +#include // Board-specific #include @@ -267,4 +268,9 @@ BOOST_AUTO_TEST_CASE( BoardStackupLayerType ) testEnums(); } +BOOST_AUTO_TEST_CASE( DrcSeverity ) +{ + testEnums( true ); +} + BOOST_AUTO_TEST_SUITE_END()