30#include <google/protobuf/empty.pb.h>
40using namespace kiapi::common::commands;
42using google::protobuf::Empty;
80 GetVersionResponse reply;
85 reply.mutable_version()->set_major( std::get<0>( version ) );
86 reply.mutable_version()->set_minor( std::get<1>( version ) );
87 reply.mutable_version()->set_patch( std::get<2>( version ) );
96 wxFileName fn( wxEmptyString, wxString::FromUTF8( aCtx.
Request.binary_name() ) );
98 fn.SetExt( wxT(
"exe" ) );
103 reply.set_path(
path.ToUTF8() );
111 NetClassesResponse reply;
113 std::shared_ptr<NET_SETTINGS>& netSettings =
116 google::protobuf::Any
any;
118 netSettings->GetDefaultNetclass()->Serialize(
any );
119 any.UnpackTo( reply.add_net_classes() );
121 for(
const auto& netClass : netSettings->GetNetclasses() | std::views::values )
123 netClass->Serialize(
any );
124 any.UnpackTo( reply.add_net_classes() );
134 std::shared_ptr<NET_SETTINGS>& netSettings =
137 if( aCtx.
Request.merge_mode() == MapMergeMode::MMM_REPLACE )
138 netSettings->ClearNetclasses();
140 auto netClasses = netSettings->GetNetclasses();
141 google::protobuf::Any
any;
143 for(
const auto& ncProto : aCtx.
Request.net_classes() )
145 any.PackFrom( ncProto );
146 wxString
name = wxString::FromUTF8( ncProto.name() );
148 if(
name == wxT(
"Default" ) )
150 netSettings->GetDefaultNetclass()->Deserialize(
any );
154 if( !netClasses.contains(
name ) )
155 netClasses.insert( {
name, std::make_shared<NETCLASS>(
name,
false ) } );
157 netClasses[
name]->Deserialize(
any );
161 netSettings->SetNetclasses( netClasses );
177 google::protobuf::Any
any;
183 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
184 e.set_error_message(
"Could not decode text in GetTextExtents message" );
185 return tl::unexpected( e );
188 types::Box2 response;
196 response.mutable_position()->set_x_nm( bbox.
GetPosition().
x );
197 response.mutable_position()->set_y_nm( bbox.
GetPosition().
y );
198 response.mutable_size()->set_x_nm( bbox.
GetSize().
x );
199 response.mutable_size()->set_y_nm( bbox.
GetSize().
y );
208 GetTextAsShapesResponse reply;
210 for(
const TextOrTextBox& textMsg : aCtx.
Request.text() )
213 const Text* textPtr = &textMsg.text();
215 if( textMsg.has_textbox() )
217 dummyText.set_text( textMsg.textbox().text() );
218 dummyText.mutable_attributes()->CopyFrom( textMsg.textbox().attributes() );
219 textPtr = &dummyText;
223 google::protobuf::Any
any;
224 any.PackFrom( *textPtr );
229 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
230 e.set_error_message(
"Could not decode text in GetTextAsShapes message" );
231 return tl::unexpected( e );
234 std::shared_ptr<SHAPE_COMPOUND> shapes =
text.GetEffectiveTextShape(
false );
236 TextWithShapes* entry = reply.add_text_with_shapes();
237 entry->mutable_text()->CopyFrom( textMsg );
239 for(
SHAPE* subshape : shapes->Shapes() )
243 GraphicShape* shapeMsg = entry->mutable_shapes()->add_shapes();
244 any.UnpackTo( shapeMsg );
247 if( textMsg.has_textbox() )
249 GraphicShape* border = entry->mutable_shapes()->add_shapes();
250 int width = textMsg.textbox().attributes().stroke_width().value_nm();
251 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
256 PackVector2( *border->mutable_segment()->mutable_start(), tl );
260 border = entry->mutable_shapes()->add_shapes();
261 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
263 PackVector2( *border->mutable_segment()->mutable_end(), br );
266 border = entry->mutable_shapes()->add_shapes();
267 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
268 PackVector2( *border->mutable_segment()->mutable_start(), br );
272 border = entry->mutable_shapes()->add_shapes();
273 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
275 PackVector2( *border->mutable_segment()->mutable_end(), tl );
286 if( !aCtx.
Request.has_document() || aCtx.
Request.document().type() != DOCTYPE_PROJECT )
289 e.set_status( ApiStatusCode::AS_UNHANDLED );
291 return tl::unexpected( e );
294 ExpandTextVariablesResponse reply;
297 for(
const std::string& textMsg : aCtx.
Request.text() )
301 if( aCtx.
Request.expand_env_vars() )
304 reply.add_text(
result.ToUTF8() );
314 wxString identifier = wxString::FromUTF8( aCtx.
Request.identifier() );
316 if( identifier.IsEmpty() )
319 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
320 e.set_error_message(
"plugin identifier is missing" );
321 return tl::unexpected( e );
327 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
328 e.set_error_message(
"plugin identifier is invalid" );
329 return tl::unexpected( e );
333 path.AppendDir(
"plugins" );
338 path.AppendDir( identifier );
340 StringResponse reply;
341 reply.set_response(
path.GetPath() );
349 if( !aCtx.
Request.has_document() || aCtx.
Request.document().type() != DOCTYPE_PROJECT )
352 e.set_status( ApiStatusCode::AS_UNHANDLED );
354 return tl::unexpected( e );
362 e.set_status( ApiStatusCode::AS_NOT_READY );
363 e.set_error_message(
"no valid project is loaded, cannot get text variables" );
364 return tl::unexpected( e );
367 const std::map<wxString, wxString>& vars =
project.GetTextVars();
369 project::TextVariables reply;
370 auto map = reply.mutable_variables();
372 for(
const auto& [key, value] : vars )
373 ( *map )[ std::string( key.ToUTF8() ) ] = value.ToUTF8();
382 if( !aCtx.
Request.has_document() || aCtx.
Request.document().type() != DOCTYPE_PROJECT )
385 e.set_status( ApiStatusCode::AS_UNHANDLED );
387 return tl::unexpected( e );
395 e.set_status( ApiStatusCode::AS_NOT_READY );
396 e.set_error_message(
"no valid project is loaded, cannot set text variables" );
397 return tl::unexpected( e );
400 const project::TextVariables& newVars = aCtx.
Request.variables();
401 std::map<wxString, wxString>& vars =
project.GetTextVars();
403 if( aCtx.
Request.merge_mode() == MapMergeMode::MMM_REPLACE )
406 for(
const auto& [key, value] : newVars.variables() )
407 vars[wxString::FromUTF8( key )] = wxString::FromUTF8( value );
421 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
422 e.set_error_message(
"OpenDocument is not available in this KiCad mode" );
423 return tl::unexpected( e );
436 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
437 e.set_error_message(
"CloseDocument is not available in this KiCad mode" );
438 return tl::unexpected( e );
451 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
452 e.set_error_message(
"CreateDocument is not available in this KiCad mode" );
453 return tl::unexpected( e );
465 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
466 e.set_error_message(
"CloseAllDocuments is not available in this KiCad mode" );
467 return tl::unexpected( e );
476 GetPathsResponse reply;
478 auto addPath = [&]( types::PathType aType,
const wxString& aPath )
480 PathEntry* entry = reply.add_paths();
481 entry->set_type( aType );
482 entry->set_path( aPath.ToUTF8() );
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
constexpr EDA_IU_SCALE pcbIUScale
const std::tuple< int, int, int > & GetMajorMinorPatchTuple()
Get the build version numbers as a tuple.
wxString GetBuildVersion()
Get the full KiCad version string.
HANDLER_RESULT< Empty > handlePing(const HANDLER_CONTEXT< commands::Ping > &aCtx)
HANDLER_RESULT< types::Box2 > handleGetTextExtents(const HANDLER_CONTEXT< commands::GetTextExtents > &aCtx)
CLOSE_ALL_DOCUMENTS_HANDLER m_closeAllDocumentsHandler
HANDLER_RESULT< commands::GetTextAsShapesResponse > handleGetTextAsShapes(const HANDLER_CONTEXT< commands::GetTextAsShapes > &aCtx)
HANDLER_RESULT< commands::GetVersionResponse > handleGetVersion(const HANDLER_CONTEXT< commands::GetVersion > &aCtx)
CREATE_DOCUMENT_HANDLER m_createDocumentHandler
HANDLER_RESULT< Empty > handleCloseAllDocuments(const HANDLER_CONTEXT< commands::CloseAllDocuments > &aCtx)
HANDLER_RESULT< commands::OpenDocumentResponse > handleCreateDocument(const HANDLER_CONTEXT< commands::CreateDocument > &aCtx)
HANDLER_RESULT< commands::PathResponse > handleGetKiCadBinaryPath(const HANDLER_CONTEXT< commands::GetKiCadBinaryPath > &aCtx)
HANDLER_RESULT< commands::NetClassesResponse > handleGetNetClasses(const HANDLER_CONTEXT< commands::GetNetClasses > &aCtx)
CLOSE_DOCUMENT_HANDLER m_closeDocumentHandler
OPEN_DOCUMENT_HANDLER m_openDocumentHandler
HANDLER_RESULT< Empty > handleCloseDocument(const HANDLER_CONTEXT< commands::CloseDocument > &aCtx)
HANDLER_RESULT< Empty > handleSetNetClasses(const HANDLER_CONTEXT< commands::SetNetClasses > &aCtx)
HANDLER_RESULT< commands::StringResponse > handleGetPluginSettingsPath(const HANDLER_CONTEXT< commands::GetPluginSettingsPath > &aCtx)
HANDLER_RESULT< commands::OpenDocumentResponse > handleOpenDocument(const HANDLER_CONTEXT< commands::OpenDocument > &aCtx)
HANDLER_RESULT< commands::ExpandTextVariablesResponse > handleExpandTextVariables(const HANDLER_CONTEXT< commands::ExpandTextVariables > &aCtx)
HANDLER_RESULT< Empty > handleSetTextVariables(const HANDLER_CONTEXT< commands::SetTextVariables > &aCtx)
HANDLER_RESULT< commands::GetPathsResponse > handleGetPaths(const HANDLER_CONTEXT< commands::GetPaths > &aCtx)
HANDLER_RESULT< project::TextVariables > handleGetTextVariables(const HANDLER_CONTEXT< commands::GetTextVariables > &aCtx)
void registerHandler(HANDLER_RESULT< ResponseType >(HandlerType::*aHandler)(const HANDLER_CONTEXT< RequestType > &))
Registers an API command handler for the given message types.
static bool IsValidIdentifier(const wxString &aIdentifier)
constexpr const Vec & GetPosition() const
const BOX2< Vec > GetBoundingBoxRotated(const VECTOR2I &aRotCenter, const EDA_ANGLE &aAngle) const
Useful to calculate bounding box of rotated items, when rotation is not cardinal.
constexpr const SizeVec & GetSize() const
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
static wxString GetUserPluginsPath()
Gets the user path for plugins.
static wxString GetStockSymbolsPath()
Gets the stock (install) symbols path.
static wxString GetUserTemplatesPath()
Gets the user path for custom templates.
static bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
static wxString GetStock3dmodelsPath()
Gets the stock (install) 3dmodels path.
static wxString GetStockTemplatesPath()
Gets the stock (install) templates path.
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
static wxString GetStockDesignBlocksPath()
Gets the stock (install) footprints path.
static wxString GetStockFootprintsPath()
Gets the stock (install) footprints path.
virtual SETTINGS_MANAGER & GetSettingsManager() const
std::shared_ptr< NET_SETTINGS > m_NetSettings
Net settings for this project (owned here)
Container for project specific data.
virtual PROJECT_FILE & GetProjectFile() const
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Save a loaded project.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
An abstract shape on 2D plane.
A type-safe container of any type.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, RESOLUTION_CONTEXT aContext)
static std::string ToStdString(const wxString &aStr)
wxString FindKicadFile(const wxString &shortname)
Search the executable file shortname in KiCad binary path and return full file name if found or short...
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
PGM_BASE & Pgm()
The global program "get" accessor.
RequestMessageType Request
wxString result
Test unit parsing edge cases and error handling.
VECTOR2< int32_t > VECTOR2I