23#include <fmt/ranges.h>
24#include <magic_enum.hpp>
50#include <api/common/types/base_types.pb.h>
52using namespace kiapi::common::commands;
53using types::CommandStatus;
55using types::DocumentType;
56using types::ItemRequestStatus;
106 const std::string& aCommandName )
const
112 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
113 e.set_error_message( fmt::format(
"{} is not available in headless mode", aCommandName ) );
125 const wxString& aMessage )
137 return std::make_unique<BOARD_COMMIT>(
toolManager(),
true,
false );
158 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
159 e.set_error_message(
"Tried to create an item in a null container" );
160 return tl::unexpected( e );
166 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
167 e.set_error_message( fmt::format(
"Tried to create a pad in {}, which is not a footprint",
169 return tl::unexpected( e );
174 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
175 e.set_error_message( fmt::format(
"Tried to create a footprint in {}, which is not a board",
177 return tl::unexpected( e );
185 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
186 e.set_error_message( fmt::format(
"Tried to create an item of type {}, which is unhandled",
187 magic_enum::enum_name( aType ) ) );
188 return tl::unexpected( e );
196 const std::string& aClientName )
199 std::vector<BOARD_ITEM*> validatedItems;
201 for( std::pair<const KIID, ItemDeletionStatus> pair : aItemsToDelete )
209 aItemsToDelete[pair.first] = ItemDeletionStatus::IDS_IMMUTABLE;
213 validatedItems.push_back( item );
214 aItemsToDelete[pair.first] = ItemDeletionStatus::IDS_OK;
232 const DocumentSpecifier& aDocument,
const KIID& aId )
242 const std::string& aClientName,
243 const types::ItemHeader &aHeader,
244 const google::protobuf::RepeatedPtrField<google::protobuf::Any>& aItems,
245 std::function<
void( ItemStatus, google::protobuf::Any )> aItemHandler )
251 if( !containerResult && containerResult.error().status() == ApiStatusCode::AS_UNHANDLED )
254 e.set_status( ApiStatusCode::AS_UNHANDLED );
255 return tl::unexpected( e );
257 else if( !containerResult )
259 e.CopyFrom( containerResult.error() );
260 return tl::unexpected( e );
266 if( containerResult->has_value() )
268 const KIID& containerId = **containerResult;
269 std::optional<BOARD_ITEM*> optItem =
getItemById( containerId );
277 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
278 e.set_error_message( fmt::format(
279 "The requested container {} is not a valid board item container",
281 return tl::unexpected( e );
286 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
287 e.set_error_message( fmt::format(
288 "The requested container {} does not exist in this document",
290 return tl::unexpected( e );
296 for(
const google::protobuf::Any& anyItem : aItems )
303 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
304 status.set_error_message( fmt::format(
"Could not decode a valid type from {}",
305 anyItem.type_url() ) );
306 aItemHandler( status, anyItem );
312 board::types::Dimension dimension;
313 anyItem.UnpackTo( &dimension );
315 switch( dimension.dimension_style_case() )
322 case board::types::Dimension::DIMENSION_STYLE_NOT_SET:
break;
329 if( !creationResult )
331 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
332 status.set_error_message( creationResult.error().error_message() );
333 aItemHandler( status, anyItem );
337 std::unique_ptr<BOARD_ITEM> item( std::move( *creationResult ) );
339 bool unpacked =
false;
342 unpacked =
group->DeserializeGroup( anyItem, commit );
344 unpacked = item->Deserialize( anyItem );
348 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
349 e.set_error_message( fmt::format(
"could not unpack {} from request",
350 item->GetClass().ToStdString() ) );
351 return tl::unexpected( e );
354 if( std::vector<wxString> removed = item->RemoveConflictingCustomProperties(); !removed.empty() )
357 [](
const wxString& aIn )
359 return std::string( aIn.ToUTF8() );
362 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
363 status.set_error_message( fmt::format(
364 "Invalid custom properties for item {}: property name(s) '{}' already in use",
365 item->m_Uuid.AsStdString(), fmt::join( std::views::transform( removed, as_str ),
", " ) ) );
367 aItemHandler( status, anyItem );
371 std::optional<BOARD_ITEM*> optItem =
getItemById( item->m_Uuid );
373 if( aCreate && optItem )
375 status.set_code( ItemStatusCode::ISC_EXISTING );
376 status.set_error_message( fmt::format(
"an item with UUID {} already exists",
377 item->m_Uuid.AsStdString() ) );
378 aItemHandler( status, anyItem );
381 else if( !aCreate && !optItem )
383 status.set_code( ItemStatusCode::ISC_NONEXISTENT );
384 status.set_error_message( fmt::format(
"an item with UUID {} does not exist",
385 item->m_Uuid.AsStdString() ) );
386 aItemHandler( status, anyItem );
391 && !item->FitsEnabledLayers(
board->GetEnabledLayers(),
board->GetCopperLayerCount() ) )
393 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
394 status.set_error_message(
395 "attempted to add item with no overlapping layers with the board" );
396 aItemHandler( status, anyItem );
400 status.set_code( ItemStatusCode::ISC_OK );
401 google::protobuf::Any newItem;
411 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
412 status.set_error_message(
"a table cell must target a table container" );
413 aItemHandler( status, anyItem );
419 table->AddCell( cell );
436 item->Serialize( newItem );
437 commit->
Add( item.release() );
455 commit->
Remove( boardItem );
456 item->Serialize( newItem );
459 commit->
Add( newBoardItem );
463 parentGroup->
AddItem( newBoardItem );
467 commit->
Modify( boardItem );
473 aItemHandler( status, newItem );
479 :
_(
"Modified items via API" ) );
483 return ItemRequestStatus::IRS_OK;
488 const google::protobuf::RepeatedField<int>& aTypes )
490 std::vector<KICAD_T>
types;
492 for(
int typeRaw : aTypes )
494 auto typeMessage =
static_cast<common::types::KiCadObjectType
>( typeRaw );
498 types.emplace_back( type );
508 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"RunAction" ) )
509 return tl::unexpected( *headless );
511 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
512 return tl::unexpected( *busy );
514 RunActionResponse response;
517 response.set_status( RunActionStatus::RAS_OK );
519 response.set_status( RunActionStatus::RAS_INVALID );
528 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
529 return tl::unexpected( *busy );
534 e.set_status( ApiStatusCode::AS_UNHANDLED );
535 return tl::unexpected( e );
538 GetItemsResponse response;
540 std::vector<BOARD_ITEM*> items;
542 for(
const kiapi::common::types::KIID&
id : aCtx.
Request.items() )
544 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
545 items.emplace_back( *item );
551 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
552 e.set_error_message(
"none of the requested IDs were found or valid" );
553 return tl::unexpected( e );
558 google::protobuf::Any itemBuf;
559 item->Serialize( itemBuf );
560 response.mutable_items()->Add( std::move( itemBuf ) );
563 response.set_status( ItemRequestStatus::IRS_OK );
571 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetSelection" ) )
572 return tl::unexpected( *headless );
578 e.set_status( ApiStatusCode::AS_UNHANDLED );
579 return tl::unexpected( e );
590 SelectionResponse response;
595 item->Serialize( *response.add_items() );
605 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"ClearSelection" ) )
606 return tl::unexpected( *headless );
608 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
609 return tl::unexpected( *busy );
615 e.set_status( ApiStatusCode::AS_UNHANDLED );
616 return tl::unexpected( e );
630 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"AddToSelection" ) )
631 return tl::unexpected( *headless );
633 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
634 return tl::unexpected( *busy );
640 e.set_status( ApiStatusCode::AS_UNHANDLED );
641 return tl::unexpected( e );
647 std::vector<EDA_ITEM*> toAdd;
649 for(
const types::KIID&
id : aCtx.
Request.items() )
651 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
652 toAdd.emplace_back( *item );
658 SelectionResponse response;
661 item->Serialize( *response.add_items() );
670 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"RemoveFromSelection" ) )
671 return tl::unexpected( *headless );
673 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
674 return tl::unexpected( *busy );
680 e.set_status( ApiStatusCode::AS_UNHANDLED );
681 return tl::unexpected( e );
687 std::vector<EDA_ITEM*> toRemove;
689 for(
const types::KIID&
id : aCtx.
Request.items() )
691 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
692 toRemove.emplace_back( *item );
698 SelectionResponse response;
701 item->Serialize( *response.add_items() );
712 if( !documentValidation )
713 return tl::unexpected( documentValidation.error() );
715 BoardStackupResponse response;
728 if( !documentValidation )
729 return tl::unexpected( documentValidation.error() );
731 BoardEnabledLayersResponse response;
734 int copperLayerCount =
board->GetCopperLayerCount();
736 response.set_copper_layer_count( copperLayerCount );
738 LSET enabled =
board->GetEnabledLayers();
757 if( !documentValidation )
758 return tl::unexpected( documentValidation.error() );
761 GraphicsDefaultsResponse response;
764 constexpr std::array<kiapi::board::BoardLayerClass, LAYER_CLASS_COUNT> classOrder = {
765 kiapi::board::BLC_SILKSCREEN,
766 kiapi::board::BLC_COPPER,
767 kiapi::board::BLC_EDGES,
768 kiapi::board::BLC_COURTYARD,
769 kiapi::board::BLC_FABRICATION,
770 kiapi::board::BLC_OTHER
775 kiapi::board::BoardLayerGraphicsDefaults* l = response.mutable_defaults()->add_layers();
777 l->set_layer( classOrder[i] );
780 kiapi::common::types::TextAttributes*
text = l->mutable_text();
795 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
796 return tl::unexpected( *busy );
802 e.set_status( ApiStatusCode::AS_UNHANDLED );
803 return tl::unexpected( e );
806 GetBoundingBoxResponse response;
807 bool includeText = aCtx.
Request.mode() == BoundingBoxMode::BBM_ITEM_AND_CHILD_TEXT;
809 for(
const types::KIID& idMsg : aCtx.
Request.items() )
811 KIID id( idMsg.value() );
812 std::optional<BOARD_ITEM*> optItem =
getItemById(
id );
821 bbox =
static_cast<FOOTPRINT*
>( item )->GetBoundingBox( includeText );
825 response.add_items()->set_value( idMsg.value() );
826 PackBox2( *response.add_boxes(), bbox );
837 !documentValidation )
839 return tl::unexpected( documentValidation.error() );
842 PadShapeAsPolygonResponse response;
845 for(
const types::KIID& padRequest : aCtx.
Request.pads() )
847 KIID id( padRequest.value() );
848 std::optional<BOARD_ITEM*> optPad =
getItemById(
id );
850 if( !optPad || ( *optPad )->Type() !=
PCB_PAD_T )
853 response.add_pads()->set_value( padRequest.value() );
857 pad->TransformShapeToPolygon( poly,
pad->Padstack().EffectiveLayerFor( layer ), 0,
860 types::PolygonWithHoles* polyMsg = response.mutable_polygons()->Add();
871 using board::types::BoardLayer;
874 !documentValidation )
876 return tl::unexpected( documentValidation.error() );
879 PadstackPresenceResponse response;
883 for(
const int layer : aCtx.
Request.layers() )
886 for(
const types::KIID& padRequest : aCtx.
Request.items() )
888 KIID id( padRequest.value() );
889 std::optional<BOARD_ITEM*> optItem =
getItemById(
id );
894 switch( ( *optItem )->Type() )
898 PAD*
pad =
static_cast<PAD*
>( *optItem );
902 PadstackPresenceEntry* entry = response.add_entries();
903 entry->mutable_item()->set_value(
pad->m_Uuid.AsStdString() );
905 entry->set_presence(
pad->FlashLayer( layer ) ? PSP_PRESENT : PSP_NOT_PRESENT );
917 PadstackPresenceEntry* entry = response.add_entries();
918 entry->mutable_item()->set_value(
via->m_Uuid.AsStdString() );
920 entry->set_presence(
via->FlashLayer( layer ) ? PSP_PRESENT : PSP_NOT_PRESENT );
940 if( !documentValidation )
941 return tl::unexpected( documentValidation.error() );
943 ExpandTextVariablesResponse reply;
946 std::function<bool( wxString* )> textResolver =
947 [&]( wxString* token ) ->
bool
950 return board->ResolveTextVar( token, 0 );
953 for(
const std::string& textMsg : aCtx.
Request.text() )
957 if( aCtx.
Request.expand_env_vars() )
960 reply.add_text(
text.ToUTF8() );
970 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"InteractiveMoveItems" ) )
971 return tl::unexpected( *headless );
973 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
974 return tl::unexpected( *busy );
978 if( !documentValidation )
979 return tl::unexpected( documentValidation.error() );
982 std::vector<EDA_ITEM*> toSelect;
984 for(
const kiapi::common::types::KIID&
id : aCtx.
Request.items() )
986 if( std::optional<BOARD_ITEM*> item =
getItemById(
KIID(
id.value() ) ) )
987 toSelect.emplace_back(
static_cast<EDA_ITEM*
>( *item ) );
990 if( toSelect.empty() )
993 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
994 e.set_error_message( fmt::format(
"None of the given items exist on the board",
995 aCtx.
Request.board().board_filename() ) );
996 return tl::unexpected( e );
1015 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1016 return tl::unexpected( *busy );
1020 if( !containerResult && containerResult.error().status() == ApiStatusCode::AS_UNHANDLED )
1023 ApiResponseStatus e;
1024 e.set_status( ApiStatusCode::AS_UNHANDLED );
1025 return tl::unexpected( e );
1027 else if( !containerResult )
1029 return tl::unexpected( containerResult.error() );
1035 FlipItemsResponse response;
1036 response.mutable_header()->CopyFrom( aCtx.
Request.header() );
1040 bool anyModified =
false;
1042 for(
const types::KIID&
id : aCtx.
Request.items() )
1044 ItemFlipResult*
result = response.add_flipped_items();
1046 std::optional<BOARD_ITEM*> optItem =
getItemById(
KIID(
id.value() ) );
1050 result->mutable_status()->set_code( ItemStatusCode::ISC_NONEXISTENT );
1051 result->mutable_status()->set_error_message(
1052 fmt::format(
"an item with UUID {} does not exist",
id.value() ) );
1058 static const std::set<KICAD_T> flippableTypes = {
1087 if( !flippableTypes.contains( itemType ) )
1089 result->mutable_status()->set_code( ItemStatusCode::ISC_INVALID_TYPE );
1090 result->mutable_status()->set_error_message(
1091 fmt::format(
"items of type {} cannot be flipped",
1092 magic_enum::enum_name( itemType ) ) );
1102 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
1106 google::protobuf::Any itemBuf;
1108 *
result->mutable_item() = std::move( itemBuf );
1110 result->mutable_status()->set_code( ItemStatusCode::ISC_OK );
1113 response.set_status( ItemRequestStatus::IRS_OK );
1127 if( !documentValidation )
1128 return tl::unexpected( documentValidation.error() );
1130 SavedDocumentResponse response;
1131 response.mutable_document()->CopyFrom( aCtx.
Request.document() );
1135 [&](
const wxString& aData )
1137 response.set_contents( aData.ToUTF8() );
1149 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SaveSelectionToString" ) )
1150 return tl::unexpected( *headless );
1152 SavedSelectionResponse response;
1160 [&](
const wxString& aData )
1162 response.set_contents( aData.ToUTF8() );
1175 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1176 return tl::unexpected( *busy );
1180 if( !documentValidation )
1181 return tl::unexpected( documentValidation.error() );
1183 CreateItemsResponse response;
1191 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetVisibleLayers" ) )
1192 return tl::unexpected( *headless );
1196 if( !documentValidation )
1197 return tl::unexpected( documentValidation.error() );
1199 BoardLayers response;
1211 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SetVisibleLayers" ) )
1212 return tl::unexpected( *headless );
1214 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1215 return tl::unexpected( *busy );
1219 if( !documentValidation )
1220 return tl::unexpected( documentValidation.error() );
1225 for(
int layerIdx : aCtx.
Request.layers() )
1231 visible.
set( layer );
1239 editFrame->Refresh();
1247 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"GetActiveLayer" ) )
1248 return tl::unexpected( *headless );
1252 if( !documentValidation )
1253 return tl::unexpected( documentValidation.error() );
1257 BoardLayerResponse response;
1268 if( std::optional<ApiResponseStatus> headless =
checkForHeadless(
"SetActiveLayer" ) )
1269 return tl::unexpected( *headless );
1271 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
1272 return tl::unexpected( *busy );
1276 if( !documentValidation )
1277 return tl::unexpected( documentValidation.error() );
1281 if( !
board()->GetEnabledLayers().Contains( layer ) )
1283 ApiResponseStatus err;
1284 err.set_status( ApiStatusCode::AS_BAD_REQUEST );
1285 err.set_error_message( fmt::format(
"Layer {} is not a valid layer for the given board",
1286 magic_enum::enum_name( layer ) ) );
1287 return tl::unexpected( err );
KICOMMON_API types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICOMMON_API KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
API_HANDLER_BOARD(std::shared_ptr< BOARD_CONTEXT > aContext, EDA_BASE_FRAME *aFrame=nullptr)
HANDLER_RESULT< commands::ExpandTextVariablesResponse > handleExpandTextVariables(const HANDLER_CONTEXT< commands::ExpandTextVariables > &aCtx)
HANDLER_RESULT< BoardEnabledLayersResponse > handleGetBoardEnabledLayers(const HANDLER_CONTEXT< GetBoardEnabledLayers > &aCtx)
std::unique_ptr< COMMIT > createCommit() override
Override this to create an appropriate COMMIT subclass for the frame in question.
HANDLER_RESULT< commands::SelectionResponse > handleGetSelection(const HANDLER_CONTEXT< commands::GetSelection > &aCtx)
HANDLER_RESULT< commands::SavedSelectionResponse > handleSaveSelectionToString(const HANDLER_CONTEXT< commands::SaveSelectionToString > &aCtx)
HANDLER_RESULT< Empty > handleSetActiveLayer(const HANDLER_CONTEXT< SetActiveLayer > &aCtx)
HANDLER_RESULT< BoardLayers > handleGetVisibleLayers(const HANDLER_CONTEXT< GetVisibleLayers > &aCtx)
TOOL_MANAGER * toolManager() const
HANDLER_RESULT< commands::SelectionResponse > handleAddToSelection(const HANDLER_CONTEXT< commands::AddToSelection > &aCtx)
HANDLER_RESULT< commands::CreateItemsResponse > handleParseAndCreateItemsFromString(const HANDLER_CONTEXT< commands::ParseAndCreateItemsFromString > &aCtx)
HANDLER_RESULT< Empty > handleClearSelection(const HANDLER_CONTEXT< commands::ClearSelection > &aCtx)
std::vector< KICAD_T > parseRequestedItemTypes(const google::protobuf::RepeatedField< int > &aTypes)
HANDLER_RESULT< Empty > handleInteractiveMoveItems(const HANDLER_CONTEXT< InteractiveMoveItems > &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< BoardStackupResponse > handleGetStackup(const HANDLER_CONTEXT< GetBoardStackup > &aCtx)
void pushCurrentCommit(const std::string &aClientName, const wxString &aMessage) override
HANDLER_RESULT< commands::GetItemsResponse > handleGetItemsById(const HANDLER_CONTEXT< commands::GetItemsById > &aCtx)
std::optional< EDA_ITEM * > getItemFromDocument(const DocumentSpecifier &aDocument, const KIID &aId) override
void deleteItemsInternal(std::map< KIID, ItemDeletionStatus > &aItemsToDelete, const std::string &aClientName) override
HANDLER_RESULT< commands::SelectionResponse > handleRemoveFromSelection(const HANDLER_CONTEXT< commands::RemoveFromSelection > &aCtx)
HANDLER_RESULT< GraphicsDefaultsResponse > handleGetGraphicsDefaults(const HANDLER_CONTEXT< GetGraphicsDefaults > &aCtx)
HANDLER_RESULT< BoardLayerResponse > handleGetActiveLayer(const HANDLER_CONTEXT< GetActiveLayer > &aCtx)
HANDLER_RESULT< commands::GetBoundingBoxResponse > handleGetBoundingBox(const HANDLER_CONTEXT< commands::GetBoundingBox > &aCtx)
static HANDLER_RESULT< std::unique_ptr< BOARD_ITEM > > createItemForType(KICAD_T aType, BOARD_ITEM_CONTAINER *aContainer)
HANDLER_RESULT< commands::RunActionResponse > handleRunAction(const HANDLER_CONTEXT< commands::RunAction > &aCtx)
std::optional< ApiResponseStatus > checkForHeadless(const std::string &aCommandName) const
HANDLER_RESULT< commands::SavedDocumentResponse > handleSaveDocumentToString(const HANDLER_CONTEXT< commands::SaveDocumentToString > &aCtx)
HANDLER_RESULT< PadShapeAsPolygonResponse > handleGetPadShapeAsPolygon(const HANDLER_CONTEXT< GetPadShapeAsPolygon > &aCtx)
std::shared_ptr< BOARD_CONTEXT > m_context
HANDLER_RESULT< PadstackPresenceResponse > handleCheckPadstackPresenceOnLayers(const HANDLER_CONTEXT< CheckPadstackPresenceOnLayers > &aCtx)
virtual BOARD_ITEM_CONTAINER * getDefaultContainer()
HANDLER_RESULT< Empty > handleSetVisibleLayers(const HANDLER_CONTEXT< SetVisibleLayers > &aCtx)
std::optional< BOARD_ITEM * > getItemById(const KIID &aId) const
HANDLER_RESULT< FlipItemsResponse > handleFlipItems(const HANDLER_CONTEXT< FlipItems > &aCtx)
HANDLER_RESULT< bool > validateDocument(const DocumentSpecifier &aDocument)
HANDLER_RESULT< std::optional< KIID > > validateItemHeaderDocument(const kiapi::common::types::ItemHeader &aHeader)
If the header is valid, returns the item container.
API_HANDLER_EDITOR(EDA_BASE_FRAME *aFrame=nullptr)
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.
virtual void onModified()
void registerHandler(HANDLER_RESULT< ResponseType >(HandlerType::*aHandler)(const HANDLER_CONTEXT< RequestType > &))
Registers an API command handler for the given message types.
BASE_SET & reset(size_t pos)
BASE_SET & set(size_t pos)
Container for design settings for a BOARD object.
bool m_TextUpright[LAYER_CLASS_COUNT]
int m_TextThickness[LAYER_CLASS_COUNT]
int m_LineThickness[LAYER_CLASS_COUNT]
VECTOR2I m_TextSize[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void CopyFrom(const BOARD_ITEM *aOther)
virtual void Normalize()
Perform any normalization required after a user rotate and/or flip.
virtual void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
Flip this object, i.e.
Information pertinent to a Pcbnew printed circuit board.
void SetVisibleLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
void SaveBoard(const wxString &aFileName, BOARD &aBoard, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aBoard to a storage file in a format that this PCB_IO implementation knows about or it can be u...
void SaveSelection(const PCB_SELECTION &selected, bool isFootprintEditor)
void SetWriter(std::function< void(const wxString &)> aWriter)
void SetBoard(BOARD *aBoard)
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.
The base frame for deriving all KiCad main window classes.
The base class for create windows for drawing purpose.
void AddItem(EDA_ITEM *aItem)
Add item to group.
A base class for most all the KiCad significant classes used in schematics and boards.
virtual VECTOR2I GetPosition() const
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
virtual EDA_GROUP * GetParentGroup() const
KICAD_T Type() const
Returns the type of object.
virtual wxString GetFriendlyName() const
std::string AsStdString() const
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
static TOOL_ACTION move
move or drag an item
Common, abstract interface for edit frames.
APPEARANCE_CONTROLS * GetAppearancePanel()
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual PCB_LAYER_ID GetActiveLayer() const
void SyncLayersVisibility(const BOARD *aBoard)
Update "visibility" property of each layer of a given BOARD.
A set of BOARD_ITEMs (i.e., without duplicates).
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
void SetReferencePoint(const VECTOR2I &aP)
virtual void Serialize(google::protobuf::Any &aContainer) const
Serializes this object to the given Any message.
Represent a set of closed polygons.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
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)
PCB_LAYER_ID
A quick note on layer IDs:
void PackLayerSet(google::protobuf::RepeatedField< int > &aOutput, const LSET &aLayerSet)
void PackBoardStackup(const BOARD &aBoard, BoardStackup &aOut)
KICOMMON_API std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
KICOMMON_API void PackBox2(types::Box2 &aOutput, const BOX2I &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackPolyLine(types::PolyLine &aOutput, const SHAPE_LINE_CHAIN &aSlc, const EDA_IU_SCALE &aScale)
Class to handle a set of BOARD_ITEMs.
std::vector< EDA_ITEM * > EDA_ITEMS
RequestMessageType Request
wxString result
Test unit parsing edge cases and error handling.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_GRID_ITEM_T
a subgrid placed on a board
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension