24#include <magic_enum.hpp>
27#include <wx/filename.h>
29#include <api/common/types/base_types.pb.h>
31using namespace kiapi::common::commands;
32using kiapi::common::types::CommandStatus;
33using kiapi::common::types::DocumentType;
34using kiapi::common::types::ItemRequestStatus;
41 registerHandler<GetOpenDocuments, GetOpenDocumentsResponse>(
48 return std::make_unique<SCH_COMMIT>(
m_frame );
54 if( aDocument.type() != DocumentType::DOCTYPE_SCHEMATIC )
67 if( aCtx.
Request.type() != DocumentType::DOCTYPE_SCHEMATIC )
71 e.set_status( ApiStatusCode::AS_UNHANDLED );
72 return tl::unexpected( e );
75 GetOpenDocumentsResponse response;
76 common::types::DocumentSpecifier doc;
80 doc.set_type( DocumentType::DOCTYPE_SCHEMATIC );
81 doc.set_board_filename( fn.GetFullName() );
83 response.mutable_documents()->Add( std::move( doc ) );
94 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
95 e.set_error_message(
"Tried to create an item in a null container" );
96 return tl::unexpected( e );
102 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
103 e.set_error_message( fmt::format(
"Tried to create a pin in {}, which is not a symbol",
105 return tl::unexpected( e );
110 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
111 e.set_error_message( fmt::format(
"Tried to create a symbol in {}, which is not a schematic",
113 return tl::unexpected( e );
121 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
122 e.set_error_message( fmt::format(
"Tried to create an item of type {}, which is unhandled",
123 magic_enum::enum_name( aType ) ) );
124 return tl::unexpected( e );
132 const std::string& aClientName,
133 const types::ItemHeader &aHeader,
134 const google::protobuf::RepeatedPtrField<google::protobuf::Any>& aItems,
135 std::function<
void( ItemStatus, google::protobuf::Any )> aItemHandler )
141 if( !containerResult && containerResult.error().status() == ApiStatusCode::AS_UNHANDLED )
144 e.set_status( ApiStatusCode::AS_UNHANDLED );
145 return tl::unexpected( e );
147 else if( !containerResult )
149 e.CopyFrom( containerResult.error() );
150 return tl::unexpected( e );
156 std::map<KIID, EDA_ITEM*> itemUuidMap;
158 std::for_each( screenItems.
begin(), screenItems.
end(),
161 itemUuidMap[aItem->m_Uuid] = aItem;
166 if( containerResult->has_value() )
168 const KIID& containerId = **containerResult;
170 if( itemUuidMap.count( containerId ) )
172 container = itemUuidMap.at( containerId );
176 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
177 e.set_error_message( fmt::format(
178 "The requested container {} is not a valid schematic item container",
180 return tl::unexpected( e );
185 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
186 e.set_error_message( fmt::format(
187 "The requested container {} does not exist in this document",
189 return tl::unexpected( e );
195 for(
const google::protobuf::Any& anyItem : aItems )
202 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
203 status.set_error_message( fmt::format(
"Could not decode a valid type from {}",
204 anyItem.type_url() ) );
205 aItemHandler( status, anyItem );
212 if( !creationResult )
214 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
215 status.set_error_message( creationResult.error().error_message() );
216 aItemHandler( status, anyItem );
220 std::unique_ptr<EDA_ITEM> item( std::move( *creationResult ) );
222 if( !item->Deserialize( anyItem ) )
224 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
225 e.set_error_message( fmt::format(
"could not unpack {} from request",
226 item->GetClass().ToStdString() ) );
227 return tl::unexpected( e );
230 if( aCreate && itemUuidMap.count( item->m_Uuid ) )
232 status.set_code( ItemStatusCode::ISC_EXISTING );
233 status.set_error_message( fmt::format(
"an item with UUID {} already exists",
234 item->m_Uuid.AsStdString() ) );
235 aItemHandler( status, anyItem );
238 else if( !aCreate && !itemUuidMap.count( item->m_Uuid ) )
240 status.set_code( ItemStatusCode::ISC_NONEXISTENT );
241 status.set_error_message( fmt::format(
"an item with UUID {} does not exist",
242 item->m_Uuid.AsStdString() ) );
243 aItemHandler( status, anyItem );
247 status.set_code( ItemStatusCode::ISC_OK );
248 google::protobuf::Any newItem;
252 item->Serialize( newItem );
253 commit->
Add( item.release() );
260 EDA_ITEM* edaItem = itemUuidMap[item->m_Uuid];
264 schItem->SwapData(
static_cast<SCH_ITEM*
>( item.get() ) );
266 commit->
Modify( schItem );
277 aItemHandler( status, newItem );
281 return ItemRequestStatus::IRS_OK;
286 const std::string& aClientName )
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
Base class for API handlers related to editor frames.
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.
COMMIT * getCurrentCommit(const std::string &aClientName)
virtual void pushCurrentCommit(const std::string &aClientName, const wxString &aMessage)
std::set< std::string > m_activeClients
std::unique_ptr< COMMIT > createCommit() override
Override this to create an appropriate COMMIT subclass for the frame in question.
std::optional< EDA_ITEM * > getItemFromDocument(const DocumentSpecifier &aDocument, const KIID &aId) override
HANDLER_RESULT< std::unique_ptr< EDA_ITEM > > createItemForType(KICAD_T aType, EDA_ITEM *aContainer)
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)
bool validateDocumentInternal(const DocumentSpecifier &aDocument) const override
void deleteItemsInternal(std::map< KIID, ItemDeletionStatus > &aItemsToDelete, const std::string &aClientName) override
Represent a set of changes (additions, deletions or modifications) of a data model (e....
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
A base class for most all the KiCad significant classes used in schematics and boards.
virtual wxString GetFriendlyName() const
Implements an R-tree for fast spatial and type indexing of schematic items.
iterator end()
Returns a read/write iterator that points to one past the last element in the EE_RTREE.
iterator begin()
Returns a read/write iterator that points to the first element in the EE_RTREE N.B.
std::string AsStdString() const
Holds all the data relating to one schematic.
Schematic editor (Eeschema) main window.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
wxString GetCurrentFileName() const override
Get the full filename + path of the currently opened file in the frame.
Base class for any item which can be embedded within the SCHEMATIC container class,...
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
virtual void Serialize(google::protobuf::Any &aContainer) const
Serializes this object to the given Any message.
KICOMMON_API std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
RequestMessageType Request
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.