KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_gendrill.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) 1992-2019 Jean_Pierre Charras <jp.charras at wanadoo.fr>
5 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <confirm.h>
26#include <core/arraydim.h>
28#include <pcb_edit_frame.h>
29#include <pcbnew_settings.h>
30#include <pcbplot.h>
33#include <bitmaps.h>
35#include <board.h>
37#include <footprint.h>
38#include <pad.h>
39#include <pcb_track.h>
40#include <paths.h>
41#include <project.h>
42#include <dialog_gendrill.h>
44#include <reporter.h>
45#include <wx/msgdlg.h>
46#include <wx/dirdlg.h>
47#include <wx/filedlg.h>
49
50// list of allowed precision for EXCELLON files, for integer format:
51// Due to difference between inches and mm,
52// there are 2 precision values, one for inches and one for metric
53// Note: for decimla format, the precision is not used
56
57
58/* This function displays the dialog frame for drill tools
59 */
61{
62 PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
63 DIALOG_GENDRILL dlg( editFrame, editFrame );
64
65 dlg.ShowModal();
66 return 0;
67}
68
69
70DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* aPcbEditFrame, wxWindow* aParent ) :
71 DIALOG_GENDRILL_BASE( aParent )
72{
73 m_pcbEditFrame = aPcbEditFrame;
75 m_job = nullptr;
77
78 SetupStandardButtons( { { wxID_OK, _( "Generate Drill File" ) },
79 { wxID_APPLY, _( "Generate Map File" ) },
80 { wxID_CANCEL, _( "Close" ) } } );
81
82 m_buttonsSizer->Layout();
83
84 SetReturnCode( 1 );
85 initDialog();
86 GetSizer()->SetSizeHints( this );
87}
88
89
90
92 wxWindow* aParent ) :
93 DIALOG_GENDRILL_BASE( aParent )
94{
95 m_pcbEditFrame = aPcbEditFrame;
97 m_job = aJob;
98
99 // hide ui elements that dont belong for job config
100 m_buttonReport->Hide();
101 bMainSizer->Remove( bMsgSizer );
102 m_messagesBox->Hide();
103
104 m_sdbSizerApply->Hide();
105 SetupStandardButtons( { { wxID_OK, _( "Save" ) }, { wxID_CANCEL, _( "Cancel" ) } } );
106 m_buttonsSizer->Layout();
107
108 SetReturnCode( 1 );
109
110 GetSizer()->SetSizeHints( this );
111}
112
113
114// Static members of DIALOG_GENDRILL
115int DIALOG_GENDRILL::m_UnitDrillIsInch = false; // Only for Excellon format
117bool DIALOG_GENDRILL::m_MinimalHeader = false; // Only for Excellon format
118bool DIALOG_GENDRILL::m_Mirror = false; // Only for Excellon format
119bool DIALOG_GENDRILL::m_Merge_PTH_NPTH = false; // Only for Excellon format
120int DIALOG_GENDRILL::m_mapFileType = 4; // The last choice in m_Choice_Drill_Map
122bool DIALOG_GENDRILL::m_UseRouteModeForOvalHoles = true; // Use G00 route mode to "drill" oval holes
123
125{
126}
127
128
130{
131 return true;
132}
133
134
136{
137 initDialog();
138 return true;
139}
140
141
143{
144 if( !m_job )
145 {
146 auto cfg = m_pcbEditFrame->GetPcbNewSettings();
147
148 m_Merge_PTH_NPTH = cfg->m_GenDrill.merge_pth_npth;
149 m_MinimalHeader = cfg->m_GenDrill.minimal_header;
150 m_Mirror = cfg->m_GenDrill.mirror;
151 m_UnitDrillIsInch = cfg->m_GenDrill.unit_drill_is_inch;
152 m_UseRouteModeForOvalHoles = cfg->m_GenDrill.use_route_for_oval_holes;
153 m_drillFileType = cfg->m_GenDrill.drill_file_type;
154 m_mapFileType = cfg->m_GenDrill.map_file_type;
155 m_ZerosFormat = cfg->m_GenDrill.zeros_format;
156
157 // Ensure validity of m_mapFileType
158 if( m_mapFileType < 0 || m_mapFileType >= (int) m_Choice_Drill_Map->GetCount() )
159 m_mapFileType = m_Choice_Drill_Map->GetCount() - 1; // last item in list = default = PDF
160 }
161
163
165}
166
167
169{
170 if( !m_job )
171 {
172 m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
173
174 m_rbExcellon->SetValue( m_drillFileType == 0 );
175 m_rbGerberX2->SetValue( m_drillFileType == 1 );
176 m_Choice_Unit->SetSelection( m_UnitDrillIsInch ? 1 : 0 );
177 m_Choice_Zeros_Format->SetSelection( m_ZerosFormat );
179 m_Check_Minimal->SetValue( m_MinimalHeader );
180
181 m_Choice_Drill_Offset->SetSelection( m_drillOriginIsAuxAxis ? 1 : 0 );
182
183 m_Check_Mirror->SetValue( m_Mirror );
185 m_Choice_Drill_Map->SetSelection( m_mapFileType );
186 m_radioBoxOvalHoleMode->SetSelection( m_UseRouteModeForOvalHoles ? 0 : 1 );
187
188 // Output directory
190 }
191 else
192 {
193 m_browseButton->Hide();
195
199 m_Choice_Zeros_Format->SetSelection( static_cast<int>( m_job->m_zeroFormat ) );
202
204
207 m_Choice_Drill_Map->SetSelection( static_cast<int>( m_job->m_mapFormat ) );
208 m_radioBoxOvalHoleMode->SetSelection( m_job->m_excellonOvalDrillRoute ? 0 : 1 );
209 }
210
216
217 for( FOOTPRINT* footprint : m_board->Footprints() )
218 {
219 for( PAD* pad : footprint->Pads() )
220 {
221 if( pad->GetDrillShape() == PAD_DRILL_SHAPE::CIRCLE )
222 {
223 if( pad->GetDrillSize().x != 0 )
224 {
225 if( pad->GetAttribute() == PAD_ATTRIB::NPTH )
227 else
229 }
230 }
231 else
232 {
233 if( pad->GetDrillSize().x != 0 && pad->GetDrillSize().y != 0 )
234 {
235 if( pad->GetAttribute() == PAD_ATTRIB::NPTH )
237 else
239 }
240 }
241 }
242 }
243
244 for( PCB_TRACK* track : m_board->Tracks() )
245 {
246 const PCB_VIA *via = dynamic_cast<const PCB_VIA*>( track );
247
248 if( via )
249 {
250 switch( via->GetViaType() )
251 {
252 case VIATYPE::THROUGH: m_throughViasCount++; break;
253 case VIATYPE::MICROVIA: m_microViasCount++; break;
254 case VIATYPE::BLIND_BURIED: m_blindOrBuriedViasCount++; break;
255 default: break;
256 }
257 }
258 }
259
260 // Display hole counts:
261 m_PlatedPadsCountInfoMsg->SetLabel( wxString() << m_platedPadsHoleCount );
262 m_NotPlatedPadsCountInfoMsg->SetLabel( wxString() << m_notplatedPadsHoleCount );
263 m_ThroughViasInfoMsg->SetLabel( wxString() << m_throughViasCount );
264 m_MicroViasInfoMsg->SetLabel( wxString() << m_microViasCount );
265 m_BuriedViasInfoMsg->SetLabel( wxString() << m_blindOrBuriedViasCount );
266
267 wxCommandEvent dummy;
269}
270
271
272void DIALOG_GENDRILL::onFileFormatSelection( wxCommandEvent& event )
273{
274 bool enbl_Excellon = m_rbExcellon->GetValue();
275
276 m_drillFileType = enbl_Excellon ? 0 : 1;
277
278 m_Choice_Unit->Enable( enbl_Excellon );
279 m_Choice_Zeros_Format->Enable( enbl_Excellon );
280 m_Check_Mirror->Enable( enbl_Excellon );
281 m_Check_Minimal->Enable( enbl_Excellon );
282 m_Check_Merge_PTH_NPTH->Enable( enbl_Excellon );
283 m_radioBoxOvalHoleMode->Enable( enbl_Excellon );
284
285 if( enbl_Excellon )
286 {
288 }
289 else
290 {
291 m_staticTextPrecision->Enable( true );
292 m_staticTextPrecision->SetLabel( m_plotOpts.GetGerberPrecision() == 6 ? wxT( "4.6" )
293 : wxT( "4.5" ) );
294 }
295}
296
297
299{
301
302 auto cfg = m_pcbEditFrame->GetPcbNewSettings();
303
305 cfg->m_GenDrill.minimal_header = m_MinimalHeader;
306 cfg->m_GenDrill.mirror = m_Mirror;
307 cfg->m_GenDrill.unit_drill_is_inch = m_UnitDrillIsInch;
308 cfg->m_GenDrill.use_route_for_oval_holes = m_UseRouteModeForOvalHoles;
309 cfg->m_GenDrill.drill_file_type = m_drillFileType;
310 cfg->m_GenDrill.map_file_type = m_mapFileType;
311 cfg->m_GenDrill.zeros_format = m_ZerosFormat;
312}
313
314
315void DIALOG_GENDRILL::OnSelDrillUnitsSelected( wxCommandEvent& event )
316{
318}
319
320
321void DIALOG_GENDRILL::OnGenMapFile( wxCommandEvent& event )
322{
323 if( !m_job )
324 {
325 GenDrillAndMapFiles( false, true );
326 }
327}
328
329
330void DIALOG_GENDRILL::OnGenDrillFile( wxCommandEvent& event )
331{
332 if( !m_job )
333 {
334 GenDrillAndMapFiles( true, false );
335 }
336 else
337 {
341 m_job->m_drillUnits = m_Choice_Unit->GetSelection() == 0
347 m_job->m_excellonMirrorY = m_Check_Mirror->IsChecked();
349 m_job->m_mapFormat = static_cast<JOB_EXPORT_PCB_DRILL::MAP_FORMAT>( m_Choice_Drill_Map->GetSelection() );
351 Close();
352 }
353}
354
355
356void DIALOG_GENDRILL::OnSelZerosFmtSelected( wxCommandEvent& event )
357{
359}
360
361
363{
364 if( m_Choice_Unit->GetSelection()== 1 )
365 {
366 // Units = inches
368 }
369 else
370 {
371 // metric options
373 }
374
376 m_staticTextPrecision->Enable( false );
377 else
378 m_staticTextPrecision->Enable( true );
379}
380
381
383{
384 // Build the absolute path of current output directory to preselect it in the file browser.
385 wxString path = ExpandEnvVarSubstitutions( m_outputDirectoryName->GetValue(), &Prj() );
386 path = Prj().AbsolutePath( path );
387
388 wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
389
390 if( dirDialog.ShowModal() == wxID_CANCEL )
391 return;
392
393 wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
394 wxFileName fn( Prj().AbsolutePath( m_board->GetFileName() ) );
395 wxString defaultPath = fn.GetPathWithSep();
396 wxString msg;
397 msg.Printf( _( "Do you want to use a path relative to\n'%s'?" ), defaultPath );
398
399 wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
400 wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
401
402 if( dialog.ShowModal() == wxID_YES )
403 {
404 if( !dirName.MakeRelativeTo( defaultPath ) )
405 {
406 wxMessageBox( _( "Cannot make path relative (target volume different from board "
407 "file volume)!" ),
408 _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
409 }
410 }
411
412 m_outputDirectoryName->SetValue( dirName.GetFullPath() );
413}
414
415
417{
418 // Set output directory and replace backslashes with forward ones
419 wxString dirStr;
420 dirStr = m_outputDirectoryName->GetValue();
421 dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
423 m_drillOriginIsAuxAxis = m_Choice_Drill_Offset->GetSelection() == 1;
425
426 m_mapFileType = m_Choice_Drill_Map->GetSelection();
427
428 m_UnitDrillIsInch = (m_Choice_Unit->GetSelection() == 0) ? false : true;
429 m_MinimalHeader = m_Check_Minimal->IsChecked();
430 m_Mirror = m_Check_Mirror->IsChecked();
432 m_ZerosFormat = m_Choice_Zeros_Format->GetSelection();
434
435 if( m_Choice_Drill_Offset->GetSelection() == 0 )
436 m_DrillFileOffset = VECTOR2I( 0, 0 );
437 else
439
442 else
444
446 {
449 }
450}
451
452
453void DIALOG_GENDRILL::GenDrillAndMapFiles( bool aGenDrill, bool aGenMap )
454{
455 UpdateConfig(); // set params and Save drill options
456
459
460 const PLOT_FORMAT filefmt[] = {
461 // Keep these format ids in the same order than m_Choice_Drill_Map choices
462 PLOT_FORMAT::POST,
463 PLOT_FORMAT::GERBER, // Only X2 format because we need the .FileFunction attribute
464 PLOT_FORMAT::DXF,
465 PLOT_FORMAT::SVG,
466 PLOT_FORMAT::PDF
467 };
468
469 unsigned choice = (unsigned) m_Choice_Drill_Map->GetSelection();
470
471 if( choice >= arrayDim( filefmt ) )
472 choice = arrayDim( filefmt )-1; // Last choice = PDF
473
474 // Create output directory if it does not exist (also transform it in absolute form).
475 // Bail if it fails.
476
477 std::function<bool( wxString* )> textResolver =
478 [&]( wxString* token ) -> bool
479 {
480 // Handles m_board->GetTitleBlock() *and* m_board->GetProject()
481 return m_board->ResolveTextVar( token, 0 );
482 };
483
485 path = ExpandTextVars( path, &textResolver );
486 path = ExpandEnvVarSubstitutions( path, nullptr );
487
488 wxFileName outputDir = wxFileName::DirName( path );
489 wxString boardFilename = m_board->GetFileName();
490
491 if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
492 {
493 wxString msg;
494 msg.Printf( _( "Could not write drill and/or map files to folder '%s'." ),
495 outputDir.GetPath() );
496 DisplayError( this, msg );
497 return;
498 }
499
500 if( m_drillFileType == 0 )
501 {
502 EXCELLON_WRITER excellonWriter( m_board );
507 excellonWriter.SetMapFileFormat( filefmt[choice] );
508
509 excellonWriter.CreateDrillandMapFilesSet( outputDir.GetFullPath(), aGenDrill, aGenMap,
510 &reporter );
511 }
512 else
513 {
514 GERBER_WRITER gerberWriter( m_board );
515 // Set gerber precision: only 5 or 6 digits for mantissa are allowed
516 // (SetFormat() accept 5 or 6, and any other value set the precision to 5)
517 // the integer part precision is always 4, and units always mm
518 gerberWriter.SetFormat( m_plotOpts.GetGerberPrecision() );
519 gerberWriter.SetOptions( m_DrillFileOffset );
520 gerberWriter.SetMapFileFormat( filefmt[choice] );
521
522 gerberWriter.CreateDrillandMapFilesSet( outputDir.GetFullPath(), aGenDrill, aGenMap,
523 &reporter );
524 }
525}
526
527
528void DIALOG_GENDRILL::OnGenReportFile( wxCommandEvent& event )
529{
530 UpdateConfig(); // set params and Save drill options
531
532 wxFileName fn = m_board->GetFileName();
533
534 fn.SetName( fn.GetName() + wxT( "-drl" ) );
535 fn.SetExt( FILEEXT::ReportFileExtension );
536
537 wxString defaultPath = ExpandEnvVarSubstitutions( m_plotOpts.GetOutputDirectory(), &Prj() );
538 defaultPath = Prj().AbsolutePath( defaultPath );
539
540 if( defaultPath.IsEmpty() )
541 defaultPath = PATHS::GetDefaultUserProjectsPath();
542
543 wxFileDialog dlg( this, _( "Save Drill Report File" ), defaultPath, fn.GetFullName(),
544 FILEEXT::ReportFileWildcard(), wxFD_SAVE );
545
546 if( dlg.ShowModal() == wxID_CANCEL )
547 return;
548
549 bool success;
550
551 // Info is slightly different between Excellon and Gerber
552 // (file ext, Merge PTH/NPTH option)
553 if( m_drillFileType == 0 )
554 {
555 EXCELLON_WRITER excellonWriter( m_board );
556 excellonWriter.SetMergeOption( m_Merge_PTH_NPTH );
557 success = excellonWriter.GenDrillReportFile( dlg.GetPath() );
558 }
559 else
560 {
561 GERBER_WRITER gerberWriter( m_board );
562 success = gerberWriter.GenDrillReportFile( dlg.GetPath() );
563 }
564
565 wxString msg;
566
567 if( ! success )
568 {
569 msg.Printf( _( "Failed to create file '%s'." ), dlg.GetPath() );
570 m_messagesBox->AppendText( msg );
571 }
572 else
573 {
574 msg.Printf( _( "Report file '%s' created." ), dlg.GetPath() );
575 m_messagesBox->AppendText( msg );
576 }
577}
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
const VECTOR2I & GetAuxOrigin()
int GenerateDrillFiles(const TOOL_EVENT &aEvent)
void SetPlotOptions(const PCB_PLOT_PARAMS &aOptions)
Definition: board.h:693
bool ResolveTextVar(wxString *token, int aDepth) const
Definition: board.cpp:433
const FOOTPRINTS & Footprints() const
Definition: board.h:331
const TRACKS & Tracks() const
Definition: board.h:329
const wxString & GetFileName() const
Definition: board.h:327
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:692
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:895
Class DIALOG_GENDRILL_BASE.
wxRadioButton * m_rbExcellon
wxRadioBox * m_Choice_Drill_Offset
wxStaticText * m_staticTextPrecision
STD_BITMAP_BUTTON * m_browseButton
wxStaticBoxSizer * bMsgSizer
wxStaticText * m_MicroViasInfoMsg
wxRadioButton * m_rbGerberX2
wxStaticText * m_PlatedPadsCountInfoMsg
wxCheckBox * m_Check_Merge_PTH_NPTH
wxStaticText * m_ThroughViasInfoMsg
wxStaticText * m_BuriedViasInfoMsg
wxStaticText * m_NotPlatedPadsCountInfoMsg
wxRadioBox * m_radioBoxOvalHoleMode
wxTextCtrl * m_outputDirectoryName
wxRadioBox * m_Choice_Zeros_Format
PCB_PLOT_PARAMS m_plotOpts
VECTOR2I m_DrillFileOffset
void onFileFormatSelection(wxCommandEvent &event) override
void OnSelDrillUnitsSelected(wxCommandEvent &event) override
bool TransferDataFromWindow() override
static bool m_MinimalHeader
static bool m_Merge_PTH_NPTH
PCB_EDIT_FRAME * m_pcbEditFrame
static bool m_Mirror
DIALOG_GENDRILL(PCB_EDIT_FRAME *aPcbEditFrame, wxWindow *aParent)
bool TransferDataToWindow() override
void OnGenReportFile(wxCommandEvent &event) override
void GenDrillAndMapFiles(bool aGenDrill, bool aGenMap)
Call the functions to create EXCELLON drill files and/or drill map files.
void OnSelZerosFmtSelected(wxCommandEvent &event) override
void OnGenDrillFile(wxCommandEvent &event) override
static int m_UnitDrillIsInch
void UpdateDrillParams()
Update board drill/plot parameters.
static bool m_UseRouteModeForOvalHoles
static int m_ZerosFormat
void OnGenMapFile(wxCommandEvent &event) override
void OnOutputDirectoryBrowseClicked(wxCommandEvent &event) override
static int m_mapFileType
DRILL_PRECISION m_Precision
static int m_drillFileType
JOB_EXPORT_PCB_DRILL * m_job
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowModal() override
Helper to handle drill precision format in excellon files.
virtual void ClearMsgPanel()
Clear all messages from the message panel.
Create Excellon drill, drill map, and drill report files.
void SetFormat(bool aMetric, ZEROS_FMT aZerosFmt=DECIMAL_FORMAT, int aLeftDigits=0, int aRightDigits=0)
Initialize internal parameters to match the given format.
bool CreateDrillandMapFilesSet(const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER *aReporter=nullptr)
Create the full set of Excellon drill file for the board.
void SetOptions(bool aMirror, bool aMinimalHeader, const VECTOR2I &aOffset, bool aMerge_PTH_NPTH)
Initialize internal parameters to match drill options.
void SetRouteModeForOvalHoles(bool aUseRouteModeForOvalHoles)
void SetMapFileFormat(PLOT_FORMAT aMapFmt)
Initialize the format for the drill map file.
bool GenDrillReportFile(const wxString &aFullFileName)
Create a plain text report file giving a list of drill values and drill count for through holes,...
void SetMergeOption(bool aMerge)
Set the option to make separate drill files for PTH and NPTH.
Used to create Gerber drill files.
bool CreateDrillandMapFilesSet(const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER *aReporter=nullptr)
Create the full set of Excellon drill file for the board filenames are computed from the board name,...
void SetOptions(const VECTOR2I &aOffset)
Initialize internal parameters to match drill options.
void SetFormat(int aRightDigits=6)
Initialize internal parameters to match the given format.
void SetOutputPath(const wxString &aPath)
Definition: job.cpp:129
wxString GetOutputPath() const
Definition: job.h:119
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Definition: pad.h:54
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:140
DIALOG_GENERATE_DRILL m_GenDrill
virtual const PCB_PLOT_PARAMS & GetPlotSettings() const
Return the PCB_PLOT_PARAMS for the BOARD owned by this frame.
PCBNEW_SETTINGS * GetPcbNewSettings() const
BOARD * GetBoard() const
The main frame for Pcbnew.
void OnModify() override
Must be called after a board change to set the modified flag.
bool GetUseAuxOrigin() const
void SetOutputDirectory(const wxString &aDir)
wxString GetOutputDirectory() const
int GetGerberPrecision() const
bool IsSameAs(const PCB_PLOT_PARAMS &aPcbPlotParams) const
Compare current settings to aPcbPlotParams, including not saved parameters in brd file.
void SetUseAuxOrigin(bool aAux)
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition: project.cpp:359
void SetBitmap(const wxBitmapBundle &aBmp)
Generic, UI-independent tool event.
Definition: tool_event.h:167
A wrapper for reporting to a wxTextCtrl object.
Definition: reporter.h:145
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:348
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
Definition: common.cpp:59
bool EnsureFileDirectoryExists(wxFileName *aTargetFullFileName, const wxString &aBaseFilename, REPORTER *aReporter)
Make aTargetFullFileName absolute and create the path of this file if it doesn't yet exist.
Definition: common.cpp:369
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
This file is part of the common library.
static DRILL_PRECISION precisionListForInches(2, 4)
static DRILL_PRECISION precisionListForMetric(3, 3)
#define _(s)
Classes used in drill files, map files and report files generation.
Classes used in drill files, map files and report files generation.
static const std::string ReportFileExtension
static wxString ReportFileWildcard()
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:65
std::vector< FAB_LAYER_COLOR > dummy
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691
Definition of file extensions used in Kicad.