KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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
70 m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
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{
224 if( GetPlotFileFormat() == PLOT_FORMAT::HPGL )
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 );
278 m_penWidth.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 {
344 }
345
346 return static_cast<COLOR_SETTINGS*>( m_colorTheme->GetClientData( selection ) );
347}
348
349
350void DIALOG_PLOT_SCHEMATIC::OnPlotCurrent( wxCommandEvent& event )
351{
352 plotSchematic( false );
353}
354
355
356void DIALOG_PLOT_SCHEMATIC::OnPlotAll( wxCommandEvent& event )
357{
358 plotSchematic( true );
359}
360
361
363{
364 wxBusyCursor dummy;
365
367
368 getPlotOptions( &renderSettings );
369
370 std::unique_ptr<SCH_PLOTTER> schPlotter = std::make_unique<SCH_PLOTTER>( m_parent );
371
373
374 SCH_PLOT_SETTINGS plotSettings;
376 plotSettings.m_plotAll = aPlotAll;
377 plotSettings.m_blackAndWhite = !getModeColor();
378 plotSettings.m_useBackgroundColor = m_plotBackgroundColor->GetValue();
379 plotSettings.m_theme = colors->GetFilename();
380 plotSettings.m_HPGLPenSize = m_HPGLPenSize;
381 plotSettings.m_HPGLPaperSizeSelect = static_cast<HPGL_PAGE_SIZE>( m_HPGLPaperSizeSelect );
382 plotSettings.m_HPGLPlotOrigin =
383 static_cast<HPGL_PLOT_ORIGIN_AND_UNITS>( m_plotOriginOpt->GetSelection() );
384 plotSettings.m_outputDirectory = getOutputPath();
385 plotSettings.m_pageSizeSelect = m_pageSizeSelect;
386
387
388 schPlotter->Plot( GetPlotFileFormat(), plotSettings, &renderSettings,
390
391 if( GetPlotFileFormat() == PLOT_FORMAT::PDF && getOpenFileAfterPlot() )
392 wxLaunchDefaultApplication( schPlotter->GetLastOutputFilePath() );
393}
394
395
397{
399
400 if( m_HPGLPenSize > schIUScale.mmToIU( 2 ) )
402
403 if( m_HPGLPenSize < schIUScale.mmToIU( 0.01 ) )
405}
406
407
409{
410 wxString msg;
411 wxString extMsg;
412 wxFileName fn;
413
414 extMsg.Printf( _( "Falling back to user path '%s'." ), KIPLATFORM::ENV::GetDocumentsPath() );
415
416 // Build the absolute path of current output directory to preselect it in the file browser.
417 std::function<bool( wxString* )> textResolver =
418 [&]( wxString* token ) -> bool
419 {
420 return m_parent->Schematic().ResolveTextVar( token, 0 );
421 };
422
423 wxString path = m_outputDirectoryName->GetValue();
424 path = ExpandTextVars( path, &textResolver );
426
427 fn.SetPath( path );
428
429 // If the contents of the path edit control results in an absolute path, return it as is.
430 if( fn.IsAbsolute() )
431 return path;
432
433 // When editing a schematic that is not part of a project in the stand alone mode, the
434 // project path is not defined.
435 if( Prj().IsNullProject() )
436 {
438
439 if( screen && !screen->GetFileName().IsEmpty() )
440 {
441 fn = screen->GetFileName();
442 msg.Printf( _( "Cannot normalize path '%s%s'." ), fn.GetPathWithSep(), path );
443 fn.SetPath( fn.GetPathWithSep() + path );
444
445 // Normalize always returns true for a non-empty file name so clear the file name
446 // and extension so that only the path is normalized.
447 fn.SetName( wxEmptyString );
448 fn.SetExt( wxEmptyString );
449
450 if( fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) )
451 {
452 path = fn.GetPath();
453 }
454 else
455 {
456 wxMessageDialog dlg( this, msg, _( "Warning" ), wxOK | wxCENTER | wxRESIZE_BORDER
457 | wxICON_EXCLAMATION | wxSTAY_ON_TOP );
458
459 dlg.SetExtendedMessage( extMsg );
460 dlg.ShowModal();
461
463 }
464 }
465 else
466 {
467 msg = _( "No project or path defined for the current schematic." );
468
469 wxMessageDialog dlg( this, msg, _( "Warning" ), wxOK | wxCENTER | wxRESIZE_BORDER
470 | wxICON_EXCLAMATION | wxSTAY_ON_TOP );
471 dlg.SetExtendedMessage( extMsg );
472 dlg.ShowModal();
473
474 // Always fall back to user's document path if no other absolute path can be normalized.
476 }
477 }
478 else
479 {
480 msg.Printf( _( "Cannot normalize path '%s%s'." ), Prj().GetProjectPath(), path );
481
482 // Build the absolute path of current output directory and the project path.
483 fn.SetPath( Prj().GetProjectPath() + path );
484
485 if( fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) )
486 {
487 path = fn.GetPath();
488 }
489 else
490 {
491 wxMessageDialog dlg( this, msg, _( "Warning" ),
492 wxOK | wxCENTER | wxRESIZE_BORDER | wxICON_EXCLAMATION |
493 wxSTAY_ON_TOP );
494
495 dlg.SetExtendedMessage( extMsg );
496 dlg.ShowModal();
497
499 }
500 }
501
502 return path;
503}
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:106
Color settings are a bit different than most of the settings objects in that there can be more than o...
static const wxString COLOR_BUILTIN_DEFAULT
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:95
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:152
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:205
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
Definition: schematic.cpp:122
SCH_SHEET & Root() const
Definition: schematic.h:102
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:310
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:380
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