28#include <fmt/ranges.h>
30#include <magic_enum.hpp>
62#include <wx/filename.h>
64#include <api/common/commands/library_commands.pb.h>
65#include <api/common/types/base_types.pb.h>
70using namespace kiapi::common::commands;
71using kiapi::common::types::CommandStatus;
72using kiapi::common::types::DocumentType;
73using kiapi::common::types::ItemRequestStatus;
100 types::RunJobResponse response;
105 response.add_output_path( output.m_outputPath.ToUTF8() );
109 response.set_status( types::JobStatus::JS_SUCCESS );
113 response.set_status( types::JobStatus::JS_ERROR );
114 response.set_message( fmt::format(
"Schematic export job '{}' failed with exit code {}: {}",
116 reporter.GetMessages().ToStdString() ) );
132 using namespace kiapi::schematic::jobs;
134 using namespace kiapi::schematic::commands;
199 return std::make_unique<SCH_COMMIT>(
toolManager() );
222 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
223 e.set_error_message( fmt::format(
"{} is not available in headless mode", aCommandName ) );
233 kiapi::schematic::types::SchematicSymbolInstance symbol;
238 aOut.PackFrom( symbol );
242 kiapi::schematic::types::SheetSymbol sheet;
247 aOut.PackFrom( sheet );
272tl::expected<bool, ApiResponseStatus>
275 if( aDocument.type() != DocumentType::DOCTYPE_SCHEMATIC )
278 e.set_status( ApiStatusCode::AS_UNHANDLED );
279 return tl::unexpected( e );
284 if( aDocument.project().name().compare( prj.
GetProjectName().ToUTF8() ) != 0 )
287 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
288 e.set_error_message( fmt::format(
"the requested project {} is not open",
289 aDocument.project().name() ) );
290 return tl::unexpected( e );
293 if( aDocument.project().path().compare( prj.
GetProjectPath().ToUTF8() ) != 0 )
296 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
297 e.set_error_message( fmt::format(
"the requested project {} is not open at path {}",
298 aDocument.project().name(),
299 aDocument.project().path() ) );
300 return tl::unexpected( e );
303 if( aDocument.has_sheet_path() )
310 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
311 e.set_error_message( fmt::format(
"the requested sheet path {} is not valid for this schematic",
312 path.AsString().ToStdString() ) );
313 return tl::unexpected( e );
323 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
324 return tl::unexpected( *busy );
328 if( !documentValidation )
329 return tl::unexpected( documentValidation.error() );
331 if( !
context()->SaveSchematic() )
334 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
335 e.set_error_message(
"failed to save schematic" );
336 return tl::unexpected( e );
339 return google::protobuf::Empty();
346 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
347 return tl::unexpected( *busy );
351 if( !documentValidation )
352 return tl::unexpected( documentValidation.error() );
354 wxFileName schematicPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.path() ) ) );
356 if( !schematicPath.IsOk() || !schematicPath.IsDirWritable() )
359 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
361 fmt::format(
"save path '{}' could not be opened", schematicPath.GetFullPath().ToStdString() ) );
362 return tl::unexpected( e );
365 if( schematicPath.FileExists() && ( !schematicPath.IsFileWritable() || !aCtx.
Request.options().overwrite() ) )
368 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
369 e.set_error_message( fmt::format(
"save path '{}' exists and cannot be overwritten",
370 schematicPath.GetFullPath().ToStdString() ) );
371 return tl::unexpected( e );
377 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
378 e.set_error_message( fmt::format(
"save path '{}' must have a kicad_sch extension",
379 schematicPath.GetFullPath().ToStdString() ) );
380 return tl::unexpected( e );
383 bool includeProject =
true;
385 if( aCtx.
Request.has_options() )
386 includeProject = aCtx.
Request.options().include_project();
388 if( !
context()->SaveSchematicCopy( schematicPath.GetFullPath(), includeProject ) )
391 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
392 e.set_error_message(
"failed to save schematic copy" );
393 return tl::unexpected( e );
396 return google::protobuf::Empty();
403 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_SCHEMATIC )
406 e.set_status( ApiStatusCode::AS_UNHANDLED );
407 return tl::unexpected( e );
412 if( !documentValidation )
413 return tl::unexpected( documentValidation.error() );
418 e.set_status( ApiStatusCode::AS_BUSY );
419 e.set_error_message(
"cannot revert while a commit is open" );
420 return tl::unexpected( e );
423 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
424 return tl::unexpected( *busy );
426 if( !
context()->RevertToSaved() )
429 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
430 e.set_error_message(
"could not revert: there is no saved file on disk to revert to" );
431 return tl::unexpected( e );
434 return google::protobuf::Empty();
443 if( !documentValidation )
444 return tl::unexpected( documentValidation.error() );
446 commands::SavedDocumentResponse response;
450 if( !topLevelSheet || !topLevelSheet->
GetScreen() )
453 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
454 e.set_error_message(
"schematic has no top-level sheet to save" );
455 return tl::unexpected( e );
463 std::string contents = formatter.
GetString();
465 response.set_contents( contents );
474 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SaveSelectionToString" ) )
475 return tl::unexpected( *headless );
480 if( selection.Empty() )
483 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
484 e.set_error_message(
"the selection is empty" );
485 return tl::unexpected( e );
488 commands::SavedSelectionResponse response;
493 response.add_ids()->set_value( item->m_Uuid.AsStdString() );
500 std::string contents = formatter.
GetString();
502 response.set_contents( contents );
511 if( aCtx.
Request.type() != DocumentType::DOCTYPE_SCHEMATIC )
516 e.set_status( ApiStatusCode::AS_UNHANDLED );
517 return tl::unexpected( e );
520 GetOpenDocumentsResponse response;
521 common::types::DocumentSpecifier doc;
523 wxFileName fn(
m_context->GetCurrentFileName() );
525 doc.set_type( DocumentType::DOCTYPE_SCHEMATIC );
527 if( std::optional<SCH_SHEET_PATH>
path =
m_context->GetCurrentSheet() )
532 response.mutable_documents()->Add( std::move( doc ) );
541 return tl::unexpected( documentValidation.error() );
543 GetDocumentModifiedStateResponse response;
545 if( aCtx.
Request.document().has_sheet_path() )
554 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
555 e.set_error_message(
"the requested sheet path is not valid for this schematic" );
556 return tl::unexpected( e );
559 if(
const SCH_SCREEN* screen = sheetPath->LastScreen() )
561 response.set_state( screen->IsContentModified() ? DocumentModifiedState::DMS_MODIFIED
562 : DocumentModifiedState::DMS_UNMODIFIED );
571 response.set_state(
schematic()->Hierarchy().IsModified() ? DocumentModifiedState::DMS_MODIFIED
572 : DocumentModifiedState::DMS_UNMODIFIED );
579 std::erase_if( aTypeList,
589 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
590 return tl::unexpected( *busy );
595 return tl::unexpected( valid.error() );
600 if( aCtx.
Request.types().empty() )
603 std::set<KICAD_T> typesRequested;
605 for(
KICAD_T type : requestedTypes )
606 typesRequested.insert( type );
610 if( typesRequested.empty() )
613 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
614 e.set_error_message(
"none of the requested types are valid for a Schematic object" );
615 return tl::unexpected( e );
619 std::optional<SCH_SHEET_PATH> pathFilter;
621 if( aCtx.
Request.header().document().has_sheet_path() )
627 std::map<KICAD_T, std::vector<std::pair<EDA_ITEM*, SCH_SHEET_PATH>>> itemMap;
632 const SCH_SCREEN* aScreen = aPath.LastScreen();
636 itemMap[ aItem->Type() ].emplace_back( aItem, aPath );
642 aItem->RunOnChildren(
645 itemMap[ aChild->
Type() ].emplace_back( aChild, aPath );
653 processScreen( *pathFilter );
658 processScreen(
path );
661 GetItemsResponse response;
662 google::protobuf::Any
any;
664 for(
KICAD_T type : typesRequested )
666 for(
const auto& [item, itemPath] : itemMap[type] )
669 response.mutable_items()->Add( std::move(
any ) );
673 response.set_status( ItemRequestStatus::IRS_OK );
680 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
681 return tl::unexpected( *busy );
686 e.set_status( ApiStatusCode::AS_UNHANDLED );
687 return tl::unexpected( e );
691 std::optional<SCH_SHEET_PATH> pathFilter;
693 if( aCtx.
Request.header().document().has_sheet_path() )
699 GetItemsResponse response;
701 google::protobuf::Any
any;
703 for(
const types::KIID& idProto : aCtx.
Request.items() )
705 KIID id( idProto.value() );
711 item = pathFilter->ResolveItem(
id );
712 itemPath = *pathFilter;
716 item = hierarchy.
ResolveItem(
id, &itemPath,
true );
724 kiapi::schematic::types::SchematicSymbolInstance symbol;
729 any.PackFrom( symbol );
733 kiapi::schematic::types::SheetSymbol sheet;
738 any.PackFrom( sheet );
745 response.mutable_items()->Add( std::move(
any ) );
748 if( response.items().empty() )
751 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
752 e.set_error_message(
"none of the requested IDs were found or valid" );
753 return tl::unexpected( e );
756 response.set_status( ItemRequestStatus::IRS_OK );
764 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetSelection" ) )
765 return tl::unexpected( *headless );
771 e.set_status( ApiStatusCode::AS_UNHANDLED );
772 return tl::unexpected( e );
783 SelectionResponse response;
784 google::protobuf::Any
any;
791 response.mutable_items()->Add( std::move(
any ) );
802 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"ClearSelection" ) )
803 return tl::unexpected( *headless );
805 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
806 return tl::unexpected( *busy );
812 e.set_status( ApiStatusCode::AS_UNHANDLED );
813 return tl::unexpected( e );
826 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"AddToSelection" ) )
827 return tl::unexpected( *headless );
829 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
830 return tl::unexpected( *busy );
836 e.set_status( ApiStatusCode::AS_UNHANDLED );
837 return tl::unexpected( e );
845 for(
const types::KIID&
id : aCtx.
Request.items() )
850 if( std::optional<SCH_ITEM*> item =
getItemById(
KIID(
id.value() ), &itemPath );
851 item && itemPath == current )
853 toAdd.push_back( *item );
860 SelectionResponse response;
861 google::protobuf::Any
any;
866 response.mutable_items()->Add( std::move(
any ) );
876 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"RemoveFromSelection" ) )
877 return tl::unexpected( *headless );
879 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
880 return tl::unexpected( *busy );
886 e.set_status( ApiStatusCode::AS_UNHANDLED );
887 return tl::unexpected( e );
895 for(
const types::KIID&
id : aCtx.
Request.items() )
899 if( std::optional<SCH_ITEM*> item =
getItemById(
KIID(
id.value() ), &itemPath );
900 item && itemPath == current )
902 toRemove.push_back( *item );
909 SelectionResponse response;
910 google::protobuf::Any
any;
915 response.mutable_items()->Add( std::move(
any ) );
927 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
928 e.set_error_message(
"Tried to create an item in a null container" );
929 return tl::unexpected( e );
935 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
936 e.set_error_message( fmt::format(
"type {} is not supported by the schematic API handler",
937 magic_enum::enum_name( aType ) ) );
938 return tl::unexpected( e );
944 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
945 e.set_error_message( fmt::format(
"Tried to create a pin in {}, which is not a symbol",
947 return tl::unexpected( e );
952 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
953 e.set_error_message( fmt::format(
"Tried to create a sheet symbol in {}, which is not a "
956 return tl::unexpected( e );
961 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
962 e.set_error_message( fmt::format(
"Tried to create a symbol in {}, which is not a "
965 return tl::unexpected( e );
970 if( created && !created->GetParent() )
971 created->SetParent( aContainer );
976 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
977 e.set_error_message( fmt::format(
"Tried to create an item of type {}, which is unhandled",
978 magic_enum::enum_name( aType ) ) );
979 return tl::unexpected( e );
987 const std::string& aClientName,
988 const types::ItemHeader &aHeader,
989 const google::protobuf::RepeatedPtrField<google::protobuf::Any>& aItems,
990 std::function<
void( ItemStatus, google::protobuf::Any )> aItemHandler )
996 if( !containerResult && containerResult.error().status() == ApiStatusCode::AS_UNHANDLED )
999 e.set_status( ApiStatusCode::AS_UNHANDLED );
1000 return tl::unexpected( e );
1002 else if( !containerResult )
1004 e.CopyFrom( containerResult.error() );
1005 return tl::unexpected( e );
1012 if( aHeader.document().has_sheet_path() )
1023 bool connectivityChanged =
false;
1025 for(
const google::protobuf::Any& anyItem : aItems )
1032 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
1033 status.set_error_message( fmt::format(
"Could not decode a valid type from {}",
1034 anyItem.type_url() ) );
1035 aItemHandler( status, anyItem );
1039 EDA_ITEM* container = targetScreen;
1043 if( !creationResult )
1045 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
1046 status.set_error_message( creationResult.error().error_message() );
1047 aItemHandler( status, anyItem );
1051 std::unique_ptr<EDA_ITEM> item( std::move( *creationResult ) );
1053 bool unpacked =
false;
1057 kiapi::schematic::types::SchematicSymbolInstance symbolProto;
1058 kiapi::schematic::types::SheetSymbol sheetProto;
1062 unpacked = anyItem.UnpackTo( &symbolProto )
1067 unpacked = anyItem.UnpackTo( &sheetProto );
1073 if( tl::expected<bool, ApiResponseStatus>
result =
UnpackSheet( sheet, sheetProto );
1080 return tl::unexpected(
result.error() );
1086 unpacked =
group->DeserializeGroup( anyItem, commit );
1090 unpacked = item->Deserialize( anyItem );
1095 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1096 e.set_error_message( fmt::format(
"could not unpack {} from request",
1097 item->GetClass().ToStdString() ) );
1098 return tl::unexpected( e );
1101 if( std::vector<wxString> removed = item->RemoveConflictingCustomProperties(); !removed.empty() )
1104 [](
const wxString& aIn )
1106 return std::string( aIn.ToUTF8() );
1109 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
1110 status.set_error_message( fmt::format(
1111 "Invalid custom properties for item {}: property name(s) '{}' already in use",
1112 item->m_Uuid.AsStdString(), fmt::join( std::views::transform( removed, as_str ),
", " ) ) );
1114 aItemHandler( status, anyItem );
1121 existingItem = targetPath.
ResolveItem( item->m_Uuid );
1124 existingPath = targetPath;
1126 if( aCreate && existingItem )
1128 status.set_code( ItemStatusCode::ISC_EXISTING );
1129 status.set_error_message( fmt::format(
"an item with UUID {} already exists",
1130 item->m_Uuid.AsStdString() ) );
1131 aItemHandler( status, anyItem );
1134 else if( !aCreate && !existingItem )
1136 status.set_code( ItemStatusCode::ISC_NONEXISTENT );
1137 status.set_error_message( fmt::format(
"an item with UUID {} does not exist",
1138 item->m_Uuid.AsStdString() ) );
1139 aItemHandler( status, anyItem );
1147 if( itemScreen != targetScreen )
1149 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
1150 status.set_error_message( fmt::format(
"item {} exists on a different sheet than targeted",
1151 item->m_Uuid.AsStdString() ) );
1152 aItemHandler( status, anyItem );
1167 parentPath = targetPath;
1169 parentPath = existingPath;
1173 if( !destFilePath.IsEmpty() )
1180 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
1181 status.set_error_message(
"sheet update would create recursive hierarchy" );
1182 aItemHandler( status, anyItem );
1188 status.set_code( ItemStatusCode::ISC_OK );
1189 google::protobuf::Any newItem;
1194 commit->
Add( createdItem, targetScreen );
1198 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1199 e.set_error_message(
"could not add the requested item to its parent container" );
1200 return tl::unexpected( e );
1206 kiapi::schematic::types::SchematicSymbolInstance packed;
1210 if(
PackSymbol( &packed, symbol, targetPath ) )
1211 newItem.PackFrom( packed );
1216 kiapi::schematic::types::SheetSymbol packed;
1218 if( sheetProto.page_number().empty() )
1223 if(
PackSheet( &packed, sheet, targetPath ) )
1224 newItem.PackFrom( packed );
1235 std::vector<SCH_SYMBOL_INSTANCE> symbolPlacements;
1236 std::vector<SCH_SHEET_INSTANCE> sheetPlacements;
1239 symbolPlacements =
static_cast<SCH_SYMBOL*
>( existingItem )->GetInstances();
1241 sheetPlacements =
static_cast<SCH_SHEET*
>( existingItem )->GetInstances();
1243 commit->
Modify( existingItem, targetScreen );
1249 connectivityChanged =
true;
1255 kiapi::schematic::types::SchematicSymbolInstance packed;
1262 if(
PackSymbol( &packed, symbol, existingPath ) )
1263 newItem.PackFrom( packed );
1268 kiapi::schematic::types::SheetSymbol packed;
1275 if(
PackSheet( &packed, sheet, existingPath ) )
1276 newItem.PackFrom( packed );
1284 aItemHandler( status, newItem );
1290 :
_(
"Modified items via API" ) );
1293 if(
m_frame && connectivityChanged )
1296 return ItemRequestStatus::IRS_OK;
1301 const std::string& aClientName )
1306 for(
auto& [
id, status] : aItemsToDelete )
1316 status = ItemDeletionStatus::IDS_IMMUTABLE;
1321 status = ItemDeletionStatus::IDS_OK;
1332 return std::nullopt;
1337 return std::nullopt;
1345 if( aDocument.has_sheet_path() )
1349 if( std::optional<SCH_SHEET_PATH> sheetPath =
schematic()->Hierarchy().GetSheetPathByKIIDPath(
path ) )
1350 return sheetPath->LastScreen();
1355 if( std::optional<SCH_SHEET_PATH> current =
m_context->GetCurrentSheet() )
1356 return current->LastScreen();
1361 return path.LastScreen();
1368 return &screen->GetTitleBlock();
1370 return std::nullopt;
1377 return screen->GetPageSettings();
1379 return std::nullopt;
1387 screen->SetPageSettings( aPageInfo );
1388 screen->SetContentModified();
1419 else if(
schematic()->GetCurrentScreen() )
1426static std::optional<ApiResponseStatus>
1429 aJob.
m_drawingSheet = wxString::FromUTF8( aSettings.drawing_sheet() );
1430 aJob.
m_defaultFont = wxString::FromUTF8( aSettings.default_font() );
1431 aJob.
m_variant = wxString::FromUTF8( aSettings.variant() );
1438 aJob.
m_theme = wxString::FromUTF8( aSettings.theme() );
1442 for(
const std::string& page : aSettings.plot_pages() )
1443 aJob.
m_plotPages.push_back( wxString::FromUTF8( page ) );
1445 if( aSettings.page_size() != schematic::jobs::SchematicJobPageSize::SJPS_UNKNOWN )
1448 switch( aSettings.sheet_mode() )
1450 case schematic::jobs::SJSM_ALL_SHEETS: aJob.
m_plotAll =
true;
break;
1451 case schematic::jobs::SJSM_SINGLE_SHEET: aJob.
m_plotAll =
false;
break;
1452 case schematic::jobs::SJSM_UNKNOWN:
1456 return std::nullopt;
1463 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1464 return tl::unexpected( *busy );
1468 if( !documentValidation )
1469 return tl::unexpected( documentValidation.error() );
1471 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_SVG>( aCtx.
Request.plot_settings().sheet_mode()
1472 != schematic::jobs::SJSM_SINGLE_SHEET );
1473 plotJob->m_filename =
m_context->GetCurrentFileName();
1475 if( !aCtx.
Request.job_settings().output_path().empty() )
1476 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.
Request.job_settings().output_path() ) );
1479 return tl::unexpected( *err );
1488 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1489 return tl::unexpected( *busy );
1493 if( !documentValidation )
1494 return tl::unexpected( documentValidation.error() );
1496 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_DXF>( aCtx.
Request.plot_settings().sheet_mode()
1497 != schematic::jobs::SJSM_SINGLE_SHEET );
1499 plotJob->m_filename =
m_context->GetCurrentFileName();
1501 if( !aCtx.
Request.job_settings().output_path().empty() )
1502 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.
Request.job_settings().output_path() ) );
1505 return tl::unexpected( *err );
1514 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1515 return tl::unexpected( *busy );
1519 if( !documentValidation )
1520 return tl::unexpected( documentValidation.error() );
1522 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_PDF>(
false );
1523 plotJob->m_filename =
m_context->GetCurrentFileName();
1525 if( !aCtx.
Request.job_settings().output_path().empty() )
1526 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.
Request.job_settings().output_path() ) );
1529 return tl::unexpected( *err );
1531 plotJob->m_PDFPropertyPopups = aCtx.
Request.property_popups();
1532 plotJob->m_PDFHierarchicalLinks = aCtx.
Request.hierarchical_links();
1533 plotJob->m_PDFMetadata = aCtx.
Request.include_metadata();
1542 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1543 return tl::unexpected( *busy );
1547 if( !documentValidation )
1548 return tl::unexpected( documentValidation.error() );
1550 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_PS>( aCtx.
Request.plot_settings().sheet_mode()
1551 != schematic::jobs::SJSM_SINGLE_SHEET );
1552 plotJob->m_filename =
m_context->GetCurrentFileName();
1554 if( !aCtx.
Request.job_settings().output_path().empty() )
1555 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.
Request.job_settings().output_path() ) );
1558 return tl::unexpected( *err );
1567 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1568 return tl::unexpected( *busy );
1571 return tl::unexpected( validation.error() );
1573 const schematic::jobs::SchematicJobSheetMode sheetMode = aCtx.
Request.plot_settings().sheet_mode();
1575 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_PNG>( sheetMode != schematic::jobs::SJSM_SINGLE_SHEET );
1576 plotJob->m_filename =
m_context->GetCurrentFileName();
1578 if( !aCtx.
Request.job_settings().output_path().empty() )
1579 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.
Request.job_settings().output_path() ) );
1582 return tl::unexpected( *err );
1590 ApiResponseStatus status;
1591 status.set_status( ApiStatusCode::AS_BAD_REQUEST );
1593 return tl::unexpected( status );
1596 plotJob->m_dpi = dpi;
1600 plotJob->m_antialias = aCtx.
Request.antialiasing() != types::AntialiasingMode::AAM_NONE;
1609 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1610 return tl::unexpected( *busy );
1614 if( !documentValidation )
1615 return tl::unexpected( documentValidation.error() );
1617 if( aCtx.
Request.format() == kiapi::schematic::jobs::SchematicNetlistFormat::SNF_UNKNOWN )
1619 ApiResponseStatus e;
1620 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1621 e.set_error_message(
"RunSchematicJobExportNetlist requires a valid format" );
1622 return tl::unexpected( e );
1628 if( !aCtx.
Request.job_settings().output_path().empty() )
1633 if( !aCtx.
Request.variant_name().empty() )
1643 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1644 return tl::unexpected( *busy );
1648 if( !documentValidation )
1649 return tl::unexpected( documentValidation.error() );
1654 if( !aCtx.
Request.job_settings().output_path().empty() )
1670 switch( aCtx.
Request.fields().filter_scope() )
1672 case kiapi::schematic::jobs::BOMFilterScope::BFS_VISIBLE:
1676 case kiapi::schematic::jobs::BOMFilterScope::BFS_ALL:
1680 case kiapi::schematic::jobs::BOMFilterScope::BFS_REFERENCE:
1686 if( aCtx.
Request.fields().sort_direction() == kiapi::schematic::jobs::BOMSortDirection::BSD_ASCENDING )
1690 else if( aCtx.
Request.fields().sort_direction() == kiapi::schematic::jobs::BOMSortDirection::BSD_DESCENDING )
1695 for(
const kiapi::schematic::jobs::BOMField& field : aCtx.
Request.fields().fields() )
1697 bomJob.
m_fieldsOrdered.emplace_back( wxString::FromUTF8( field.name() ) );
1698 bomJob.
m_fieldsLabels.emplace_back( wxString::FromUTF8( field.label() ) );
1700 if( field.group_by() )
1701 bomJob.
m_fieldsGroupBy.emplace_back( wxString::FromUTF8( field.name() ) );
1707 if( !aCtx.
Request.variant_name().empty() )
1723 if( sheetName.IsEmpty() && aSheet->
GetScreen() )
1726 sheetName = fn.GetName();
1729 aInstance->set_name( sheetName.ToUTF8() );
1730 aInstance->set_filename( aSheet->
GetFileName().ToUTF8() );
1731 aInstance->set_page_number( aPath.
GetPageNumber().ToUTF8() );
1735 std::vector<SCH_ITEM*> childSheets;
1738 std::ranges::sort( childSheets,
1750 for(
SCH_ITEM* childItem : childSheets )
1753 kiapi::schematic::types::SheetInstance* childInstance = aInstance->add_children();
1767 if( !documentValidation )
1768 return tl::unexpected( documentValidation.error() );
1770 kiapi::schematic::commands::SchematicHierarchyResponse response;
1771 response.mutable_document()->CopyFrom( aCtx.
Request.document() );
1779 std::ranges::sort( topLevelSheets,
1791 for(
SCH_SHEET* topSheet : topLevelSheets )
1793 kiapi::schematic::types::SheetInstance* instance = response.add_top_level_sheets();
1804 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1805 return tl::unexpected( *busy );
1809 if( !documentValidation )
1810 return tl::unexpected( documentValidation.error() );
1813 const bool filterByType = aCtx.
Request.types_size() > 0;
1815 if( filterByType &&
types.empty() )
1817 ApiResponseStatus e;
1818 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1819 e.set_error_message(
"none of the requested types are valid for a Schematic object" );
1820 return tl::unexpected( e );
1823 std::set<KICAD_T> typeFilter(
types.begin(),
types.end() );
1827 if( !connectionGraph )
1829 ApiResponseStatus e;
1830 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1831 e.set_error_message(
"schematic has no connection graph" );
1832 return tl::unexpected( e );
1835 kiapi::schematic::commands::SchematicNetlistResponse response;
1836 response.mutable_document()->CopyFrom( aCtx.
Request.document() );
1838 for(
const auto& [key, subgraphList] : connectionGraph->
GetNetMap() )
1840 if( subgraphList.empty() )
1851 kiapi::schematic::types::SchematicNet* net = response.add_nets();
1852 net->set_name( key.Name.ToUTF8() );
1856 kiapi::schematic::types::SchematicNetSheetContents* sheetContents = net->add_sheets();
1857 PackSheetPath( *sheetContents->mutable_path(), subGraph->GetSheet() );
1859 for(
SCH_ITEM* item : subGraph->GetItems() )
1861 if( filterByType && !typeFilter.contains( item->Type() ) )
1864 sheetContents->add_items()->set_value( item->m_Uuid.AsStdString() );
1877 wxLogTrace(
traceApi,
"Received announce from frame %d at %s",
1883 CrossProbeAnnounceResponse response;
1884 response.set_status( CPS_OK );
1890 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
1891 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
1892 const wxString& aVariantName = wxEmptyString,
bool aRecursive =
false )
1902 findSymbolsAndPins( aSchematicSheetList, candidate, aSyncSymMap, aSyncPinMap, aVariantName, aRecursive );
1910 for(
unsigned ii = 0; ii < references.
GetCount(); ii++ )
1919 wxString fullRef = schRef.
GetRef() + refNum;
1922 if( fullRef.StartsWith( wxS(
"#" ) ) )
1926 if( refNum.compare( wxS(
"?" ) ) == 0 )
1930 auto symMatchIt = aSyncSymMap.find( fullRef );
1932 if( symMatchIt != aSyncSymMap.end() )
1934 symMatchIt->second.emplace_back( schRef );
1941 auto symPinMatchIt = aSyncPinMap.find( fullRef );
1943 if( symPinMatchIt != aSyncPinMap.end() )
1945 std::unordered_map<wxString, SCH_PIN*>& pinMap = symPinMatchIt->second;
1946 std::vector<SCH_PIN*> pinsOnSheet = symbol->
GetPins( &aSheetPath );
1950 int pinUnit =
pin->GetLibPin()->GetUnit();
1952 if( pinUnit > 0 && pinUnit != schRef.
GetUnit() )
1957 for(
const wxString&
pad :
1960 auto pinIt = pinMap.find(
pad );
1962 if( pinIt != pinMap.end() )
1964 pinIt->second =
pin;
1978 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
1979 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
1980 std::unordered_map<SCH_SHEET_PATH, bool>& aCache )
1982 auto cacheIt = aCache.find( aSheetPath );
1984 if( cacheIt != aCache.end() )
1985 return cacheIt->second;
1994 aSyncPinMap, aCache );
1998 aCache.emplace( aSheetPath,
false );
2008 aCache.emplace( aSheetPath,
false );
2012 for(
unsigned ii = 0; ii < references.
GetCount(); ii++ )
2020 wxString fullRef = schRef.
GetRef() + refNum;
2023 if( fullRef.StartsWith( wxS(
"#" ) ) )
2027 if( refNum.compare( wxS(
"?" ) ) == 0 )
2030 if( aSyncSymMap.find( fullRef ) == aSyncSymMap.end() )
2032 aCache.emplace( aSheetPath,
false );
2036 if( aSyncPinMap.find( fullRef ) != aSyncPinMap.end() )
2038 aCache.emplace( aSheetPath,
false );
2043 aCache.emplace( aSheetPath,
true );
2048std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>>
2050 const kiapi::common::commands::SyncSelection& aSync )
2052 std::unordered_map<wxString, std::vector<SCH_REFERENCE>> syncSymMap;
2053 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>> syncPinMap;
2054 std::unordered_map<SCH_SHEET_PATH, bool> fullyWantedCache;
2056 std::optional<wxString> focusSymbol;
2057 std::optional<std::pair<wxString, wxString>> focusPin;
2058 std::unordered_map<SCH_SHEET_PATH, std::vector<SCH_ITEM*>> focusItemResults;
2063 std::vector<SCH_SHEET_PATH> orderedSheets;
2064 orderedSheets.reserve( allSheetsList.size() );
2070 orderedSheets.push_back( sheetPath );
2073 const bool focusOnFirst = ( aSync.mode() == kiapi::common::commands::SSM_ITEMS_AND_NETS ) && aSync.has_focus_item();
2075 for(
const kiapi::common::commands::SelectionSpec& spec : aSync.items() )
2077 switch( spec.spec_case() )
2079 case kiapi::common::commands::SelectionSpec::kFootprint:
2081 wxString symRef = wxString::FromUTF8( spec.footprint().reference() );
2082 syncSymMap[symRef] = std::vector<SCH_REFERENCE>();
2086 case kiapi::common::commands::SelectionSpec::kPad:
2088 wxString symRef = wxString::FromUTF8( spec.pad().reference() );
2089 wxString padNum = wxString::FromUTF8( spec.pad().number() );
2090 syncPinMap[symRef][padNum] =
nullptr;
2101 const kiapi::common::commands::SelectionSpec& focusSpec = aSync.focus_item();
2103 if( focusSpec.has_footprint() )
2104 focusSymbol = wxString::FromUTF8( focusSpec.footprint().reference() );
2105 else if( focusSpec.has_pad() )
2106 focusPin = std::make_pair( wxString::FromUTF8( focusSpec.pad().reference() ),
2107 wxString::FromUTF8( focusSpec.pad().number() ) );
2111 auto flattenSyncMaps =
2112 [&syncSymMap, &syncPinMap]() -> std::vector<SCH_ITEM*>
2114 std::vector<SCH_ITEM*> allVec;
2116 for(
const auto& [symRef, symbols] : syncSymMap )
2119 allVec.push_back( ref.GetSymbol() );
2122 for(
const auto& [symRef, pinMap] : syncPinMap )
2124 for(
const auto& [padNum,
pin] : pinMap )
2127 allVec.push_back(
pin );
2134 auto clearSyncMaps =
2135 [&syncSymMap, &syncPinMap]()
2137 for(
auto& [symRef, symbols] : syncSymMap )
2140 for(
auto& [reference, pins] : syncPinMap )
2142 for(
auto& [number,
pin] : pins )
2147 auto syncMapsValuesEmpty =
2148 [&syncSymMap, &syncPinMap]() ->
bool
2150 for(
const auto& [symRef, symbols] : syncSymMap )
2152 if( symbols.size() > 0 )
2156 for(
const auto& [symRef, pins] : syncPinMap )
2158 for(
const auto& [padNum,
pin] : pins )
2168 auto checkFocusItems =
2173 auto findIt = syncSymMap.find( *focusSymbol );
2175 if( findIt != syncSymMap.end() )
2177 if( findIt->second.size() > 0 )
2178 focusItemResults[aSheet].push_back( findIt->second.front().GetSymbol() );
2183 auto findIt = syncPinMap.find( focusPin->first );
2185 if( findIt != syncPinMap.end() )
2187 if( findIt->second[focusPin->second] )
2188 focusItemResults[aSheet].push_back( findIt->second[focusPin->second] );
2193 auto makeRetForSheet =
2200 std::vector<SCH_ITEM*> itemsVector = flattenSyncMaps();
2206 kiidPath.push_back( item->m_Uuid );
2208 std::optional<SCH_SHEET_PATH> subsheetPath =
2215 syncPinMap, fullyWantedCache ) )
2217 itemsVector.push_back( item );
2221 return std::make_tuple( aSheet, aFocusItem, itemsVector );
2232 checkFocusItems( sheetPath );
2235 if( focusItemResults.size() > 0 )
2239 const std::vector<SCH_ITEM*>& items = focusItemResults[sheetPath];
2241 if( !items.empty() )
2242 return makeRetForSheet( sheetPath, items.front() );
2254 if( !syncMapsValuesEmpty() )
2257 return makeRetForSheet( sheetPath,
nullptr );
2262 return std::nullopt;
2269 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SyncSelection" ) )
2270 return tl::unexpected( *headless );
2272 SyncSelectionResponse response;
2276 if( !settings.
on_selection && aCtx.
Request.context() != SyncSelectionContext::SSC_EXPLICIT )
2278 response.set_status( CPS_DISABLED );
2279 response.set_message(
"implicit selection sync disabled by user" );
2284 if( aCtx.
Request.items_size() == 0 )
2292 response.set_status( CPS_OK );
2296 std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>> findRet =
2301 auto& [sheetPath, focusItem, items] = *findRet;
2309 if(
frame()->eeconfig()->m_CrossProbing.flash_selection )
2320 std::vector<SCH_ITEM*> itemPtrs;
2321 std::copy( items.begin(), items.end(), std::back_inserter( itemPtrs ) );
2332 response.set_status( CPS_OK );
2340 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"HighlightNets" ) )
2341 return tl::unexpected( *headless );
2343 HighlightNetsResponse response;
2351 response.set_status( CPS_DISABLED );
2358 if( aCtx.
Request.net_name_size() > 0 )
2359 net = wxString::FromUTF8( aCtx.
Request.net_name( 0 ) );
2363 response.set_status( CPS_OK );
2374 if( !documentValidation )
2375 return tl::unexpected( documentValidation.error() );
2379 if( aCtx.
Request.document().has_sheet_path() )
2383 if( std::optional<SCH_SHEET_PATH> resolvedPath =
schematic()->Hierarchy().GetSheetPathByKIIDPath( kiidPath ) )
2385 path = *resolvedPath;
2389 ExpandTextVariablesResponse reply;
2391 std::function<bool( wxString* )> textResolver =
2392 [&]( wxString* token ) ->
bool
2399 for(
const std::string& textMsg : aCtx.
Request.text() )
2403 if( aCtx.
Request.expand_env_vars() )
2406 reply.add_text(
text.ToUTF8() );
2415 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_SCHEMATIC )
2418 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2419 return tl::unexpected( *busy );
2422 return tl::unexpected( documentValidation.error() );
2424 VariantsResponse response;
2426 response.mutable_document()->CopyFrom( aCtx.
Request.document() );
2428 for(
const wxString&
name :
schematic()->GetVariantNames() )
2430 types::DesignVariant* var = response.add_variants();
2431 var->set_name(
name.ToUTF8() );
2432 var->set_description(
schematic()->GetVariantDescription(
name ).ToUTF8() );
2441 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_SCHEMATIC )
2444 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2445 return tl::unexpected( *busy );
2448 return tl::unexpected( documentValidation.error() );
2451 wxString
name = wxString::FromUTF8( aCtx.
Request.name() );
2455 ApiResponseStatus e;
2456 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2457 e.set_error_message( fmt::format(
"'{}' is not a usable new variant name", aCtx.
Request.name() ) );
2458 return tl::unexpected( e );
2463 if( aCtx.
Request.has_description() )
2475 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_SCHEMATIC )
2478 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2479 return tl::unexpected( *busy );
2482 return tl::unexpected( documentValidation.error() );
2487 wxString
name = wxString::FromUTF8( aCtx.
Request.name() );
2491 ApiResponseStatus e;
2492 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2493 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.name() ) );
2494 return tl::unexpected( e );
2499 ApiResponseStatus e;
2500 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2501 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.name() ) );
2502 return tl::unexpected( e );
2509 if(
frame()->Schematic().GetCurrentVariant().CmpNoCase(
name ) == 0 )
2522 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_SCHEMATIC )
2525 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2526 return tl::unexpected( *busy );
2529 return tl::unexpected( documentValidation.error() );
2534 wxString oldName = wxString::FromUTF8( aCtx.
Request.old_name() );
2535 wxString newName = wxString::FromUTF8( aCtx.
Request.new_name() );
2539 ApiResponseStatus e;
2540 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2541 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.old_name() ) );
2542 return tl::unexpected( e );
2547 ApiResponseStatus e;
2548 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2549 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.new_name() ) );
2550 return tl::unexpected( e );
2555 ApiResponseStatus e;
2556 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2557 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.old_name() ) );
2558 return tl::unexpected( e );
2563 ApiResponseStatus e;
2564 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2565 e.set_error_message( fmt::format(
"a variant named '{}' already exists", aCtx.
Request.new_name() ) );
2566 return tl::unexpected( e );
2569 schematic->RenameVariant( oldName, newName, &commit );
2580 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_SCHEMATIC )
2583 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2584 return tl::unexpected( *busy );
2587 return tl::unexpected( documentValidation.error() );
2592 wxString oldName = wxString::FromUTF8( aCtx.
Request.old_name() );
2593 wxString newName = wxString::FromUTF8( aCtx.
Request.new_name() );
2597 ApiResponseStatus e;
2598 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2599 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.old_name() ) );
2600 return tl::unexpected( e );
2605 ApiResponseStatus e;
2606 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2607 e.set_error_message( fmt::format(
"'{}' is not a valid variant name", aCtx.
Request.new_name() ) );
2608 return tl::unexpected( e );
2613 ApiResponseStatus e;
2614 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2615 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.old_name() ) );
2616 return tl::unexpected( e );
2621 ApiResponseStatus e;
2622 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2623 e.set_error_message( fmt::format(
"a variant named '{}' already exists", aCtx.
Request.new_name() ) );
2624 return tl::unexpected( e );
2627 schematic->CopyVariant( oldName, newName, &commit );
2638 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_SCHEMATIC )
2641 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2642 return tl::unexpected( *busy );
2645 return tl::unexpected( documentValidation.error() );
2648 wxString
name = wxString::FromUTF8( aCtx.
Request.name() );
2652 ApiResponseStatus e;
2653 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2654 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.name() ) );
2655 return tl::unexpected( e );
2666 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_SCHEMATIC )
2669 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2670 return tl::unexpected( *busy );
2673 return tl::unexpected( documentValidation.error() );
2681 ApiResponseStatus e;
2682 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2683 e.set_error_message( fmt::format(
"no variant named '{}' exists", aCtx.
Request.name() ) );
2684 return tl::unexpected( e );
2688 wxString
name = aCtx.
Request.has_name() ? wxString::FromUTF8( aCtx.
Request.name() ) : wxString();
2702 if( aCtx.
Request.document().type() != DocumentType::DOCTYPE_SCHEMATIC )
2706 return tl::unexpected( documentValidation.error() );
2708 CurrentVariantResponse response;
2710 if( wxString current =
schematic()->GetCurrentVariant(); !current.
IsEmpty() )
2711 response.set_name( current.ToUTF8() );
2720 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
2721 return tl::unexpected( *busy );
2725 ApiResponseStatus e;
2726 e.set_status( ApiStatusCode::AS_UNHANDLED );
2727 return tl::unexpected( e );
2734 ApiResponseStatus e;
2735 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2736 e.set_error_message(
"lib_id must specify both a library nickname and an entry name" );
2737 return tl::unexpected( e );
2745 ApiResponseStatus e;
2746 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2747 e.set_error_message( fmt::format(
"symbol '{}' not found", libId.
Format().
wx_str() ) );
2748 return tl::unexpected( e );
2754 if( aCtx.
Request.header().document().has_sheet_path() )
2764 ApiResponseStatus e;
2765 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2766 e.set_error_message( fmt::format(
"the requested sheet path {} is not valid for this schematic",
2768 return tl::unexpected( e );
2774 int unit = aCtx.
Request.has_unit() ? aCtx.
Request.unit().unit() : 1;
2778 ApiResponseStatus e;
2779 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
2780 e.set_error_message( fmt::format(
"unit {} is out of range for symbol '{}' ({} units)", unit,
2782 return tl::unexpected( e );
2787 std::unique_ptr<SCH_SYMBOL> symbol(
2788 std::make_unique<SCH_SYMBOL>( *libSymbol, libId, &targetPath, unit, 0, position ) );
2790 if( aCtx.
Request.has_orientation() )
2793 if( !aCtx.
Request.reference().empty() )
2795 symbol->SetRef( &targetPath, wxString::FromUTF8( aCtx.
Request.reference() ) );
2806 annotate |=
frame->eeconfig()->m_AnnotatePanel.automatic;
2817 schematic()->Settings().m_AnnotateStartNum, existingRefs,
false, &hierarchy );
2824 if(
frame->eeconfig()->m_AutoplaceFields.enable )
2830 commit->
Add( placed, targetScreen );
2835 PlaceFromLibraryResponse response;
2836 response.mutable_header()->CopyFrom( aCtx.
Request.header() );
2838 kiapi::schematic::types::SchematicSymbolInstance packed;
2840 if(
PackSymbol( &packed, placed, targetPath ) )
2841 response.mutable_item()->PackFrom( packed );
KICOMMON_API KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
static std::optional< ApiResponseStatus > applySchematicPlotSettings(const schematic::jobs::SchematicPlotSettings &aSettings, JOB_EXPORT_SCH_PLOT &aJob)
HANDLER_RESULT< types::RunJobResponse > ExecuteSchematicJob(KIWAY *aKiway, JOB &aJob)
bool findSymbolsAndPins(const SCH_SHEET_LIST &aSchematicSheetList, const SCH_SHEET_PATH &aSheetPath, std::unordered_map< wxString, std::vector< SCH_REFERENCE > > &aSyncSymMap, std::unordered_map< wxString, std::unordered_map< wxString, SCH_PIN * > > &aSyncPinMap, const wxString &aVariantName=wxEmptyString, bool aRecursive=false)
std::optional< std::tuple< SCH_SHEET_PATH, SCH_ITEM *, std::vector< SCH_ITEM * > > > findItemsFromSyncSelection(const SCHEMATIC &aSchematic, const kiapi::common::commands::SyncSelection &aSync)
bool sheetContainsOnlyWantedItems(const SCH_SHEET_LIST &aSchematicSheetList, const SCH_SHEET_PATH &aSheetPath, std::unordered_map< wxString, std::vector< SCH_REFERENCE > > &aSyncSymMap, std::unordered_map< wxString, std::unordered_map< wxString, SCH_PIN * > > &aSyncPinMap, std::unordered_map< SCH_SHEET_PATH, bool > &aCache)
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
void ApplySymbolInstance(SCH_SYMBOL *aSymbol, const kiapi::schematic::types::SchematicSymbolInstance &aInput, const SCH_SHEET_PATH &aPath, SCHEMATIC *aSchematic)
Apply placement-specific data to an aSymbol at aPath: reference, unit, and the per-placement attribut...
tl::expected< bool, ApiResponseStatus > UnpackSheet(SCH_SHEET *aOutput, const kiapi::schematic::types::SheetSymbol &aInput)
Unpack the every placement data from the input.
bool PackSheet(kiapi::schematic::types::SheetSymbol *aOutput, const SCH_SHEET *aInput, const SCH_SHEET_PATH &aPath)
bool PackSymbol(kiapi::schematic::types::SchematicSymbolInstance *aOutput, const SCH_SYMBOL *aInput, const SCH_SHEET_PATH &aPath)
void ApplySheetInstance(SCH_SHEET *aSheet, const kiapi::schematic::types::SheetSymbol &aInput, const SCH_SHEET_PATH &aParentPath, SCHEMATIC *aSchematic)
Apply the placement data in a sheet message to aSheet: page number and the variants the message carri...
bool UnpackSymbol(SCH_SYMBOL *aOutput, const kiapi::schematic::types::SchematicSymbolInstance &aInput)
Unpack the geometry, the library definition, fields, and the default-variant attributes that are shar...
BASE_SCREEN class implementation.
constexpr EDA_IU_SCALE schIUScale
static TOOL_ACTION selectionClear
Clear the current selection.
HANDLER_RESULT< bool > validateDocument(const DocumentSpecifier &aDocument)
HANDLER_RESULT< types::PageSettings > handleSetPageSettings(const HANDLER_CONTEXT< commands::SetPageSettings > &aCtx)
HANDLER_RESULT< std::optional< KIID > > validateItemHeaderDocument(const kiapi::common::types::ItemHeader &aHeader)
If the header is valid, returns the item container.
HANDLER_RESULT< types::PageSettings > handleGetPageSettings(const HANDLER_CONTEXT< commands::GetPageSettings > &aCtx)
API_HANDLER_EDITOR(EDA_BASE_FRAME *aFrame=nullptr)
static std::vector< KICAD_T > parseRequestedItemTypes(const google::protobuf::RepeatedField< int > &aTypes)
COMMIT * getCurrentCommit(const std::string &aClientName)
virtual void pushCurrentCommit(const std::string &aClientName, const wxString &aMessage)
std::set< std::string > m_activeClients
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< types::RunJobResponse > handleRunSchematicJobExportDxf(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportDxf > &aCtx)
wxString getDrawingSheetFileName() override
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportPng(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportPng > &aCtx)
HANDLER_RESULT< Empty > handleSetCurrentVariant(const HANDLER_CONTEXT< commands::SetCurrentVariant > &aCtx)
HANDLER_RESULT< kiapi::schematic::commands::SchematicHierarchyResponse > handleGetSchematicHierarchy(const HANDLER_CONTEXT< kiapi::schematic::commands::GetSchematicHierarchy > &aCtx)
HANDLER_RESULT< commands::VariantsResponse > handleGetVariants(const HANDLER_CONTEXT< commands::GetVariants > &aCtx)
std::unique_ptr< COMMIT > createCommit() override
Override this to create an appropriate COMMIT subclass for the frame in question.
SCHEMATIC * schematic() const
HANDLER_RESULT< commands::SelectionResponse > handleGetSelection(const HANDLER_CONTEXT< commands::GetSelection > &aCtx)
HANDLER_RESULT< Empty > handleCopyVariant(const HANDLER_CONTEXT< commands::CopyVariant > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportPdf(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportPdf > &aCtx)
SCH_SCREEN * resolveScreenFromDocument(const DocumentSpecifier &aDocument) const
Returns the sheet path's screen when one is given and it is found, or null.
HANDLER_RESULT< commands::CurrentVariantResponse > handleGetCurrentVariant(const HANDLER_CONTEXT< commands::GetCurrentVariant > &aCtx)
static std::set< KICAD_T > s_allowedTypes
HANDLER_RESULT< commands::GetItemsResponse > handleGetItemsById(const HANDLER_CONTEXT< commands::GetItemsById > &aCtx)
HANDLER_RESULT< google::protobuf::Empty > handleSaveDocument(const HANDLER_CONTEXT< commands::SaveDocument > &aCtx)
std::optional< PAGE_INFO > getPageSettings(const DocumentSpecifier &aDocument) override
HANDLER_RESULT< kiapi::schematic::commands::SchematicNetlistResponse > handleGetSchematicNetlist(const HANDLER_CONTEXT< kiapi::schematic::commands::GetSchematicNetlist > &aCtx)
std::optional< SCH_ITEM * > getItemById(const KIID &aId, SCH_SHEET_PATH *aPathOut=nullptr) const
std::shared_ptr< SCH_CONTEXT > m_context
std::optional< EDA_ITEM * > getItemFromDocument(const DocumentSpecifier &aDocument, const KIID &aId) override
TOOL_MANAGER * toolManager() const
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportSvg(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportSvg > &aCtx)
HANDLER_RESULT< Empty > handleDeleteVariant(const HANDLER_CONTEXT< commands::DeleteVariant > &aCtx)
HANDLER_RESULT< Empty > handleClearSelection(const HANDLER_CONTEXT< commands::ClearSelection > &aCtx)
HANDLER_RESULT< commands::HighlightNetsResponse > handleHighlightNets(const HANDLER_CONTEXT< commands::HighlightNets > &aCtx)
std::optional< ApiResponseStatus > checkForHeadless(const std::string &aCommandName) const
bool setPageSettings(const DocumentSpecifier &aDocument, const PAGE_INFO &aPageInfo) override
HANDLER_RESULT< commands::SavedSelectionResponse > handleSaveSelectionToString(const HANDLER_CONTEXT< commands::SaveSelectionToString > &aCtx)
HANDLER_RESULT< commands::CrossProbeAnnounceResponse > handleCrossProbeAnnounce(const HANDLER_CONTEXT< commands::CrossProbeAnnounce > &aCtx)
HANDLER_RESULT< std::unique_ptr< EDA_ITEM > > createItemForType(KICAD_T aType, EDA_ITEM *aContainer)
HANDLER_RESULT< kiapi::common::commands::PlaceFromLibraryResponse > handlePlaceSymbolFromLibrary(const HANDLER_CONTEXT< kiapi::schematic::commands::PlaceSymbolFromLibrary > &aCtx)
HANDLER_RESULT< commands::GetDocumentModifiedStateResponse > handleGetDocumentModifiedState(const HANDLER_CONTEXT< commands::GetDocumentModifiedState > &aCtx) override
HANDLER_RESULT< Empty > handleRenameVariant(const HANDLER_CONTEXT< commands::RenameVariant > &aCtx)
void filterValidSchTypes(std::set< KICAD_T > &aTypeList)
std::optional< TITLE_BLOCK * > getTitleBlock(const DocumentSpecifier &aDocument) override
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportBOM(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportBOM > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportPs(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportPs > &aCtx)
HANDLER_RESULT< commands::SavedDocumentResponse > handleSaveDocumentToString(const HANDLER_CONTEXT< commands::SaveDocumentToString > &aCtx)
PROJECT & project() const
void onModified() override
API_HANDLER_SCH(SCH_EDIT_FRAME *aFrame)
bool packSchItem(google::protobuf::Any &aOut, SCH_ITEM *aItem, const SCH_SHEET_PATH &aPath)
Serializes a schematic item into aOut, using path-aware packing for symbols and sheets.
HANDLER_RESULT< Empty > handleAddVariant(const HANDLER_CONTEXT< commands::AddVariant > &aCtx)
HANDLER_RESULT< types::ItemRequestStatus > handleCreateUpdateItemsInternal(bool aCreate, const std::string &aClientName, const types::ItemHeader &aHeader, const google::protobuf::RepeatedPtrField< google::protobuf::Any > &aItems, std::function< void(commands::ItemStatus, google::protobuf::Any)> aItemHandler) override
HANDLER_RESULT< commands::GetOpenDocumentsResponse > handleGetOpenDocuments(const HANDLER_CONTEXT< commands::GetOpenDocuments > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportNetlist(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportNetlist > &aCtx)
HANDLER_RESULT< google::protobuf::Empty > handleRevertDocument(const HANDLER_CONTEXT< commands::RevertDocument > &aCtx)
HANDLER_RESULT< commands::SelectionResponse > handleAddToSelection(const HANDLER_CONTEXT< commands::AddToSelection > &aCtx)
HANDLER_RESULT< commands::SelectionResponse > handleRemoveFromSelection(const HANDLER_CONTEXT< commands::RemoveFromSelection > &aCtx)
HANDLER_RESULT< commands::ExpandTextVariablesResponse > handleExpandTextVariables(const HANDLER_CONTEXT< commands::ExpandTextVariables > &aCtx)
void deleteItemsInternal(std::map< KIID, ItemDeletionStatus > &aItemsToDelete, const std::string &aClientName) override
void packSheetInstance(kiapi::schematic::types::SheetInstance *aInstance, SCH_SHEET_PATH &aPath, SCH_SHEET *aSheet)
tl::expected< bool, ApiResponseStatus > validateDocumentInternal(const DocumentSpecifier &aDocument) const override
HANDLER_RESULT< commands::SyncSelectionResponse > handleSyncSelection(const HANDLER_CONTEXT< commands::SyncSelection > &aCtx)
SCH_EDIT_FRAME * frame() const
HANDLER_RESULT< google::protobuf::Empty > handleSaveCopyOfDocument(const HANDLER_CONTEXT< commands::SaveCopyOfDocument > &aCtx)
SCH_CONTEXT * context() const
void setDrawingSheetFileName(const wxString &aFileName) override
HANDLER_RESULT< Empty > handleSetVariantDescription(const HANDLER_CONTEXT< commands::SetVariantDescription > &aCtx)
HANDLER_RESULT< commands::GetItemsResponse > handleGetItems(const HANDLER_CONTEXT< commands::GetItems > &aCtx)
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
void SetContentModified(bool aModified=true)
Represent a set of changes (additions, deletions or modifications) of a data model (e....
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Calculate the connectivity of a schematic and generate netlists.
const NET_MAP & GetNetMap() const
A subgraph is a set of items that are electrically connected on a single sheet.
static PRIORITY GetDriverPriority(SCH_ITEM *aDriver)
Return the priority (higher is more important) of a candidate driver.
const SCH_CONNECTION * GetDriverConnection() const
static void RegisterPeer(FRAME_T aFrameType, const std::string &aSocketPath)
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
A base class for most all the KiCad significant classes used in schematics and boards.
KICAD_T Type() const
Returns the type of object.
virtual wxString GetFriendlyName() const
EE_TYPE OfType(KICAD_T aType) const
std::vector< wxString > m_variantNames
wxString m_stringDelimiter
wxString m_fieldDelimiter
bool m_includeByteOrderMark
std::vector< wxString > m_fieldsOrdered
wxString m_refRangeDelimiter
std::vector< wxString > m_fieldsLabels
std::vector< wxString > m_fieldsGroupBy
wxString m_bomFmtPresetName
BOM_FILTER_SCOPE m_filterScope
std::vector< wxString > m_variantNames
JOB_PAGE_SIZE m_pageSizeSelect
bool m_useBackgroundColor
std::vector< wxString > m_plotPages
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
wxString AsString() const
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
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.
Define a library symbol object.
int GetUnitCount() const override
Describe the page size and margins of a paper page on which to eventually print or plot.
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
Container for project specific data.
virtual const wxString GetProjectPath() const
Return the full path of the project.
virtual const wxString GetProjectName() const
Return the short name of the project.
wxString m_SchDrawingSheetFileName
Holds all the data relating to one schematic.
SCHEMATIC_SETTINGS & Settings() const
SCH_SCREEN * GetCurrentScreen() const
SCH_ITEM * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
SCH_SHEET * GetTopLevelSheet(int aIndex=0) const
wxString GetCurrentVariant() const
Return the current variant being edited.
CONNECTION_GRAPH * ConnectionGraph() const
bool ResolveTextVar(const SCH_SHEET_PATH *aSheetPath, wxString *token, int aDepth) const
std::vector< SCH_SHEET * > GetTopLevelSheets() const
Get the list of top-level sheets.
SCH_SHEET_PATH & CurrentSheet() const
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
EESCHEMA_SETTINGS * eeconfig() const
Schematic editor (Eeschema) main window.
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, PROGRESS_REPORTER *aProgressReporter=nullptr, bool aCleanupDone=false)
Generate the connection data for the entire schematic hierarchy.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
void SetCurrentVariant(const wxString &aVariantName)
void UpdateVariantSelectionCtrl(const wxArrayString &aVariantNames)
Update the variant name control on the main toolbar.
SCH_SHEET_PATH & GetCurrentSheet() const
void LoadDrawingSheet()
Load the drawing sheet file.
void SetSyncingSelection(bool aSet)
void StartCrossProbeFlash(const std::vector< SCH_ITEM * > &aItems)
void HandleRemoteNetHighlight(const wxString &aNetName)
A set of SCH_ITEMs (i.e., without duplicates).
A SCH_IO derivation for loading schematic files using the new s-expression file format.
void FormatSchematicToFormatter(OUTPUTFORMATTER *aOut, SCH_SHEET *aSheet, SCHEMATIC *aSchematic, const std::map< std::string, UTF8 > *aProperties=nullptr)
Serialize a schematic sheet to an OUTPUTFORMATTER without file I/O or Prettify.
void Format(SCH_SHEET *aSheet)
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual bool IsConnectable() const
void SetConnectivityDirty(bool aDirty=true)
void SwapItemData(SCH_ITEM *aImage)
Swap data between aItem and aImage.
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
void SortByReferenceOnly()
Sort the list of references by reference.
void ReannotateByOptions(ANNOTATE_ORDER_T aSortOption, ANNOTATE_ALGO_T aAlgoOption, int aStartNumber, const SCH_REFERENCE_LIST &aAdditionalRefs, bool aStartAtCurrent, SCH_SHEET_LIST *aHierarchy)
Forces reannotation of the provided references.
void SetRefDesTracker(std::shared_ptr< REFDES_TRACKER > aTracker)
void AddItem(const SCH_REFERENCE &aItem)
void UpdateAnnotation()
Update the symbol references for the schematic project (or the current sheet).
A helper to define a symbol's reference designator in a schematic.
bool AlwaysAnnotate() const
Verify the reference should always be automatically annotated.
void Split()
Attempt to split the reference designator into a name (U) and number (1).
bool IsSplitNeeded()
Determine if this reference needs to be split or if it likely already has been.
SCH_SYMBOL * GetSymbol() const
wxString GetRefNumber() const
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
void GetSheets(std::vector< SCH_ITEM * > *aItems) const
Similar to Items().OfType( SCH_SHEET_T ), but return the sheets in a deterministic order (L-R,...
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
SCH_ITEM * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
Fetch a SCH_ITEM by ID.
wxString GetNextPageNumber() const
void GetSymbols(SCH_REFERENCE_LIST &aReferences, SYMBOL_FILTER aSymbolFilter, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
bool TestForRecursion(const SCH_SHEET_LIST &aSrcSheetHierarchy, const wxString &aDestFileName)
Test every SCH_SHEET_PATH in this SCH_SHEET_LIST to verify if adding the sheets stored in aSrcSheetHi...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
int ComparePageNum(const SCH_SHEET_PATH &aSheetPathToTest) const
Compare sheets by their page number.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, SYMBOL_FILTER aSymbolFilter, bool aForceIncludeOrphanSymbols=false) const
Adds SCH_REFERENCE object to aReferences for each symbol in the sheet.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_ITEM * ResolveItem(const KIID &aID) const
Fetch a SCH_ITEM by ID.
SCH_SCREEN * LastScreen()
wxString GetPageNumber() const
bool IsContainedWithin(const SCH_SHEET_PATH &aSheetPathToTest) const
Check if this path is contained inside aSheetPathToTest.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
wxString GetFileName() const
Return the filename corresponding to this sheet.
void AddInstance(const SCH_SHEET_INSTANCE &aInstance)
SCH_SCREEN * GetScreen() const
wxString GetShownName(RESOLUTION_CONTEXT aContext) const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
virtual void Serialize(google::protobuf::Any &aContainer) const
Serializes this object to the given Any message.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
A wrapper for reporting to a wxString object.
A type-safe container of any type.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, RESOLUTION_CONTEXT aContext)
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
static const std::string KiCadSchematicFileExtension
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.
KICOMMON_API void PackProject(types::ProjectSpecifier &aOutput, const PROJECT &aInput)
KICOMMON_API KIID_PATH UnpackSheetPath(const types::SheetPath &aInput)
KICOMMON_API std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
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 PackSheetPath(types::SheetPath &aOutput, const KIID_PATH &aInput)
KICOMMON_API LIB_ID UnpackLibId(const types::LibraryIdentifier &aId)
const KICOMMON_API std::string KiwayClientName
const KICOMMON_API std::string StandaloneCrossProbeClientName
constexpr int MIN_PNG_DPI
constexpr int MAX_PNG_DPI
std::shared_ptr< SCH_CONTEXT > CreateSchFrameContext(SCH_EDIT_FRAME *aFrame)
Class to handle a set of SCH_ITEMs.
std::vector< EDA_ITEM * > EDA_ITEMS
ANNOTATE_ORDER_T
Schematic annotation order options.
ANNOTATE_ALGO_T
Schematic annotation type options.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
@ SYMBOL_FILTER_NON_POWER
wxString GetDefaultVariantName()
std::vector< wxString > ExpandStackedPinNotation(const wxString &aPinName, bool *aValid)
Expand stacked pin notation like [1,2,3], [1-4], [A1-A4], or [AA1-AA3,AB4,CD12-CD14] into individual ...
bool on_selection
Synchronize the selection for multiple items too.
bool auto_highlight
Automatically turn on highlight mode in the target frame.
RequestMessageType Request
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
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.
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.