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 )
68 if( aCtx.
Request.type() != DocumentType::DOCTYPE_SCHEMATIC )
73 e.set_status( ApiStatusCode::AS_UNHANDLED );
74 return tl::unexpected( e );
77 GetOpenDocumentsResponse response;
78 common::types::DocumentSpecifier doc;
82 doc.set_type( DocumentType::DOCTYPE_SCHEMATIC );
83 doc.set_board_filename( fn.GetFullName() );
85 response.mutable_documents()->Add( std::move( doc ) );
96 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
97 e.set_error_message(
"Tried to create an item in a null container" );
98 return tl::unexpected( e );
104 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
105 e.set_error_message( fmt::format(
"Tried to create a pin in {}, which is not a symbol",
107 return tl::unexpected( e );
112 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
113 e.set_error_message( fmt::format(
"Tried to create a symbol in {}, which is not a "
116 return tl::unexpected( e );
124 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
125 e.set_error_message( fmt::format(
"Tried to create an item of type {}, which is unhandled",
126 magic_enum::enum_name( aType ) ) );
127 return tl::unexpected( e );
135 const std::string& aClientName,
136 const types::ItemHeader &aHeader,
137 const google::protobuf::RepeatedPtrField<google::protobuf::Any>& aItems,
138 std::function<
void( ItemStatus, google::protobuf::Any )> aItemHandler )
144 if( !containerResult && containerResult.error().status() == ApiStatusCode::AS_UNHANDLED )
147 e.set_status( ApiStatusCode::AS_UNHANDLED );
148 return tl::unexpected( e );
150 else if( !containerResult )
152 e.CopyFrom( containerResult.error() );
153 return tl::unexpected( e );
159 std::map<KIID, EDA_ITEM*> itemUuidMap;
161 std::for_each( screenItems.
begin(), screenItems.
end(),
164 itemUuidMap[aItem->m_Uuid] = aItem;
169 if( containerResult->has_value() )
171 const KIID& containerId = **containerResult;
173 if( itemUuidMap.count( containerId ) )
175 container = itemUuidMap.at( containerId );
179 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
180 e.set_error_message( fmt::format(
181 "The requested container {} is not a valid schematic item container",
183 return tl::unexpected( e );
188 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
189 e.set_error_message( fmt::format(
190 "The requested container {} does not exist in this document",
192 return tl::unexpected( e );
198 for(
const google::protobuf::Any& anyItem : aItems )
205 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
206 status.set_error_message( fmt::format(
"Could not decode a valid type from {}",
207 anyItem.type_url() ) );
208 aItemHandler( status, anyItem );
215 if( !creationResult )
217 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
218 status.set_error_message( creationResult.error().error_message() );
219 aItemHandler( status, anyItem );
223 std::unique_ptr<EDA_ITEM> item( std::move( *creationResult ) );
225 if( !item->Deserialize( anyItem ) )
227 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
228 e.set_error_message( fmt::format(
"could not unpack {} from request",
229 item->GetClass().ToStdString() ) );
230 return tl::unexpected( e );
233 if( aCreate && itemUuidMap.count( item->m_Uuid ) )
235 status.set_code( ItemStatusCode::ISC_EXISTING );
236 status.set_error_message( fmt::format(
"an item with UUID {} already exists",
237 item->m_Uuid.AsStdString() ) );
238 aItemHandler( status, anyItem );
241 else if( !aCreate && !itemUuidMap.count( item->m_Uuid ) )
243 status.set_code( ItemStatusCode::ISC_NONEXISTENT );
244 status.set_error_message( fmt::format(
"an item with UUID {} does not exist",
245 item->m_Uuid.AsStdString() ) );
246 aItemHandler( status, anyItem );
250 status.set_code( ItemStatusCode::ISC_OK );
251 google::protobuf::Any newItem;
255 item->Serialize( newItem );
256 commit->
Add( item.release() );
263 EDA_ITEM* edaItem = itemUuidMap[item->m_Uuid];
267 schItem->SwapData(
static_cast<SCH_ITEM*
>( item.get() ) );
269 commit->
Modify( schItem );
280 aItemHandler( status, newItem );
284 return ItemRequestStatus::IRS_OK;
289 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)
Modify a given item in the model.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
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.