KiCad PCB EDA Suite
gerbview/dialogs/dialog_print_using_printer.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) 2010-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <fctsys.h>
26 
27 #include <kiface_i.h>
28 #include <common.h>
29 #include <class_drawpanel.h>
30 #include <confirm.h>
31 
33 #include <printout_controler.h>
34 
35 #include <gerbview.h>
36 #include <gerbview_frame.h>
37 #include <gerber_file_image.h>
38 #include <gerber_file_image_list.h>
39 
40 #include <enabler.h>
41 
44 
45 #define OPTKEY_LAYERBASE wxT( "PlotLayer_%d" )
46 #define OPTKEY_PRINT_X_FINESCALE_ADJ wxT( "PrintXFineScaleAdj" )
47 #define OPTKEY_PRINT_Y_FINESCALE_ADJ wxT( "PrintYFineScaleAdj" )
48 #define OPTKEY_PRINT_SCALE wxT( "PrintScale" )
49 #define OPTKEY_PRINT_PAGE_FRAME wxT( "PrintPageFrame" )
50 #define OPTKEY_PRINT_MONOCHROME_MODE wxT( "PrintMonochrome" )
51 
53 
54 static double s_ScaleList[] =
55 { 0, 0.5, 0.7, 0.999, 1.0, 1.4, 2.0, 3.0, 4.0 };
56 
57 // Define min et max reasonnable values for print scale
58 #define MIN_SCALE 0.01
59 #define MAX_SCALE 100.0
60 
61 // static print data and page setup data, to remember settings during the session
62 static wxPrintData* s_printData;
63 static wxPageSetupDialogData* s_pageSetupData = (wxPageSetupDialogData*) NULL;
64 
65 // Variables locales
67 
68 
69 /* Dialog to print schematic. Class derived from DIALOG_PRINT_USING_PRINTER_BASE
70  * created by wxFormBuilder
71  */
73 {
74 private:
76  wxConfigBase* m_Config;
77  wxCheckBox* m_BoxSelectLayer[32];
78 
79 public:
82 
83 private:
84  void OnCloseWindow( wxCloseEvent& event ) override;
85  void OnInitDialog( wxInitDialogEvent& event );
86  void OnPageSetup( wxCommandEvent& event ) override;
87  void OnPrintPreview( wxCommandEvent& event ) override;
88  void OnPrintButtonClick( wxCommandEvent& event ) override;
89  void OnScaleSelectionClick( wxCommandEvent& event ) override;
90 
91  void OnButtonCloseClick( wxCommandEvent& event ) override { Close(); }
92  void SetPrintParameters();
93  void InitValues();
94 
95 public:
96  bool IsMirrored() { return m_Print_Mirror->IsChecked(); }
97  bool PrintUsingSinglePage() { return true; }
99  // Prepare print parameters. return true if OK,
100  // false if there is an issue (mainly no printable layers)
101  bool PreparePrintPrms();
102 };
103 
104 
105 void GERBVIEW_FRAME::ToPrinter( wxCommandEvent& event )
106 {
107  if( s_printData == NULL ) // First print
108  s_printData = new wxPrintData();
109 
110  if( !s_printData->Ok() )
111  {
112  DisplayError( this, _( "Error Init Printer info" ) );
113  return;
114  }
115 
116  s_printData->SetQuality( wxPRINT_QUALITY_HIGH );
117  s_printData->SetOrientation( GetPageSettings().IsPortrait() ?
118  wxPORTRAIT : wxLANDSCAPE );
119 
121 
122  frame->ShowModal();
123  frame->Destroy();
124 }
125 
126 
129 {
130  m_Parent = parent;
132 
133  InitValues( );
134  GetSizer()->SetSizeHints( this );
135 
136 #ifdef __WXMAC__
137  /* Problems with modal on wx-2.9 - Anyway preview is standard for OSX */
138  m_buttonPreview->Hide();
139 #endif
140 
141  GetSizer()->Fit( this );
142 }
143 
144 
146 {
147  SetFocus();
148  wxString msg;
149 
150  if( s_pageSetupData == NULL )
151  {
152  s_pageSetupData = new wxPageSetupDialogData;
153  // Set initial page margins.
154  // Margins are already set in Gerbview, so we can use 0
155  s_pageSetupData->SetMarginTopLeft( wxPoint( 0, 0 ) );
156  s_pageSetupData->SetMarginBottomRight( wxPoint( 0, 0 ) );
157  }
158 
159  s_Parameters.m_PageSetupData = s_pageSetupData;
161 
162  // Create layer list
163  for( unsigned ii = 0; ii < images->ImagesMaxCount(); ++ii )
164  {
165  msg = _( "Layer" );
166  msg << wxT( " " ) << ii + 1;
167 
168  wxStaticBoxSizer* boxSizer = ( ii < 16 ) ? m_leftLayersBoxSizer
170 
171  m_BoxSelectLayer[ii] = new wxCheckBox( boxSizer->GetStaticBox(),
172  wxID_ANY, msg );
173  boxSizer->Add( m_BoxSelectLayer[ii], wxGROW | wxLEFT | wxRIGHT | wxTOP );
174 
175  if( images->GetGbrImage( ii ) == NULL ) // Nothing loaded on this draw layer
176  m_BoxSelectLayer[ii]->Enable( false );
177  }
178 
179  // Read the scale adjust option
180  int scale_idx = 4; // default selected scale = ScaleList[4] = 1.000
181 
182  if( m_Config )
183  {
184  m_Config->Read( OPTKEY_PRINT_X_FINESCALE_ADJ, &s_Parameters.m_XScaleAdjust );
185  m_Config->Read( OPTKEY_PRINT_Y_FINESCALE_ADJ, &s_Parameters.m_YScaleAdjust );
186  m_Config->Read( OPTKEY_PRINT_SCALE, &scale_idx );
187  m_Config->Read( OPTKEY_PRINT_PAGE_FRAME, &s_Parameters.m_Print_Sheet_Ref, 1 );
189 
190  // Test for a reasonnable scale value. Set to 1 if problem
191  if( s_Parameters.m_XScaleAdjust < MIN_SCALE ||
192  s_Parameters.m_YScaleAdjust < MIN_SCALE ||
193  s_Parameters.m_XScaleAdjust > MAX_SCALE ||
194  s_Parameters.m_YScaleAdjust > MAX_SCALE )
195  s_Parameters.m_XScaleAdjust = s_Parameters.m_YScaleAdjust = 1.0;
196 
197  for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
198  {
199  wxString layerKey;
200  bool option;
201 
202  layerKey.Printf( OPTKEY_LAYERBASE, layer );
203  m_Config->Read( layerKey, &option, false );
204  m_BoxSelectLayer[layer]->SetValue( option );
205  }
206  }
207 
208  m_ScaleOption->SetSelection( scale_idx );
209  scale_idx = m_ScaleOption->GetSelection();
210  s_Parameters.m_PrintScale = s_ScaleList[scale_idx];
211  m_Print_Mirror->SetValue( s_Parameters.m_PrintMirror );
212 
213 
214  if( s_Parameters.m_Print_Black_and_White )
215  m_ModeColorOption->SetSelection( 1 );
216  else
217  m_ModeColorOption->SetSelection( 0 );
218 
219  s_Parameters.m_PenDefaultSize = 0;
220 
221  // Create scale adjust option
222  msg.Printf( wxT( "%f" ), s_Parameters.m_XScaleAdjust );
223  m_FineAdjustXscaleOpt->SetValue( msg );
224  msg.Printf( wxT( "%f" ), s_Parameters.m_YScaleAdjust );
225  m_FineAdjustYscaleOpt->SetValue( msg );
226 
227  bool enable = (s_Parameters.m_PrintScale == 1.0);
228 
229  m_FineAdjustXscaleOpt->Enable(enable);
230  m_FineAdjustYscaleOpt->Enable(enable);
231 }
232 
233 
235 {
236  std::vector<int> layerList;
237 
238  for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
239  {
240  if( m_BoxSelectLayer[ii]->IsChecked() && m_BoxSelectLayer[ii]->IsEnabled() )
241  layerList.push_back( ii );
242  }
243 
245  s_Parameters.m_PageCount = layerList.size();
246 
247  return s_Parameters.m_PageCount;
248 }
249 
250 
251 void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event )
252 {
254 
255  if( m_Config )
256  {
257  m_Config->Write( OPTKEY_PRINT_X_FINESCALE_ADJ, s_Parameters.m_XScaleAdjust );
258  m_Config->Write( OPTKEY_PRINT_Y_FINESCALE_ADJ, s_Parameters.m_YScaleAdjust );
259  m_Config->Write( OPTKEY_PRINT_SCALE, m_ScaleOption->GetSelection() );
260  m_Config->Write( OPTKEY_PRINT_PAGE_FRAME, s_Parameters.m_Print_Sheet_Ref);
262  wxString layerKey;
263 
264  for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
265  {
266  layerKey.Printf( OPTKEY_LAYERBASE, layer );
267  m_Config->Write( layerKey, m_BoxSelectLayer[layer]->IsChecked() );
268  }
269  }
270 
271  EndModal( 0 );
272 }
273 
274 
276 {
277  s_Parameters.m_PrintMirror = m_Print_Mirror->GetValue();
278  s_Parameters.m_Print_Black_and_White =
279  m_ModeColorOption->GetSelection() != 0;
280 
281  // Due to negative objects in gerber objects, always use one page per image,
282  // because these objects create artefact when they are printed on an existing image.
283  s_Parameters.m_OptionPrintPage = false;
284 
286 
287  int idx = m_ScaleOption->GetSelection();
288  s_Parameters.m_PrintScale = s_ScaleList[idx];
289 
290  // Test for a reasonnable scale value
291  bool ok = true;
292  double scaleX;
293  m_FineAdjustXscaleOpt->GetValue().ToDouble( &scaleX );
294 
295  double scaleY;
296  m_FineAdjustYscaleOpt->GetValue().ToDouble( &scaleY );
297 
298  if( scaleX > MAX_SCALE || scaleY > MAX_SCALE )
299  {
300  DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very large value" ) );
301  ok = false;
302  }
303 
304  if( scaleX < MIN_SCALE || scaleY < MIN_SCALE )
305  {
306  DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very small value" ) );
307  ok = false;
308  }
309 
310  if( ok )
311  {
312  s_Parameters.m_XScaleAdjust = scaleX;
313  s_Parameters.m_YScaleAdjust = scaleY;
314  }
315  else
316  {
317  // Update actual fine scale value
318  m_FineAdjustXscaleOpt->SetValue( wxString::Format( "%f", s_Parameters.m_XScaleAdjust ) );
319  m_FineAdjustYscaleOpt->SetValue( wxString::Format( "%f", s_Parameters.m_YScaleAdjust ) );
320  }
321 }
322 
323 void DIALOG_PRINT_USING_PRINTER::OnScaleSelectionClick( wxCommandEvent& event )
324 {
325  double scale = s_ScaleList[m_ScaleOption->GetSelection()];
326  bool enable = (scale == 1.0);
327 
329  m_FineAdjustXscaleOpt->Enable(enable);
330 
332  m_FineAdjustYscaleOpt->Enable(enable);
333 }
334 
335 // Open a dialog box for printer setup (printer options, page size ...)
336 void DIALOG_PRINT_USING_PRINTER::OnPageSetup( wxCommandEvent& event )
337 {
339 
340  wxPageSetupDialog pageSetupDialog(this, s_pageSetupData);
341  pageSetupDialog.ShowModal();
342 
343  (*s_printData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
344  (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
345 }
346 
348 {
350 
351  // If no layer selected, we have no plot. prompt user if it happens
352  // because he could think there is a bug in Pcbnew:
353  if( m_Parent->GetGerberLayout()->GetPrintableLayers().size() == 0 )
354  {
355  DisplayError( this, _( "No layer selected" ) );
356  return false;
357  }
358 
359  return true;
360 }
361 
362 // Open and display a previewer frame for printing
363 void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event )
364 {
365  if( !PreparePrintPrms() )
366  return;
367 
368  // Pass two printout objects: for preview, and possible printing.
369  wxString title = _( "Print Preview" );
370  wxPrintPreview* preview =
371  new wxPrintPreview( new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ),
372  new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ),
373  s_printData );
374 
375  if( preview == NULL )
376  {
377  DisplayError( this, wxT( "OnPrintPreview() problem" ) );
378  return;
379  }
380 
381 
382  // Uses the parent position and size.
383  // @todo uses last position and size ans store them when exit in m_Config
384  wxPoint WPos = m_Parent->GetPosition();
385  wxSize WSize = m_Parent->GetSize();
386 
387  wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, WPos, WSize );
388  frame->SetMinSize( wxSize( 550, 350 ) );
389 
390  frame->Initialize();
391 
392  frame->Raise(); // Needed on Ubuntu/Unity to display the frame
393  frame->Show( true );
394 }
395 
396 
397 void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event )
398 {
399  if( !PreparePrintPrms() )
400  return;
401 
402  wxPrintDialogData printDialogData( *s_printData );
403 
404  wxPrinter printer( &printDialogData );
405  wxString title = _( "Print" );
406  BOARD_PRINTOUT_CONTROLLER printout( s_Parameters, m_Parent, title );
407 
408  // Disable 'Print' button to prevent issuing another print
409  // command before the previous one is finished (causes problems on Windows)
410  ENABLER printBtnDisable( *m_buttonPrint, false );
411 
412  if( !printer.Print( this, &printout, true ) )
413  {
414  if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
415  DisplayError( this, _( "There was a problem printing" ) );
416  }
417  else
418  {
419  *s_printData = printer.GetPrintDialogData().GetPrintData();
420  }
421 }
422 
Board print handler definition file.
This file is part of the common library.
void SetPrintableLayers(const std::vector< int > &aLayerList)
Function SetPrintableLayers Set the list of printable graphic layers.
Definition: gbr_layout.h:143
Class PRINT_PARAMETERS handles the parameters used to print a board drawing.
void OnScaleSelectionClick(wxCommandEvent &event) override
static PRINT_PARAMETERS s_Parameters
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
std::vector< int > GetPrintableLayers()
Function GetPrintableLayers.
Definition: gbr_layout.h:152
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
void OnPrintButtonClick(wxCommandEvent &event) override
#define GERBER_DRAWLAYERS_COUNT
GERBER_FILE_IMAGE * GetGbrImage(int aIdx)
static wxPageSetupDialogData * s_pageSetupData
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
GBR_LAYOUT * GetGerberLayout() const
void OnInitDialog(wxInitDialogEvent &event)
void OnPageSetup(wxCommandEvent &event) override
wxPageSetupDialogData * m_PageSetupData
const int scale
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:205
void OnButtonCloseClick(wxCommandEvent &event) override
Class BOARD_PRINTOUT_CONTROLLER is a class derived from wxPrintout to handle the necessary informatio...
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Definition: gbr_layout.cpp:50
The common library.
void OnPrintPreview(wxCommandEvent &event) override
void ToPrinter(wxCommandEvent &event)
Function ToPrinter Open a dialog frame to print layers.
bool Enable(bool enable) override
void OnCloseWindow(wxCloseEvent &event) override
static wxPrintData * s_printData
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:216
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:185
Simple class to automatically enable/disable widgets.
Definition: enabler.h:29