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 <wx/choicdlg.h>
23#include <wx/filedlg.h>
24#include <kiplatform/ui.h>
25
26#include <board.h>
27#include <pcb_edit_frame.h>
28#include <project.h>
35#include <tool/tool_manager.h>
36#include <string_utils.h>
39#include <wx_filename.h>
40
41
43 DIALOG_EXPORT_2581_BASE( aParent ),
44 m_parent( aParent ),
45 m_job( nullptr )
46{
48
49 SetupStandardButtons( { { wxID_OK, _( "Export" ) },
50 { wxID_CANCEL, _( "Close" ) } } );
51
52 // DIALOG_SHIM needs a unique hash_key because classname will be the same for both job and
53 // non-job versions.
54 m_hash_key = TO_UTF8( GetTitle() );
55
56 init();
57
58 // Now all widgets have the size fixed, call FinishDialogSettings
60
61 // The messages panel uses a negative min width so it doesn't drive the dialog width.
62 // Ensure the dialog is at least wide enough for the standard buttons and the messages
63 // panel's internal controls (filter checkboxes and Save button).
64 int btnWidth = m_stdButtons->GetMinSize().GetWidth() + 10;
65 int panelWidth = m_messagesPanel->GetBestSize().GetWidth() + 10;
66 int minWidth = std::max( btnWidth, panelWidth );
67 wxSize dialogMin = GetMinSize();
68
69 if( dialogMin.GetWidth() < minWidth )
70 {
71 SetMinSize( wxSize( minWidth, dialogMin.GetHeight() ) );
72 SetSize( wxSize( std::max( GetSize().GetWidth(), minWidth ), GetSize().GetHeight() ) );
73 }
74}
75
76
78 wxWindow* aParent ) :
79 DIALOG_EXPORT_2581_BASE( aParent ),
80 m_parent( aEditFrame ),
81 m_job( aJob )
82{
83 m_browseButton->Hide();
84
86
87 SetTitle( m_job->GetSettingsDialogTitle() );
88
89 // DIALOG_SHIM needs a unique hash_key because classname will be the same for both job and
90 // non-job versions.
91 m_hash_key = TO_UTF8( GetTitle() );
92
93 init();
94
95 // Now all widgets have the size fixed, call FinishDialogSettings
97
98 // The messages panel uses a negative min width so it doesn't drive the dialog width.
99 // Ensure the dialog is at least wide enough for the standard buttons and the messages
100 // panel's internal controls (filter checkboxes and Save button).
101 int btnWidth = m_stdButtons->GetMinSize().GetWidth() + 10;
102 int panelWidth = m_messagesPanel->GetBestSize().GetWidth() + 10;
103 int minWidth = std::max( btnWidth, panelWidth );
104 wxSize dialogMin = GetMinSize();
105
106 if( dialogMin.GetWidth() < minWidth )
107 {
108 SetMinSize( wxSize( minWidth, dialogMin.GetHeight() ) );
109 SetSize( wxSize( std::max( GetSize().GetWidth(), minWidth ), GetSize().GetHeight() ) );
110 }
111}
112
113
114void DIALOG_EXPORT_2581::onBrowseClicked( wxCommandEvent& event )
115{
116 // Build the absolute path of current output directory to preselect it in the file browser.
117 wxString path = ExpandEnvVarSubstitutions( m_outputFileName->GetValue(), &Prj() );
118 wxFileName fn( Prj().AbsolutePath( path ) );
119 wxString ipc_files = _( "IPC-2581 Files (*.xml)|*.xml" );
120 wxString compressed_files = _( "IPC-2581 Compressed Files (*.zip)|*.zip" );
121
122 wxFileDialog dlg( this, _( "Export IPC-2581 File" ), fn.GetPath(), fn.GetFullName(),
123 m_cbCompress->IsChecked() ? compressed_files : ipc_files,
124 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
125
127
128 if( dlg.ShowModal() == wxID_CANCEL )
129 return;
130
131 m_outputFileName->SetValue( dlg.GetPath() );
132
133}
134
135void DIALOG_EXPORT_2581::onCompressCheck( wxCommandEvent& event )
136{
137 if( m_cbCompress->GetValue() )
138 {
139 wxFileName fn = m_outputFileName->GetValue();
140
141 fn.SetExt( "zip" );
142 m_outputFileName->SetValue( fn.GetFullPath() );
143 }
144 else
145 {
146 wxFileName fn = m_outputFileName->GetValue();
147
148 fn.SetExt( "xml" );
149 m_outputFileName->SetValue( fn.GetFullPath() );
150 }
151}
152
153
154void DIALOG_EXPORT_2581::onOKClick( wxCommandEvent& event )
155{
156 if( m_job )
157 {
159 EndModal( wxID_OK );
160
161 return;
162 }
163
165
167 m_job = &job;
168
170
171 m_job = nullptr;
172
173 m_messagesPanel->Clear();
174
175 REPORTER& reporter = m_messagesPanel->Reporter();
176
177 wxFileName pcbFileName = GetOutputPath();
179
180 if( pcbFileName.GetName().empty() )
181 {
182 reporter.Report( _( "The board must be saved before generating IPC-2581 file." ),
184 return;
185 }
186
187 if( !m_parent->IsWritable( pcbFileName ) )
188 {
189 reporter.Report( wxString::Format( _( "Insufficient permissions to write file '%s'." ),
190 pcbFileName.GetFullPath() ),
192 return;
193 }
194
195 m_parent->GetToolManager()->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( this );
196
197 WX_PROGRESS_REPORTER progress( this, _( "Generate IPC-2581 File" ),
199
200 if( !GenerateIpc2581File( job, m_parent->GetBoard(), &progress, &reporter ) )
201 return;
202
203 reporter.Report( _( "IPC-2581 file generated successfully." ), RPT_SEVERITY_ACTION );
204}
205
206
208{
209 m_contentPanel->Configure( FAB_CONTENT_FORMAT::IPC2581, m_parent->GetBoard() );
210}
211
212
214{
215 IPC2581_BOM_FIELDS bomFields;
216
217 if( !m_job )
218 {
219 wxString path = m_outputFileName->GetValue();
220
221 if( path.IsEmpty() )
222 {
223 wxFileName brdFile( m_parent->GetBoard()->GetFileName() );
224 brdFile.SetExt( wxT( "xml" ) );
225 path = brdFile.GetFullPath();
226 m_outputFileName->SetValue( path );
227 }
228 }
229 else
230 {
231 m_choiceUnits->SetSelection( m_job->m_units == JOB_EXPORT_PCB_FAB::UNITS::MM ? 0 : 1 );
232 m_precision->SetValue( static_cast<int>( m_job->m_precision ) );
233 m_versionChoice->SetSelection( m_job->m_version == JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::B ? 0 : 1 );
234 m_cbCompress->SetValue( m_job->m_compress );
235 m_outputFileName->SetValue( m_job->GetConfiguredOutputPath() );
236 }
237
238 wxCommandEvent dummy;
240
242
243 if( !m_job )
244 {
245 bomFields.m_internalId = prj.m_IP2581Bom.id;
246 bomFields.m_mfgPn = prj.m_IP2581Bom.MPN;
247 bomFields.m_mfg = prj.m_IP2581Bom.mfg;
248 bomFields.m_distPn = prj.m_IP2581Bom.distPN;
249 bomFields.m_dist = prj.m_IP2581Bom.dist;
250 bomFields.m_revision = prj.m_IP2581Bom.bomRev.IsEmpty() ? prj.m_IP2581Bom.schRevision : prj.m_IP2581Bom.bomRev;
251
252 if( std::optional<IPC2581::MODE> mode = IPC2581::ModeFromToken( prj.m_IP2581Bom.mode ) )
253 m_contentPanel->SetDataSet( *mode );
254
255 m_contentPanel->SetSectionKey( prj.m_IP2581Bom.sections );
256
257 m_contentPanel->SetNetNames( prj.m_IP2581Bom.netNames == wxS( "anonymize" )
260 m_contentPanel->SetRefDes( prj.m_IP2581Bom.refDes == wxS( "omit" )
263 }
264 else
265 {
266 bomFields.m_internalId = m_job->m_colInternalId;
267 bomFields.m_mfgPn = m_job->m_colMfgPn;
268 bomFields.m_mfg = m_job->m_colMfg;
269 bomFields.m_distPn = m_job->m_colDistPn;
270 bomFields.m_dist = m_job->m_colDist;
271 bomFields.m_revision = m_job->m_bomRev;
272
273 m_contentPanel->SetDataSet( m_job->m_dataSet );
274
275 m_contentPanel->SetSectionKey( m_job->m_sections );
276
277 m_contentPanel->SetNetNames( m_job->m_netNames );
278 m_contentPanel->SetRefDes( m_job->m_refDes );
279 m_contentPanel->SetVariantNames( m_job->m_variantNames );
280 }
281
282 m_contentPanel->SetBomFields( bomFields );
283
284 return true;
285}
286
287
289{
291 const IPC2581_BOM_FIELDS& bomFields = m_contentPanel->GetBomFields();
292
293 prj.m_IP2581Bom.id = bomFields.m_internalId;
294 prj.m_IP2581Bom.mfg = bomFields.m_mfg;
295 prj.m_IP2581Bom.MPN = bomFields.m_mfgPn;
296 prj.m_IP2581Bom.distPN = bomFields.m_distPn;
297 prj.m_IP2581Bom.dist = bomFields.m_dist;
298 prj.m_IP2581Bom.bomRev = bomFields.m_revision;
299 prj.m_IP2581Bom.mode = IPC2581::ModeToken( m_contentPanel->GetDataSet() );
300 prj.m_IP2581Bom.sections = m_contentPanel->GetSectionKey();
302 ? wxS( "anonymize" ) : wxS( "include" );
304 ? wxS( "omit" ) : wxS( "include" );
305}
306
307
309{
310 if( m_job )
311 {
312 const IPC2581_BOM_FIELDS& bomFields = m_contentPanel->GetBomFields();
313 m_job->SetConfiguredOutputPath( m_outputFileName->GetValue() );
314
315 m_job->m_colInternalId = bomFields.m_internalId;
316 m_job->m_colDist = bomFields.m_dist;
317 m_job->m_colDistPn = bomFields.m_distPn;
318 m_job->m_colMfg = bomFields.m_mfg;
319 m_job->m_colMfgPn = bomFields.m_mfgPn;
320 m_job->m_bomRev = bomFields.m_revision;
321
324 m_job->m_units = GetUnitsString() == wxT( "mm" ) ? JOB_EXPORT_PCB_FAB::UNITS::MM
326 m_job->m_precision = m_precision->GetValue();
327 m_job->m_compress = GetCompress();
328 m_job->m_dataSet = m_contentPanel->GetDataSet();
329 m_job->m_netNames = m_contentPanel->GetNetNames();
330 m_job->m_refDes = m_contentPanel->GetRefDes();
331
332 m_job->m_sections = m_contentPanel->GetSectionKey();
333 m_job->m_variantNames = m_contentPanel->GetVariantNames();
334 }
335
336 return true;
337}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
wxStdDialogButtonSizer * m_stdButtons
PANEL_FAB_EXPORT_CONTENT * m_contentPanel
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
bool TransferDataToWindow() override
void onCompressCheck(wxCommandEvent &event) override
void onOKClick(wxCommandEvent &event) override
bool TransferDataFromWindow() override
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...
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
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...
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
static void ResolvePossibleSymlinks(wxFileName &aFilename)
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
Handle actions specific to filling copper zones.
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)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition idf_helpers.h:37
bool GenerateIpc2581File(JOB_EXPORT_PCB_IPC2581 &aJob, BOARD *aBoard, PROGRESS_REPORTER *aProgressReporter, REPORTER *aReporter)
Write the IPC-2581 file or archive of aJob and record it as a job output.
std::optional< MODE > ModeFromToken(const wxString &aToken)
Read a Table 4 function mode token in upper case or in lower case.
wxString ModeToken(MODE aMode)
Table 4 function mode token such as FABRICATION.
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:533
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_ACTION
std::vector< FAB_LAYER_COLOR > dummy
std::optional< wxString > sections
Table 4 section key, unset when the mode picks the sections.
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 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.
Fields that supply the IPC-2581 BOM section.
std::string path
IbisParser parser & reporter
#define PR_CAN_ABORT