29#include <google/protobuf/empty.pb.h>
39using namespace kiapi::common::commands;
40using namespace kiapi::common::types;
41using google::protobuf::Empty;
48 registerHandler<GetKiCadBinaryPath, PathResponse>(
54 registerHandler<GetTextAsShapes, GetTextAsShapesResponse>(
56 registerHandler<ExpandTextVariables, ExpandTextVariablesResponse>(
58 registerHandler<GetPluginSettingsPath, StringResponse>(
60 registerHandler<GetTextVariables, project::TextVariables>(
62 registerHandler<SetTextVariables, Empty>(
71 GetVersionResponse reply;
73 reply.mutable_version()->set_full_version(
GetBuildVersion().ToStdString() );
76 reply.mutable_version()->set_major( std::get<0>( version ) );
77 reply.mutable_version()->set_minor( std::get<1>( version ) );
78 reply.mutable_version()->set_patch( std::get<2>( version ) );
87 wxFileName fn( wxEmptyString, wxString::FromUTF8( aCtx.
Request.binary_name() ) );
89 fn.SetExt( wxT(
"exe" ) );
94 reply.set_path(
path.ToUTF8() );
102 NetClassesResponse reply;
104 std::shared_ptr<NET_SETTINGS>& netSettings =
107 google::protobuf::Any any;
109 netSettings->GetDefaultNetclass()->Serialize( any );
110 any.UnpackTo( reply.add_net_classes() );
112 for(
const auto& netClass : netSettings->GetNetclasses() | std::views::values )
114 netClass->Serialize( any );
115 any.UnpackTo( reply.add_net_classes() );
125 std::shared_ptr<NET_SETTINGS>& netSettings =
128 if( aCtx.
Request.merge_mode() == MapMergeMode::MMM_REPLACE )
129 netSettings->ClearNetclasses();
131 auto netClasses = netSettings->GetNetclasses();
132 google::protobuf::Any any;
134 for(
const auto& ncProto : aCtx.
Request.net_classes() )
136 any.PackFrom( ncProto );
137 wxString
name = wxString::FromUTF8( ncProto.name() );
139 if(
name == wxT(
"Default" ) )
141 netSettings->GetDefaultNetclass()->Deserialize( any );
145 if( !netClasses.contains(
name ) )
146 netClasses.insert( {
name, std::make_shared<NETCLASS>(
name,
false ) } );
148 netClasses[
name]->Deserialize( any );
152 netSettings->SetNetclasses( netClasses );
168 google::protobuf::Any any;
169 any.PackFrom( aCtx.
Request.text() );
171 if( !
text.Deserialize( any ) )
174 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
175 e.set_error_message(
"Could not decode text in GetTextExtents message" );
176 return tl::unexpected( e );
179 types::Box2 response;
187 response.mutable_position()->set_x_nm( bbox.
GetPosition().
x );
188 response.mutable_position()->set_y_nm( bbox.
GetPosition().
y );
189 response.mutable_size()->set_x_nm( bbox.
GetSize().
x );
190 response.mutable_size()->set_y_nm( bbox.
GetSize().
y );
199 GetTextAsShapesResponse reply;
201 for(
const TextOrTextBox& textMsg : aCtx.
Request.text() )
204 const Text* textPtr = &textMsg.text();
206 if( textMsg.has_textbox() )
208 dummyText.set_text( textMsg.textbox().text() );
209 dummyText.mutable_attributes()->CopyFrom( textMsg.textbox().attributes() );
210 textPtr = &dummyText;
214 google::protobuf::Any any;
215 any.PackFrom( *textPtr );
217 if( !
text.Deserialize( any ) )
220 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
221 e.set_error_message(
"Could not decode text in GetTextAsShapes message" );
222 return tl::unexpected( e );
225 std::shared_ptr<SHAPE_COMPOUND> shapes =
text.GetEffectiveTextShape(
false );
227 TextWithShapes* entry = reply.add_text_with_shapes();
228 entry->mutable_text()->CopyFrom( textMsg );
230 for(
SHAPE* subshape : shapes->Shapes() )
234 GraphicShape* shapeMsg = entry->mutable_shapes()->add_shapes();
235 any.UnpackTo( shapeMsg );
238 if( textMsg.has_textbox() )
240 GraphicShape* border = entry->mutable_shapes()->add_shapes();
241 int width = textMsg.textbox().attributes().stroke_width().value_nm();
242 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
247 PackVector2( *border->mutable_segment()->mutable_start(), tl );
251 border = entry->mutable_shapes()->add_shapes();
252 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
254 PackVector2( *border->mutable_segment()->mutable_end(), br );
257 border = entry->mutable_shapes()->add_shapes();
258 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
259 PackVector2( *border->mutable_segment()->mutable_start(), br );
263 border = entry->mutable_shapes()->add_shapes();
264 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
266 PackVector2( *border->mutable_segment()->mutable_end(), tl );
277 if( !aCtx.
Request.has_document() || aCtx.
Request.document().type() != DOCTYPE_PROJECT )
280 e.set_status( ApiStatusCode::AS_UNHANDLED );
282 return tl::unexpected( e );
285 ExpandTextVariablesResponse reply;
288 for(
const std::string& textMsg : aCtx.
Request.text() )
291 reply.add_text( result.ToUTF8() );
301 wxString identifier = wxString::FromUTF8( aCtx.
Request.identifier() );
303 if( identifier.IsEmpty() )
306 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
307 e.set_error_message(
"plugin identifier is missing" );
308 return tl::unexpected( e );
314 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
315 e.set_error_message(
"plugin identifier is invalid" );
316 return tl::unexpected( e );
320 path.AppendDir(
"plugins" );
325 path.AppendDir( identifier );
327 StringResponse reply;
328 reply.set_response(
path.GetPath() );
336 if( !aCtx.
Request.has_document() || aCtx.
Request.document().type() != DOCTYPE_PROJECT )
339 e.set_status( ApiStatusCode::AS_UNHANDLED );
341 return tl::unexpected( e );
349 e.set_status( ApiStatusCode::AS_NOT_READY );
350 e.set_error_message(
"no valid project is loaded, cannot get text variables" );
351 return tl::unexpected( e );
354 const std::map<wxString, wxString>& vars =
project.GetTextVars();
356 project::TextVariables reply;
357 auto map = reply.mutable_variables();
359 for(
const auto& [key, value] : vars )
360 ( *map )[ std::string( key.ToUTF8() ) ] = value.ToUTF8();
369 if( !aCtx.
Request.has_document() || aCtx.
Request.document().type() != DOCTYPE_PROJECT )
372 e.set_status( ApiStatusCode::AS_UNHANDLED );
374 return tl::unexpected( e );
382 e.set_status( ApiStatusCode::AS_NOT_READY );
383 e.set_error_message(
"no valid project is loaded, cannot set text variables" );
384 return tl::unexpected( e );
387 const project::TextVariables& newVars = aCtx.
Request.variables();
388 std::map<wxString, wxString>& vars =
project.GetTextVars();
390 if( aCtx.
Request.merge_mode() == MapMergeMode::MMM_REPLACE )
393 for(
const auto& [key, value] : newVars.variables() )
394 vars[wxString::FromUTF8( key )] = wxString::FromUTF8( value );
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)
HANDLER_RESULT< commands::GetTextAsShapesResponse > handleGetTextAsShapes(const HANDLER_CONTEXT< commands::GetTextAsShapes > &aCtx)
HANDLER_RESULT< commands::GetVersionResponse > handleGetVersion(const HANDLER_CONTEXT< commands::GetVersion > &aCtx)
HANDLER_RESULT< commands::PathResponse > handleGetKiCadBinaryPath(const HANDLER_CONTEXT< commands::GetKiCadBinaryPath > &aCtx)
HANDLER_RESULT< commands::NetClassesResponse > handleGetNetClasses(const HANDLER_CONTEXT< commands::GetNetClasses > &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::ExpandTextVariablesResponse > handleExpandTextVariables(const HANDLER_CONTEXT< commands::ExpandTextVariables > &aCtx)
HANDLER_RESULT< Empty > handleSetTextVariables(const HANDLER_CONTEXT< commands::SetTextVariables > &aCtx)
HANDLER_RESULT< project::TextVariables > handleGetTextVariables(const HANDLER_CONTEXT< commands::GetTextVariables > &aCtx)
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 bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
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.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
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)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput)
PGM_BASE & Pgm()
The global program "get" accessor.
RequestMessageType Request