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 <page_layout/ws_painter.h>
34 #include <sch_painter.h>
35 #include <schematic.h>
36 
37 #include <wx/dirdlg.h>
38 #include <wx/msgdlg.h>
39 
40 // static members (static to remember last state):
43 
44 
46  : DIALOG_PLOT_SCHEMATIC_BASE( parent ),
47  m_parent( parent ),
48  m_plotFormat( PLOT_FORMAT::UNDEFINED ),
49  m_HPGLPenSize( 1.0 ),
50  m_defaultLineWidth( parent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits, true ),
51  m_penWidth( parent, m_penWidthLabel, m_penWidthCtrl, m_penWidthUnits, true )
52 {
53  m_configChanged = false;
54 
55  m_browseButton->SetBitmap( KiBitmap( folder_xpm ) );
56 
57  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
58  // that requires us to correct the button labels here.
59  m_sdbSizer1OK->SetLabel( _( "Plot All Pages" ) );
60  m_sdbSizer1Apply->SetLabel( _( "Plot Current Page" ) );
61  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
62  m_sdbSizer1->Layout();
63 
64  m_sdbSizer1OK->SetDefault();
65  initDlg();
66 
67  // Now all widgets have the size fixed, call FinishDialogSettings
69 }
70 
71 
72 // Initialize the dialog options:
74 {
75  auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
76  wxASSERT( cfg );
77 
78  if( cfg )
79  {
80  for( COLOR_SETTINGS* settings : Pgm().GetSettingsManager().GetColorSettingsList() )
81  {
82  int idx = m_colorTheme->Append( settings->GetName(), static_cast<void*>( settings ) );
83 
84  if( settings->GetFilename() == cfg->m_PlotPanel.color_theme )
85  m_colorTheme->SetSelection( idx );
86  }
87 
88  m_colorTheme->Enable( cfg->m_PlotPanel.color );
89 
90  m_plotBackgroundColor->Enable( cfg->m_PlotPanel.color );
91  m_plotBackgroundColor->SetValue( cfg->m_PlotPanel.background_color );
92 
93  // Set color or B&W plot option
94  setModeColor( cfg->m_PlotPanel.color );
95 
96  // Set plot or not frame reference option
97  setPlotFrameRef( cfg->m_PlotPanel.frame_reference );
98 
99  // Set HPGL plot origin to center of paper of left bottom corner
100  SetPlotOriginCenter( cfg->m_PlotPanel.hpgl_origin );
101 
102  m_HPGLPaperSizeSelect = cfg->m_PlotPanel.hpgl_paper_size;
103 
104  // HPGL Pen Size is stored in mm in config
105  m_HPGLPenSize = cfg->m_PlotPanel.hpgl_pen_size * IU_PER_MM;
106 
107  // Switch to the last save plot format
108  PLOT_FORMAT fmt = static_cast<PLOT_FORMAT>( cfg->m_PlotPanel.format );
109 
110  switch( fmt )
111  {
112  default:
113  case PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 0 ); break;
114  case PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 1 ); break;
115  case PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
116  case PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
117  case PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
118  }
119 
120  if( fmt == PLOT_FORMAT::DXF || fmt == PLOT_FORMAT::HPGL )
121  m_plotBackgroundColor->Disable();
122 
123  // Set the default line width (pen width which should be used for
124  // items that do not have a pen size defined (like frame ref)
125  // the default line width is stored in mils in config
126  m_defaultLineWidth.SetValue( Mils2iu( cfg->m_Drawing.default_line_thickness ) );
127  }
128 
129  // Initialize HPGL specific widgets
131 
132  // Plot directory
134  wxString path = settings.m_PlotDirectoryName;
135 #ifdef __WINDOWS__
136  path.Replace( '/', '\\' );
137 #endif
138  m_outputDirectoryName->SetValue( path );
139 }
140 
141 
147 {
148  // Build the absolute path of current output directory to preselect it in the file browser.
149  wxString path = ExpandEnvVarSubstitutions( m_outputDirectoryName->GetValue(), &Prj() );
150  path = Prj().AbsolutePath( path );
151 
152  wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
153 
154  if( dirDialog.ShowModal() == wxID_CANCEL )
155  return;
156 
157  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
158 
159  wxFileName fn( Prj().AbsolutePath( m_parent->Schematic().Root().GetFileName() ) );
160  wxString defaultPath = fn.GetPathWithSep();
161  wxString msg;
162  wxFileName relPathTest; // Used to test if we can make the path relative
163 
164  relPathTest.Assign( dirDialog.GetPath() );
165 
166  // Test if making the path relative is possible before asking the user if they want to do it
167  if( relPathTest.MakeRelativeTo( defaultPath ) )
168  {
169  msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ), defaultPath );
170 
171  wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
172  wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
173 
174  if( dialog.ShowModal() == wxID_YES )
175  dirName.MakeRelativeTo( defaultPath );
176  }
177 
178  m_outputDirectoryName->SetValue( dirName.GetFullPath() );
179 }
180 
181 
183 {
184  switch( m_plotFormatOpt->GetSelection() )
185  {
186  default:
187  case 0:
188  return PLOT_FORMAT::POST;
189  case 1:
190  return PLOT_FORMAT::PDF;
191  case 2:
192  return PLOT_FORMAT::SVG;
193  case 3:
194  return PLOT_FORMAT::DXF;
195  case 4:
196  return PLOT_FORMAT::HPGL;
197  }
198 }
199 
200 
201 void DIALOG_PLOT_SCHEMATIC::OnPageSizeSelected( wxCommandEvent& event )
202 {
204  m_HPGLPaperSizeSelect = m_paperSizeOption->GetSelection();
205  else
206  m_pageSizeSelect = m_paperSizeOption->GetSelection();
207 }
208 
209 
210 void DIALOG_PLOT_SCHEMATIC::OnUpdateUI( wxUpdateUIEvent& event )
211 {
213 
214  if( fmt != m_plotFormat )
215  {
216  m_plotFormat = fmt;
217 
218  wxArrayString paperSizes;
219  paperSizes.push_back( _( "Schematic size" ) );
220 
221  int selection;
222 
223  if( fmt == PLOT_FORMAT::HPGL )
224  {
225  paperSizes.push_back( _( "A5" ) );
226  paperSizes.push_back( _( "A4" ) );
227  paperSizes.push_back( _( "A3" ) );
228  paperSizes.push_back( _( "A2" ) );
229  paperSizes.push_back( _( "A1" ) );
230  paperSizes.push_back( _( "A0" ) );
231  paperSizes.push_back( _( "A" ) );
232  paperSizes.push_back( _( "B" ) );
233  paperSizes.push_back( _( "C" ) );
234  paperSizes.push_back( _( "D" ) );
235  paperSizes.push_back( _( "E" ) );
236 
237  selection = m_HPGLPaperSizeSelect;
238  }
239  else
240  {
241  paperSizes.push_back( _( "A4" ) );
242  paperSizes.push_back( _( "A" ) );
243 
244  selection = m_pageSizeSelect;
245  }
246 
247  m_paperSizeOption->Set( paperSizes );
248  m_paperSizeOption->SetSelection( selection );
249 
251  fmt == PLOT_FORMAT::POST || fmt == PLOT_FORMAT::PDF || fmt == PLOT_FORMAT::SVG );
252 
253  m_plotOriginTitle->Enable( fmt == PLOT_FORMAT::HPGL );
254  m_plotOriginOpt->Enable( fmt == PLOT_FORMAT::HPGL );
256 
257  m_plotBackgroundColor->Enable(
258  fmt == PLOT_FORMAT::POST || fmt == PLOT_FORMAT::PDF || fmt == PLOT_FORMAT::SVG );
259 
260  m_colorTheme->Enable( fmt != PLOT_FORMAT::HPGL );
261  m_ModeColorOption->Enable( fmt != PLOT_FORMAT::HPGL );
262  }
263 }
264 
265 
267 {
269 
270  EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
271  wxASSERT( cfg );
272 
274 
275  if( cfg )
276  {
278  cfg->m_PlotPanel.color = getModeColor();
279  cfg->m_PlotPanel.color_theme = colors->GetFilename();
281  cfg->m_PlotPanel.format = static_cast<int>( GetPlotFileFormat() );
284 
285  // HPGL Pen Size is stored in mm in config
287  }
288 
289  aSettings->LoadColors( colors );
290  aSettings->SetDefaultPenWidth( (int) m_defaultLineWidth.GetValue() );
291 
292  if( m_plotBackgroundColor->GetValue() )
293  aSettings->SetBackgroundColor( colors->GetColor( LAYER_SCHEMATIC_BACKGROUND ) );
294  else
295  aSettings->SetBackgroundColor( COLOR4D::UNSPECIFIED );
296 
297  // Plot directory
298  wxString path = m_outputDirectoryName->GetValue();
299  path.Replace( '\\', '/' );
300 
302 
303  if( settings.m_PlotDirectoryName != path )
304  m_configChanged = true;
305 
306  settings.m_PlotDirectoryName = path;
307 }
308 
309 
311 {
312  int selection = m_colorTheme->GetSelection();
313 
314  if( selection < 0 )
315  return Pgm().GetSettingsManager().GetColorSettings( "_builtin_default" );
316 
317  return static_cast<COLOR_SETTINGS*>( m_colorTheme->GetClientData( selection ) );
318 }
319 
320 
321 void DIALOG_PLOT_SCHEMATIC::OnPlotCurrent( wxCommandEvent& event )
322 {
323  PlotSchematic( false );
324 }
325 
326 
327 void DIALOG_PLOT_SCHEMATIC::OnPlotAll( wxCommandEvent& event )
328 {
329  PlotSchematic( true );
330 }
331 
332 
334 {
336 
337  getPlotOptions( &renderSettings );
338 
339  switch( GetPlotFileFormat() )
340  {
341  default:
342  case PLOT_FORMAT::POST:
343  createPSFile( aPlotAll, getPlotFrameRef(), &renderSettings );
344  break;
345  case PLOT_FORMAT::DXF:
346  CreateDXFFile( aPlotAll, getPlotFrameRef(), &renderSettings );
347  break;
348  case PLOT_FORMAT::PDF:
349  createPDFFile( aPlotAll, getPlotFrameRef(), &renderSettings );
350  break;
351  case PLOT_FORMAT::SVG:
352  createSVGFile( aPlotAll, getPlotFrameRef(), &renderSettings );
353  break;
354  case PLOT_FORMAT::HPGL:
355  createHPGLFile( aPlotAll, getPlotFrameRef(), &renderSettings );
356  break;
357  }
358 }
359 
360 
361 wxFileName DIALOG_PLOT_SCHEMATIC::createPlotFileName( const wxString& aPlotFileName,
362  const wxString& aExtension,
363  REPORTER* aReporter )
364 {
365  wxString path = ExpandEnvVarSubstitutions( m_outputDirectoryName->GetValue(), &Prj() );
366  wxFileName outputDir = wxFileName::DirName( path );
367 
368  wxString plotFileName = Prj().AbsolutePath( aPlotFileName + wxT( "." ) + aExtension);
369 
370  if( !EnsureFileDirectoryExists( &outputDir, plotFileName, aReporter ) )
371  {
372  wxString msg = wxString::Format( _( "Could not write plot files to folder \"%s\"." ),
373  outputDir.GetPath() );
374  aReporter->Report( msg, RPT_SEVERITY_ERROR );
375  }
376 
377  wxFileName fn( plotFileName );
378  fn.SetPath( outputDir.GetFullPath() );
379  return fn;
380 }
void PlotSchematic(bool aPlotAll)
const BITMAP_OPAQUE folder_xpm[1]
Definition: folder.cpp:20
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:125
DIALOG_PLOT_SCHEMATIC(SCH_EDIT_FRAME *parent)
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:255
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)
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:102
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:270
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
void setPlotFrameRef(bool aPlot)
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:67
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:283
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:498
SETTINGS_MANAGER * GetSettingsManager()
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Function Format outputs 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
Sets the background color.
SCH_SHEET & Root() const
Definition: schematic.h:102
see class PGM_BASE
#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)
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)