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;
98 case kiapi::common::commands::CMA_DROP:
106 case kiapi::common::commands::CMA_COMMIT:
108 if( aCtx.
Request.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",
114 return tl::unexpected( e );
137 return m_commits.at( aClientName ).second.get();
142 const wxString& aMessage )
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 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;
230 [&](
const ItemStatus& aStatus,
const google::protobuf::Any& aItem )
232 ItemCreationResult itemResult;
233 itemResult.mutable_status()->CopyFrom( aStatus );
234 itemResult.mutable_item()->CopyFrom( aItem );
235 response.mutable_created_items()->Add( std::move( itemResult ) );
238 if( !result.has_value() )
239 return tl::unexpected( result.error() );
241 response.set_status( *result );
249 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
250 return tl::unexpected( *busy );
252 UpdateItemsResponse response;
257 [&](
const ItemStatus& aStatus,
const google::protobuf::Any& aItem )
259 ItemUpdateResult itemResult;
260 itemResult.mutable_status()->CopyFrom( aStatus );
261 itemResult.mutable_item()->CopyFrom( aItem );
262 response.mutable_updated_items()->Add( std::move( itemResult ) );
265 if( !result.has_value() )
266 return tl::unexpected( result.error() );
268 response.set_status( *result );
276 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
277 return tl::unexpected( *busy );
283 e.set_status( ApiStatusCode::AS_UNHANDLED );
284 return tl::unexpected( e );
287 std::map<KIID, ItemDeletionStatus> itemsToDelete;
289 for(
const kiapi::common::types::KIID& kiidBuf : aCtx.
Request.item_ids() )
291 if( !kiidBuf.value().empty() )
293 KIID kiid( kiidBuf.value() );
294 itemsToDelete[kiid] = ItemDeletionStatus::IDS_NONEXISTENT;
298 if( itemsToDelete.empty() )
301 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
302 e.set_error_message(
"no valid items to delete were given" );
303 return tl::unexpected( e );
308 DeleteItemsResponse response;
310 for(
const auto& [
id, status] : itemsToDelete )
312 ItemDeletionResult result;
313 result.mutable_id()->set_value(
id.AsStdString() );
314 result.set_status( status );
317 response.set_status( kiapi::common::types::ItemRequestStatus::IRS_OK );
325 if( std::optional<ApiResponseStatus> busy =
checkForBusy() )
326 return tl::unexpected( *busy );
332 e.set_status( ApiStatusCode::AS_UNHANDLED );
333 return tl::unexpected( e );
336 HitTestResponse response;
344 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
345 e.set_error_message(
"the requested item ID is not present in the given document" );
346 return tl::unexpected( e );
350 response.set_result( HitTestResult::HTR_HIT );
352 response.set_result( HitTestResult::HTR_NO_HIT );
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
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::DeleteItemsResponse > handleDeleteItems(const HANDLER_CONTEXT< commands::DeleteItems > &aCtx)
virtual std::optional< EDA_ITEM * > getItemFromDocument(const DocumentSpecifier &aDocument, const KIID &aId)=0
HANDLER_RESULT< std::optional< KIID > > validateItemHeaderDocument(const kiapi::common::types::ItemHeader &aHeader)
If the header is valid, returns the item container.
HANDLER_RESULT< commands::EndCommitResponse > handleEndCommit(const HANDLER_CONTEXT< commands::EndCommit > &aCtx)
API_HANDLER_EDITOR(EDA_BASE_FRAME *aFrame=nullptr)
HANDLER_RESULT< commands::CreateItemsResponse > handleCreateItems(const HANDLER_CONTEXT< commands::CreateItems > &aCtx)
COMMIT * getCurrentCommit(const std::string &aClientName)
virtual void pushCurrentCommit(const std::string &aClientName, const wxString &aMessage)
virtual HANDLER_RESULT< 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)=0
std::set< std::string > m_activeClients
std::map< std::string, std::pair< KIID, std::unique_ptr< COMMIT > > > m_commits
HANDLER_RESULT< commands::UpdateItemsResponse > handleUpdateItems(const HANDLER_CONTEXT< commands::UpdateItems > &aCtx)
virtual void deleteItemsInternal(std::map< KIID, ItemDeletionStatus > &aItemsToDelete, const std::string &aClientName)=0
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
virtual types::DocumentType thisDocumentType() const =0
Override this to specify which document type this editor handles.
HANDLER_RESULT< commands::BeginCommitResponse > handleBeginCommit(const HANDLER_CONTEXT< commands::BeginCommit > &aCtx)
HANDLER_RESULT< commands::HitTestResponse > handleHitTest(const HANDLER_CONTEXT< commands::HitTest > &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.
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput)
RequestMessageType Request