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