21#include <magic_enum.hpp>
71#include <api/common/types/base_types.pb.h>
79#include <wx/filename.h>
81using namespace kiapi::common::commands;
82using types::CommandStatus;
83using types::DocumentType;
84using types::ItemRequestStatus;
210 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
211 e.set_error_message( fmt::format(
"{} is not available in headless mode", aCommandName ) );
219 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"RunAction" ) )
220 return tl::unexpected( *headless );
222 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
223 return tl::unexpected( *busy );
225 RunActionResponse response;
228 response.set_status( RunActionStatus::RAS_OK );
230 response.set_status( RunActionStatus::RAS_INVALID );
239 if( aCtx.
Request.type() != DocumentType::DOCTYPE_PCB )
243 e.set_status( ApiStatusCode::AS_UNHANDLED );
244 return tl::unexpected( e );
247 GetOpenDocumentsResponse response;
248 common::types::DocumentSpecifier doc;
250 wxFileName fn(
context()->GetCurrentFileName() );
252 doc.set_type( DocumentType::DOCTYPE_PCB );
253 doc.set_board_filename( fn.GetFullName() );
255 doc.mutable_project()->set_name(
project().GetProjectName().ToStdString() );
256 doc.mutable_project()->set_path(
project().GetProjectDirectory().ToStdString() );
258 response.mutable_documents()->Add( std::move( doc ) );
266 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
267 return tl::unexpected( *busy );
271 if( !documentValidation )
272 return tl::unexpected( documentValidation.error() );
282 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
283 return tl::unexpected( *busy );
287 if( !documentValidation )
288 return tl::unexpected( documentValidation.error() );
290 wxFileName boardPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.path() ) ) );
292 if( !boardPath.IsOk() || !boardPath.IsDirWritable() )
295 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
296 e.set_error_message( fmt::format(
"save path '{}' could not be opened",
297 boardPath.GetFullPath().ToStdString() ) );
298 return tl::unexpected( e );
301 if( boardPath.FileExists()
302 && ( !boardPath.IsFileWritable() || !aCtx.
Request.options().overwrite() ) )
305 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
306 e.set_error_message( fmt::format(
"save path '{}' exists and cannot be overwritten",
307 boardPath.GetFullPath().ToStdString() ) );
308 return tl::unexpected( e );
314 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
315 e.set_error_message( fmt::format(
"save path '{}' must have a kicad_pcb extension",
316 boardPath.GetFullPath().ToStdString() ) );
317 return tl::unexpected( e );
322 if( board->
GetFileName().Matches( boardPath.GetFullPath() ) )
328 bool includeProject =
true;
330 if( aCtx.
Request.has_options() )
331 includeProject = aCtx.
Request.options().include_project();
342 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"RevertDocument" ) )
343 return tl::unexpected( *headless );
345 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
346 return tl::unexpected( *busy );
350 if( !documentValidation )
351 return tl::unexpected( documentValidation.error() );
375 return std::make_unique<BOARD_COMMIT>(
frame() );
377 return std::make_unique<BOARD_COMMIT>(
toolManager(),
true,
false );
394 if( aDocument.type() != DocumentType::DOCTYPE_PCB )
397 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
398 e.set_error_message(
"the requested document is not a board" );
399 return tl::unexpected( e );
402 wxFileName fn(
context()->GetCurrentFileName() );
404 if( aDocument.board_filename().compare( fn.GetFullName() ) != 0 )
407 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
408 e.set_error_message( fmt::format(
"the requested document {} is not open",
409 aDocument.board_filename() ) );
410 return tl::unexpected( e );
423 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
424 e.set_error_message(
"Tried to create an item in a null container" );
425 return tl::unexpected( e );
431 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
432 e.set_error_message( fmt::format(
"Tried to create a pad in {}, which is not a footprint",
434 return tl::unexpected( e );
439 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
440 e.set_error_message( fmt::format(
"Tried to create a footprint in {}, which is not a board",
442 return tl::unexpected( e );
450 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
451 e.set_error_message( fmt::format(
"Tried to create an item of type {}, which is unhandled",
452 magic_enum::enum_name( aType ) ) );
453 return tl::unexpected( e );
461 const std::string& aClientName,
462 const types::ItemHeader &aHeader,
463 const google::protobuf::RepeatedPtrField<google::protobuf::Any>& aItems,
464 std::function<
void( ItemStatus, google::protobuf::Any )> aItemHandler )
470 if( !containerResult && containerResult.error().status() == ApiStatusCode::AS_UNHANDLED )
473 e.set_status( ApiStatusCode::AS_UNHANDLED );
474 return tl::unexpected( e );
476 else if( !containerResult )
478 e.CopyFrom( containerResult.error() );
479 return tl::unexpected( e );
485 if( containerResult->has_value() )
487 const KIID& containerId = **containerResult;
488 std::optional<BOARD_ITEM*> optItem =
getItemById( containerId );
496 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
497 e.set_error_message( fmt::format(
498 "The requested container {} is not a valid board item container",
500 return tl::unexpected( e );
505 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
506 e.set_error_message( fmt::format(
507 "The requested container {} does not exist in this document",
509 return tl::unexpected( e );
515 for(
const google::protobuf::Any& anyItem : aItems )
522 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
523 status.set_error_message( fmt::format(
"Could not decode a valid type from {}",
524 anyItem.type_url() ) );
525 aItemHandler( status, anyItem );
531 board::types::Dimension dimension;
532 anyItem.UnpackTo( &dimension );
534 switch( dimension.dimension_style_case() )
541 case board::types::Dimension::DIMENSION_STYLE_NOT_SET:
break;
548 if( !creationResult )
550 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
551 status.set_error_message( creationResult.error().error_message() );
552 aItemHandler( status, anyItem );
556 std::unique_ptr<BOARD_ITEM> item( std::move( *creationResult ) );
558 if( !item->Deserialize( anyItem ) )
560 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
561 e.set_error_message( fmt::format(
"could not unpack {} from request",
562 item->GetClass().ToStdString() ) );
563 return tl::unexpected( e );
566 std::optional<BOARD_ITEM*> optItem =
getItemById( item->m_Uuid );
568 if( aCreate && optItem )
570 status.set_code( ItemStatusCode::ISC_EXISTING );
571 status.set_error_message( fmt::format(
"an item with UUID {} already exists",
572 item->m_Uuid.AsStdString() ) );
573 aItemHandler( status, anyItem );
576 else if( !aCreate && !optItem )
578 status.set_code( ItemStatusCode::ISC_NONEXISTENT );
579 status.set_error_message( fmt::format(
"an item with UUID {} does not exist",
580 item->m_Uuid.AsStdString() ) );
581 aItemHandler( status, anyItem );
585 if( aCreate && !(
board->GetEnabledLayers() & item->GetLayerSet() ).any() )
587 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
588 status.set_error_message(
589 "attempted to add item with no overlapping layers with the board" );
590 aItemHandler( status, anyItem );
594 status.set_code( ItemStatusCode::ISC_OK );
595 google::protobuf::Any newItem;
611 item->Serialize( newItem );
612 commit->
Add( item.release() );
629 commit->
Remove( boardItem );
630 item->Serialize( newItem );
633 commit->
Add( newBoardItem );
637 parentGroup->
AddItem( newBoardItem );
641 commit->
Modify( boardItem );
647 aItemHandler( status, newItem );
653 :
_(
"Modified items via API" ) );
657 return ItemRequestStatus::IRS_OK;
663 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
664 return tl::unexpected( *busy );
670 e.set_status( ApiStatusCode::AS_UNHANDLED );
671 return tl::unexpected( e );
674 GetItemsResponse response;
677 std::vector<BOARD_ITEM*> items;
678 std::set<KICAD_T> typesRequested, typesInserted;
679 bool handledAnything =
false;
683 typesRequested.emplace( type );
685 if( typesInserted.count( type ) )
693 handledAnything =
true;
694 std::copy(
board->Tracks().begin(),
board->Tracks().end(),
695 std::back_inserter( items ) );
701 handledAnything =
true;
705 std::copy( fp->Pads().begin(), fp->Pads().end(),
706 std::back_inserter( items ) );
715 handledAnything =
true;
717 std::copy(
board->Footprints().begin(),
board->Footprints().end(),
718 std::back_inserter( items ) );
730 handledAnything =
true;
731 bool inserted =
false;
735 if( item->Type() == type )
737 items.emplace_back( item );
743 typesInserted.insert( type );
750 handledAnything =
true;
751 bool inserted =
false;
755 switch (item->Type()) {
761 items.emplace_back( item );
779 handledAnything =
true;
781 std::copy(
board->Zones().begin(),
board->Zones().end(),
782 std::back_inserter( items ) );
790 handledAnything =
true;
792 std::copy(
board->Groups().begin(),
board->Groups().end(),
793 std::back_inserter( items ) );
803 if( !handledAnything )
806 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
807 e.set_error_message(
"none of the requested types are valid for a Board object" );
808 return tl::unexpected( e );
813 if( !typesRequested.count( item->Type() ) )
816 google::protobuf::Any itemBuf;
817 item->Serialize( itemBuf );
818 response.mutable_items()->Add( std::move( itemBuf ) );
821 response.set_status( ItemRequestStatus::IRS_OK );
829 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
830 return tl::unexpected( *busy );
835 e.set_status( ApiStatusCode::AS_UNHANDLED );
836 return tl::unexpected( e );
839 GetItemsResponse response;
841 std::vector<BOARD_ITEM*> items;
843 for(
const kiapi::common::types::KIID&
id : aCtx.
Request.items() )
845 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
846 items.emplace_back( *item );
852 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
853 e.set_error_message(
"none of the requested IDs were found or valid" );
854 return tl::unexpected( e );
859 google::protobuf::Any itemBuf;
860 item->Serialize( itemBuf );
861 response.mutable_items()->Add( std::move( itemBuf ) );
864 response.set_status( ItemRequestStatus::IRS_OK );
869 const std::string& aClientName )
872 std::vector<BOARD_ITEM*> validatedItems;
874 for( std::pair<const KIID, ItemDeletionStatus> pair : aItemsToDelete )
878 validatedItems.push_back( item );
879 aItemsToDelete[pair.first] = ItemDeletionStatus::IDS_OK;
909 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetSelection" ) )
910 return tl::unexpected( *headless );
916 e.set_status( ApiStatusCode::AS_UNHANDLED );
917 return tl::unexpected( e );
928 SelectionResponse response;
933 item->Serialize( *response.add_items() );
943 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"ClearSelection" ) )
944 return tl::unexpected( *headless );
946 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
947 return tl::unexpected( *busy );
953 e.set_status( ApiStatusCode::AS_UNHANDLED );
954 return tl::unexpected( e );
968 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"AddToSelection" ) )
969 return tl::unexpected( *headless );
971 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
972 return tl::unexpected( *busy );
978 e.set_status( ApiStatusCode::AS_UNHANDLED );
979 return tl::unexpected( e );
985 std::vector<EDA_ITEM*> toAdd;
987 for(
const types::KIID&
id : aCtx.
Request.items() )
989 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
990 toAdd.emplace_back( *item );
996 SelectionResponse response;
999 item->Serialize( *response.add_items() );
1008 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"RemoveFromSelection" ) )
1009 return tl::unexpected( *headless );
1011 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1012 return tl::unexpected( *busy );
1016 ApiResponseStatus e;
1018 e.set_status( ApiStatusCode::AS_UNHANDLED );
1019 return tl::unexpected( e );
1025 std::vector<EDA_ITEM*> toRemove;
1027 for(
const types::KIID&
id : aCtx.
Request.items() )
1029 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
1030 toRemove.emplace_back( *item );
1036 SelectionResponse response;
1039 item->Serialize( *response.add_items() );
1050 if( !documentValidation )
1051 return tl::unexpected( documentValidation.error() );
1053 BoardStackupResponse response;
1054 google::protobuf::Any
any;
1058 any.UnpackTo( response.mutable_stackup() );
1061 for( board::BoardStackupLayer& layer : *response.mutable_stackup()->mutable_layers() )
1063 if( layer.type() == board::BoardStackupLayerType::BSLT_DIELECTRIC )
1069 layer.set_user_name(
board()->GetLayerName(
id ) );
1081 if( !documentValidation )
1082 return tl::unexpected( documentValidation.error() );
1084 BoardEnabledLayersResponse response;
1087 int copperLayerCount =
board->GetCopperLayerCount();
1089 response.set_copper_layer_count( copperLayerCount );
1091 LSET enabled =
board->GetEnabledLayers();
1110 if( !documentValidation )
1111 return tl::unexpected( documentValidation.error() );
1113 if( aCtx.
Request.copper_layer_count() % 2 != 0 )
1115 ApiResponseStatus e;
1116 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1117 e.set_error_message(
"copper_layer_count must be an even number" );
1118 return tl::unexpected( e );
1123 ApiResponseStatus e;
1124 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1125 e.set_error_message( fmt::format(
"copper_layer_count must be below %d",
MAX_CU_LAYERS ) );
1126 return tl::unexpected( e );
1129 int copperLayerCount =
static_cast<int>( aCtx.
Request.copper_layer_count() );
1134 enabled &=
~LSET::AllCuMask();
1139 LSET previousEnabled =
board->GetEnabledLayers();
1140 LSET changedLayers = enabled ^ previousEnabled;
1142 board->SetEnabledLayers( enabled );
1143 board->SetVisibleLayers(
board->GetVisibleLayers() | changedLayers );
1149 if( !enabled[layer_id] &&
board->HasItemsOnLayer( layer_id ) )
1150 removedLayers.push_back( layer_id );
1153 bool modified =
false;
1155 if( !removedLayers.empty() )
1160 modified |=
board->RemoveAllItemsOnLayer( layer_id );
1163 if( enabled != previousEnabled )
1169 BoardEnabledLayersResponse response;
1171 response.set_copper_layer_count( copperLayerCount );
1183 if( !documentValidation )
1184 return tl::unexpected( documentValidation.error() );
1187 GraphicsDefaultsResponse response;
1190 constexpr std::array<kiapi::board::BoardLayerClass, LAYER_CLASS_COUNT> classOrder = {
1191 kiapi::board::BLC_SILKSCREEN,
1192 kiapi::board::BLC_COPPER,
1193 kiapi::board::BLC_EDGES,
1194 kiapi::board::BLC_COURTYARD,
1195 kiapi::board::BLC_FABRICATION,
1196 kiapi::board::BLC_OTHER
1201 kiapi::board::BoardLayerGraphicsDefaults* l = response.mutable_defaults()->add_layers();
1203 l->set_layer( classOrder[i] );
1206 kiapi::common::types::TextAttributes*
text = l->mutable_text();
1223 if( !documentValidation )
1224 return tl::unexpected( documentValidation.error() );
1227 BoardDesignRulesResponse response;
1228 kiapi::board::BoardDesignRules* rules = response.mutable_rules();
1230 kiapi::board::MinimumConstraints* constraints = rules->mutable_constraints();
1232 constraints->mutable_min_clearance()->set_value_nm( bds.
m_MinClearance );
1233 constraints->mutable_min_groove_width()->set_value_nm( bds.
m_MinGrooveWidth );
1234 constraints->mutable_min_connection_width()->set_value_nm( bds.
m_MinConn );
1235 constraints->mutable_min_track_width()->set_value_nm( bds.
m_TrackMinWidth );
1237 constraints->mutable_min_via_size()->set_value_nm( bds.
m_ViasMinSize );
1238 constraints->mutable_min_through_drill()->set_value_nm( bds.
m_MinThroughDrill );
1242 constraints->mutable_hole_clearance()->set_value_nm( bds.
m_HoleClearance );
1243 constraints->mutable_hole_to_hole_min()->set_value_nm( bds.
m_HoleToHoleMin );
1244 constraints->mutable_silk_clearance()->set_value_nm( bds.
m_SilkClearance );
1249 kiapi::board::PredefinedSizes* sizes = rules->mutable_predefined_sizes();
1252 sizes->add_tracks()->mutable_width()->set_value_nm( bds.
m_TrackWidthList[ii] );
1256 kiapi::board::PresetViaDimension*
via = sizes->add_vias();
1263 kiapi::board::PresetDiffPairDimension* pair = sizes->add_diff_pairs();
1269 kiapi::board::SolderMaskPasteDefaults* maskPaste = rules->mutable_solder_mask_paste();
1278 kiapi::board::TeardropDefaults* teardrops = rules->mutable_teardrops();
1291 kiapi::board::TeardropTargetEntry* entry = teardrops->add_target_params();
1295 entry->mutable_params()->set_enabled( params->
m_Enabled );
1296 entry->mutable_params()->mutable_max_length()->set_value_nm( params->
m_TdMaxLen );
1297 entry->mutable_params()->mutable_max_width()->set_value_nm( params->
m_TdMaxWidth );
1301 entry->mutable_params()->set_curved_edges( params->
m_CurvedEdges );
1306 kiapi::board::ViaProtectionDefaults* viaProtection = rules->mutable_via_protection();
1314 viaProtection->set_cap( bds.
m_CapVias );
1319 board::DrcSeveritySetting* setting = rules->add_severities();
1320 setting->set_rule_type(
1327 kiapi::board::DrcExclusion* exclusion = rules->add_exclusions();
1328 exclusion->mutable_marker()->mutable_id()->set_opaque_id( serialized.ToStdString() );
1333 exclusion->set_comment( it->second.ToStdString() );
1336 response.set_custom_rules_status( CRS_NONE );
1342 if( !rulesPath.IsEmpty() && wxFileName::IsFileReadable( rulesPath ) )
1344 wxFFile file( rulesPath,
"r" );
1346 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
1348 if( !file.IsOpened() )
1350 response.set_custom_rules_status( CRS_INVALID );
1354 file.ReadAll( &content );
1360 parser.
Parse( parsedRules,
nullptr );
1361 response.set_custom_rules_status( CRS_VALID );
1365 response.set_custom_rules_status( CRS_INVALID );
1378 if( !documentValidation )
1379 return tl::unexpected( documentValidation.error() );
1382 const kiapi::board::BoardDesignRules& rules = aCtx.
Request.rules();
1384 if( rules.has_constraints() )
1386 const kiapi::board::MinimumConstraints& constraints = rules.constraints();
1388 newSettings.
m_MinClearance = constraints.min_clearance().value_nm();
1390 newSettings.
m_MinConn = constraints.min_connection_width().value_nm();
1391 newSettings.
m_TrackMinWidth = constraints.min_track_width().value_nm();
1393 newSettings.
m_ViasMinSize = constraints.min_via_size().value_nm();
1398 newSettings.
m_HoleClearance = constraints.hole_clearance().value_nm();
1399 newSettings.
m_HoleToHoleMin = constraints.hole_to_hole_min().value_nm();
1400 newSettings.
m_SilkClearance = constraints.silk_clearance().value_nm();
1406 if( rules.has_predefined_sizes() )
1411 for(
const kiapi::board::PresetTrackWidth& track : rules.predefined_sizes().tracks() )
1417 for(
const kiapi::board::PresetViaDimension&
via : rules.predefined_sizes().vias() )
1420 static_cast<int>(
via.drill().value_nm() ) );
1426 for(
const kiapi::board::PresetDiffPairDimension& pair : rules.predefined_sizes().diff_pairs() )
1429 static_cast<int>( pair.width().value_nm() ),
1430 static_cast<int>( pair.gap().value_nm() ),
1431 static_cast<int>( pair.via_gap().value_nm() ) );
1435 if( rules.has_solder_mask_paste() )
1437 const kiapi::board::SolderMaskPasteDefaults& maskPaste = rules.solder_mask_paste();
1445 maskPaste.allow_soldermask_bridges_in_footprints();
1448 if( rules.has_teardrops() )
1450 const kiapi::board::TeardropDefaults& teardrops = rules.teardrops();
1458 for(
const kiapi::board::TeardropTargetEntry& entry : teardrops.target_params() )
1460 if( entry.target() == kiapi::board::TeardropTarget::TDT_UNKNOWN )
1468 params->
m_Enabled = entry.params().enabled();
1469 params->
m_TdMaxLen = entry.params().max_length().value_nm();
1470 params->
m_TdMaxWidth = entry.params().max_width().value_nm();
1480 if( rules.has_via_protection() )
1482 const kiapi::board::ViaProtectionDefaults& viaProtection = rules.via_protection();
1490 newSettings.
m_CapVias = viaProtection.cap();
1491 newSettings.
m_FillVias = viaProtection.fill();
1494 if( rules.severities_size() > 0 )
1498 for(
const kiapi::board::DrcSeveritySetting& severitySetting : rules.severities() )
1506 if( !permitted.contains( setting ) )
1508 ApiResponseStatus e;
1509 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1510 e.set_error_message( fmt::format(
"DRC severity must be error, warning, or ignore" ) );
1511 return tl::unexpected( e );
1518 if( rules.exclusions_size() > 0 )
1523 for(
const kiapi::board::DrcExclusion& exclusion : rules.exclusions() )
1525 wxString serialized = wxString::FromUTF8( exclusion.marker().id().opaque_id() );
1527 if( serialized.IsEmpty() )
1529 ApiResponseStatus e;
1530 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1531 e.set_error_message(
"DrcExclusion marker id must not be empty" );
1532 return tl::unexpected( e );
1540 std::vector<BOARD_DESIGN_SETTINGS::VALIDATION_ERROR> errors = newSettings.
ValidateDesignRules();
1542 if( !errors.empty() )
1546 ApiResponseStatus e;
1547 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1548 e.set_error_message( fmt::format(
"Invalid board design rules: {}: {}",
1551 return tl::unexpected( e );
1574 if( !documentValidation )
1575 return tl::unexpected( documentValidation.error() );
1577 CustomRulesResponse response;
1578 response.set_status( CRS_NONE );
1584 if( rulesPath.IsEmpty() || !wxFileName::IsFileReadable( rulesPath ) )
1587 wxFFile file( rulesPath,
"r" );
1589 if( !file.IsOpened() )
1591 response.set_status( CRS_INVALID );
1592 response.set_error_text(
"Failed to open custom rules file" );
1597 file.ReadAll( &content );
1600 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
1605 parser.
Parse( parsedRules,
nullptr );
1609 response.set_status( CRS_INVALID );
1610 response.set_error_text( ioe.
What().ToStdString() );
1614 for(
const std::shared_ptr<DRC_RULE>& rule : parsedRules )
1621 kiapi::board::CustomRule* customRule = response.add_rules();
1623 if( rule->m_Condition )
1624 customRule->set_condition( rule->m_Condition->GetExpression().ToUTF8() );
1628 board::CustomRuleConstraint* constraintProto = customRule->add_constraints();
1629 constraint.
ToProto( *constraintProto );
1633 customRule->set_name( rule->m_Name.ToUTF8() );
1635 if( rule->m_LayerSource.CmpNoCase( wxS(
"outer" ) ) == 0 )
1637 customRule->set_layer_mode( kiapi::board::CRLM_OUTER );
1639 else if( rule->m_LayerSource.CmpNoCase( wxS(
"inner" ) ) == 0 )
1641 customRule->set_layer_mode( kiapi::board::CRLM_INNER );
1643 else if( !rule->m_LayerSource.IsEmpty() )
1649 customRule->set_single_layer(
1654 if( !comment.IsEmpty() )
1655 customRule->set_comments( comment );
1658 response.set_status( CRS_VALID );
1668 if( !documentValidation )
1669 return tl::unexpected( documentValidation.error() );
1675 if( aCtx.
Request.rules_size() == 0 )
1677 if( wxFileName::FileExists( rulesPath ) )
1679 if( !wxRemoveFile( rulesPath ) )
1681 CustomRulesResponse response;
1682 response.set_status( CRS_INVALID );
1683 response.set_error_text(
"Failed to remove custom rules file" );
1688 CustomRulesResponse response;
1689 response.set_status( CRS_NONE );
1694 rulesText <<
"(version 1)\n";
1696 for(
const board::CustomRule& rule : aCtx.
Request.rules() )
1698 wxString serializationError;
1701 if( serializedRule.IsEmpty() )
1703 CustomRulesResponse response;
1704 response.set_status( CRS_INVALID );
1706 if( serializationError.IsEmpty() )
1707 response.set_error_text(
"Failed to serialize custom rule" );
1709 response.set_error_text( serializationError.ToUTF8() );
1714 rulesText <<
"\n" << serializedRule;
1720 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
1722 parser.
Parse( parsedRules,
nullptr );
1726 CustomRulesResponse response;
1727 response.set_status( CRS_INVALID );
1728 response.set_error_text( ioe.
What().ToStdString() );
1732 wxFFile file( rulesPath,
"w" );
1734 if( !file.IsOpened() )
1736 CustomRulesResponse response;
1737 response.set_status( CRS_INVALID );
1738 response.set_error_text(
"Failed to open custom rules file for writing" );
1742 if( !file.Write( rulesText ) )
1746 CustomRulesResponse response;
1747 response.set_status( CRS_INVALID );
1748 response.set_error_text(
"Failed to write custom rules file" );
1764 !documentValidation )
1766 return tl::unexpected( documentValidation.error() );
1785 ApiResponseStatus e;
1786 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1787 e.set_error_message(
"Unexpected origin type" );
1788 return tl::unexpected( e );
1792 types::Vector2 reply;
1800 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1801 return tl::unexpected( *busy );
1804 !documentValidation )
1806 return tl::unexpected( documentValidation.error() );
1817 frame()->CallAfter( [f, origin]()
1832 frame()->CallAfter( [f, origin]()
1844 ApiResponseStatus e;
1845 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1846 e.set_error_message(
"Unexpected origin type" );
1847 return tl::unexpected( e );
1859 !documentValidation )
1861 return tl::unexpected( documentValidation.error() );
1864 BoardLayerNameResponse response;
1868 response.set_name(
board()->GetLayerName(
id ) );
1877 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1878 return tl::unexpected( *busy );
1882 ApiResponseStatus e;
1884 e.set_status( ApiStatusCode::AS_UNHANDLED );
1885 return tl::unexpected( e );
1888 GetBoundingBoxResponse response;
1889 bool includeText = aCtx.
Request.mode() == BoundingBoxMode::BBM_ITEM_AND_CHILD_TEXT;
1891 for(
const types::KIID& idMsg : aCtx.
Request.items() )
1893 KIID id( idMsg.value() );
1894 std::optional<BOARD_ITEM*> optItem =
getItemById(
id );
1903 bbox =
static_cast<FOOTPRINT*
>( item )->GetBoundingBox( includeText );
1907 response.add_items()->set_value( idMsg.value() );
1908 PackBox2( *response.add_boxes(), bbox );
1919 !documentValidation )
1921 return tl::unexpected( documentValidation.error() );
1924 PadShapeAsPolygonResponse response;
1927 for(
const types::KIID& padRequest : aCtx.
Request.pads() )
1929 KIID id( padRequest.value() );
1930 std::optional<BOARD_ITEM*> optPad =
getItemById(
id );
1932 if( !optPad || ( *optPad )->Type() !=
PCB_PAD_T )
1935 response.add_pads()->set_value( padRequest.value() );
1937 PAD*
pad =
static_cast<PAD*
>( *optPad );
1939 pad->TransformShapeToPolygon( poly,
pad->Padstack().EffectiveLayerFor( layer ), 0,
1942 types::PolygonWithHoles* polyMsg = response.mutable_polygons()->Add();
1953 using board::types::BoardLayer;
1956 !documentValidation )
1958 return tl::unexpected( documentValidation.error() );
1961 PadstackPresenceResponse response;
1965 for(
const int layer : aCtx.
Request.layers() )
1968 for(
const types::KIID& padRequest : aCtx.
Request.items() )
1970 KIID id( padRequest.value() );
1971 std::optional<BOARD_ITEM*> optItem =
getItemById(
id );
1976 switch( ( *optItem )->Type() )
1980 PAD*
pad =
static_cast<PAD*
>( *optItem );
1984 PadstackPresenceEntry* entry = response.add_entries();
1985 entry->mutable_item()->set_value(
pad->m_Uuid.AsStdString() );
1987 entry->set_presence(
pad->FlashLayer( layer ) ? PSP_PRESENT : PSP_NOT_PRESENT );
1999 PadstackPresenceEntry* entry = response.add_entries();
2000 entry->mutable_item()->set_value(
via->m_Uuid.AsStdString() );
2002 entry->set_presence(
via->FlashLayer( layer ) ? PSP_PRESENT : PSP_NOT_PRESENT );
2067 if( !documentValidation )
2068 return tl::unexpected( documentValidation.error() );
2070 ExpandTextVariablesResponse reply;
2073 std::function<bool( wxString* )> textResolver =
2074 [&]( wxString* token ) ->
bool
2077 return board->ResolveTextVar( token, 0 );
2080 for(
const std::string& textMsg : aCtx.
Request.text() )
2083 reply.add_text(
text.ToUTF8() );
2093 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"InteractiveMoveItems" ) )
2094 return tl::unexpected( *headless );
2096 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2097 return tl::unexpected( *busy );
2101 if( !documentValidation )
2102 return tl::unexpected( documentValidation.error() );
2105 std::vector<EDA_ITEM*> toSelect;
2107 for(
const kiapi::common::types::KIID&
id : aCtx.
Request.items() )
2109 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
2110 toSelect.emplace_back(
static_cast<EDA_ITEM*
>( *item ) );
2113 if( toSelect.empty() )
2115 ApiResponseStatus e;
2116 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2117 e.set_error_message( fmt::format(
"None of the given items exist on the board",
2118 aCtx.
Request.board().board_filename() ) );
2119 return tl::unexpected( e );
2139 if( !documentValidation )
2140 return tl::unexpected( documentValidation.error() );
2142 NetsResponse response;
2145 std::set<wxString> netclassFilter;
2147 for(
const std::string& nc : aCtx.
Request.netclass_filter() )
2148 netclassFilter.insert( wxString( nc.c_str(), wxConvUTF8 ) );
2154 if( !netclassFilter.empty() && nc )
2156 bool inClass =
false;
2158 for(
const wxString&
filter : netclassFilter )
2171 board::types::Net* netProto = response.add_nets();
2172 netProto->set_name( net->GetNetname() );
2173 netProto->mutable_code()->set_value( net->GetNetCode() );
2183 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2184 return tl::unexpected( *busy );
2188 ApiResponseStatus e;
2189 e.set_status( ApiStatusCode::AS_UNHANDLED );
2190 return tl::unexpected( e );
2194 const bool filterByType = aCtx.
Request.types_size() > 0;
2196 if( filterByType && types.empty() )
2198 ApiResponseStatus e;
2199 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2200 e.set_error_message(
"none of the requested types are valid for a Board object" );
2201 return tl::unexpected( e );
2204 std::set<KICAD_T> typeFilter( types.begin(), types.end() );
2205 std::vector<BOARD_CONNECTED_ITEM*> sourceItems;
2207 for(
const types::KIID&
id : aCtx.
Request.items() )
2209 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
2212 sourceItems.emplace_back( connected );
2216 if( sourceItems.empty() )
2218 ApiResponseStatus e;
2219 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2220 e.set_error_message(
"none of the requested IDs were found or valid connected items" );
2221 return tl::unexpected( e );
2224 GetItemsResponse response;
2226 std::set<KIID> insertedItems;
2232 if( filterByType && !typeFilter.contains( connected->Type() ) )
2235 if( !insertedItems.insert( connected->m_Uuid ).second )
2238 connected->Serialize( *response.add_items() );
2242 response.set_status( ItemRequestStatus::IRS_OK );
2250 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2251 return tl::unexpected( *busy );
2255 ApiResponseStatus e;
2256 e.set_status( ApiStatusCode::AS_UNHANDLED );
2257 return tl::unexpected( e );
2261 const bool filterByType = aCtx.
Request.types_size() > 0;
2263 if( filterByType && types.empty() )
2265 ApiResponseStatus e;
2266 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2267 e.set_error_message(
"none of the requested types are valid for a Board object" );
2268 return tl::unexpected( e );
2274 GetItemsResponse response;
2276 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
2277 std::set<KIID> insertedItems;
2281 for(
const board::types::Net& net : aCtx.
Request.nets() )
2290 if( !insertedItems.insert( item->m_Uuid ).second )
2293 item->Serialize( *response.add_items() );
2297 response.set_status( ItemRequestStatus::IRS_OK );
2305 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2306 return tl::unexpected( *busy );
2310 ApiResponseStatus e;
2311 e.set_status( ApiStatusCode::AS_UNHANDLED );
2312 return tl::unexpected( e );
2316 const bool filterByType = aCtx.
Request.types_size() > 0;
2318 if( filterByType && types.empty() )
2320 ApiResponseStatus e;
2321 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2322 e.set_error_message(
"none of the requested types are valid for a Board object" );
2323 return tl::unexpected( e );
2329 std::set<wxString> requestedClasses;
2331 for(
const std::string& netClass : aCtx.
Request.net_classes() )
2332 requestedClasses.insert( wxString( netClass.c_str(), wxConvUTF8 ) );
2334 GetItemsResponse response;
2336 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
2337 std::set<KIID> insertedItems;
2346 if( !requestedClasses.empty() )
2351 bool inClass =
false;
2353 for(
const wxString&
filter : requestedClasses )
2368 if( !insertedItems.insert( item->m_Uuid ).second )
2371 item->Serialize( *response.add_items() );
2375 response.set_status( ItemRequestStatus::IRS_OK );
2383 NetClassForNetsResponse response;
2387 google::protobuf::Any
any;
2389 for(
const board::types::Net& net : aCtx.
Request.net() )
2397 auto [pair, rc] = response.mutable_classes()->insert( { net.name(), {} } );
2398 any.UnpackTo( &pair->second );
2407 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2408 return tl::unexpected( *busy );
2412 if( !documentValidation )
2413 return tl::unexpected( documentValidation.error() );
2415 if( aCtx.
Request.zones().empty() )
2418 frame()->CallAfter( [mgr]()
2426 ApiResponseStatus e;
2427 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
2428 return tl::unexpected( e );
2440 if( !documentValidation )
2441 return tl::unexpected( documentValidation.error() );
2443 SavedDocumentResponse response;
2444 response.mutable_document()->CopyFrom( aCtx.
Request.document() );
2448 [&](
const wxString& aData )
2450 response.set_contents( aData.ToUTF8() );
2462 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SaveSelectionToString" ) )
2463 return tl::unexpected( *headless );
2465 SavedSelectionResponse response;
2473 [&](
const wxString& aData )
2475 response.set_contents( aData.ToUTF8() );
2488 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2489 return tl::unexpected( *busy );
2493 if( !documentValidation )
2494 return tl::unexpected( documentValidation.error() );
2496 CreateItemsResponse response;
2504 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetVisibleLayers" ) )
2505 return tl::unexpected( *headless );
2509 if( !documentValidation )
2510 return tl::unexpected( documentValidation.error() );
2512 BoardLayers response;
2524 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SetVisibleLayers" ) )
2525 return tl::unexpected( *headless );
2527 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2528 return tl::unexpected( *busy );
2532 if( !documentValidation )
2533 return tl::unexpected( documentValidation.error() );
2538 for(
int layerIdx : aCtx.
Request.layers() )
2544 visible.
set( layer );
2558 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetActiveLayer" ) )
2559 return tl::unexpected( *headless );
2563 if( !documentValidation )
2564 return tl::unexpected( documentValidation.error() );
2566 BoardLayerResponse response;
2577 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SetActiveLayer" ) )
2578 return tl::unexpected( *headless );
2580 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2581 return tl::unexpected( *busy );
2585 if( !documentValidation )
2586 return tl::unexpected( documentValidation.error() );
2590 if( !
board()->GetEnabledLayers().Contains( layer ) )
2592 ApiResponseStatus err;
2593 err.set_status( ApiStatusCode::AS_BAD_REQUEST );
2594 err.set_error_message( fmt::format(
"Layer {} is not a valid layer for the given board",
2595 magic_enum::enum_name( layer ) ) );
2596 return tl::unexpected( err );
2607 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetBoardEditorAppearanceSettings" ) )
2608 return tl::unexpected( *headless );
2610 BoardEditorAppearanceSettings reply;
2618 reply.set_net_color_display(
2621 reply.set_board_flip(
frame()->GetCanvas()->GetView()->IsMirroredX()
2622 ? BoardFlipMode::BFM_FLIPPED_X
2623 : BoardFlipMode::BFM_NORMAL );
2637 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SetBoardEditorAppearanceSettings" ) )
2638 return tl::unexpected( *headless );
2640 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2641 return tl::unexpected( *busy );
2646 const BoardEditorAppearanceSettings& newSettings = aCtx.
Request.settings();
2653 bool flip = newSettings.board_flip() == BoardFlipMode::BFM_FLIPPED_X;
2675 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2676 return tl::unexpected( *busy );
2680 if( !documentValidation )
2681 return tl::unexpected( documentValidation.error() );
2689 drcItem->SetErrorMessage( wxString::FromUTF8( aCtx.
Request.message() ) );
2693 for(
const auto&
id : aCtx.
Request.items() )
2694 ids.emplace_back(
KIID(
id.value() ) );
2697 drcItem->SetItems( ids );
2699 const auto& pos = aCtx.
Request.position();
2700 VECTOR2I position(
static_cast<int>( pos.x_nm() ),
static_cast<int>( pos.y_nm() ) );
2705 commit->
Add( marker );
2706 commit->
Push( wxS(
"API injected DRC marker" ) );
2708 InjectDrcErrorResponse response;
2716 const std::string& aCommandName )
2718 if( aUnits == types::Units::U_INCH || aUnits == types::Units::U_MM
2719 || aUnits == types::Units::U_UNKNOWN )
2721 return std::nullopt;
2724 ApiResponseStatus e;
2725 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2726 e.set_error_message( fmt::format(
"{} supports only inch and mm units", aCommandName ) );
2731std::optional<ApiResponseStatus>
2733 const std::string& aCommandName )
2735 if( aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_UNKNOWN
2736 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_ALL_LAYERS_ONE_PAGE
2737 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_EACH_LAYER_OWN_FILE )
2739 return std::nullopt;
2742 ApiResponseStatus e;
2743 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2744 e.set_error_message( fmt::format(
"{} does not support EACH_LAYER_OWN_PAGE pagination mode",
2753 for(
int layer : aSettings.layers() )
2756 static_cast<board::types::BoardLayer
>( layer ) );
2760 ApiResponseStatus e;
2761 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2762 e.set_error_message(
"Board plot settings contain an invalid layer" );
2769 for(
int layer : aSettings.common_layers() )
2772 static_cast<board::types::BoardLayer
>( layer ) );
2776 ApiResponseStatus e;
2777 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2778 e.set_error_message(
"Board plot settings contain an invalid common layer" );
2785 aJob.
m_colorTheme = wxString::FromUTF8( aSettings.color_theme() );
2786 aJob.
m_drawingSheet = wxString::FromUTF8( aSettings.drawing_sheet() );
2787 aJob.
m_variant = wxString::FromUTF8( aSettings.variant() );
2789 aJob.
m_mirror = aSettings.mirror();
2792 aJob.
m_scale = aSettings.scale();
2800 aJob.
m_plotRefDes = aSettings.plot_reference_designators();
2810 return std::nullopt;
2816 types::RunJobResponse response;
2819 if( !aContext || !aContext->
GetKiway() )
2821 response.set_status( types::JobStatus::JS_ERROR );
2822 response.set_message(
"Internal error" );
2824 wxCHECK_MSG(
false, response,
"context missing valid kiway in ExecuteBoardJob?" );
2830 response.add_output_path(
output.m_outputPath.ToUTF8() );
2834 response.set_status( types::JobStatus::JS_SUCCESS );
2838 response.set_status( types::JobStatus::JS_ERROR );
2839 response.set_message( fmt::format(
"Board export job '{}' failed with exit code {}: {}",
2849 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2850 return tl::unexpected( *busy );
2854 if( !documentValidation )
2855 return tl::unexpected( documentValidation.error() );
2908 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2909 return tl::unexpected( *busy );
2913 if( !documentValidation )
2914 return tl::unexpected( documentValidation.error() );
2956 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2957 return tl::unexpected( *busy );
2961 if( !documentValidation )
2962 return tl::unexpected( documentValidation.error() );
2969 return tl::unexpected( *err );
2974 if( std::optional<ApiResponseStatus> paginationError =
2976 "RunBoardJobExportSvg" ) )
2978 return tl::unexpected( *paginationError );
2990 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2991 return tl::unexpected( *busy );
2995 if( !documentValidation )
2996 return tl::unexpected( documentValidation.error() );
3003 return tl::unexpected( *err );
3008 if( std::optional<ApiResponseStatus> unitError =
3011 return tl::unexpected( *unitError );
3016 if( std::optional<ApiResponseStatus> paginationError =
3018 "RunBoardJobExportDxf" ) )
3020 return tl::unexpected( *paginationError );
3032 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3033 return tl::unexpected( *busy );
3037 if( !documentValidation )
3038 return tl::unexpected( documentValidation.error() );
3045 return tl::unexpected( *err );
3062 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3063 return tl::unexpected( *busy );
3067 if( !documentValidation )
3068 return tl::unexpected( documentValidation.error() );
3075 return tl::unexpected( *err );
3077 if( std::optional<ApiResponseStatus> paginationError =
3079 "RunBoardJobExportPs" ) )
3081 return tl::unexpected( *paginationError );
3099 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3100 return tl::unexpected( *busy );
3104 if( !documentValidation )
3105 return tl::unexpected( documentValidation.error() );
3107 if( aCtx.
Request.layers().empty() )
3109 ApiResponseStatus e;
3110 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3111 e.set_error_message(
"RunBoardJobExportGerbers requires at least one layer" );
3112 return tl::unexpected( e );
3119 for(
int layer : aCtx.
Request.layers() )
3123 static_cast<board::types::BoardLayer
>( layer ) );
3127 ApiResponseStatus e;
3128 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3129 e.set_error_message(
"RunBoardJobExportGerbers contains an invalid layer" );
3130 return tl::unexpected( e );
3143 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3144 return tl::unexpected( *busy );
3148 if( !documentValidation )
3149 return tl::unexpected( documentValidation.error() );
3157 if( std::optional<ApiResponseStatus> unitError =
3160 return tl::unexpected( *unitError );
3167 if( aCtx.
Request.has_excellon() )
3169 const ExcellonFormatOptions& excellonOptions = aCtx.
Request.excellon();
3171 if( excellonOptions.has_mirror_y() )
3174 if( excellonOptions.has_minimal_header() )
3177 if( excellonOptions.has_combine_pth_npth() )
3180 if( excellonOptions.has_route_oval_holes() )
3184 if( aCtx.
Request.map_format() != DrillMapFormat::DMF_UNKNOWN )
3192 if( aCtx.
Request.has_gerber_generate_tenting() )
3195 if( aCtx.
Request.report_format() != DrillReportFormat::DRF_UNKNOWN )
3199 if( aCtx.
Request.has_report_filename() )
3210 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3211 return tl::unexpected( *busy );
3215 if( !documentValidation )
3216 return tl::unexpected( documentValidation.error() );
3222 if( aCtx.
Request.has_use_drill_place_file_origin() )
3232 if( aCtx.
Request.has_include_board_edge_for_gerber() )
3239 if( std::optional<ApiResponseStatus> unitError =
3242 return tl::unexpected( *unitError );
3255 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3256 return tl::unexpected( *busy );
3260 if( !documentValidation )
3261 return tl::unexpected( documentValidation.error() );
3280 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3281 return tl::unexpected( *busy );
3285 if( !documentValidation )
3286 return tl::unexpected( documentValidation.error() );
3294 if( aCtx.
Request.has_precision() )
3299 job.
m_colMfgPn = wxString::FromUTF8( aCtx.
Request.manufacturer_part_number_column() );
3300 job.
m_colMfg = wxString::FromUTF8( aCtx.
Request.manufacturer_column() );
3301 job.
m_colDistPn = wxString::FromUTF8( aCtx.
Request.distributor_part_number_column() );
3305 if( std::optional<ApiResponseStatus> unitError =
3308 return tl::unexpected( *unitError );
3321 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3322 return tl::unexpected( *busy );
3326 if( !documentValidation )
3327 return tl::unexpected( documentValidation.error() );
3340 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3341 return tl::unexpected( *busy );
3345 if( !documentValidation )
3346 return tl::unexpected( documentValidation.error() );
3354 if( aCtx.
Request.has_precision() )
3357 if( std::optional<ApiResponseStatus> unitError =
3360 return tl::unexpected( *unitError );
3373 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3374 return tl::unexpected( *busy );
3378 if( !documentValidation )
3379 return tl::unexpected( documentValidation.error() );
3387 if( std::optional<ApiResponseStatus> unitError =
3390 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(BOARD_CONTEXT *aContext, JOB &aJob)
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
BASE_SCREEN class implementation.
std::shared_ptr< BOARD_CONTEXT > CreatePcbFrameContext(PCB_EDIT_FRAME *aFrame)
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION gridSetOrigin
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
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)
API_HANDLER_EDITOR(EDA_BASE_FRAME *aFrame=nullptr)
static std::vector< KICAD_T > parseRequestedItemTypes(const google::protobuf::RepeatedField< int > &aTypes)
COMMIT * getCurrentCommit(const std::string &aClientName)
virtual void pushCurrentCommit(const std::string &aClientName, const wxString &aMessage)
std::set< std::string > m_activeClients
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
HANDLER_RESULT< commands::SelectionResponse > handleAddToSelection(const HANDLER_CONTEXT< commands::AddToSelection > &aCtx)
HANDLER_RESULT< commands::CreateItemsResponse > handleParseAndCreateItemsFromString(const HANDLER_CONTEXT< commands::ParseAndCreateItemsFromString > &aCtx)
std::optional< TITLE_BLOCK * > getTitleBlock() override
HANDLER_RESULT< Empty > handleInteractiveMoveItems(const HANDLER_CONTEXT< InteractiveMoveItems > &aCtx)
HANDLER_RESULT< Empty > handleSetActiveLayer(const HANDLER_CONTEXT< SetActiveLayer > &aCtx)
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)
static HANDLER_RESULT< std::unique_ptr< BOARD_ITEM > > createItemForType(KICAD_T aType, BOARD_ITEM_CONTAINER *aContainer)
std::optional< BOARD_ITEM * > getItemById(const KIID &aId) const
HANDLER_RESULT< commands::GetItemsResponse > handleGetConnectedItems(const HANDLER_CONTEXT< GetConnectedItems > &aCtx)
HANDLER_RESULT< types::Vector2 > handleGetBoardOrigin(const HANDLER_CONTEXT< GetBoardOrigin > &aCtx)
std::shared_ptr< BOARD_CONTEXT > m_context
HANDLER_RESULT< commands::GetItemsResponse > handleGetItemsByNetClass(const HANDLER_CONTEXT< GetItemsByNetClass > &aCtx)
bool setPageSettings(const PAGE_INFO &aPageInfo) override
std::unique_ptr< COMMIT > createCommit() override
Override this to create an appropriate COMMIT subclass for the frame in question.
BOARD_CONTEXT * context() const
HANDLER_RESULT< BoardStackupResponse > handleGetStackup(const HANDLER_CONTEXT< GetBoardStackup > &aCtx)
HANDLER_RESULT< commands::SelectionResponse > handleGetSelection(const HANDLER_CONTEXT< commands::GetSelection > &aCtx)
HANDLER_RESULT< NetClassForNetsResponse > handleGetNetClassForNets(const HANDLER_CONTEXT< GetNetClassForNets > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportIpcD356(const HANDLER_CONTEXT< RunBoardJobExportIpcD356 > &aCtx)
HANDLER_RESULT< BoardDesignRulesResponse > handleGetBoardDesignRules(const HANDLER_CONTEXT< GetBoardDesignRules > &aCtx)
std::optional< EDA_ITEM * > getItemFromDocument(const DocumentSpecifier &aDocument, const KIID &aId) override
HANDLER_RESULT< commands::ExpandTextVariablesResponse > handleExpandTextVariables(const HANDLER_CONTEXT< commands::ExpandTextVariables > &aCtx)
std::optional< ApiResponseStatus > checkForHeadless(const std::string &aCommandName) const
HANDLER_RESULT< Empty > handleSetVisibleLayers(const HANDLER_CONTEXT< SetVisibleLayers > &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< GraphicsDefaultsResponse > handleGetGraphicsDefaults(const HANDLER_CONTEXT< GetGraphicsDefaults > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExport3D(const HANDLER_CONTEXT< RunBoardJobExport3D > &aCtx)
TOOL_MANAGER * toolManager() const
HANDLER_RESULT< commands::GetItemsResponse > handleGetItemsById(const HANDLER_CONTEXT< commands::GetItemsById > &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)
HANDLER_RESULT< Empty > handleClearSelection(const HANDLER_CONTEXT< commands::ClearSelection > &aCtx)
HANDLER_RESULT< commands::RunActionResponse > handleRunAction(const HANDLER_CONTEXT< commands::RunAction > &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< BoardLayers > handleGetVisibleLayers(const HANDLER_CONTEXT< GetVisibleLayers > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportSvg(const HANDLER_CONTEXT< RunBoardJobExportSvg > &aCtx)
HANDLER_RESULT< PadstackPresenceResponse > handleCheckPadstackPresenceOnLayers(const HANDLER_CONTEXT< CheckPadstackPresenceOnLayers > &aCtx)
HANDLER_RESULT< commands::SelectionResponse > handleRemoveFromSelection(const HANDLER_CONTEXT< commands::RemoveFromSelection > &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< commands::SavedDocumentResponse > handleSaveDocumentToString(const HANDLER_CONTEXT< commands::SaveDocumentToString > &aCtx)
HANDLER_RESULT< commands::GetBoundingBoxResponse > handleGetBoundingBox(const HANDLER_CONTEXT< commands::GetBoundingBox > &aCtx)
HANDLER_RESULT< Empty > handleSaveDocument(const HANDLER_CONTEXT< commands::SaveDocument > &aCtx)
void deleteItemsInternal(std::map< KIID, ItemDeletionStatus > &aItemsToDelete, const std::string &aClientName) override
PROJECT & project() const
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportDrill(const HANDLER_CONTEXT< RunBoardJobExportDrill > &aCtx)
HANDLER_RESULT< BoardEnabledLayersResponse > handleGetBoardEnabledLayers(const HANDLER_CONTEXT< GetBoardEnabledLayers > &aCtx)
HANDLER_RESULT< commands::GetItemsResponse > handleGetItems(const HANDLER_CONTEXT< commands::GetItems > &aCtx)
HANDLER_RESULT< PadShapeAsPolygonResponse > handleGetPadShapeAsPolygon(const HANDLER_CONTEXT< GetPadShapeAsPolygon > &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< types::ItemRequestStatus > handleCreateUpdateItemsInternal(bool aCreate, const std::string &aClientName, const types::ItemHeader &aHeader, const google::protobuf::RepeatedPtrField< google::protobuf::Any > &aItems, std::function< void(commands::ItemStatus, google::protobuf::Any)> aItemHandler) override
HANDLER_RESULT< BoardLayerResponse > handleGetActiveLayer(const HANDLER_CONTEXT< GetActiveLayer > &aCtx)
HANDLER_RESULT< Empty > handleRevertDocument(const HANDLER_CONTEXT< commands::RevertDocument > &aCtx)
HANDLER_RESULT< commands::SavedSelectionResponse > handleSaveSelectionToString(const HANDLER_CONTEXT< commands::SaveSelectionToString > &aCtx)
void pushCurrentCommit(const std::string &aClientName, const wxString &aMessage) override
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)
BASE_SET & reset(size_t pos)
BASE_SET & set(size_t pos)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
An interface for the frame surface that the API handlers need; to enable headless mode.
virtual bool SaveBoard()=0
virtual bool SavePcbCopy(const wxString &aFileName, bool aCreateProject, bool aHeadless)=0
virtual KIWAY * GetKiway() const =0
virtual BOARD * GetBoard() const =0
virtual PROJECT & Prj() const =0
virtual wxString GetCurrentFileName() 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
bool m_TextUpright[LAYER_CLASS_COUNT]
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
int m_TextThickness[LAYER_CLASS_COUNT]
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.
int m_LineThickness[LAYER_CLASS_COUNT]
double m_SolderPasteMarginRatio
VECTOR2I m_TextSize[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
std::vector< VIA_DIMENSION > m_ViasDimensionsList
int m_ViasMinAnnularWidth
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void CopyFrom(const BOARD_ITEM *aOther)
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Information pertinent to a Pcbnew printed circuit board.
BOARD_STACKUP GetStackupOrDefault() const
void SetVisibleLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
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
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
void SaveSelection(const PCB_SELECTION &selected, bool isFootprintEditor)
void SetWriter(std::function< void(const wxString &)> aWriter)
void SaveBoard(const wxString &aFileName, BOARD *aBoard, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aBoard to a storage file in a format that this PCB_IO implementation knows about or it can be u...
void SetBoard(BOARD *aBoard)
Represent a set of changes (additions, deletions or modifications) of a data model (e....
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aFlags=0)=0
Execute the changes.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
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
void AddItem(EDA_ITEM *aItem)
Add item to group.
A base class for most all the KiCad significant classes used in schematics and boards.
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
virtual EDA_GROUP * GetParentGroup() const
KICAD_T Type() const
Returns the type of object.
virtual wxString GetFriendlyName() const
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.
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
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 move
move or drag an item
static TOOL_ACTION drillSetOrigin
APPEARANCE_CONTROLS * GetAppearancePanel()
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.
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.
void SyncLayersVisibility(const BOARD *aBoard)
Update "visibility" property of each layer of a given BOARD.
The main frame for Pcbnew.
void LoadDrawingSheet()
Load the drawing sheet file.
void SetActiveLayer(PCB_LAYER_ID aLayer) override
Change the currently active layer to aLayer and also update the APPEARANCE_CONTROLS.
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,...
A set of BOARD_ITEMs (i.e., without duplicates).
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
void SetReferencePoint(const VECTOR2I &aP)
virtual void Serialize(google::protobuf::Any &aContainer) const
Serializes this object to the given Any message.
Represent a set of closed polygons.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
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.
const wxString & GetMessages() const
A type-safe container of any type.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
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 std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
KICOMMON_API VECTOR3D UnpackVector3D(const types::Vector3D &aInput)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackBox2(types::Box2 &aOutput, const BOX2I &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackPolyLine(types::PolyLine &aOutput, const SHAPE_LINE_CHAIN &aSlc, const EDA_IU_SCALE &aScale)
Class to handle a set of BOARD_ITEMs.
std::vector< EDA_ITEM * > EDA_ITEMS
RequestMessageType Request
RATSNEST_MODE m_RatsnestMode
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