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 <wx/dir.h>
39#include <wx/file.h>
40#include <memory>
41#include <connection_graph.h>
42#include "eeschema_helpers.h"
43#include <filename_resolver.h>
44#include <kiway.h>
45#include <sch_painter.h>
46#include <locale_io.h>
47#include <erc/erc.h>
48#include <erc/erc_report.h>
52#include <paths.h>
53#include <reporter.h>
54#include <string_utils.h>
55
57
58#include <sch_file_versions.h>
59#include <sch_io/sch_io.h>
61
62#include <netlist.h>
72
73#include <fields_data_model.h>
74
79#include <confirm.h>
80#include <project_sch.h>
81
83
84
86 JOB_DISPATCHER( aKiway ),
87 m_cliSchematic( nullptr )
88{
89 Register( "bom",
90 std::bind( &EESCHEMA_JOBS_HANDLER::JobExportBom, this, std::placeholders::_1 ),
91 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
92 {
93 JOB_EXPORT_SCH_BOM* bomJob = dynamic_cast<JOB_EXPORT_SCH_BOM*>( job );
94
95 SCH_EDIT_FRAME* editFrame =
96 static_cast<SCH_EDIT_FRAME*>( aKiway->Player( FRAME_SCH, false ) );
97
98 wxCHECK( bomJob && editFrame, false );
99
100 DIALOG_SYMBOL_FIELDS_TABLE dlg( editFrame, bomJob );
101 return dlg.ShowModal() == wxID_OK;
102 } );
103 Register( "pythonbom",
104 std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPythonBom, this, std::placeholders::_1 ),
105 []( JOB* job, wxWindow* aParent ) -> bool
106 {
107 return true;
108 } );
109 Register( "netlist",
110 std::bind( &EESCHEMA_JOBS_HANDLER::JobExportNetlist, this, std::placeholders::_1 ),
111 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
112 {
113 JOB_EXPORT_SCH_NETLIST* netJob = dynamic_cast<JOB_EXPORT_SCH_NETLIST*>( job );
114
115 SCH_EDIT_FRAME* editFrame =
116 static_cast<SCH_EDIT_FRAME*>( aKiway->Player( FRAME_SCH, false ) );
117
118 wxCHECK( netJob && editFrame, false );
119
120 DIALOG_EXPORT_NETLIST dlg( editFrame, aParent, netJob );
121 return dlg.ShowModal() == wxID_OK;
122 } );
123 Register( "plot",
124 std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPlot, this, std::placeholders::_1 ),
125 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
126 {
127 JOB_EXPORT_SCH_PLOT* plotJob = dynamic_cast<JOB_EXPORT_SCH_PLOT*>( job );
128
129 SCH_EDIT_FRAME* editFrame =
130 static_cast<SCH_EDIT_FRAME*>( aKiway->Player( FRAME_SCH, false ) );
131
132 wxCHECK( plotJob && editFrame, false );
133
134 if( plotJob->m_plotFormat == SCH_PLOT_FORMAT::HPGL )
135 {
136 DisplayErrorMessage( editFrame,
137 _( "Plotting to HPGL is no longer supported as of KiCad 10.0." ) );
138 return false;
139 }
140
141 DIALOG_PLOT_SCHEMATIC dlg( editFrame, aParent, plotJob );
142 return dlg.ShowModal() == wxID_OK;
143 } );
144 Register( "symupgrade",
145 std::bind( &EESCHEMA_JOBS_HANDLER::JobSymUpgrade, this, std::placeholders::_1 ),
146 []( JOB* job, wxWindow* aParent ) -> bool
147 {
148 return true;
149 } );
150 Register( "symsvg",
151 std::bind( &EESCHEMA_JOBS_HANDLER::JobSymExportSvg, this, std::placeholders::_1 ),
152 []( JOB* job, wxWindow* aParent ) -> bool
153 {
154 return true;
155 } );
156 Register( "erc", std::bind( &EESCHEMA_JOBS_HANDLER::JobSchErc, this, std::placeholders::_1 ),
157 []( JOB* job, wxWindow* aParent ) -> bool
158 {
159 JOB_SCH_ERC* ercJob = dynamic_cast<JOB_SCH_ERC*>( job );
160
161 wxCHECK( ercJob, false );
162
163 DIALOG_ERC_JOB_CONFIG dlg( aParent, ercJob );
164 return dlg.ShowModal() == wxID_OK;
165 } );
166 Register( "upgrade", std::bind( &EESCHEMA_JOBS_HANDLER::JobUpgrade, this, std::placeholders::_1 ),
167 []( JOB* job, wxWindow* aParent ) -> bool
168 {
169 return true;
170 } );
171}
172
173
175{
176 SCHEMATIC* sch = nullptr;
177
178 if( !Pgm().IsGUI() && Pgm().GetSettingsManager().IsProjectOpenNotDummy() )
179 {
181 wxString schPath = aPath;
182
183 if( schPath.IsEmpty() )
184 {
185 wxFileName path = project.GetProjectFullName();
187 path.MakeAbsolute();
188 schPath = path.GetFullPath();
189 }
190
191 if( !m_cliSchematic )
192 m_cliSchematic = EESCHEMA_HELPERS::LoadSchematic( schPath, true, false, &project );
193
194 sch = m_cliSchematic;
195 }
196 else if( Pgm().IsGUI() && Pgm().GetSettingsManager().IsProjectOpen() )
197 {
198 SCH_EDIT_FRAME* editFrame = static_cast<SCH_EDIT_FRAME*>( m_kiway->Player( FRAME_SCH, false ) );
199
200 if( editFrame )
201 sch = &editFrame->Schematic();
202 }
203 else if( !aPath.IsEmpty() )
204 {
205 sch = EESCHEMA_HELPERS::LoadSchematic( aPath, true, false );
206 }
207
208 if( !sch )
209 m_reporter->Report( _( "Failed to load schematic\n" ), RPT_SEVERITY_ERROR );
210
211 return sch;
212}
213
215 const wxString& aTheme, SCHEMATIC* aSch,
216 const wxString& aDrawingSheetOverride )
217{
218 COLOR_SETTINGS* cs = ::GetColorSettings( aTheme );
219 aRenderSettings->LoadColors( cs );
220 aRenderSettings->m_ShowHiddenPins = false;
221 aRenderSettings->m_ShowHiddenFields = false;
222 aRenderSettings->m_ShowPinAltIcons = false;
223
224 aRenderSettings->SetDefaultPenWidth( aSch->Settings().m_DefaultLineWidth );
225 aRenderSettings->m_LabelSizeRatio = aSch->Settings().m_LabelSizeRatio;
226 aRenderSettings->m_TextOffsetRatio = aSch->Settings().m_TextOffsetRatio;
227 aRenderSettings->m_PinSymbolSize = aSch->Settings().m_PinSymbolSize;
228
229 aRenderSettings->SetDashLengthRatio( aSch->Settings().m_DashedLineDashRatio );
230 aRenderSettings->SetGapLengthRatio( aSch->Settings().m_DashedLineGapRatio );
231
232 // Load the drawing sheet from the filename stored in BASE_SCREEN::m_DrawingSheetFileName.
233 // If empty, or not existing, the default drawing sheet is loaded.
234
235 auto loadSheet =
236 [&]( const wxString& path ) -> bool
237 {
238 wxString msg;
239 FILENAME_RESOLVER resolve;
240 resolve.SetProject( &aSch->Project() );
241 resolve.SetProgramBase( &Pgm() );
242
243 wxString absolutePath = resolve.ResolvePath( path, wxGetCwd(),
244 { aSch->GetEmbeddedFiles() } );
245
246 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( absolutePath, &msg ) )
247 {
248 m_reporter->Report( wxString::Format( _( "Error loading drawing sheet '%s'." ), path )
249 + wxS( "\n" ) + msg + wxS( "\n" ),
251 return false;
252 }
253
254 return true;
255 };
256
257 // try to load the override first
258 if( !aDrawingSheetOverride.IsEmpty() && loadSheet( aDrawingSheetOverride ) )
259 return;
260
261 // no override or failed override continues here
262 loadSheet( aSch->Settings().m_SchDrawingSheetFileName );
263}
264
265
267{
268 JOB_EXPORT_SCH_PLOT* aPlotJob = dynamic_cast<JOB_EXPORT_SCH_PLOT*>( aJob );
269
270 wxCHECK( aPlotJob, CLI::EXIT_CODES::ERR_UNKNOWN );
271
272 if( aPlotJob->m_plotFormat == SCH_PLOT_FORMAT::HPGL )
273 {
274 m_reporter->Report( _( "Plotting to HPGL is no longer supported as of KiCad 10.0.\n" ),
277 }
278
279 SCHEMATIC* sch = getSchematic( aPlotJob->m_filename );
280
281 if( !sch )
283
284 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
285 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
286
287 // Apply variant if specified
288 if( !aPlotJob->m_variantNames.empty() )
289 {
290 // For plot export, we use the first variant name from the set
291 wxString variantName = *aPlotJob->m_variantNames.begin();
292
293 if( variantName != wxS( "all" ) )
294 sch->SetCurrentVariant( variantName );
295 }
296
297 std::unique_ptr<SCH_RENDER_SETTINGS> renderSettings = std::make_unique<SCH_RENDER_SETTINGS>();
298 InitRenderSettings( renderSettings.get(), aPlotJob->m_theme, sch, aPlotJob->m_drawingSheet );
299
300 wxString font = aPlotJob->m_defaultFont;
301
302 if( font.IsEmpty() )
303 {
305 font = cfg ? cfg->m_Appearance.default_font : wxString( KICAD_FONT_NAME );
306 }
307
308 renderSettings->SetDefaultFont( font );
309 renderSettings->SetMinPenWidth( aPlotJob->m_minPenWidth );
310
311 std::unique_ptr<SCH_PLOTTER> schPlotter = std::make_unique<SCH_PLOTTER>( sch );
312
314
315 switch( aPlotJob->m_plotFormat )
316 {
317 case SCH_PLOT_FORMAT::DXF: format = PLOT_FORMAT::DXF; break;
318 case SCH_PLOT_FORMAT::PDF: format = PLOT_FORMAT::PDF; break;
319 case SCH_PLOT_FORMAT::SVG: format = PLOT_FORMAT::SVG; break;
320 case SCH_PLOT_FORMAT::POST: format = PLOT_FORMAT::POST; break;
321 case SCH_PLOT_FORMAT::HPGL: /* no longer supported */ break;
322 }
323
324 int pageSizeSelect = PageFormatReq::PAGE_SIZE_AUTO;
325
326 switch( aPlotJob->m_pageSizeSelect )
327 {
328 case JOB_PAGE_SIZE::PAGE_SIZE_A: pageSizeSelect = PageFormatReq::PAGE_SIZE_A; break;
329 case JOB_PAGE_SIZE::PAGE_SIZE_A4: pageSizeSelect = PageFormatReq::PAGE_SIZE_A4; break;
331 }
332
333 wxString outPath = aPlotJob->GetFullOutputPath( &sch->Project() );
334
335 if( !PATHS::EnsurePathExists( outPath, !aPlotJob->GetOutputPathIsDirectory() ) )
336 {
337 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
339 }
340
341 SCH_PLOT_OPTS plotOpts;
342 plotOpts.m_blackAndWhite = aPlotJob->m_blackAndWhite;
343 plotOpts.m_PDFPropertyPopups = aPlotJob->m_PDFPropertyPopups;
345 plotOpts.m_PDFMetadata = aPlotJob->m_PDFMetadata;
346
347 if( aPlotJob->GetOutputPathIsDirectory() )
348 {
349 plotOpts.m_outputDirectory = outPath;
350 plotOpts.m_outputFile = wxEmptyString;
351 }
352 else
353 {
354 plotOpts.m_outputDirectory = wxEmptyString;
355 plotOpts.m_outputFile = outPath;
356 }
357
358 plotOpts.m_pageSizeSelect = pageSizeSelect;
359 plotOpts.m_plotAll = aPlotJob->m_plotAll;
360 plotOpts.m_plotDrawingSheet = aPlotJob->m_plotDrawingSheet;
361 plotOpts.m_plotPages = aPlotJob->m_plotPages;
362 plotOpts.m_theme = aPlotJob->m_theme;
363 plotOpts.m_useBackgroundColor = aPlotJob->m_useBackgroundColor;
364 plotOpts.m_plotHopOver = aPlotJob->m_show_hop_over;
365
366 // Use variant from m_variantNames if specified, otherwise use the schematic's current variant
367 if( !aPlotJob->m_variantNames.empty() )
368 plotOpts.m_variant = aPlotJob->m_variantNames.front();
369
370 // Always export dxf in mm by kicad-cli (similar to Pcbnew)
372
373 schPlotter->Plot( format, plotOpts, renderSettings.get(), m_reporter );
374
375 if( m_reporter->HasMessageOfSeverity( RPT_SEVERITY_ERROR ) )
377
378 return CLI::EXIT_CODES::OK;
379}
380
381
383{
384 JOB_EXPORT_SCH_NETLIST* aNetJob = dynamic_cast<JOB_EXPORT_SCH_NETLIST*>( aJob );
385
386 wxCHECK( aNetJob, CLI::EXIT_CODES::ERR_UNKNOWN );
387
388 SCHEMATIC* sch = getSchematic( aNetJob->m_filename );
389
390 if( !sch )
392
393 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
394 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
395
396 // Apply variant if specified
397 if( !aNetJob->m_variantNames.empty() )
398 {
399 // For netlist export, we use the first variant name from the set
400 wxString variantName = *aNetJob->m_variantNames.begin();
401
402 if( variantName != wxS( "all" ) )
403 sch->SetCurrentVariant( variantName );
404 }
405
406 // Annotation warning check
407 SCH_REFERENCE_LIST referenceList;
408 sch->Hierarchy().GetSymbols( referenceList );
409
410 if( referenceList.GetCount() > 0 )
411 {
412 if( referenceList.CheckAnnotation(
413 []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
414 {
415 // We're only interested in the end result -- either errors or not
416 } )
417 > 0 )
418 {
419 m_reporter->Report( _( "Warning: schematic has annotation errors, please use the "
420 "schematic editor to fix them\n" ),
422 }
423 }
424
425 // Test duplicate sheet names:
426 ERC_TESTER erc( sch );
427
428 if( erc.TestDuplicateSheetNames( false ) > 0 )
429 m_reporter->Report( _( "Warning: duplicate sheet names.\n" ), RPT_SEVERITY_WARNING );
430
431 std::unique_ptr<NETLIST_EXPORTER_BASE> helper;
432 unsigned netlistOption = 0;
433
434 wxString fileExt;
435
436 switch( aNetJob->format )
437 {
440 helper = std::make_unique<NETLIST_EXPORTER_KICAD>( sch );
441 break;
442
445 helper = std::make_unique<NETLIST_EXPORTER_ORCADPCB2>( sch );
446 break;
447
450 helper = std::make_unique<NETLIST_EXPORTER_CADSTAR>( sch );
451 break;
452
456 helper = std::make_unique<NETLIST_EXPORTER_SPICE>( sch );
457 break;
458
461 helper = std::make_unique<NETLIST_EXPORTER_SPICE_MODEL>( sch );
462 break;
463
465 fileExt = wxS( "xml" );
466 helper = std::make_unique<NETLIST_EXPORTER_XML>( sch );
467 break;
468
470 fileExt = wxS( "asc" );
471 helper = std::make_unique<NETLIST_EXPORTER_PADS>( sch );
472 break;
473
475 fileExt = wxS( "txt" );
476 helper = std::make_unique<NETLIST_EXPORTER_ALLEGRO>( sch );
477 break;
478
479 default:
480 m_reporter->Report( _( "Unknown netlist format.\n" ), RPT_SEVERITY_ERROR );
482 }
483
484 if( aNetJob->GetConfiguredOutputPath().IsEmpty() )
485 {
486 wxFileName fn = sch->GetFileName();
487 fn.SetName( fn.GetName() );
488 fn.SetExt( fileExt );
489
490 aNetJob->SetConfiguredOutputPath( fn.GetFullName() );
491 }
492
493 wxString outPath = aNetJob->GetFullOutputPath( &sch->Project() );
494
495 if( !PATHS::EnsurePathExists( outPath, true ) )
496 {
497 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
499 }
500
501 bool res = helper->WriteNetlist( outPath, netlistOption, *m_reporter );
502
503 if( !res )
505
506 return CLI::EXIT_CODES::OK;
507}
508
509
511{
512 JOB_EXPORT_SCH_BOM* aBomJob = dynamic_cast<JOB_EXPORT_SCH_BOM*>( aJob );
513
514 wxCHECK( aBomJob, CLI::EXIT_CODES::ERR_UNKNOWN );
515
516 SCHEMATIC* sch = getSchematic( aBomJob->m_filename );
517
518 if( !sch )
520
521 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
522 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
523
524 wxString currentVariant;
525
526 if( !aBomJob->m_variantNames.empty() )
527 {
528 currentVariant = aBomJob->m_variantNames.front();
529
530 if( currentVariant != wxS( "all" ) )
531 sch->SetCurrentVariant( currentVariant );
532 }
533
534 // Annotation warning check
535 SCH_REFERENCE_LIST referenceList;
536 sch->Hierarchy().GetSymbols( referenceList, false, false );
537
538 if( referenceList.GetCount() > 0 )
539 {
540 SCH_REFERENCE_LIST copy = referenceList;
541
542 // Check annotation splits references...
543 if( copy.CheckAnnotation(
544 []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
545 {
546 // We're only interested in the end result -- either errors or not
547 } )
548 > 0 )
549 {
550 m_reporter->Report(
551 _( "Warning: schematic has annotation errors, please use the schematic "
552 "editor to fix them\n" ),
554 }
555 }
556
557 // Test duplicate sheet names:
558 ERC_TESTER erc( sch );
559
560 if( erc.TestDuplicateSheetNames( false ) > 0 )
561 m_reporter->Report( _( "Warning: duplicate sheet names.\n" ), RPT_SEVERITY_WARNING );
562
563 // Build our data model
564 FIELDS_EDITOR_GRID_DATA_MODEL dataModel( referenceList, nullptr );
565
566 // Mandatory fields first
567 for( FIELD_T fieldId : MANDATORY_FIELDS )
568 {
569 dataModel.AddColumn( GetCanonicalFieldName( fieldId ),
570 GetDefaultFieldName( fieldId, DO_TRANSLATE ), false, currentVariant );
571 }
572
573 // Generated/virtual fields (e.g. ${QUANTITY}, ${ITEM_NUMBER}) present only in the fields table
576 false, currentVariant );
579 false, currentVariant );
580
581 // Attribute fields (boolean flags on symbols)
582 dataModel.AddColumn( wxS( "${DNP}" ), GetGeneratedFieldDisplayName( wxS( "${DNP}" ) ),
583 false, currentVariant );
584 dataModel.AddColumn( wxS( "${EXCLUDE_FROM_BOM}" ), GetGeneratedFieldDisplayName( wxS( "${EXCLUDE_FROM_BOM}" ) ),
585 false, currentVariant );
586 dataModel.AddColumn( wxS( "${EXCLUDE_FROM_BOARD}" ), GetGeneratedFieldDisplayName( wxS( "${EXCLUDE_FROM_BOARD}" ) ),
587 false, currentVariant );
588 dataModel.AddColumn( wxS( "${EXCLUDE_FROM_SIM}" ), GetGeneratedFieldDisplayName( wxS( "${EXCLUDE_FROM_SIM}" ) ),
589 false, currentVariant );
590
591 // User field names in symbols second
592 std::set<wxString> userFieldNames;
593
594 for( size_t i = 0; i < referenceList.GetCount(); ++i )
595 {
596 SCH_SYMBOL* symbol = referenceList[i].GetSymbol();
597
598 for( SCH_FIELD& field : symbol->GetFields() )
599 {
600 if( !field.IsMandatory() && !field.IsPrivate() )
601 userFieldNames.insert( field.GetName() );
602 }
603 }
604
605 for( const wxString& fieldName : userFieldNames )
606 dataModel.AddColumn( fieldName, GetGeneratedFieldDisplayName( fieldName ), true, currentVariant );
607
608 // Add any templateFieldNames which aren't already present in the userFieldNames
609 for( const TEMPLATE_FIELDNAME& templateFieldname :
611 {
612 if( userFieldNames.count( templateFieldname.m_Name ) == 0 )
613 {
614 dataModel.AddColumn( templateFieldname.m_Name, GetGeneratedFieldDisplayName( templateFieldname.m_Name ),
615 false, currentVariant );
616 }
617 }
618
619 BOM_PRESET preset;
620
621 // Load a preset if one is specified
622 if( !aBomJob->m_bomPresetName.IsEmpty() )
623 {
624 // Find the preset
625 const BOM_PRESET* schPreset = nullptr;
626
627 for( const BOM_PRESET& p : BOM_PRESET::BuiltInPresets() )
628 {
629 if( p.name == aBomJob->m_bomPresetName )
630 {
631 schPreset = &p;
632 break;
633 }
634 }
635
636 for( const BOM_PRESET& p : sch->Settings().m_BomPresets )
637 {
638 if( p.name == aBomJob->m_bomPresetName )
639 {
640 schPreset = &p;
641 break;
642 }
643 }
644
645 if( !schPreset )
646 {
647 m_reporter->Report( wxString::Format( _( "BOM preset '%s' not found" ) + wxS( "\n" ),
648 aBomJob->m_bomPresetName ),
650
652 }
653
654 preset = *schPreset;
655 }
656 else
657 {
658 size_t i = 0;
659
660 for( const wxString& fieldName : aBomJob->m_fieldsOrdered )
661 {
662 // Handle wildcard. We allow the wildcard anywhere in the list, but it needs to respect
663 // fields that come before and after the wildcard.
664 if( fieldName == wxS( "*" ) )
665 {
666 for( const BOM_FIELD& modelField : dataModel.GetFieldsOrdered() )
667 {
668 struct BOM_FIELD field;
669
670 field.name = modelField.name;
671 field.show = true;
672 field.groupBy = false;
673 field.label = field.name;
674
675 bool fieldAlreadyPresent = false;
676
677 for( BOM_FIELD& presetField : preset.fieldsOrdered )
678 {
679 if( presetField.name == field.name )
680 {
681 fieldAlreadyPresent = true;
682 break;
683 }
684 }
685
686 bool fieldLaterInList = false;
687
688 for( const wxString& fieldInList : aBomJob->m_fieldsOrdered )
689 {
690 if( fieldInList == field.name )
691 {
692 fieldLaterInList = true;
693 break;
694 }
695 }
696
697 if( !fieldAlreadyPresent && !fieldLaterInList )
698 preset.fieldsOrdered.emplace_back( field );
699 }
700
701 continue;
702 }
703
704 struct BOM_FIELD field;
705
706 field.name = fieldName;
707 field.show = !fieldName.StartsWith( wxT( "__" ), &field.name );
708 field.groupBy = alg::contains( aBomJob->m_fieldsGroupBy, field.name );
709
710 if( ( aBomJob->m_fieldsLabels.size() > i ) && !aBomJob->m_fieldsLabels[i].IsEmpty() )
711 field.label = aBomJob->m_fieldsLabels[i];
712 else if( IsGeneratedField( field.name ) )
713 field.label = GetGeneratedFieldDisplayName( field.name );
714 else
715 field.label = field.name;
716
717 preset.fieldsOrdered.emplace_back( field );
718 i++;
719 }
720
721 preset.sortAsc = aBomJob->m_sortAsc;
722 preset.sortField = aBomJob->m_sortField;
723 preset.filterString = aBomJob->m_filterString;
724 preset.groupSymbols = ( aBomJob->m_fieldsGroupBy.size() > 0 );
725 preset.excludeDNP = aBomJob->m_excludeDNP;
726 }
727
728 BOM_FMT_PRESET fmt;
729
730 // Load a format preset if one is specified
731 if( !aBomJob->m_bomFmtPresetName.IsEmpty() )
732 {
733 std::optional<BOM_FMT_PRESET> schFmtPreset;
734
736 {
737 if( p.name == aBomJob->m_bomFmtPresetName )
738 {
739 schFmtPreset = p;
740 break;
741 }
742 }
743
744 for( const BOM_FMT_PRESET& p : sch->Settings().m_BomFmtPresets )
745 {
746 if( p.name == aBomJob->m_bomFmtPresetName )
747 {
748 schFmtPreset = p;
749 break;
750 }
751 }
752
753 if( !schFmtPreset )
754 {
755 m_reporter->Report( wxString::Format( _( "BOM format preset '%s' not found" ) + wxS( "\n" ),
756 aBomJob->m_bomFmtPresetName ),
758
760 }
761
762 fmt = *schFmtPreset;
763 }
764 else
765 {
766 fmt.fieldDelimiter = aBomJob->m_fieldDelimiter;
767 fmt.stringDelimiter = aBomJob->m_stringDelimiter;
768 fmt.refDelimiter = aBomJob->m_refDelimiter;
770 fmt.keepTabs = aBomJob->m_keepTabs;
771 fmt.keepLineBreaks = aBomJob->m_keepLineBreaks;
772 }
773
774 if( aBomJob->GetConfiguredOutputPath().IsEmpty() )
775 {
776 wxFileName fn = sch->GetFileName();
777 fn.SetName( fn.GetName() );
778 fn.SetExt( FILEEXT::CsvFileExtension );
779
780 aBomJob->SetConfiguredOutputPath( fn.GetFullName() );
781 }
782
783 wxString configuredPath = aBomJob->GetConfiguredOutputPath();
784 bool hasVariantPlaceholder = configuredPath.Contains( wxS( "${VARIANT}" ) );
785
786 // Determine which variants to process
787 std::vector<wxString> variantsToProcess;
788
789 if( aBomJob->m_variantNames.size() > 1 && hasVariantPlaceholder )
790 {
791 variantsToProcess = aBomJob->m_variantNames;
792 }
793 else
794 {
795 variantsToProcess.push_back( currentVariant );
796 }
797
798 for( const wxString& variantName : variantsToProcess )
799 {
800 std::vector<wxString> singleVariant = { variantName };
801 dataModel.SetVariantNames( singleVariant );
802 dataModel.SetCurrentVariant( variantName );
803 dataModel.ApplyBomPreset( preset, variantName );
804
805 wxString outPath;
806
807 if( hasVariantPlaceholder )
808 {
809 wxString variantPath = configuredPath;
810 variantPath.Replace( wxS( "${VARIANT}" ), variantName );
811 aBomJob->SetConfiguredOutputPath( variantPath );
812 outPath = aBomJob->GetFullOutputPath( &sch->Project() );
813 aBomJob->SetConfiguredOutputPath( configuredPath );
814 }
815 else
816 {
817 outPath = aBomJob->GetFullOutputPath( &sch->Project() );
818 }
819
820 if( !PATHS::EnsurePathExists( outPath, true ) )
821 {
822 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
824 }
825
826 wxFile f;
827
828 if( !f.Open( outPath, wxFile::write ) )
829 {
830 m_reporter->Report( wxString::Format( _( "Unable to open destination '%s'" ), outPath ),
832
834 }
835
836 bool res = f.Write( dataModel.Export( fmt ) );
837
838 if( !res )
840
841 m_reporter->Report( wxString::Format( _( "Wrote bill of materials to '%s'." ), outPath ),
843 }
844
845 return CLI::EXIT_CODES::OK;
846}
847
848
850{
851 JOB_EXPORT_SCH_PYTHONBOM* aNetJob = dynamic_cast<JOB_EXPORT_SCH_PYTHONBOM*>( aJob );
852
853 wxCHECK( aNetJob, CLI::EXIT_CODES::ERR_UNKNOWN );
854
855 SCHEMATIC* sch = getSchematic( aNetJob->m_filename );
856
857 if( !sch )
859
860 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
861 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
862
863 // Annotation warning check
864 SCH_REFERENCE_LIST referenceList;
865 sch->Hierarchy().GetSymbols( referenceList );
866
867 if( referenceList.GetCount() > 0 )
868 {
869 if( referenceList.CheckAnnotation(
870 []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
871 {
872 // We're only interested in the end result -- either errors or not
873 } )
874 > 0 )
875 {
876 m_reporter->Report( _( "Warning: schematic has annotation errors, please use the "
877 "schematic editor to fix them\n" ),
879 }
880 }
881
882 // Test duplicate sheet names:
883 ERC_TESTER erc( sch );
884
885 if( erc.TestDuplicateSheetNames( false ) > 0 )
886 m_reporter->Report( _( "Warning: duplicate sheet names.\n" ), RPT_SEVERITY_WARNING );
887
888 std::unique_ptr<NETLIST_EXPORTER_XML> xmlNetlist =
889 std::make_unique<NETLIST_EXPORTER_XML>( sch );
890
891 if( aNetJob->GetConfiguredOutputPath().IsEmpty() )
892 {
893 wxFileName fn = sch->GetFileName();
894 fn.SetName( fn.GetName() + "-bom" );
895 fn.SetExt( FILEEXT::XmlFileExtension );
896
897 aNetJob->SetConfiguredOutputPath( fn.GetFullName() );
898 }
899
900 wxString outPath = aNetJob->GetFullOutputPath( &sch->Project() );
901
902 if( !PATHS::EnsurePathExists( outPath, true ) )
903 {
904 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
906 }
907
908 bool res = xmlNetlist->WriteNetlist( outPath, GNL_OPT_BOM, *m_reporter );
909
910 if( !res )
912
913 m_reporter->Report( wxString::Format( _( "Wrote bill of materials to '%s'." ), outPath ),
915
916 return CLI::EXIT_CODES::OK;
917}
918
919
921 LIB_SYMBOL* symbol )
922{
923 wxCHECK( symbol, CLI::EXIT_CODES::ERR_UNKNOWN );
924
925 std::shared_ptr<LIB_SYMBOL> parent;
926 LIB_SYMBOL* symbolToPlot = symbol;
927
928 // if the symbol is an alias, then the draw items are stored in the root symbol
929 if( symbol->IsDerived() )
930 {
931 parent = symbol->GetRootSymbol();
932
933 wxCHECK( parent, CLI::EXIT_CODES::ERR_UNKNOWN );
934
935 symbolToPlot = parent.get();
936 }
937
938 // iterate from unit 1, unit 0 would be "all units" which we don't want
939 for( int unit = 1; unit < symbol->GetUnitCount() + 1; unit++ )
940 {
941 for( int bodyStyle = 1; bodyStyle <= symbol->GetBodyStyleCount(); ++bodyStyle )
942 {
943 wxString filename;
944 wxFileName fn;
945
946 fn.SetPath( aSvgJob->m_outputDirectory );
947 fn.SetExt( FILEEXT::SVGFileExtension );
948
949 filename = symbol->GetName();
950
951 for( wxChar c : wxFileName::GetForbiddenChars( wxPATH_DOS ) )
952 filename.Replace( c, ' ' );
953
954 // Even single units get a unit number in the filename. This simplifies the
955 // handling of the files as they have a uniform pattern.
956 // Also avoids aliasing 'sym', unit 2 and 'sym_unit2', unit 1 to the same file.
957 filename += wxString::Format( "_unit%d", unit );
958
959 if( symbol->HasDeMorganBodyStyles() )
960 {
961 if( bodyStyle == 2 )
962 filename += wxS( "_demorgan" );
963 }
964 else if( bodyStyle <= (int) symbol->GetBodyStyleNames().size() )
965 {
966 filename += wxS( "_" ) + symbol->GetBodyStyleNames()[bodyStyle-1].Lower();
967 }
968
969 fn.SetName( filename );
970 m_reporter->Report( wxString::Format( _( "Plotting symbol '%s' unit %d to '%s'\n" ),
971 symbol->GetName(),
972 unit,
973 fn.GetFullPath() ),
975
976 // Get the symbol bounding box to fit the plot page to it
977 BOX2I symbolBB = symbol->Flatten()->GetUnitBoundingBox( unit, bodyStyle,
978 !aSvgJob->m_includeHiddenFields );
980 pageInfo.SetHeightMils( schIUScale.IUToMils( symbolBB.GetHeight() * 1.2 ) );
981 pageInfo.SetWidthMils( schIUScale.IUToMils( symbolBB.GetWidth() * 1.2 ) );
982
983 SVG_PLOTTER* plotter = new SVG_PLOTTER();
984 plotter->SetRenderSettings( aRenderSettings );
985 plotter->SetPageSettings( pageInfo );
986 plotter->SetColorMode( !aSvgJob->m_blackAndWhite );
987
988 VECTOR2I plot_offset = symbolBB.GetCenter();
989 const double scale = 1.0;
990
991 // Currently, plot units are in decimal
992 plotter->SetViewport( plot_offset, schIUScale.IU_PER_MILS / 10, scale, false );
993
994 plotter->SetCreator( wxT( "Eeschema-SVG" ) );
995
996 if( !plotter->OpenFile( fn.GetFullPath() ) )
997 {
998 m_reporter->Report( wxString::Format( _( "Unable to open destination '%s'" ) + wxS( "\n" ),
999 fn.GetFullPath() ),
1001
1002 delete plotter;
1004 }
1005
1006 LOCALE_IO toggle;
1007 SCH_PLOT_OPTS plotOpts;
1008
1009 plotter->StartPlot( wxT( "1" ) );
1010
1011 bool background = true;
1012 VECTOR2I offset( pageInfo.GetWidthIU( schIUScale.IU_PER_MILS ) / 2,
1013 pageInfo.GetHeightIU( schIUScale.IU_PER_MILS ) / 2 );
1014
1015 // note, we want the fields from the original symbol pointer (in case of non-alias)
1016 symbolToPlot->Plot( plotter, background, plotOpts, unit, bodyStyle, offset, false );
1017 symbol->PlotFields( plotter, background, plotOpts, unit, bodyStyle, offset, false );
1018
1019 symbolToPlot->Plot( plotter, !background, plotOpts, unit, bodyStyle, offset, false );
1020 symbol->PlotFields( plotter, !background, plotOpts, unit, bodyStyle, offset, false );
1021
1022 plotter->EndPlot();
1023 delete plotter;
1024 }
1025 }
1026
1027 if( m_reporter->HasMessageOfSeverity( RPT_SEVERITY_ERROR ) )
1029
1030 return CLI::EXIT_CODES::OK;
1031}
1032
1033
1035{
1036 JOB_SYM_EXPORT_SVG* svgJob = dynamic_cast<JOB_SYM_EXPORT_SVG*>( aJob );
1037
1038 wxCHECK( svgJob, CLI::EXIT_CODES::ERR_UNKNOWN );
1039
1040 wxFileName fn( svgJob->m_libraryPath );
1041 fn.MakeAbsolute();
1042
1043 SCH_IO_KICAD_SEXPR_LIB_CACHE schLibrary( fn.GetFullPath() );
1044
1045 try
1046 {
1047 schLibrary.Load();
1048 }
1049 catch( ... )
1050 {
1051 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1053 }
1054
1055 if( m_progressReporter )
1056 m_progressReporter->KeepRefreshing();
1057
1058 LIB_SYMBOL* symbol = nullptr;
1059
1060 if( !svgJob->m_symbol.IsEmpty() )
1061 {
1062 // See if the selected symbol exists
1063 symbol = schLibrary.GetSymbol( svgJob->m_symbol );
1064
1065 if( !symbol )
1066 {
1067 m_reporter->Report( _( "There is no symbol selected to save." ) + wxS( "\n" ),
1070 }
1071 }
1072
1073 if( !svgJob->m_outputDirectory.IsEmpty() && !wxDir::Exists( svgJob->m_outputDirectory ) )
1074 {
1075 if( !wxFileName::Mkdir( svgJob->m_outputDirectory ) )
1076 {
1077 m_reporter->Report( wxString::Format( _( "Unable to create output directory '%s'." ) + wxS( "\n" ),
1078 svgJob->m_outputDirectory ),
1081 }
1082 }
1083
1084 SCH_RENDER_SETTINGS renderSettings;
1086 renderSettings.LoadColors( cs );
1087 renderSettings.SetDefaultPenWidth( DEFAULT_LINE_WIDTH_MILS * schIUScale.IU_PER_MILS );
1088 renderSettings.m_ShowHiddenPins = svgJob->m_includeHiddenPins;
1089 renderSettings.m_ShowHiddenFields = svgJob->m_includeHiddenFields;
1090
1091 int exitCode = CLI::EXIT_CODES::OK;
1092
1093 if( symbol )
1094 {
1095 exitCode = doSymExportSvg( svgJob, &renderSettings, symbol );
1096 }
1097 else
1098 {
1099 // Just plot all the symbols we can
1100 const LIB_SYMBOL_MAP& libSymMap = schLibrary.GetSymbolMap();
1101
1102 for( const auto& [name, libSymbol] : libSymMap )
1103 {
1104 if( m_progressReporter )
1105 {
1106 m_progressReporter->AdvancePhase( wxString::Format( _( "Exporting %s" ), name ) );
1107 m_progressReporter->KeepRefreshing();
1108 }
1109
1110 exitCode = doSymExportSvg( svgJob, &renderSettings, libSymbol );
1111
1112 if( exitCode != CLI::EXIT_CODES::OK )
1113 break;
1114 }
1115 }
1116
1117 return exitCode;
1118}
1119
1120
1122{
1123 JOB_SYM_UPGRADE* upgradeJob = dynamic_cast<JOB_SYM_UPGRADE*>( aJob );
1124
1125 wxCHECK( upgradeJob, CLI::EXIT_CODES::ERR_UNKNOWN );
1126
1127 wxFileName fn( upgradeJob->m_libraryPath );
1128 fn.MakeAbsolute();
1129
1130 SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
1131
1132 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1133 {
1134 if( wxFile::Exists( upgradeJob->m_outputLibraryPath ) )
1135 {
1136 m_reporter->Report( _( "Output path must not conflict with existing path\n" ),
1138
1140 }
1141 }
1142 else if( fileType != SCH_IO_MGR::SCH_KICAD )
1143 {
1144 m_reporter->Report( _( "Output path must be specified to convert legacy and non-KiCad libraries\n" ),
1146
1148 }
1149
1150 if( fileType == SCH_IO_MGR::SCH_KICAD )
1151 {
1152 SCH_IO_KICAD_SEXPR_LIB_CACHE schLibrary( fn.GetFullPath() );
1153
1154 try
1155 {
1156 schLibrary.Load();
1157 }
1158 catch( ... )
1159 {
1160 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1162 }
1163
1164 if( m_progressReporter )
1165 m_progressReporter->KeepRefreshing();
1166
1167 bool shouldSave =
1169
1170 if( shouldSave )
1171 {
1172 m_reporter->Report( _( "Saving symbol library in updated format\n" ), RPT_SEVERITY_ACTION );
1173
1174 try
1175 {
1176 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1177 schLibrary.SetFileName( upgradeJob->m_outputLibraryPath );
1178
1179 schLibrary.SetModified();
1180 schLibrary.Save();
1181 }
1182 catch( ... )
1183 {
1184 m_reporter->Report( ( "Unable to save library\n" ), RPT_SEVERITY_ERROR );
1186 }
1187 }
1188 else
1189 {
1190 m_reporter->Report( _( "Symbol library was not updated\n" ), RPT_SEVERITY_ERROR );
1191 }
1192 }
1193 else
1194 {
1195 if( !SCH_IO_MGR::ConvertLibrary( nullptr, fn.GetAbsolutePath(), upgradeJob->m_outputLibraryPath ) )
1196 {
1197 m_reporter->Report( ( "Unable to convert library\n" ), RPT_SEVERITY_ERROR );
1199 }
1200 }
1201
1202 return CLI::EXIT_CODES::OK;
1203}
1204
1205
1206
1208{
1209 JOB_SCH_ERC* ercJob = dynamic_cast<JOB_SCH_ERC*>( aJob );
1210
1211 wxCHECK( ercJob, CLI::EXIT_CODES::ERR_UNKNOWN );
1212
1213 SCHEMATIC* sch = getSchematic( ercJob->m_filename );
1214
1215 if( !sch )
1217
1218 aJob->SetTitleBlock( sch->RootScreen()->GetTitleBlock() );
1219 sch->Project().ApplyTextVars( aJob->GetVarOverrides() );
1220
1221 if( ercJob->GetConfiguredOutputPath().IsEmpty() )
1222 {
1223 wxFileName fn = sch->GetFileName();
1224 fn.SetName( fn.GetName() + wxS( "-erc" ) );
1225
1227 fn.SetExt( FILEEXT::JsonFileExtension );
1228 else
1229 fn.SetExt( FILEEXT::ReportFileExtension );
1230
1231 ercJob->SetConfiguredOutputPath( fn.GetFullName() );
1232 }
1233
1234 wxString outPath = ercJob->GetFullOutputPath( &sch->Project() );
1235
1236 if( !PATHS::EnsurePathExists( outPath, true ) )
1237 {
1238 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
1240 }
1241
1242 EDA_UNITS units;
1243
1244 switch( ercJob->m_units )
1245 {
1246 case JOB_SCH_ERC::UNITS::INCH: units = EDA_UNITS::INCH; break;
1247 case JOB_SCH_ERC::UNITS::MILS: units = EDA_UNITS::MILS; break;
1248 case JOB_SCH_ERC::UNITS::MM: units = EDA_UNITS::MM; break;
1249 default: units = EDA_UNITS::MM; break;
1250 }
1251
1252 std::shared_ptr<SHEETLIST_ERC_ITEMS_PROVIDER> markersProvider =
1253 std::make_shared<SHEETLIST_ERC_ITEMS_PROVIDER>( sch );
1254
1255 // Running ERC requires libraries be loaded, so make sure they have been
1257 adapter->AsyncLoad();
1258 adapter->BlockUntilLoaded();
1259
1260 ERC_TESTER ercTester( sch );
1261
1262 std::unique_ptr<DS_PROXY_VIEW_ITEM> drawingSheet( getDrawingSheetProxyView( sch ) );
1263 ercTester.RunTests( drawingSheet.get(), nullptr, m_kiway->KiFACE( KIWAY::FACE_CVPCB ),
1264 &sch->Project(), m_progressReporter );
1265
1266 markersProvider->SetSeverities( ercJob->m_severity );
1267
1268 m_reporter->Report( wxString::Format( _( "Found %d violations\n" ), markersProvider->GetCount() ),
1270
1271 ERC_REPORT reportWriter( sch, units, markersProvider );
1272
1273 bool wroteReport = false;
1274
1276 wroteReport = reportWriter.WriteJsonReport( outPath );
1277 else
1278 wroteReport = reportWriter.WriteTextReport( outPath );
1279
1280 if( !wroteReport )
1281 {
1282 m_reporter->Report( wxString::Format( _( "Unable to save ERC report to %s\n" ), outPath ),
1285 }
1286
1287 m_reporter->Report( wxString::Format( _( "Saved ERC Report to %s\n" ), outPath ),
1289
1290 if( ercJob->m_exitCodeViolations )
1291 {
1292 if( markersProvider->GetCount() > 0 )
1294 }
1295
1297}
1298
1299
1301{
1302 JOB_SCH_UPGRADE* aUpgradeJob = dynamic_cast<JOB_SCH_UPGRADE*>( aJob );
1303
1304 if( aUpgradeJob == nullptr )
1306
1307 SCHEMATIC* sch = getSchematic( aUpgradeJob->m_filename );
1308
1309 if( !sch )
1311
1312 bool shouldSave = aUpgradeJob->m_force;
1313
1315 shouldSave = true;
1316
1317 if( !shouldSave )
1318 {
1319 m_reporter->Report( _( "Schematic file was not updated\n" ), RPT_SEVERITY_ERROR );
1321 }
1322
1323 // needs an absolute path
1324 wxFileName schPath( aUpgradeJob->m_filename );
1325 schPath.MakeAbsolute();
1326 const wxString schFullPath = schPath.GetFullPath();
1327
1328 try
1329 {
1330 IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
1331 SCH_SHEET* loadedSheet = pi->LoadSchematicFile( schFullPath, sch );
1332 pi->SaveSchematicFile( schFullPath, loadedSheet, sch );
1333 }
1334 catch( const IO_ERROR& ioe )
1335 {
1336 wxString msg =
1337 wxString::Format( _( "Error saving schematic file '%s'.\n%s" ), schFullPath, ioe.What().GetData() );
1338 m_reporter->Report( msg, RPT_SEVERITY_ERROR );
1340 }
1341
1342 m_reporter->Report( _( "Successfully saved schematic file using the latest format\n" ), RPT_SEVERITY_INFO );
1343
1345}
1346
1347
1349{
1350 DS_PROXY_VIEW_ITEM* drawingSheet =
1352 &aSch->Project(), &aSch->RootScreen()->GetTitleBlock(),
1353 aSch->GetProperties() );
1354
1355 drawingSheet->SetPageNumber( TO_UTF8( aSch->RootScreen()->GetPageNumber() ) );
1356 drawingSheet->SetSheetCount( aSch->RootScreen()->GetPageCount() );
1357 drawingSheet->SetFileName( TO_UTF8( aSch->RootScreen()->GetFileName() ) );
1360 drawingSheet->SetIsFirstPage( aSch->RootScreen()->GetVirtualPageNumber() == 1 );
1361
1362 drawingSheet->SetSheetName( "" );
1363 drawingSheet->SetSheetPath( "" );
1364
1365 return drawingSheet;
1366}
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:1907
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
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:204
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:146
const std::vector< wxString > & GetBodyStyleNames() const
Definition lib_symbol.h:774
bool HasDeMorganBodyStyles() const override
Definition lib_symbol.h:771
int GetBodyStyleCount() const override
Definition lib_symbol.h:763
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:478
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:122
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
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.
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
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...
void AsyncLoad() override
Loads all available libraries for this adapter type in the background.
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:322
bool IsGeneratedField(const wxString &aSource)
Returns true if the string is generated, e.g contains a single text var reference.
Definition common.cpp:334
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.