26#include <magic_enum.hpp>
46#include <wx/filename.h>
48#include <api/common/types/base_types.pb.h>
50using namespace kiapi::common::commands;
51using kiapi::common::types::CommandStatus;
52using kiapi::common::types::DocumentType;
53using kiapi::common::types::ItemRequestStatus;
80 types::RunJobResponse response;
85 response.add_output_path(
output.m_outputPath.ToUTF8() );
89 response.set_status( types::JobStatus::JS_SUCCESS );
93 response.set_status( types::JobStatus::JS_ERROR );
94 response.set_message( fmt::format(
"Schematic export job '{}' failed with exit code {}: {}",
96 reporter.GetMessages().ToStdString() ) );
113 using namespace kiapi::schematic::jobs;
114 using namespace kiapi::schematic::types;
148 return std::make_unique<SCH_COMMIT>(
m_frame );
150 return std::make_unique<SCH_COMMIT>(
toolManager() );
175tl::expected<bool, ApiResponseStatus>
178 if( aDocument.type() != DocumentType::DOCTYPE_SCHEMATIC )
181 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
182 e.set_error_message(
"the requested document is not a schematic" );
183 return tl::unexpected( e );
188 if( aDocument.project().name().compare( prj.
GetProjectName().ToUTF8() ) != 0 )
191 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
192 e.set_error_message( fmt::format(
"the requested project {} is not open",
193 aDocument.project().name() ) );
194 return tl::unexpected( e );
197 if( aDocument.project().path().compare( prj.
GetProjectPath().ToUTF8() ) != 0 )
200 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
201 e.set_error_message( fmt::format(
"the requested project {} is not open at path {}",
202 aDocument.project().name(),
203 aDocument.project().path() ) );
204 return tl::unexpected( e );
207 if( aDocument.has_sheet_path() )
214 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
215 e.set_error_message( fmt::format(
"the requested sheet path {} is not valid for this schematic",
216 path.AsString().ToStdString() ) );
217 return tl::unexpected( e );
227 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
228 return tl::unexpected( *busy );
232 if( !documentValidation )
233 return tl::unexpected( documentValidation.error() );
235 if( !
context()->SaveSchematic() )
238 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
239 e.set_error_message(
"failed to save schematic" );
240 return tl::unexpected( e );
243 return google::protobuf::Empty();
250 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
251 return tl::unexpected( *busy );
255 if( !documentValidation )
256 return tl::unexpected( documentValidation.error() );
258 wxFileName schematicPath(
project().AbsolutePath( wxString::FromUTF8( aCtx.
Request.path() ) ) );
260 if( !schematicPath.IsOk() || !schematicPath.IsDirWritable() )
263 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
265 fmt::format(
"save path '{}' could not be opened", schematicPath.GetFullPath().ToStdString() ) );
266 return tl::unexpected( e );
269 if( schematicPath.FileExists() && ( !schematicPath.IsFileWritable() || !aCtx.
Request.options().overwrite() ) )
272 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
273 e.set_error_message( fmt::format(
"save path '{}' exists and cannot be overwritten",
274 schematicPath.GetFullPath().ToStdString() ) );
275 return tl::unexpected( e );
281 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
282 e.set_error_message( fmt::format(
"save path '{}' must have a kicad_sch extension",
283 schematicPath.GetFullPath().ToStdString() ) );
284 return tl::unexpected( e );
287 bool includeProject =
true;
289 if( aCtx.
Request.has_options() )
290 includeProject = aCtx.
Request.options().include_project();
292 if( !
context()->SaveSchematicCopy( schematicPath.GetFullPath(), includeProject ) )
295 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
296 e.set_error_message(
"failed to save schematic copy" );
297 return tl::unexpected( e );
300 return google::protobuf::Empty();
307 if( aCtx.
Request.type() != DocumentType::DOCTYPE_SCHEMATIC )
312 e.set_status( ApiStatusCode::AS_UNHANDLED );
313 return tl::unexpected( e );
316 GetOpenDocumentsResponse response;
317 common::types::DocumentSpecifier doc;
319 wxFileName fn(
m_context->GetCurrentFileName() );
321 doc.set_type( DocumentType::DOCTYPE_SCHEMATIC );
323 if( std::optional<SCH_SHEET_PATH>
path =
m_context->GetCurrentSheet() )
328 response.mutable_documents()->Add( std::move( doc ) );
335 std::erase_if( aTypeList,
345 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
346 return tl::unexpected( *busy );
351 return tl::unexpected( valid.error() );
354 std::set<KICAD_T> typesRequested, typesInserted;
357 typesRequested.insert( type );
361 if( typesRequested.empty() )
364 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
365 e.set_error_message(
"none of the requested types are valid for a Schematic object" );
366 return tl::unexpected( e );
370 std::optional<SCH_SHEET_PATH> pathFilter;
372 if( aCtx.
Request.header().document().has_sheet_path() )
378 std::map<KICAD_T, std::vector<std::pair<EDA_ITEM*, SCH_SHEET_PATH>>> itemMap;
383 const SCH_SCREEN* aScreen = aPath.LastScreen();
387 itemMap[ aItem->Type() ].emplace_back( aItem, aPath );
389 aItem->RunOnChildren(
392 itemMap[ aChild->
Type() ].emplace_back( aChild, aPath );
400 processScreen( *pathFilter );
405 processScreen(
path );
408 GetItemsResponse response;
409 google::protobuf::Any
any;
416 if( typesInserted.contains( type ) )
419 for(
const auto& [item, itemPath] : itemMap[type] )
423 kiapi::schematic::types::SchematicSymbolInstance symbol;
428 any.PackFrom( symbol );
432 kiapi::schematic::types::SheetSymbol sheet;
437 any.PackFrom( sheet );
441 item->Serialize(
any );
444 response.mutable_items()->Add( std::move(
any ) );
448 response.set_status( ItemRequestStatus::IRS_OK );
455 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
456 return tl::unexpected( *busy );
461 e.set_status( ApiStatusCode::AS_UNHANDLED );
462 return tl::unexpected( e );
466 std::optional<SCH_SHEET_PATH> pathFilter;
468 if( aCtx.
Request.header().document().has_sheet_path() )
474 GetItemsResponse response;
476 google::protobuf::Any
any;
478 for(
const types::KIID& idProto : aCtx.
Request.items() )
480 KIID id( idProto.value() );
486 item = pathFilter->ResolveItem(
id );
487 itemPath = *pathFilter;
491 item = hierarchy.
ResolveItem(
id, &itemPath,
true );
499 kiapi::schematic::types::SchematicSymbolInstance symbol;
504 any.PackFrom( symbol );
508 kiapi::schematic::types::SheetSymbol sheet;
513 any.PackFrom( sheet );
520 response.mutable_items()->Add( std::move(
any ) );
523 if( response.items().empty() )
526 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
527 e.set_error_message(
"none of the requested IDs were found or valid" );
528 return tl::unexpected( e );
531 response.set_status( ItemRequestStatus::IRS_OK );
541 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
542 e.set_error_message(
"Tried to create an item in a null container" );
543 return tl::unexpected( e );
549 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
550 e.set_error_message( fmt::format(
"type {} is not supported by the schematic API handler",
551 magic_enum::enum_name( aType ) ) );
552 return tl::unexpected( e );
558 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
559 e.set_error_message( fmt::format(
"Tried to create a pin in {}, which is not a symbol",
561 return tl::unexpected( e );
566 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
567 e.set_error_message( fmt::format(
"Tried to create a sheet symbol in {}, which is not a "
570 return tl::unexpected( e );
575 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
576 e.set_error_message( fmt::format(
"Tried to create a symbol in {}, which is not a "
579 return tl::unexpected( e );
584 if( created && !created->GetParent() )
585 created->SetParent( aContainer );
590 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
591 e.set_error_message( fmt::format(
"Tried to create an item of type {}, which is unhandled",
592 magic_enum::enum_name( aType ) ) );
593 return tl::unexpected( e );
601 const std::string& aClientName,
602 const types::ItemHeader &aHeader,
603 const google::protobuf::RepeatedPtrField<google::protobuf::Any>& aItems,
604 std::function<
void( ItemStatus, google::protobuf::Any )> aItemHandler )
610 if( !containerResult && containerResult.error().status() == ApiStatusCode::AS_UNHANDLED )
613 e.set_status( ApiStatusCode::AS_UNHANDLED );
614 return tl::unexpected( e );
616 else if( !containerResult )
618 e.CopyFrom( containerResult.error() );
619 return tl::unexpected( e );
626 if( aHeader.document().has_sheet_path() )
638 for(
const google::protobuf::Any& anyItem : aItems )
645 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
646 status.set_error_message( fmt::format(
"Could not decode a valid type from {}",
647 anyItem.type_url() ) );
648 aItemHandler( status, anyItem );
656 if( !creationResult )
658 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
659 status.set_error_message( creationResult.error().error_message() );
660 aItemHandler( status, anyItem );
664 std::unique_ptr<EDA_ITEM> item( std::move( *creationResult ) );
666 bool unpacked =
false;
670 kiapi::schematic::types::SchematicSymbolInstance symbol;
671 unpacked = anyItem.UnpackTo( &symbol )
676 kiapi::schematic::types::SheetSymbol sheetProto;
677 unpacked = anyItem.UnpackTo( &sheetProto );
683 if( tl::expected<bool, ApiResponseStatus>
result =
UnpackSheet( sheet, sheetProto );
695 if( instance.
m_Path.empty() )
706 return tl::unexpected(
result.error() );
712 unpacked = item->Deserialize( anyItem );
717 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
718 e.set_error_message( fmt::format(
"could not unpack {} from request",
719 item->GetClass().ToStdString() ) );
720 return tl::unexpected( e );
726 existingItem = targetPath.
ResolveItem( item->m_Uuid );
729 existingPath = targetPath;
731 if( aCreate && existingItem )
733 status.set_code( ItemStatusCode::ISC_EXISTING );
734 status.set_error_message( fmt::format(
"an item with UUID {} already exists",
735 item->m_Uuid.AsStdString() ) );
736 aItemHandler( status, anyItem );
739 else if( !aCreate && !existingItem )
741 status.set_code( ItemStatusCode::ISC_NONEXISTENT );
742 status.set_error_message( fmt::format(
"an item with UUID {} does not exist",
743 item->m_Uuid.AsStdString() ) );
744 aItemHandler( status, anyItem );
752 if( itemScreen != targetScreen )
754 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
755 status.set_error_message( fmt::format(
"item {} exists on a different sheet than targeted",
756 item->m_Uuid.AsStdString() ) );
757 aItemHandler( status, anyItem );
772 parentPath = targetPath;
774 parentPath = existingPath;
778 if( !destFilePath.IsEmpty() )
785 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
786 status.set_error_message(
"sheet update would create recursive hierarchy" );
787 aItemHandler( status, anyItem );
793 status.set_code( ItemStatusCode::ISC_OK );
794 google::protobuf::Any newItem;
799 commit->
Add( createdItem, targetScreen );
803 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
804 e.set_error_message(
"could not add the requested item to its parent container" );
805 return tl::unexpected( e );
810 kiapi::schematic::types::SchematicSymbolInstance symbol;
813 newItem.PackFrom( symbol );
817 kiapi::schematic::types::SheetSymbol sheet;
820 newItem.PackFrom( sheet );
829 commit->
Modify( existingItem, targetScreen );
835 kiapi::schematic::types::SchematicSymbolInstance symbol;
838 newItem.PackFrom( symbol );
843 kiapi::schematic::types::SheetSymbol sheet;
846 newItem.PackFrom( sheet );
854 aItemHandler( status, newItem );
860 :
_(
"Modified items via API" ) );
864 return ItemRequestStatus::IRS_OK;
869 const std::string& aClientName )
874 for(
auto& [
id, status] : aItemsToDelete )
884 status = ItemDeletionStatus::IDS_IMMUTABLE;
889 status = ItemDeletionStatus::IDS_OK;
913 wxCHECK(
m_context->GetCurrentSheet(), std::nullopt );
914 return &
m_context->GetCurrentSheet()->LastScreen()->GetTitleBlock();
920 wxCHECK(
m_context->GetCurrentSheet(), std::nullopt );
921 return m_context->GetCurrentSheet()->LastScreen()->GetPageSettings();
927 wxCHECK(
m_context->GetCurrentSheet(),
false );
928 m_context->GetCurrentSheet()->LastScreen()->SetPageSettings( aPageInfo );
962 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
963 return tl::unexpected( *busy );
967 if( !documentValidation )
968 return tl::unexpected( documentValidation.error() );
970 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_SVG>();
971 plotJob->m_filename =
m_context->GetCurrentFileName();
973 if( !aCtx.
Request.job_settings().output_path().empty() )
974 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.
Request.job_settings().output_path() ) );
976 const kiapi::schematic::jobs::SchematicPlotSettings& settings = aCtx.
Request.plot_settings();
978 plotJob->m_drawingSheet = wxString::FromUTF8( settings.drawing_sheet() );
979 plotJob->m_defaultFont = wxString::FromUTF8( settings.default_font() );
980 plotJob->m_variant = wxString::FromUTF8( settings.variant() );
981 plotJob->m_plotAll = settings.plot_all();
982 plotJob->m_plotDrawingSheet = settings.plot_drawing_sheet();
983 plotJob->m_show_hop_over = settings.show_hop_over();
984 plotJob->m_blackAndWhite = settings.black_and_white();
985 plotJob->m_useBackgroundColor = settings.use_background_color();
986 plotJob->m_minPenWidth = settings.min_pen_width();
987 plotJob->m_theme = wxString::FromUTF8( settings.theme() );
989 plotJob->m_plotPages.clear();
991 for(
const std::string& page : settings.plot_pages() )
992 plotJob->m_plotPages.push_back( wxString::FromUTF8( page ) );
994 if( aCtx.
Request.plot_settings().page_size() != kiapi::schematic::jobs::SchematicJobPageSize::SJPS_UNKNOWN )
1006 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1007 return tl::unexpected( *busy );
1011 if( !documentValidation )
1012 return tl::unexpected( documentValidation.error() );
1014 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_DXF>();
1015 plotJob->m_filename =
m_context->GetCurrentFileName();
1017 if( !aCtx.
Request.job_settings().output_path().empty() )
1018 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.
Request.job_settings().output_path() ) );
1020 const kiapi::schematic::jobs::SchematicPlotSettings& settings = aCtx.
Request.plot_settings();
1022 plotJob->m_drawingSheet = wxString::FromUTF8( settings.drawing_sheet() );
1023 plotJob->m_defaultFont = wxString::FromUTF8( settings.default_font() );
1024 plotJob->m_variant = wxString::FromUTF8( settings.variant() );
1025 plotJob->m_plotAll = settings.plot_all();
1026 plotJob->m_plotDrawingSheet = settings.plot_drawing_sheet();
1027 plotJob->m_show_hop_over = settings.show_hop_over();
1028 plotJob->m_blackAndWhite = settings.black_and_white();
1029 plotJob->m_useBackgroundColor = settings.use_background_color();
1030 plotJob->m_minPenWidth = settings.min_pen_width();
1031 plotJob->m_theme = wxString::FromUTF8( settings.theme() );
1033 plotJob->m_plotPages.clear();
1035 for(
const std::string& page : settings.plot_pages() )
1036 plotJob->m_plotPages.push_back( wxString::FromUTF8( page ) );
1038 if( aCtx.
Request.plot_settings().page_size() != kiapi::schematic::jobs::SchematicJobPageSize::SJPS_UNKNOWN )
1050 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1051 return tl::unexpected( *busy );
1055 if( !documentValidation )
1056 return tl::unexpected( documentValidation.error() );
1058 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_PDF>(
false );
1059 plotJob->m_filename =
m_context->GetCurrentFileName();
1061 if( !aCtx.
Request.job_settings().output_path().empty() )
1062 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.
Request.job_settings().output_path() ) );
1064 const kiapi::schematic::jobs::SchematicPlotSettings& settings = aCtx.
Request.plot_settings();
1066 plotJob->m_drawingSheet = wxString::FromUTF8( settings.drawing_sheet() );
1067 plotJob->m_defaultFont = wxString::FromUTF8( settings.default_font() );
1068 plotJob->m_variant = wxString::FromUTF8( settings.variant() );
1069 plotJob->m_plotAll = settings.plot_all();
1070 plotJob->m_plotDrawingSheet = settings.plot_drawing_sheet();
1071 plotJob->m_show_hop_over = settings.show_hop_over();
1072 plotJob->m_blackAndWhite = settings.black_and_white();
1073 plotJob->m_useBackgroundColor = settings.use_background_color();
1074 plotJob->m_minPenWidth = settings.min_pen_width();
1075 plotJob->m_theme = wxString::FromUTF8( settings.theme() );
1077 plotJob->m_plotPages.clear();
1079 for(
const std::string& page : settings.plot_pages() )
1080 plotJob->m_plotPages.push_back( wxString::FromUTF8( page ) );
1082 if( aCtx.
Request.plot_settings().page_size() != kiapi::schematic::jobs::SchematicJobPageSize::SJPS_UNKNOWN )
1087 plotJob->m_PDFPropertyPopups = aCtx.
Request.property_popups();
1088 plotJob->m_PDFHierarchicalLinks = aCtx.
Request.hierarchical_links();
1089 plotJob->m_PDFMetadata = aCtx.
Request.include_metadata();
1098 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1099 return tl::unexpected( *busy );
1103 if( !documentValidation )
1104 return tl::unexpected( documentValidation.error() );
1106 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_PS>();
1107 plotJob->m_filename =
m_context->GetCurrentFileName();
1109 if( !aCtx.
Request.job_settings().output_path().empty() )
1110 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.
Request.job_settings().output_path() ) );
1112 const kiapi::schematic::jobs::SchematicPlotSettings& settings = aCtx.
Request.plot_settings();
1114 plotJob->m_drawingSheet = wxString::FromUTF8( settings.drawing_sheet() );
1115 plotJob->m_defaultFont = wxString::FromUTF8( settings.default_font() );
1116 plotJob->m_variant = wxString::FromUTF8( settings.variant() );
1117 plotJob->m_plotAll = settings.plot_all();
1118 plotJob->m_plotDrawingSheet = settings.plot_drawing_sheet();
1119 plotJob->m_show_hop_over = settings.show_hop_over();
1120 plotJob->m_blackAndWhite = settings.black_and_white();
1121 plotJob->m_useBackgroundColor = settings.use_background_color();
1122 plotJob->m_minPenWidth = settings.min_pen_width();
1123 plotJob->m_theme = wxString::FromUTF8( settings.theme() );
1125 plotJob->m_plotPages.clear();
1127 for(
const std::string& page : settings.plot_pages() )
1128 plotJob->m_plotPages.push_back( wxString::FromUTF8( page ) );
1130 if( aCtx.
Request.plot_settings().page_size() != kiapi::schematic::jobs::SchematicJobPageSize::SJPS_UNKNOWN )
1142 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1143 return tl::unexpected( *busy );
1147 if( !documentValidation )
1148 return tl::unexpected( documentValidation.error() );
1150 if( aCtx.
Request.format() == kiapi::schematic::jobs::SchematicNetlistFormat::SNF_UNKNOWN )
1152 ApiResponseStatus e;
1153 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1154 e.set_error_message(
"RunSchematicJobExportNetlist requires a valid format" );
1155 return tl::unexpected( e );
1161 if( !aCtx.
Request.job_settings().output_path().empty() )
1166 if( !aCtx.
Request.variant_name().empty() )
1176 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1177 return tl::unexpected( *busy );
1181 if( !documentValidation )
1182 return tl::unexpected( documentValidation.error() );
1187 if( !aCtx.
Request.job_settings().output_path().empty() )
1202 if( aCtx.
Request.fields().sort_direction() == kiapi::schematic::jobs::BOMSortDirection::BSD_ASCENDING )
1206 else if( aCtx.
Request.fields().sort_direction() == kiapi::schematic::jobs::BOMSortDirection::BSD_DESCENDING )
1211 for(
const kiapi::schematic::jobs::BOMField& field : aCtx.
Request.fields().fields() )
1213 bomJob.
m_fieldsOrdered.emplace_back( wxString::FromUTF8( field.name() ) );
1214 bomJob.
m_fieldsLabels.emplace_back( wxString::FromUTF8( field.label() ) );
1216 if( field.group_by() )
1217 bomJob.
m_fieldsGroupBy.emplace_back( wxString::FromUTF8( field.name() ) );
1223 if( !aCtx.
Request.variant_name().empty() )
1239 if( sheetName.IsEmpty() && aSheet->
GetScreen() )
1242 sheetName = fn.GetName();
1245 aInstance->set_name( sheetName.ToUTF8() );
1246 aInstance->set_filename( aSheet->
GetFileName().ToUTF8() );
1247 aInstance->set_page_number( aPath.
GetPageNumber().ToUTF8() );
1251 std::vector<SCH_ITEM*> childSheets;
1254 std::ranges::sort( childSheets,
1266 for(
SCH_ITEM* childItem : childSheets )
1269 kiapi::schematic::types::SheetInstance* childInstance = aInstance->add_children();
1283 if( !documentValidation )
1284 return tl::unexpected( documentValidation.error() );
1286 kiapi::schematic::types::SchematicHierarchyResponse response;
1287 response.mutable_document()->CopyFrom( aCtx.
Request.document() );
1295 std::ranges::sort( topLevelSheets,
1307 for(
SCH_SHEET* topSheet : topLevelSheets )
1309 kiapi::schematic::types::SheetInstance* instance = response.add_top_level_sheets();
1320 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1321 return tl::unexpected( *busy );
1325 if( !documentValidation )
1326 return tl::unexpected( documentValidation.error() );
1329 const bool filterByType = aCtx.
Request.types_size() > 0;
1331 if( filterByType && types.empty() )
1333 ApiResponseStatus e;
1334 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1335 e.set_error_message(
"none of the requested types are valid for a Schematic object" );
1336 return tl::unexpected( e );
1339 std::set<KICAD_T> typeFilter( types.begin(), types.end() );
1343 if( !connectionGraph )
1345 ApiResponseStatus e;
1346 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
1347 e.set_error_message(
"schematic has no connection graph" );
1348 return tl::unexpected( e );
1351 kiapi::schematic::types::SchematicNetlistResponse response;
1352 response.mutable_document()->CopyFrom( aCtx.
Request.document() );
1354 for(
const auto& [key, subgraphList] : connectionGraph->
GetNetMap() )
1356 if( subgraphList.empty() )
1367 kiapi::schematic::types::SchematicNet* net = response.add_nets();
1368 net->set_name( key.Name.ToUTF8() );
1372 kiapi::schematic::types::SchematicNetSheetContents* sheetContents = net->add_sheets();
1373 PackSheetPath( *sheetContents->mutable_path(), subGraph->GetSheet().Path() );
1375 for(
SCH_ITEM* item : subGraph->GetItems() )
1377 if( filterByType && !typeFilter.contains( item->Type() ) )
1380 sheetContents->add_items()->set_value( item->m_Uuid.AsStdString() );
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
HANDLER_RESULT< types::RunJobResponse > ExecuteSchematicJob(KIWAY *aKiway, JOB &aJob)
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
tl::expected< bool, ApiResponseStatus > UnpackSheet(SCH_SHEET *aOutput, const kiapi::schematic::types::SheetSymbol &aInput)
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)
bool UnpackSymbol(SCH_SYMBOL *aOutput, const kiapi::schematic::types::SchematicSymbolInstance &aInput)
BASE_SCREEN class implementation.
HANDLER_RESULT< bool > validateDocument(const DocumentSpecifier &aDocument)
HANDLER_RESULT< types::PageSettings > handleSetPageSettings(const HANDLER_CONTEXT< commands::SetPageSettings > &aCtx)
HANDLER_RESULT< std::optional< KIID > > validateItemHeaderDocument(const kiapi::common::types::ItemHeader &aHeader)
If the header is valid, returns the item container.
HANDLER_RESULT< types::PageSettings > handleGetPageSettings(const HANDLER_CONTEXT< commands::GetPageSettings > &aCtx)
API_HANDLER_EDITOR(EDA_BASE_FRAME *aFrame=nullptr)
static std::vector< KICAD_T > parseRequestedItemTypes(const google::protobuf::RepeatedField< int > &aTypes)
COMMIT * getCurrentCommit(const std::string &aClientName)
virtual void pushCurrentCommit(const std::string &aClientName, const wxString &aMessage)
std::set< std::string > m_activeClients
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportDxf(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportDxf > &aCtx)
std::optional< TITLE_BLOCK * > getTitleBlock() override
wxString getDrawingSheetFileName() override
HANDLER_RESULT< kiapi::schematic::types::SchematicHierarchyResponse > handleGetSchematicHierarchy(const HANDLER_CONTEXT< kiapi::schematic::types::GetSchematicHierarchy > &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< kiapi::schematic::types::SchematicNetlistResponse > handleGetSchematicNetlist(const HANDLER_CONTEXT< kiapi::schematic::types::GetSchematicNetlist > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportPdf(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportPdf > &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< SCH_ITEM * > getItemById(const KIID &aId, SCH_SHEET_PATH *aPathOut=nullptr) const
bool setPageSettings(const PAGE_INFO &aPageInfo) override
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< std::unique_ptr< EDA_ITEM > > createItemForType(KICAD_T aType, EDA_ITEM *aContainer)
void filterValidSchTypes(std::set< KICAD_T > &aTypeList)
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportBOM(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportBOM > &aCtx)
std::optional< PAGE_INFO > getPageSettings() override
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportPs(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportPs > &aCtx)
PROJECT & project() const
void onModified() override
API_HANDLER_SCH(SCH_EDIT_FRAME *aFrame)
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)
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< google::protobuf::Empty > handleSaveCopyOfDocument(const HANDLER_CONTEXT< commands::SaveCopyOfDocument > &aCtx)
SCH_CONTEXT * context() const
void setDrawingSheetFileName(const wxString &aFileName) override
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.
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
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 generates 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
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
std::vector< wxString > m_fieldsLabels
std::vector< wxString > m_fieldsOrdered
wxString m_refRangeDelimiter
std::vector< wxString > m_fieldsGroupBy
std::vector< wxString > m_variantNames
wxString m_stringDelimiter
wxString m_fieldDelimiter
wxString m_bomFmtPresetName
std::vector< wxString > m_variantNames
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
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)
Describe the page size and margins of a paper page on which to eventually print or plot.
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.
CONNECTION_GRAPH * ConnectionGraph() const
std::vector< SCH_SHEET * > GetTopLevelSheets() const
Get the list of top-level sheets.
Schematic editor (Eeschema) main window.
Base class for any item which can be embedded within the SCHEMATIC container class,...
void SwapItemData(SCH_ITEM *aImage)
Swap data between aItem and aImage.
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
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.
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
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
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
wxString GetShownName(bool aAllowExtraText) const
const std::vector< SCH_SHEET_INSTANCE > & GetInstances() const
virtual void Serialize(google::protobuf::Any &aContainer) const
Serializes this object to the given Any message.
A wrapper for reporting to a wxString object.
A type-safe container of any type.
static const std::string KiCadSchematicFileExtension
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 void PackSheetPath(types::SheetPath &aOutput, const KIID_PATH &aInput)
std::shared_ptr< SCH_CONTEXT > CreateSchFrameContext(SCH_EDIT_FRAME *aFrame)
Class to handle a set of SCH_ITEMs.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
RequestMessageType Request
A simple container for sheet instance information.
IbisParser parser & reporter
wxString result
Test unit parsing edge cases and error handling.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition of file extensions used in Kicad.