KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_export_2581.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <set>
23#include <map>
24#include <vector>
25
26#include <wx/choicdlg.h>
27#include <wx/filedlg.h>
28#include <wx/filefn.h>
29#include <kiplatform/ui.h>
30
31#include <board.h>
32#include <footprint.h>
33#include <kiway_holder.h>
34#include <paths.h>
35#include <pcb_edit_frame.h>
36#include <pcbnew_settings.h>
37#include <pgm_base.h>
38#include <project.h>
41#include <pcb_io/pcb_io_mgr.h>
45#include <string_utils.h>
48#include <kiplatform/io.h>
49#include <wx/wfstream.h>
50#include <wx/zipstrm.h>
51#include <wx_filename.h>
52
53
55 DIALOG_EXPORT_2581_BASE( aParent ),
56 m_parent( aParent ),
57 m_job( nullptr )
58{
60
61 SetupStandardButtons( { { wxID_OK, _( "Export" ) },
62 { wxID_CANCEL, _( "Close" ) } } );
63
64 // DIALOG_SHIM needs a unique hash_key because classname will be the same for both job and
65 // non-job versions.
66 m_hash_key = TO_UTF8( GetTitle() );
67
68 init();
69
70 // Now all widgets have the size fixed, call FinishDialogSettings
72
73 // The messages panel uses a negative min width so it doesn't drive the dialog width.
74 // Ensure the dialog is at least wide enough for the standard buttons and the messages
75 // panel's internal controls (filter checkboxes and Save button).
76 int btnWidth = m_stdButtons->GetMinSize().GetWidth() + 10;
77 int panelWidth = m_messagesPanel->GetBestSize().GetWidth() + 10;
78 int minWidth = std::max( btnWidth, panelWidth );
79 wxSize dialogMin = GetMinSize();
80
81 if( dialogMin.GetWidth() < minWidth )
82 {
83 SetMinSize( wxSize( minWidth, dialogMin.GetHeight() ) );
84 SetSize( wxSize( std::max( GetSize().GetWidth(), minWidth ), GetSize().GetHeight() ) );
85 }
86}
87
88
90 wxWindow* aParent ) :
91 DIALOG_EXPORT_2581_BASE( aParent ),
92 m_parent( aEditFrame ),
93 m_job( aJob )
94{
95 m_browseButton->Hide();
96
98
99 SetTitle( m_job->GetSettingsDialogTitle() );
100
101 // DIALOG_SHIM needs a unique hash_key because classname will be the same for both job and
102 // non-job versions.
103 m_hash_key = TO_UTF8( GetTitle() );
104
105 init();
106
107 // Now all widgets have the size fixed, call FinishDialogSettings
109
110 // The messages panel uses a negative min width so it doesn't drive the dialog width.
111 // Ensure the dialog is at least wide enough for the standard buttons and the messages
112 // panel's internal controls (filter checkboxes and Save button).
113 int btnWidth = m_stdButtons->GetMinSize().GetWidth() + 10;
114 int panelWidth = m_messagesPanel->GetBestSize().GetWidth() + 10;
115 int minWidth = std::max( btnWidth, panelWidth );
116 wxSize dialogMin = GetMinSize();
117
118 if( dialogMin.GetWidth() < minWidth )
119 {
120 SetMinSize( wxSize( minWidth, dialogMin.GetHeight() ) );
121 SetSize( wxSize( std::max( GetSize().GetWidth(), minWidth ), GetSize().GetHeight() ) );
122 }
123}
124
125
126void DIALOG_EXPORT_2581::onBrowseClicked( wxCommandEvent& event )
127{
128 // Build the absolute path of current output directory to preselect it in the file browser.
129 wxString path = ExpandEnvVarSubstitutions( m_outputFileName->GetValue(), &Prj() );
130 wxFileName fn( Prj().AbsolutePath( path ) );
131 wxString ipc_files = _( "IPC-2581 Files (*.xml)|*.xml" );
132 wxString compressed_files = _( "IPC-2581 Compressed Files (*.zip)|*.zip" );
133
134 wxFileDialog dlg( this, _( "Export IPC-2581 File" ), fn.GetPath(), fn.GetFullName(),
135 m_cbCompress->IsChecked() ? compressed_files : ipc_files,
136 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
137
139
140 if( dlg.ShowModal() == wxID_CANCEL )
141 return;
142
143 m_outputFileName->SetValue( dlg.GetPath() );
144
145}
146
147void DIALOG_EXPORT_2581::onCompressCheck( wxCommandEvent& event )
148{
149 if( m_cbCompress->GetValue() )
150 {
151 wxFileName fn = m_outputFileName->GetValue();
152
153 fn.SetExt( "zip" );
154 m_outputFileName->SetValue( fn.GetFullPath() );
155 }
156 else
157 {
158 wxFileName fn = m_outputFileName->GetValue();
159
160 fn.SetExt( "xml" );
161 m_outputFileName->SetValue( fn.GetFullPath() );
162 }
163}
164
165
166void DIALOG_EXPORT_2581::onOKClick( wxCommandEvent& event )
167{
168 if( m_job )
169 {
171 EndModal( wxID_OK );
172
173 return;
174 }
175
177
179 m_job = &job;
180
182
183 m_job = nullptr;
184
185 m_messagesPanel->Clear();
186
187 REPORTER& reporter = m_messagesPanel->Reporter();
188
189 wxFileName pcbFileName = GetOutputPath();
191
192 if( pcbFileName.GetName().empty() )
193 {
194 reporter.Report( _( "The board must be saved before generating IPC-2581 file." ),
196 return;
197 }
198
199 if( !m_parent->IsWritable( pcbFileName ) )
200 {
201 reporter.Report( wxString::Format( _( "Insufficient permissions to write file '%s'." ),
202 pcbFileName.GetFullPath() ),
204 return;
205 }
206
207 WX_PROGRESS_REPORTER progress( this, _( "Generate IPC-2581 File" ),
209
210 if( !GenerateFile( job, m_parent->GetBoard(), &progress, &reporter ) )
211 return;
212
213 reporter.Report( _( "IPC-2581 file generated successfully." ), RPT_SEVERITY_ACTION );
214}
215
216
218 PROGRESS_REPORTER* aProgressReporter, REPORTER* aReporter )
219{
220 wxCHECK( aBoard, false );
221 wxString outPath = aJob.GetFullOutputPath( aBoard->GetProject() );
222
223 if( !PATHS::EnsurePathExists( outPath, true ) )
224 {
225 if( aReporter )
226 aReporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
227
228 return false;
229 }
230
231 std::map<std::string, UTF8> props;
232 props["units"] = aJob.m_units == JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::MM ? "mm" : "inch";
233 props["sigfig"] = wxString::Format( "%d", aJob.m_precision );
234 props["version"] = aJob.m_version == JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::C ? "C" : "B";
235 props["OEMRef"] = aJob.m_colInternalId;
236 props["mpn"] = aJob.m_colMfgPn;
237 props["mfg"] = aJob.m_colMfg;
238 props["dist"] = aJob.m_colDist;
239 props["distpn"] = aJob.m_colDistPn;
240
241 if( !aJob.m_mode.IsEmpty() )
242 props["mode"] = aJob.m_mode;
243
244 if( !aJob.m_sections.IsEmpty() )
245 props["sections"] = aJob.m_sections;
246
247 if( !aJob.m_netNamePolicy.IsEmpty() )
248 props["netnames"] = aJob.m_netNamePolicy;
249
250 if( !aJob.m_refDesPolicy.IsEmpty() )
251 props["refdes"] = aJob.m_refDesPolicy;
252
253 wxString bomRev = aJob.m_bomRev;
254
255 if( bomRev.IsEmpty() && aBoard->GetProject() )
256 {
257 const IP2581_BOM& bomSettings = aBoard->GetProject()->GetProjectFile().m_IP2581Bom;
258 bomRev = bomSettings.bomRev;
259
260 if( bomRev.IsEmpty() )
261 bomRev = bomSettings.schRevision;
262 }
263
264 if( !bomRev.IsEmpty() )
265 props["bomrev"] = bomRev;
266
267 wxString tempFile = wxFileName::CreateTempFileName( wxS( "pcbnew_ipc" ) );
268
269 try
270 {
272 pi->SetProgressReporter( aProgressReporter );
273 pi->SetReporter( aReporter );
274 pi->SaveBoard( tempFile, *aBoard, &props );
275 }
276 catch( const IO_ERROR& ioe )
277 {
278 if( aReporter )
279 {
280 aReporter->Report( wxString::Format( _( "Error generating IPC-2581 file '%s'.\n%s" ),
281 aJob.m_filename,
282 ioe.What() ),
284 }
285
286 wxRemoveFile( tempFile );
287
288 return false;
289 }
290
291 if( aJob.m_compress )
292 {
293 wxFileName tempfn = outPath;
294 tempfn.SetExt( FILEEXT::Ipc2581FileExtension );
295 wxFileName zipfn = tempFile;
296 zipfn.SetExt( "zip" );
297
298 {
299 wxFFileOutputStream fnout( zipfn.GetFullPath() );
300
301 // Use a large I/O buffer to improve compatibility with cloud-synced folders.
302 // See KIPLATFORM::IO::CLOUD_SYNC_BUFFER_SIZE comment for details.
303 if( FILE* fp = fnout.GetFile()->fp() )
304 setvbuf( fp, nullptr, _IOFBF, KIPLATFORM::IO::CLOUD_SYNC_BUFFER_SIZE );
305
306 wxZipOutputStream zip( fnout );
307 wxFFileInputStream fnin( tempFile );
308
309 zip.PutNextEntry( tempfn.GetFullName() );
310 fnin.Read( zip );
311 }
312
313 wxRemoveFile( tempFile );
314 tempFile = zipfn.GetFullPath();
315 }
316
317 // If save succeeded, replace the original with what we just wrote
318 if( !wxRenameFile( tempFile, outPath ) )
319 {
320 if( aReporter )
321 {
322 aReporter->Report( wxString::Format( _( "Error generating IPC-2581 file '%s'.\n"
323 "Failed to rename temporary file '%s." ),
324 outPath,
325 tempFile ),
327 }
328
329 return false;
330 }
331
332 aJob.AddOutput( outPath );
333 return true;
334}
335
336
341
342
344{
345 IPC2581::MODE mode = GetDataSet();
346 IPC2581::SECTION_SET requested;
347
349 requested = IPC2581::RecommendedOptionalSections( mode );
350
351 // Table 4 by itself only gives the schema sections
353}
354
355
356std::vector<std::pair<IPC2581::SECTION, wxString>> DIALOG_EXPORT_2581::sectionLabels()
357{
358 return {
359 { IPC2581::SECTION::BOM_AVL, _( "BOM" ) },
360 { IPC2581::SECTION::PACKAGES, _( "packages" ) },
361 { IPC2581::SECTION::COMPONENTS, _( "components" ) },
362 { IPC2581::SECTION::PADSTACKS, _( "padstacks" ) },
363 { IPC2581::SECTION::STACKUP, _( "stackup" ) },
364 { IPC2581::SECTION::PROFILE, _( "board profile" ) },
365 { IPC2581::SECTION::SOLDERMASK, _( "solder mask" ) },
366 { IPC2581::SECTION::SOLDERPASTE, _( "solder paste" ) },
367 { IPC2581::SECTION::SILKSCREEN, _( "silkscreen" ) },
368 { IPC2581::SECTION::DRILL_ROUT, _( "drill and router" ) },
369 { IPC2581::SECTION::DOCUMENTATION, _( "documentation" ) },
370 { IPC2581::SECTION::OUTER_COPPER, _( "outer copper" ) },
371 { IPC2581::SECTION::INNER_COPPER, _( "inner copper" ) },
372 { IPC2581::SECTION::DIELECTRIC, _( "dielectric" ) },
373 { IPC2581::SECTION::MISC_FAB, _( "misc fab layers" ) },
374 { IPC2581::SECTION::LOGICAL_NET, _( "logical netlist" ) },
375 { IPC2581::SECTION::PHYSICAL_NET, _( "physical netlist" ) },
376 };
377}
378
379
381{
383
384 wxString summary;
385
386 for( const auto& [section, label] : sectionLabels() )
387 {
388 if( !sections.Contains( section ) )
389 continue;
390
391 if( !summary.IsEmpty() )
392 summary << wxT( ", " );
393
394 summary << label;
395 }
396
397 m_lblIncludes->SetLabel( wxString::Format( _( "Includes: %s" ), summary ) );
398 m_lblIncludes->Wrap( 280 );
399
401
402 Layout();
403}
404
405
406void DIALOG_EXPORT_2581::onDataSetChange( wxCommandEvent& event )
407{
408 // A new function mode removes the section key of the previous function mode
409 m_sectionKey.reset();
411}
412
413
414void DIALOG_EXPORT_2581::onCustomizeClick( wxCommandEvent& event )
415{
416 IPC2581::MODE mode = GetDataSet();
419
420 // Some pre-sets have 'optional' items. If you've chosen a preset, then
421 // you can only change the optional ones, not the required or forbidden ones
422 std::vector<IPC2581::SECTION> offered;
423 wxArrayString labels;
424 wxArrayInt selected;
425
426 for( const auto& [section, label] : sectionLabels() )
427 {
428 if( !optional.Contains( section ) )
429 continue;
430
431 if( current.Contains( section ) )
432 selected.Add( static_cast<int>( offered.size() ) );
433
434 offered.push_back( section );
435 labels.Add( label );
436 }
437
438 if( offered.empty() )
439 {
440 wxMessageBox( _( "This data set has no optional sections to choose from." ),
441 _( "Customize Content" ), wxOK | wxICON_INFORMATION, this );
442 return;
443 }
444
445 wxMultiChoiceDialog dlg( this, _( "Choose the optional sections to include." ),
446 _( "Customize Content" ), labels );
447 dlg.SetSelections( selected );
448
449 if( dlg.ShowModal() != wxID_OK )
450 return;
451
453
454 for( int index : dlg.GetSelections() )
455 chosen.Set( offered[index] );
456
459}
460
461
462void DIALOG_EXPORT_2581::onBomFieldsClick( wxCommandEvent& event )
463{
464 DIALOG_EXPORT_2581_BOM dlg( this, m_parent->GetBoard(), m_bomFields );
465
466 if( dlg.ShowModal() == wxID_OK )
467 m_bomFields = dlg.GetFields();
468}
469
470
472{
473 if( !m_job )
474 {
475 wxString path = m_outputFileName->GetValue();
476
477 if( path.IsEmpty() )
478 {
479 wxFileName brdFile( m_parent->GetBoard()->GetFileName() );
480 brdFile.SetExt( wxT( "xml" ) );
481 path = brdFile.GetFullPath();
482 m_outputFileName->SetValue( path );
483 }
484 }
485 else
486 {
487 m_choiceUnits->SetSelection( m_job->m_units == JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::MM ? 0 : 1 );
488 m_precision->SetValue( static_cast<int>( m_job->m_precision ) );
489 m_versionChoice->SetSelection( m_job->m_version == JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::B ? 0 : 1 );
490 m_cbCompress->SetValue( m_job->m_compress );
491 m_outputFileName->SetValue( m_job->GetConfiguredOutputPath() );
492 }
493
494 wxCommandEvent dummy;
496
498
499 if( !m_job )
500 {
501 m_bomFields.m_internalId = prj.m_IP2581Bom.id;
502 m_bomFields.m_mfgPn = prj.m_IP2581Bom.MPN;
503 m_bomFields.m_mfg = prj.m_IP2581Bom.mfg;
504 m_bomFields.m_distPn = prj.m_IP2581Bom.distPN;
505 m_bomFields.m_dist = prj.m_IP2581Bom.dist;
506 m_bomFields.m_revision = prj.m_IP2581Bom.bomRev.IsEmpty() ? prj.m_IP2581Bom.schRevision
507 : prj.m_IP2581Bom.bomRev;
508
509 if( std::optional<IPC2581::MODE> mode = IPC2581::ModeFromToken( prj.m_IP2581Bom.mode ) )
510 m_choiceDataSet->SetSelection( static_cast<int>( *mode ) );
511
512 if( !prj.m_IP2581Bom.sections.IsEmpty() )
514
515 m_choiceNetNames->SetSelection( prj.m_IP2581Bom.netNames == wxT( "anonymize" ) ? 1 : 0 );
516 m_choiceRefDes->SetSelection( prj.m_IP2581Bom.refDes == wxT( "omit" ) ? 1 : 0 );
517 }
518 else
519 {
520 m_bomFields.m_internalId = m_job->m_colInternalId;
521 m_bomFields.m_mfgPn = m_job->m_colMfgPn;
522 m_bomFields.m_mfg = m_job->m_colMfg;
523 m_bomFields.m_distPn = m_job->m_colDistPn;
524 m_bomFields.m_dist = m_job->m_colDist;
525 m_bomFields.m_revision = m_job->m_bomRev;
526
527 if( std::optional<IPC2581::MODE> mode = IPC2581::ModeFromToken( m_job->m_mode ) )
528 m_choiceDataSet->SetSelection( static_cast<int>( *mode ) );
529
530 if( !m_job->m_sections.IsEmpty() )
531 m_sectionKey = m_job->m_sections;
532
533 m_choiceNetNames->SetSelection( m_job->m_netNamePolicy == wxT( "anonymize" ) ? 1 : 0 );
534 m_choiceRefDes->SetSelection( m_job->m_refDesPolicy == wxT( "omit" ) ? 1 : 0 );
535 }
536
538
539 return true;
540}
541
542
544{
546
547 prj.m_IP2581Bom.id = m_bomFields.m_internalId;
548 prj.m_IP2581Bom.mfg = m_bomFields.m_mfg;
549 prj.m_IP2581Bom.MPN = m_bomFields.m_mfgPn;
550 prj.m_IP2581Bom.distPN = m_bomFields.m_distPn;
551 prj.m_IP2581Bom.dist = m_bomFields.m_dist;
552 prj.m_IP2581Bom.bomRev = m_bomFields.m_revision;
554 prj.m_IP2581Bom.sections = m_sectionKey.value_or( wxString() );
557}
558
559
561{
562 if( m_job )
563 {
564 m_job->SetConfiguredOutputPath( m_outputFileName->GetValue() );
565
566 m_job->m_colInternalId = m_bomFields.m_internalId;
567 m_job->m_colDist = m_bomFields.m_dist;
568 m_job->m_colDistPn = m_bomFields.m_distPn;
569 m_job->m_colMfg = m_bomFields.m_mfg;
570 m_job->m_colMfgPn = m_bomFields.m_mfgPn;
571 m_job->m_bomRev = m_bomFields.m_revision;
572
577 m_job->m_precision = m_precision->GetValue();
578 m_job->m_compress = GetCompress();
579 m_job->m_mode = IPC2581::ModeToken( GetDataSet() );
580 m_job->m_netNamePolicy = GetNetNamePolicy();
581 m_job->m_refDesPolicy = GetRefDesPolicy();
582
583 m_job->m_sections = m_sectionKey.value_or( wxString() );
584 }
585
586 return true;
587}
int index
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:409
PROJECT * GetProject() const
Definition board.h:767
wxStdDialogButtonSizer * m_stdButtons
DIALOG_EXPORT_2581_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Export IPC-2581"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
WX_HTML_REPORT_PANEL * m_messagesPanel
STD_BITMAP_BUTTON * m_browseButton
const IPC2581_BOM_FIELDS & GetFields() const
void onCustomizeClick(wxCommandEvent &event) override
wxString GetNetNamePolicy() const
static bool GenerateFile(JOB_EXPORT_PCB_IPC2581 &aJob, BOARD *aBoard, PROGRESS_REPORTER *aProgressReporter, REPORTER *aReporter)
IPC2581::SECTION_SET resolvedSections() const
IPC2581_BOM_FIELDS m_bomFields
bool TransferDataToWindow() override
void onCompressCheck(wxCommandEvent &event) override
std::optional< wxString > m_sectionKey
Set when the user selects the sections An empty value is then a true selection.
void onDataSetChange(wxCommandEvent &event) override
void onOKClick(wxCommandEvent &event) override
void updateContentSummary()
Set the includes line and the BOM Fields button from the function mode.
bool TransferDataFromWindow() override
static std::vector< std::pair< IPC2581::SECTION, wxString > > sectionLabels()
IPC2581::MODE GetDataSet() const
void onBomFieldsClick(wxCommandEvent &event) override
wxString GetRefDesPolicy() const
DIALOG_EXPORT_2581(PCB_EDIT_FRAME *aParent)
PCB_EDIT_FRAME * m_parent
void onBrowseClicked(wxCommandEvent &event) override
wxString GetUnitsString() const
JOB_EXPORT_PCB_IPC2581 * m_job
wxString GetOutputPath() const
void saveToProject()
Keep the dialog selections A job keeps them on the job.
void SetupStandardButtons(std::map< int, wxString > aLabels={})
std::string m_hash_key
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int ShowModal() override
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()
Set of schema sections.
bool Contains(SECTION aSection) const
SECTION_SET & Set(SECTION aSection, bool aOn=true)
wxString m_sections
Table 4 section key that replaces the optional sections of the function mode An empty value lets the ...
wxString m_refDesPolicy
Set to include or to omit.
wxString m_mode
Table 4 function mode token such as FABRICATION An empty value keeps the content that KiCad wrote bef...
wxString m_netNamePolicy
Set to include or to anonymize An anonymous name keeps the connections.
void AddOutput(wxString aOutputPath)
Definition job.h:216
wxString GetFullOutputPath(PROJECT *aProject) const
Returns the full output path for the job, taking into account the configured output path,...
Definition job.cpp:150
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
static bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
Definition paths.cpp:508
The main frame for Pcbnew.
static constexpr int EXPORT_PHASES
Content logistic history CAD data components the two netlists BOM vendor list references the write an...
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
A progress reporter interface for use in multi-threaded environments.
The backing store for a PROJECT, in JSON format.
struct IP2581_BOM m_IP2581Bom
Layer pair list for the board.
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:201
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:102
static void ResolvePossibleSymlinks(wxFileName &aFilename)
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition common.cpp:776
#define _(s)
static const std::string Ipc2581FileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
MODE
Columns of Table 4.
SECTION_SET RecommendedOptionalSections(MODE aMode)
Optional schema sections that aMode selects by default.
wxString ModeToken(MODE aMode)
Table 4 function mode token such as FABRICATION.
bool SectionSetFromKeyString(const wxString &aKey, SECTION_SET &aResult)
Read a sectionKey attribute value Return false for an unknown character.
RESOLVE_RESULT ResolveSections(REVISION aRevision, MODE aMode, const SECTION_SET &aRequested)
Compare aRequested with Table 4 and give the attributes to remove and the conflicts.
wxString SectionKeyString(const SECTION_SET &aSet)
Give aSet as a sectionKey attribute value.
SECTION_SET OptionalSections(MODE aMode)
Schema sections that Table 4 marks O for aMode.
std::optional< MODE > ModeFromToken(const wxString &aToken)
Read a Table 4 function mode token in upper case or in lower case.
static constexpr size_t CLOUD_SYNC_BUFFER_SIZE
Buffer size for file I/O operations on cloud-synced folders.
Definition io.h:169
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:521
see class PGM_BASE
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_ACTION
std::vector< FAB_LAYER_COLOR > dummy
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
wxString mfg
Manufacturer name column.
wxString refDes
Set to include or to omit.
wxString bomRev
Explicit BOM revision override set by user.
wxString schRevision
Auto-propagated schematic title block revision.
wxString sections
Table 4 section key for the optional sections.
wxString MPN
Manufacturer part number column.
wxString netNames
Set to include or to anonymize.
wxString id
Internal ID column.
wxString dist
Distributor name column.
wxString mode
Table 4 function mode token.
wxString distPN
Distributor part number column.
std::string path
IbisParser parser & reporter
#define PR_CAN_ABORT