21#include <magic_enum.hpp>
70#include <api/common/types/base_types.pb.h>
78#include <wx/filename.h>
80using namespace kiapi::common::commands;
81using types::CommandStatus;
82using types::DocumentType;
83using types::ItemRequestStatus;
170 if( aCtx.
Request.type() != DocumentType::DOCTYPE_PCB )
174 e.set_status( ApiStatusCode::AS_UNHANDLED );
175 return tl::unexpected( e );
178 GetOpenDocumentsResponse response;
179 common::types::DocumentSpecifier doc;
181 wxFileName fn(
pcbContext()->GetCurrentFileName() );
183 doc.set_type( DocumentType::DOCTYPE_PCB );
184 doc.set_board_filename( fn.GetFullName() );
186 doc.mutable_project()->set_name(
project().GetProjectName().ToStdString() );
187 doc.mutable_project()->set_path(
project().GetProjectDirectory().ToStdString() );
189 response.mutable_documents()->Add( std::move( doc ) );
197 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
198 return tl::unexpected( *busy );
202 if( !documentValidation )
203 return tl::unexpected( documentValidation.error() );
213 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
214 return tl::unexpected( *busy );
218 if( !documentValidation )
219 return tl::unexpected( documentValidation.error() );
221 wxFileName boardPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.path() ) ) );
223 if( !boardPath.IsOk() || !boardPath.IsDirWritable() )
226 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
227 e.set_error_message( fmt::format(
"save path '{}' could not be opened",
228 boardPath.GetFullPath().ToStdString() ) );
229 return tl::unexpected( e );
232 if( boardPath.FileExists()
233 && ( !boardPath.IsFileWritable() || !aCtx.
Request.options().overwrite() ) )
236 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
237 e.set_error_message( fmt::format(
"save path '{}' exists and cannot be overwritten",
238 boardPath.GetFullPath().ToStdString() ) );
239 return tl::unexpected( e );
245 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
246 e.set_error_message( fmt::format(
"save path '{}' must have a kicad_pcb extension",
247 boardPath.GetFullPath().ToStdString() ) );
248 return tl::unexpected( e );
253 if( board->
GetFileName().Matches( boardPath.GetFullPath() ) )
259 bool includeProject =
true;
261 if( aCtx.
Request.has_options() )
262 includeProject = aCtx.
Request.options().include_project();
273 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"RevertDocument" ) )
274 return tl::unexpected( *headless );
276 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
277 return tl::unexpected( *busy );
281 if( !documentValidation )
282 return tl::unexpected( documentValidation.error() );
296 if( aDocument.type() != DocumentType::DOCTYPE_PCB )
299 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
300 e.set_error_message(
"the requested document is not a board" );
301 return tl::unexpected( e );
304 wxFileName fn(
pcbContext()->GetCurrentFileName() );
306 if( aDocument.board_filename().compare( fn.GetFullName() ) != 0 )
309 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
310 e.set_error_message( fmt::format(
"the requested document {} is not open",
311 aDocument.board_filename() ) );
312 return tl::unexpected( e );
321 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
322 return tl::unexpected( *busy );
328 e.set_status( ApiStatusCode::AS_UNHANDLED );
329 return tl::unexpected( e );
332 GetItemsResponse response;
335 std::vector<BOARD_ITEM*> items;
336 std::set<KICAD_T> typesRequested, typesInserted;
337 bool handledAnything =
false;
341 typesRequested.emplace( type );
343 if( typesInserted.count( type ) )
351 handledAnything =
true;
352 std::copy(
board->Tracks().begin(),
board->Tracks().end(),
353 std::back_inserter( items ) );
359 handledAnything =
true;
363 std::copy( fp->Pads().begin(), fp->Pads().end(),
364 std::back_inserter( items ) );
373 handledAnything =
true;
375 std::copy(
board->Footprints().begin(),
board->Footprints().end(),
376 std::back_inserter( items ) );
388 handledAnything =
true;
389 bool inserted =
false;
393 if( item->Type() == type )
395 items.emplace_back( item );
401 typesInserted.insert( type );
408 handledAnything =
true;
409 bool inserted =
false;
413 switch (item->Type()) {
419 items.emplace_back( item );
437 handledAnything =
true;
439 std::copy(
board->Zones().begin(),
board->Zones().end(),
440 std::back_inserter( items ) );
448 handledAnything =
true;
450 std::copy(
board->Groups().begin(),
board->Groups().end(),
451 std::back_inserter( items ) );
461 if( !handledAnything )
464 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
465 e.set_error_message(
"none of the requested types are valid for a Board object" );
466 return tl::unexpected( e );
471 if( !typesRequested.count( item->Type() ) )
474 google::protobuf::Any itemBuf;
475 item->Serialize( itemBuf );
476 response.mutable_items()->Add( std::move( itemBuf ) );
479 response.set_status( ItemRequestStatus::IRS_OK );
489 if( !documentValidation )
490 return tl::unexpected( documentValidation.error() );
492 if( aCtx.
Request.copper_layer_count() % 2 != 0 )
495 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
496 e.set_error_message(
"copper_layer_count must be an even number" );
497 return tl::unexpected( e );
503 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
504 e.set_error_message( fmt::format(
"copper_layer_count must be below %d",
MAX_CU_LAYERS ) );
505 return tl::unexpected( e );
508 int copperLayerCount =
static_cast<int>( aCtx.
Request.copper_layer_count() );
513 enabled &=
~LSET::AllCuMask();
518 LSET previousEnabled =
board->GetEnabledLayers();
519 LSET changedLayers = enabled ^ previousEnabled;
521 board->SetEnabledLayers( enabled );
522 board->SetVisibleLayers(
board->GetVisibleLayers() | changedLayers );
528 if( !enabled[layer_id] &&
board->HasItemsOnLayer( layer_id ) )
529 removedLayers.push_back( layer_id );
532 bool modified =
false;
534 if( !removedLayers.empty() )
539 modified |=
board->RemoveAllItemsOnLayer( layer_id );
542 if( enabled != previousEnabled )
548 BoardEnabledLayersResponse response;
550 response.set_copper_layer_count( copperLayerCount );
562 if( !documentValidation )
563 return tl::unexpected( documentValidation.error() );
566 BoardDesignRulesResponse response;
567 kiapi::board::BoardDesignRules* rules = response.mutable_rules();
569 kiapi::board::MinimumConstraints* constraints = rules->mutable_constraints();
571 constraints->mutable_min_clearance()->set_value_nm( bds.
m_MinClearance );
572 constraints->mutable_min_groove_width()->set_value_nm( bds.
m_MinGrooveWidth );
573 constraints->mutable_min_connection_width()->set_value_nm( bds.
m_MinConn );
574 constraints->mutable_min_track_width()->set_value_nm( bds.
m_TrackMinWidth );
576 constraints->mutable_min_via_size()->set_value_nm( bds.
m_ViasMinSize );
581 constraints->mutable_hole_clearance()->set_value_nm( bds.
m_HoleClearance );
582 constraints->mutable_hole_to_hole_min()->set_value_nm( bds.
m_HoleToHoleMin );
583 constraints->mutable_silk_clearance()->set_value_nm( bds.
m_SilkClearance );
588 kiapi::board::PredefinedSizes* sizes = rules->mutable_predefined_sizes();
591 sizes->add_tracks()->mutable_width()->set_value_nm( bds.
m_TrackWidthList[ii] );
595 kiapi::board::PresetViaDimension*
via = sizes->add_vias();
602 kiapi::board::PresetDiffPairDimension* pair = sizes->add_diff_pairs();
608 kiapi::board::SolderMaskPasteDefaults* maskPaste = rules->mutable_solder_mask_paste();
617 kiapi::board::TeardropDefaults* teardrops = rules->mutable_teardrops();
630 kiapi::board::TeardropTargetEntry* entry = teardrops->add_target_params();
634 entry->mutable_params()->set_enabled( params->
m_Enabled );
635 entry->mutable_params()->mutable_max_length()->set_value_nm( params->
m_TdMaxLen );
636 entry->mutable_params()->mutable_max_width()->set_value_nm( params->
m_TdMaxWidth );
640 entry->mutable_params()->set_curved_edges( params->
m_CurvedEdges );
645 kiapi::board::ViaProtectionDefaults* viaProtection = rules->mutable_via_protection();
658 board::DrcSeveritySetting* setting = rules->add_severities();
659 setting->set_rule_type(
666 kiapi::board::DrcExclusion* exclusion = rules->add_exclusions();
667 exclusion->mutable_marker()->mutable_id()->set_opaque_id( serialized.ToStdString() );
672 exclusion->set_comment( it->second.ToStdString() );
675 response.set_custom_rules_status( CRS_NONE );
681 if( !rulesPath.IsEmpty() && wxFileName::IsFileReadable( rulesPath ) )
683 wxFFile file( rulesPath,
"r" );
685 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
687 if( !file.IsOpened() )
689 response.set_custom_rules_status( CRS_INVALID );
693 file.ReadAll( &content );
699 parser.
Parse( parsedRules,
nullptr );
700 response.set_custom_rules_status( CRS_VALID );
704 response.set_custom_rules_status( CRS_INVALID );
717 if( !documentValidation )
718 return tl::unexpected( documentValidation.error() );
721 const kiapi::board::BoardDesignRules& rules = aCtx.
Request.rules();
723 if( rules.has_constraints() )
725 const kiapi::board::MinimumConstraints& constraints = rules.constraints();
727 newSettings.
m_MinClearance = constraints.min_clearance().value_nm();
729 newSettings.
m_MinConn = constraints.min_connection_width().value_nm();
730 newSettings.
m_TrackMinWidth = constraints.min_track_width().value_nm();
732 newSettings.
m_ViasMinSize = constraints.min_via_size().value_nm();
738 newSettings.
m_HoleToHoleMin = constraints.hole_to_hole_min().value_nm();
745 if( rules.has_predefined_sizes() )
750 for(
const kiapi::board::PresetTrackWidth& track : rules.predefined_sizes().tracks() )
756 for(
const kiapi::board::PresetViaDimension&
via : rules.predefined_sizes().vias() )
759 static_cast<int>(
via.drill().value_nm() ) );
765 for(
const kiapi::board::PresetDiffPairDimension& pair : rules.predefined_sizes().diff_pairs() )
768 static_cast<int>( pair.width().value_nm() ),
769 static_cast<int>( pair.gap().value_nm() ),
770 static_cast<int>( pair.via_gap().value_nm() ) );
774 if( rules.has_solder_mask_paste() )
776 const kiapi::board::SolderMaskPasteDefaults& maskPaste = rules.solder_mask_paste();
784 maskPaste.allow_soldermask_bridges_in_footprints();
787 if( rules.has_teardrops() )
789 const kiapi::board::TeardropDefaults& teardrops = rules.teardrops();
797 for(
const kiapi::board::TeardropTargetEntry& entry : teardrops.target_params() )
799 if( entry.target() == kiapi::board::TeardropTarget::TDT_UNKNOWN )
807 params->
m_Enabled = entry.params().enabled();
808 params->
m_TdMaxLen = entry.params().max_length().value_nm();
809 params->
m_TdMaxWidth = entry.params().max_width().value_nm();
819 if( rules.has_via_protection() )
821 const kiapi::board::ViaProtectionDefaults& viaProtection = rules.via_protection();
829 newSettings.
m_CapVias = viaProtection.cap();
830 newSettings.
m_FillVias = viaProtection.fill();
833 if( rules.severities_size() > 0 )
837 for(
const kiapi::board::DrcSeveritySetting& severitySetting : rules.severities() )
845 if( !permitted.contains( setting ) )
848 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
849 e.set_error_message( fmt::format(
"DRC severity must be error, warning, or ignore" ) );
850 return tl::unexpected( e );
857 if( rules.exclusions_size() > 0 )
862 for(
const kiapi::board::DrcExclusion& exclusion : rules.exclusions() )
864 wxString serialized = wxString::FromUTF8( exclusion.marker().id().opaque_id() );
866 if( serialized.IsEmpty() )
869 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
870 e.set_error_message(
"DrcExclusion marker id must not be empty" );
871 return tl::unexpected( e );
879 std::vector<BOARD_DESIGN_SETTINGS::VALIDATION_ERROR> errors = newSettings.
ValidateDesignRules();
881 if( !errors.empty() )
886 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
887 e.set_error_message( fmt::format(
"Invalid board design rules: {}: {}",
890 return tl::unexpected( e );
913 if( !documentValidation )
914 return tl::unexpected( documentValidation.error() );
916 CustomRulesResponse response;
917 response.set_status( CRS_NONE );
923 if( rulesPath.IsEmpty() || !wxFileName::IsFileReadable( rulesPath ) )
926 wxFFile file( rulesPath,
"r" );
928 if( !file.IsOpened() )
930 response.set_status( CRS_INVALID );
931 response.set_error_text(
"Failed to open custom rules file" );
936 file.ReadAll( &content );
939 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
944 parser.
Parse( parsedRules,
nullptr );
948 response.set_status( CRS_INVALID );
949 response.set_error_text( ioe.
What().ToStdString() );
953 for(
const std::shared_ptr<DRC_RULE>& rule : parsedRules )
960 kiapi::board::CustomRule* customRule = response.add_rules();
962 if( rule->m_Condition )
963 customRule->set_condition( rule->m_Condition->GetExpression().ToUTF8() );
967 board::CustomRuleConstraint* constraintProto = customRule->add_constraints();
968 constraint.
ToProto( *constraintProto );
972 customRule->set_name( rule->m_Name.ToUTF8() );
974 if( rule->m_LayerSource.CmpNoCase( wxS(
"outer" ) ) == 0 )
976 customRule->set_layer_mode( kiapi::board::CRLM_OUTER );
978 else if( rule->m_LayerSource.CmpNoCase( wxS(
"inner" ) ) == 0 )
980 customRule->set_layer_mode( kiapi::board::CRLM_INNER );
982 else if( !rule->m_LayerSource.IsEmpty() )
988 customRule->set_single_layer(
993 if( !comment.IsEmpty() )
994 customRule->set_comments( comment );
997 response.set_status( CRS_VALID );
1007 if( !documentValidation )
1008 return tl::unexpected( documentValidation.error() );
1014 if( aCtx.
Request.rules_size() == 0 )
1016 if( wxFileName::FileExists( rulesPath ) )
1018 if( !wxRemoveFile( rulesPath ) )
1020 CustomRulesResponse response;
1021 response.set_status( CRS_INVALID );
1022 response.set_error_text(
"Failed to remove custom rules file" );
1027 CustomRulesResponse response;
1028 response.set_status( CRS_NONE );
1033 rulesText <<
"(version 1)\n";
1035 for(
const board::CustomRule& rule : aCtx.
Request.rules() )
1037 wxString serializationError;
1040 if( serializedRule.IsEmpty() )
1042 CustomRulesResponse response;
1043 response.set_status( CRS_INVALID );
1045 if( serializationError.IsEmpty() )
1046 response.set_error_text(
"Failed to serialize custom rule" );
1048 response.set_error_text( serializationError.ToUTF8() );
1053 rulesText <<
"\n" << serializedRule;
1059 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
1061 parser.
Parse( parsedRules,
nullptr );
1065 CustomRulesResponse response;
1066 response.set_status( CRS_INVALID );
1067 response.set_error_text( ioe.
What().ToStdString() );
1071 wxFFile file( rulesPath,
"w" );
1073 if( !file.IsOpened() )
1075 CustomRulesResponse response;
1076 response.set_status( CRS_INVALID );
1077 response.set_error_text(
"Failed to open custom rules file for writing" );
1081 if( !file.Write( rulesText ) )
1085 CustomRulesResponse response;
1086 response.set_status( CRS_INVALID );
1087 response.set_error_text(
"Failed to write custom rules file" );
1103 !documentValidation )
1105 return tl::unexpected( documentValidation.error() );
1124 ApiResponseStatus e;
1125 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1126 e.set_error_message(
"Unexpected origin type" );
1127 return tl::unexpected( e );
1131 types::Vector2 reply;
1139 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1140 return tl::unexpected( *busy );
1143 !documentValidation )
1145 return tl::unexpected( documentValidation.error() );
1156 frame()->CallAfter( [f, origin]()
1171 frame()->CallAfter( [f, origin]()
1183 ApiResponseStatus e;
1184 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1185 e.set_error_message(
"Unexpected origin type" );
1186 return tl::unexpected( e );
1198 !documentValidation )
1200 return tl::unexpected( documentValidation.error() );
1203 BoardLayerNameResponse response;
1207 response.set_name(
board()->GetLayerName(
id ) );
1262 if( !documentValidation )
1263 return tl::unexpected( documentValidation.error() );
1265 NetsResponse response;
1268 std::set<wxString> netclassFilter;
1270 for(
const std::string& nc : aCtx.
Request.netclass_filter() )
1271 netclassFilter.insert( wxString( nc.c_str(), wxConvUTF8 ) );
1277 if( !netclassFilter.empty() && nc )
1279 bool inClass =
false;
1281 for(
const wxString&
filter : netclassFilter )
1294 board::types::Net* netProto = response.add_nets();
1295 netProto->set_name( net->GetNetname() );
1296 netProto->mutable_code()->set_value( net->GetNetCode() );
1306 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1307 return tl::unexpected( *busy );
1311 ApiResponseStatus e;
1312 e.set_status( ApiStatusCode::AS_UNHANDLED );
1313 return tl::unexpected( e );
1317 const bool filterByType = aCtx.
Request.types_size() > 0;
1319 if( filterByType && types.empty() )
1321 ApiResponseStatus e;
1322 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1323 e.set_error_message(
"none of the requested types are valid for a Board object" );
1324 return tl::unexpected( e );
1327 std::set<KICAD_T> typeFilter( types.begin(), types.end() );
1328 std::vector<BOARD_CONNECTED_ITEM*> sourceItems;
1330 for(
const types::KIID&
id : aCtx.
Request.items() )
1332 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
1335 sourceItems.emplace_back( connected );
1339 if( sourceItems.empty() )
1341 ApiResponseStatus e;
1342 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1343 e.set_error_message(
"none of the requested IDs were found or valid connected items" );
1344 return tl::unexpected( e );
1347 GetItemsResponse response;
1349 std::set<KIID> insertedItems;
1355 if( filterByType && !typeFilter.contains( connected->Type() ) )
1358 if( !insertedItems.insert( connected->m_Uuid ).second )
1361 connected->Serialize( *response.add_items() );
1365 response.set_status( ItemRequestStatus::IRS_OK );
1373 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1374 return tl::unexpected( *busy );
1378 ApiResponseStatus e;
1379 e.set_status( ApiStatusCode::AS_UNHANDLED );
1380 return tl::unexpected( e );
1384 const bool filterByType = aCtx.
Request.types_size() > 0;
1386 if( filterByType && types.empty() )
1388 ApiResponseStatus e;
1389 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1390 e.set_error_message(
"none of the requested types are valid for a Board object" );
1391 return tl::unexpected( e );
1397 GetItemsResponse response;
1399 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
1400 std::set<KIID> insertedItems;
1404 for(
const board::types::Net& net : aCtx.
Request.nets() )
1413 if( !insertedItems.insert( item->m_Uuid ).second )
1416 item->Serialize( *response.add_items() );
1420 response.set_status( ItemRequestStatus::IRS_OK );
1428 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1429 return tl::unexpected( *busy );
1433 ApiResponseStatus e;
1434 e.set_status( ApiStatusCode::AS_UNHANDLED );
1435 return tl::unexpected( e );
1439 const bool filterByType = aCtx.
Request.types_size() > 0;
1441 if( filterByType && types.empty() )
1443 ApiResponseStatus e;
1444 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1445 e.set_error_message(
"none of the requested types are valid for a Board object" );
1446 return tl::unexpected( e );
1452 std::set<wxString> requestedClasses;
1454 for(
const std::string& netClass : aCtx.
Request.net_classes() )
1455 requestedClasses.insert( wxString( netClass.c_str(), wxConvUTF8 ) );
1457 GetItemsResponse response;
1459 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
1460 std::set<KIID> insertedItems;
1469 if( !requestedClasses.empty() )
1474 bool inClass =
false;
1476 for(
const wxString&
filter : requestedClasses )
1491 if( !insertedItems.insert( item->m_Uuid ).second )
1494 item->Serialize( *response.add_items() );
1498 response.set_status( ItemRequestStatus::IRS_OK );
1506 NetClassForNetsResponse response;
1510 google::protobuf::Any
any;
1512 for(
const board::types::Net& net : aCtx.
Request.net() )
1520 auto [pair, rc] = response.mutable_classes()->insert( { net.name(), {} } );
1521 any.UnpackTo( &pair->second );
1530 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1531 return tl::unexpected( *busy );
1535 if( !documentValidation )
1536 return tl::unexpected( documentValidation.error() );
1538 if( aCtx.
Request.zones().empty() )
1541 frame()->CallAfter( [mgr]()
1549 ApiResponseStatus e;
1550 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
1551 return tl::unexpected( e );
1561 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetBoardEditorAppearanceSettings" ) )
1562 return tl::unexpected( *headless );
1564 BoardEditorAppearanceSettings reply;
1572 reply.set_net_color_display(
1575 reply.set_board_flip(
frame()->GetCanvas()->GetView()->IsMirroredX()
1576 ? BoardFlipMode::BFM_FLIPPED_X
1577 : BoardFlipMode::BFM_NORMAL );
1591 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SetBoardEditorAppearanceSettings" ) )
1592 return tl::unexpected( *headless );
1594 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1595 return tl::unexpected( *busy );
1600 const BoardEditorAppearanceSettings& newSettings = aCtx.
Request.settings();
1607 bool flip = newSettings.board_flip() == BoardFlipMode::BFM_FLIPPED_X;
1629 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1630 return tl::unexpected( *busy );
1634 if( !documentValidation )
1635 return tl::unexpected( documentValidation.error() );
1643 drcItem->SetErrorMessage( wxString::FromUTF8( aCtx.
Request.message() ) );
1647 for(
const auto&
id : aCtx.
Request.items() )
1648 ids.emplace_back(
KIID(
id.value() ) );
1651 drcItem->SetItems( ids );
1653 const auto& pos = aCtx.
Request.position();
1654 VECTOR2I position(
static_cast<int>( pos.x_nm() ),
static_cast<int>( pos.y_nm() ) );
1659 commit->
Add( marker );
1660 commit->
Push( wxS(
"API injected DRC marker" ) );
1662 InjectDrcErrorResponse response;
1670 const std::string& aCommandName )
1672 if( aUnits == types::Units::U_INCH || aUnits == types::Units::U_MM
1673 || aUnits == types::Units::U_UNKNOWN )
1675 return std::nullopt;
1678 ApiResponseStatus e;
1679 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1680 e.set_error_message( fmt::format(
"{} supports only inch and mm units", aCommandName ) );
1685std::optional<ApiResponseStatus>
1687 const std::string& aCommandName )
1689 if( aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_UNKNOWN
1690 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_ALL_LAYERS_ONE_PAGE
1691 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_EACH_LAYER_OWN_FILE )
1693 return std::nullopt;
1696 ApiResponseStatus e;
1697 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1698 e.set_error_message( fmt::format(
"{} does not support EACH_LAYER_OWN_PAGE pagination mode",
1707 for(
int layer : aSettings.layers() )
1710 static_cast<board::types::BoardLayer
>( layer ) );
1714 ApiResponseStatus e;
1715 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1716 e.set_error_message(
"Board plot settings contain an invalid layer" );
1723 for(
int layer : aSettings.common_layers() )
1726 static_cast<board::types::BoardLayer
>( layer ) );
1730 ApiResponseStatus e;
1731 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1732 e.set_error_message(
"Board plot settings contain an invalid common layer" );
1739 aJob.
m_colorTheme = wxString::FromUTF8( aSettings.color_theme() );
1740 aJob.
m_drawingSheet = wxString::FromUTF8( aSettings.drawing_sheet() );
1741 aJob.
m_variant = wxString::FromUTF8( aSettings.variant() );
1743 aJob.
m_mirror = aSettings.mirror();
1746 aJob.
m_scale = aSettings.scale();
1754 aJob.
m_plotRefDes = aSettings.plot_reference_designators();
1764 return std::nullopt;
1770 types::RunJobResponse response;
1773 if( !aContext || !aContext->
GetKiway() )
1775 response.set_status( types::JobStatus::JS_ERROR );
1776 response.set_message(
"Internal error" );
1778 wxCHECK_MSG(
false, response,
"context missing valid kiway in ExecuteBoardJob?" );
1784 response.add_output_path(
output.m_outputPath.ToUTF8() );
1788 response.set_status( types::JobStatus::JS_SUCCESS );
1792 response.set_status( types::JobStatus::JS_ERROR );
1793 response.set_message( fmt::format(
"Board export job '{}' failed with exit code {}: {}",
1795 reporter.GetMessages().ToStdString() ) );
1803 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1804 return tl::unexpected( *busy );
1808 if( !documentValidation )
1809 return tl::unexpected( documentValidation.error() );
1862 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1863 return tl::unexpected( *busy );
1867 if( !documentValidation )
1868 return tl::unexpected( documentValidation.error() );
1910 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1911 return tl::unexpected( *busy );
1915 if( !documentValidation )
1916 return tl::unexpected( documentValidation.error() );
1923 return tl::unexpected( *err );
1928 if( std::optional<ApiResponseStatus> paginationError =
1930 "RunBoardJobExportSvg" ) )
1932 return tl::unexpected( *paginationError );
1944 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1945 return tl::unexpected( *busy );
1949 if( !documentValidation )
1950 return tl::unexpected( documentValidation.error() );
1957 return tl::unexpected( *err );
1962 if( std::optional<ApiResponseStatus> unitError =
1965 return tl::unexpected( *unitError );
1970 if( std::optional<ApiResponseStatus> paginationError =
1972 "RunBoardJobExportDxf" ) )
1974 return tl::unexpected( *paginationError );
1986 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1987 return tl::unexpected( *busy );
1991 if( !documentValidation )
1992 return tl::unexpected( documentValidation.error() );
1999 return tl::unexpected( *err );
2016 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2017 return tl::unexpected( *busy );
2021 if( !documentValidation )
2022 return tl::unexpected( documentValidation.error() );
2029 return tl::unexpected( *err );
2031 if( std::optional<ApiResponseStatus> paginationError =
2033 "RunBoardJobExportPs" ) )
2035 return tl::unexpected( *paginationError );
2053 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2054 return tl::unexpected( *busy );
2058 if( !documentValidation )
2059 return tl::unexpected( documentValidation.error() );
2061 if( aCtx.
Request.layers().empty() )
2063 ApiResponseStatus e;
2064 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2065 e.set_error_message(
"RunBoardJobExportGerbers requires at least one layer" );
2066 return tl::unexpected( e );
2073 for(
int layer : aCtx.
Request.layers() )
2077 static_cast<board::types::BoardLayer
>( layer ) );
2081 ApiResponseStatus e;
2082 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2083 e.set_error_message(
"RunBoardJobExportGerbers contains an invalid layer" );
2084 return tl::unexpected( e );
2097 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2098 return tl::unexpected( *busy );
2102 if( !documentValidation )
2103 return tl::unexpected( documentValidation.error() );
2111 if( std::optional<ApiResponseStatus> unitError =
2114 return tl::unexpected( *unitError );
2121 if( aCtx.
Request.has_excellon() )
2123 const ExcellonFormatOptions& excellonOptions = aCtx.
Request.excellon();
2125 if( excellonOptions.has_mirror_y() )
2128 if( excellonOptions.has_minimal_header() )
2131 if( excellonOptions.has_combine_pth_npth() )
2134 if( excellonOptions.has_route_oval_holes() )
2138 if( aCtx.
Request.map_format() != DrillMapFormat::DMF_UNKNOWN )
2146 if( aCtx.
Request.has_gerber_generate_tenting() )
2149 if( aCtx.
Request.report_format() != DrillReportFormat::DRF_UNKNOWN )
2153 if( aCtx.
Request.has_report_filename() )
2164 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2165 return tl::unexpected( *busy );
2169 if( !documentValidation )
2170 return tl::unexpected( documentValidation.error() );
2176 if( aCtx.
Request.has_use_drill_place_file_origin() )
2186 if( aCtx.
Request.has_include_board_edge_for_gerber() )
2193 if( std::optional<ApiResponseStatus> unitError =
2196 return tl::unexpected( *unitError );
2209 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2210 return tl::unexpected( *busy );
2214 if( !documentValidation )
2215 return tl::unexpected( documentValidation.error() );
2234 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2235 return tl::unexpected( *busy );
2239 if( !documentValidation )
2240 return tl::unexpected( documentValidation.error() );
2248 if( aCtx.
Request.has_precision() )
2253 job.
m_colMfgPn = wxString::FromUTF8( aCtx.
Request.manufacturer_part_number_column() );
2254 job.
m_colMfg = wxString::FromUTF8( aCtx.
Request.manufacturer_column() );
2255 job.
m_colDistPn = wxString::FromUTF8( aCtx.
Request.distributor_part_number_column() );
2259 if( std::optional<ApiResponseStatus> unitError =
2262 return tl::unexpected( *unitError );
2275 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2276 return tl::unexpected( *busy );
2280 if( !documentValidation )
2281 return tl::unexpected( documentValidation.error() );
2294 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2295 return tl::unexpected( *busy );
2299 if( !documentValidation )
2300 return tl::unexpected( documentValidation.error() );
2308 if( aCtx.
Request.has_precision() )
2311 if( std::optional<ApiResponseStatus> unitError =
2314 return tl::unexpected( *unitError );
2327 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2328 return tl::unexpected( *busy );
2332 if( !documentValidation )
2333 return tl::unexpected( documentValidation.error() );
2341 if( std::optional<ApiResponseStatus> unitError =
2344 return tl::unexpected( *unitError );
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
std::optional< ApiResponseStatus > ValidatePaginationModeForSingleOrPerFile(kiapi::board::jobs::BoardJobPaginationMode aMode, const std::string &aCommandName)
std::optional< ApiResponseStatus > ApplyBoardPlotSettings(const BoardPlotSettings &aSettings, JOB_EXPORT_PCB_PLOT &aJob)
std::optional< ApiResponseStatus > ValidateUnitsInchMm(types::Units aUnits, const std::string &aCommandName)
HANDLER_RESULT< types::RunJobResponse > ExecuteBoardJob(PCB_CONTEXT *aContext, JOB &aJob)
BASE_SCREEN class implementation.
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION gridSetOrigin
API_HANDLER_BOARD(std::shared_ptr< BOARD_CONTEXT > aContext, EDA_BASE_FRAME *aFrame=nullptr)
TOOL_MANAGER * toolManager() const
std::vector< KICAD_T > parseRequestedItemTypes(const google::protobuf::RepeatedField< int > &aTypes)
PROJECT & project() const
BOARD_CONTEXT * context() const
std::optional< ApiResponseStatus > checkForHeadless(const std::string &aCommandName) const
std::optional< BOARD_ITEM * > getItemById(const KIID &aId) const
HANDLER_RESULT< bool > validateDocument(const DocumentSpecifier &aDocument)
HANDLER_RESULT< types::PageSettings > handleSetPageSettings(const HANDLER_CONTEXT< commands::SetPageSettings > &aCtx)
HANDLER_RESULT< std::optional< KIID > > validateItemHeaderDocument(const kiapi::common::types::ItemHeader &aHeader)
If the header is valid, returns the item container.
HANDLER_RESULT< types::PageSettings > handleGetPageSettings(const HANDLER_CONTEXT< commands::GetPageSettings > &aCtx)
COMMIT * getCurrentCommit(const std::string &aClientName)
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
std::optional< TITLE_BLOCK * > getTitleBlock() override
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportPdf(const HANDLER_CONTEXT< RunBoardJobExportPdf > &aCtx)
HANDLER_RESULT< BoardDesignRulesResponse > handleSetBoardDesignRules(const HANDLER_CONTEXT< SetBoardDesignRules > &aCtx)
API_HANDLER_PCB(PCB_EDIT_FRAME *aFrame)
HANDLER_RESULT< commands::GetItemsResponse > handleGetConnectedItems(const HANDLER_CONTEXT< GetConnectedItems > &aCtx)
HANDLER_RESULT< types::Vector2 > handleGetBoardOrigin(const HANDLER_CONTEXT< GetBoardOrigin > &aCtx)
HANDLER_RESULT< commands::GetItemsResponse > handleGetItemsByNetClass(const HANDLER_CONTEXT< GetItemsByNetClass > &aCtx)
bool setPageSettings(const PAGE_INFO &aPageInfo) override
HANDLER_RESULT< NetClassForNetsResponse > handleGetNetClassForNets(const HANDLER_CONTEXT< GetNetClassForNets > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportIpcD356(const HANDLER_CONTEXT< RunBoardJobExportIpcD356 > &aCtx)
PCB_CONTEXT * pcbContext() const
HANDLER_RESULT< BoardDesignRulesResponse > handleGetBoardDesignRules(const HANDLER_CONTEXT< GetBoardDesignRules > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportGerbers(const HANDLER_CONTEXT< RunBoardJobExportGerbers > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportODB(const HANDLER_CONTEXT< RunBoardJobExportODB > &aCtx)
HANDLER_RESULT< Empty > handleSaveCopyOfDocument(const HANDLER_CONTEXT< commands::SaveCopyOfDocument > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExport3D(const HANDLER_CONTEXT< RunBoardJobExport3D > &aCtx)
void setDrawingSheetFileName(const wxString &aFileName) override
HANDLER_RESULT< commands::GetItemsResponse > handleGetItemsByNet(const HANDLER_CONTEXT< GetItemsByNet > &aCtx)
std::optional< PAGE_INFO > getPageSettings() override
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportIpc2581(const HANDLER_CONTEXT< RunBoardJobExportIpc2581 > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportPosition(const HANDLER_CONTEXT< RunBoardJobExportPosition > &aCtx)
HANDLER_RESULT< Empty > handleSetBoardOrigin(const HANDLER_CONTEXT< SetBoardOrigin > &aCtx)
HANDLER_RESULT< BoardLayerNameResponse > handleGetBoardLayerName(const HANDLER_CONTEXT< GetBoardLayerName > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportStats(const HANDLER_CONTEXT< RunBoardJobExportStats > &aCtx)
void onModified() override
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportPs(const HANDLER_CONTEXT< RunBoardJobExportPs > &aCtx)
HANDLER_RESULT< CustomRulesResponse > handleGetCustomDesignRules(const HANDLER_CONTEXT< GetCustomDesignRules > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportSvg(const HANDLER_CONTEXT< RunBoardJobExportSvg > &aCtx)
HANDLER_RESULT< commands::GetOpenDocumentsResponse > handleGetOpenDocuments(const HANDLER_CONTEXT< commands::GetOpenDocuments > &aCtx)
HANDLER_RESULT< BoardEditorAppearanceSettings > handleGetBoardEditorAppearanceSettings(const HANDLER_CONTEXT< GetBoardEditorAppearanceSettings > &aCtx)
HANDLER_RESULT< NetsResponse > handleGetNets(const HANDLER_CONTEXT< GetNets > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportDxf(const HANDLER_CONTEXT< RunBoardJobExportDxf > &aCtx)
HANDLER_RESULT< Empty > handleSaveDocument(const HANDLER_CONTEXT< commands::SaveDocument > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportDrill(const HANDLER_CONTEXT< RunBoardJobExportDrill > &aCtx)
HANDLER_RESULT< commands::GetItemsResponse > handleGetItems(const HANDLER_CONTEXT< commands::GetItems > &aCtx)
HANDLER_RESULT< InjectDrcErrorResponse > handleInjectDrcError(const HANDLER_CONTEXT< InjectDrcError > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportRender(const HANDLER_CONTEXT< RunBoardJobExportRender > &aCtx)
PCB_EDIT_FRAME * frame() const
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportGencad(const HANDLER_CONTEXT< RunBoardJobExportGencad > &aCtx)
HANDLER_RESULT< BoardEnabledLayersResponse > handleSetBoardEnabledLayers(const HANDLER_CONTEXT< SetBoardEnabledLayers > &aCtx)
HANDLER_RESULT< Empty > handleSetBoardEditorAppearanceSettings(const HANDLER_CONTEXT< SetBoardEditorAppearanceSettings > &aCtx)
tl::expected< bool, ApiResponseStatus > validateDocumentInternal(const DocumentSpecifier &aDocument) const override
HANDLER_RESULT< Empty > handleRefillZones(const HANDLER_CONTEXT< RefillZones > &aCtx)
HANDLER_RESULT< Empty > handleRevertDocument(const HANDLER_CONTEXT< commands::RevertDocument > &aCtx)
HANDLER_RESULT< CustomRulesResponse > handleSetCustomDesignRules(const HANDLER_CONTEXT< SetCustomDesignRules > &aCtx)
wxString getDrawingSheetFileName() override
void registerHandler(HANDLER_RESULT< ResponseType >(HandlerType::*aHandler)(const HANDLER_CONTEXT< RequestType > &))
Registers an API command handler for the given message types.
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
void SetContentModified(bool aModified=true)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual KIWAY * GetKiway() const =0
virtual BOARD * GetBoard() const =0
virtual PROJECT & Prj() const =0
Container for design settings for a BOARD object.
std::map< wxString, wxString > m_DrcExclusionComments
int m_CopperEdgeClearance
std::map< int, SEVERITY > m_DRCSeverities
int m_MinSilkTextThickness
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
std::set< wxString > m_DrcExclusions
int m_SolderMaskToCopperClearance
const VECTOR2I & GetGridOrigin() const
bool m_AllowSoldermaskBridgesInFPs
TEARDROP_PARAMETERS_LIST m_TeardropParamsList
The parameters of teardrops for the different teardrop targets (via/pad, track end).
const VECTOR2I & GetAuxOrigin() const
int m_SolderMaskExpansion
std::vector< int > m_TrackWidthList
std::vector< VALIDATION_ERROR > ValidateDesignRules(std::optional< EDA_UNITS > aUnits=std::nullopt) const
Validate design settings values and return per-field errors.
double m_SolderPasteMarginRatio
std::vector< VIA_DIMENSION > m_ViasDimensionsList
int m_ViasMinAnnularWidth
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Information pertinent to a Pcbnew printed circuit board.
const PAGE_INFO & GetPageSettings() const
void SetDesignSettings(const BOARD_DESIGN_SETTINGS &aSettings)
TITLE_BLOCK & GetTitleBlock()
void SetPageSettings(const PAGE_INFO &aPageSettings)
const wxString & GetFileName() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Represent a set of changes (additions, deletions or modifications) of a data model (e....
virtual void Push(const wxString &aMessage=wxT("A commit"), int aFlags=0)=0
Execute the changes.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
void ToProto(kiapi::board::CustomRuleConstraint &aProto) const
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
static wxString ExtractRuleComment(const wxString &aOriginalText)
Extract comment lines from a rule.
static wxString ExtractRuleText(const wxString &aContent, const wxString &aRuleName)
Extract the complete original text of a rule from file content.
static wxString FormatRuleFromProto(const kiapi::board::CustomRule &aRule, wxString *aErrorText=nullptr)
void ReleaseFile()
Release the current file marked in use.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
double m_BoardOutlinesChainingEpsilon
bool m_IncludeUnspecified
wxString m_ComponentFilter
bool m_UsePcbCenterOrigin
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
JOB_EXPORT_PCB_3D::FORMAT m_format
EXPORTER_STEP_PARAMS m_3dparams
Despite the name; also used for other formats.
ZEROS_FORMAT m_zeroFormat
bool m_excellonOvalDrillRoute
DRILL_ORIGIN m_drillOrigin
bool m_excellonCombinePTHNPTH
bool m_excellonMinimalHeader
bool m_plotGraphicItemsUsingContours
bool m_useIndividualShapes
IPC2581_VERSION m_version
ODB_COMPRESSION m_compressionMode
bool m_pdfFrontFPPropertyPopups
wxString m_pdfBackgroundColor
bool m_pdfSingle
This is a hack to deal with cli having the wrong behavior We will deprecate out the wrong behavior,...
bool m_pdfBackFPPropertyPopups
GEN_MODE m_pdfGenMode
The background color specified in a hex string.
bool m_sketchDNPFPsOnFabLayers
bool m_plotFootprintValues
LSEQ m_plotOnAllLayersSequence
Used by SVG & PDF.
bool m_checkZonesBeforePlot
bool m_sketchPadsOnFabLayers
DRILL_MARKS m_drillShapeOption
Used by SVG/DXF/PDF/Gerbers.
bool m_crossoutDNPFPsOnFabLayers
bool m_hideDNPFPsOnFabLayers
bool m_mirror
Common Options.
bool m_subtractSolderMaskFromSilk
LSEQ m_plotLayerSequence
Layers to include on all individual layer prints.
wxString m_variant
Variant name for variant-aware filtering.
bool m_useDrillPlaceFileOrigin
bool m_excludeFootprintsWithTh
double m_trackWidthCorrection
bool m_subtractHolesFromBoardArea
bool m_excludeFootprintsWithoutPads
bool m_subtractHolesFromCopperAreas
VECTOR3D m_lightBottomIntensity
VECTOR3D m_lightTopIntensity
VECTOR3D m_lightCameraIntensity
bool m_proceduralTextures
bool m_useBoardStackupColors
VECTOR3D m_lightSideIntensity
std::string m_appearancePreset
An simple container class that lets us dispatch output jobs to kifaces.
void SetConfiguredOutputPath(const wxString &aPath)
Sets the configured output path for the job, this path is always saved to file.
const std::vector< JOB_OUTPUT > & GetOutputs()
const std::string & GetType() const
void SetMirror(bool aMirrorX, bool aMirrorY)
Control the mirroring of the VIEW.
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
bool IsMirroredX() const
Return true if view is flipped across the X axis.
void RecacheAllItems()
Rebuild GAL display lists.
bool IsMirroredY() const
Return true if view is flipped across the Y axis.
std::string AsStdString() const
int ProcessJob(KIWAY::FACE_T aFace, JOB *aJob, REPORTER *aReporter=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
static int NameToLayer(wxString &aName)
Return the layer number from a layer name.
A collection of nets and the parameters used to route or test these nets.
bool ContainsNetclassWithName(const wxString &netclass) const
Determines if the given netclass name is a constituent of this (maybe aggregate) netclass.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Handle the data for a net.
Container for NETINFO_ITEM elements, which are the nets.
NETINFO_ITEM * GetNetItem(int aNetCode) const
Describe the page size and margins of a paper page on which to eventually print or plot.
DISPLAY_OPTIONS m_Display
static TOOL_ACTION zoneFillAll
static TOOL_ACTION drillSetOrigin
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
PCBNEW_SETTINGS * GetPcbNewSettings() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aRefresh=true)
Update the current display options.
PCB-editor-specific context; extends BOARD_CONTEXT with save/filename operations.
virtual bool SaveBoard()=0
virtual wxString GetCurrentFileName() const =0
virtual bool SavePcbCopy(const wxString &aFileName, bool aCreateProject, bool aHeadless)=0
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
NET_COLOR_MODE m_NetColorMode
How to use color overrides on specific nets and netclasses.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
The main frame for Pcbnew.
void LoadDrawingSheet()
Load the drawing sheet file.
void OnModify() override
Must be called after a board change to set the modified flag.
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Load a KiCad board (.kicad_pcb) from aFileName.
void UpdateUserInterface()
Update the layer manager and other widgets from the board setup (layer and items visibility,...
const KIID GetUUID() const override
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
std::vector< KIID > KIIDS
TEARDROP_PARAMETERS_LIST is a helper class to handle the list of TEARDROP_PARAMETERS needed to build ...
bool m_UseRoundShapesOnly
True to create teardrops for round shapes only.
bool m_TargetVias
True to create teardrops for vias.
bool m_TargetPTHPads
True to create teardrops for pads with holes.
bool m_TargetTrack2Track
True to create teardrops at the end of a track connected to the end of another track having a differe...
TEARDROP_PARAMETERS * GetParameters(TARGET_TD aTdType)
bool m_TargetSMDPads
True to create teardrops for pads SMD, edge connectors,.
TEARDROP_PARAMETARS is a helper class to handle parameters needed to build teardrops for a board thes...
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxLen
max allowed length for teardrops in IU. <= 0 to disable
bool m_AllowUseTwoTracks
True to create teardrops using 2 track segments if the first in too small.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_BestLengthRatio
The length of a teardrop as ratio between length and size of pad/via.
double m_WidthtoSizeFilterRatio
The ratio (H/D) between the via/pad size and the track width max value to create a teardrop 1....
bool m_TdOnPadsInZones
A filter to exclude pads inside zone fills.
bool m_Enabled
Flag to enable teardrops.
bool m_CurvedEdges
True if the teardrop should be curved.
A wrapper for reporting to a wxString object.
A type-safe container of any type.
static const std::string DesignRulesFileExtension
static const std::string KiCadPcbFileExtension
#define KICTL_REVERT
reverting to a previously-saved (KiCad) file.
@ LAYER_DRC_WARNING
Layer for DRC markers with #SEVERITY_WARNING.
@ LAYER_DRC_ERROR
Layer for DRC markers with #SEVERITY_ERROR.
PCB_LAYER_ID
A quick note on layer IDs:
void PackLayerSet(google::protobuf::RepeatedField< int > &aOutput, const LSET &aLayerSet)
LSET UnpackLayerSet(const google::protobuf::RepeatedField< int > &aProtoLayerSet)
KICOMMON_API VECTOR3D UnpackVector3D(const types::Vector3D &aInput)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
std::shared_ptr< PCB_CONTEXT > CreatePcbFrameContext(PCB_EDIT_FRAME *aFrame)
Class to handle a set of BOARD_ITEMs.
RequestMessageType Request
RATSNEST_MODE m_RatsnestMode
IbisParser parser & reporter
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D