KiCad PCB EDA Suite
dialog_plot_schematic.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-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2010 Lorenzo Marcantonio
6 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
7 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <bitmaps.h>
28#include <common.h> // For ExpandEnvVarSubstitutions
32#include <eeschema_settings.h>
33#include <kiface_base.h>
34#include <locale_io.h>
38#include <reporter.h>
39#include <trace_helpers.h>
42#include <wx_filename.h>
43
44#include <sch_edit_frame.h>
45#include <sch_painter.h>
46#include <schematic.h>
47#include <sch_screen.h>
48
49#include <wx/dirdlg.h>
50#include <wx/msgdlg.h>
52#include <wx/log.h>
53
54
55// static members (static to remember last state):
58
59
62 m_parent( parent ),
63 m_plotFormat( PLOT_FORMAT::UNDEFINED ),
64 m_HPGLPenSize( 1.0 ),
65 m_defaultLineWidth( parent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits ),
66 m_penWidth( parent, m_penWidthLabel, m_penWidthCtrl, m_penWidthUnits )
67{
68 m_configChanged = false;
69
71
72 m_MessagesBox->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) );
73
74 SetupStandardButtons( { { wxID_OK, _( "Plot All Pages" ) },
75 { wxID_APPLY, _( "Plot Current Page" ) },
76 { wxID_CANCEL, _( "Close" ) } } );
77
78 initDlg();
79
80 // Now all widgets have the size fixed, call FinishDialogSettings
82}
83
84
86{
87 auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
88 wxASSERT( cfg );
89
90 if( cfg )
91 {
93 {
94 int idx = m_colorTheme->Append( settings->GetName(), static_cast<void*>( settings ) );
95
96 if( settings->GetFilename() == cfg->m_PlotPanel.color_theme )
97 m_colorTheme->SetSelection( idx );
98 }
99
100 m_colorTheme->Enable( cfg->m_PlotPanel.color );
101
102 m_plotBackgroundColor->Enable( cfg->m_PlotPanel.color );
103 m_plotBackgroundColor->SetValue( cfg->m_PlotPanel.background_color );
104
105 // Set color or B&W plot option
106 setModeColor( cfg->m_PlotPanel.color );
107
108 // Set plot or not frame reference option
109 setPlotDrawingSheet( cfg->m_PlotPanel.frame_reference );
110
111 setOpenFileAfterPlot( cfg->m_PlotPanel.open_file_after_plot );
112
113 // HPGL plot origin and unit system configuration
114 m_plotOriginOpt->SetSelection( cfg->m_PlotPanel.hpgl_origin );
115
116 m_HPGLPaperSizeSelect = static_cast<HPGL_PAGE_SIZE>( cfg->m_PlotPanel.hpgl_paper_size );
117
118 // HPGL Pen Size is stored in mm in config
119 m_HPGLPenSize = cfg->m_PlotPanel.hpgl_pen_size * schIUScale.IU_PER_MM;
120
121 // Switch to the last save plot format
122 PLOT_FORMAT fmt = static_cast<PLOT_FORMAT>( cfg->m_PlotPanel.format );
123
124 switch( fmt )
125 {
126 default:
127 case PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 0 ); break;
128 case PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 1 ); break;
129 case PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
130 case PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
131 case PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
132 }
133
134 if( fmt == PLOT_FORMAT::DXF || fmt == PLOT_FORMAT::HPGL )
135 m_plotBackgroundColor->Disable();
136
137 // Set the default line width (pen width which should be used for
138 // items that do not have a pen size defined (like frame ref)
139 // the default line width is stored in mils in config
140 m_defaultLineWidth.SetValue( schIUScale.MilsToIU( cfg->m_Drawing.default_line_thickness ) );
141 }
142
143 // Initialize HPGL specific widgets
145
146 // Plot directory
148 wxString path = settings.m_PlotDirectoryName;
149#ifdef __WINDOWS__
150 path.Replace( '/', '\\' );
151#endif
152 m_outputDirectoryName->SetValue( path );
153}
154
155
161{
162 // Build the absolute path of current output directory to preselect it in the file browser.
163 wxString path = ExpandEnvVarSubstitutions( m_outputDirectoryName->GetValue(), &Prj() );
164
165 // When editing a schematic that is not part of a project in the stand alone mode, the
166 // project path is not defined so point to the users document path to save the plot files.
167 if( Prj().IsNullProject() )
168 {
170 }
171 else
172 {
173 // Build the absolute path of current output directory to preselect it in the file browser.
175 path = Prj().AbsolutePath( path );
176 }
177
178 wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
179
180 if( dirDialog.ShowModal() == wxID_CANCEL )
181 return;
182
183 wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
184
185 wxFileName fn( Prj().AbsolutePath( m_parent->Schematic().Root().GetFileName() ) );
186 wxString defaultPath = fn.GetPathWithSep();
187 wxString msg;
188 wxFileName relPathTest; // Used to test if we can make the path relative
189
190 relPathTest.Assign( dirDialog.GetPath() );
191
192 // Test if making the path relative is possible before asking the user if they want to do it
193 if( relPathTest.MakeRelativeTo( defaultPath ) )
194 {
195 msg.Printf( _( "Do you want to use a path relative to\n'%s'?" ), defaultPath );
196
197 wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
198 wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
199
200 if( dialog.ShowModal() == wxID_YES )
201 dirName.MakeRelativeTo( defaultPath );
202 }
203
204 m_outputDirectoryName->SetValue( dirName.GetFullPath() );
205}
206
207
209{
210 switch( m_plotFormatOpt->GetSelection() )
211 {
212 default:
213 case 0: return PLOT_FORMAT::POST;
214 case 1: return PLOT_FORMAT::PDF;
215 case 2: return PLOT_FORMAT::SVG;
216 case 3: return PLOT_FORMAT::DXF;
217 case 4: return PLOT_FORMAT::HPGL;
218 }
219}
220
221
222void DIALOG_PLOT_SCHEMATIC::OnPageSizeSelected( wxCommandEvent& event )
223{
225 m_HPGLPaperSizeSelect = static_cast<HPGL_PAGE_SIZE>( m_paperSizeOption->GetSelection() );
226 else
227 m_pageSizeSelect = m_paperSizeOption->GetSelection();
228}
229
230
231void DIALOG_PLOT_SCHEMATIC::OnUpdateUI( wxUpdateUIEvent& event )
232{
234
235 if( fmt != m_plotFormat )
236 {
237 m_plotFormat = fmt;
238
239 wxArrayString paperSizes;
240 paperSizes.push_back( _( "Schematic size" ) );
241
242 int selection;
243
244 if( fmt == PLOT_FORMAT::HPGL )
245 {
246 paperSizes.push_back( _( "A5" ) );
247 paperSizes.push_back( _( "A4" ) );
248 paperSizes.push_back( _( "A3" ) );
249 paperSizes.push_back( _( "A2" ) );
250 paperSizes.push_back( _( "A1" ) );
251 paperSizes.push_back( _( "A0" ) );
252 paperSizes.push_back( _( "A" ) );
253 paperSizes.push_back( _( "B" ) );
254 paperSizes.push_back( _( "C" ) );
255 paperSizes.push_back( _( "D" ) );
256 paperSizes.push_back( _( "E" ) );
257
258 selection = static_cast<int>( m_HPGLPaperSizeSelect );
259 }
260 else
261 {
262 paperSizes.push_back( _( "A4" ) );
263 paperSizes.push_back( _( "A" ) );
264
265 selection = m_pageSizeSelect;
266 }
267
268 m_openFileAfterPlot->Enable( fmt == PLOT_FORMAT::PDF );
269
270 m_paperSizeOption->Set( paperSizes );
271 m_paperSizeOption->SetSelection( selection );
272
274 fmt == PLOT_FORMAT::POST || fmt == PLOT_FORMAT::PDF || fmt == PLOT_FORMAT::SVG );
275
276 m_plotOriginTitle->Enable( fmt == PLOT_FORMAT::HPGL );
277 m_plotOriginOpt->Enable( fmt == PLOT_FORMAT::HPGL );
279
280 m_plotBackgroundColor->Enable(
281 fmt == PLOT_FORMAT::POST || fmt == PLOT_FORMAT::PDF || fmt == PLOT_FORMAT::SVG );
282
283 m_colorTheme->Enable( fmt != PLOT_FORMAT::HPGL );
284 m_ModeColorOption->Enable( fmt != PLOT_FORMAT::HPGL );
285 }
286}
287
288
290{
292
293 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
294 wxASSERT( cfg );
295
297
298 if( cfg )
299 {
302 cfg->m_PlotPanel.color_theme = colors->GetFilename();
304 cfg->m_PlotPanel.format = static_cast<int>( GetPlotFileFormat() );
305 cfg->m_PlotPanel.hpgl_origin = m_plotOriginOpt->GetSelection();
306 cfg->m_PlotPanel.hpgl_paper_size = static_cast<int>( m_HPGLPaperSizeSelect );
308
309 // HPGL Pen Size is stored in mm in config
311
312 aSettings->SetDefaultFont( cfg->m_Appearance.default_font );
313 }
314
315 aSettings->LoadColors( colors );
316 aSettings->SetMinPenWidth( (int) m_defaultLineWidth.GetValue() );
317
318 if( m_plotBackgroundColor->GetValue() )
320 else
321 aSettings->SetBackgroundColor( COLOR4D::UNSPECIFIED );
322
323 // Plot directory
324 wxString path = m_outputDirectoryName->GetValue();
325 path.Replace( '\\', '/' );
326
328
329 if( settings.m_PlotDirectoryName != path )
330 m_configChanged = true;
331
332 settings.m_PlotDirectoryName = path;
333}
334
335
337{
338 int selection = m_colorTheme->GetSelection();
339
340 if( selection < 0 )
341 return m_parent->GetSettingsManager()->GetColorSettings( "_builtin_default" );
342
343 return static_cast<COLOR_SETTINGS*>( m_colorTheme->GetClientData( selection ) );
344}
345
346
347void DIALOG_PLOT_SCHEMATIC::OnPlotCurrent( wxCommandEvent& event )
348{
349 plotSchematic( false );
350}
351
352
353void DIALOG_PLOT_SCHEMATIC::OnPlotAll( wxCommandEvent& event )
354{
355 plotSchematic( true );
356}
357
358
360{
361 wxBusyCursor dummy;
362
364
365 getPlotOptions( &renderSettings );
366
367 std::unique_ptr<SCH_PLOTTER> schPlotter = std::make_unique<SCH_PLOTTER>( m_parent );
368
370
371 SCH_PLOT_SETTINGS plotSettings;
373 plotSettings.m_plotAll = aPlotAll;
374 plotSettings.m_blackAndWhite = !getModeColor();
375 plotSettings.m_useBackgroundColor = m_plotBackgroundColor->GetValue();
376 plotSettings.m_theme = colors->GetFilename();
377 plotSettings.m_HPGLPenSize = m_HPGLPenSize;
378 plotSettings.m_HPGLPaperSizeSelect = static_cast<HPGL_PAGE_SIZE>( m_HPGLPaperSizeSelect );
379 plotSettings.m_HPGLPlotOrigin =
380 static_cast<HPGL_PLOT_ORIGIN_AND_UNITS>( m_plotOriginOpt->GetSelection() );
381 plotSettings.m_outputDirectory = getOutputPath();
382 plotSettings.m_pageSizeSelect = m_pageSizeSelect;
383
384
385 schPlotter->Plot( GetPlotFileFormat(), plotSettings, &renderSettings,
387
389 wxLaunchDefaultApplication( schPlotter->GetLastOutputFilePath() );
390}
391
392
394{
396
397 if( m_HPGLPenSize > schIUScale.mmToIU( 2 ) )
399
400 if( m_HPGLPenSize < schIUScale.mmToIU( 0.01 ) )
402}
403
404
406{
407 wxString msg;
408 wxString extMsg;
409 wxFileName fn;
410
411 extMsg.Printf( _( "Falling back to user path '%s'." ), KIPLATFORM::ENV::GetDocumentsPath() );
412
413 // Build the absolute path of current output directory to preselect it in the file browser.
414 std::function<bool( wxString* )> textResolver =
415 [&]( wxString* token ) -> bool
416 {
417 return m_parent->Schematic().ResolveTextVar( token, 0 );
418 };
419
420 wxString path = m_outputDirectoryName->GetValue();
421 path = ExpandTextVars( path, &textResolver );
423
424 fn.SetPath( path );
425
426 // If the contents of the path edit control results in an absolute path, return it as is.
427 if( fn.IsAbsolute() )
428 return path;
429
430 // When editing a schematic that is not part of a project in the stand alone mode, the
431 // project path is not defined.
432 if( Prj().IsNullProject() )
433 {
435
436 if( screen && !screen->GetFileName().IsEmpty() )
437 {
438 fn = screen->GetFileName();
439 msg.Printf( _( "Cannot normalize path '%s%s'." ), fn.GetPathWithSep(), path );
440 fn.SetPath( fn.GetPathWithSep() + path );
441
442 // Normalize always returns true for a non-empty file name so clear the file name
443 // and extension so that only the path is normalized.
444 fn.SetName( wxEmptyString );
445 fn.SetExt( wxEmptyString );
446
447 if( fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) )
448 {
449 path = fn.GetPath();
450 }
451 else
452 {
453 wxMessageDialog dlg( this, msg, _( "Warning" ), wxOK | wxCENTER | wxRESIZE_BORDER
454 | wxICON_EXCLAMATION | wxSTAY_ON_TOP );
455
456 dlg.SetExtendedMessage( extMsg );
457 dlg.ShowModal();
458
460 }
461 }
462 else
463 {
464 msg = _( "No project or path defined for the current schematic." );
465
466 wxMessageDialog dlg( this, msg, _( "Warning" ), wxOK | wxCENTER | wxRESIZE_BORDER
467 | wxICON_EXCLAMATION | wxSTAY_ON_TOP );
468 dlg.SetExtendedMessage( extMsg );
469 dlg.ShowModal();
470
471 // Always fall back to user's document path if no other absolute path can be normalized.
473 }
474 }
475 else
476 {
477 msg.Printf( _( "Cannot normalize path '%s%s'." ), Prj().GetProjectPath(), path );
478
479 // Build the absolute path of current output directory and the project path.
480 fn.SetPath( Prj().GetProjectPath() + path );
481
482 if( fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) )
483 {
484 path = fn.GetPath();
485 }
486 else
487 {
488 wxMessageDialog dlg( this, msg, _( "Warning" ),
489 wxOK | wxCENTER | wxRESIZE_BORDER | wxICON_EXCLAMATION |
490 wxSTAY_ON_TOP );
491
492 dlg.SetExtendedMessage( extMsg );
493 dlg.ShowModal();
494
496 }
497 }
498
499 return path;
500}
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:105
@ small_folder
Color settings are a bit different than most of the settings objects in that there can be more than o...
COLOR4D GetColor(int aLayer) const
Class DIALOG_PLOT_SCHEMATIC_BASE.
WX_HTML_REPORT_PANEL * m_MessagesBox
DIALOG_PLOT_SCHEMATIC(SCH_EDIT_FRAME *parent)
void OnPageSizeSelected(wxCommandEvent &event) override
void OnPlotAll(wxCommandEvent &event) override
static HPGL_PAGE_SIZE m_HPGLPaperSizeSelect
void OnOutputDirectoryBrowseClicked(wxCommandEvent &event) override
Set the m_outputDirectoryName variable to the selected directory from directory dialog.
void OnPlotCurrent(wxCommandEvent &event) override
void setModeColor(bool aColor)
void setPlotDrawingSheet(bool aPlot)
void setOpenFileAfterPlot(bool aOpenFileAfterPlot)
void getPlotOptions(RENDER_SETTINGS *aSettings)
COLOR_SETTINGS * getColorSettings()
void plotSchematic(bool aPlotAll)
void OnUpdateUI(wxUpdateUIEvent &event) override
wxString getOutputPath()
Determine the best absolute path to plot files given the contents of the path edit control.
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
SETTINGS_MANAGER * GetSettingsManager() const
wxString GetFilename() const
Definition: json_settings.h:73
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:93
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
virtual void LoadColors(const COLOR_SETTINGS *aSettings)
void SetDefaultFont(const wxString &aFont)
virtual void SetBackgroundColor(const COLOR4D &aColor)=0
Set the background color.
void SetMinPenWidth(int aWidth)
Store schematic specific render settings.
Definition: sch_painter.h:71
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
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:305
These settings were stored in SCH_BASE_FRAME previously.
bool ResolveTextVar(wxString *token, int aDepth) const
Definition: schematic.cpp:125
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:178
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
Definition: schematic.cpp:119
SCH_SHEET & Root() const
Definition: schematic.h:91
KIGFX::SCH_RENDER_SETTINGS * GetRenderSettings()
Schematic editor (Eeschema) main window.
SCHEMATIC & Schematic() const
const wxString & GetFileName() const
Definition: sch_screen.h:144
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:302
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves a color settings object that applications can read colors from.
std::vector< COLOR_SETTINGS * > GetColorSettingsList()
void SetBitmap(const wxBitmap &aBmp)
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void SetFileName(const wxString &aReportFileName)
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:299
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
Definition: common.cpp:58
The common library.
#define _(s)
@ LAYER_SCHEMATIC_BACKGROUND
Definition: layer_ids.h:376
wxString GetDocumentsPath()
Retrieves the operating system specific path for a user's documents.
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:70
Plotting engine (DXF)
Plotting engine (HPGL)
Plotting engines similar to ps (PostScript, Gerber, svg)
@ PAGE_SIZE_AUTO
Definition: sch_plotter.h:56
HPGL_PAGE_SIZE
Definition: sch_plotter.h:63
HPGL_PLOT_ORIGIN_AND_UNITS
Definition: sch_plotter.h:46
std::vector< FAB_LAYER_COLOR > dummy
const double IU_PER_MM
Definition: base_units.h:77
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
double m_HPGLPenSize
Definition: sch_plotter.h:86
wxString m_theme
Definition: sch_plotter.h:88
HPGL_PAGE_SIZE m_HPGLPaperSizeSelect
Definition: sch_plotter.h:87
HPGL_PLOT_ORIGIN_AND_UNITS m_HPGLPlotOrigin
Definition: sch_plotter.h:93
bool m_useBackgroundColor
Definition: sch_plotter.h:85
wxString m_outputDirectory
Definition: sch_plotter.h:90
wxLogTrace helper definitions.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:38