37#include <api/common/types/base_types.pb.h>
39using namespace kiapi::common::commands;
40using types::CommandStatus;
41using types::DocumentType;
42using types::ItemRequestStatus;
76 if( aDocument.type() != DocumentType::DOCTYPE_FOOTPRINT )
79 e.set_status( ApiStatusCode::AS_UNHANDLED );
80 return tl::unexpected( e );
88 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
89 e.set_error_message(
"no footprint is currently open" );
90 return tl::unexpected( e );
96 if( 0 != aDocument.lib_id().library_nickname().compare( actual_lib ) )
99 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
100 e.set_error_message( fmt::format(
"the requested library is {} but the actual library is {}",
101 aDocument.lib_id().library_nickname(), actual_lib ) );
102 return tl::unexpected( e );
105 if( 0 != aDocument.lib_id().entry_name().compare( actual_name ) )
108 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
109 e.set_error_message( fmt::format(
"the requested footprint name is {} but the actual name is {}",
110 aDocument.lib_id().entry_name(), actual_name ) );
111 return tl::unexpected( e );
118 const DocumentSpecifier& aDocument )
120 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
121 return tl::unexpected( *busy );
125 if( !documentValidation )
126 return tl::unexpected( documentValidation.error() );
130 if( !editorFootprint )
133 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
134 e.set_error_message(
"no footprint is currently loaded" );
135 return tl::unexpected( e );
138 return editorFootprint;
144 if( aCtx.
Request.type() != DocumentType::DOCTYPE_FOOTPRINT )
147 e.set_status( ApiStatusCode::AS_UNHANDLED );
148 return tl::unexpected( e );
153 wxString libraryName = aCtx.
Request.identifier().library_nickname();
154 wxString fpName = aCtx.
Request.identifier().entry_name();
156 LIB_ID fpid( libraryName, fpName );
160 std::unique_ptr<FOOTPRINT> footprint(
166 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
167 e.set_error_message(
"could not open footprint" );
168 return tl::unexpected( e );
174 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
175 e.set_error_message( fmt::format(
"could not open footprint due to IO error {}",
176 err.
Problem().ToStdString() ) );
177 return tl::unexpected( e );
187 if( aCtx.
Request.type() != DocumentType::DOCTYPE_FOOTPRINT )
190 e.set_status( ApiStatusCode::AS_UNHANDLED );
191 return tl::unexpected( e );
194 GetOpenDocumentsResponse response;
195 common::types::DocumentSpecifier doc;
199 doc.set_type( DocumentType::DOCTYPE_FOOTPRINT );
203 if( !
project().IsNullProject() )
209 response.mutable_documents()->Add( std::move( doc ) );
220 return tl::unexpected( footprint.error() );
225 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
226 e.set_error_message(
"failed to save footprint" );
227 return tl::unexpected( e );
240 return tl::unexpected( footprint.error() );
242 wxString pathStr = wxString::FromUTF8( aCtx.
Request.path() );
244 if( pathStr.IsEmpty() )
247 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
248 e.set_error_message(
"path must contain the new footprint name, "
249 "optionally prefixed with a library nickname (e.g. \"lib:name\")" );
250 return tl::unexpected( e );
255 targetId.
Parse( pathStr );
259 if( libraryName.IsEmpty() )
265 std::unique_ptr<FOOTPRINT>
copy(
static_cast<FOOTPRINT*
>( ( *footprint )->Clone() ) );
266 copy->SetFPID(
LIB_ID( libraryName, newName ) );
271 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
272 e.set_error_message( fmt::format(
"failed to save footprint copy '{}' to library '{}'",
273 newName.ToStdString(),
274 libraryName.ToStdString() ) );
275 return tl::unexpected( e );
285 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
286 return tl::unexpected( *busy );
290 if( !documentValidation )
291 return tl::unexpected( documentValidation.error() );
319 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
320 return tl::unexpected( *busy );
326 e.set_status( ApiStatusCode::AS_UNHANDLED );
327 return tl::unexpected( e );
330 GetItemsResponse response;
333 std::vector<BOARD_ITEM*> items;
334 std::set<KICAD_T> typesRequested, typesInserted;
335 bool handledAnything =
false;
339 if( aCtx.
Request.types().empty() )
342 for(
KICAD_T type : requestedTypes )
344 typesRequested.emplace( type );
346 if( typesInserted.count( type ) )
353 handledAnything =
true;
355 std::copy( footprint->
Pads().begin(), footprint->
Pads().end(),
356 std::back_inserter( items ) );
364 handledAnything =
true;
367 std::back_inserter( items ) );
379 handledAnything =
true;
380 bool inserted =
false;
384 if( item->Type() == type )
386 items.emplace_back( item );
392 typesInserted.insert( type );
399 handledAnything =
true;
400 bool inserted =
false;
410 items.emplace_back( child );
424 handledAnything =
true;
425 bool inserted =
false;
429 switch( item->Type() )
436 items.emplace_back( item );
459 handledAnything =
true;
461 std::copy( footprint->
Zones().begin(), footprint->
Zones().end(),
462 std::back_inserter( items ) );
470 handledAnything =
true;
472 std::copy( footprint->
Groups().begin(), footprint->
Groups().end(),
473 std::back_inserter( items ) );
484 if( !handledAnything )
487 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
488 e.set_error_message(
"none of the requested types are valid for a Footprint object" );
489 return tl::unexpected( e );
494 if( !typesRequested.count( item->Type() ) )
497 google::protobuf::Any itemBuf;
498 item->Serialize( itemBuf );
499 response.mutable_items()->Add( std::move( itemBuf ) );
502 response.set_status( ItemRequestStatus::IRS_OK );
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
API_HANDLER_BOARD(std::shared_ptr< BOARD_CONTEXT > aContext, EDA_BASE_FRAME *aFrame=nullptr)
std::vector< KICAD_T > parseRequestedItemTypes(const google::protobuf::RepeatedField< int > &aTypes)
PROJECT & project() const
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.
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
void registerHandler(HANDLER_RESULT< ResponseType >(HandlerType::*aHandler)(const HANDLER_CONTEXT< RequestType > &))
Registers an API command handler for the given message types.
void SetContentModified(bool aModified=true)
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...
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString Problem() const
what was the problem?
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
bool IsValid() const
Check if this LID_ID is valid.
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
const wxString GetUniStringLibNickname() const
const UTF8 & GetLibItemName() const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
static std::string ToStdString(const wxString &aStr)
Class to handle a set of BOARD_ITEMs.
RequestMessageType Request
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_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_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension