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>
39 
42 
43 #define OPTKEY_LAYERBASE wxT( "PlotLayer_%d" )
44 #define OPTKEY_PRINT_X_FINESCALE_ADJ wxT( "PrintXFineScaleAdj" )
45 #define OPTKEY_PRINT_Y_FINESCALE_ADJ wxT( "PrintYFineScaleAdj" )
46 #define OPTKEY_PRINT_SCALE wxT( "PrintScale" )
47 #define OPTKEY_PRINT_PAGE_FRAME wxT( "PrintPageFrame" )
48 #define OPTKEY_PRINT_MONOCHROME_MODE wxT( "PrintMonochrome" )
49 
51 
52 static double s_ScaleList[] =
53 { 0, 0.5, 0.7, 0.999, 1.0, 1.4, 2.0, 3.0, 4.0 };
54 
55 // Define min et max reasonnable values for print scale
56 #define MIN_SCALE 0.01
57 #define MAX_SCALE 100.0
58 
59 // static print data and page setup data, to remember settings during the session
60 static wxPrintData* s_printData;
61 static wxPageSetupDialogData* s_pageSetupData = (wxPageSetupDialogData*) NULL;
62 
63 // Variables locales
65 
66 
67 /* Dialog to print schematic. Class derived from DIALOG_PRINT_USING_PRINTER_BASE
68  * created by wxFormBuilder
69  */
71 {
72 private:
74  wxConfigBase* m_Config;
75  wxCheckBox* m_BoxSelectLayer[32];
76 
77 public:
80 
81 private:
82  void OnCloseWindow( wxCloseEvent& event ) override;
83  void OnInitDialog( wxInitDialogEvent& event );
84  void OnPageSetup( wxCommandEvent& event ) override;
85  void OnPrintPreview( wxCommandEvent& event ) override;
86  void OnPrintButtonClick( wxCommandEvent& event ) override;
87  void OnScaleSelectionClick( wxCommandEvent& event ) override;
88 
89  void OnButtonCloseClick( wxCommandEvent& event ) override { Close(); }
90  void SetPrintParameters();
91  void InitValues();
92 
93 public:
94  bool IsMirrored() { return m_Print_Mirror->IsChecked(); }
95  bool PrintUsingSinglePage() { return true; }
97  // Prepare print parameters. return true if OK,
98  // false if there is an issue (mainly no printable layers)
99  bool PreparePrintPrms();
100 };
101 
102 
103 void GERBVIEW_FRAME::ToPrinter( wxCommandEvent& event )
104 {
105  if( s_printData == NULL ) // First print
106  s_printData = new wxPrintData();
107 
108  if( !s_printData->Ok() )
109  {
110  DisplayError( this, _( "Error Init Printer info" ) );
111  return;
112  }
113 
114  s_printData->SetQuality( wxPRINT_QUALITY_HIGH );
115  s_printData->SetOrientation( GetPageSettings().IsPortrait() ?
116  wxPORTRAIT : wxLANDSCAPE );
117 
119 
120  frame->ShowModal();
121  frame->Destroy();
122 }
123 
124 
127 {
128  m_Parent = parent;
130 
131  InitValues( );
132  GetSizer()->SetSizeHints( this );
133 
134 #ifdef __WXMAC__
135  /* Problems with modal on wx-2.9 - Anyway preview is standard for OSX */
136  m_buttonPreview->Hide();
137 #endif
138 
139  GetSizer()->Fit( this );
140 }
141 
142 
144 {
145  SetFocus();
146  wxString msg;
147 
148  if( s_pageSetupData == NULL )
149  {
150  s_pageSetupData = new wxPageSetupDialogData;
151  // Set initial page margins.
152  // Margins are already set in Gerbview, so we can use 0
153  s_pageSetupData->SetMarginTopLeft( wxPoint( 0, 0 ) );
154  s_pageSetupData->SetMarginBottomRight( wxPoint( 0, 0 ) );
155  }
156 
157  s_Parameters.m_PageSetupData = s_pageSetupData;
159 
160  // Create layer list
161  for( unsigned ii = 0; ii < images->ImagesMaxCount(); ++ii )
162  {
163  msg = _( "Layer" );
164  msg << wxT( " " ) << ii + 1;
165 
166  wxStaticBoxSizer* boxSizer = ( ii < 16 ) ? m_leftLayersBoxSizer
168 
169  m_BoxSelectLayer[ii] = new wxCheckBox( boxSizer->GetStaticBox(),
170  wxID_ANY, msg );
171  boxSizer->Add( m_BoxSelectLayer[ii], wxGROW | wxLEFT | wxRIGHT | wxTOP );
172 
173  if( images->GetGbrImage( ii ) == NULL ) // Nothing loaded on this draw layer
174  m_BoxSelectLayer[ii]->Enable( false );
175  }
176 
177  // Read the scale adjust option
178  int scale_idx = 4; // default selected scale = ScaleList[4] = 1.000
179 
180  if( m_Config )
181  {
182  m_Config->Read( OPTKEY_PRINT_X_FINESCALE_ADJ, &s_Parameters.m_XScaleAdjust );
183  m_Config->Read( OPTKEY_PRINT_Y_FINESCALE_ADJ, &s_Parameters.m_YScaleAdjust );
184  m_Config->Read( OPTKEY_PRINT_SCALE, &scale_idx );
185  m_Config->Read( OPTKEY_PRINT_PAGE_FRAME, &s_Parameters.m_Print_Sheet_Ref, 1 );
187 
188  // Test for a reasonnable scale value. Set to 1 if problem
189  if( s_Parameters.m_XScaleAdjust < MIN_SCALE ||
190  s_Parameters.m_YScaleAdjust < MIN_SCALE ||
191  s_Parameters.m_XScaleAdjust > MAX_SCALE ||
192  s_Parameters.m_YScaleAdjust > MAX_SCALE )
193  s_Parameters.m_XScaleAdjust = s_Parameters.m_YScaleAdjust = 1.0;
194 
195  for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
196  {
197  wxString layerKey;
198  bool option;
199 
200  layerKey.Printf( OPTKEY_LAYERBASE, layer );
201  m_Config->Read( layerKey, &option, false );
202  m_BoxSelectLayer[layer]->SetValue( option );
203  }
204  }
205 
206  m_ScaleOption->SetSelection( scale_idx );
207  scale_idx = m_ScaleOption->GetSelection();
208  s_Parameters.m_PrintScale = s_ScaleList[scale_idx];
209  m_Print_Mirror->SetValue( s_Parameters.m_PrintMirror );
210 
211 
212  if( s_Parameters.m_Print_Black_and_White )
213  m_ModeColorOption->SetSelection( 1 );
214  else
215  m_ModeColorOption->SetSelection( 0 );
216 
217  s_Parameters.m_PenDefaultSize = 0;
218 
219  // Create scale adjust option
220  msg.Printf( wxT( "%f" ), s_Parameters.m_XScaleAdjust );
221  m_FineAdjustXscaleOpt->SetValue( msg );
222  msg.Printf( wxT( "%f" ), s_Parameters.m_YScaleAdjust );
223  m_FineAdjustYscaleOpt->SetValue( msg );
224 
225  bool enable = (s_Parameters.m_PrintScale == 1.0);
226 
227  m_FineAdjustXscaleOpt->Enable(enable);
228  m_FineAdjustYscaleOpt->Enable(enable);
229 }
230 
231 
233 {
234  std::vector<int> layerList;
235 
236  for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
237  {
238  if( m_BoxSelectLayer[ii]->IsChecked() && m_BoxSelectLayer[ii]->IsEnabled() )
239  layerList.push_back( ii );
240  }
241 
243  s_Parameters.m_PageCount = layerList.size();
244 
245  return s_Parameters.m_PageCount;
246 }
247 
248 
249 void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event )
250 {
252 
253  if( m_Config )
254  {
255  m_Config->Write( OPTKEY_PRINT_X_FINESCALE_ADJ, s_Parameters.m_XScaleAdjust );
256  m_Config->Write( OPTKEY_PRINT_Y_FINESCALE_ADJ, s_Parameters.m_YScaleAdjust );
257  m_Config->Write( OPTKEY_PRINT_SCALE, m_ScaleOption->GetSelection() );
258  m_Config->Write( OPTKEY_PRINT_PAGE_FRAME, s_Parameters.m_Print_Sheet_Ref);
260  wxString layerKey;
261 
262  for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
263  {
264  layerKey.Printf( OPTKEY_LAYERBASE, layer );
265  m_Config->Write( layerKey, m_BoxSelectLayer[layer]->IsChecked() );
266  }
267  }
268 
269  EndModal( 0 );
270 }
271 
272 
274 {
275  s_Parameters.m_PrintMirror = m_Print_Mirror->GetValue();
276  s_Parameters.m_Print_Black_and_White =
277  m_ModeColorOption->GetSelection() != 0;
278 
279  // Due to negative objects in gerber objects, always use one page per image,
280  // because these objects create artefact when they are printed on an existing image.
281  s_Parameters.m_OptionPrintPage = false;
282 
284 
285  int idx = m_ScaleOption->GetSelection();
286  s_Parameters.m_PrintScale = s_ScaleList[idx];
287 
288  // Test for a reasonnable scale value
289  bool ok = true;
290  double scaleX;
291  m_FineAdjustXscaleOpt->GetValue().ToDouble( &scaleX );
292 
293  double scaleY;
294  m_FineAdjustYscaleOpt->GetValue().ToDouble( &scaleY );
295 
296  if( scaleX > MAX_SCALE || scaleY > MAX_SCALE )
297  {
298  DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very large value" ) );
299  ok = false;
300  }
301 
302  if( scaleX < MIN_SCALE || scaleY < MIN_SCALE )
303  {
304  DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very small value" ) );
305  ok = false;
306  }
307 
308  if( ok )
309  {
310  s_Parameters.m_XScaleAdjust = scaleX;
311  s_Parameters.m_YScaleAdjust = scaleY;
312  }
313  else
314  {
315  // Update actual fine scale value
316  m_FineAdjustXscaleOpt->SetValue( wxString::Format( "%f", s_Parameters.m_XScaleAdjust ) );
317  m_FineAdjustYscaleOpt->SetValue( wxString::Format( "%f", s_Parameters.m_YScaleAdjust ) );
318  }
319 }
320 
321 void DIALOG_PRINT_USING_PRINTER::OnScaleSelectionClick( wxCommandEvent& event )
322 {
323  double scale = s_ScaleList[m_ScaleOption->GetSelection()];
324  bool enable = (scale == 1.0);
325 
327  m_FineAdjustXscaleOpt->Enable(enable);
328 
330  m_FineAdjustYscaleOpt->Enable(enable);
331 }
332 
333 // Open a dialog box for printer setup (printer options, page size ...)
334 void DIALOG_PRINT_USING_PRINTER::OnPageSetup( wxCommandEvent& event )
335 {
337 
338  wxPageSetupDialog pageSetupDialog(this, s_pageSetupData);
339  pageSetupDialog.ShowModal();
340 
341  (*s_printData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
342  (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
343 }
344 
346 {
348 
349  // If no layer selected, we have no plot. prompt user if it happens
350  // because he could think there is a bug in Pcbnew:
351  if( m_Parent->GetGerberLayout()->GetPrintableLayers().size() == 0 )
352  {
353  DisplayError( this, _( "No layer selected" ) );
354  return false;
355  }
356 
357  return true;
358 }
359 
360 // Open and display a previewer frame for printing
361 void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event )
362 {
363  if( !PreparePrintPrms() )
364  return;
365 
366  // Pass two printout objects: for preview, and possible printing.
367  wxString title = _( "Print Preview" );
368  wxPrintPreview* preview =
369  new wxPrintPreview( new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ),
370  new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ),
371  s_printData );
372 
373  if( preview == NULL )
374  {
375  DisplayError( this, wxT( "OnPrintPreview() problem" ) );
376  return;
377  }
378 
379 
380  // Uses the parent position and size.
381  // @todo uses last position and size ans store them when exit in m_Config
382  wxPoint WPos = m_Parent->GetPosition();
383  wxSize WSize = m_Parent->GetSize();
384 
385  wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, WPos, WSize );
386  frame->SetMinSize( wxSize( 550, 350 ) );
387 
388  frame->Initialize();
389 
390  frame->Raise(); // Needed on Ubuntu/Unity to display the frame
391  frame->Show( true );
392 }
393 
394 
395 void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event )
396 {
397  if( !PreparePrintPrms() )
398  return;
399 
400  wxPrintDialogData printDialogData( *s_printData );
401 
402  wxPrinter printer( &printDialogData );
403  wxString title = _( "Print" );
404  BOARD_PRINTOUT_CONTROLLER printout( s_Parameters, m_Parent, title );
405 
406  if( !printer.Print( this, &printout, true ) )
407  {
408  if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
409  DisplayError( this, _( "There was a problem printing" ) );
410  return;
411  }
412  else
413  {
414  *s_printData = printer.GetPrintDialogData().GetPrintData();
415  }
416 }
417 
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.
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.
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 DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:104
void OnInitDialog(wxInitDialogEvent &event)
void OnPageSetup(wxCommandEvent &event) override
wxPageSetupDialogData * m_PageSetupData
const PAGE_INFO & GetPageSettings() const override
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
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 DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:73