21#include <magic_enum.hpp>
31#include <api/common/commands/library_commands.pb.h>
90#include <api/common/types/base_types.pb.h>
91#include <api/board/board_rules.pb.h>
93#include <google/protobuf/util/json_util.h>
102using namespace kiapi::common::commands;
103using namespace kiapi::board::commands;
104using types::CommandStatus;
105using types::DocumentType;
106using types::ItemRequestStatus;
219 if( aCtx.
Request.type() != DocumentType::DOCTYPE_PCB )
223 e.set_status( ApiStatusCode::AS_UNHANDLED );
224 return tl::unexpected( e );
227 GetOpenDocumentsResponse response;
228 common::types::DocumentSpecifier doc;
230 wxFileName fn(
pcbContext()->GetCurrentFileName() );
232 doc.set_type( DocumentType::DOCTYPE_PCB );
233 doc.set_board_filename( fn.GetFullName() );
238 response.mutable_documents()->Add( std::move( doc ) );
246 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
247 return tl::unexpected( *busy );
251 if( !documentValidation )
252 return tl::unexpected( documentValidation.error() );
262 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
263 return tl::unexpected( *busy );
267 if( !documentValidation )
268 return tl::unexpected( documentValidation.error() );
270 wxFileName boardPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.path() ) ) );
272 if( !boardPath.IsOk() || !boardPath.IsDirWritable() )
275 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
276 e.set_error_message( fmt::format(
"save path '{}' could not be opened",
277 boardPath.GetFullPath().ToStdString() ) );
278 return tl::unexpected( e );
281 if( boardPath.FileExists()
282 && ( !boardPath.IsFileWritable() || !aCtx.
Request.options().overwrite() ) )
285 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
286 e.set_error_message( fmt::format(
"save path '{}' exists and cannot be overwritten",
287 boardPath.GetFullPath().ToStdString() ) );
288 return tl::unexpected( e );
294 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
295 e.set_error_message( fmt::format(
"save path '{}' must have a kicad_pcb extension",
296 boardPath.GetFullPath().ToStdString() ) );
297 return tl::unexpected( e );
302 if( board->
GetFileName().Matches( boardPath.GetFullPath() ) )
308 bool includeProject =
true;
310 if( aCtx.
Request.has_options() )
311 includeProject = aCtx.
Request.options().include_project();
325 if( !documentValidation )
326 return tl::unexpected( documentValidation.error() );
333 e.set_status( ApiStatusCode::AS_BUSY );
334 e.set_error_message(
"cannot revert while a commit is open" );
335 return tl::unexpected( e );
338 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
339 return tl::unexpected( *busy );
344 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
345 e.set_error_message(
"could not revert: there is no saved file on disk to revert to" );
346 return tl::unexpected( e );
355 if( aDocument.type() != DocumentType::DOCTYPE_PCB )
358 e.set_status( ApiStatusCode::AS_UNHANDLED );
359 return tl::unexpected( e );
362 wxFileName fn(
pcbContext()->GetCurrentFileName() );
364 if( aDocument.board_filename().compare( fn.GetFullName() ) != 0 )
367 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
368 e.set_error_message( fmt::format(
"the requested document {} is not open",
369 aDocument.board_filename() ) );
370 return tl::unexpected( e );
401 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
402 return tl::unexpected( *busy );
408 e.set_status( ApiStatusCode::AS_UNHANDLED );
409 return tl::unexpected( e );
412 GetItemsResponse response;
415 std::vector<BOARD_ITEM*> items;
416 std::set<KICAD_T> typesRequested, typesInserted;
417 bool handledAnything =
false;
421 if( aCtx.
Request.types().empty() )
424 for(
KICAD_T type : requestedTypes )
426 typesRequested.emplace( type );
428 if( typesInserted.count( type ) )
436 handledAnything =
true;
437 std::copy(
board->Tracks().begin(),
board->Tracks().end(),
438 std::back_inserter( items ) );
444 handledAnything =
true;
448 std::copy( fp->Pads().begin(), fp->Pads().end(),
449 std::back_inserter( items ) );
458 handledAnything =
true;
460 std::copy(
board->Footprints().begin(),
board->Footprints().end(),
461 std::back_inserter( items ) );
475 handledAnything =
true;
476 bool inserted =
false;
480 if( item->Type() == type )
482 items.emplace_back( item );
488 typesInserted.insert( type );
495 handledAnything =
true;
496 bool inserted =
false;
500 switch (item->Type()) {
506 items.emplace_back( item );
524 handledAnything =
true;
526 std::copy(
board->Zones().begin(),
board->Zones().end(),
527 std::back_inserter( items ) );
535 handledAnything =
true;
537 std::copy(
board->Groups().begin(),
board->Groups().end(),
538 std::back_inserter( items ) );
546 handledAnything =
true;
547 std::copy(
board->Points().begin(),
board->Points().end(), std::back_inserter( items ) );
554 handledAnything =
true;
556 std::copy(
board->Constraints().begin(),
board->Constraints().end(),
557 std::back_inserter( items ) );
568 if( !handledAnything )
571 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
572 e.set_error_message(
"none of the requested types are valid for a Board object" );
573 return tl::unexpected( e );
578 if( !typesRequested.count( item->Type() ) )
581 google::protobuf::Any itemBuf;
582 item->Serialize( itemBuf );
583 response.mutable_items()->Add( std::move( itemBuf ) );
586 response.set_status( ItemRequestStatus::IRS_OK );
596 if( !documentValidation )
597 return tl::unexpected( documentValidation.error() );
599 if( aCtx.
Request.copper_layer_count() % 2 != 0 )
602 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
603 e.set_error_message(
"copper_layer_count must be an even number" );
604 return tl::unexpected( e );
610 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
611 e.set_error_message( fmt::format(
"copper_layer_count must be below %d",
MAX_CU_LAYERS ) );
612 return tl::unexpected( e );
615 int copperLayerCount =
static_cast<int>( aCtx.
Request.copper_layer_count() );
620 enabled &=
~LSET::AllCuMask();
625 LSET previousEnabled =
board->GetEnabledLayers();
626 LSET changedLayers = enabled ^ previousEnabled;
628 board->SetEnabledLayers( enabled );
629 board->SetVisibleLayers(
board->GetVisibleLayers() | changedLayers );
635 if( !enabled[layer_id] &&
board->HasItemsOnLayer( layer_id ) )
636 removedLayers.push_back( layer_id );
639 bool modified =
false;
641 if( !removedLayers.empty() )
646 modified |=
board->RemoveAllItemsOnLayer( layer_id );
651 if( enabled != previousEnabled )
658 BoardEnabledLayersResponse response;
660 response.set_copper_layer_count( copperLayerCount );
671 return tl::unexpected( documentValidation.error() );
673 common::types::EmbeddedFiles response;
684 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
685 e.set_error_message(
"embedded file validation failed" );
686 return tl::unexpected( e );
695 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
696 return tl::unexpected( *busy );
699 return tl::unexpected( documentValidation.error() );
709 for(
const std::shared_ptr<EMBEDDED_FILES::EMBEDDED_FILE>& file : files.
EmbeddedFileMap() | std::views::values )
711 auto copy = std::make_shared<EMBEDDED_FILES::EMBEDDED_FILE>( *file );
722 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
723 return tl::unexpected( *busy );
726 return tl::unexpected( documentValidation.error() );
744 if( !documentValidation )
745 return tl::unexpected( documentValidation.error() );
748 BoardDesignRulesResponse response;
749 kiapi::board::BoardDesignRules* rules = response.mutable_rules();
751 kiapi::board::MinimumConstraints* constraints = rules->mutable_constraints();
753 constraints->mutable_min_clearance()->set_value_nm( bds.
m_MinClearance );
754 constraints->mutable_min_groove_width()->set_value_nm( bds.
m_MinGrooveWidth );
755 constraints->mutable_min_connection_width()->set_value_nm( bds.
m_MinConn );
756 constraints->mutable_min_track_width()->set_value_nm( bds.
m_TrackMinWidth );
758 constraints->mutable_min_via_size()->set_value_nm( bds.
m_ViasMinSize );
763 constraints->mutable_hole_clearance()->set_value_nm( bds.
m_HoleClearance );
764 constraints->mutable_hole_to_hole_min()->set_value_nm( bds.
m_HoleToHoleMin );
765 constraints->mutable_silk_clearance()->set_value_nm( bds.
m_SilkClearance );
770 kiapi::board::PredefinedSizes* sizes = rules->mutable_predefined_sizes();
773 sizes->add_tracks()->mutable_width()->set_value_nm( bds.
m_TrackWidthList[ii] );
777 kiapi::board::PresetViaDimension*
via = sizes->add_vias();
784 kiapi::board::PresetDiffPairDimension* pair = sizes->add_diff_pairs();
790 kiapi::board::SolderMaskPasteDefaults* maskPaste = rules->mutable_solder_mask_paste();
799 kiapi::board::TeardropDefaults* teardrops = rules->mutable_teardrops();
812 kiapi::board::TeardropTargetEntry* entry = teardrops->add_target_params();
816 entry->mutable_params()->set_enabled( params->
m_Enabled );
817 entry->mutable_params()->mutable_max_length()->set_value_nm( params->
m_TdMaxLen );
818 entry->mutable_params()->mutable_max_width()->set_value_nm( params->
m_TdMaxWidth );
822 entry->mutable_params()->set_curved_edges( params->
m_CurvedEdges );
827 kiapi::board::ViaProtectionDefaults* viaProtection = rules->mutable_via_protection();
840 board::DrcSeveritySetting* setting = rules->add_severities();
841 setting->set_rule_type(
847 rules->add_exclusions()->CopyFrom( exclusion.
ToProto() );
849 response.set_custom_rules_status( CRS_NONE );
853 if( !rulesPath.IsEmpty() && wxFileName::IsFileReadable( rulesPath ) )
855 wxFFile file( rulesPath,
"r" );
857 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
859 if( !file.IsOpened() )
861 response.set_custom_rules_status( CRS_INVALID );
865 file.ReadAll( &content );
871 parser.
Parse( parsedRules,
nullptr );
872 response.set_custom_rules_status( CRS_VALID );
876 response.set_custom_rules_status( CRS_INVALID );
889 if( !documentValidation )
890 return tl::unexpected( documentValidation.error() );
893 const kiapi::board::BoardDesignRules& rules = aCtx.
Request.rules();
895 if( rules.has_constraints() )
897 const kiapi::board::MinimumConstraints& constraints = rules.constraints();
899 newSettings.
m_MinClearance = constraints.min_clearance().value_nm();
901 newSettings.
m_MinConn = constraints.min_connection_width().value_nm();
902 newSettings.
m_TrackMinWidth = constraints.min_track_width().value_nm();
904 newSettings.
m_ViasMinSize = constraints.min_via_size().value_nm();
910 newSettings.
m_HoleToHoleMin = constraints.hole_to_hole_min().value_nm();
917 if( rules.has_predefined_sizes() )
922 for(
const kiapi::board::PresetTrackWidth& track : rules.predefined_sizes().tracks() )
928 for(
const kiapi::board::PresetViaDimension&
via : rules.predefined_sizes().vias() )
931 static_cast<int>(
via.drill().value_nm() ) );
937 for(
const kiapi::board::PresetDiffPairDimension& pair : rules.predefined_sizes().diff_pairs() )
940 static_cast<int>( pair.width().value_nm() ),
941 static_cast<int>( pair.gap().value_nm() ),
942 static_cast<int>( pair.via_gap().value_nm() ) );
946 if( rules.has_solder_mask_paste() )
948 const kiapi::board::SolderMaskPasteDefaults& maskPaste = rules.solder_mask_paste();
956 maskPaste.allow_soldermask_bridges_in_footprints();
959 if( rules.has_teardrops() )
961 const kiapi::board::TeardropDefaults& teardrops = rules.teardrops();
969 for(
const kiapi::board::TeardropTargetEntry& entry : teardrops.target_params() )
971 if( entry.target() == kiapi::board::TeardropTarget::TDT_UNKNOWN )
979 params->
m_Enabled = entry.params().enabled();
980 params->
m_TdMaxLen = entry.params().max_length().value_nm();
981 params->
m_TdMaxWidth = entry.params().max_width().value_nm();
991 if( rules.has_via_protection() )
993 const kiapi::board::ViaProtectionDefaults& viaProtection = rules.via_protection();
1001 newSettings.
m_CapVias = viaProtection.cap();
1002 newSettings.
m_FillVias = viaProtection.fill();
1005 if( rules.severities_size() > 0 )
1009 for(
const kiapi::board::DrcSeveritySetting& severitySetting : rules.severities() )
1017 if( !permitted.contains( setting ) )
1019 ApiResponseStatus e;
1020 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1021 e.set_error_message( fmt::format(
"DRC severity must be error, warning, or ignore" ) );
1022 return tl::unexpected( e );
1029 if( rules.exclusions_size() > 0 )
1033 for(
const kiapi::board::DrcExclusion& exclusion : rules.exclusions() )
1037 std::vector<BOARD_DESIGN_SETTINGS::VALIDATION_ERROR> errors = newSettings.
ValidateDesignRules();
1039 if( !errors.empty() )
1043 ApiResponseStatus e;
1044 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1045 e.set_error_message( fmt::format(
"Invalid board design rules: {}: {}",
1048 return tl::unexpected( e );
1071 if( !documentValidation )
1072 return tl::unexpected( documentValidation.error() );
1074 CustomRulesResponse response;
1075 response.set_status( CRS_NONE );
1079 if( rulesPath.IsEmpty() || !wxFileName::IsFileReadable( rulesPath ) )
1082 wxFFile file( rulesPath,
"r" );
1084 if( !file.IsOpened() )
1086 response.set_status( CRS_INVALID );
1087 response.set_error_text(
"Failed to open custom rules file" );
1092 file.ReadAll( &content );
1095 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
1100 parser.
Parse( parsedRules,
nullptr );
1104 response.set_status( CRS_INVALID );
1105 response.set_error_text( ioe.
What().ToStdString() );
1109 for(
const std::shared_ptr<DRC_RULE>& rule : parsedRules )
1116 kiapi::board::CustomRule* customRule = response.add_rules();
1118 if( rule->m_Condition )
1119 customRule->set_condition( rule->m_Condition->GetExpression().ToUTF8() );
1123 board::CustomRuleConstraint* constraintProto = customRule->add_constraints();
1124 constraint.
ToProto( *constraintProto );
1128 customRule->set_name( rule->m_Name.ToUTF8() );
1130 if( rule->m_LayerSource.CmpNoCase( wxS(
"outer" ) ) == 0 )
1132 customRule->set_layer_mode( kiapi::board::CRLM_OUTER );
1134 else if( rule->m_LayerSource.CmpNoCase( wxS(
"inner" ) ) == 0 )
1136 customRule->set_layer_mode( kiapi::board::CRLM_INNER );
1138 else if( !rule->m_LayerSource.IsEmpty() )
1144 customRule->set_single_layer(
1149 if( !comment.IsEmpty() )
1150 customRule->set_comments( comment );
1153 response.set_status( CRS_VALID );
1163 if( !documentValidation )
1164 return tl::unexpected( documentValidation.error() );
1168 if( aCtx.
Request.rules_size() == 0 )
1170 if( wxFileName::FileExists( rulesPath ) )
1172 if( !wxRemoveFile( rulesPath ) )
1174 CustomRulesResponse response;
1175 response.set_status( CRS_INVALID );
1176 response.set_error_text(
"Failed to remove custom rules file" );
1181 CustomRulesResponse response;
1182 response.set_status( CRS_NONE );
1187 rulesText <<
"(version 2)\n";
1189 for(
const board::CustomRule& rule : aCtx.
Request.rules() )
1191 wxString serializationError;
1194 if( serializedRule.IsEmpty() )
1196 CustomRulesResponse response;
1197 response.set_status( CRS_INVALID );
1199 if( serializationError.IsEmpty() )
1200 response.set_error_text(
"Failed to serialize custom rule" );
1202 response.set_error_text( serializationError.ToUTF8() );
1207 rulesText <<
"\n" << serializedRule;
1213 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
1215 parser.
Parse( parsedRules,
nullptr );
1219 CustomRulesResponse response;
1220 response.set_status( CRS_INVALID );
1221 response.set_error_text( ioe.
What().ToStdString() );
1225 wxFFile file( rulesPath,
"w" );
1227 if( !file.IsOpened() )
1229 CustomRulesResponse response;
1230 response.set_status( CRS_INVALID );
1231 response.set_error_text(
"Failed to open custom rules file for writing" );
1235 if( !file.Write( rulesText ) )
1239 CustomRulesResponse response;
1240 response.set_status( CRS_INVALID );
1241 response.set_error_text(
"Failed to write custom rules file" );
1257 !documentValidation )
1259 return tl::unexpected( documentValidation.error() );
1278 ApiResponseStatus e;
1279 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1280 e.set_error_message(
"Unexpected origin type" );
1281 return tl::unexpected( e );
1285 types::Vector2 reply;
1293 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1294 return tl::unexpected( *busy );
1297 !documentValidation )
1299 return tl::unexpected( documentValidation.error() );
1355 ApiResponseStatus e;
1356 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1357 e.set_error_message(
"Unexpected origin type" );
1358 return tl::unexpected( e );
1370 !documentValidation )
1372 return tl::unexpected( documentValidation.error() );
1375 BoardLayerNameResponse response;
1379 response.set_name(
board()->GetLayerName(
id ) );
1389 !documentValidation )
1391 return tl::unexpected( documentValidation.error() );
1394 BoardLayerResponse response;
1454 return tl::unexpected( documentValidation.error() );
1456 GetDocumentModifiedStateResponse response;
1457 response.set_state(
pcbContext()->IsContentModified() ? DocumentModifiedState::DMS_MODIFIED
1458 : DocumentModifiedState::DMS_UNMODIFIED );
1467 if( !documentValidation )
1468 return tl::unexpected( documentValidation.error() );
1470 NetsResponse response;
1473 std::set<wxString> netclassFilter;
1475 for(
const std::string& nc : aCtx.
Request.netclass_filter() )
1476 netclassFilter.insert( wxString( nc.c_str(), wxConvUTF8 ) );
1482 if( !netclassFilter.empty() && nc )
1484 bool inClass =
false;
1486 for(
const wxString&
filter : netclassFilter )
1499 board::types::Net* netProto = response.add_nets();
1500 netProto->set_name( net->GetNetname() );
1501 netProto->mutable_code()->set_value( net->GetNetCode() );
1511 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1512 return tl::unexpected( *busy );
1516 ApiResponseStatus e;
1517 e.set_status( ApiStatusCode::AS_UNHANDLED );
1518 return tl::unexpected( e );
1522 const bool filterByType = aCtx.
Request.types_size() > 0;
1524 if( filterByType &&
types.empty() )
1526 ApiResponseStatus e;
1527 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1528 e.set_error_message(
"none of the requested types are valid for a Board object" );
1529 return tl::unexpected( e );
1532 std::set<KICAD_T> typeFilter(
types.begin(),
types.end() );
1533 std::vector<BOARD_CONNECTED_ITEM*> sourceItems;
1535 for(
const types::KIID&
id : aCtx.
Request.items() )
1537 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
1540 sourceItems.emplace_back( connected );
1544 if( sourceItems.empty() )
1546 ApiResponseStatus e;
1547 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1548 e.set_error_message(
"none of the requested IDs were found or valid connected items" );
1549 return tl::unexpected( e );
1552 GetItemsResponse response;
1554 std::set<KIID> insertedItems;
1560 if( filterByType && !typeFilter.contains( connected->Type() ) )
1563 if( !insertedItems.insert( connected->m_Uuid ).second )
1566 connected->Serialize( *response.add_items() );
1570 response.set_status( ItemRequestStatus::IRS_OK );
1578 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1579 return tl::unexpected( *busy );
1583 ApiResponseStatus e;
1584 e.set_status( ApiStatusCode::AS_UNHANDLED );
1585 return tl::unexpected( e );
1589 const bool filterByType = aCtx.
Request.types_size() > 0;
1591 if( filterByType &&
types.empty() )
1593 ApiResponseStatus e;
1594 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1595 e.set_error_message(
"none of the requested types are valid for a Board object" );
1596 return tl::unexpected( e );
1602 GetItemsResponse response;
1604 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
1605 std::set<KIID> insertedItems;
1609 for(
const board::types::Net& net : aCtx.
Request.nets() )
1618 if( !insertedItems.insert( item->m_Uuid ).second )
1621 item->Serialize( *response.add_items() );
1625 response.set_status( ItemRequestStatus::IRS_OK );
1633 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1634 return tl::unexpected( *busy );
1638 ApiResponseStatus e;
1639 e.set_status( ApiStatusCode::AS_UNHANDLED );
1640 return tl::unexpected( e );
1644 const bool filterByType = aCtx.
Request.types_size() > 0;
1646 if( filterByType &&
types.empty() )
1648 ApiResponseStatus e;
1649 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1650 e.set_error_message(
"none of the requested types are valid for a Board object" );
1651 return tl::unexpected( e );
1657 std::set<wxString> requestedClasses;
1659 for(
const std::string& netClass : aCtx.
Request.net_classes() )
1660 requestedClasses.insert( wxString( netClass.c_str(), wxConvUTF8 ) );
1662 GetItemsResponse response;
1664 std::shared_ptr<CONNECTIVITY_DATA> conn =
board->GetConnectivity();
1665 std::set<KIID> insertedItems;
1674 if( !requestedClasses.empty() )
1679 bool inClass =
false;
1681 for(
const wxString&
filter : requestedClasses )
1696 if( !insertedItems.insert( item->m_Uuid ).second )
1699 item->Serialize( *response.add_items() );
1703 response.set_status( ItemRequestStatus::IRS_OK );
1711 NetClassForNetsResponse response;
1715 for(
const board::types::Net& net : aCtx.
Request.net() )
1722 auto [pair, rc] = response.mutable_classes()->insert( { net.name(), {} } );
1732 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1733 return tl::unexpected( *busy );
1737 if( !documentValidation )
1738 return tl::unexpected( documentValidation.error() );
1747 if( aCtx.
Request.zones().empty() )
1751 frame()->CallAfter( [mgr]()
1765 std::vector<ZONE*> toFill;
1767 for(
const types::KIID&
id : aCtx.
Request.zones() )
1771 if( !item || ( *item )->Type() !=
PCB_ZONE_T )
1773 ApiResponseStatus e;
1774 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1775 e.set_error_message( fmt::format(
"zone with ID {} not found on the board",
id.value() ) );
1776 return tl::unexpected( e );
1779 ZONE* zone =
static_cast<ZONE*
>( *item );
1784 ApiResponseStatus e;
1785 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1786 e.set_error_message( fmt::format(
"zone with ID {} is a rule area and cannot be filled",
1788 return tl::unexpected( e );
1793 toFill.push_back( zone );
1799 if( !filler.
Fill( toFill ) )
1803 ApiResponseStatus e;
1804 e.set_status( ApiStatusCode::AS_UNKNOWN );
1805 e.set_error_message(
"zone fill failed" );
1806 return tl::unexpected( e );
1821 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1822 return tl::unexpected( *busy );
1826 if( !documentValidation )
1827 return tl::unexpected( documentValidation.error() );
1829 wxFileName netlistPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.netlist_path() ) ) );
1831 if( !netlistPath.IsOk() || !netlistPath.FileExists() )
1833 ApiResponseStatus e;
1834 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1835 e.set_error_message(
1836 fmt::format(
"netlist file '{}' could not be opened", netlistPath.GetFullPath().ToStdString() ) );
1837 return tl::unexpected( e );
1843 const bool lookupByTimestamp = aCtx.
Request.match_mode() != NetlistMatchMode::NMM_REFERENCE;
1846 netlist.SetFindByTimeStamp( lookupByTimestamp );
1847 netlist.SetReplaceFootprints( aCtx.
Request.update_footprints() );
1851 ApiResponseStatus e;
1852 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1853 e.set_error_message( fmt::format(
"unable to handle netlist file '{}': {}",
1854 netlistPath.GetFullPath().ToStdString(),
1855 reporter.GetMessages().ToStdString() ) );
1856 return tl::unexpected( e );
1862 updater->SetIsDryRun( aCtx.
Request.dry_run() );
1863 updater->SetLookupByTimestamp( lookupByTimestamp );
1864 updater->SetDeleteUnusedFootprints( aCtx.
Request.delete_extra_footprints() );
1865 updater->SetReplaceFootprints( aCtx.
Request.update_footprints() );
1866 updater->SetTransferGroups( aCtx.
Request.transfer_groups() );
1867 updater->SetOverrideLocks( aCtx.
Request.override_locks() );
1868 updater->SetUpdateFields(
true );
1870 const bool success = updater->UpdateNetlist(
netlist );
1872 if( !aCtx.
Request.dry_run() && success )
1875 ImportNetlistResponse response;
1876 response.set_report(
reporter.GetMessages().ToUTF8() );
1877 response.set_error_count( updater->GetErrorCount() );
1878 response.set_warning_count( updater->GetWarningCount() );
1879 response.set_new_footprint_count( updater->GetNewFootprintCount() );
1887 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetBoardEditorAppearanceSettings" ) )
1888 return tl::unexpected( *headless );
1890 BoardEditorAppearanceSettings reply;
1898 reply.set_net_color_display(
1901 reply.set_board_flip(
frame()->GetCanvas()->GetView()->IsMirroredX()
1902 ? BoardFlipMode::BFM_FLIPPED_X
1903 : BoardFlipMode::BFM_NORMAL );
1917 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SetBoardEditorAppearanceSettings" ) )
1918 return tl::unexpected( *headless );
1920 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1921 return tl::unexpected( *busy );
1925 const BoardEditorAppearanceSettings& newSettings = aCtx.
Request.settings();
1931 options.
m_FlipBoardView = newSettings.board_flip() == BoardFlipMode::BFM_FLIPPED_X;
1949 if( !documentValidation )
1950 return tl::unexpected( documentValidation.error() );
1954 BoardPlotSettingsResponse response;
1955 BoardPlotSettings* settings = response.mutable_plot_settings();
1962 settings->set_mirror( plotOpts.
GetMirror() );
1965 settings->set_scale( plotOpts.
GetScale() );
1972 settings->set_plot_footprint_values( plotOpts.
GetPlotValue() );
1987 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1988 return tl::unexpected( *busy );
1992 if( !documentValidation )
1993 return tl::unexpected( documentValidation.error() );
1995 const BoardPlotSettings& settings = aCtx.
Request.plot_settings();
2002 for(
int layer : settings.common_layers() )
2009 ApiResponseStatus e;
2010 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2011 e.set_error_message( fmt::format(
"SetBoardPlotSettings contains an invalid layer {}",
2012 magic_enum::enum_name( layerId ) ) );
2013 return tl::unexpected( e );
2016 commonLayers.push_back( layerId );
2021 plotOpts.
SetMirror( settings.mirror() );
2024 plotOpts.
SetScale( settings.scale() );
2031 plotOpts.
SetPlotValue( settings.plot_footprint_values() );
2052 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2053 return tl::unexpected( *busy );
2057 if( !documentValidation )
2058 return tl::unexpected( documentValidation.error() );
2066 drcItem->SetErrorMessage( wxString::FromUTF8( aCtx.
Request.message() ) );
2070 for(
const auto&
id : aCtx.
Request.items() )
2071 ids.emplace_back(
KIID(
id.value() ) );
2074 drcItem->SetItems( ids );
2076 const auto& pos = aCtx.
Request.position();
2077 VECTOR2I position(
static_cast<int>( pos.x_nm() ),
static_cast<int>( pos.y_nm() ) );
2082 commit->
Add( marker );
2083 commit->
Push( wxS(
"API injected DRC marker" ) );
2085 InjectDrcErrorResponse response;
2093 const std::string& aCommandName )
2095 if( aUnits == types::Units::U_INCH || aUnits == types::Units::U_MM
2096 || aUnits == types::Units::U_UNKNOWN )
2098 return std::nullopt;
2101 ApiResponseStatus e;
2102 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2103 e.set_error_message( fmt::format(
"{} supports only inch and mm units", aCommandName ) );
2108std::optional<ApiResponseStatus>
2110 const std::string& aCommandName )
2112 if( aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_UNKNOWN
2113 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_ALL_LAYERS_ONE_PAGE
2114 || aMode == kiapi::board::jobs::BoardJobPaginationMode::BJPM_EACH_LAYER_OWN_FILE )
2116 return std::nullopt;
2119 ApiResponseStatus e;
2120 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2121 e.set_error_message( fmt::format(
"{} does not support EACH_LAYER_OWN_PAGE pagination mode",
2130 for(
int layer : aSettings.layers() )
2133 static_cast<board::types::BoardLayer
>( layer ) );
2137 ApiResponseStatus e;
2138 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2139 e.set_error_message(
"Board plot settings contain an invalid layer" );
2146 for(
int layer : aSettings.common_layers() )
2149 static_cast<board::types::BoardLayer
>( layer ) );
2153 ApiResponseStatus e;
2154 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2155 e.set_error_message(
"Board plot settings contain an invalid common layer" );
2162 aJob.
m_colorTheme = wxString::FromUTF8( aSettings.color_theme() );
2163 aJob.
m_drawingSheet = wxString::FromUTF8( aSettings.drawing_sheet() );
2164 aJob.
m_variant = wxString::FromUTF8( aSettings.variant() );
2166 aJob.
m_mirror = aSettings.mirror();
2169 aJob.
m_scale = aSettings.scale();
2177 aJob.
m_plotRefDes = aSettings.plot_reference_designators();
2187 return std::nullopt;
2193 types::RunJobResponse response;
2196 if( !aContext || !aContext->
GetKiway() )
2198 response.set_status( types::JobStatus::JS_ERROR );
2199 response.set_message(
"Internal error" );
2200 wxCHECK_MSG(
false, response,
"context missing valid kiway in ExecuteBoardJob?" );
2207 response.add_output_path( output.m_outputPath.ToUTF8() );
2211 response.set_status( types::JobStatus::JS_SUCCESS );
2215 response.set_status( types::JobStatus::JS_ERROR );
2216 response.set_message( fmt::format(
"Board export job '{}' failed with exit code {}: {}",
2218 reporter.GetMessages().ToStdString() ) );
2226 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2227 return tl::unexpected( *busy );
2231 if( !documentValidation )
2232 return tl::unexpected( documentValidation.error() );
2285 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2286 return tl::unexpected( *busy );
2290 if( !documentValidation )
2291 return tl::unexpected( documentValidation.error() );
2333 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2334 return tl::unexpected( *busy );
2338 if( !documentValidation )
2339 return tl::unexpected( documentValidation.error() );
2346 return tl::unexpected( *err );
2351 if( std::optional<ApiResponseStatus> paginationError =
2353 "RunBoardJobExportSvg" ) )
2355 return tl::unexpected( *paginationError );
2367 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2368 return tl::unexpected( *busy );
2372 if( !documentValidation )
2373 return tl::unexpected( documentValidation.error() );
2380 return tl::unexpected( *err );
2385 if( std::optional<ApiResponseStatus> unitError =
2388 return tl::unexpected( *unitError );
2393 if( std::optional<ApiResponseStatus> paginationError =
2395 "RunBoardJobExportDxf" ) )
2397 return tl::unexpected( *paginationError );
2409 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2410 return tl::unexpected( *busy );
2414 if( !documentValidation )
2415 return tl::unexpected( documentValidation.error() );
2422 return tl::unexpected( *err );
2439 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2440 return tl::unexpected( *busy );
2444 if( !documentValidation )
2445 return tl::unexpected( documentValidation.error() );
2452 return tl::unexpected( *err );
2454 if( std::optional<ApiResponseStatus> paginationError =
2456 "RunBoardJobExportPs" ) )
2458 return tl::unexpected( *paginationError );
2476 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2477 return tl::unexpected( *busy );
2480 return tl::unexpected( validation.error() );
2487 return tl::unexpected( *err );
2489 if( std::optional<ApiResponseStatus> paginationError =
2492 return tl::unexpected( *paginationError );
2503 ApiResponseStatus status;
2504 status.set_status( ApiStatusCode::AS_BAD_REQUEST );
2506 return tl::unexpected( status );
2522 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2523 return tl::unexpected( *busy );
2527 if( !documentValidation )
2528 return tl::unexpected( documentValidation.error() );
2539 return tl::unexpected( *err );
2548 switch( aCtx.
Request.precision() )
2551 case GerberPrecision::GP_5: job.
m_precision = 5;
break;
2552 case GerberPrecision::GP_6: job.
m_precision = 6;
break;
2562 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2563 return tl::unexpected( *busy );
2567 if( !documentValidation )
2568 return tl::unexpected( documentValidation.error() );
2576 if( std::optional<ApiResponseStatus> unitError =
2579 return tl::unexpected( *unitError );
2586 if( aCtx.
Request.has_excellon() )
2588 const ExcellonFormatOptions& excellonOptions = aCtx.
Request.excellon();
2590 if( excellonOptions.has_mirror_y() )
2593 if( excellonOptions.has_minimal_header() )
2596 if( excellonOptions.has_combine_pth_npth() )
2599 if( excellonOptions.has_route_oval_holes() )
2603 if( aCtx.
Request.map_format() != DrillMapFormat::DMF_UNKNOWN )
2611 if( aCtx.
Request.has_gerber_generate_tenting() )
2614 if( aCtx.
Request.report_format() != DrillReportFormat::DRF_UNKNOWN )
2618 if( aCtx.
Request.has_report_filename() )
2629 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2630 return tl::unexpected( *busy );
2634 if( !documentValidation )
2635 return tl::unexpected( documentValidation.error() );
2641 if( aCtx.
Request.has_use_drill_place_file_origin() )
2651 if( aCtx.
Request.has_include_board_edge_for_gerber() )
2658 if( std::optional<ApiResponseStatus> unitError =
2661 return tl::unexpected( *unitError );
2674 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2675 return tl::unexpected( *busy );
2679 if( !documentValidation )
2680 return tl::unexpected( documentValidation.error() );
2699 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2700 return tl::unexpected( *busy );
2704 if( !documentValidation )
2705 return tl::unexpected( documentValidation.error() );
2713 if( aCtx.
Request.has_precision() )
2718 job.
m_colMfgPn = wxString::FromUTF8( aCtx.
Request.manufacturer_part_number_column() );
2719 job.
m_colMfg = wxString::FromUTF8( aCtx.
Request.manufacturer_column() );
2720 job.
m_colDistPn = wxString::FromUTF8( aCtx.
Request.distributor_part_number_column() );
2724 if( std::optional<ApiResponseStatus> unitError =
2727 return tl::unexpected( *unitError );
2740 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2741 return tl::unexpected( *busy );
2745 if( !documentValidation )
2746 return tl::unexpected( documentValidation.error() );
2759 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2760 return tl::unexpected( *busy );
2764 if( !documentValidation )
2765 return tl::unexpected( documentValidation.error() );
2773 if( aCtx.
Request.has_precision() )
2776 if( std::optional<ApiResponseStatus> unitError =
2779 return tl::unexpected( *unitError );
2792 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2793 return tl::unexpected( *busy );
2797 if( !documentValidation )
2798 return tl::unexpected( documentValidation.error() );
2806 if( std::optional<ApiResponseStatus> unitError =
2809 return tl::unexpected( *unitError );
2825 wxLogTrace(
traceApi,
"Received announce from frame %d at %s",
2831 CrossProbeAnnounceResponse response;
2832 response.set_status( CPS_OK );
2839 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SyncSelection" ) )
2840 return tl::unexpected( *headless );
2842 SyncSelectionResponse response;
2846 if( !settings.
on_selection && aCtx.
Request.context() != SyncSelectionContext::SSC_EXPLICIT )
2848 response.set_status( CPS_DISABLED );
2849 response.set_message(
"implicit selection sync disabled by user" );
2853 std::vector<BOARD_ITEM*> items =
2858 if( aCtx.
Request.mode() == SyncSelectionMode::SSM_ITEMS_AND_NETS )
2870 wxLogTrace(
traceCrossProbeFlash,
"MAIL_SELECTION(_FORCE) PCB: flash enabled, items=%zu", items.size() );
2877 std::vector<BOARD_ITEM*> boardItems;
2878 std::copy( items.begin(), items.end(), std::back_inserter( boardItems ) );
2887 response.set_status( CPS_OK );
2895 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"HighlightNets" ) )
2896 return tl::unexpected( *headless );
2898 HighlightNetsResponse response;
2906 response.set_status( CPS_DISABLED );
2907 response.set_message(
"net highlight cross-probing disabled by user" );
2912 std::vector<wxString> nets;
2914 for(
const std::string&
name : aCtx.
Request.net_name() )
2915 nets.emplace_back( wxString::FromUTF8(
name ) );
2919 response.set_status( CPS_OK );
2926 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_PCB )
2929 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2930 return tl::unexpected( *busy );
2933 return tl::unexpected( documentValidation.error() );
2936 VariantsResponse response;
2940 for(
const wxString&
name :
board->GetVariantNames() )
2942 types::DesignVariant* var = response.add_variants();
2943 var->set_name(
name.ToUTF8() );
2944 var->set_description(
board->GetVariantDescription(
name ).ToUTF8() );
2953 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_PCB )
2956 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2957 return tl::unexpected( *busy );
2960 return tl::unexpected( documentValidation.error() );
2964 wxString
name = wxString::FromUTF8( aCtx.
Request.name() );
2968 ApiResponseStatus e;
2969 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2970 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.name() ) );
2971 return tl::unexpected( e );
2976 ApiResponseStatus e;
2977 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2978 e.set_error_message( fmt::format(
"a variant named '{}' already exists", aCtx.
Request.name() ) );
2979 return tl::unexpected( e );
2984 if( aCtx.
Request.has_description() )
2985 board->SetVariantDescription(
name, wxString::FromUTF8( aCtx.
Request.description() ) );
2996 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_PCB )
2999 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3000 return tl::unexpected( *busy );
3003 return tl::unexpected( documentValidation.error() );
3007 wxString
name = wxString::FromUTF8( aCtx.
Request.name() );
3011 ApiResponseStatus e;
3012 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3013 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.name() ) );
3014 return tl::unexpected( e );
3019 ApiResponseStatus e;
3020 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3021 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.name() ) );
3022 return tl::unexpected( e );
3036 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_PCB )
3039 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3040 return tl::unexpected( *busy );
3043 return tl::unexpected( documentValidation.error() );
3047 wxString oldName = wxString::FromUTF8( aCtx.
Request.old_name() );
3048 wxString newName = wxString::FromUTF8( aCtx.
Request.new_name() );
3052 ApiResponseStatus e;
3053 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3054 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.old_name() ) );
3055 return tl::unexpected( e );
3060 ApiResponseStatus e;
3061 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3062 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.new_name() ) );
3063 return tl::unexpected( e );
3066 if( !
board->HasVariant( oldName ) )
3068 ApiResponseStatus e;
3069 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3070 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.old_name() ) );
3071 return tl::unexpected( e );
3074 if(
board->HasVariant( newName ) )
3076 ApiResponseStatus e;
3077 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3078 e.set_error_message( fmt::format(
"a variant named '{}' already exists", aCtx.
Request.new_name() ) );
3079 return tl::unexpected( e );
3082 board->RenameVariant( oldName, newName );
3093 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_PCB )
3096 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3097 return tl::unexpected( *busy );
3100 return tl::unexpected( documentValidation.error() );
3104 wxString oldName = wxString::FromUTF8( aCtx.
Request.old_name() );
3105 wxString newName = wxString::FromUTF8( aCtx.
Request.new_name() );
3109 ApiResponseStatus e;
3110 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3111 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.old_name() ) );
3112 return tl::unexpected( e );
3117 ApiResponseStatus e;
3118 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3119 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.new_name() ) );
3120 return tl::unexpected( e );
3123 if( !
board->HasVariant( oldName ) )
3125 ApiResponseStatus e;
3126 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3127 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.old_name() ) );
3128 return tl::unexpected( e );
3131 if(
board->HasVariant( newName ) )
3133 ApiResponseStatus e;
3134 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3135 e.set_error_message( fmt::format(
"a variant named '{}' already exists", aCtx.
Request.new_name() ) );
3136 return tl::unexpected( e );
3139 board->CopyVariant( oldName, newName,
3140 aCtx.
Request.has_new_description() ? wxString::FromUTF8( aCtx.
Request.new_description() )
3152 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_PCB )
3155 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3156 return tl::unexpected( *busy );
3159 return tl::unexpected( documentValidation.error() );
3163 wxString
name = wxString::FromUTF8( aCtx.
Request.name() );
3167 ApiResponseStatus e;
3168 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3169 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.name() ) );
3170 return tl::unexpected( e );
3173 board->SetVariantDescription(
name, wxString::FromUTF8( aCtx.
Request.description() ) );
3181 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_PCB )
3184 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3185 return tl::unexpected( *busy );
3188 return tl::unexpected( documentValidation.error() );
3196 ApiResponseStatus e;
3197 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3198 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.name() ) );
3199 return tl::unexpected( e );
3203 wxString varName = aCtx.
Request.has_name() ? wxString::FromUTF8( aCtx.
Request.name() ) : wxString();
3208 board->SetCurrentVariant( varName );
3217 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_PCB )
3221 return tl::unexpected( documentValidation.error() );
3223 CurrentVariantResponse response;
3225 if( wxString current =
pcbContext()->GetBoard()->GetCurrentVariant(); !current.IsEmpty() )
3226 response.set_name( current.ToUTF8() );
3235 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
3236 return tl::unexpected( *busy );
3240 ApiResponseStatus e;
3241 e.set_status( ApiStatusCode::AS_UNHANDLED );
3242 return tl::unexpected( e );
3249 ApiResponseStatus e;
3250 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3251 e.set_error_message(
"lib_id must specify both a library nickname and an entry name" );
3252 return tl::unexpected( e );
3260 ApiResponseStatus e;
3261 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3262 e.set_error_message(
"layer must be F_Cu or B_Cu" );
3263 return tl::unexpected( e );
3270 ApiResponseStatus e;
3271 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
3272 e.set_error_message( fmt::format(
"footprint '{}' not found", libId.
Format().
wx_str() ) );
3273 return tl::unexpected( e );
3276 footprint->SetUuid(
KIID() );
3277 footprint->RunOnChildren(
3284 footprint->SetParent(
board() );
3288 if( aCtx.
Request.has_orientation() )
3289 footprint->SetOrientationDegrees( aCtx.
Request.orientation().value_degrees() );
3291 footprint->SetLayerAndFlip( layer );
3294 FOOTPRINT* placed = footprint.release();
3295 commit->
Add( placed );
3300 PlaceFromLibraryResponse response;
3301 response.mutable_header()->CopyFrom( aCtx.
Request.header() );
3302 placed->
Serialize( *response.mutable_item() );
KICOMMON_API types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICOMMON_API 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)
HANDLER_RESULT< Empty > unpackEmbeddedFiles(EMBEDDED_FILES &aOutput, const common::types::EmbeddedFiles &aProto)
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)
static const std::vector< KICAD_T > s_allowedBoardTypes
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)
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
void pushCurrentCommit(const std::string &aClientName, const wxString &aMessage) override
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)
std::set< std::string > m_activeClients
std::map< std::string, std::pair< KIID, std::unique_ptr< COMMIT > > > m_commits
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
HANDLER_RESULT< ImportNetlistResponse > handleImportNetlist(const HANDLER_CONTEXT< ImportNetlist > &aCtx)
HANDLER_RESULT< BoardPlotSettingsResponse > handleGetBoardPlotSettings(const HANDLER_CONTEXT< GetBoardPlotSettings > &aCtx)
HANDLER_RESULT< Empty > handleDeleteVariant(const HANDLER_CONTEXT< commands::DeleteVariant > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportPdf(const HANDLER_CONTEXT< RunBoardJobExportPdf > &aCtx)
HANDLER_RESULT< google::protobuf::Empty > handleSetEmbeddedFiles(const HANDLER_CONTEXT< SetEmbeddedFiles > &aCtx)
HANDLER_RESULT< commands::CurrentVariantResponse > handleGetCurrentVariant(const HANDLER_CONTEXT< commands::GetCurrentVariant > &aCtx)
HANDLER_RESULT< BoardDesignRulesResponse > handleSetBoardDesignRules(const HANDLER_CONTEXT< SetBoardDesignRules > &aCtx)
API_HANDLER_PCB(PCB_EDIT_FRAME *aFrame)
HANDLER_RESULT< Empty > handleAddVariant(const HANDLER_CONTEXT< commands::AddVariant > &aCtx)
HANDLER_RESULT< commands::GetItemsResponse > handleGetConnectedItems(const HANDLER_CONTEXT< GetConnectedItems > &aCtx)
HANDLER_RESULT< commands::VariantsResponse > handleGetVariants(const HANDLER_CONTEXT< commands::GetVariants > &aCtx)
HANDLER_RESULT< types::Vector2 > handleGetBoardOrigin(const HANDLER_CONTEXT< GetBoardOrigin > &aCtx)
HANDLER_RESULT< commands::GetItemsResponse > handleGetItemsByNetClass(const HANDLER_CONTEXT< GetItemsByNetClass > &aCtx)
HANDLER_RESULT< NetClassForNetsResponse > handleGetNetClassForNets(const HANDLER_CONTEXT< GetNetClassForNets > &aCtx)
HANDLER_RESULT< commands::CrossProbeAnnounceResponse > handleCrossProbeAnnounce(const HANDLER_CONTEXT< commands::CrossProbeAnnounce > &aCtx)
HANDLER_RESULT< Empty > handleCopyVariant(const HANDLER_CONTEXT< commands::CopyVariant > &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< commands::GetDocumentModifiedStateResponse > handleGetDocumentModifiedState(const HANDLER_CONTEXT< commands::GetDocumentModifiedState > &aCtx) override
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)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportPng(const HANDLER_CONTEXT< RunBoardJobExportPng > &aCtx)
HANDLER_RESULT< Empty > handleSetCurrentVariant(const HANDLER_CONTEXT< commands::SetCurrentVariant > &aCtx)
void setDrawingSheetFileName(const wxString &aFileName) override
HANDLER_RESULT< commands::GetItemsResponse > handleGetItemsByNet(const HANDLER_CONTEXT< GetItemsByNet > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportIpc2581(const HANDLER_CONTEXT< RunBoardJobExportIpc2581 > &aCtx)
std::optional< TITLE_BLOCK * > getTitleBlock(const DocumentSpecifier &aDocument) override
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportPosition(const HANDLER_CONTEXT< RunBoardJobExportPosition > &aCtx)
HANDLER_RESULT< Empty > handleSetBoardOrigin(const HANDLER_CONTEXT< SetBoardOrigin > &aCtx)
HANDLER_RESULT< Empty > handleSetBoardPlotSettings(const HANDLER_CONTEXT< SetBoardPlotSettings > &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)
bool setPageSettings(const DocumentSpecifier &aDocument, const PAGE_INFO &aPageInfo) override
HANDLER_RESULT< types::RunJobResponse > handleRunBoardJobExportSvg(const HANDLER_CONTEXT< RunBoardJobExportSvg > &aCtx)
HANDLER_RESULT< commands::GetOpenDocumentsResponse > handleGetOpenDocuments(const HANDLER_CONTEXT< commands::GetOpenDocuments > &aCtx)
HANDLER_RESULT< commands::SyncSelectionResponse > handleSyncSelection(const HANDLER_CONTEXT< commands::SyncSelection > &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 > handleSetVariantDescription(const HANDLER_CONTEXT< commands::SetVariantDescription > &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< kiapi::common::commands::PlaceFromLibraryResponse > handlePlaceFootprintFromLibrary(const HANDLER_CONTEXT< kiapi::board::commands::PlaceFootprintFromLibrary > &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 > handleRenameVariant(const HANDLER_CONTEXT< commands::RenameVariant > &aCtx)
std::optional< PAGE_INFO > getPageSettings(const DocumentSpecifier &aDocument) override
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< commands::HighlightNetsResponse > handleHighlightNets(const HANDLER_CONTEXT< commands::HighlightNets > &aCtx)
HANDLER_RESULT< google::protobuf::Empty > handleAddEmbeddedFiles(const HANDLER_CONTEXT< AddEmbeddedFiles > &aCtx)
HANDLER_RESULT< common::types::EmbeddedFiles > handleGetEmbeddedFiles(const HANDLER_CONTEXT< GetEmbeddedFiles > &aCtx)
HANDLER_RESULT< BoardLayerResponse > handleGetBoardLayerByName(const HANDLER_CONTEXT< GetBoardLayerByName > &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.
CROSS_PROBING_SETTINGS m_CrossProbing
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
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.
int m_CopperEdgeClearance
std::map< int, SEVERITY > m_DRCSeverities
void SetGridOrigin(const VECTOR2I &aOrigin)
int m_MinSilkTextThickness
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
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).
void SetAuxOrigin(const VECTOR2I &aOrigin)
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
std::set< DRC_EXCLUSION, DRC_EXCLUSION_COMPARE > m_DrcExclusions
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void CopyFrom(const BOARD_ITEM *aOther)
Information pertinent to a Pcbnew printed circuit board.
void SetPlotOptions(const PCB_PLOT_PARAMS &aOptions)
EMBEDDED_FILES * GetEmbeddedFiles() override
const PAGE_INFO & GetPageSettings() const
void SetDesignSettings(const BOARD_DESIGN_SETTINGS &aSettings)
TITLE_BLOCK & GetTitleBlock()
PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Return the ID of a layer.
void SetPageSettings(const PAGE_INFO &aPageSettings)
const wxString & GetFileName() const
const PCB_PLOT_PARAMS & GetPlotOptions() 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.
static void RegisterPeer(FRAME_T aFrameType, const std::string &aSocketPath)
void ToProto(kiapi::board::CustomRuleConstraint &aProto) const
Container for an DRC exclusion, which is a PCB_MARKER plus an optional comment.
static DRC_EXCLUSION FromProto(const kiapi::board::DrcExclusion &aMessage)
const kiapi::board::DrcExclusion & ToProto() 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)
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
const std::map< wxString, std::shared_ptr< EMBEDDED_FILE > > & EmbeddedFileMap() const
Provide an iterable view of the file collection.
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
bool m_useBoardPlotParams
bool m_useProtelFileExtension
bool m_includeNetlistAttributes
bool m_disableApertureMacros
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 UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
std::string AsStdString() const
int ProcessJob(KIWAY::FACE_T aFace, JOB *aJob, REPORTER *aReporter=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
A logical library item identifier and consists of various portions much like a URI.
bool IsValid() const
Check if this LID_ID is valid.
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 syncSelection
Sets selection to specified items, zooms to fit, if enabled.
static TOOL_ACTION drillSetOrigin
static TOOL_ACTION syncSelectionWithNets
Sets selection to specified items with connected nets, zooms to fit, if enabled.
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.
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aRefresh=true)
Update the current display options.
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
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 void SetContentModified(bool aModified=true)=0
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.
bool m_FlipBoardView
true if the board is flipped to show the mirrored view
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.
void StartCrossProbeFlash(const std::vector< BOARD_ITEM * > &aItems)
void UpdateVariantSelectionCtrl()
Update the variant selection dropdown with the current board's variant names.
void SetCurrentVariant(const wxString &aVariantName)
Set the current variant on the board and update the drawing sheet's cached variant name and descripti...
void UpdateUserInterface()
Update the layer manager and other widgets from the board setup (layer and items visibility,...
void HandleRemoteNetHighlight(const std::vector< wxString > &aNetNames)
const KIID GetUUID() const override
Parameters and options when plotting/printing a board.
void SetDrillMarksType(DRILL_MARKS aVal)
bool GetUseAuxOrigin() const
LSEQ GetPlotOnAllLayersSequence() const
bool GetHideDNPFPsOnFabLayers() const
void SetLayerSelection(const LSET &aSelection)
void SetPlotReference(bool aFlag)
void SetSketchPadsOnFabLayers(bool aFlag)
bool GetCrossoutDNPFPsOnFabLayers() const
bool GetSketchDNPFPsOnFabLayers() const
void SetPlotOnAllLayersSequence(LSEQ aSeq)
void SetPlotFrameRef(bool aFlag)
void SetSketchDNPFPsOnFabLayers(bool aFlag)
void SetPlotPadNumbers(bool aFlag)
LSET GetLayerSelection() const
bool GetPlotReference() const
void SetScale(double aVal)
void SetMirror(bool aFlag)
void SetBlackAndWhite(bool blackAndWhite)
void SetSubtractMaskFromSilk(bool aSubtract)
bool GetSketchPadsOnFabLayers() const
void SetHideDNPFPsOnFabLayers(bool aFlag)
bool GetSubtractMaskFromSilk() const
void SetPlotValue(bool aFlag)
bool GetPlotPadNumbers() const
DRILL_MARKS GetDrillMarksType() const
bool GetPlotValue() const
void SetNegative(bool aFlag)
bool GetBlackAndWhite() const
void SetUseAuxOrigin(bool aAux)
bool GetPlotFrameRef() const
void SetCrossoutDNPFPsOnFabLayers(bool aFlag)
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:
static std::string ToStdString(const wxString &aStr)
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
static const std::string KiCadPcbFileExtension
const wxChar *const traceCrossProbeFlash
Flag to enable debug output for cross-probe flash operations.
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
bool IsPcbLayer(int aLayer)
Test whether a layer is a valid layer for Pcbnew.
@ LAYER_DRC_WARNING
Layer for DRC markers with #SEVERITY_WARNING.
@ LAYER_DRC_ERROR
Layer for DRC markers with #SEVERITY_ERROR.
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
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)
void PackEmbeddedFiles(common::types::EmbeddedFiles &aOutput, const EMBEDDED_FILES &aFiles)
bool UnpackEmbeddedFiles(EMBEDDED_FILES &aOutput, const common::types::EmbeddedFiles &aProto)
LSET UnpackLayerSet(const google::protobuf::RepeatedField< int > &aProtoLayerSet)
std::vector< BOARD_ITEM * > FindItemsFromSyncSelection(const BOARD *aBoard, const google::protobuf::RepeatedPtrField< kiapi::common::commands::SelectionSpec > &aItems)
Resolve a cross-probe selection request against a board.
KICOMMON_API VECTOR3D UnpackVector3D(const types::Vector3D &aInput)
KICOMMON_API ApiResponseStatus MakeResponseStatus(ApiStatusCode aCode, const std::string &aMessage)
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)
KICOMMON_API LIB_ID UnpackLibId(const types::LibraryIdentifier &aId)
const KICOMMON_API std::string KiwayClientName
const KICOMMON_API std::string StandaloneCrossProbeClientName
std::shared_ptr< PCB_CONTEXT > CreatePcbFrameContext(PCB_EDIT_FRAME *aFrame)
Class to handle a set of BOARD_ITEMs.
FOOTPRINT * LoadFootprintFromProject(BOARD *aBoard, const LIB_ID &aFootprintId, bool aKeepUuid)
Load a footprint from the project library table and apply board default settings.
constexpr int MIN_PNG_DPI
constexpr int MAX_PNG_DPI
#define SKIP_CONNECTIVITY
wxString GetDefaultVariantName()
bool flash_selection
Flash newly cross-probed selection (visual attention aid).
bool on_selection
Synchronize the selection for multiple items too.
bool auto_highlight
Automatically turn on highlight mode in the target frame.
RequestMessageType Request
RATSNEST_MODE m_RatsnestMode
IbisParser parser & reporter
wxString result
Test unit parsing edge cases and error handling.
wxLogTrace helper definitions.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ PCB_CONSTRAINT_T
a geometric constraint between board items
@ 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_GRID_ITEM_T
a subgrid placed on a board
@ 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_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
@ 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