KiCad PCB EDA Suite
Loading...
Searching...
No Matches
api_handler_sch.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) 2024 Jon Evans <[email protected]>
5 * Copyright The 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 <api/api_handler_sch.h>
22#include <api/api_enums.h>
23#include <api/api_sch_utils.h>
24#include <api/api_utils.h>
25#include <api/sch_context.h>
26#include <magic_enum.hpp>
30#include <kiway.h>
31#include <sch_commit.h>
32#include <sch_edit_frame.h>
33#include <wx/filename.h>
34
35#include <api/common/types/base_types.pb.h>
36
37using namespace kiapi::common::commands;
38using kiapi::common::types::CommandStatus;
39using kiapi::common::types::DocumentType;
40using kiapi::common::types::ItemRequestStatus;
41
42
44{
45 types::RunJobResponse response;
46 WX_STRING_REPORTER reporter;
47 int exitCode = aKiway->ProcessJob( KIWAY::FACE_SCH, &aJob, &reporter );
48
49 for( const JOB_OUTPUT& output : aJob.GetOutputs() )
50 response.add_output_path( output.m_outputPath.ToUTF8() );
51
52 if( exitCode == 0 )
53 {
54 response.set_status( types::JobStatus::JS_SUCCESS );
55 return response;
56 }
57
58 response.set_status( types::JobStatus::JS_ERROR );
59 response.set_message( fmt::format( "Schematic export job '{}' failed with exit code {}: {}",
60 aJob.GetType(), exitCode,
61 reporter.GetMessages().ToStdString() ) );
62 return response;
63}
64
65
70
71
94
95
96std::unique_ptr<COMMIT> API_HANDLER_SCH::createCommit()
97{
98 return std::make_unique<SCH_COMMIT>( m_frame );
99}
100
101
102bool API_HANDLER_SCH::validateDocumentInternal( const DocumentSpecifier& aDocument ) const
103{
104 if( aDocument.type() != DocumentType::DOCTYPE_SCHEMATIC )
105 return false;
106
107 // TODO(JE) need serdes for SCH_SHEET_PATH <> SheetPath
108 return true;
109
110 //wxString currentPath = m_frame->GetCurrentSheet().PathAsString();
111 //return 0 == aDocument.sheet_path().compare( currentPath.ToStdString() );
112}
113
114
117{
118 if( aCtx.Request.type() != DocumentType::DOCTYPE_SCHEMATIC )
119 {
120 ApiResponseStatus e;
121
122 // No message needed for AS_UNHANDLED; this is an internal flag for the API server
123 e.set_status( ApiStatusCode::AS_UNHANDLED );
124 return tl::unexpected( e );
125 }
126
127 GetOpenDocumentsResponse response;
128 common::types::DocumentSpecifier doc;
129
130 wxFileName fn( m_context->GetCurrentFileName() );
131
132 doc.set_type( DocumentType::DOCTYPE_SCHEMATIC );
133 doc.set_board_filename( fn.GetFullName() );
134
135 response.mutable_documents()->Add( std::move( doc ) );
136 return response;
137}
138
139
142{
143 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
144 return tl::unexpected( *busy );
145
146 HANDLER_RESULT<bool> documentValidation = validateDocument( aCtx.Request.job_settings().document() );
147
148 if( !documentValidation )
149 return tl::unexpected( documentValidation.error() );
150
151 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_SVG>();
152 plotJob->m_filename = m_context->GetCurrentFileName();
153
154 if( !aCtx.Request.job_settings().output_path().empty() )
155 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.Request.job_settings().output_path() ) );
156
157 const kiapi::schematic::jobs::SchematicPlotSettings& settings = aCtx.Request.plot_settings();
158
159 plotJob->m_drawingSheet = wxString::FromUTF8( settings.drawing_sheet() );
160 plotJob->m_defaultFont = wxString::FromUTF8( settings.default_font() );
161 plotJob->m_variant = wxString::FromUTF8( settings.variant() );
162 plotJob->m_plotAll = settings.plot_all();
163 plotJob->m_plotDrawingSheet = settings.plot_drawing_sheet();
164 plotJob->m_show_hop_over = settings.show_hop_over();
165 plotJob->m_blackAndWhite = settings.black_and_white();
166 plotJob->m_useBackgroundColor = settings.use_background_color();
167 plotJob->m_minPenWidth = settings.min_pen_width();
168 plotJob->m_theme = wxString::FromUTF8( settings.theme() );
169
170 plotJob->m_plotPages.clear();
171
172 for( const std::string& page : settings.plot_pages() )
173 plotJob->m_plotPages.push_back( wxString::FromUTF8( page ) );
174
175 if( aCtx.Request.plot_settings().page_size() != kiapi::schematic::jobs::SchematicJobPageSize::SJPS_UNKNOWN )
176 {
177 plotJob->m_pageSizeSelect = FromProtoEnum<JOB_PAGE_SIZE>( aCtx.Request.plot_settings().page_size() );
178 }
179
180 return ExecuteSchematicJob( m_context->GetKiway(), *plotJob );
181}
182
183
186{
187 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
188 return tl::unexpected( *busy );
189
190 HANDLER_RESULT<bool> documentValidation = validateDocument( aCtx.Request.job_settings().document() );
191
192 if( !documentValidation )
193 return tl::unexpected( documentValidation.error() );
194
195 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_DXF>();
196 plotJob->m_filename = m_context->GetCurrentFileName();
197
198 if( !aCtx.Request.job_settings().output_path().empty() )
199 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.Request.job_settings().output_path() ) );
200
201 const kiapi::schematic::jobs::SchematicPlotSettings& settings = aCtx.Request.plot_settings();
202
203 plotJob->m_drawingSheet = wxString::FromUTF8( settings.drawing_sheet() );
204 plotJob->m_defaultFont = wxString::FromUTF8( settings.default_font() );
205 plotJob->m_variant = wxString::FromUTF8( settings.variant() );
206 plotJob->m_plotAll = settings.plot_all();
207 plotJob->m_plotDrawingSheet = settings.plot_drawing_sheet();
208 plotJob->m_show_hop_over = settings.show_hop_over();
209 plotJob->m_blackAndWhite = settings.black_and_white();
210 plotJob->m_useBackgroundColor = settings.use_background_color();
211 plotJob->m_minPenWidth = settings.min_pen_width();
212 plotJob->m_theme = wxString::FromUTF8( settings.theme() );
213
214 plotJob->m_plotPages.clear();
215
216 for( const std::string& page : settings.plot_pages() )
217 plotJob->m_plotPages.push_back( wxString::FromUTF8( page ) );
218
219 if( aCtx.Request.plot_settings().page_size() != kiapi::schematic::jobs::SchematicJobPageSize::SJPS_UNKNOWN )
220 {
221 plotJob->m_pageSizeSelect = FromProtoEnum<JOB_PAGE_SIZE>( aCtx.Request.plot_settings().page_size() );
222 }
223
224 return ExecuteSchematicJob( m_context->GetKiway(), *plotJob );
225}
226
227
230{
231 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
232 return tl::unexpected( *busy );
233
234 HANDLER_RESULT<bool> documentValidation = validateDocument( aCtx.Request.job_settings().document() );
235
236 if( !documentValidation )
237 return tl::unexpected( documentValidation.error() );
238
239 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_PDF>( false );
240 plotJob->m_filename = m_context->GetCurrentFileName();
241
242 if( !aCtx.Request.job_settings().output_path().empty() )
243 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.Request.job_settings().output_path() ) );
244
245 const kiapi::schematic::jobs::SchematicPlotSettings& settings = aCtx.Request.plot_settings();
246
247 plotJob->m_drawingSheet = wxString::FromUTF8( settings.drawing_sheet() );
248 plotJob->m_defaultFont = wxString::FromUTF8( settings.default_font() );
249 plotJob->m_variant = wxString::FromUTF8( settings.variant() );
250 plotJob->m_plotAll = settings.plot_all();
251 plotJob->m_plotDrawingSheet = settings.plot_drawing_sheet();
252 plotJob->m_show_hop_over = settings.show_hop_over();
253 plotJob->m_blackAndWhite = settings.black_and_white();
254 plotJob->m_useBackgroundColor = settings.use_background_color();
255 plotJob->m_minPenWidth = settings.min_pen_width();
256 plotJob->m_theme = wxString::FromUTF8( settings.theme() );
257
258 plotJob->m_plotPages.clear();
259
260 for( const std::string& page : settings.plot_pages() )
261 plotJob->m_plotPages.push_back( wxString::FromUTF8( page ) );
262
263 if( aCtx.Request.plot_settings().page_size() != kiapi::schematic::jobs::SchematicJobPageSize::SJPS_UNKNOWN )
264 {
265 plotJob->m_pageSizeSelect = FromProtoEnum<JOB_PAGE_SIZE>( aCtx.Request.plot_settings().page_size() );
266 }
267
268 plotJob->m_PDFPropertyPopups = aCtx.Request.property_popups();
269 plotJob->m_PDFHierarchicalLinks = aCtx.Request.hierarchical_links();
270 plotJob->m_PDFMetadata = aCtx.Request.include_metadata();
271
272 return ExecuteSchematicJob( m_context->GetKiway(), *plotJob );
273}
274
275
278{
279 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
280 return tl::unexpected( *busy );
281
282 HANDLER_RESULT<bool> documentValidation = validateDocument( aCtx.Request.job_settings().document() );
283
284 if( !documentValidation )
285 return tl::unexpected( documentValidation.error() );
286
287 auto plotJob = std::make_unique<JOB_EXPORT_SCH_PLOT_PS>();
288 plotJob->m_filename = m_context->GetCurrentFileName();
289
290 if( !aCtx.Request.job_settings().output_path().empty() )
291 plotJob->SetConfiguredOutputPath( wxString::FromUTF8( aCtx.Request.job_settings().output_path() ) );
292
293 const kiapi::schematic::jobs::SchematicPlotSettings& settings = aCtx.Request.plot_settings();
294
295 plotJob->m_drawingSheet = wxString::FromUTF8( settings.drawing_sheet() );
296 plotJob->m_defaultFont = wxString::FromUTF8( settings.default_font() );
297 plotJob->m_variant = wxString::FromUTF8( settings.variant() );
298 plotJob->m_plotAll = settings.plot_all();
299 plotJob->m_plotDrawingSheet = settings.plot_drawing_sheet();
300 plotJob->m_show_hop_over = settings.show_hop_over();
301 plotJob->m_blackAndWhite = settings.black_and_white();
302 plotJob->m_useBackgroundColor = settings.use_background_color();
303 plotJob->m_minPenWidth = settings.min_pen_width();
304 plotJob->m_theme = wxString::FromUTF8( settings.theme() );
305
306 plotJob->m_plotPages.clear();
307
308 for( const std::string& page : settings.plot_pages() )
309 plotJob->m_plotPages.push_back( wxString::FromUTF8( page ) );
310
311 if( aCtx.Request.plot_settings().page_size() != kiapi::schematic::jobs::SchematicJobPageSize::SJPS_UNKNOWN )
312 {
313 plotJob->m_pageSizeSelect = FromProtoEnum<JOB_PAGE_SIZE>( aCtx.Request.plot_settings().page_size() );
314 }
315
316 return ExecuteSchematicJob( m_context->GetKiway(), *plotJob );
317}
318
319
322{
323 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
324 return tl::unexpected( *busy );
325
326 HANDLER_RESULT<bool> documentValidation = validateDocument( aCtx.Request.job_settings().document() );
327
328 if( !documentValidation )
329 return tl::unexpected( documentValidation.error() );
330
331 if( aCtx.Request.format() == kiapi::schematic::jobs::SchematicNetlistFormat::SNF_UNKNOWN )
332 {
333 ApiResponseStatus e;
334 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
335 e.set_error_message( "RunSchematicJobExportNetlist requires a valid format" );
336 return tl::unexpected( e );
337 }
338
339 JOB_EXPORT_SCH_NETLIST netlistJob;
340 netlistJob.m_filename = m_context->GetCurrentFileName();
341
342 if( !aCtx.Request.job_settings().output_path().empty() )
343 netlistJob.SetConfiguredOutputPath( wxString::FromUTF8( aCtx.Request.job_settings().output_path() ) );
344
346
347 if( !aCtx.Request.variant_name().empty() )
348 netlistJob.m_variantNames.emplace_back( wxString::FromUTF8( aCtx.Request.variant_name() ) );
349
350 return ExecuteSchematicJob( m_context->GetKiway(), netlistJob );
351}
352
353
356{
357 if( std::optional<ApiResponseStatus> busy = checkForBusy() )
358 return tl::unexpected( *busy );
359
360 HANDLER_RESULT<bool> documentValidation = validateDocument( aCtx.Request.job_settings().document() );
361
362 if( !documentValidation )
363 return tl::unexpected( documentValidation.error() );
364
365 JOB_EXPORT_SCH_BOM bomJob;
366 bomJob.m_filename = m_context->GetCurrentFileName();
367
368 if( !aCtx.Request.job_settings().output_path().empty() )
369 bomJob.SetConfiguredOutputPath( wxString::FromUTF8( aCtx.Request.job_settings().output_path() ) );
370
371 bomJob.m_bomFmtPresetName = wxString::FromUTF8( aCtx.Request.format().preset_name() );
372 bomJob.m_fieldDelimiter = wxString::FromUTF8( aCtx.Request.format().field_delimiter() );
373 bomJob.m_stringDelimiter = wxString::FromUTF8( aCtx.Request.format().string_delimiter() );
374 bomJob.m_refDelimiter = wxString::FromUTF8( aCtx.Request.format().ref_delimiter() );
375 bomJob.m_refRangeDelimiter = wxString::FromUTF8( aCtx.Request.format().ref_range_delimiter() );
376 bomJob.m_keepTabs = aCtx.Request.format().keep_tabs();
377 bomJob.m_keepLineBreaks = aCtx.Request.format().keep_line_breaks();
378
379 bomJob.m_bomPresetName = wxString::FromUTF8( aCtx.Request.fields().preset_name() );
380 bomJob.m_sortField = wxString::FromUTF8( aCtx.Request.fields().sort_field() );
381 bomJob.m_filterString = wxString::FromUTF8( aCtx.Request.fields().filter() );
382
383 if( aCtx.Request.fields().sort_direction() == kiapi::schematic::jobs::BOMSortDirection::BSD_ASCENDING )
384 {
385 bomJob.m_sortAsc = true;
386 }
387 else if( aCtx.Request.fields().sort_direction() == kiapi::schematic::jobs::BOMSortDirection::BSD_DESCENDING )
388 {
389 bomJob.m_sortAsc = false;
390 }
391
392 for( const kiapi::schematic::jobs::BOMField& field : aCtx.Request.fields().fields() )
393 {
394 bomJob.m_fieldsOrdered.emplace_back( wxString::FromUTF8( field.name() ) );
395 bomJob.m_fieldsLabels.emplace_back( wxString::FromUTF8( field.label() ) );
396
397 if( field.group_by() )
398 bomJob.m_fieldsGroupBy.emplace_back( wxString::FromUTF8( field.name() ) );
399 }
400
401 bomJob.m_excludeDNP = aCtx.Request.exclude_dnp();
402 bomJob.m_groupSymbols = aCtx.Request.group_symbols();
403
404 if( !aCtx.Request.variant_name().empty() )
405 bomJob.m_variantNames.emplace_back( wxString::FromUTF8( aCtx.Request.variant_name() ) );
406
407 return ExecuteSchematicJob( m_context->GetKiway(), bomJob );
408}
409
410
412 EDA_ITEM* aContainer )
413{
414 if( !aContainer )
415 {
416 ApiResponseStatus e;
417 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
418 e.set_error_message( "Tried to create an item in a null container" );
419 return tl::unexpected( e );
420 }
421
422 if( aType == SCH_PIN_T && !dynamic_cast<SCH_SYMBOL*>( aContainer ) )
423 {
424 ApiResponseStatus e;
425 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
426 e.set_error_message( fmt::format( "Tried to create a pin in {}, which is not a symbol",
427 aContainer->GetFriendlyName().ToStdString() ) );
428 return tl::unexpected( e );
429 }
430 else if( aType == SCH_SYMBOL_T && !dynamic_cast<SCHEMATIC*>( aContainer ) )
431 {
432 ApiResponseStatus e;
433 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
434 e.set_error_message( fmt::format( "Tried to create a symbol in {}, which is not a "
435 "schematic",
436 aContainer->GetFriendlyName().ToStdString() ) );
437 return tl::unexpected( e );
438 }
439
440 std::unique_ptr<EDA_ITEM> created = CreateItemForType( aType, aContainer );
441
442 if( !created )
443 {
444 ApiResponseStatus e;
445 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
446 e.set_error_message( fmt::format( "Tried to create an item of type {}, which is unhandled",
447 magic_enum::enum_name( aType ) ) );
448 return tl::unexpected( e );
449 }
450
451 return created;
452}
453
454
456 const std::string& aClientName,
457 const types::ItemHeader &aHeader,
458 const google::protobuf::RepeatedPtrField<google::protobuf::Any>& aItems,
459 std::function<void( ItemStatus, google::protobuf::Any )> aItemHandler )
460{
461 ApiResponseStatus e;
462
463 auto containerResult = validateItemHeaderDocument( aHeader );
464
465 if( !containerResult && containerResult.error().status() == ApiStatusCode::AS_UNHANDLED )
466 {
467 // No message needed for AS_UNHANDLED; this is an internal flag for the API server
468 e.set_status( ApiStatusCode::AS_UNHANDLED );
469 return tl::unexpected( e );
470 }
471 else if( !containerResult )
472 {
473 e.CopyFrom( containerResult.error() );
474 return tl::unexpected( e );
475 }
476
477 SCH_SCREEN* screen = m_context->GetSchematic()->RootScreen();
478 EE_RTREE& screenItems = screen->Items();
479
480 std::map<KIID, EDA_ITEM*> itemUuidMap;
481
482 std::for_each( screenItems.begin(), screenItems.end(),
483 [&]( EDA_ITEM* aItem )
484 {
485 itemUuidMap[aItem->m_Uuid] = aItem;
486 } );
487
488 EDA_ITEM* container = nullptr;
489
490 if( containerResult->has_value() )
491 {
492 const KIID& containerId = **containerResult;
493
494 if( itemUuidMap.count( containerId ) )
495 {
496 container = itemUuidMap.at( containerId );
497
498 if( !container )
499 {
500 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
501 e.set_error_message( fmt::format(
502 "The requested container {} is not a valid schematic item container",
503 containerId.AsStdString() ) );
504 return tl::unexpected( e );
505 }
506 }
507 else
508 {
509 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
510 e.set_error_message( fmt::format(
511 "The requested container {} does not exist in this document",
512 containerId.AsStdString() ) );
513 return tl::unexpected( e );
514 }
515 }
516
517 COMMIT* commit = getCurrentCommit( aClientName );
518
519 for( const google::protobuf::Any& anyItem : aItems )
520 {
521 ItemStatus status;
522 std::optional<KICAD_T> type = TypeNameFromAny( anyItem );
523
524 if( !type )
525 {
526 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
527 status.set_error_message( fmt::format( "Could not decode a valid type from {}",
528 anyItem.type_url() ) );
529 aItemHandler( status, anyItem );
530 continue;
531 }
532
534 createItemForType( *type, container );
535
536 if( !creationResult )
537 {
538 status.set_code( ItemStatusCode::ISC_INVALID_TYPE );
539 status.set_error_message( creationResult.error().error_message() );
540 aItemHandler( status, anyItem );
541 continue;
542 }
543
544 std::unique_ptr<EDA_ITEM> item( std::move( *creationResult ) );
545
546 if( !item->Deserialize( anyItem ) )
547 {
548 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
549 e.set_error_message( fmt::format( "could not unpack {} from request",
550 item->GetClass().ToStdString() ) );
551 return tl::unexpected( e );
552 }
553
554 if( aCreate && itemUuidMap.count( item->m_Uuid ) )
555 {
556 status.set_code( ItemStatusCode::ISC_EXISTING );
557 status.set_error_message( fmt::format( "an item with UUID {} already exists",
558 item->m_Uuid.AsStdString() ) );
559 aItemHandler( status, anyItem );
560 continue;
561 }
562 else if( !aCreate && !itemUuidMap.count( item->m_Uuid ) )
563 {
564 status.set_code( ItemStatusCode::ISC_NONEXISTENT );
565 status.set_error_message( fmt::format( "an item with UUID {} does not exist",
566 item->m_Uuid.AsStdString() ) );
567 aItemHandler( status, anyItem );
568 continue;
569 }
570
571 status.set_code( ItemStatusCode::ISC_OK );
572 google::protobuf::Any newItem;
573
574 if( aCreate )
575 {
576 item->Serialize( newItem );
577 commit->Add( item.release(), screen );
578
579 if( !m_activeClients.count( aClientName ) )
580 pushCurrentCommit( aClientName, _( "Added items via API" ) );
581 }
582 else
583 {
584 EDA_ITEM* edaItem = itemUuidMap[item->m_Uuid];
585
586 if( SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( edaItem ) )
587 {
588 schItem->SwapItemData( static_cast<SCH_ITEM*>( item.get() ) );
589 schItem->Serialize( newItem );
590 commit->Modify( schItem, screen );
591 }
592 else
593 {
594 wxASSERT( false );
595 }
596
597 if( !m_activeClients.count( aClientName ) )
598 pushCurrentCommit( aClientName, _( "Created items via API" ) );
599 }
600
601 aItemHandler( status, newItem );
602 }
603
604
605 return ItemRequestStatus::IRS_OK;
606}
607
608
609void API_HANDLER_SCH::deleteItemsInternal( std::map<KIID, ItemDeletionStatus>& aItemsToDelete,
610 const std::string& aClientName )
611{
612 // TODO
613}
614
615
616std::optional<EDA_ITEM*> API_HANDLER_SCH::getItemFromDocument( const DocumentSpecifier& aDocument,
617 const KIID& aId )
618{
619 if( !validateDocument( aDocument ) )
620 return std::nullopt;
621
622 // TODO
623
624 return std::nullopt;
625}
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:41
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
Definition api_handler.h:45
HANDLER_RESULT< types::RunJobResponse > ExecuteSchematicJob(KIWAY *aKiway, JOB &aJob)
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
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.
API_HANDLER_EDITOR(EDA_BASE_FRAME *aFrame=nullptr)
COMMIT * getCurrentCommit(const std::string &aClientName)
virtual void pushCurrentCommit(const std::string &aClientName, const wxString &aMessage)
std::set< std::string > m_activeClients
virtual std::optional< ApiResponseStatus > checkForBusy()
Checks if the editor can accept commands.
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportDxf(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportDxf > &aCtx)
SCH_EDIT_FRAME * m_frame
std::unique_ptr< COMMIT > createCommit() override
Override this to create an appropriate COMMIT subclass for the frame in question.
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportPdf(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportPdf > &aCtx)
std::shared_ptr< SCH_CONTEXT > m_context
std::optional< EDA_ITEM * > getItemFromDocument(const DocumentSpecifier &aDocument, const KIID &aId) override
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportSvg(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportSvg > &aCtx)
HANDLER_RESULT< std::unique_ptr< EDA_ITEM > > createItemForType(KICAD_T aType, EDA_ITEM *aContainer)
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportBOM(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportBOM > &aCtx)
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportPs(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportPs > &aCtx)
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)
HANDLER_RESULT< types::RunJobResponse > handleRunSchematicJobExportNetlist(const HANDLER_CONTEXT< kiapi::schematic::jobs::RunSchematicJobExportNetlist > &aCtx)
bool validateDocumentInternal(const DocumentSpecifier &aDocument) const override
void deleteItemsInternal(std::map< KIID, ItemDeletionStatus > &aItemsToDelete, const std::string &aClientName) override
void registerHandler(HANDLER_RESULT< ResponseType >(HandlerType::*aHandler)(const HANDLER_CONTEXT< RequestType > &))
Registers an API command handler for the given message types.
Definition api_handler.h:93
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition commit.h:72
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:106
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:78
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:100
virtual wxString GetFriendlyName() const
Definition eda_item.cpp:411
Implement an R-tree for fast spatial and type indexing of schematic items.
Definition sch_rtree.h:38
ee_rtree::Iterator begin() const
Return a read/write iterator that points to the first.
Definition sch_rtree.h:265
ee_rtree::Iterator end() const
Return a read/write iterator that points to one past the last element in the EE_RTREE.
Definition sch_rtree.h:273
std::vector< wxString > m_fieldsLabels
std::vector< wxString > m_fieldsOrdered
std::vector< wxString > m_fieldsGroupBy
std::vector< wxString > m_variantNames
std::vector< wxString > m_variantNames
An simple container class that lets us dispatch output jobs to kifaces.
Definition job.h:184
void SetConfiguredOutputPath(const wxString &aPath)
Sets the configured output path for the job, this path is always saved to file.
Definition job.cpp:157
const std::vector< JOB_OUTPUT > & GetOutputs()
Definition job.h:215
const std::string & GetType() const
Definition job.h:195
Definition kiid.h:48
std::string AsStdString() const
Definition kiid.cpp:250
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:315
int ProcessJob(KIWAY::FACE_T aFace, JOB *aJob, REPORTER *aReporter=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Definition kiway.cpp:748
@ FACE_SCH
eeschema DSO
Definition kiway.h:322
Holds all the data relating to one schematic.
Definition schematic.h:89
Schematic editor (Eeschema) main window.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:168
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:119
Schematic symbol object.
Definition sch_symbol.h:76
A wrapper for reporting to a wxString object.
Definition reporter.h:191
const wxString & GetMessages() const
Definition reporter.cpp:78
#define _(s)
KICOMMON_API std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
Definition api_utils.cpp:33
STL namespace.
std::shared_ptr< SCH_CONTEXT > CreateSchFrameContext(SCH_EDIT_FRAME *aFrame)
RequestMessageType Request
Definition api_handler.h:52
nlohmann::json output
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:75
@ SCH_SYMBOL_T
Definition typeinfo.h:173
@ SCH_PIN_T
Definition typeinfo.h:154