KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eeschema_jobs_handler.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) 2022 Mark Roszko <[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
22#include <common.h>
23#include <pgm_base.h>
24#include <cli/exit_codes.h>
25#include <sch_plotter.h>
32#include <jobs/job_sch_erc.h>
36#include <schematic.h>
37#include <schematic_settings.h>
38#include <sch_screen.h>
39#include <wx/dir.h>
40#include <wx/file.h>
41#include <memory>
42#include <connection_graph.h>
43#include "eeschema_helpers.h"
44#include <filename_resolver.h>
45#include <kiway.h>
46#include <sch_painter.h>
47#include <locale_io.h>
48#include <erc/erc.h>
49#include <erc/erc_report.h>
53#include <paths.h>
54#include <reporter.h>
55#include <string_utils.h>
56
58
59#include <sch_file_versions.h>
60#include <sch_io/sch_io.h>
62
63#include <netlist.h>
73
74#include <fields_data_model.h>
75
80#include <confirm.h>
81#include <project_sch.h>
82
84
85
87 JOB_DISPATCHER( aKiway ),
88 m_cliSchematic( nullptr )
89{
90 Register( "bom",
91 std::bind( &EESCHEMA_JOBS_HANDLER::JobExportBom, this, std::placeholders::_1 ),
92 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
93 {
94 JOB_EXPORT_SCH_BOM* bomJob = dynamic_cast<JOB_EXPORT_SCH_BOM*>( job );
95
96 SCH_EDIT_FRAME* editFrame =
97 static_cast<SCH_EDIT_FRAME*>( aKiway->Player( FRAME_SCH, false ) );
98
99 wxCHECK( bomJob && editFrame, false );
100
101 DIALOG_SYMBOL_FIELDS_TABLE dlg( editFrame, bomJob );
102 return dlg.ShowModal() == wxID_OK;
103 } );
104 Register( "pythonbom",
105 std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPythonBom, this, std::placeholders::_1 ),
106 []( JOB* job, wxWindow* aParent ) -> bool
107 {
108 return true;
109 } );
110 Register( "netlist",
111 std::bind( &EESCHEMA_JOBS_HANDLER::JobExportNetlist, this, std::placeholders::_1 ),
112 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
113 {
114 JOB_EXPORT_SCH_NETLIST* netJob = dynamic_cast<JOB_EXPORT_SCH_NETLIST*>( job );
115
116 SCH_EDIT_FRAME* editFrame =
117 static_cast<SCH_EDIT_FRAME*>( aKiway->Player( FRAME_SCH, false ) );
118
119 wxCHECK( netJob && editFrame, false );
120
121 DIALOG_EXPORT_NETLIST dlg( editFrame, aParent, netJob );
122 return dlg.ShowModal() == wxID_OK;
123 } );
124 Register( "plot",
125 std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPlot, this, std::placeholders::_1 ),
126 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
127 {
128 JOB_EXPORT_SCH_PLOT* plotJob = dynamic_cast<JOB_EXPORT_SCH_PLOT*>( job );
129
130 SCH_EDIT_FRAME* editFrame =
131 static_cast<SCH_EDIT_FRAME*>( aKiway->Player( FRAME_SCH, false ) );
132
133 wxCHECK( plotJob && editFrame, false );
134
135 if( plotJob->m_plotFormat == SCH_PLOT_FORMAT::HPGL )
136 {
137 DisplayErrorMessage( editFrame,
138 _( "Plotting to HPGL is no longer supported as of KiCad 10.0." ) );
139 return false;
140 }
141
142 DIALOG_PLOT_SCHEMATIC dlg( editFrame, aParent, plotJob );
143 return dlg.ShowModal() == wxID_OK;
144 } );
145 Register( "symupgrade",
146 std::bind( &EESCHEMA_JOBS_HANDLER::JobSymUpgrade, this, std::placeholders::_1 ),
147 []( JOB* job, wxWindow* aParent ) -> bool
148 {
149 return true;
150 } );
151 Register( "symsvg",
152 std::bind( &EESCHEMA_JOBS_HANDLER::JobSymExportSvg, this, std::placeholders::_1 ),
153 []( JOB* job, wxWindow* aParent ) -> bool
154 {
155 return true;
156 } );
157 Register( "erc", std::bind( &EESCHEMA_JOBS_HANDLER::JobSchErc, this, std::placeholders::_1 ),
158 []( JOB* job, wxWindow* aParent ) -> bool
159 {
160 JOB_SCH_ERC* ercJob = dynamic_cast<JOB_SCH_ERC*>( job );
161
162 wxCHECK( ercJob, false );
163
164 DIALOG_ERC_JOB_CONFIG dlg( aParent, ercJob );
165 return dlg.ShowModal() == wxID_OK;
166 } );
167 Register( "upgrade", std::bind( &EESCHEMA_JOBS_HANDLER::JobUpgrade, this, std::placeholders::_1 ),
168 []( JOB* job, wxWindow* aParent ) -> bool
169 {
170 return true;
171 } );
172}
173
174
176{
177 SCHEMATIC* sch = nullptr;
178
179 if( !Pgm().IsGUI() && Pgm().GetSettingsManager().IsProjectOpenNotDummy() )
180 {
182 wxString schPath = aPath;
183
184 if( schPath.IsEmpty() )
185 {
186 wxFileName path = project.GetProjectFullName();
188 path.MakeAbsolute();
189 schPath = path.GetFullPath();
190 }
191
192 if( !m_cliSchematic )
193 m_cliSchematic = EESCHEMA_HELPERS::LoadSchematic( schPath, true, false, &project );
194
195 sch = m_cliSchematic;
196 }
197 else if( Pgm().IsGUI() && Pgm().GetSettingsManager().IsProjectOpen() )
198 {
199 SCH_EDIT_FRAME* editFrame = static_cast<SCH_EDIT_FRAME*>( m_kiway->Player( FRAME_SCH, false ) );
200
201 if( editFrame )
202 sch = &editFrame->Schematic();
203 }
204 else if( !aPath.IsEmpty() )
205 {
206 sch = EESCHEMA_HELPERS::LoadSchematic( aPath, true, false );
207 }
208
209 if( !sch )
210 m_reporter->Report( _( "Failed to load schematic\n" ), RPT_SEVERITY_ERROR );
211
212 return sch;
213}
214
216 const wxString& aTheme, SCHEMATIC* aSch,
217 const wxString& aDrawingSheetOverride )
218{
219 COLOR_SETTINGS* cs = ::GetColorSettings( aTheme );
220 aRenderSettings->LoadColors( cs );
221 aRenderSettings->m_ShowHiddenPins = false;
222 aRenderSettings->m_ShowHiddenFields = false;
223 aRenderSettings->m_ShowPinAltIcons = false;
224
225 aRenderSettings->SetDefaultPenWidth( aSch->Settings().m_DefaultLineWidth );
226 aRenderSettings->m_LabelSizeRatio = aSch->Settings().m_LabelSizeRatio;
227 aRenderSettings->m_TextOffsetRatio = aSch->Settings().m_TextOffsetRatio;
228 aRenderSettings->m_PinSymbolSize = aSch->Settings().m_PinSymbolSize;
229
230 aRenderSettings->SetDashLengthRatio( aSch->Settings().m_DashedLineDashRatio );
231 aRenderSettings->SetGapLengthRatio( aSch->Settings().m_DashedLineGapRatio );
232
233 // Load the drawing sheet from the filename stored in BASE_SCREEN::m_DrawingSheetFileName.
234 // If empty, or not existing, the default drawing sheet is loaded.
235
236 auto loadSheet =
237 [&]( const wxString& path ) -> bool
238 {
239 wxString msg;
240 FILENAME_RESOLVER resolve;
241 resolve.SetProject( &aSch->Project() );
242 resolve.SetProgramBase( &Pgm() );
243
244 wxString absolutePath = resolve.ResolvePath( path, wxGetCwd(),
245 { aSch->GetEmbeddedFiles() } );
246
247 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( absolutePath, &msg ) )
248 {
249 m_reporter->Report( wxString::Format( _( "Error loading drawing sheet '%s'." ), path )
250 + wxS( "\n" ) + msg + wxS( "\n" ),
252 return false;
253 }
254
255 return true;
256 };
257
258 // try to load the override first
259 if( !aDrawingSheetOverride.IsEmpty() && loadSheet( aDrawingSheetOverride ) )
260 return;
261
262 // no override or failed override continues here
263 loadSheet( aSch->Settings().m_SchDrawingSheetFileName );
264}
265
266
268{
269 JOB_EXPORT_SCH_PLOT* aPlotJob = dynamic_cast<JOB_EXPORT_SCH_PLOT*>( aJob );
270
271 wxCHECK( aPlotJob, CLI::EXIT_CODES::ERR_UNKNOWN );
272
273 if( aPlotJob->m_plotFormat == SCH_PLOT_FORMAT::HPGL )
274 {
275 m_reporter->Report( _( "Plotting to HPGL is no longer supported as of KiCad 10.0.\n" ),
278 }
279
280 SCHEMATIC* sch = getSchematic( aPlotJob->m_filename );
281
282 if( !sch )
284
285 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
286 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
287
288 // Apply variant if specified
289 if( !aPlotJob->m_variantNames.empty() )
290 {
291 // For plot export, we use the first variant name from the set
292 wxString variantName = *aPlotJob->m_variantNames.begin();
293
294 if( variantName != wxS( "all" ) )
295 sch->SetCurrentVariant( variantName );
296 }
297
298 std::unique_ptr<SCH_RENDER_SETTINGS> renderSettings = std::make_unique<SCH_RENDER_SETTINGS>();
299 InitRenderSettings( renderSettings.get(), aPlotJob->m_theme, sch, aPlotJob->m_drawingSheet );
300
301 wxString font = aPlotJob->m_defaultFont;
302
303 if( font.IsEmpty() )
304 {
306 font = cfg ? cfg->m_Appearance.default_font : wxString( KICAD_FONT_NAME );
307 }
308
309 renderSettings->SetDefaultFont( font );
310 renderSettings->SetMinPenWidth( aPlotJob->m_minPenWidth );
311
312 // Clear cached bounding boxes for all text items so they're recomputed with the correct
313 // default font. This is necessary because text bounding boxes may have been cached during
314 // schematic loading before the render settings (and thus default font) were configured.
315 SCH_SCREENS screens( sch->Root() );
316
317 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
318 {
319 for( SCH_ITEM* item : screen->Items() )
320 item->ClearCaches();
321
322 for( const auto& [libItemName, libSymbol] : screen->GetLibSymbols() )
323 libSymbol->ClearCaches();
324 }
325
326 std::unique_ptr<SCH_PLOTTER> schPlotter = std::make_unique<SCH_PLOTTER>( sch );
327
329
330 switch( aPlotJob->m_plotFormat )
331 {
332 case SCH_PLOT_FORMAT::DXF: format = PLOT_FORMAT::DXF; break;
333 case SCH_PLOT_FORMAT::PDF: format = PLOT_FORMAT::PDF; break;
334 case SCH_PLOT_FORMAT::SVG: format = PLOT_FORMAT::SVG; break;
335 case SCH_PLOT_FORMAT::POST: format = PLOT_FORMAT::POST; break;
336 case SCH_PLOT_FORMAT::HPGL: /* no longer supported */ break;
337 }
338
339 int pageSizeSelect = PageFormatReq::PAGE_SIZE_AUTO;
340
341 switch( aPlotJob->m_pageSizeSelect )
342 {
343 case JOB_PAGE_SIZE::PAGE_SIZE_A: pageSizeSelect = PageFormatReq::PAGE_SIZE_A; break;
344 case JOB_PAGE_SIZE::PAGE_SIZE_A4: pageSizeSelect = PageFormatReq::PAGE_SIZE_A4; break;
346 }
347
348 wxString outPath = aPlotJob->GetFullOutputPath( &sch->Project() );
349
350 if( !PATHS::EnsurePathExists( outPath, !aPlotJob->GetOutputPathIsDirectory() ) )
351 {
352 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
354 }
355
356 SCH_PLOT_OPTS plotOpts;
357 plotOpts.m_blackAndWhite = aPlotJob->m_blackAndWhite;
358 plotOpts.m_PDFPropertyPopups = aPlotJob->m_PDFPropertyPopups;
360 plotOpts.m_PDFMetadata = aPlotJob->m_PDFMetadata;
361
362 if( aPlotJob->GetOutputPathIsDirectory() )
363 {
364 plotOpts.m_outputDirectory = outPath;
365 plotOpts.m_outputFile = wxEmptyString;
366 }
367 else
368 {
369 plotOpts.m_outputDirectory = wxEmptyString;
370 plotOpts.m_outputFile = outPath;
371 }
372
373 plotOpts.m_pageSizeSelect = pageSizeSelect;
374 plotOpts.m_plotAll = aPlotJob->m_plotAll;
375 plotOpts.m_plotDrawingSheet = aPlotJob->m_plotDrawingSheet;
376 plotOpts.m_plotPages = aPlotJob->m_plotPages;
377 plotOpts.m_theme = aPlotJob->m_theme;
378 plotOpts.m_useBackgroundColor = aPlotJob->m_useBackgroundColor;
379 plotOpts.m_plotHopOver = aPlotJob->m_show_hop_over;
380
381 // Use variant from m_variantNames if specified, otherwise use the schematic's current variant
382 if( !aPlotJob->m_variantNames.empty() )
383 plotOpts.m_variant = aPlotJob->m_variantNames.front();
384
385 // Always export dxf in mm by kicad-cli (similar to Pcbnew)
387
388 schPlotter->Plot( format, plotOpts, renderSettings.get(), m_reporter );
389
390 if( m_reporter->HasMessageOfSeverity( RPT_SEVERITY_ERROR ) )
392
393 return CLI::EXIT_CODES::OK;
394}
395
396
398{
399 JOB_EXPORT_SCH_NETLIST* aNetJob = dynamic_cast<JOB_EXPORT_SCH_NETLIST*>( aJob );
400
401 wxCHECK( aNetJob, CLI::EXIT_CODES::ERR_UNKNOWN );
402
403 SCHEMATIC* sch = getSchematic( aNetJob->m_filename );
404
405 if( !sch )
407
408 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
409 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
410
411 // Apply variant if specified
412 if( !aNetJob->m_variantNames.empty() )
413 {
414 // For netlist export, we use the first variant name from the set
415 wxString variantName = *aNetJob->m_variantNames.begin();
416
417 if( variantName != wxS( "all" ) )
418 sch->SetCurrentVariant( variantName );
419 }
420
421 // Annotation warning check
422 SCH_REFERENCE_LIST referenceList;
423 sch->Hierarchy().GetSymbols( referenceList );
424
425 if( referenceList.GetCount() > 0 )
426 {
427 if( referenceList.CheckAnnotation(
428 []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
429 {
430 // We're only interested in the end result -- either errors or not
431 } )
432 > 0 )
433 {
434 m_reporter->Report( _( "Warning: schematic has annotation errors, please use the "
435 "schematic editor to fix them\n" ),
437 }
438 }
439
440 // Test duplicate sheet names:
441 ERC_TESTER erc( sch );
442
443 if( erc.TestDuplicateSheetNames( false ) > 0 )
444 m_reporter->Report( _( "Warning: duplicate sheet names.\n" ), RPT_SEVERITY_WARNING );
445
446 std::unique_ptr<NETLIST_EXPORTER_BASE> helper;
447 unsigned netlistOption = 0;
448
449 wxString fileExt;
450
451 switch( aNetJob->format )
452 {
455 helper = std::make_unique<NETLIST_EXPORTER_KICAD>( sch );
456 break;
457
460 helper = std::make_unique<NETLIST_EXPORTER_ORCADPCB2>( sch );
461 break;
462
465 helper = std::make_unique<NETLIST_EXPORTER_CADSTAR>( sch );
466 break;
467
471 helper = std::make_unique<NETLIST_EXPORTER_SPICE>( sch );
472 break;
473
476 helper = std::make_unique<NETLIST_EXPORTER_SPICE_MODEL>( sch );
477 break;
478
480 fileExt = wxS( "xml" );
481 helper = std::make_unique<NETLIST_EXPORTER_XML>( sch );
482 break;
483
485 fileExt = wxS( "asc" );
486 helper = std::make_unique<NETLIST_EXPORTER_PADS>( sch );
487 break;
488
490 fileExt = wxS( "txt" );
491 helper = std::make_unique<NETLIST_EXPORTER_ALLEGRO>( sch );
492 break;
493
494 default:
495 m_reporter->Report( _( "Unknown netlist format.\n" ), RPT_SEVERITY_ERROR );
497 }
498
499 if( aNetJob->GetConfiguredOutputPath().IsEmpty() )
500 {
501 wxFileName fn = sch->GetFileName();
502 fn.SetName( fn.GetName() );
503 fn.SetExt( fileExt );
504
505 aNetJob->SetConfiguredOutputPath( fn.GetFullName() );
506 }
507
508 wxString outPath = aNetJob->GetFullOutputPath( &sch->Project() );
509
510 if( !PATHS::EnsurePathExists( outPath, true ) )
511 {
512 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
514 }
515
516 bool res = helper->WriteNetlist( outPath, netlistOption, *m_reporter );
517
518 if( !res )
520
521 return CLI::EXIT_CODES::OK;
522}
523
524
526{
527 JOB_EXPORT_SCH_BOM* aBomJob = dynamic_cast<JOB_EXPORT_SCH_BOM*>( aJob );
528
529 wxCHECK( aBomJob, CLI::EXIT_CODES::ERR_UNKNOWN );
530
531 SCHEMATIC* sch = getSchematic( aBomJob->m_filename );
532
533 if( !sch )
535
536 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
537 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
538
539 wxString currentVariant;
540
541 if( !aBomJob->m_variantNames.empty() )
542 {
543 currentVariant = aBomJob->m_variantNames.front();
544
545 if( currentVariant != wxS( "all" ) )
546 sch->SetCurrentVariant( currentVariant );
547 }
548
549 // Annotation warning check
550 SCH_REFERENCE_LIST referenceList;
551 sch->Hierarchy().GetSymbols( referenceList, false, false );
552
553 if( referenceList.GetCount() > 0 )
554 {
555 SCH_REFERENCE_LIST copy = referenceList;
556
557 // Check annotation splits references...
558 if( copy.CheckAnnotation(
559 []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
560 {
561 // We're only interested in the end result -- either errors or not
562 } )
563 > 0 )
564 {
565 m_reporter->Report(
566 _( "Warning: schematic has annotation errors, please use the schematic "
567 "editor to fix them\n" ),
569 }
570 }
571
572 // Test duplicate sheet names:
573 ERC_TESTER erc( sch );
574
575 if( erc.TestDuplicateSheetNames( false ) > 0 )
576 m_reporter->Report( _( "Warning: duplicate sheet names.\n" ), RPT_SEVERITY_WARNING );
577
578 // Build our data model
579 FIELDS_EDITOR_GRID_DATA_MODEL dataModel( referenceList, nullptr );
580
581 // Mandatory fields first
582 for( FIELD_T fieldId : MANDATORY_FIELDS )
583 {
584 dataModel.AddColumn( GetCanonicalFieldName( fieldId ),
585 GetDefaultFieldName( fieldId, DO_TRANSLATE ), false, currentVariant );
586 }
587
588 // Generated/virtual fields (e.g. ${QUANTITY}, ${ITEM_NUMBER}) present only in the fields table
591 false, currentVariant );
594 false, currentVariant );
595
596 // Attribute fields (boolean flags on symbols)
597 dataModel.AddColumn( wxS( "${DNP}" ), GetGeneratedFieldDisplayName( wxS( "${DNP}" ) ),
598 false, currentVariant );
599 dataModel.AddColumn( wxS( "${EXCLUDE_FROM_BOM}" ), GetGeneratedFieldDisplayName( wxS( "${EXCLUDE_FROM_BOM}" ) ),
600 false, currentVariant );
601 dataModel.AddColumn( wxS( "${EXCLUDE_FROM_BOARD}" ), GetGeneratedFieldDisplayName( wxS( "${EXCLUDE_FROM_BOARD}" ) ),
602 false, currentVariant );
603 dataModel.AddColumn( wxS( "${EXCLUDE_FROM_SIM}" ), GetGeneratedFieldDisplayName( wxS( "${EXCLUDE_FROM_SIM}" ) ),
604 false, currentVariant );
605
606 // User field names in symbols second
607 std::set<wxString> userFieldNames;
608
609 for( size_t i = 0; i < referenceList.GetCount(); ++i )
610 {
611 SCH_SYMBOL* symbol = referenceList[i].GetSymbol();
612
613 for( SCH_FIELD& field : symbol->GetFields() )
614 {
615 if( !field.IsMandatory() && !field.IsPrivate() )
616 userFieldNames.insert( field.GetName() );
617 }
618 }
619
620 for( const wxString& fieldName : userFieldNames )
621 dataModel.AddColumn( fieldName, GetGeneratedFieldDisplayName( fieldName ), true, currentVariant );
622
623 // Add any templateFieldNames which aren't already present in the userFieldNames
624 for( const TEMPLATE_FIELDNAME& templateFieldname :
626 {
627 if( userFieldNames.count( templateFieldname.m_Name ) == 0 )
628 {
629 dataModel.AddColumn( templateFieldname.m_Name, GetGeneratedFieldDisplayName( templateFieldname.m_Name ),
630 false, currentVariant );
631 }
632 }
633
634 BOM_PRESET preset;
635
636 // Load a preset if one is specified
637 if( !aBomJob->m_bomPresetName.IsEmpty() )
638 {
639 // Find the preset
640 const BOM_PRESET* schPreset = nullptr;
641
642 for( const BOM_PRESET& p : BOM_PRESET::BuiltInPresets() )
643 {
644 if( p.name == aBomJob->m_bomPresetName )
645 {
646 schPreset = &p;
647 break;
648 }
649 }
650
651 for( const BOM_PRESET& p : sch->Settings().m_BomPresets )
652 {
653 if( p.name == aBomJob->m_bomPresetName )
654 {
655 schPreset = &p;
656 break;
657 }
658 }
659
660 if( !schPreset )
661 {
662 m_reporter->Report( wxString::Format( _( "BOM preset '%s' not found" ) + wxS( "\n" ),
663 aBomJob->m_bomPresetName ),
665
667 }
668
669 preset = *schPreset;
670 }
671 else
672 {
673 size_t i = 0;
674
675 for( const wxString& fieldName : aBomJob->m_fieldsOrdered )
676 {
677 // Handle wildcard. We allow the wildcard anywhere in the list, but it needs to respect
678 // fields that come before and after the wildcard.
679 if( fieldName == wxS( "*" ) )
680 {
681 for( const BOM_FIELD& modelField : dataModel.GetFieldsOrdered() )
682 {
683 struct BOM_FIELD field;
684
685 field.name = modelField.name;
686 field.show = true;
687 field.groupBy = false;
688 field.label = field.name;
689
690 bool fieldAlreadyPresent = false;
691
692 for( BOM_FIELD& presetField : preset.fieldsOrdered )
693 {
694 if( presetField.name == field.name )
695 {
696 fieldAlreadyPresent = true;
697 break;
698 }
699 }
700
701 bool fieldLaterInList = false;
702
703 for( const wxString& fieldInList : aBomJob->m_fieldsOrdered )
704 {
705 if( fieldInList == field.name )
706 {
707 fieldLaterInList = true;
708 break;
709 }
710 }
711
712 if( !fieldAlreadyPresent && !fieldLaterInList )
713 preset.fieldsOrdered.emplace_back( field );
714 }
715
716 continue;
717 }
718
719 struct BOM_FIELD field;
720
721 field.name = fieldName;
722 field.show = !fieldName.StartsWith( wxT( "__" ), &field.name );
723 field.groupBy = alg::contains( aBomJob->m_fieldsGroupBy, field.name );
724
725 if( ( aBomJob->m_fieldsLabels.size() > i ) && !aBomJob->m_fieldsLabels[i].IsEmpty() )
726 field.label = aBomJob->m_fieldsLabels[i];
727 else if( IsGeneratedField( field.name ) )
728 field.label = GetGeneratedFieldDisplayName( field.name );
729 else
730 field.label = field.name;
731
732 preset.fieldsOrdered.emplace_back( field );
733 i++;
734 }
735
736 preset.sortAsc = aBomJob->m_sortAsc;
737 preset.sortField = aBomJob->m_sortField;
738 preset.filterString = aBomJob->m_filterString;
739 preset.groupSymbols = aBomJob->m_groupSymbols;
740 preset.excludeDNP = aBomJob->m_excludeDNP;
741 }
742
743 BOM_FMT_PRESET fmt;
744
745 // Load a format preset if one is specified
746 if( !aBomJob->m_bomFmtPresetName.IsEmpty() )
747 {
748 std::optional<BOM_FMT_PRESET> schFmtPreset;
749
751 {
752 if( p.name == aBomJob->m_bomFmtPresetName )
753 {
754 schFmtPreset = p;
755 break;
756 }
757 }
758
759 for( const BOM_FMT_PRESET& p : sch->Settings().m_BomFmtPresets )
760 {
761 if( p.name == aBomJob->m_bomFmtPresetName )
762 {
763 schFmtPreset = p;
764 break;
765 }
766 }
767
768 if( !schFmtPreset )
769 {
770 m_reporter->Report( wxString::Format( _( "BOM format preset '%s' not found" ) + wxS( "\n" ),
771 aBomJob->m_bomFmtPresetName ),
773
775 }
776
777 fmt = *schFmtPreset;
778 }
779 else
780 {
781 fmt.fieldDelimiter = aBomJob->m_fieldDelimiter;
782 fmt.stringDelimiter = aBomJob->m_stringDelimiter;
783 fmt.refDelimiter = aBomJob->m_refDelimiter;
785 fmt.keepTabs = aBomJob->m_keepTabs;
786 fmt.keepLineBreaks = aBomJob->m_keepLineBreaks;
787 }
788
789 if( aBomJob->GetConfiguredOutputPath().IsEmpty() )
790 {
791 wxFileName fn = sch->GetFileName();
792 fn.SetName( fn.GetName() );
793 fn.SetExt( FILEEXT::CsvFileExtension );
794
795 aBomJob->SetConfiguredOutputPath( fn.GetFullName() );
796 }
797
798 wxString configuredPath = aBomJob->GetConfiguredOutputPath();
799 bool hasVariantPlaceholder = configuredPath.Contains( wxS( "${VARIANT}" ) );
800
801 // Determine which variants to process
802 std::vector<wxString> variantsToProcess;
803
804 if( aBomJob->m_variantNames.size() > 1 && hasVariantPlaceholder )
805 {
806 variantsToProcess = aBomJob->m_variantNames;
807 }
808 else
809 {
810 variantsToProcess.push_back( currentVariant );
811 }
812
813 for( const wxString& variantName : variantsToProcess )
814 {
815 std::vector<wxString> singleVariant = { variantName };
816 dataModel.SetVariantNames( singleVariant );
817 dataModel.SetCurrentVariant( variantName );
818 dataModel.ApplyBomPreset( preset, variantName );
819
820 wxString outPath;
821
822 if( hasVariantPlaceholder )
823 {
824 wxString variantPath = configuredPath;
825 variantPath.Replace( wxS( "${VARIANT}" ), variantName );
826 aBomJob->SetConfiguredOutputPath( variantPath );
827 outPath = aBomJob->GetFullOutputPath( &sch->Project() );
828 aBomJob->SetConfiguredOutputPath( configuredPath );
829 }
830 else
831 {
832 outPath = aBomJob->GetFullOutputPath( &sch->Project() );
833 }
834
835 if( !PATHS::EnsurePathExists( outPath, true ) )
836 {
837 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
839 }
840
841 wxFile f;
842
843 if( !f.Open( outPath, wxFile::write ) )
844 {
845 m_reporter->Report( wxString::Format( _( "Unable to open destination '%s'" ), outPath ),
847
849 }
850
851 bool res = f.Write( dataModel.Export( fmt ) );
852
853 if( !res )
855
856 m_reporter->Report( wxString::Format( _( "Wrote bill of materials to '%s'." ), outPath ),
858 }
859
860 return CLI::EXIT_CODES::OK;
861}
862
863
865{
866 JOB_EXPORT_SCH_PYTHONBOM* aNetJob = dynamic_cast<JOB_EXPORT_SCH_PYTHONBOM*>( aJob );
867
868 wxCHECK( aNetJob, CLI::EXIT_CODES::ERR_UNKNOWN );
869
870 SCHEMATIC* sch = getSchematic( aNetJob->m_filename );
871
872 if( !sch )
874
875 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
876 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
877
878 // Annotation warning check
879 SCH_REFERENCE_LIST referenceList;
880 sch->Hierarchy().GetSymbols( referenceList );
881
882 if( referenceList.GetCount() > 0 )
883 {
884 if( referenceList.CheckAnnotation(
885 []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
886 {
887 // We're only interested in the end result -- either errors or not
888 } )
889 > 0 )
890 {
891 m_reporter->Report( _( "Warning: schematic has annotation errors, please use the "
892 "schematic editor to fix them\n" ),
894 }
895 }
896
897 // Test duplicate sheet names:
898 ERC_TESTER erc( sch );
899
900 if( erc.TestDuplicateSheetNames( false ) > 0 )
901 m_reporter->Report( _( "Warning: duplicate sheet names.\n" ), RPT_SEVERITY_WARNING );
902
903 std::unique_ptr<NETLIST_EXPORTER_XML> xmlNetlist =
904 std::make_unique<NETLIST_EXPORTER_XML>( sch );
905
906 if( aNetJob->GetConfiguredOutputPath().IsEmpty() )
907 {
908 wxFileName fn = sch->GetFileName();
909 fn.SetName( fn.GetName() + "-bom" );
910 fn.SetExt( FILEEXT::XmlFileExtension );
911
912 aNetJob->SetConfiguredOutputPath( fn.GetFullName() );
913 }
914
915 wxString outPath = aNetJob->GetFullOutputPath( &sch->Project() );
916
917 if( !PATHS::EnsurePathExists( outPath, true ) )
918 {
919 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
921 }
922
923 bool res = xmlNetlist->WriteNetlist( outPath, GNL_OPT_BOM, *m_reporter );
924
925 if( !res )
927
928 m_reporter->Report( wxString::Format( _( "Wrote bill of materials to '%s'." ), outPath ),
930
931 return CLI::EXIT_CODES::OK;
932}
933
934
936 LIB_SYMBOL* symbol )
937{
938 wxCHECK( symbol, CLI::EXIT_CODES::ERR_UNKNOWN );
939
940 std::shared_ptr<LIB_SYMBOL> parent;
941 LIB_SYMBOL* symbolToPlot = symbol;
942
943 // if the symbol is an alias, then the draw items are stored in the root symbol
944 if( symbol->IsDerived() )
945 {
946 parent = symbol->GetRootSymbol();
947
948 wxCHECK( parent, CLI::EXIT_CODES::ERR_UNKNOWN );
949
950 symbolToPlot = parent.get();
951 }
952
953 // iterate from unit 1, unit 0 would be "all units" which we don't want
954 for( int unit = 1; unit < symbol->GetUnitCount() + 1; unit++ )
955 {
956 for( int bodyStyle = 1; bodyStyle <= symbol->GetBodyStyleCount(); ++bodyStyle )
957 {
958 wxString filename;
959 wxFileName fn;
960
961 fn.SetPath( aSvgJob->m_outputDirectory );
962 fn.SetExt( FILEEXT::SVGFileExtension );
963
964 filename = symbol->GetName();
965
966 for( wxChar c : wxFileName::GetForbiddenChars( wxPATH_DOS ) )
967 filename.Replace( c, ' ' );
968
969 // Even single units get a unit number in the filename. This simplifies the
970 // handling of the files as they have a uniform pattern.
971 // Also avoids aliasing 'sym', unit 2 and 'sym_unit2', unit 1 to the same file.
972 filename += wxString::Format( "_unit%d", unit );
973
974 if( symbol->HasDeMorganBodyStyles() )
975 {
976 if( bodyStyle == 2 )
977 filename += wxS( "_demorgan" );
978 }
979 else if( bodyStyle <= (int) symbol->GetBodyStyleNames().size() )
980 {
981 filename += wxS( "_" ) + symbol->GetBodyStyleNames()[bodyStyle-1].Lower();
982 }
983
984 fn.SetName( filename );
985 m_reporter->Report( wxString::Format( _( "Plotting symbol '%s' unit %d to '%s'\n" ),
986 symbol->GetName(),
987 unit,
988 fn.GetFullPath() ),
990
991 // Get the symbol bounding box to fit the plot page to it
992 BOX2I symbolBB = symbol->Flatten()->GetUnitBoundingBox( unit, bodyStyle,
993 !aSvgJob->m_includeHiddenFields );
995 pageInfo.SetHeightMils( schIUScale.IUToMils( symbolBB.GetHeight() * 1.2 ) );
996 pageInfo.SetWidthMils( schIUScale.IUToMils( symbolBB.GetWidth() * 1.2 ) );
997
998 SVG_PLOTTER* plotter = new SVG_PLOTTER();
999 plotter->SetRenderSettings( aRenderSettings );
1000 plotter->SetPageSettings( pageInfo );
1001 plotter->SetColorMode( !aSvgJob->m_blackAndWhite );
1002
1003 VECTOR2I plot_offset = symbolBB.GetCenter();
1004 const double scale = 1.0;
1005
1006 // Currently, plot units are in decimal
1007 plotter->SetViewport( plot_offset, schIUScale.IU_PER_MILS / 10, scale, false );
1008
1009 plotter->SetCreator( wxT( "Eeschema-SVG" ) );
1010
1011 if( !plotter->OpenFile( fn.GetFullPath() ) )
1012 {
1013 m_reporter->Report( wxString::Format( _( "Unable to open destination '%s'" ) + wxS( "\n" ),
1014 fn.GetFullPath() ),
1016
1017 delete plotter;
1019 }
1020
1021 LOCALE_IO toggle;
1022 SCH_PLOT_OPTS plotOpts;
1023
1024 plotter->StartPlot( wxT( "1" ) );
1025
1026 bool background = true;
1027 VECTOR2I offset( pageInfo.GetWidthIU( schIUScale.IU_PER_MILS ) / 2,
1028 pageInfo.GetHeightIU( schIUScale.IU_PER_MILS ) / 2 );
1029
1030 // note, we want the fields from the original symbol pointer (in case of non-alias)
1031 symbolToPlot->Plot( plotter, background, plotOpts, unit, bodyStyle, offset, false );
1032 symbol->PlotFields( plotter, background, plotOpts, unit, bodyStyle, offset, false );
1033
1034 symbolToPlot->Plot( plotter, !background, plotOpts, unit, bodyStyle, offset, false );
1035 symbol->PlotFields( plotter, !background, plotOpts, unit, bodyStyle, offset, false );
1036
1037 plotter->EndPlot();
1038 delete plotter;
1039 }
1040 }
1041
1042 if( m_reporter->HasMessageOfSeverity( RPT_SEVERITY_ERROR ) )
1044
1045 return CLI::EXIT_CODES::OK;
1046}
1047
1048
1050{
1051 JOB_SYM_EXPORT_SVG* svgJob = dynamic_cast<JOB_SYM_EXPORT_SVG*>( aJob );
1052
1053 wxCHECK( svgJob, CLI::EXIT_CODES::ERR_UNKNOWN );
1054
1055 wxFileName fn( svgJob->m_libraryPath );
1056 fn.MakeAbsolute();
1057
1058 SCH_IO_KICAD_SEXPR_LIB_CACHE schLibrary( fn.GetFullPath() );
1059
1060 try
1061 {
1062 schLibrary.Load();
1063 }
1064 catch( ... )
1065 {
1066 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1068 }
1069
1070 if( m_progressReporter )
1071 m_progressReporter->KeepRefreshing();
1072
1073 LIB_SYMBOL* symbol = nullptr;
1074
1075 if( !svgJob->m_symbol.IsEmpty() )
1076 {
1077 // See if the selected symbol exists
1078 symbol = schLibrary.GetSymbol( svgJob->m_symbol );
1079
1080 if( !symbol )
1081 {
1082 m_reporter->Report( _( "There is no symbol selected to save." ) + wxS( "\n" ),
1085 }
1086 }
1087
1088 if( !svgJob->m_outputDirectory.IsEmpty() && !wxDir::Exists( svgJob->m_outputDirectory ) )
1089 {
1090 if( !wxFileName::Mkdir( svgJob->m_outputDirectory ) )
1091 {
1092 m_reporter->Report( wxString::Format( _( "Unable to create output directory '%s'." ) + wxS( "\n" ),
1093 svgJob->m_outputDirectory ),
1096 }
1097 }
1098
1099 SCH_RENDER_SETTINGS renderSettings;
1101 renderSettings.LoadColors( cs );
1102 renderSettings.SetDefaultPenWidth( DEFAULT_LINE_WIDTH_MILS * schIUScale.IU_PER_MILS );
1103 renderSettings.m_ShowHiddenPins = svgJob->m_includeHiddenPins;
1104 renderSettings.m_ShowHiddenFields = svgJob->m_includeHiddenFields;
1105
1106 int exitCode = CLI::EXIT_CODES::OK;
1107
1108 if( symbol )
1109 {
1110 exitCode = doSymExportSvg( svgJob, &renderSettings, symbol );
1111 }
1112 else
1113 {
1114 // Just plot all the symbols we can
1115 const LIB_SYMBOL_MAP& libSymMap = schLibrary.GetSymbolMap();
1116
1117 for( const auto& [name, libSymbol] : libSymMap )
1118 {
1119 if( m_progressReporter )
1120 {
1121 m_progressReporter->AdvancePhase( wxString::Format( _( "Exporting %s" ), name ) );
1122 m_progressReporter->KeepRefreshing();
1123 }
1124
1125 exitCode = doSymExportSvg( svgJob, &renderSettings, libSymbol );
1126
1127 if( exitCode != CLI::EXIT_CODES::OK )
1128 break;
1129 }
1130 }
1131
1132 return exitCode;
1133}
1134
1135
1137{
1138 JOB_SYM_UPGRADE* upgradeJob = dynamic_cast<JOB_SYM_UPGRADE*>( aJob );
1139
1140 wxCHECK( upgradeJob, CLI::EXIT_CODES::ERR_UNKNOWN );
1141
1142 wxFileName fn( upgradeJob->m_libraryPath );
1143 fn.MakeAbsolute();
1144
1145 SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
1146
1147 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1148 {
1149 if( wxFile::Exists( upgradeJob->m_outputLibraryPath ) )
1150 {
1151 m_reporter->Report( _( "Output path must not conflict with existing path\n" ),
1153
1155 }
1156 }
1157 else if( fileType != SCH_IO_MGR::SCH_KICAD )
1158 {
1159 m_reporter->Report( _( "Output path must be specified to convert legacy and non-KiCad libraries\n" ),
1161
1163 }
1164
1165 if( fileType == SCH_IO_MGR::SCH_KICAD )
1166 {
1167 SCH_IO_KICAD_SEXPR_LIB_CACHE schLibrary( fn.GetFullPath() );
1168
1169 try
1170 {
1171 schLibrary.Load();
1172 }
1173 catch( ... )
1174 {
1175 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1177 }
1178
1179 if( m_progressReporter )
1180 m_progressReporter->KeepRefreshing();
1181
1182 bool shouldSave =
1184
1185 if( shouldSave )
1186 {
1187 m_reporter->Report( _( "Saving symbol library in updated format\n" ), RPT_SEVERITY_ACTION );
1188
1189 try
1190 {
1191 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1192 schLibrary.SetFileName( upgradeJob->m_outputLibraryPath );
1193
1194 schLibrary.SetModified();
1195 schLibrary.Save();
1196 }
1197 catch( ... )
1198 {
1199 m_reporter->Report( ( "Unable to save library\n" ), RPT_SEVERITY_ERROR );
1201 }
1202 }
1203 else
1204 {
1205 m_reporter->Report( _( "Symbol library was not updated\n" ), RPT_SEVERITY_ERROR );
1206 }
1207 }
1208 else
1209 {
1210 if( !SCH_IO_MGR::ConvertLibrary( nullptr, fn.GetAbsolutePath(), upgradeJob->m_outputLibraryPath ) )
1211 {
1212 m_reporter->Report( ( "Unable to convert library\n" ), RPT_SEVERITY_ERROR );
1214 }
1215 }
1216
1217 return CLI::EXIT_CODES::OK;
1218}
1219
1220
1221
1223{
1224 JOB_SCH_ERC* ercJob = dynamic_cast<JOB_SCH_ERC*>( aJob );
1225
1226 wxCHECK( ercJob, CLI::EXIT_CODES::ERR_UNKNOWN );
1227
1228 SCHEMATIC* sch = getSchematic( ercJob->m_filename );
1229
1230 if( !sch )
1232
1233 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
1234 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
1235
1236 if( ercJob->GetConfiguredOutputPath().IsEmpty() )
1237 {
1238 wxFileName fn = sch->GetFileName();
1239 fn.SetName( fn.GetName() + wxS( "-erc" ) );
1240
1242 fn.SetExt( FILEEXT::JsonFileExtension );
1243 else
1244 fn.SetExt( FILEEXT::ReportFileExtension );
1245
1246 ercJob->SetConfiguredOutputPath( fn.GetFullName() );
1247 }
1248
1249 wxString outPath = ercJob->GetFullOutputPath( &sch->Project() );
1250
1251 if( !PATHS::EnsurePathExists( outPath, true ) )
1252 {
1253 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
1255 }
1256
1257 EDA_UNITS units;
1258
1259 switch( ercJob->m_units )
1260 {
1261 case JOB_SCH_ERC::UNITS::INCH: units = EDA_UNITS::INCH; break;
1262 case JOB_SCH_ERC::UNITS::MILS: units = EDA_UNITS::MILS; break;
1263 case JOB_SCH_ERC::UNITS::MM: units = EDA_UNITS::MM; break;
1264 default: units = EDA_UNITS::MM; break;
1265 }
1266
1267 std::shared_ptr<SHEETLIST_ERC_ITEMS_PROVIDER> markersProvider =
1268 std::make_shared<SHEETLIST_ERC_ITEMS_PROVIDER>( sch );
1269
1270 // Running ERC requires libraries be loaded, so make sure they have been
1272 adapter->AsyncLoad();
1273 adapter->BlockUntilLoaded();
1274
1275 ERC_TESTER ercTester( sch );
1276
1277 std::unique_ptr<DS_PROXY_VIEW_ITEM> drawingSheet( getDrawingSheetProxyView( sch ) );
1278 ercTester.RunTests( drawingSheet.get(), nullptr, m_kiway->KiFACE( KIWAY::FACE_CVPCB ),
1279 &sch->Project(), m_progressReporter );
1280
1281 markersProvider->SetSeverities( ercJob->m_severity );
1282
1283 m_reporter->Report( wxString::Format( _( "Found %d violations\n" ), markersProvider->GetCount() ),
1285
1286 ERC_REPORT reportWriter( sch, units, markersProvider );
1287
1288 bool wroteReport = false;
1289
1291 wroteReport = reportWriter.WriteJsonReport( outPath );
1292 else
1293 wroteReport = reportWriter.WriteTextReport( outPath );
1294
1295 if( !wroteReport )
1296 {
1297 m_reporter->Report( wxString::Format( _( "Unable to save ERC report to %s\n" ), outPath ),
1300 }
1301
1302 m_reporter->Report( wxString::Format( _( "Saved ERC Report to %s\n" ), outPath ),
1304
1305 if( ercJob->m_exitCodeViolations )
1306 {
1307 if( markersProvider->GetCount() > 0 )
1309 }
1310
1312}
1313
1314
1316{
1317 JOB_SCH_UPGRADE* aUpgradeJob = dynamic_cast<JOB_SCH_UPGRADE*>( aJob );
1318
1319 if( aUpgradeJob == nullptr )
1321
1322 SCHEMATIC* sch = getSchematic( aUpgradeJob->m_filename );
1323
1324 if( !sch )
1326
1327 bool shouldSave = aUpgradeJob->m_force;
1328
1330 shouldSave = true;
1331
1332 if( !shouldSave )
1333 {
1334 m_reporter->Report( _( "Schematic file was not updated\n" ), RPT_SEVERITY_ERROR );
1336 }
1337
1338 // needs an absolute path
1339 wxFileName schPath( aUpgradeJob->m_filename );
1340 schPath.MakeAbsolute();
1341 const wxString schFullPath = schPath.GetFullPath();
1342
1343 try
1344 {
1345 IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
1346 SCH_SHEET* loadedSheet = pi->LoadSchematicFile( schFullPath, sch );
1347 pi->SaveSchematicFile( schFullPath, loadedSheet, sch );
1348 }
1349 catch( const IO_ERROR& ioe )
1350 {
1351 wxString msg =
1352 wxString::Format( _( "Error saving schematic file '%s'.\n%s" ), schFullPath, ioe.What().GetData() );
1353 m_reporter->Report( msg, RPT_SEVERITY_ERROR );
1355 }
1356
1357 m_reporter->Report( _( "Successfully saved schematic file using the latest format\n" ), RPT_SEVERITY_INFO );
1358
1360}
1361
1362
1364{
1365 DS_PROXY_VIEW_ITEM* drawingSheet =
1367 &aSch->Project(), &aSch->RootScreen()->GetTitleBlock(),
1368 aSch->GetProperties() );
1369
1370 drawingSheet->SetPageNumber( TO_UTF8( aSch->RootScreen()->GetPageNumber() ) );
1371 drawingSheet->SetSheetCount( aSch->RootScreen()->GetPageCount() );
1372 drawingSheet->SetFileName( TO_UTF8( aSch->RootScreen()->GetFileName() ) );
1375 drawingSheet->SetIsFirstPage( aSch->RootScreen()->GetVirtualPageNumber() == 1 );
1376
1377 drawingSheet->SetSheetName( "" );
1378 drawingSheet->SetSheetPath( "" );
1379
1380 return drawingSheet;
1381}
const char * name
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:114
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
int GetPageCount() const
Definition base_screen.h:72
int GetVirtualPageNumber() const
Definition base_screen.h:75
const wxString & GetPageNumber() const
constexpr size_type GetWidth() const
Definition box2.h:214
constexpr const Vec GetCenter() const
Definition box2.h:230
constexpr size_type GetHeight() const
Definition box2.h:215
Color settings are a bit different than most of the settings objects in that there can be more than o...
int ShowModal() override
static DS_DATA_MODEL & GetTheInstance()
Return the instance of DS_DATA_MODEL used in the application.
void SetSheetPath(const std::string &aSheetPath)
Set the sheet path displayed in the title block.
void SetSheetCount(int aSheetCount)
Change the sheet-count number displayed in the title block.
void SetPageNumber(const std::string &aPageNumber)
Change the page number displayed in the title block.
void SetSheetName(const std::string &aSheetName)
Set the sheet name displayed in the title block.
void SetPageBorderColorLayer(int aLayerId)
Override the layer used to pick the color of the page border (normally LAYER_GRID)
void SetIsFirstPage(bool aIsFirstPage)
Change if this is first page.
void SetFileName(const std::string &aFileName)
Set the file name displayed in the title block.
void SetColorLayer(int aLayerId)
Can be used to override which layer ID is used for drawing sheet item colors.
static SCHEMATIC * LoadSchematic(const wxString &aFileName, bool aSetActive, bool aForceDefaultProject, PROJECT *aProject=nullptr, bool aCalculateConnectivity=true)
void InitRenderSettings(SCH_RENDER_SETTINGS *aRenderSettings, const wxString &aTheme, SCHEMATIC *aSch, const wxString &aDrawingSheetOverride=wxEmptyString)
Configure the SCH_RENDER_SETTINGS object with the correct data to be used with plotting.
SCHEMATIC * getSchematic(const wxString &aPath)
DS_PROXY_VIEW_ITEM * getDrawingSheetProxyView(SCHEMATIC *aSch)
int doSymExportSvg(JOB_SYM_EXPORT_SVG *aSvgJob, SCH_RENDER_SETTINGS *aRenderSettings, LIB_SYMBOL *symbol)
bool WriteJsonReport(const wxString &aFullFileName)
Writes a JSON formatted ERC Report to the given file path in the c-locale.
bool WriteTextReport(const wxString &aFullFileName)
Writes the text report also available via GetTextReport directly to a given file path.
void RunTests(DS_PROXY_VIEW_ITEM *aDrawingSheet, SCH_EDIT_FRAME *aEditFrame, KIFACE *aCvPcb, PROJECT *aProject, PROGRESS_REPORTER *aProgressReporter)
Definition erc.cpp:1985
void AddColumn(const wxString &aFieldName, const wxString &aLabel, bool aAddedByUser, const wxString &aVariantName)
wxString Export(const BOM_FMT_PRESET &settings)
void ApplyBomPreset(const BOM_PRESET &preset, const wxString &aVariantName)
static const wxString ITEM_NUMBER_VARIABLE
void SetVariantNames(const std::vector< wxString > &aVariantNames)
static const wxString QUANTITY_VARIABLE
std::vector< BOM_FIELD > GetFieldsOrdered()
void SetCurrentVariant(const wxString &aVariantName)
Set the current variant name for highlighting purposes.
Provide an extensible class to resolve 3D model paths.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath, std::vector< const EMBEDDED_FILES * > aEmbeddedFilesStack)
Determine the full path of the given file name.
void SetProgramBase(PGM_BASE *aBase)
Set a pointer to the application's PGM_BASE instance used to extract the local env vars.
bool SetProject(const PROJECT *aProject, bool *flgChanged=nullptr)
Set the current KiCad project directory as the first entry in the model path list.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
void Register(const std::string &aJobTypeName, std::function< int(JOB *job)> aHandler, std::function< bool(JOB *job, wxWindow *aParent)> aConfigHandler)
JOB_DISPATCHER(KIWAY *aKiway)
PROGRESS_REPORTER * m_progressReporter
REPORTER * m_reporter
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
JOB_PAGE_SIZE m_pageSizeSelect
SCH_PLOT_FORMAT m_plotFormat
std::vector< wxString > m_variantNames
std::vector< wxString > m_plotPages
bool m_exitCodeViolations
Definition job_rc.h:52
int m_severity
Definition job_rc.h:49
UNITS m_units
Definition job_rc.h:48
OUTPUT_FORMAT m_format
Definition job_rc.h:50
wxString m_filename
Definition job_rc.h:47
wxString m_outputLibraryPath
An simple container class that lets us dispatch output jobs to kifaces.
Definition job.h:183
void SetConfiguredOutputPath(const wxString &aPath)
Sets the configured output path for the job, this path is always saved to file.
Definition job.cpp:157
wxString GetFullOutputPath(PROJECT *aProject) const
Returns the full output path for the job, taking into account the configured output path,...
Definition job.cpp:150
bool GetOutputPathIsDirectory() const
Definition job.h:255
wxString GetConfiguredOutputPath() const
Returns the configured output path for the job.
Definition job.h:232
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition job.h:203
const std::map< wxString, wxString > & GetVarOverrides() const
Definition job.h:196
void SetDefaultPenWidth(int aWidth)
void SetGapLengthRatio(double aRatio)
void SetDashLengthRatio(double aRatio)
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:294
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:403
@ FACE_CVPCB
Definition kiway.h:303
void AsyncLoad()
Loads all available libraries for this adapter type in the background.
Define a library symbol object.
Definition lib_symbol.h:83
const BOX2I GetUnitBoundingBox(int aUnit, int aBodyStyle, bool aIgnoreHiddenFields=true, bool aIgnoreLabelsOnInvisiblePins=true) const
Get the bounding box for the symbol.
bool IsDerived() const
Definition lib_symbol.h:203
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
void PlotFields(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed)
Plot symbol fields.
std::shared_ptr< LIB_SYMBOL > GetRootSymbol() const
Get the parent symbol that does not have another parent.
wxString GetName() const override
Definition lib_symbol.h:145
const std::vector< wxString > & GetBodyStyleNames() const
Definition lib_symbol.h:787
bool HasDeMorganBodyStyles() const override
Definition lib_symbol.h:784
int GetBodyStyleCount() const override
Definition lib_symbol.h:776
int GetUnitCount() const override
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:41
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition page_info.h:79
int GetHeightIU(double aIUScale) const
Gets the page height in IU.
Definition page_info.h:168
void SetHeightMils(double aHeightInMils)
int GetWidthIU(double aIUScale) const
Gets the page width in IU.
Definition page_info.h:159
void SetWidthMils(double aWidthInMils)
static bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
Definition paths.cpp:508
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:132
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Definition plotter.cpp:77
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition plotter.h:169
void SetRenderSettings(RENDER_SETTINGS *aSettings)
Definition plotter.h:166
virtual void SetCreator(const wxString &aCreator)
Definition plotter.h:188
virtual void SetColorMode(bool aColorMode)
Plot in B/W or color.
Definition plotter.h:163
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
Container for project specific data.
Definition project.h:65
virtual void ApplyTextVars(const std::map< wxString, wxString > &aVarsMap)
Applies the given var map, it will create or update existing vars.
Definition project.cpp:123
std::vector< BOM_PRESET > m_BomPresets
std::vector< BOM_FMT_PRESET > m_BomFmtPresets
Holds all the data relating to one schematic.
Definition schematic.h:88
void SetCurrentVariant(const wxString &aVariantName)
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
SCHEMATIC_SETTINGS & Settings() const
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
PROJECT & Project() const
Return a reference to the project this schematic is part of.
Definition schematic.h:103
EMBEDDED_FILES * GetEmbeddedFiles() override
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
const std::map< wxString, wxString > * GetProperties()
Definition schematic.h:106
SCH_SHEET & Root() const
Definition schematic.h:132
Schematic editor (Eeschema) main window.
SCHEMATIC & Schematic() const
A cache assistant for the KiCad s-expression symbol libraries.
void Save(const std::optional< bool > &aOpt=std::nullopt) override
Save the entire library to file m_libFileName;.
virtual LIB_SYMBOL * GetSymbol(const wxString &aName)
void SetFileName(const wxString &aFileName)
const LIB_SYMBOL_MAP & GetSymbolMap() const
void SetModified(bool aModified=true)
static bool ConvertLibrary(std::map< std::string, UTF8 > *aOldFileProps, const wxString &aOldFilePath, const wxString &aNewFilepath)
Convert a schematic symbol library to the latest KiCad format.
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a symbol library using the file extension of aLibPath.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:167
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
int CheckAnnotation(ANNOTATION_ERROR_HANDLER aErrorHandler)
Check for annotations errors.
A helper to define a symbol's reference designator in a schematic.
void LoadColors(const COLOR_SETTINGS *aSettings) override
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition sch_screen.h:747
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
const PAGE_INFO & GetPageSettings() const
Definition sch_screen.h:140
const wxString & GetFileName() const
Definition sch_screen.h:153
int GetFileFormatVersionAtLoad() const
Definition sch_screen.h:138
const TITLE_BLOCK & GetTitleBlock() const
Definition sch_screen.h:164
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
Schematic symbol object.
Definition sch_symbol.h:76
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
virtual bool StartPlot(const wxString &aPageNumber) override
Create SVG file header.
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
virtual bool EndPlot() override
An interface to the global shared library manager that is schematic-specific and linked to one projec...
const std::vector< TEMPLATE_FIELDNAME > & GetTemplateFieldNames()
Return a template field name list for read only access.
wxString GetGeneratedFieldDisplayName(const wxString &aSource)
Returns any variables unexpanded, e.g.
Definition common.cpp:323
bool IsGeneratedField(const wxString &aSource)
Returns true if the string is generated, e.g contains a single text var reference.
Definition common.cpp:335
The common library.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
This file is part of the common library.
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
#define _(s)
EDA_UNITS
Definition eda_units.h:48
ERCE_T
ERC error codes.
@ FRAME_SCH
Definition frame_type.h:34
static const std::string CadstarNetlistFileExtension
static const std::string NetlistFileExtension
static const std::string ReportFileExtension
static const std::string JsonFileExtension
static const std::string XmlFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string OrCadPcb2NetlistFileExtension
static const std::string CsvFileExtension
static const std::string SpiceFileExtension
static const std::string SVGFileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
#define KICAD_FONT_NAME
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition layer_ids.h:496
@ LAYER_SCHEMATIC_PAGE_LIMITS
Definition layer_ids.h:497
static const int ERR_ARGS
Definition exit_codes.h:31
static const int OK
Definition exit_codes.h:30
static const int ERR_RC_VIOLATIONS
Rules check violation count was greater than 0.
Definition exit_codes.h:37
static const int ERR_INVALID_INPUT_FILE
Definition exit_codes.h:33
static const int SUCCESS
Definition exit_codes.h:29
static const int ERR_INVALID_OUTPUT_CONFLICT
Definition exit_codes.h:34
static const int ERR_UNKNOWN
Definition exit_codes.h:32
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition kicad_algo.h:100
@ GNL_OPT_BOM
SETTINGS_MANAGER * GetSettingsManager()
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
PLOT_FORMAT
The set of supported output plot formats.
Definition plotter.h:64
Plotting engines similar to ps (PostScript, Gerber, svg)
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
#define SEXPR_SYMBOL_LIB_FILE_VERSION
This file contains the file format version information for the s-expression schematic and symbol libr...
#define SEXPR_SCHEMATIC_FILE_VERSION
Schematic file version.
@ PAGE_SIZE_AUTO
Definition sch_plotter.h:48
@ PAGE_SIZE_A
Definition sch_plotter.h:50
@ PAGE_SIZE_A4
Definition sch_plotter.h:49
COLOR_SETTINGS * GetColorSettings(const wxString &aName)
T * GetAppSettings(const char *aFilename)
const int scale
MODEL3D_FORMAT_TYPE fileType(const char *aFileName)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
wxString label
wxString name
wxString fieldDelimiter
static std::vector< BOM_FMT_PRESET > BuiltInPresets()
wxString stringDelimiter
wxString refRangeDelimiter
wxString refDelimiter
wxString sortField
bool groupSymbols
std::vector< BOM_FIELD > fieldsOrdered
static std::vector< BOM_PRESET > BuiltInPresets()
bool excludeDNP
wxString filterString
std::vector< wxString > m_plotPages
Definition sch_plotter.h:58
wxString m_theme
Definition sch_plotter.h:67
DXF_UNITS m_DXF_File_Unit
Definition sch_plotter.h:74
bool m_PDFPropertyPopups
Definition sch_plotter.h:64
wxString m_outputDirectory
Definition sch_plotter.h:69
wxString m_outputFile
Definition sch_plotter.h:70
bool m_blackAndWhite
Definition sch_plotter.h:61
wxString m_variant
Definition sch_plotter.h:71
bool m_PDFHierarchicalLinks
Definition sch_plotter.h:65
bool m_useBackgroundColor
Definition sch_plotter.h:63
bool m_plotDrawingSheet
Definition sch_plotter.h:57
Hold a name of a symbol's field, field value, and default visibility.
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
wxString GetDefaultFieldName(FIELD_T aFieldId, bool aTranslateForHI)
Return a default symbol field name for a mandatory field type.
#define DO_TRANSLATE
#define MANDATORY_FIELDS
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
wxString GetCanonicalFieldName(FIELD_T aFieldType)
std::string path
VECTOR3I res
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
Definition of file extensions used in Kicad.