KiCad PCB EDA Suite
Loading...
Searching...
No Matches
api_handler_pcb.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 <magic_enum.hpp>
22
23#include <api/api_handler_pcb.h>
24#include <api/api_pcb_utils.h>
25#include <api/api_enums.h>
26#include <api/api_utils.h>
27#include <board_commit.h>
29#include <footprint.h>
30#include <netinfo.h>
31#include <pad.h>
32#include <pcb_edit_frame.h>
33#include <pcb_group.h>
34#include <pcb_reference_image.h>
35#include <pcb_shape.h>
36#include <pcb_text.h>
37#include <pcb_textbox.h>
38#include <pcb_track.h>
39#include <project.h>
40#include <tool/tool_manager.h>
41#include <tools/pcb_actions.h>
43#include <zone.h>
44
45#include <api/common/types/base_types.pb.h>
46
47using namespace kiapi::common::commands;
48using kiapi::common::types::CommandStatus;
49using kiapi::common::types::DocumentType;
50using kiapi::common::types::ItemRequestStatus;
51
52
54 API_HANDLER_EDITOR( aFrame )
55{
56 registerHandler<RunAction, RunActionResponse>( &API_HANDLER_PCB::handleRunAction );
57 registerHandler<GetOpenDocuments, GetOpenDocumentsResponse>(
59
60
61 registerHandler<GetItems, GetItemsResponse>( &API_HANDLER_PCB::handleGetItems );
62
63 registerHandler<GetBoardStackup, BoardStackupResponse>( &API_HANDLER_PCB::handleGetStackup );
64 registerHandler<GetGraphicsDefaults, GraphicsDefaultsResponse>(
66 registerHandler<GetTextExtents, commands::BoundingBoxResponse>(
68
69 registerHandler<InteractiveMoveItems, Empty>( &API_HANDLER_PCB::handleInteractiveMoveItems );
70 registerHandler<GetNets, NetsResponse>( &API_HANDLER_PCB::handleGetNets );
71 registerHandler<RefillZones, Empty>( &API_HANDLER_PCB::handleRefillZones );
72}
73
74
76{
77 return static_cast<PCB_EDIT_FRAME*>( m_frame );
78}
79
80
82 const HANDLER_CONTEXT& )
83{
84 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
85 return tl::unexpected( *busy );
86
87 RunActionResponse response;
88
89 if( frame()->GetToolManager()->RunAction( aRequest.action(), true ) )
90 response.set_status( RunActionStatus::RAS_OK );
91 else
92 response.set_status( RunActionStatus::RAS_INVALID );
93
94 return response;
95}
96
97
99 GetOpenDocuments& aMsg, const HANDLER_CONTEXT& )
100{
101 if( aMsg.type() != DocumentType::DOCTYPE_PCB )
102 {
103 ApiResponseStatus e;
104 // No message needed for AS_UNHANDLED; this is an internal flag for the API server
105 e.set_status( ApiStatusCode::AS_UNHANDLED );
106 return tl::unexpected( e );
107 }
108
109 GetOpenDocumentsResponse response;
110 common::types::DocumentSpecifier doc;
111
112 wxFileName fn( frame()->GetCurrentFileName() );
113
114 doc.set_type( DocumentType::DOCTYPE_PCB );
115 doc.set_board_filename( fn.GetFullName() );
116
117 doc.mutable_project()->set_name( frame()->Prj().GetProjectName().ToStdString() );
118 doc.mutable_project()->set_path( frame()->Prj().GetProjectDirectory().ToStdString() );
119
120 response.mutable_documents()->Add( std::move( doc ) );
121 return response;
122}
123
124
125void API_HANDLER_PCB::pushCurrentCommit( const HANDLER_CONTEXT& aCtx, const wxString& aMessage )
126{
128 frame()->Refresh();
129}
130
131
132std::unique_ptr<COMMIT> API_HANDLER_PCB::createCommit()
133{
134 return std::make_unique<BOARD_COMMIT>( frame() );
135}
136
137
138std::optional<BOARD_ITEM*> API_HANDLER_PCB::getItemById( const KIID& aId ) const
139{
140 BOARD_ITEM* item = frame()->GetBoard()->GetItem( aId );
141
142 if( item == DELETED_BOARD_ITEM::GetInstance() )
143 return std::nullopt;
144
145 return item;
146}
147
148
149bool API_HANDLER_PCB::validateDocumentInternal( const DocumentSpecifier& aDocument ) const
150{
151 if( aDocument.type() != DocumentType::DOCTYPE_PCB )
152 return false;
153
154 wxFileName fn( frame()->GetCurrentFileName() );
155 return 0 == aDocument.board_filename().compare( fn.GetFullName() );
156}
157
158
160 BOARD_ITEM_CONTAINER* aContainer )
161{
162 if( !aContainer )
163 {
164 ApiResponseStatus e;
165 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
166 e.set_error_message( "Tried to create an item in a null container" );
167 return tl::unexpected( e );
168 }
169
170 if( aType == PCB_PAD_T && !dynamic_cast<FOOTPRINT*>( aContainer ) )
171 {
172 ApiResponseStatus e;
173 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
174 e.set_error_message( fmt::format( "Tried to create a pad in {}, which is not a footprint",
175 aContainer->GetFriendlyName().ToStdString() ) );
176 return tl::unexpected( e );
177 }
178 else if( aType == PCB_FOOTPRINT_T && !dynamic_cast<BOARD*>( aContainer ) )
179 {
180 ApiResponseStatus e;
181 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
182 e.set_error_message( fmt::format( "Tried to create a footprint in {}, which is not a board",
183 aContainer->GetFriendlyName().ToStdString() ) );
184 return tl::unexpected( e );
185 }
186
187 std::unique_ptr<BOARD_ITEM> created = CreateItemForType( aType, aContainer );
188
189 if( !created )
190 {
191 ApiResponseStatus e;
192 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
193 e.set_error_message( fmt::format( "Tried to create an item of type {}, which is unhandled",
194 magic_enum::enum_name( aType ) ) );
195 return tl::unexpected( e );
196 }
197
198 return created;
199}
200
201
203 const HANDLER_CONTEXT& aCtx,
204 const types::ItemHeader &aHeader,
205 const google::protobuf::RepeatedPtrField<google::protobuf::Any>& aItems,
206 std::function<void( ItemStatus, google::protobuf::Any )> aItemHandler )
207{
208 ApiResponseStatus e;
209
210 auto containerResult = validateItemHeaderDocument( aHeader );
211
212 if( !containerResult && containerResult.error().status() == ApiStatusCode::AS_UNHANDLED )
213 {
214 // No message needed for AS_UNHANDLED; this is an internal flag for the API server
215 e.set_status( ApiStatusCode::AS_UNHANDLED );
216 return tl::unexpected( e );
217 }
218 else if( !containerResult )
219 {
220 e.CopyFrom( containerResult.error() );
221 return tl::unexpected( e );
222 }
223
224 BOARD* board = frame()->GetBoard();
225 BOARD_ITEM_CONTAINER* container = board;
226
227 if( containerResult->has_value() )
228 {
229 const KIID& containerId = **containerResult;
230 std::optional<BOARD_ITEM*> optItem = getItemById( containerId );
231
232 if( optItem )
233 {
234 container = dynamic_cast<BOARD_ITEM_CONTAINER*>( *optItem );
235
236 if( !container )
237 {
238 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
239 e.set_error_message( fmt::format(
240 "The requested container {} is not a valid board item container",
241 containerId.AsStdString() ) );
242 return tl::unexpected( e );
243 }
244 }
245 else
246 {
247 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
248 e.set_error_message( fmt::format(
249 "The requested container {} does not exist in this document",
250 containerId.AsStdString() ) );
251 return tl::unexpected( e );
252 }
253 }
254
255 BOARD_COMMIT* commit = static_cast<BOARD_COMMIT*>( getCurrentCommit( aCtx ) );
256
257 for( const google::protobuf::Any& anyItem : aItems )
258 {
259 ItemStatus status;
260 std::optional<KICAD_T> type = TypeNameFromAny( anyItem );
261
262 if( !type )
263 {
264 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
265 status.set_error_message( fmt::format( "Could not decode a valid type from {}",
266 anyItem.type_url() ) );
267 aItemHandler( status, anyItem );
268 continue;
269 }
270
272 createItemForType( *type, container );
273
274 if( !creationResult )
275 {
276 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
277 status.set_error_message( creationResult.error().error_message() );
278 aItemHandler( status, anyItem );
279 continue;
280 }
281
282 std::unique_ptr<BOARD_ITEM> item( std::move( *creationResult ) );
283
284 if( !item->Deserialize( anyItem ) )
285 {
286 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
287 e.set_error_message( fmt::format( "could not unpack {} from request",
288 item->GetClass().ToStdString() ) );
289 return tl::unexpected( e );
290 }
291
292 std::optional<BOARD_ITEM*> optItem = getItemById( item->m_Uuid );
293
294 if( aCreate && optItem )
295 {
296 status.set_code( ItemStatusCode::ISC_EXISTING );
297 status.set_error_message( fmt::format( "an item with UUID {} already exists",
298 item->m_Uuid.AsStdString() ) );
299 aItemHandler( status, anyItem );
300 continue;
301 }
302 else if( !aCreate && !optItem )
303 {
304 status.set_code( ItemStatusCode::ISC_NONEXISTENT );
305 status.set_error_message( fmt::format( "an item with UUID {} does not exist",
306 item->m_Uuid.AsStdString() ) );
307 aItemHandler( status, anyItem );
308 continue;
309 }
310
311 if( aCreate && !board->GetEnabledLayers().Contains( item->GetLayer() ) )
312 {
313 status.set_code( ItemStatusCode::ISC_INVALID_DATA );
314 status.set_error_message( fmt::format( "attempted to add item on disabled layer {}",
315 LayerName( item->GetLayer() ).ToStdString() ) );
316 aItemHandler( status, anyItem );
317 continue;
318 }
319
320 status.set_code( ItemStatusCode::ISC_OK );
321 google::protobuf::Any newItem;
322
323 if( aCreate )
324 {
325 item->Serialize( newItem );
326 commit->Add( item.release() );
327 }
328 else
329 {
330 BOARD_ITEM* boardItem = *optItem;
331 commit->Modify( boardItem );
332 boardItem->SwapItemData( item.get() );
333 boardItem->Serialize( newItem );
334 }
335
336 aItemHandler( status, newItem );
337 }
338
339 if( !m_activeClients.count( aCtx.ClientName ) )
340 {
341 pushCurrentCommit( aCtx, aCreate ? _( "Created items via API" )
342 : _( "Added items via API" ) );
343 }
344
345
346 return ItemRequestStatus::IRS_OK;
347}
348
349
351 const HANDLER_CONTEXT& )
352{
353 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
354 return tl::unexpected( *busy );
355
356 if( !validateItemHeaderDocument( aMsg.header() ) )
357 {
358 ApiResponseStatus e;
359 // No message needed for AS_UNHANDLED; this is an internal flag for the API server
360 e.set_status( ApiStatusCode::AS_UNHANDLED );
361 return tl::unexpected( e );
362 }
363
364 GetItemsResponse response;
365
366 BOARD* board = frame()->GetBoard();
367 std::vector<BOARD_ITEM*> items;
368 std::set<KICAD_T> typesRequested, typesInserted;
369 bool handledAnything = false;
370
371 for( int typeRaw : aMsg.types() )
372 {
373 auto typeMessage = static_cast<common::types::KiCadObjectType>( typeRaw );
374 KICAD_T type = FromProtoEnum<KICAD_T>( typeMessage );
375
376 if( type == TYPE_NOT_INIT )
377 continue;
378
379 typesRequested.emplace( type );
380
381 if( typesInserted.count( type ) )
382 continue;
383
384 switch( type )
385 {
386 case PCB_TRACE_T:
387 case PCB_ARC_T:
388 case PCB_VIA_T:
389 handledAnything = true;
390 std::copy( board->Tracks().begin(), board->Tracks().end(),
391 std::back_inserter( items ) );
392 typesInserted.insert( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } );
393 break;
394
395 case PCB_PAD_T:
396 {
397 handledAnything = true;
398
399 for( FOOTPRINT* fp : board->Footprints() )
400 {
401 std::copy( fp->Pads().begin(), fp->Pads().end(),
402 std::back_inserter( items ) );
403 }
404
405 typesInserted.insert( PCB_PAD_T );
406 break;
407 }
408
409 case PCB_FOOTPRINT_T:
410 {
411 handledAnything = true;
412
413 std::copy( board->Footprints().begin(), board->Footprints().end(),
414 std::back_inserter( items ) );
415
416 typesInserted.insert( PCB_FOOTPRINT_T );
417 break;
418 }
419
420 default:
421 break;
422 }
423 }
424
425 if( !handledAnything )
426 {
427 ApiResponseStatus e;
428 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
429 e.set_error_message( "none of the requested types are valid for a Board object" );
430 return tl::unexpected( e );
431 }
432
433 for( const BOARD_ITEM* item : items )
434 {
435 if( !typesRequested.count( item->Type() ) )
436 continue;
437
438 google::protobuf::Any itemBuf;
439 item->Serialize( itemBuf );
440 response.mutable_items()->Add( std::move( itemBuf ) );
441 }
442
443 response.set_status( ItemRequestStatus::IRS_OK );
444 return response;
445}
446
447
448void API_HANDLER_PCB::deleteItemsInternal( std::map<KIID, ItemDeletionStatus>& aItemsToDelete,
449 const HANDLER_CONTEXT& aCtx )
450{
451 BOARD* board = frame()->GetBoard();
452 std::vector<BOARD_ITEM*> validatedItems;
453
454 for( std::pair<const KIID, ItemDeletionStatus> pair : aItemsToDelete )
455 {
456 if( BOARD_ITEM* item = board->GetItem( pair.first ) )
457 {
458 validatedItems.push_back( item );
459 aItemsToDelete[pair.first] = ItemDeletionStatus::IDS_OK;
460 }
461
462 // Note: we don't currently support locking items from API modification, but here is where
463 // to add it in the future (and return IDS_IMMUTABLE)
464 }
465
466 COMMIT* commit = getCurrentCommit( aCtx );
467
468 for( BOARD_ITEM* item : validatedItems )
469 commit->Remove( item );
470
471 if( !m_activeClients.count( aCtx.ClientName ) )
472 pushCurrentCommit( aCtx, _( "Deleted items via API" ) );
473}
474
475
476std::optional<EDA_ITEM*> API_HANDLER_PCB::getItemFromDocument( const DocumentSpecifier& aDocument,
477 const KIID& aId )
478{
479 if( !validateDocument( aDocument ) )
480 return std::nullopt;
481
482 return getItemById( aId );
483}
484
485
487 const HANDLER_CONTEXT& aCtx )
488{
489 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
490 return tl::unexpected( *busy );
491
492 HANDLER_RESULT<bool> documentValidation = validateDocument( aMsg.board() );
493
494 if( !documentValidation )
495 return tl::unexpected( documentValidation.error() );
496
497 BoardStackupResponse response;
498 google::protobuf::Any any;
499
501
502 any.UnpackTo( response.mutable_stackup() );
503
504 return response;
505}
506
507
509 GetGraphicsDefaults& aMsg,
510 const HANDLER_CONTEXT& aCtx )
511{
512 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
513 return tl::unexpected( *busy );
514
515 HANDLER_RESULT<bool> documentValidation = validateDocument( aMsg.board() );
516
517 if( !documentValidation )
518 return tl::unexpected( documentValidation.error() );
519
521 GraphicsDefaultsResponse response;
522
523 // TODO: This should change to be an enum class
524 constexpr std::array<kiapi::board::BoardLayerClass, LAYER_CLASS_COUNT> classOrder = {
525 kiapi::board::BLC_SILKSCREEN,
526 kiapi::board::BLC_COPPER,
527 kiapi::board::BLC_EDGES,
528 kiapi::board::BLC_COURTYARD,
529 kiapi::board::BLC_FABRICATION,
530 kiapi::board::BLC_OTHER
531 };
532
533 for( int i = 0; i < LAYER_CLASS_COUNT; ++i )
534 {
535 kiapi::board::BoardLayerGraphicsDefaults* l = response.mutable_defaults()->add_layers();
536
537 l->set_layer( classOrder[i] );
538 l->mutable_line_thickness()->set_value_nm( bds.m_LineThickness[i] );
539
540 kiapi::common::types::TextAttributes* text = l->mutable_text();
541 text->mutable_size()->set_x_nm( bds.m_TextSize[i].x );
542 text->mutable_size()->set_y_nm( bds.m_TextSize[i].y );
543 text->mutable_stroke_width()->set_value_nm( bds.m_TextThickness[i] );
544 text->set_italic( bds.m_TextItalic[i] );
545 text->set_keep_upright( bds.m_TextUpright[i] );
546 }
547
548 return response;
549}
550
551
553 GetTextExtents& aMsg,
554 const HANDLER_CONTEXT& aCtx )
555{
556 PCB_TEXT text( frame()->GetBoard() );
557
558 google::protobuf::Any any;
559 any.PackFrom( aMsg.text() );
560
561 if( !text.Deserialize( any ) )
562 {
563 ApiResponseStatus e;
564 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
565 e.set_error_message( "Could not decode text in GetTextExtents message" );
566 return tl::unexpected( e );
567 }
568
569 commands::BoundingBoxResponse response;
570
571 BOX2I bbox = text.GetTextBox();
572 EDA_ANGLE angle = text.GetTextAngle();
573
574 if( !angle.IsZero() )
575 bbox = bbox.GetBoundingBoxRotated( text.GetTextPos(), text.GetTextAngle() );
576
577 response.mutable_position()->set_x_nm( bbox.GetPosition().x );
578 response.mutable_position()->set_y_nm( bbox.GetPosition().y );
579 response.mutable_size()->set_x_nm( bbox.GetSize().x );
580 response.mutable_size()->set_y_nm( bbox.GetSize().y );
581
582 return response;
583}
584
585
587 const HANDLER_CONTEXT& aCtx )
588{
589 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
590 return tl::unexpected( *busy );
591
592 HANDLER_RESULT<bool> documentValidation = validateDocument( aMsg.board() );
593
594 if( !documentValidation )
595 return tl::unexpected( documentValidation.error() );
596
598 std::vector<EDA_ITEM*> toSelect;
599
600 for( const kiapi::common::types::KIID& id : aMsg.items() )
601 {
602 if( std::optional<BOARD_ITEM*> item = getItemById( KIID( id.value() ) ) )
603 toSelect.emplace_back( static_cast<EDA_ITEM*>( *item ) );
604 }
605
606 if( toSelect.empty() )
607 {
608 ApiResponseStatus e;
609 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
610 e.set_error_message( fmt::format( "None of the given items exist on the board",
611 aMsg.board().board_filename() ) );
612 return tl::unexpected( e );
613 }
614
615 PCB_SELECTION_TOOL* selectionTool = mgr->GetTool<PCB_SELECTION_TOOL>();
616 selectionTool->GetSelection().SetReferencePoint( toSelect[0]->GetPosition() );
617
619 mgr->RunAction<EDA_ITEMS*>( PCB_ACTIONS::selectItems, &toSelect );
620
621 COMMIT* commit = getCurrentCommit( aCtx );
622 mgr->PostAction( PCB_ACTIONS::move, commit );
623
624 return Empty();
625}
626
627
629 const HANDLER_CONTEXT& aCtx )
630{
631 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
632 return tl::unexpected( *busy );
633
634 HANDLER_RESULT<bool> documentValidation = validateDocument( aMsg.board() );
635
636 if( !documentValidation )
637 return tl::unexpected( documentValidation.error() );
638
639 NetsResponse response;
640 BOARD* board = frame()->GetBoard();
641
642 std::set<wxString> netclassFilter;
643
644 for( const std::string& nc : aMsg.netclass_filter() )
645 netclassFilter.insert( wxString( nc.c_str(), wxConvUTF8 ) );
646
647 for( NETINFO_ITEM* net : board->GetNetInfo() )
648 {
649 NETCLASS* nc = net->GetNetClass();
650
651 if( !netclassFilter.empty() && nc && !netclassFilter.count( nc->GetName() ) )
652 continue;
653
654 board::types::Net* netProto = response.add_nets();
655 netProto->set_name( net->GetNetname() );
656 netProto->mutable_code()->set_value( net->GetNetCode() );
657 }
658
659 return response;
660}
661
662
664 const HANDLER_CONTEXT& aCtx )
665{
666 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
667 return tl::unexpected( *busy );
668
669 HANDLER_RESULT<bool> documentValidation = validateDocument( aMsg.board() );
670
671 if( !documentValidation )
672 return tl::unexpected( documentValidation.error() );
673
674 if( aMsg.zones().empty() )
675 {
677 frame()->CallAfter( [mgr]()
678 {
680 } );
681 }
682 else
683 {
684 // TODO
685 ApiResponseStatus e;
686 e.set_status( ApiStatusCode::AS_UNIMPLEMENTED );
687 return tl::unexpected( e );
688 }
689
690 return Empty();
691}
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
Definition: api_handler.h:45
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
@ LAYER_CLASS_COUNT
Base class for API handlers related to editor frames.
virtual void pushCurrentCommit(const HANDLER_CONTEXT &aCtx, const wxString &aMessage)
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 HANDLER_CONTEXT &aCtx)
std::set< std::string > m_activeClients
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
EDA_BASE_FRAME * m_frame
HANDLER_RESULT< commands::GetItemsResponse > handleGetItems(commands::GetItems &aMsg, const HANDLER_CONTEXT &aCtx)
bool validateDocumentInternal(const DocumentSpecifier &aDocument) const override
API_HANDLER_PCB(PCB_EDIT_FRAME *aFrame)
static HANDLER_RESULT< std::unique_ptr< BOARD_ITEM > > createItemForType(KICAD_T aType, BOARD_ITEM_CONTAINER *aContainer)
std::optional< BOARD_ITEM * > getItemById(const KIID &aId) const
HANDLER_RESULT< commands::BoundingBoxResponse > handleGetTextExtents(GetTextExtents &aMsg, const HANDLER_CONTEXT &aCtx)
std::unique_ptr< COMMIT > createCommit() override
Override this to create an appropriate COMMIT subclass for the frame in question.
HANDLER_RESULT< Empty > handleInteractiveMoveItems(InteractiveMoveItems &aMsg, const HANDLER_CONTEXT &aCtx)
HANDLER_RESULT< BoardStackupResponse > handleGetStackup(GetBoardStackup &aMsg, const HANDLER_CONTEXT &aCtx)
void deleteItemsInternal(std::map< KIID, ItemDeletionStatus > &aItemsToDelete, const HANDLER_CONTEXT &aCtx) override
std::optional< EDA_ITEM * > getItemFromDocument(const DocumentSpecifier &aDocument, const KIID &aId) override
HANDLER_RESULT< commands::RunActionResponse > handleRunAction(commands::RunAction &aMsg, const HANDLER_CONTEXT &aCtx)
HANDLER_RESULT< types::ItemRequestStatus > handleCreateUpdateItemsInternal(bool aCreate, const HANDLER_CONTEXT &aCtx, const types::ItemHeader &aHeader, const google::protobuf::RepeatedPtrField< google::protobuf::Any > &aItems, std::function< void(commands::ItemStatus, google::protobuf::Any)> aItemHandler) override
HANDLER_RESULT< Empty > handleRefillZones(RefillZones &aMsg, const HANDLER_CONTEXT &aCtx)
HANDLER_RESULT< GraphicsDefaultsResponse > handleGetGraphicsDefaults(GetGraphicsDefaults &aMsg, const HANDLER_CONTEXT &aCtx)
void pushCurrentCommit(const HANDLER_CONTEXT &aCtx, const wxString &aMessage) override
HANDLER_RESULT< commands::GetOpenDocumentsResponse > handleGetOpenDocuments(commands::GetOpenDocuments &aMsg, const HANDLER_CONTEXT &aCtx)
PCB_EDIT_FRAME * frame() const
HANDLER_RESULT< NetsResponse > handleGetNets(GetNets &aMsg, const HANDLER_CONTEXT &aCtx)
Container for design settings for a BOARD object.
bool m_TextUpright[LAYER_CLASS_COUNT]
int m_TextThickness[LAYER_CLASS_COUNT]
int m_LineThickness[LAYER_CLASS_COUNT]
VECTOR2I m_TextSize[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:77
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
Definition: board_item.cpp:175
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:282
BOARD_STACKUP GetStackupOrDefault() const
Definition: board.cpp:2170
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:853
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:677
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1290
const FOOTPRINTS & Footprints() const
Definition: board.h:323
const TRACKS & Tracks() const
Definition: board.h:321
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:794
const Vec & GetPosition() const
Definition: box2.h:201
const SizeVec & GetSize() const
Definition: box2.h:196
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:685
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition: commit.h:74
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been removed.
Definition: commit.h:92
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:80
static DELETED_BOARD_ITEM * GetInstance()
Definition: board_item.h:437
bool IsZero() const
Definition: eda_angle.h:133
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:88
virtual wxString GetFriendlyName() const
Definition: eda_item.cpp:329
Definition: kiid.h:49
std::string AsStdString() const
Definition: kiid.cpp:263
bool Contains(PCB_LAYER_ID aLayer)
See if the layer set contains a PCB layer.
Definition: layer_ids.h:648
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:44
const wxString GetName() const
Definition: netclass.h:62
Handle the data for a net.
Definition: netinfo.h:56
static TOOL_ACTION zoneFillAll
Definition: pcb_actions.h:397
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:68
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:120
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: pcb_actions.h:76
BOARD * GetBoard() const
The main frame for Pcbnew.
The selection tool: currently supports:
PCB_SELECTION & GetSelection()
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.cpp:179
virtual void Serialize(google::protobuf::Any &aContainer) const
Serializes this object to the given Any message.
Definition: serializable.h:43
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
Master controller class:
Definition: tool_manager.h:62
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:150
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:235
#define _(s)
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:532
PROJECT & Prj()
Definition: kicad.cpp:595
wxString LayerName(int aLayer)
Returns the default display name for a given layer.
Definition: layer_id.cpp:30
std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
Definition: api_utils.cpp:27
Class to handle a set of BOARD_ITEMs.
BOARD * GetBoard()
std::string ClientName
Definition: api_handler.h:50
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ TYPE_NOT_INIT
Definition: typeinfo.h:81
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96