KiCad PCB EDA Suite
dialog_print_generic.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 CERN
3  * Author: Maciej Suminski <maciej.suminski@cern.ch>
4  *
5  * This program is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation, either version 3 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "dialog_print_generic.h"
20 
21 #include <confirm.h>
22 #include <eda_draw_frame.h>
23 #include <printout.h>
24 #include <pgm_base.h>
25 
26 // Define min and max reasonable values for print scale
27 static constexpr double MIN_SCALE = 0.01;
28 static constexpr double MAX_SCALE = 100.0;
29 
31  : DIALOG_PRINT_GENERIC_BASE( aParent ),
32  m_config( nullptr ),
33  m_settings( aSettings )
34 {
35  // Note: for the validator, min value is 0.0, to allow typing values like 0.5
36  // that start by 0
37  m_scaleValidator.SetRange( 0.0, MAX_SCALE );
38  m_scaleCustomText->SetValidator( m_scaleValidator );
39 
40  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
41  // that requires us to correct the button labels here.
42  m_sdbSizer1OK->SetLabel( _( "Print" ) );
43  m_sdbSizer1Apply->SetLabel( _( "Print Preview" ) );
44  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
45  m_sdbSizer1->Layout();
46 
47  m_sdbSizer1OK->SetDefault();
48 
49 #if defined(__WXMAC__) or defined(__WXGTK__)
50  // Preview does not work well on GTK or Mac,
51  // but these platforms provide native print preview
52  m_sdbSizer1Apply->Hide();
53 #endif
54 
56  Layout();
57  initPrintData();
58 }
59 
60 
62 {
63 }
64 
65 
67 {
68  m_titleBlock->SetValue( aValue );
69  m_titleBlock->Hide();
70 
71  if( m_config )
72  {
74  m_settings->m_titleBlock = aValue;
76  }
77 }
78 
79 
81 {
83  m_settings->m_titleBlock = m_titleBlock->GetValue();
84  m_settings->m_blackWhite = m_outputMode->GetSelection();
85 
86  if( m_config )
88 }
89 
90 
92 {
93  if( m_scale1->GetValue() )
94  return 1.0;
95 
96  if( m_scaleFit->GetValue() )
97  return 0.0;
98 
99  if( m_scaleCustom->GetValue() )
100  {
101  double scale = 1.0;;
102 
103  if( !m_scaleCustomText->GetValue().ToDouble( &scale ) )
104  {
105  DisplayInfoMessage( nullptr, _( "Warning: Bad scale number" ) );
106  scale = 1.0;
107  }
108 
109  if( scale > MAX_SCALE )
110  {
111  scale = MAX_SCALE;
112  setScaleValue( scale );
113  DisplayInfoMessage( nullptr,
114  wxString::Format( _( "Warning: Scale option set to a very large value.\n"
115  " Clamped to %f" ), scale ) );
116  }
117  else if( scale < MIN_SCALE )
118  {
119  scale = MIN_SCALE;
120  setScaleValue( scale );
121  DisplayInfoMessage( nullptr,
122  wxString::Format( _( "Warning: Scale option set to a very small value.\n"
123  " Clamped to %f" ), scale ) );
124  }
125  return scale;
126  }
127 
128  wxCHECK( false, 1.0 );
129 }
130 
131 
133 {
134  wxASSERT( aValue >= 0.0 );
135 
136  if( aValue == 0.0 ) // fit to page
137  {
138  m_scaleFit->SetValue( true );
139  }
140  else if( aValue == 1.0 )
141  {
142  m_scale1->SetValue( true );
143  }
144  else
145  {
146  // Silently clamp the value (it comes from the config file).
147  if( aValue > MAX_SCALE )
148  aValue = MAX_SCALE;
149  else if( aValue < MIN_SCALE )
150  aValue = MIN_SCALE;
151 
152  m_scaleCustom->SetValue( true );
153  m_scaleCustomText->SetValue( wxString::Format( wxT( "%f" ), aValue ) );
154  }
155 }
156 
157 
159 {
160  if( !wxDialog::TransferDataToWindow() )
161  return false;
162 
163  if( m_config )
165 
167  m_titleBlock->SetValue( m_settings->m_titleBlock );
168  m_outputMode->SetSelection( m_settings->m_blackWhite ? 1 : 0 );
169 
170  return true;
171 }
172 
173 
174 void DIALOG_PRINT_GENERIC::onPageSetup( wxCommandEvent& event )
175 {
176  wxPageSetupDialog pageSetupDialog( this, s_pageSetupData );
177  pageSetupDialog.ShowModal();
178 
179  (*s_PrintData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
180  (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
181 }
182 
183 
184 void DIALOG_PRINT_GENERIC::onPrintPreview( wxCommandEvent& event )
185 {
186  m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
187  saveSettings();
188 
189  if( m_settings->m_pageCount == 0 )
190  {
191  DisplayError( this, _( "Nothing to print" ) );
192  return;
193  }
194 
195  // Pass two printout objects: for preview, and possible printing.
196  wxString title = _( "Print Preview" );
197  wxPrintPreview* preview =
198  new wxPrintPreview( createPrintout( title ), createPrintout( title ), s_PrintData );
199 
200  preview->SetZoom( 100 );
201 
202  wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, m_parent->GetPosition(),
203  m_parent->GetSize() );
204  frame->SetMinSize( wxSize( 550, 350 ) );
205  frame->Center();
206 
207  // On wxGTK, set the flag wxTOPLEVEL_EX_DIALOG is mandatory, if we want
208  // close the frame using the X box in caption, when the preview frame is run
209  // from a dialog
210  frame->SetExtraStyle( frame->GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
211 
212  // We use here wxPreviewFrame_WindowModal option to make the wxPrintPreview frame
213  // modal for its caller only.
214  // An other reason is the fact when closing the frame without this option,
215  // all top level frames are reenabled.
216  // With this option, only the parent is reenabled.
217  // Reenabling all top level frames should be made by the parent dialog.
218  frame->InitializeWithModality( wxPreviewFrame_WindowModal );
219 
220  frame->Raise(); // Needed on Ubuntu/Unity to display the frame
221  frame->Show( true );
222 }
223 
224 
225 void DIALOG_PRINT_GENERIC::onPrintButtonClick( wxCommandEvent& event )
226 {
227  if( Pgm().m_Printing )
228  {
229  DisplayError( this, _( "Previous print job not yet complete." ) );
230  return;
231  }
232 
233  m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
234  saveSettings();
235 
236  if( m_settings->m_pageCount == 0 )
237  {
238  DisplayError( this, _( "Nothing to print" ) );
239  return;
240  }
241 
242  wxPrintDialogData printDialogData( *s_PrintData );
243  printDialogData.SetMaxPage( m_settings->m_pageCount );
244 
245  wxPrinter printer( &printDialogData );
246  auto printout = std::unique_ptr<wxPrintout>( createPrintout( _( "Print" ) ) );
247 
248  Pgm().m_Printing = true;
249  {
250  if( !printer.Print( this, printout.get(), true ) )
251  {
252  if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
253  DisplayError( this, _( "There was a problem printing." ) );
254  }
255  else
256  {
257  *s_PrintData = printer.GetPrintDialogData().GetPrintData();
258  }
259  }
260  Pgm().m_Printing = false;
261 }
262 
263 
264 void DIALOG_PRINT_GENERIC::onCloseButton( wxCommandEvent& event )
265 {
266  saveSettings();
267 
268  if( IsQuasiModal() )
269  EndQuasiModal( wxID_CANCEL );
270 
271  if( IsModal() )
272  EndModal( wxID_CANCEL );
273 
274  Close();
275 }
276 
277 
278 void DIALOG_PRINT_GENERIC::onClose( wxCloseEvent& event )
279 {
280  saveSettings();
281  event.Skip();
282 }
283 
284 
285 void DIALOG_PRINT_GENERIC::onSetCustomScale( wxCommandEvent& event )
286 {
287  // Select 'custom scale' radio button when user types in a value in the
288  // custom scale text box
289  m_scaleCustom->SetValue( true );
290 }
291 
292 
294 {
295  if( !s_PrintData ) // First print
296  {
297  s_PrintData = new wxPrintData();
298 
299  if( !s_PrintData->Ok() )
300  DisplayError( this, _( "An error occurred initializing the printer information." ) );
301 
302  s_PrintData->SetQuality( wxPRINT_QUALITY_HIGH ); // Default resolution = HIGH;
303  }
304 
305  if( !s_pageSetupData )
306  {
307  const PAGE_INFO& pageInfo = m_settings->m_pageInfo;
308 
309  s_pageSetupData = new wxPageSetupDialogData( *s_PrintData );
310  s_pageSetupData->SetPaperId( pageInfo.GetPaperId() );
311  s_pageSetupData->GetPrintData().SetOrientation( pageInfo.GetWxOrientation() );
312 
313  if( pageInfo.IsCustom() )
314  {
315  if( pageInfo.IsPortrait() )
316  s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetWidthMils() ),
317  Mils2mm( pageInfo.GetHeightMils() ) ) );
318  else
319  s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetHeightMils() ),
320  Mils2mm( pageInfo.GetWidthMils() ) ) );
321  }
322 
323  *s_PrintData = s_pageSetupData->GetPrintData();
324  }
325 }
326 
327 
328 wxPrintData* DIALOG_PRINT_GENERIC::s_PrintData = nullptr;
329 wxPageSetupDialogData* DIALOG_PRINT_GENERIC::s_pageSetupData = nullptr;
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
double getScaleValue()
Return scale value selected in the dialog.
const PAGE_INFO & m_pageInfo
Definition: printout.h:56
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:104
wxPrintOrientation GetWxOrientation() const
Function GetWxOrientation.
Definition: page_info.h:128
virtual void Save(APP_SETTINGS_BASE *aConfig)
Definition: printout.cpp:24
PRINT_PARAMETERS handles the parameters used to print a board drawing.
Definition: printout.h:31
This file is part of the common library.
int GetHeightMils() const
Definition: page_info.h:141
void onCloseButton(wxCommandEvent &event) override
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void onPageSetup(wxCommandEvent &event) override
Class DIALOG_PRINT_GENERIC_BASE.
bool IsCustom() const
Function IsCustom returns true if the type is Custom.
Definition: page_info.cpp:180
The base class for create windows for drawing purpose.
static constexpr double MIN_SCALE
wxPaperSize GetPaperId() const
Function GetPaperId.
Definition: page_info.h:135
virtual void Load(APP_SETTINGS_BASE *aConfig)
Definition: printout.cpp:32
double m_scale
Printing scale.
Definition: printout.h:51
void onPrintButtonClick(wxCommandEvent &event) override
void setScaleValue(double aValue)
Select a corresponding scale radio button and update custom scale value if needed.
bool m_titleBlock
Print frame and title block.
Definition: printout.h:52
static constexpr double MAX_SCALE
PRINTOUT_SETTINGS * m_settings
PAGE_INFO describes the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
static wxPrintData * s_PrintData
int Mils2mm(double x)
Convert mils to mm.
Definition: base_units.h:65
bool IsQuasiModal()
Definition: dialog_shim.h:123
bool m_blackWhite
Print in B&W or Color.
Definition: printout.h:53
bool TransferDataToWindow() override
void EndQuasiModal(int retCode)
const int scale
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
bool IsPortrait() const
Definition: page_info.h:122
#define _(s)
Definition: 3d_actions.cpp:33
int m_pageCount
Number of pages to print.
Definition: printout.h:54
static wxPageSetupDialogData * s_pageSetupData
DIALOG_PRINT_GENERIC(EDA_DRAW_FRAME *aParent, PRINTOUT_SETTINGS *aSettings)
void onClose(wxCloseEvent &event) override
void ForcePrintBorder(bool aValue)
Set 'print border and title block' to a requested value and hides the corresponding checkbox.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:267
void onPrintPreview(wxCommandEvent &event) override
APP_SETTINGS_BASE * m_config
void onSetCustomScale(wxCommandEvent &event) override
wxStdDialogButtonSizer * m_sdbSizer1
virtual wxPrintout * createPrintout(const wxString &aTitle)=0
Create a printout with a requested title.
int GetWidthMils() const
Definition: page_info.h:138
wxFloatingPointValidator< double > m_scaleValidator