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