KiCad PCB EDA Suite
Loading...
Searching...
No Matches
api_handler_common.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023 Jon Evans <[email protected]>
5 * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <tuple>
22
24#include <build_version.h>
25#include <eda_shape.h>
26#include <eda_text.h>
28#include <google/protobuf/empty.pb.h>
29#include <pgm_base.h>
30#include <api/api_utils.h>
34#include <wx/string.h>
35
36using namespace kiapi::common::commands;
37using namespace kiapi::common::types;
38using google::protobuf::Empty;
39
40
43{
44 registerHandler<commands::GetVersion, GetVersionResponse>( &API_HANDLER_COMMON::handleGetVersion );
45 registerHandler<GetNetClasses, NetClassesResponse>( &API_HANDLER_COMMON::handleGetNetClasses );
46 registerHandler<Ping, Empty>( &API_HANDLER_COMMON::handlePing );
47 registerHandler<GetTextExtents, types::Box2>( &API_HANDLER_COMMON::handleGetTextExtents );
48 registerHandler<GetTextAsShapes, GetTextAsShapesResponse>(
50 registerHandler<ExpandTextVariables, ExpandTextVariablesResponse>(
52}
53
54
57{
58 GetVersionResponse reply;
59
60 reply.mutable_version()->set_full_version( GetBuildVersion().ToStdString() );
61
62 std::tuple<int, int, int> version = GetMajorMinorPatchTuple();
63 reply.mutable_version()->set_major( std::get<0>( version ) );
64 reply.mutable_version()->set_minor( std::get<1>( version ) );
65 reply.mutable_version()->set_patch( std::get<2>( version ) );
66
67 return reply;
68}
69
70
73{
74 NetClassesResponse reply;
75
76 std::shared_ptr<NET_SETTINGS>& netSettings =
78
79 for( const auto& [name, netClass] : netSettings->GetNetclasses() )
80 {
81 reply.add_net_classes()->set_name( name.ToStdString() );
82 }
83
84 return reply;
85}
86
87
89{
90 return Empty();
91}
92
93
96{
98 google::protobuf::Any any;
99 any.PackFrom( aCtx.Request.text() );
100
101 if( !text.Deserialize( any ) )
102 {
103 ApiResponseStatus e;
104 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
105 e.set_error_message( "Could not decode text in GetTextExtents message" );
106 return tl::unexpected( e );
107 }
108
109 types::Box2 response;
110
111 BOX2I bbox = text.GetTextBox();
112 EDA_ANGLE angle = text.GetTextAngle();
113
114 if( !angle.IsZero() )
115 bbox = bbox.GetBoundingBoxRotated( text.GetTextPos(), text.GetTextAngle() );
116
117 response.mutable_position()->set_x_nm( bbox.GetPosition().x );
118 response.mutable_position()->set_y_nm( bbox.GetPosition().y );
119 response.mutable_size()->set_x_nm( bbox.GetSize().x );
120 response.mutable_size()->set_y_nm( bbox.GetSize().y );
121
122 return response;
123}
124
125
128{
129 GetTextAsShapesResponse reply;
130
131 for( const TextOrTextBox& textMsg : aCtx.Request.text() )
132 {
133 Text dummyText;
134 const Text* textPtr = &textMsg.text();
135
136 if( textMsg.has_textbox() )
137 {
138 dummyText.set_text( textMsg.textbox().text() );
139 dummyText.mutable_attributes()->CopyFrom( textMsg.textbox().attributes() );
140 textPtr = &dummyText;
141 }
142
144 google::protobuf::Any any;
145 any.PackFrom( *textPtr );
146
147 if( !text.Deserialize( any ) )
148 {
149 ApiResponseStatus e;
150 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
151 e.set_error_message( "Could not decode text in GetTextAsShapes message" );
152 return tl::unexpected( e );
153 }
154
155 std::shared_ptr<SHAPE_COMPOUND> shapes = text.GetEffectiveTextShape( false );
156
157 TextWithShapes* entry = reply.add_text_with_shapes();
158 entry->mutable_text()->CopyFrom( textMsg );
159
160 for( SHAPE* subshape : shapes->Shapes() )
161 {
162 EDA_SHAPE proxy( *subshape );
163 proxy.Serialize( any );
164 GraphicShape* shapeMsg = entry->mutable_shapes()->add_shapes();
165 any.UnpackTo( shapeMsg );
166 }
167
168 if( textMsg.has_textbox() )
169 {
170 GraphicShape* border = entry->mutable_shapes()->add_shapes();
171 int width = textMsg.textbox().attributes().stroke_width().value_nm();
172 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
173 VECTOR2I tl = UnpackVector2( textMsg.textbox().top_left() );
174 VECTOR2I br = UnpackVector2( textMsg.textbox().bottom_right() );
175
176 // top
177 PackVector2( *border->mutable_segment()->mutable_start(), tl );
178 PackVector2( *border->mutable_segment()->mutable_end(), VECTOR2I( br.x, tl.y ) );
179
180 // right
181 border = entry->mutable_shapes()->add_shapes();
182 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
183 PackVector2( *border->mutable_segment()->mutable_start(), VECTOR2I( br.x, tl.y ) );
184 PackVector2( *border->mutable_segment()->mutable_end(), br );
185
186 // bottom
187 border = entry->mutable_shapes()->add_shapes();
188 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
189 PackVector2( *border->mutable_segment()->mutable_start(), br );
190 PackVector2( *border->mutable_segment()->mutable_end(), VECTOR2I( tl.x, br.y ) );
191
192 // left
193 border = entry->mutable_shapes()->add_shapes();
194 border->mutable_attributes()->mutable_stroke()->mutable_width()->set_value_nm( width );
195 PackVector2( *border->mutable_segment()->mutable_start(), VECTOR2I( tl.x, br.y ) );
196 PackVector2( *border->mutable_segment()->mutable_end(), tl );
197 }
198 }
199
200 return reply;
201}
202
203
206{
207 if( !aCtx.Request.has_document() || aCtx.Request.document().type() != DOCTYPE_PROJECT )
208 {
209 ApiResponseStatus e;
210 e.set_status( ApiStatusCode::AS_UNHANDLED );
211 // No error message, this is a flag that the server should try a different handler
212 return tl::unexpected( e );
213 }
214
215 ExpandTextVariablesResponse reply;
217
218 for( const std::string& textMsg : aCtx.Request.text() )
219 {
220 wxString result = ExpandTextVars( wxString::FromUTF8( textMsg ), &project );
221 reply.add_text( result.ToUTF8() );
222 }
223
224 return reply;
225}
const char * name
Definition: DXF_plotter.cpp:57
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
Definition: api_handler.h:45
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
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::NetClassesResponse > handleGetNetClasses(const HANDLER_CONTEXT< commands::GetNetClasses > &aCtx)
HANDLER_RESULT< commands::ExpandTextVariablesResponse > handleExpandTextVariables(const HANDLER_CONTEXT< commands::ExpandTextVariables > &aCtx)
constexpr const Vec & GetPosition() const
Definition: box2.h:211
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.
Definition: box2.h:720
constexpr const SizeVec & GetSize() const
Definition: box2.h:206
bool IsZero() const
Definition: eda_angle.h:133
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: eda_shape.cpp:146
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:80
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
std::shared_ptr< NET_SETTINGS > m_NetSettings
Net settings for this project (owned here)
Definition: project_file.h:178
Container for project specific data.
Definition: project.h:64
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:200
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
An abstract shape on 2D plane.
Definition: shape.h:126
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
Definition: common.cpp:59
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput)
Definition: api_utils.cpp:84
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput)
Definition: api_utils.cpp:77
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
RequestMessageType Request
Definition: api_handler.h:52