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 <stambaughw@gmail.com>
7  * Copyright (C) 1992-2020 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>
29 #include <dialog_plot_schematic.h>
30 #include <eeschema_settings.h>
31 #include <kiface_i.h>
32 #include <pgm_base.h>
35 #include <sch_painter.h>
36 #include <schematic.h>
37 
38 #include <wx/dirdlg.h>
39 #include <wx/msgdlg.h>
40 
41 // static members (static to remember last state):
44 
45 
47  : DIALOG_PLOT_SCHEMATIC_BASE( parent ),
48  m_parent( parent ),
49  m_plotFormat( PLOT_FORMAT::UNDEFINED ),
50  m_HPGLPenSize( 1.0 ),
51  m_defaultLineWidth( parent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits, true ),
52  m_penWidth( parent, m_penWidthLabel, m_penWidthCtrl, m_penWidthUnits, true )
53 {
54  m_configChanged = false;
55 
56  m_browseButton->SetBitmap( KiBitmap( small_folder_xpm ) );
57 
58  m_MessagesBox->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) );
59 
60  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
61  // that requires us to correct the button labels here.
62  m_sdbSizer1OK->SetLabel( _( "Plot All Pages" ) );
63  m_sdbSizer1Apply->SetLabel( _( "Plot Current Page" ) );
64  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
65  m_sdbSizer1->Layout();
66 
67  m_sdbSizer1OK->SetDefault();
68  initDlg();
69 
70  // Now all widgets have the size fixed, call FinishDialogSettings
72 }
73 
74 
75 // Initialize the dialog options:
77 {
78  auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
79  wxASSERT( cfg );
80 
81  if( cfg )
82  {
83  for( COLOR_SETTINGS* settings : Pgm().GetSettingsManager().GetColorSettingsList() )
84  {
85  int idx = m_colorTheme->Append( settings->GetName(), static_cast<void*>( settings ) );
86 
87  if( settings->GetFilename() == cfg->m_PlotPanel.color_theme )
88  m_colorTheme->SetSelection( idx );
89  }
90 
91  m_colorTheme->Enable( cfg->m_PlotPanel.color );
92 
93  m_plotBackgroundColor->Enable( cfg->m_PlotPanel.color );
94  m_plotBackgroundColor->SetValue( cfg->m_PlotPanel.background_color );
95 
96  // Set color or B&W plot option
97  setModeColor( cfg->m_PlotPanel.color );
98 
99  // Set plot or not frame reference option
100  setPlotDrawingSheet( cfg->m_PlotPanel.frame_reference );
101 
102  // HPGL plot origin and unit system configuration
103  m_plotOriginOpt->SetSelection( cfg->m_PlotPanel.hpgl_origin );
104 
105  m_HPGLPaperSizeSelect = cfg->m_PlotPanel.hpgl_paper_size;
106 
107  // HPGL Pen Size is stored in mm in config
108  m_HPGLPenSize = cfg->m_PlotPanel.hpgl_pen_size * IU_PER_MM;
109 
110  // Switch to the last save plot format
111  PLOT_FORMAT fmt = static_cast<PLOT_FORMAT>( cfg->m_PlotPanel.format );
112 
113  switch( fmt )
114  {
115  default:
116  case PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 0 ); break;
117  case PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 1 ); break;
118  case PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
119  case PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
120  case PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
121  }
122 
123  if( fmt == PLOT_FORMAT::DXF || fmt == PLOT_FORMAT::HPGL )
124  m_plotBackgroundColor->Disable();
125 
126  // Set the default line width (pen width which should be used for
127  // items that do not have a pen size defined (like frame ref)
128  // the default line width is stored in mils in config
129  m_defaultLineWidth.SetValue( Mils2iu( cfg->m_Drawing.default_line_thickness ) );
130  }
131 
132  // Initialize HPGL specific widgets
134 
135  // Plot directory
137  wxString path = settings.m_PlotDirectoryName;
138 #ifdef __WINDOWS__
139  path.Replace( '/', '\\' );
140 #endif
141  m_outputDirectoryName->SetValue( path );
142 }
143 
144 
150 {
151  // Build the absolute path of current output directory to preselect it in the file browser.
152  wxString path = ExpandEnvVarSubstitutions( m_outputDirectoryName->GetValue(), &Prj() );
153  path = Prj().AbsolutePath( path );
154 
155  wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
156 
157  if( dirDialog.ShowModal() == wxID_CANCEL )
158  return;
159 
160  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
161 
162  wxFileName fn( Prj().AbsolutePath( m_parent->Schematic().Root().GetFileName() ) );
163  wxString defaultPath = fn.GetPathWithSep();
164  wxString msg;
165  wxFileName relPathTest; // Used to test if we can make the path relative
166 
167  relPathTest.Assign( dirDialog.GetPath() );
168 
169  // Test if making the path relative is possible before asking the user if they want to do it
170  if( relPathTest.MakeRelativeTo( defaultPath ) )
171  {
172  msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ), defaultPath );
173 
174  wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
175  wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
176 
177  if( dialog.ShowModal() == wxID_YES )
178  dirName.MakeRelativeTo( defaultPath );
179  }
180 
181  m_outputDirectoryName->SetValue( dirName.GetFullPath() );
182 }
183 
184 
186 {
187  switch( m_plotFormatOpt->GetSelection() )
188  {
189  default:
190  case 0:
191  return PLOT_FORMAT::POST;
192  case 1:
193  return PLOT_FORMAT::PDF;
194  case 2:
195  return PLOT_FORMAT::SVG;
196  case 3:
197  return PLOT_FORMAT::DXF;
198  case 4:
199  return PLOT_FORMAT::HPGL;
200  }
201 }
202 
203 
204 void DIALOG_PLOT_SCHEMATIC::OnPageSizeSelected( wxCommandEvent& event )
205 {
207  m_HPGLPaperSizeSelect = m_paperSizeOption->GetSelection();
208  else
209  m_pageSizeSelect = m_paperSizeOption->GetSelection();
210 }
211 
212 
213 void DIALOG_PLOT_SCHEMATIC::OnUpdateUI( wxUpdateUIEvent& event )
214 {
216 
217  if( fmt != m_plotFormat )
218  {
219  m_plotFormat = fmt;
220 
221  wxArrayString paperSizes;
222  paperSizes.push_back( _( "Schematic size" ) );
223 
224  int selection;
225 
226  if( fmt == PLOT_FORMAT::HPGL )
227  {
228  paperSizes.push_back( _( "A5" ) );
229  paperSizes.push_back( _( "A4" ) );
230  paperSizes.push_back( _( "A3" ) );
231  paperSizes.push_back( _( "A2" ) );
232  paperSizes.push_back( _( "A1" ) );
233  paperSizes.push_back( _( "A0" ) );
234  paperSizes.push_back( _( "A" ) );
235  paperSizes.push_back( _( "B" ) );
236  paperSizes.push_back( _( "C" ) );
237  paperSizes.push_back( _( "D" ) );
238  paperSizes.push_back( _( "E" ) );
239 
240  selection = m_HPGLPaperSizeSelect;
241  }
242  else
243  {
244  paperSizes.push_back( _( "A4" ) );
245  paperSizes.push_back( _( "A" ) );
246 
247  selection = m_pageSizeSelect;
248  }
249 
250  m_paperSizeOption->Set( paperSizes );
251  m_paperSizeOption->SetSelection( selection );
252 
254  fmt == PLOT_FORMAT::POST || fmt == PLOT_FORMAT::PDF || fmt == PLOT_FORMAT::SVG );
255 
256  m_plotOriginTitle->Enable( fmt == PLOT_FORMAT::HPGL );
257  m_plotOriginOpt->Enable( fmt == PLOT_FORMAT::HPGL );
259 
260  m_plotBackgroundColor->Enable(
261  fmt == PLOT_FORMAT::POST || fmt == PLOT_FORMAT::PDF || fmt == PLOT_FORMAT::SVG );
262 
263  m_colorTheme->Enable( fmt != PLOT_FORMAT::HPGL );
264  m_ModeColorOption->Enable( fmt != PLOT_FORMAT::HPGL );
265  }
266 }
267 
268 
270 {
272 
273  EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
274  wxASSERT( cfg );
275 
277 
278  if( cfg )
279  {
281  cfg->m_PlotPanel.color = getModeColor();
282  cfg->m_PlotPanel.color_theme = colors->GetFilename();
284  cfg->m_PlotPanel.format = static_cast<int>( GetPlotFileFormat() );
285  cfg->m_PlotPanel.hpgl_origin = m_plotOriginOpt->GetSelection();
287 
288  // HPGL Pen Size is stored in mm in config
290  }
291 
292  aSettings->LoadColors( colors );
293  aSettings->SetDefaultPenWidth( (int) m_defaultLineWidth.GetValue() );
294 
295  if( m_plotBackgroundColor->GetValue() )
296  aSettings->SetBackgroundColor( colors->GetColor( LAYER_SCHEMATIC_BACKGROUND ) );
297  else
298  aSettings->SetBackgroundColor( COLOR4D::UNSPECIFIED );
299 
300  // Plot directory
301  wxString path = m_outputDirectoryName->GetValue();
302  path.Replace( '\\', '/' );
303 
305 
306  if( settings.m_PlotDirectoryName != path )
307  m_configChanged = true;
308 
309  settings.m_PlotDirectoryName = path;
310 }
311 
312 
314 {
315  int selection = m_colorTheme->GetSelection();
316 
317  if( selection < 0 )
318  return Pgm().GetSettingsManager().GetColorSettings( "_builtin_default" );
319 
320  return static_cast<COLOR_SETTINGS*>( m_colorTheme->GetClientData( selection ) );
321 }
322 
323 
324 void DIALOG_PLOT_SCHEMATIC::OnPlotCurrent( wxCommandEvent& event )
325 {
326  PlotSchematic( false );
327 }
328 
329 
330 void DIALOG_PLOT_SCHEMATIC::OnPlotAll( wxCommandEvent& event )
331 {
332  PlotSchematic( true );
333 }
334 
335 
337 {
339 
340  getPlotOptions( &renderSettings );
341 
342  switch( GetPlotFileFormat() )
343  {
344  default:
345  case PLOT_FORMAT::POST:
346  createPSFile( aPlotAll, getPlotDrawingSheet(), &renderSettings );
347  break;
348  case PLOT_FORMAT::DXF:
349  CreateDXFFile( aPlotAll, getPlotDrawingSheet(), &renderSettings );
350  break;
351  case PLOT_FORMAT::PDF:
352  createPDFFile( aPlotAll, getPlotDrawingSheet(), &renderSettings );
353  break;
354  case PLOT_FORMAT::SVG:
355  createSVGFile( aPlotAll, getPlotDrawingSheet(), &renderSettings );
356  break;
357  case PLOT_FORMAT::HPGL:
358  createHPGLFile( aPlotAll, getPlotDrawingSheet(), &renderSettings );
359  break;
360  }
361 }
362 
363 
364 wxFileName DIALOG_PLOT_SCHEMATIC::createPlotFileName( const wxString& aPlotFileName,
365  const wxString& aExtension,
366  REPORTER* aReporter )
367 {
368  wxString path = ExpandEnvVarSubstitutions( m_outputDirectoryName->GetValue(), &Prj() );
369  wxFileName outputDir = wxFileName::DirName( path );
370  wxString plotFileName;
371 
372  if( !aPlotFileName.IsEmpty() )
373  plotFileName = Prj().AbsolutePath( aPlotFileName + wxT( "." ) + aExtension );
374  else
375  plotFileName = Prj().AbsolutePath( _( "Schematic" ) + wxT( "." ) + aExtension );
376 
377  if( !EnsureFileDirectoryExists( &outputDir, plotFileName, aReporter ) )
378  {
379  wxString msg = wxString::Format( _( "Could not write plot files to folder \"%s\"." ),
380  outputDir.GetPath() );
381  aReporter->Report( msg, RPT_SEVERITY_ERROR );
382  }
383 
384  wxFileName fn( plotFileName );
385  fn.SetPath( outputDir.GetFullPath() );
386  return fn;
387 }
void PlotSchematic(bool aPlotAll)
void OnOutputDirectoryBrowseClicked(wxCommandEvent &event) override
Set the m_outputDirectoryName variable to the selected directory from directory dialog.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
void OnUpdateUI(wxUpdateUIEvent &event) override
const BITMAP_OPAQUE small_folder_xpm[1]
static constexpr double IU_PER_MM
Mock up a conversion function.
wxStdDialogButtonSizer * m_sdbSizer1
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:125
DIALOG_PLOT_SCHEMATIC(SCH_EDIT_FRAME *parent)
COLOR_SETTINGS * getColorSettings()
void setPlotDrawingSheet(bool aPlot)
void OnPlotCurrent(wxCommandEvent &event) override
KIGFX::SCH_RENDER_SETTINGS * GetRenderSettings()
Class DIALOG_PLOT_SCHEMATIC_BASE.
Schematic editor (Eeschema) main window.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:269
void createPDFFile(bool aPlotAll, bool aPlotDrawingSheet, RENDER_SETTINGS *aRenderSettings)
void getPlotOptions(RENDER_SETTINGS *aSettings)
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
void createSVGFile(bool aPlotAll, bool aPlotFrameRef, RENDER_SETTINGS *aSettings)
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
void OnPageSizeSelected(wxCommandEvent &event) override
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
void CreateDXFFile(bool aPlotAll, bool aPlotDrawingSheet, RENDER_SETTINGS *aRenderSettings)
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.
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:82
wxFileName createPlotFileName(const wxString &aPlotFileName, const wxString &aExtension, REPORTER *aReporter=NULL)
Create a file name with an absolute path name.
void OnPlotAll(wxCommandEvent &event) override
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:67
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
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:297
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
SCHEMATIC & Schematic() const
void createPSFile(bool aPlotAll, bool aPlotFrameRef, RENDER_SETTINGS *aSettings)
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:499
SETTINGS_MANAGER * GetSettingsManager()
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
virtual void SetBackgroundColor(const COLOR4D &aColor)=0
Set the background color.
SCH_SHEET & Root() const
Definition: schematic.h:116
see class PGM_BASE
#define _(s)
Definition: 3d_actions.cpp:33
virtual void SetValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
These settings were stored in SCH_BASE_FRAME previously.
virtual long long int GetValue()
Return the current value in Internal Units.
SCH_RENDER_SETTINGS Stores schematic-specific render settings.
Definition: sch_painter.h:72
Color settings are a bit different than most of the settings objects in that there can be more than o...
void createHPGLFile(bool aPlotAll, bool aPlotFrameRef, RENDER_SETTINGS *aRenderSettings)
WX_HTML_REPORT_PANEL * m_MessagesBox
void SetDefaultPenWidth(int aWidth)
void SetFileName(const wxString &aReportFileName)
virtual void LoadColors(const COLOR_SETTINGS *aSettings)
static VRML_COLOR colors[VRML_COLOR_LAST]
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
void setModeColor(bool aColor)