27using namespace kiapi::common::commands;
46 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
47 return tl::unexpected( *busy );
52 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
53 e.set_error_message( fmt::format(
"the client {} already has a commit in progress",
55 return tl::unexpected( e );
60 BeginCommitResponse response;
64 response.mutable_id()->set_value(
id.AsStdString() );
75 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
76 return tl::unexpected( *busy );
81 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
82 e.set_error_message( fmt::format(
"the client {} does not has a commit in progress",
84 return tl::unexpected( e );
90 const KIID&
id = pair.first;
91 const std::unique_ptr<COMMIT>& commit = pair.second;
93 EndCommitResponse response;
96 switch( aMsg.action() )
98 case kiapi::common::commands::CMA_DROP:
106 case kiapi::common::commands::CMA_COMMIT:
108 if( aMsg.id().value().compare(
id.AsStdString() ) != 0 )
111 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
112 e.set_error_message( fmt::format(
"the id {} does not match the commit in progress",
113 aMsg.id().value() ) );
114 return tl::unexpected( e );
155 const kiapi::common::types::DocumentSpecifier& aDocument )
160 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
161 e.set_error_message( fmt::format(
"the requested document {} is not open",
162 aDocument.board_filename() ) );
163 return tl::unexpected( e );
171 const kiapi::common::types::ItemHeader& aHeader )
173 if( !aHeader.has_document() || aHeader.document().type() !=
thisDocumentType() )
176 e.set_status( ApiStatusCode::AS_UNHANDLED );
178 return tl::unexpected( e );
183 if( !documentValidation )
184 return tl::unexpected( documentValidation.error() );
189 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
190 e.set_error_message( fmt::format(
"the requested document {} is not open",
191 aHeader.document().board_filename() ) );
192 return tl::unexpected( e );
195 if( aHeader.has_container() )
197 return KIID( aHeader.container().value() );
210 e.set_status( ApiStatusCode::AS_BUSY );
211 e.set_error_message(
"KiCad is busy and cannot respond to API requests right now" );
222 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
223 return tl::unexpected( *busy );
225 CreateItemsResponse response;
228 aMsg.header(), aMsg.items(),
229 [&](
const ItemStatus& aStatus,
const google::protobuf::Any& aItem )
231 ItemCreationResult itemResult;
232 itemResult.mutable_status()->CopyFrom( aStatus );
233 itemResult.mutable_item()->CopyFrom( aItem );
234 response.mutable_created_items()->Add( std::move( itemResult ) );
237 if( !result.has_value() )
238 return tl::unexpected( result.error() );
240 response.set_status( *result );
248 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
249 return tl::unexpected( *busy );
251 UpdateItemsResponse response;
254 aMsg.header(), aMsg.items(),
255 [&](
const ItemStatus& aStatus,
const google::protobuf::Any& aItem )
257 ItemUpdateResult itemResult;
258 itemResult.mutable_status()->CopyFrom( aStatus );
259 itemResult.mutable_item()->CopyFrom( aItem );
260 response.mutable_updated_items()->Add( std::move( itemResult ) );
263 if( !result.has_value() )
264 return tl::unexpected( result.error() );
266 response.set_status( *result );
274 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
275 return tl::unexpected( *busy );
281 e.set_status( ApiStatusCode::AS_UNHANDLED );
282 return tl::unexpected( e );
285 std::map<KIID, ItemDeletionStatus> itemsToDelete;
287 for(
const kiapi::common::types::KIID& kiidBuf : aMsg.item_ids() )
289 if( !kiidBuf.value().empty() )
291 KIID kiid( kiidBuf.value() );
292 itemsToDelete[kiid] = ItemDeletionStatus::IDS_NONEXISTENT;
296 if( itemsToDelete.empty() )
299 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
300 e.set_error_message(
"no valid items to delete were given" );
301 return tl::unexpected( e );
306 DeleteItemsResponse response;
308 for(
const auto& [
id, status] : itemsToDelete )
310 ItemDeletionResult result;
311 result.mutable_id()->set_value(
id.AsStdString() );
312 result.set_status( status );
315 response.set_status( kiapi::common::types::ItemRequestStatus::IRS_OK );
323 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
324 return tl::unexpected( *busy );
330 e.set_status( ApiStatusCode::AS_UNHANDLED );
331 return tl::unexpected( e );
334 HitTestResponse response;
337 KIID( aMsg.id().value() ) );
342 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
343 e.set_error_message(
"the requested item ID is not present in the given document" );
344 return tl::unexpected( e );
348 response.set_result( HitTestResult::HTR_HIT );
350 response.set_result( HitTestResult::HTR_NO_HIT );
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
HANDLER_RESULT< commands::HitTestResponse > handleHitTest(commands::HitTest &aMsg, const HANDLER_CONTEXT &aCtx)
virtual void pushCurrentCommit(const HANDLER_CONTEXT &aCtx, const wxString &aMessage)
virtual HANDLER_RESULT< ItemRequestStatus > handleCreateUpdateItemsInternal(bool aCreate, const HANDLER_CONTEXT &aCtx, const types::ItemHeader &aHeader, const google::protobuf::RepeatedPtrField< google::protobuf::Any > &aItems, std::function< void(commands::ItemStatus, google::protobuf::Any)> aItemHandler)=0
virtual kiapi::common::types::DocumentType thisDocumentType() const =0
Override this to specify which document type this editor handles.
HANDLER_RESULT< commands::BeginCommitResponse > handleBeginCommit(commands::BeginCommit &aMsg, const HANDLER_CONTEXT &aCtx)
virtual std::unique_ptr< COMMIT > createCommit()=0
Override this to create an appropriate COMMIT subclass for the frame in question.
HANDLER_RESULT< bool > validateDocument(const DocumentSpecifier &aDocument)
HANDLER_RESULT< commands::UpdateItemsResponse > handleUpdateItems(commands::UpdateItems &aMsg, const HANDLER_CONTEXT &aCtx)
virtual std::optional< EDA_ITEM * > getItemFromDocument(const DocumentSpecifier &aDocument, const KIID &aId)=0
HANDLER_RESULT< commands::EndCommitResponse > handleEndCommit(commands::EndCommit &aMsg, const HANDLER_CONTEXT &aCtx)
HANDLER_RESULT< std::optional< KIID > > validateItemHeaderDocument(const kiapi::common::types::ItemHeader &aHeader)
If the header is valid, returns the item container.
COMMIT * getCurrentCommit(const HANDLER_CONTEXT &aCtx)
API_HANDLER_EDITOR(EDA_BASE_FRAME *aFrame=nullptr)
HANDLER_RESULT< commands::DeleteItemsResponse > handleDeleteItems(commands::DeleteItems &aMsg, const HANDLER_CONTEXT &aCtx)
std::set< std::string > m_activeClients
std::map< std::string, std::pair< KIID, std::unique_ptr< COMMIT > > > m_commits
virtual void deleteItemsInternal(std::map< KIID, ItemDeletionStatus > &aItemsToDelete, const HANDLER_CONTEXT &aCtx)=0
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
HANDLER_RESULT< commands::CreateItemsResponse > handleCreateItems(commands::CreateItems &aMsg, const HANDLER_CONTEXT &aCtx)
virtual bool validateDocumentInternal(const DocumentSpecifier &aDocument) const =0
static const wxString m_defaultCommitMessage
Represent a set of changes (additions, deletions or modifications) of a data model (e....
The base frame for deriving all KiCad main window classes.
virtual bool CanAcceptApiCommands()
Checks if this frame is ready to accept API commands.
Base window classes and related definitions.
VECTOR2I UnpackVector2(const types::Vector2 &aInput)