21#include <magic_enum.hpp>
78#include <api/common/types/base_types.pb.h>
87using namespace kiapi::common::commands;
88using types::CommandStatus;
89using types::DocumentType;
90using types::ItemRequestStatus;
178 if( aCtx.
Request.type() != DocumentType::DOCTYPE_PCB )
182 e.set_status( ApiStatusCode::AS_UNHANDLED );
183 return tl::unexpected( e );
186 GetOpenDocumentsResponse response;
187 common::types::DocumentSpecifier doc;
189 wxFileName fn(
pcbContext()->GetCurrentFileName() );
191 doc.set_type( DocumentType::DOCTYPE_PCB );
192 doc.set_board_filename( fn.GetFullName() );
194 doc.mutable_project()->set_name(
project().GetProjectName().ToStdString() );
195 doc.mutable_project()->set_path(
project().GetProjectDirectory().ToStdString() );
197 response.mutable_documents()->Add( std::move( doc ) );
205 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
206 return tl::unexpected( *busy );
210 if( !documentValidation )
211 return tl::unexpected( documentValidation.error() );
221 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
222 return tl::unexpected( *busy );
226 if( !documentValidation )
227 return tl::unexpected( documentValidation.error() );
229 wxFileName boardPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.path() ) ) );
231 if( !boardPath.IsOk() || !boardPath.IsDirWritable() )
234 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
235 e.set_error_message( fmt::format(
"save path '{}' could not be opened",
236 boardPath.GetFullPath().ToStdString() ) );
237 return tl::unexpected( e );
240 if( boardPath.FileExists()
241 && ( !boardPath.IsFileWritable() || !aCtx.
Request.options().overwrite() ) )
244 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
245 e.set_error_message( fmt::format(
"save path '{}' exists and cannot be overwritten",
246 boardPath.GetFullPath().ToStdString() ) );
247 return tl::unexpected( e );
253 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
254 e.set_error_message( fmt::format(
"save path '{}' must have a kicad_pcb extension",
255 boardPath.GetFullPath().ToStdString() ) );
256 return tl::unexpected( e );
261 if( board->
GetFileName().Matches( boardPath.GetFullPath() ) )
267 bool includeProject =
true;
269 if( aCtx.
Request.has_options() )
270 includeProject = aCtx.
Request.options().include_project();
281 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"RevertDocument" ) )
282 return tl::unexpected( *headless );
284 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
285 return tl::unexpected( *busy );
289 if( !documentValidation )
290 return tl::unexpected( documentValidation.error() );
304 if( aDocument.type() != DocumentType::DOCTYPE_PCB )
307 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
308 e.set_error_message(
"the requested document is not a board" );
309 return tl::unexpected( e );
312 wxFileName fn(
pcbContext()->GetCurrentFileName() );
314 if( aDocument.board_filename().compare( fn.GetFullName() ) != 0 )
317 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
318 e.set_error_message( fmt::format(
"the requested document {} is not open",
319 aDocument.board_filename() ) );
320 return tl::unexpected( e );
329 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
330 return tl::unexpected( *busy );
336 e.set_status( ApiStatusCode::AS_UNHANDLED );
337 return tl::unexpected( e );
340 GetItemsResponse response;
343 std::vector<BOARD_ITEM*> items;
344 std::set<KICAD_T> typesRequested, typesInserted;
345 bool handledAnything =
false;
349 typesRequested.emplace( type );
351 if( typesInserted.count( type ) )
359 handledAnything =
true;
360 std::copy(
board->Tracks().begin(),
board->Tracks().end(),
361 std::back_inserter( items ) );
367 handledAnything =
true;
371 std::copy( fp->Pads().begin(), fp->Pads().end(),
372 std::back_inserter( items ) );
381 handledAnything =
true;
383 std::copy(
board->Footprints().begin(),
board->Footprints().end(),
384 std::back_inserter( items ) );
396 handledAnything =
true;
397 bool inserted =
false;
401 if( item->Type() == type )
403 items.emplace_back( item );
409 typesInserted.insert( type );
416 handledAnything =
true;
417 bool inserted =
false;
421 switch (item->Type()) {
427 items.emplace_back( item );
445 handledAnything =
true;
447 std::copy(
board->Zones().begin(),
board->Zones().end(),
448 std::back_inserter( items ) );
456 handledAnything =
true;
458 std::copy(
board->Groups().begin(),
board->Groups().end(),
459 std::back_inserter( items ) );
469 if( !handledAnything )
472 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
473 e.set_error_message(
"none of the requested types are valid for a Board object" );
474 return tl::unexpected( e );
479 if( !typesRequested.count( item->Type() ) )
482 google::protobuf::Any itemBuf;
483 item->Serialize( itemBuf );
484 response.mutable_items()->Add( std::move( itemBuf ) );
487 response.set_status( ItemRequestStatus::IRS_OK );
497 if( !documentValidation )
498 return tl::unexpected( documentValidation.error() );
500 if( aCtx.
Request.copper_layer_count() % 2 != 0 )
503 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
504 e.set_error_message(
"copper_layer_count must be an even number" );
505 return tl::unexpected( e );
511 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
512 e.set_error_message( fmt::format(
"copper_layer_count must be below %d",
MAX_CU_LAYERS ) );
513 return tl::unexpected( e );
516 int copperLayerCount =
static_cast<int>( aCtx.
Request.copper_layer_count() );
521 enabled &=
~LSET::AllCuMask();
526 LSET previousEnabled =
board->GetEnabledLayers();
527 LSET changedLayers = enabled ^ previousEnabled;
529 board->SetEnabledLayers( enabled );
530 board->SetVisibleLayers(
board->GetVisibleLayers() | changedLayers );
536 if( !enabled[layer_id] &&
board->HasItemsOnLayer( layer_id ) )
537 removedLayers.push_back( layer_id );
540 bool modified =
false;
542 if( !removedLayers.empty() )
547 modified |=
board->RemoveAllItemsOnLayer( layer_id );
550 if( enabled != previousEnabled )
556 BoardEnabledLayersResponse response;
558 response.set_copper_layer_count( copperLayerCount );
570 if( !documentValidation )
571 return tl::unexpected( documentValidation.error() );
574 BoardDesignRulesResponse response;
575 kiapi::board::BoardDesignRules* rules = response.mutable_rules();
577 kiapi::board::MinimumConstraints* constraints = rules->mutable_constraints();
579 constraints->mutable_min_clearance()->set_value_nm( bds.
m_MinClearance );
580 constraints->mutable_min_groove_width()->set_value_nm( bds.
m_MinGrooveWidth );
581 constraints->mutable_min_connection_width()->set_value_nm( bds.
m_MinConn );
582 constraints->mutable_min_track_width()->set_value_nm( bds.
m_TrackMinWidth );
584 constraints->mutable_min_via_size()->set_value_nm( bds.
m_ViasMinSize );
589 constraints->mutable_hole_clearance()->set_value_nm( bds.
m_HoleClearance );
590 constraints->mutable_hole_to_hole_min()->set_value_nm( bds.
m_HoleToHoleMin );
591 constraints->mutable_silk_clearance()->set_value_nm( bds.
m_SilkClearance );
596 kiapi::board::PredefinedSizes* sizes = rules->mutable_predefined_sizes();
599 sizes->add_tracks()->mutable_width()->set_value_nm( bds.
m_TrackWidthList[ii] );
603 kiapi::board::PresetViaDimension*
via = sizes->add_vias();
610 kiapi::board::PresetDiffPairDimension* pair = sizes->add_diff_pairs();
616 kiapi::board::SolderMaskPasteDefaults* maskPaste = rules->mutable_solder_mask_paste();
625 kiapi::board::TeardropDefaults* teardrops = rules->mutable_teardrops();
638 kiapi::board::TeardropTargetEntry* entry = teardrops->add_target_params();
642 entry->mutable_params()->set_enabled( params->
m_Enabled );
643 entry->mutable_params()->mutable_max_length()->set_value_nm( params->
m_TdMaxLen );
644 entry->mutable_params()->mutable_max_width()->set_value_nm( params->
m_TdMaxWidth );
648 entry->mutable_params()->set_curved_edges( params->
m_CurvedEdges );
653 kiapi::board::ViaProtectionDefaults* viaProtection = rules->mutable_via_protection();
666 board::DrcSeveritySetting* setting = rules->add_severities();
667 setting->set_rule_type(
674 kiapi::board::DrcExclusion* exclusion = rules->add_exclusions();
675 exclusion->mutable_marker()->mutable_id()->set_opaque_id( serialized.ToStdString() );
680 exclusion->set_comment( it->second.ToStdString() );
683 response.set_custom_rules_status( CRS_NONE );
687 if( !rulesPath.IsEmpty() && wxFileName::IsFileReadable( rulesPath ) )
689 wxFFile file( rulesPath,
"r" );
691 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
693 if( !file.IsOpened() )
695 response.set_custom_rules_status( CRS_INVALID );
699 file.ReadAll( &content );
705 parser.
Parse( parsedRules,
nullptr );
706 response.set_custom_rules_status( CRS_VALID );
710 response.set_custom_rules_status( CRS_INVALID );
723 if( !documentValidation )
724 return tl::unexpected( documentValidation.error() );
727 const kiapi::board::BoardDesignRules& rules = aCtx.
Request.rules();
729 if( rules.has_constraints() )
731 const kiapi::board::MinimumConstraints& constraints = rules.constraints();
733 newSettings.
m_MinClearance = constraints.min_clearance().value_nm();
735 newSettings.
m_MinConn = constraints.min_connection_width().value_nm();
736 newSettings.
m_TrackMinWidth = constraints.min_track_width().value_nm();
738 newSettings.
m_ViasMinSize = constraints.min_via_size().value_nm();
744 newSettings.
m_HoleToHoleMin = constraints.hole_to_hole_min().value_nm();
751 if( rules.has_predefined_sizes() )
756 for(
const kiapi::board::PresetTrackWidth& track : rules.predefined_sizes().tracks() )
762 for(
const kiapi::board::PresetViaDimension&
via : rules.predefined_sizes().vias() )
765 static_cast<int>(
via.drill().value_nm() ) );
771 for(
const kiapi::board::PresetDiffPairDimension& pair : rules.predefined_sizes().diff_pairs() )
774 static_cast<int>( pair.width().value_nm() ),
775 static_cast<int>( pair.gap().value_nm() ),
776 static_cast<int>( pair.via_gap().value_nm() ) );
780 if( rules.has_solder_mask_paste() )
782 const kiapi::board::SolderMaskPasteDefaults& maskPaste = rules.solder_mask_paste();
790 maskPaste.allow_soldermask_bridges_in_footprints();
793 if( rules.has_teardrops() )
795 const kiapi::board::TeardropDefaults& teardrops = rules.teardrops();
803 for(
const kiapi::board::TeardropTargetEntry& entry : teardrops.target_params() )
805 if( entry.target() == kiapi::board::TeardropTarget::TDT_UNKNOWN )
813 params->
m_Enabled = entry.params().enabled();
814 params->
m_TdMaxLen = entry.params().max_length().value_nm();
815 params->
m_TdMaxWidth = entry.params().max_width().value_nm();
825 if( rules.has_via_protection() )
827 const kiapi::board::ViaProtectionDefaults& viaProtection = rules.via_protection();
835 newSettings.
m_CapVias = viaProtection.cap();
836 newSettings.
m_FillVias = viaProtection.fill();
839 if( rules.severities_size() > 0 )
843 for(
const kiapi::board::DrcSeveritySetting& severitySetting : rules.severities() )
851 if( !permitted.contains( setting ) )
854 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
855 e.set_error_message( fmt::format(
"DRC severity must be error, warning, or ignore" ) );
856 return tl::unexpected( e );
863 if( rules.exclusions_size() > 0 )
868 for(
const kiapi::board::DrcExclusion& exclusion : rules.exclusions() )
870 wxString serialized = wxString::FromUTF8( exclusion.marker().id().opaque_id() );
872 if( serialized.IsEmpty() )
875 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
876 e.set_error_message(
"DrcExclusion marker id must not be empty" );
877 return tl::unexpected( e );
885 std::vector<BOARD_DESIGN_SETTINGS::VALIDATION_ERROR> errors = newSettings.
ValidateDesignRules();
887 if( !errors.empty() )
892 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
893 e.set_error_message( fmt::format(
"Invalid board design rules: {}: {}",
896 return tl::unexpected( e );
919 if( !documentValidation )
920 return tl::unexpected( documentValidation.error() );
922 CustomRulesResponse response;
923 response.set_status( CRS_NONE );
927 if( rulesPath.IsEmpty() || !wxFileName::IsFileReadable( rulesPath ) )
930 wxFFile file( rulesPath,
"r" );
932 if( !file.IsOpened() )
934 response.set_status( CRS_INVALID );
935 response.set_error_text(
"Failed to open custom rules file" );
940 file.ReadAll( &content );
943 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
948 parser.
Parse( parsedRules,
nullptr );
952 response.set_status( CRS_INVALID );
953 response.set_error_text( ioe.
What().ToStdString() );
957 for(
const std::shared_ptr<DRC_RULE>& rule : parsedRules )
964 kiapi::board::CustomRule* customRule = response.add_rules();
966 if( rule->m_Condition )
967 customRule->set_condition( rule->m_Condition->GetExpression().ToUTF8() );
971 board::CustomRuleConstraint* constraintProto = customRule->add_constraints();
972 constraint.
ToProto( *constraintProto );
976 customRule->set_name( rule->m_Name.ToUTF8() );
978 if( rule->m_LayerSource.CmpNoCase( wxS(
"outer" ) ) == 0 )
980 customRule->set_layer_mode( kiapi::board::CRLM_OUTER );
982 else if( rule->m_LayerSource.CmpNoCase( wxS(
"inner" ) ) == 0 )
984 customRule->set_layer_mode( kiapi::board::CRLM_INNER );
986 else if( !rule->m_LayerSource.IsEmpty() )
992 customRule->set_single_layer(
997 if( !comment.IsEmpty() )
998 customRule->set_comments( comment );
1001 response.set_status( CRS_VALID );
1011 if( !documentValidation )
1012 return tl::unexpected( documentValidation.error() );
1016 if( aCtx.
Request.rules_size() == 0 )
1018 if( wxFileName::FileExists( rulesPath ) )
1020 if( !wxRemoveFile( rulesPath ) )
1022 CustomRulesResponse response;
1023 response.set_status( CRS_INVALID );
1024 response.set_error_text(
"Failed to remove custom rules file" );
1029 CustomRulesResponse response;
1030 response.set_status( CRS_NONE );
1035 rulesText <<
"(version 2)\n";
1037 for(
const board::CustomRule& rule : aCtx.
Request.rules() )
1039 wxString serializationError;
1042 if( serializedRule.IsEmpty() )
1044 CustomRulesResponse response;
1045 response.set_status( CRS_INVALID );
1047 if( serializationError.IsEmpty() )
1048 response.set_error_text(
"Failed to serialize custom rule" );
1050 response.set_error_text( serializationError.ToUTF8() );
1055 rulesText <<
"\n" << serializedRule;
1061 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
1063 parser.
Parse( parsedRules,
nullptr );
1067 CustomRulesResponse response;
1068 response.set_status( CRS_INVALID );
1069 response.set_error_text( ioe.
What().ToStdString() );
1073 wxFFile file( rulesPath,
"w" );
1075 if( !file.IsOpened() )
1077 CustomRulesResponse response;
1078 response.set_status( CRS_INVALID );
1079 response.set_error_text(
"Failed to open custom rules file for writing" );
1083 if( !file.Write( rulesText ) )
1087 CustomRulesResponse response;
1088 response.set_status( CRS_INVALID );
1089 response.set_error_text(
"Failed to write custom rules file" );
1105 !documentValidation )
1107 return tl::unexpected( documentValidation.error() );
1126 ApiResponseStatus e;
1127 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1128 e.set_error_message(
"Unexpected origin type" );
1129 return tl::unexpected( e );
1133 types::Vector2 reply;
1141 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1142 return tl::unexpected( *busy );
1145 !documentValidation )
1147 return tl::unexpected( documentValidation.error() );
1158 frame()->CallAfter( [f, origin]()
1173 frame()->CallAfter( [f, origin]()
1185 ApiResponseStatus e;
1186 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1187 e.set_error_message(
"Unexpected origin type" );
1188 return tl::unexpected( e );
1200 !documentValidation )
1202 return tl::unexpected( documentValidation.error() );
1205 BoardLayerNameResponse response;
1209 response.set_name(
board()->GetLayerName(
id ) );
1264 if( !documentValidation )
1265 return tl::unexpected( documentValidation.error() );
1267 NetsResponse response;
1270 std::set<wxString> netclassFilter;
1272 for(
const std::string& nc : aCtx.
Request.netclass_filter() )
1273 netclassFilter.insert( wxString( nc.c_str(), wxConvUTF8 ) );
1279 if( !netclassFilter.empty() && nc )
1281 bool inClass =
false;
1283 for(
const wxString&
filter : netclassFilter )
1296 board::types::Net* netProto = response.add_nets();
1297 netProto->set_name( net->GetNetname() );
1298 netProto->mutable_code()->set_value( net->GetNetCode() );
1308 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1309 return tl::unexpected( *busy );
1313 ApiResponseStatus e;
1314 e.set_status( ApiStatusCode::AS_UNHANDLED );
1315 return tl::unexpected( e );
1319 const bool filterByType = aCtx.
Request.types_size() > 0;
1321 if( filterByType && types.empty() )
1323 ApiResponseStatus e;
1324 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1325 e.set_error_message(
"none of the requested types are valid for a Board object" );
1326 return tl::unexpected( e );
1329 std::set<KICAD_T> typeFilter( types.begin(), types.end() );
1330 std::vector<BOARD_CONNECTED_ITEM*> sourceItems;
1332 for(
const types::KIID&
id : aCtx.
Request.items() )
1334 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
1337 sourceItems.emplace_back( connected );
1341 if( sourceItems.empty() )
1343 ApiResponseStatus e;
1344 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1345 e.set_error_message(
"none of the requested IDs were found or valid connected items" );
1346 return tl::unexpected( e );
1349 GetItemsResponse response;
1351 std::set<KIID> insertedItems;
1357 if( filterByType && !typeFilter.contains( connected->Type() ) )
1360 if( !insertedItems.insert( connected->m_Uuid ).second )
1363 connected->Serialize( *response.add_items() );
1367 response.set_status( ItemRequestStatus::IRS_OK );
1375 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1376 return tl::unexpected( *busy );
1380 ApiResponseStatus e;
1381 e.set_status( ApiStatusCode::AS_UNHANDLED );
1382 return tl::unexpected( e );
1386 const bool filterByType = aCtx.
Request.types_size() > 0;
1388 if( filterByType && types.empty() )
1390 ApiResponseStatus e;
1391 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1392 e.set_error_message(
"none of the requested types are valid for a Board object" );
1393 return tl::unexpected( e );
1399 GetItemsResponse response;
1401 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
1402 std::set<KIID> insertedItems;
1406 for(
const board::types::Net& net : aCtx.
Request.nets() )
1415 if( !insertedItems.insert( item->m_Uuid ).second )
1418 item->Serialize( *response.add_items() );
1422 response.set_status( ItemRequestStatus::IRS_OK );
1430 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1431 return tl::unexpected( *busy );
1435 ApiResponseStatus e;
1436 e.set_status( ApiStatusCode::AS_UNHANDLED );
1437 return tl::unexpected( e );
1441 const bool filterByType = aCtx.
Request.types_size() > 0;
1443 if( filterByType && types.empty() )
1445 ApiResponseStatus e;
1446 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1447 e.set_error_message(
"none of the requested types are valid for a Board object" );
1448 return tl::unexpected( e );
1454 std::set<wxString> requestedClasses;
1456 for(
const std::string& netClass : aCtx.
Request.net_classes() )
1457 requestedClasses.insert( wxString( netClass.c_str(), wxConvUTF8 ) );
1459 GetItemsResponse response;
1461 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
1462 std::set<KIID> insertedItems;
1471 if( !requestedClasses.empty() )
1476 bool inClass =
false;
1478 for(
const wxString&
filter : requestedClasses )
1493 if( !insertedItems.insert( item->m_Uuid ).second )
1496 item->Serialize( *response.add_items() );
1500 response.set_status( ItemRequestStatus::IRS_OK );
1508 NetClassForNetsResponse response;
1512 google::protobuf::Any
any;
1514 for(
const board::types::Net& net : aCtx.
Request.net() )
1522 auto [pair, rc] = response.mutable_classes()->insert( { net.name(), {} } );
1523 any.UnpackTo( &pair->second );
1532 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1533 return tl::unexpected( *busy );
1537 if( !documentValidation )
1538 return tl::unexpected( documentValidation.error() );
1547 if( aCtx.
Request.zones().empty() )
1551 frame()->CallAfter( [mgr]()
1565 std::vector<ZONE*> toFill;
1567 for(
const types::KIID&
id : aCtx.
Request.zones() )
1571 if( !item || ( *item )->Type() !=
PCB_ZONE_T )
1573 ApiResponseStatus e;
1574 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1575 e.set_error_message( fmt::format(
"zone with ID {} not found on the board",
id.value() ) );
1576 return tl::unexpected( e );
1579 ZONE* zone =
static_cast<ZONE*
>( *item );
1584 ApiResponseStatus e;
1585 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1586 e.set_error_message( fmt::format(
"zone with ID {} is a rule area and cannot be filled",
1588 return tl::unexpected( e );
1593 toFill.push_back( zone );
1599 if( !filler.
Fill( toFill ) )
1603 ApiResponseStatus e;
1604 e.set_status( ApiStatusCode::AS_UNKNOWN );
1605 e.set_error_message(
"zone fill failed" );
1606 return tl::unexpected( e );
1621 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1622 return tl::unexpected( *busy );
1626 if( !documentValidation )
1627 return tl::unexpected( documentValidation.error() );
1629 wxFileName netlistPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.netlist_path() ) ) );
1631 if( !netlistPath.IsOk() || !netlistPath.FileExists() )
1633 ApiResponseStatus e;
1634 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1635 e.set_error_message(
1636 fmt::format(
"netlist file '{}' could not be opened", netlistPath.GetFullPath().ToStdString() ) );
1637 return tl::unexpected( e );
1643 const bool lookupByTimestamp = aCtx.
Request.match_mode() != NetlistMatchMode::NMM_REFERENCE;
1646 netlist.SetFindByTimeStamp( lookupByTimestamp );
1647 netlist.SetReplaceFootprints( aCtx.
Request.update_footprints() );
1651 ApiResponseStatus e;
1652 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1653 e.set_error_message( fmt::format(
"unable to handle netlist file '{}': {}",
1654 netlistPath.GetFullPath().ToStdString(),
1655 reporter.GetMessages().ToStdString() ) );
1656 return tl::unexpected( e );
1662 updater->SetIsDryRun( aCtx.
Request.dry_run() );
1663 updater->SetLookupByTimestamp( lookupByTimestamp );
1664 updater->SetDeleteUnusedFootprints( aCtx.
Request.delete_extra_footprints() );
1665 updater->SetReplaceFootprints( aCtx.
Request.update_footprints() );
1666 updater->SetTransferGroups( aCtx.
Request.transfer_groups() );
1667 updater->SetOverrideLocks( aCtx.
Request.override_locks() );
1668 updater->SetUpdateFields(
true );
1670 const bool success = updater->UpdateNetlist(
netlist );
1672 if( !aCtx.
Request.dry_run() && success )
1675 ImportNetlistResponse response;
1676 response.set_report(
reporter.GetMessages().ToUTF8() );
1677 response.set_error_count( updater->GetErrorCount() );
1678 response.set_warning_count( updater->GetWarningCount() );
1679 response.set_new_footprint_count( updater->GetNewFootprintCount() );
1687 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetBoardEditorAppearanceSettings" ) )
1688 return tl::unexpected( *headless );
1690 BoardEditorAppearanceSettings reply;
1698 reply.set_net_color_display(
1701 reply.set_board_flip(
frame()->GetCanvas()->GetView()->IsMirroredX()
1702 ? BoardFlipMode::BFM_FLIPPED_X
1703 : BoardFlipMode::BFM_NORMAL );
1717 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SetBoardEditorAppearanceSettings" ) )
1718 return tl::unexpected( *headless );
1720 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1721 return tl::unexpected( *busy );
1726 const BoardEditorAppearanceSettings& newSettings = aCtx.
Request.settings();
1733 bool flip = newSettings.board_flip() == BoardFlipMode::BFM_FLIPPED_X;
1755 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1756 return tl::unexpected( *busy );
1760 if( !documentValidation )
1761 return tl::unexpected( documentValidation.error() );
1769 drcItem->SetErrorMessage( wxString::FromUTF8( aCtx.
Request.message() ) );
1773 for(
const auto&
id : aCtx.
Request.items() )
1774 ids.emplace_back(
KIID(
id.value() ) );
1777 drcItem->SetItems( ids );
1779 const auto& pos = aCtx.
Request.position();
1780 VECTOR2I position(
static_cast<int>( pos.x_nm() ),
static_cast<int>( pos.y_nm() ) );
1785 commit->
Add( marker );
1786 commit->
Push( wxS(
"API injected DRC marker" ) );
1788 InjectDrcErrorResponse response;
1796 const std::string& aCommandName )
1798 if( aUnits == types::Units::U_INCH || aUnits == types::Units::U_MM
1799 || aUnits == types::Units::U_UNKNOWN )
1801 return std::nullopt;
1804 ApiResponseStatus e;
1805 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1806 e.set_error_message( fmt::format(
"{} supports only inch and mm units", aCommandName ) );
1811std::optional<ApiResponseStatus>
1813 const std::string& aCommandName )
1815 if( aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_UNKNOWN
1816 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_ALL_LAYERS_ONE_PAGE
1817 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_EACH_LAYER_OWN_FILE )
1819 return std::nullopt;
1822 ApiResponseStatus e;
1823 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1824 e.set_error_message( fmt::format(
"{} does not support EACH_LAYER_OWN_PAGE pagination mode",
1833 for(
int layer : aSettings.layers() )
1836 static_cast<board::types::BoardLayer
>( layer ) );
1840 ApiResponseStatus e;
1841 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1842 e.set_error_message(
"Board plot settings contain an invalid layer" );
1849 for(
int layer : aSettings.common_layers() )
1852 static_cast<board::types::BoardLayer
>( layer ) );
1856 ApiResponseStatus e;
1857 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1858 e.set_error_message(
"Board plot settings contain an invalid common layer" );
1865 aJob.
m_colorTheme = wxString::FromUTF8( aSettings.color_theme() );
1866 aJob.
m_drawingSheet = wxString::FromUTF8( aSettings.drawing_sheet() );
1867 aJob.
m_variant = wxString::FromUTF8( aSettings.variant() );
1869 aJob.
m_mirror = aSettings.mirror();
1872 aJob.
m_scale = aSettings.scale();
1880 aJob.
m_plotRefDes = aSettings.plot_reference_designators();
1890 return std::nullopt;
1896 types::RunJobResponse response;
1899 if( !aContext || !aContext->
GetKiway() )
1901 response.set_status( types::JobStatus::JS_ERROR );
1902 response.set_message(
"Internal error" );
1903 wxCHECK_MSG(
false, response,
"context missing valid kiway in ExecuteBoardJob?" );
1910 response.add_output_path(
output.m_outputPath.ToUTF8() );
1914 response.set_status( types::JobStatus::JS_SUCCESS );
1918 response.set_status( types::JobStatus::JS_ERROR );
1919 response.set_message( fmt::format(
"Board export job '{}' failed with exit code {}: {}",
1921 reporter.GetMessages().ToStdString() ) );
1929 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1930 return tl::unexpected( *busy );
1934 if( !documentValidation )
1935 return tl::unexpected( documentValidation.error() );
1988 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1989 return tl::unexpected( *busy );
1993 if( !documentValidation )
1994 return tl::unexpected( documentValidation.error() );
2036 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2037 return tl::unexpected( *busy );
2041 if( !documentValidation )
2042 return tl::unexpected( documentValidation.error() );
2049 return tl::unexpected( *err );
2054 if( std::optional<ApiResponseStatus> paginationError =
2056 "RunBoardJobExportSvg" ) )
2058 return tl::unexpected( *paginationError );
2070 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2071 return tl::unexpected( *busy );
2075 if( !documentValidation )
2076 return tl::unexpected( documentValidation.error() );
2083 return tl::unexpected( *err );
2088 if( std::optional<ApiResponseStatus> unitError =
2091 return tl::unexpected( *unitError );
2096 if( std::optional<ApiResponseStatus> paginationError =
2098 "RunBoardJobExportDxf" ) )
2100 return tl::unexpected( *paginationError );
2112 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2113 return tl::unexpected( *busy );
2117 if( !documentValidation )
2118 return tl::unexpected( documentValidation.error() );
2125 return tl::unexpected( *err );
2142 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2143 return tl::unexpected( *busy );
2147 if( !documentValidation )
2148 return tl::unexpected( documentValidation.error() );
2155 return tl::unexpected( *err );
2157 if( std::optional<ApiResponseStatus> paginationError =
2159 "RunBoardJobExportPs" ) )
2161 return tl::unexpected( *paginationError );
2179 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2180 return tl::unexpected( *busy );
2184 if( !documentValidation )
2185 return tl::unexpected( documentValidation.error() );
2187 if( aCtx.
Request.layers().empty() )
2189 ApiResponseStatus e;
2190 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2191 e.set_error_message(
"RunBoardJobExportGerbers requires at least one layer" );
2192 return tl::unexpected( e );
2199 for(
int layer : aCtx.
Request.layers() )
2203 static_cast<board::types::BoardLayer
>( layer ) );
2207 ApiResponseStatus e;
2208 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2209 e.set_error_message(
"RunBoardJobExportGerbers contains an invalid layer" );
2210 return tl::unexpected( e );
2223 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2224 return tl::unexpected( *busy );
2228 if( !documentValidation )
2229 return tl::unexpected( documentValidation.error() );
2237 if( std::optional<ApiResponseStatus> unitError =
2240 return tl::unexpected( *unitError );
2247 if( aCtx.
Request.has_excellon() )
2249 const ExcellonFormatOptions& excellonOptions = aCtx.
Request.excellon();
2251 if( excellonOptions.has_mirror_y() )
2254 if( excellonOptions.has_minimal_header() )
2257 if( excellonOptions.has_combine_pth_npth() )
2260 if( excellonOptions.has_route_oval_holes() )
2264 if( aCtx.
Request.map_format() != DrillMapFormat::DMF_UNKNOWN )
2272 if( aCtx.
Request.has_gerber_generate_tenting() )
2275 if( aCtx.
Request.report_format() != DrillReportFormat::DRF_UNKNOWN )
2279 if( aCtx.
Request.has_report_filename() )
2290 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2291 return tl::unexpected( *busy );
2295 if( !documentValidation )
2296 return tl::unexpected( documentValidation.error() );
2302 if( aCtx.
Request.has_use_drill_place_file_origin() )
2312 if( aCtx.
Request.has_include_board_edge_for_gerber() )
2319 if( std::optional<ApiResponseStatus> unitError =
2322 return tl::unexpected( *unitError );
2335 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2336 return tl::unexpected( *busy );
2340 if( !documentValidation )
2341 return tl::unexpected( documentValidation.error() );
2360 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2361 return tl::unexpected( *busy );
2365 if( !documentValidation )
2366 return tl::unexpected( documentValidation.error() );
2374 if( aCtx.
Request.has_precision() )
2379 job.
m_colMfgPn = wxString::FromUTF8( aCtx.
Request.manufacturer_part_number_column() );
2380 job.
m_colMfg = wxString::FromUTF8( aCtx.
Request.manufacturer_column() );
2381 job.
m_colDistPn = wxString::FromUTF8( aCtx.
Request.distributor_part_number_column() );
2385 if( std::optional<ApiResponseStatus> unitError =
2388 return tl::unexpected( *unitError );
2401 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2402 return tl::unexpected( *busy );
2406 if( !documentValidation )
2407 return tl::unexpected( documentValidation.error() );
2420 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2421 return tl::unexpected( *busy );
2425 if( !documentValidation )
2426 return tl::unexpected( documentValidation.error() );
2434 if( aCtx.
Request.has_precision() )
2437 if( std::optional<ApiResponseStatus> unitError =
2440 return tl::unexpected( *unitError );
2453 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2454 return tl::unexpected( *busy );
2458 if( !documentValidation )
2459 return tl::unexpected( documentValidation.error() );
2467 if( std::optional<ApiResponseStatus> unitError =
2470 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.
#define SKIP_CONNECTIVITY
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)
std::unique_ptr< COMMIT > createCommit() override
Override this to create an appropriate COMMIT subclass for the frame in question.
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.
HANDLER_RESULT< ImportNetlistResponse > handleImportNetlist(const HANDLER_CONTEXT< ImportNetlist > &aCtx)
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
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
wxString GetDesignRulesPath() const
Return the absolute path to the design rules file for this board.
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
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
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 void OnNetlistChanged(BOARD_NETLIST_UPDATER &aUpdater)=0
Post-import board sync (nets, classes, DRC, ratsnest, new footprint placement).
virtual bool ReadNetlistFromFile(const wxString &aFilename, NETLIST &aNetlist, REPORTER &aReporter)=0
Read a netlist file and preload component footprints.
virtual bool SavePcbCopy(const wxString &aFileName, bool aCreateProject, bool aHeadless)=0
virtual std::unique_ptr< BOARD_NETLIST_UPDATER > MakeNetlistUpdater()=0
Create a netlist updater bound to this context's board.
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.
bool Fill(const std::vector< ZONE * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Fills the given list of zones.
Handle a list of polygons defining a copper zone.
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
A type-safe container of any type.
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:
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
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