21#include <magic_enum.hpp>
73#include <api/common/types/base_types.pb.h>
82using namespace kiapi::common::commands;
83using types::CommandStatus;
84using types::DocumentType;
85using types::ItemRequestStatus;
173 if( aCtx.
Request.type() != DocumentType::DOCTYPE_PCB )
177 e.set_status( ApiStatusCode::AS_UNHANDLED );
178 return tl::unexpected( e );
181 GetOpenDocumentsResponse response;
182 common::types::DocumentSpecifier doc;
184 wxFileName fn(
pcbContext()->GetCurrentFileName() );
186 doc.set_type( DocumentType::DOCTYPE_PCB );
187 doc.set_board_filename( fn.GetFullName() );
189 doc.mutable_project()->set_name(
project().GetProjectName().ToStdString() );
190 doc.mutable_project()->set_path(
project().GetProjectDirectory().ToStdString() );
192 response.mutable_documents()->Add( std::move( doc ) );
200 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
201 return tl::unexpected( *busy );
205 if( !documentValidation )
206 return tl::unexpected( documentValidation.error() );
216 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
217 return tl::unexpected( *busy );
221 if( !documentValidation )
222 return tl::unexpected( documentValidation.error() );
224 wxFileName boardPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.path() ) ) );
226 if( !boardPath.IsOk() || !boardPath.IsDirWritable() )
229 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
230 e.set_error_message( fmt::format(
"save path '{}' could not be opened",
231 boardPath.GetFullPath().ToStdString() ) );
232 return tl::unexpected( e );
235 if( boardPath.FileExists()
236 && ( !boardPath.IsFileWritable() || !aCtx.
Request.options().overwrite() ) )
239 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
240 e.set_error_message( fmt::format(
"save path '{}' exists and cannot be overwritten",
241 boardPath.GetFullPath().ToStdString() ) );
242 return tl::unexpected( e );
248 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
249 e.set_error_message( fmt::format(
"save path '{}' must have a kicad_pcb extension",
250 boardPath.GetFullPath().ToStdString() ) );
251 return tl::unexpected( e );
256 if( board->
GetFileName().Matches( boardPath.GetFullPath() ) )
262 bool includeProject =
true;
264 if( aCtx.
Request.has_options() )
265 includeProject = aCtx.
Request.options().include_project();
276 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"RevertDocument" ) )
277 return tl::unexpected( *headless );
279 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
280 return tl::unexpected( *busy );
284 if( !documentValidation )
285 return tl::unexpected( documentValidation.error() );
299 if( aDocument.type() != DocumentType::DOCTYPE_PCB )
302 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
303 e.set_error_message(
"the requested document is not a board" );
304 return tl::unexpected( e );
307 wxFileName fn(
pcbContext()->GetCurrentFileName() );
309 if( aDocument.board_filename().compare( fn.GetFullName() ) != 0 )
312 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
313 e.set_error_message( fmt::format(
"the requested document {} is not open",
314 aDocument.board_filename() ) );
315 return tl::unexpected( e );
324 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
325 return tl::unexpected( *busy );
331 e.set_status( ApiStatusCode::AS_UNHANDLED );
332 return tl::unexpected( e );
335 GetItemsResponse response;
338 std::vector<BOARD_ITEM*> items;
339 std::set<KICAD_T> typesRequested, typesInserted;
340 bool handledAnything =
false;
344 typesRequested.emplace( type );
346 if( typesInserted.count( type ) )
354 handledAnything =
true;
355 std::copy(
board->Tracks().begin(),
board->Tracks().end(),
356 std::back_inserter( items ) );
362 handledAnything =
true;
366 std::copy( fp->Pads().begin(), fp->Pads().end(),
367 std::back_inserter( items ) );
376 handledAnything =
true;
378 std::copy(
board->Footprints().begin(),
board->Footprints().end(),
379 std::back_inserter( items ) );
391 handledAnything =
true;
392 bool inserted =
false;
396 if( item->Type() == type )
398 items.emplace_back( item );
404 typesInserted.insert( type );
411 handledAnything =
true;
412 bool inserted =
false;
416 switch (item->Type()) {
422 items.emplace_back( item );
440 handledAnything =
true;
442 std::copy(
board->Zones().begin(),
board->Zones().end(),
443 std::back_inserter( items ) );
451 handledAnything =
true;
453 std::copy(
board->Groups().begin(),
board->Groups().end(),
454 std::back_inserter( items ) );
464 if( !handledAnything )
467 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
468 e.set_error_message(
"none of the requested types are valid for a Board object" );
469 return tl::unexpected( e );
474 if( !typesRequested.count( item->Type() ) )
477 google::protobuf::Any itemBuf;
478 item->Serialize( itemBuf );
479 response.mutable_items()->Add( std::move( itemBuf ) );
482 response.set_status( ItemRequestStatus::IRS_OK );
492 if( !documentValidation )
493 return tl::unexpected( documentValidation.error() );
495 if( aCtx.
Request.copper_layer_count() % 2 != 0 )
498 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
499 e.set_error_message(
"copper_layer_count must be an even number" );
500 return tl::unexpected( e );
506 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
507 e.set_error_message( fmt::format(
"copper_layer_count must be below %d",
MAX_CU_LAYERS ) );
508 return tl::unexpected( e );
511 int copperLayerCount =
static_cast<int>( aCtx.
Request.copper_layer_count() );
516 enabled &=
~LSET::AllCuMask();
521 LSET previousEnabled =
board->GetEnabledLayers();
522 LSET changedLayers = enabled ^ previousEnabled;
524 board->SetEnabledLayers( enabled );
525 board->SetVisibleLayers(
board->GetVisibleLayers() | changedLayers );
531 if( !enabled[layer_id] &&
board->HasItemsOnLayer( layer_id ) )
532 removedLayers.push_back( layer_id );
535 bool modified =
false;
537 if( !removedLayers.empty() )
542 modified |=
board->RemoveAllItemsOnLayer( layer_id );
545 if( enabled != previousEnabled )
551 BoardEnabledLayersResponse response;
553 response.set_copper_layer_count( copperLayerCount );
565 if( !documentValidation )
566 return tl::unexpected( documentValidation.error() );
569 BoardDesignRulesResponse response;
570 kiapi::board::BoardDesignRules* rules = response.mutable_rules();
572 kiapi::board::MinimumConstraints* constraints = rules->mutable_constraints();
574 constraints->mutable_min_clearance()->set_value_nm( bds.
m_MinClearance );
575 constraints->mutable_min_groove_width()->set_value_nm( bds.
m_MinGrooveWidth );
576 constraints->mutable_min_connection_width()->set_value_nm( bds.
m_MinConn );
577 constraints->mutable_min_track_width()->set_value_nm( bds.
m_TrackMinWidth );
579 constraints->mutable_min_via_size()->set_value_nm( bds.
m_ViasMinSize );
584 constraints->mutable_hole_clearance()->set_value_nm( bds.
m_HoleClearance );
585 constraints->mutable_hole_to_hole_min()->set_value_nm( bds.
m_HoleToHoleMin );
586 constraints->mutable_silk_clearance()->set_value_nm( bds.
m_SilkClearance );
591 kiapi::board::PredefinedSizes* sizes = rules->mutable_predefined_sizes();
594 sizes->add_tracks()->mutable_width()->set_value_nm( bds.
m_TrackWidthList[ii] );
598 kiapi::board::PresetViaDimension*
via = sizes->add_vias();
605 kiapi::board::PresetDiffPairDimension* pair = sizes->add_diff_pairs();
611 kiapi::board::SolderMaskPasteDefaults* maskPaste = rules->mutable_solder_mask_paste();
620 kiapi::board::TeardropDefaults* teardrops = rules->mutable_teardrops();
633 kiapi::board::TeardropTargetEntry* entry = teardrops->add_target_params();
637 entry->mutable_params()->set_enabled( params->
m_Enabled );
638 entry->mutable_params()->mutable_max_length()->set_value_nm( params->
m_TdMaxLen );
639 entry->mutable_params()->mutable_max_width()->set_value_nm( params->
m_TdMaxWidth );
643 entry->mutable_params()->set_curved_edges( params->
m_CurvedEdges );
648 kiapi::board::ViaProtectionDefaults* viaProtection = rules->mutable_via_protection();
661 board::DrcSeveritySetting* setting = rules->add_severities();
662 setting->set_rule_type(
669 kiapi::board::DrcExclusion* exclusion = rules->add_exclusions();
670 exclusion->mutable_marker()->mutable_id()->set_opaque_id( serialized.ToStdString() );
675 exclusion->set_comment( it->second.ToStdString() );
678 response.set_custom_rules_status( CRS_NONE );
682 if( !rulesPath.IsEmpty() && wxFileName::IsFileReadable( rulesPath ) )
684 wxFFile file( rulesPath,
"r" );
686 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
688 if( !file.IsOpened() )
690 response.set_custom_rules_status( CRS_INVALID );
694 file.ReadAll( &content );
700 parser.
Parse( parsedRules,
nullptr );
701 response.set_custom_rules_status( CRS_VALID );
705 response.set_custom_rules_status( CRS_INVALID );
718 if( !documentValidation )
719 return tl::unexpected( documentValidation.error() );
722 const kiapi::board::BoardDesignRules& rules = aCtx.
Request.rules();
724 if( rules.has_constraints() )
726 const kiapi::board::MinimumConstraints& constraints = rules.constraints();
728 newSettings.
m_MinClearance = constraints.min_clearance().value_nm();
730 newSettings.
m_MinConn = constraints.min_connection_width().value_nm();
731 newSettings.
m_TrackMinWidth = constraints.min_track_width().value_nm();
733 newSettings.
m_ViasMinSize = constraints.min_via_size().value_nm();
739 newSettings.
m_HoleToHoleMin = constraints.hole_to_hole_min().value_nm();
746 if( rules.has_predefined_sizes() )
751 for(
const kiapi::board::PresetTrackWidth& track : rules.predefined_sizes().tracks() )
757 for(
const kiapi::board::PresetViaDimension&
via : rules.predefined_sizes().vias() )
760 static_cast<int>(
via.drill().value_nm() ) );
766 for(
const kiapi::board::PresetDiffPairDimension& pair : rules.predefined_sizes().diff_pairs() )
769 static_cast<int>( pair.width().value_nm() ),
770 static_cast<int>( pair.gap().value_nm() ),
771 static_cast<int>( pair.via_gap().value_nm() ) );
775 if( rules.has_solder_mask_paste() )
777 const kiapi::board::SolderMaskPasteDefaults& maskPaste = rules.solder_mask_paste();
785 maskPaste.allow_soldermask_bridges_in_footprints();
788 if( rules.has_teardrops() )
790 const kiapi::board::TeardropDefaults& teardrops = rules.teardrops();
798 for(
const kiapi::board::TeardropTargetEntry& entry : teardrops.target_params() )
800 if( entry.target() == kiapi::board::TeardropTarget::TDT_UNKNOWN )
808 params->
m_Enabled = entry.params().enabled();
809 params->
m_TdMaxLen = entry.params().max_length().value_nm();
810 params->
m_TdMaxWidth = entry.params().max_width().value_nm();
820 if( rules.has_via_protection() )
822 const kiapi::board::ViaProtectionDefaults& viaProtection = rules.via_protection();
830 newSettings.
m_CapVias = viaProtection.cap();
831 newSettings.
m_FillVias = viaProtection.fill();
834 if( rules.severities_size() > 0 )
838 for(
const kiapi::board::DrcSeveritySetting& severitySetting : rules.severities() )
846 if( !permitted.contains( setting ) )
849 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
850 e.set_error_message( fmt::format(
"DRC severity must be error, warning, or ignore" ) );
851 return tl::unexpected( e );
858 if( rules.exclusions_size() > 0 )
863 for(
const kiapi::board::DrcExclusion& exclusion : rules.exclusions() )
865 wxString serialized = wxString::FromUTF8( exclusion.marker().id().opaque_id() );
867 if( serialized.IsEmpty() )
870 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
871 e.set_error_message(
"DrcExclusion marker id must not be empty" );
872 return tl::unexpected( e );
880 std::vector<BOARD_DESIGN_SETTINGS::VALIDATION_ERROR> errors = newSettings.
ValidateDesignRules();
882 if( !errors.empty() )
887 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
888 e.set_error_message( fmt::format(
"Invalid board design rules: {}: {}",
891 return tl::unexpected( e );
914 if( !documentValidation )
915 return tl::unexpected( documentValidation.error() );
917 CustomRulesResponse response;
918 response.set_status( CRS_NONE );
922 if( rulesPath.IsEmpty() || !wxFileName::IsFileReadable( rulesPath ) )
925 wxFFile file( rulesPath,
"r" );
927 if( !file.IsOpened() )
929 response.set_status( CRS_INVALID );
930 response.set_error_text(
"Failed to open custom rules file" );
935 file.ReadAll( &content );
938 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
943 parser.
Parse( parsedRules,
nullptr );
947 response.set_status( CRS_INVALID );
948 response.set_error_text( ioe.
What().ToStdString() );
952 for(
const std::shared_ptr<DRC_RULE>& rule : parsedRules )
959 kiapi::board::CustomRule* customRule = response.add_rules();
961 if( rule->m_Condition )
962 customRule->set_condition( rule->m_Condition->GetExpression().ToUTF8() );
966 board::CustomRuleConstraint* constraintProto = customRule->add_constraints();
967 constraint.
ToProto( *constraintProto );
971 customRule->set_name( rule->m_Name.ToUTF8() );
973 if( rule->m_LayerSource.CmpNoCase( wxS(
"outer" ) ) == 0 )
975 customRule->set_layer_mode( kiapi::board::CRLM_OUTER );
977 else if( rule->m_LayerSource.CmpNoCase( wxS(
"inner" ) ) == 0 )
979 customRule->set_layer_mode( kiapi::board::CRLM_INNER );
981 else if( !rule->m_LayerSource.IsEmpty() )
987 customRule->set_single_layer(
992 if( !comment.IsEmpty() )
993 customRule->set_comments( comment );
996 response.set_status( CRS_VALID );
1006 if( !documentValidation )
1007 return tl::unexpected( documentValidation.error() );
1011 if( aCtx.
Request.rules_size() == 0 )
1013 if( wxFileName::FileExists( rulesPath ) )
1015 if( !wxRemoveFile( rulesPath ) )
1017 CustomRulesResponse response;
1018 response.set_status( CRS_INVALID );
1019 response.set_error_text(
"Failed to remove custom rules file" );
1024 CustomRulesResponse response;
1025 response.set_status( CRS_NONE );
1030 rulesText <<
"(version 2)\n";
1032 for(
const board::CustomRule& rule : aCtx.
Request.rules() )
1034 wxString serializationError;
1037 if( serializedRule.IsEmpty() )
1039 CustomRulesResponse response;
1040 response.set_status( CRS_INVALID );
1042 if( serializationError.IsEmpty() )
1043 response.set_error_text(
"Failed to serialize custom rule" );
1045 response.set_error_text( serializationError.ToUTF8() );
1050 rulesText <<
"\n" << serializedRule;
1056 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
1058 parser.
Parse( parsedRules,
nullptr );
1062 CustomRulesResponse response;
1063 response.set_status( CRS_INVALID );
1064 response.set_error_text( ioe.
What().ToStdString() );
1068 wxFFile file( rulesPath,
"w" );
1070 if( !file.IsOpened() )
1072 CustomRulesResponse response;
1073 response.set_status( CRS_INVALID );
1074 response.set_error_text(
"Failed to open custom rules file for writing" );
1078 if( !file.Write( rulesText ) )
1082 CustomRulesResponse response;
1083 response.set_status( CRS_INVALID );
1084 response.set_error_text(
"Failed to write custom rules file" );
1100 !documentValidation )
1102 return tl::unexpected( documentValidation.error() );
1121 ApiResponseStatus e;
1122 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1123 e.set_error_message(
"Unexpected origin type" );
1124 return tl::unexpected( e );
1128 types::Vector2 reply;
1136 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1137 return tl::unexpected( *busy );
1140 !documentValidation )
1142 return tl::unexpected( documentValidation.error() );
1153 frame()->CallAfter( [f, origin]()
1168 frame()->CallAfter( [f, origin]()
1180 ApiResponseStatus e;
1181 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1182 e.set_error_message(
"Unexpected origin type" );
1183 return tl::unexpected( e );
1195 !documentValidation )
1197 return tl::unexpected( documentValidation.error() );
1200 BoardLayerNameResponse response;
1204 response.set_name(
board()->GetLayerName(
id ) );
1259 if( !documentValidation )
1260 return tl::unexpected( documentValidation.error() );
1262 NetsResponse response;
1265 std::set<wxString> netclassFilter;
1267 for(
const std::string& nc : aCtx.
Request.netclass_filter() )
1268 netclassFilter.insert( wxString( nc.c_str(), wxConvUTF8 ) );
1274 if( !netclassFilter.empty() && nc )
1276 bool inClass =
false;
1278 for(
const wxString&
filter : netclassFilter )
1291 board::types::Net* netProto = response.add_nets();
1292 netProto->set_name( net->GetNetname() );
1293 netProto->mutable_code()->set_value( net->GetNetCode() );
1303 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1304 return tl::unexpected( *busy );
1308 ApiResponseStatus e;
1309 e.set_status( ApiStatusCode::AS_UNHANDLED );
1310 return tl::unexpected( e );
1314 const bool filterByType = aCtx.
Request.types_size() > 0;
1316 if( filterByType && types.empty() )
1318 ApiResponseStatus e;
1319 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1320 e.set_error_message(
"none of the requested types are valid for a Board object" );
1321 return tl::unexpected( e );
1324 std::set<KICAD_T> typeFilter( types.begin(), types.end() );
1325 std::vector<BOARD_CONNECTED_ITEM*> sourceItems;
1327 for(
const types::KIID&
id : aCtx.
Request.items() )
1329 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
1332 sourceItems.emplace_back( connected );
1336 if( sourceItems.empty() )
1338 ApiResponseStatus e;
1339 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1340 e.set_error_message(
"none of the requested IDs were found or valid connected items" );
1341 return tl::unexpected( e );
1344 GetItemsResponse response;
1346 std::set<KIID> insertedItems;
1352 if( filterByType && !typeFilter.contains( connected->Type() ) )
1355 if( !insertedItems.insert( connected->m_Uuid ).second )
1358 connected->Serialize( *response.add_items() );
1362 response.set_status( ItemRequestStatus::IRS_OK );
1370 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1371 return tl::unexpected( *busy );
1375 ApiResponseStatus e;
1376 e.set_status( ApiStatusCode::AS_UNHANDLED );
1377 return tl::unexpected( e );
1381 const bool filterByType = aCtx.
Request.types_size() > 0;
1383 if( filterByType && types.empty() )
1385 ApiResponseStatus e;
1386 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1387 e.set_error_message(
"none of the requested types are valid for a Board object" );
1388 return tl::unexpected( e );
1394 GetItemsResponse response;
1396 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
1397 std::set<KIID> insertedItems;
1401 for(
const board::types::Net& net : aCtx.
Request.nets() )
1410 if( !insertedItems.insert( item->m_Uuid ).second )
1413 item->Serialize( *response.add_items() );
1417 response.set_status( ItemRequestStatus::IRS_OK );
1425 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1426 return tl::unexpected( *busy );
1430 ApiResponseStatus e;
1431 e.set_status( ApiStatusCode::AS_UNHANDLED );
1432 return tl::unexpected( e );
1436 const bool filterByType = aCtx.
Request.types_size() > 0;
1438 if( filterByType && types.empty() )
1440 ApiResponseStatus e;
1441 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1442 e.set_error_message(
"none of the requested types are valid for a Board object" );
1443 return tl::unexpected( e );
1449 std::set<wxString> requestedClasses;
1451 for(
const std::string& netClass : aCtx.
Request.net_classes() )
1452 requestedClasses.insert( wxString( netClass.c_str(), wxConvUTF8 ) );
1454 GetItemsResponse response;
1456 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
1457 std::set<KIID> insertedItems;
1466 if( !requestedClasses.empty() )
1471 bool inClass =
false;
1473 for(
const wxString&
filter : requestedClasses )
1488 if( !insertedItems.insert( item->m_Uuid ).second )
1491 item->Serialize( *response.add_items() );
1495 response.set_status( ItemRequestStatus::IRS_OK );
1503 NetClassForNetsResponse response;
1507 google::protobuf::Any
any;
1509 for(
const board::types::Net& net : aCtx.
Request.net() )
1517 auto [pair, rc] = response.mutable_classes()->insert( { net.name(), {} } );
1518 any.UnpackTo( &pair->second );
1527 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1528 return tl::unexpected( *busy );
1532 if( !documentValidation )
1533 return tl::unexpected( documentValidation.error() );
1535 if( aCtx.
Request.zones().empty() )
1538 frame()->CallAfter( [mgr]()
1546 ApiResponseStatus e;
1547 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
1548 return tl::unexpected( e );
1557 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1558 return tl::unexpected( *busy );
1562 if( !documentValidation )
1563 return tl::unexpected( documentValidation.error() );
1565 wxFileName netlistPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.netlist_path() ) ) );
1567 if( !netlistPath.IsOk() || !netlistPath.FileExists() )
1569 ApiResponseStatus e;
1570 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1571 e.set_error_message(
1572 fmt::format(
"netlist file '{}' could not be opened", netlistPath.GetFullPath().ToStdString() ) );
1573 return tl::unexpected( e );
1579 const bool lookupByTimestamp = aCtx.
Request.match_mode() != NetlistMatchMode::NMM_REFERENCE;
1582 netlist.SetFindByTimeStamp( lookupByTimestamp );
1583 netlist.SetReplaceFootprints( aCtx.
Request.update_footprints() );
1587 ApiResponseStatus e;
1588 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1589 e.set_error_message( fmt::format(
"unable to handle netlist file '{}': {}",
1590 netlistPath.GetFullPath().ToStdString(),
1591 reporter.GetMessages().ToStdString() ) );
1592 return tl::unexpected( e );
1598 updater->SetIsDryRun( aCtx.
Request.dry_run() );
1599 updater->SetLookupByTimestamp( lookupByTimestamp );
1600 updater->SetDeleteUnusedFootprints( aCtx.
Request.delete_extra_footprints() );
1601 updater->SetReplaceFootprints( aCtx.
Request.update_footprints() );
1602 updater->SetTransferGroups( aCtx.
Request.transfer_groups() );
1603 updater->SetOverrideLocks( aCtx.
Request.override_locks() );
1604 updater->SetUpdateFields(
true );
1606 const bool success = updater->UpdateNetlist(
netlist );
1608 if( !aCtx.
Request.dry_run() && success )
1611 ImportNetlistResponse response;
1612 response.set_report(
reporter.GetMessages().ToUTF8() );
1613 response.set_error_count( updater->GetErrorCount() );
1614 response.set_warning_count( updater->GetWarningCount() );
1615 response.set_new_footprint_count( updater->GetNewFootprintCount() );
1623 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetBoardEditorAppearanceSettings" ) )
1624 return tl::unexpected( *headless );
1626 BoardEditorAppearanceSettings reply;
1634 reply.set_net_color_display(
1637 reply.set_board_flip(
frame()->GetCanvas()->GetView()->IsMirroredX()
1638 ? BoardFlipMode::BFM_FLIPPED_X
1639 : BoardFlipMode::BFM_NORMAL );
1653 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SetBoardEditorAppearanceSettings" ) )
1654 return tl::unexpected( *headless );
1656 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1657 return tl::unexpected( *busy );
1662 const BoardEditorAppearanceSettings& newSettings = aCtx.
Request.settings();
1669 bool flip = newSettings.board_flip() == BoardFlipMode::BFM_FLIPPED_X;
1691 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1692 return tl::unexpected( *busy );
1696 if( !documentValidation )
1697 return tl::unexpected( documentValidation.error() );
1705 drcItem->SetErrorMessage( wxString::FromUTF8( aCtx.
Request.message() ) );
1709 for(
const auto&
id : aCtx.
Request.items() )
1710 ids.emplace_back(
KIID(
id.value() ) );
1713 drcItem->SetItems( ids );
1715 const auto& pos = aCtx.
Request.position();
1716 VECTOR2I position(
static_cast<int>( pos.x_nm() ),
static_cast<int>( pos.y_nm() ) );
1721 commit->
Add( marker );
1722 commit->
Push( wxS(
"API injected DRC marker" ) );
1724 InjectDrcErrorResponse response;
1732 const std::string& aCommandName )
1734 if( aUnits == types::Units::U_INCH || aUnits == types::Units::U_MM
1735 || aUnits == types::Units::U_UNKNOWN )
1737 return std::nullopt;
1740 ApiResponseStatus e;
1741 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1742 e.set_error_message( fmt::format(
"{} supports only inch and mm units", aCommandName ) );
1747std::optional<ApiResponseStatus>
1749 const std::string& aCommandName )
1751 if( aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_UNKNOWN
1752 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_ALL_LAYERS_ONE_PAGE
1753 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_EACH_LAYER_OWN_FILE )
1755 return std::nullopt;
1758 ApiResponseStatus e;
1759 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1760 e.set_error_message( fmt::format(
"{} does not support EACH_LAYER_OWN_PAGE pagination mode",
1769 for(
int layer : aSettings.layers() )
1772 static_cast<board::types::BoardLayer
>( layer ) );
1776 ApiResponseStatus e;
1777 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1778 e.set_error_message(
"Board plot settings contain an invalid layer" );
1785 for(
int layer : aSettings.common_layers() )
1788 static_cast<board::types::BoardLayer
>( layer ) );
1792 ApiResponseStatus e;
1793 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1794 e.set_error_message(
"Board plot settings contain an invalid common layer" );
1801 aJob.
m_colorTheme = wxString::FromUTF8( aSettings.color_theme() );
1802 aJob.
m_drawingSheet = wxString::FromUTF8( aSettings.drawing_sheet() );
1803 aJob.
m_variant = wxString::FromUTF8( aSettings.variant() );
1805 aJob.
m_mirror = aSettings.mirror();
1808 aJob.
m_scale = aSettings.scale();
1816 aJob.
m_plotRefDes = aSettings.plot_reference_designators();
1826 return std::nullopt;
1832 types::RunJobResponse response;
1835 if( !aContext || !aContext->
GetKiway() )
1837 response.set_status( types::JobStatus::JS_ERROR );
1838 response.set_message(
"Internal error" );
1839 wxCHECK_MSG(
false, response,
"context missing valid kiway in ExecuteBoardJob?" );
1846 response.add_output_path(
output.m_outputPath.ToUTF8() );
1850 response.set_status( types::JobStatus::JS_SUCCESS );
1854 response.set_status( types::JobStatus::JS_ERROR );
1855 response.set_message( fmt::format(
"Board export job '{}' failed with exit code {}: {}",
1857 reporter.GetMessages().ToStdString() ) );
1865 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1866 return tl::unexpected( *busy );
1870 if( !documentValidation )
1871 return tl::unexpected( documentValidation.error() );
1924 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1925 return tl::unexpected( *busy );
1929 if( !documentValidation )
1930 return tl::unexpected( documentValidation.error() );
1972 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1973 return tl::unexpected( *busy );
1977 if( !documentValidation )
1978 return tl::unexpected( documentValidation.error() );
1985 return tl::unexpected( *err );
1990 if( std::optional<ApiResponseStatus> paginationError =
1992 "RunBoardJobExportSvg" ) )
1994 return tl::unexpected( *paginationError );
2006 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2007 return tl::unexpected( *busy );
2011 if( !documentValidation )
2012 return tl::unexpected( documentValidation.error() );
2019 return tl::unexpected( *err );
2024 if( std::optional<ApiResponseStatus> unitError =
2027 return tl::unexpected( *unitError );
2032 if( std::optional<ApiResponseStatus> paginationError =
2034 "RunBoardJobExportDxf" ) )
2036 return tl::unexpected( *paginationError );
2048 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2049 return tl::unexpected( *busy );
2053 if( !documentValidation )
2054 return tl::unexpected( documentValidation.error() );
2061 return tl::unexpected( *err );
2078 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2079 return tl::unexpected( *busy );
2083 if( !documentValidation )
2084 return tl::unexpected( documentValidation.error() );
2091 return tl::unexpected( *err );
2093 if( std::optional<ApiResponseStatus> paginationError =
2095 "RunBoardJobExportPs" ) )
2097 return tl::unexpected( *paginationError );
2115 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2116 return tl::unexpected( *busy );
2120 if( !documentValidation )
2121 return tl::unexpected( documentValidation.error() );
2123 if( aCtx.
Request.layers().empty() )
2125 ApiResponseStatus e;
2126 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2127 e.set_error_message(
"RunBoardJobExportGerbers requires at least one layer" );
2128 return tl::unexpected( e );
2135 for(
int layer : aCtx.
Request.layers() )
2139 static_cast<board::types::BoardLayer
>( layer ) );
2143 ApiResponseStatus e;
2144 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2145 e.set_error_message(
"RunBoardJobExportGerbers contains an invalid layer" );
2146 return tl::unexpected( e );
2159 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2160 return tl::unexpected( *busy );
2164 if( !documentValidation )
2165 return tl::unexpected( documentValidation.error() );
2173 if( std::optional<ApiResponseStatus> unitError =
2176 return tl::unexpected( *unitError );
2183 if( aCtx.
Request.has_excellon() )
2185 const ExcellonFormatOptions& excellonOptions = aCtx.
Request.excellon();
2187 if( excellonOptions.has_mirror_y() )
2190 if( excellonOptions.has_minimal_header() )
2193 if( excellonOptions.has_combine_pth_npth() )
2196 if( excellonOptions.has_route_oval_holes() )
2200 if( aCtx.
Request.map_format() != DrillMapFormat::DMF_UNKNOWN )
2208 if( aCtx.
Request.has_gerber_generate_tenting() )
2211 if( aCtx.
Request.report_format() != DrillReportFormat::DRF_UNKNOWN )
2215 if( aCtx.
Request.has_report_filename() )
2226 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2227 return tl::unexpected( *busy );
2231 if( !documentValidation )
2232 return tl::unexpected( documentValidation.error() );
2238 if( aCtx.
Request.has_use_drill_place_file_origin() )
2248 if( aCtx.
Request.has_include_board_edge_for_gerber() )
2255 if( std::optional<ApiResponseStatus> unitError =
2258 return tl::unexpected( *unitError );
2271 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2272 return tl::unexpected( *busy );
2276 if( !documentValidation )
2277 return tl::unexpected( documentValidation.error() );
2296 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2297 return tl::unexpected( *busy );
2301 if( !documentValidation )
2302 return tl::unexpected( documentValidation.error() );
2310 if( aCtx.
Request.has_precision() )
2315 job.
m_colMfgPn = wxString::FromUTF8( aCtx.
Request.manufacturer_part_number_column() );
2316 job.
m_colMfg = wxString::FromUTF8( aCtx.
Request.manufacturer_column() );
2317 job.
m_colDistPn = wxString::FromUTF8( aCtx.
Request.distributor_part_number_column() );
2321 if( std::optional<ApiResponseStatus> unitError =
2324 return tl::unexpected( *unitError );
2337 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2338 return tl::unexpected( *busy );
2342 if( !documentValidation )
2343 return tl::unexpected( documentValidation.error() );
2356 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2357 return tl::unexpected( *busy );
2361 if( !documentValidation )
2362 return tl::unexpected( documentValidation.error() );
2370 if( aCtx.
Request.has_precision() )
2373 if( std::optional<ApiResponseStatus> unitError =
2376 return tl::unexpected( *unitError );
2389 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2390 return tl::unexpected( *busy );
2394 if( !documentValidation )
2395 return tl::unexpected( documentValidation.error() );
2403 if( std::optional<ApiResponseStatus> unitError =
2406 return tl::unexpected( *unitError );
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
std::optional< ApiResponseStatus > ValidatePaginationModeForSingleOrPerFile(kiapi::board::jobs::BoardJobPaginationMode aMode, const std::string &aCommandName)
std::optional< ApiResponseStatus > ApplyBoardPlotSettings(const BoardPlotSettings &aSettings, JOB_EXPORT_PCB_PLOT &aJob)
std::optional< ApiResponseStatus > ValidateUnitsInchMm(types::Units aUnits, const std::string &aCommandName)
HANDLER_RESULT< types::RunJobResponse > ExecuteBoardJob(PCB_CONTEXT *aContext, JOB &aJob)
BASE_SCREEN class implementation.
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION gridSetOrigin
API_HANDLER_BOARD(std::shared_ptr< BOARD_CONTEXT > aContext, EDA_BASE_FRAME *aFrame=nullptr)
TOOL_MANAGER * toolManager() const
std::vector< KICAD_T > parseRequestedItemTypes(const google::protobuf::RepeatedField< int > &aTypes)
PROJECT & project() const
BOARD_CONTEXT * context() const
std::optional< ApiResponseStatus > checkForHeadless(const std::string &aCommandName) const
std::optional< BOARD_ITEM * > getItemById(const KIID &aId) const
HANDLER_RESULT< bool > validateDocument(const DocumentSpecifier &aDocument)
HANDLER_RESULT< types::PageSettings > handleSetPageSettings(const HANDLER_CONTEXT< commands::SetPageSettings > &aCtx)
HANDLER_RESULT< std::optional< KIID > > validateItemHeaderDocument(const kiapi::common::types::ItemHeader &aHeader)
If the header is valid, returns the item container.
HANDLER_RESULT< types::PageSettings > handleGetPageSettings(const HANDLER_CONTEXT< commands::GetPageSettings > &aCtx)
COMMIT * getCurrentCommit(const std::string &aClientName)
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
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.
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:
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