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 ), m_config( nullptr ), m_settings( aSettings )
32 {
33  // Note: for the validator, min value is 0.0, to allow typing values like 0.5
34  // that start by 0
35  m_scaleValidator.SetRange( 0.0, MAX_SCALE );
36  m_scaleCustomText->SetValidator( m_scaleValidator );
37 
38  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
39  // that requires us to correct the button labels here.
40  m_sdbSizer1OK->SetLabel( _( "Print" ) );
41  m_sdbSizer1Apply->SetLabel( _( "Print Preview" ) );
42  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
43  m_sdbSizer1->Layout();
44 
45  m_sdbSizer1OK->SetDefault();
46 
47 #if defined(__WXMAC__) or defined(__WXGTK__)
48  // Preview does not work well on GTK or Mac,
49  // but these platforms provide native print preview
50  m_sdbSizer1Apply->Hide();
51 #endif
52 
54  Layout();
55  initPrintData();
56 }
57 
58 
60 {
61 }
62 
63 
65 {
66  m_titleBlock->SetValue( aValue );
67  m_titleBlock->Hide();
68 
69  if( m_config )
70  {
72  m_settings->m_titleBlock = aValue;
74  }
75 }
76 
77 
79 {
81  m_settings->m_titleBlock = m_titleBlock->GetValue();
82  m_settings->m_blackWhite = m_outputMode->GetSelection();
83 
84  if( m_config )
86 }
87 
88 
90 {
91  if( m_scale1->GetValue() )
92  return 1.0;
93 
94  if( m_scaleFit->GetValue() )
95  return 0.0;
96 
97  if( m_scaleCustom->GetValue() )
98  {
99  double scale = 1.0;;
100 
101  if( !m_scaleCustomText->GetValue().ToDouble( &scale ) )
102  {
103  DisplayInfoMessage( nullptr, _( "Warning: Bad scale number" ) );
104  scale = 1.0;
105  }
106 
107  if( scale > MAX_SCALE )
108  {
109  scale = MAX_SCALE;
110  setScaleValue( scale );
111  DisplayInfoMessage( nullptr,
112  wxString::Format( _( "Warning: Scale option set to a very large value.\n"
113  " Clamped to %f" ), scale ) );
114  }
115  else if( scale < MIN_SCALE )
116  {
117  scale = MIN_SCALE;
118  setScaleValue( scale );
119  DisplayInfoMessage( nullptr,
120  wxString::Format( _( "Warning: Scale option set to a very small value.\n"
121  " Clamped to %f" ), scale ) );
122  }
123  return scale;
124  }
125 
126  wxCHECK( false, 1.0 );
127 }
128 
129 
131 {
132  wxASSERT( aValue >= 0.0 );
133 
134  if( aValue == 0.0 ) // fit to page
135  {
136  m_scaleFit->SetValue( true );
137  }
138  else if( aValue == 1.0 )
139  {
140  m_scale1->SetValue( true );
141  }
142  else
143  {
144  // Silently clamp the value (it comes from the config file).
145  if( aValue > MAX_SCALE )
146  aValue = MAX_SCALE;
147  else if( aValue < MIN_SCALE )
148  aValue = MIN_SCALE;
149 
150  m_scaleCustom->SetValue( true );
151  m_scaleCustomText->SetValue( wxString::Format( wxT( "%f" ), aValue ) );
152  }
153 }
154 
155 
157 {
158  if( !wxDialog::TransferDataToWindow() )
159  return false;
160 
161  if( m_config )
163 
165  m_titleBlock->SetValue( m_settings->m_titleBlock );
166  m_outputMode->SetSelection( m_settings->m_blackWhite ? 1 : 0 );
167 
168  return true;
169 }
170 
171 
172 void DIALOG_PRINT_GENERIC::onPageSetup( wxCommandEvent& event )
173 {
174  wxPageSetupDialog pageSetupDialog( this, s_pageSetupData );
175  pageSetupDialog.ShowModal();
176 
177  (*s_PrintData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
178  (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
179 }
180 
181 
182 void DIALOG_PRINT_GENERIC::onPrintPreview( wxCommandEvent& event )
183 {
184  m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
185  saveSettings();
186 
187  if( m_settings->m_pageCount == 0 )
188  {
189  DisplayError( this, _( "Nothing to print" ) );
190  return;
191  }
192 
193  // Pass two printout objects: for preview, and possible printing.
194  wxString title = _( "Print Preview" );
195  wxPrintPreview* preview =
196  new wxPrintPreview( createPrintout( title ), createPrintout( title ), s_PrintData );
197 
198  preview->SetZoom( 100 );
199 
200  wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, m_parent->GetPosition(),
201  m_parent->GetSize() );
202  frame->SetMinSize( wxSize( 550, 350 ) );
203  frame->Center();
204 
205  // On wxGTK, set the flag wxTOPLEVEL_EX_DIALOG is mandatory, if we want
206  // close the frame using the X box in caption, when the preview frame is run
207  // from a dialog
208  frame->SetExtraStyle( frame->GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
209 
210  // We use here wxPreviewFrame_WindowModal option to make the wxPrintPreview frame
211  // modal for its caller only.
212  // An other reason is the fact when closing the frame without this option,
213  // all top level frames are reenabled.
214  // With this option, only the parent is reenabled.
215  // Reenabling all top level frames should be made by the parent dialog.
216  frame->InitializeWithModality( wxPreviewFrame_WindowModal );
217 
218  frame->Raise(); // Needed on Ubuntu/Unity to display the frame
219  frame->Show( true );
220 }
221 
222 
223 void DIALOG_PRINT_GENERIC::onPrintButtonClick( wxCommandEvent& event )
224 {
225  if( Pgm().m_Printing )
226  {
227  DisplayError( this, _( "Previous print job not yet complete." ) );
228  return;
229  }
230 
231  m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
232  saveSettings();
233 
234  if( m_settings->m_pageCount == 0 )
235  {
236  DisplayError( this, _( "Nothing to print" ) );
237  return;
238  }
239 
240  wxPrintDialogData printDialogData( *s_PrintData );
241  printDialogData.SetMaxPage( m_settings->m_pageCount );
242 
243  wxPrinter printer( &printDialogData );
244  auto printout = std::unique_ptr<wxPrintout>( createPrintout( _( "Print" ) ) );
245 
246  Pgm().m_Printing = true;
247  {
248  if( !printer.Print( this, printout.get(), true ) )
249  {
250  if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
251  DisplayError( this, _( "There was a problem printing." ) );
252  }
253  else
254  {
255  *s_PrintData = printer.GetPrintDialogData().GetPrintData();
256  }
257  }
258  Pgm().m_Printing = false;
259 }
260 
261 
262 void DIALOG_PRINT_GENERIC::onCloseButton( wxCommandEvent& event )
263 {
264  saveSettings();
265 
266  if( IsQuasiModal() )
267  EndQuasiModal( wxID_CANCEL );
268 
269  if( IsModal() )
270  EndModal( wxID_CANCEL );
271 
272  Close();
273 }
274 
275 
276 void DIALOG_PRINT_GENERIC::onClose( wxCloseEvent& event )
277 {
278  saveSettings();
279  event.Skip();
280 }
281 
282 
283 void DIALOG_PRINT_GENERIC::onSetCustomScale( wxCommandEvent& event )
284 {
285  // Select 'custom scale' radio button when user types in a value in the
286  // custom scale text box
287  m_scaleCustom->SetValue( true );
288 }
289 
290 
292 {
293  if( !s_PrintData ) // First print
294  {
295  s_PrintData = new wxPrintData();
296 
297  if( !s_PrintData->Ok() )
298  DisplayError( this, _( "An error occurred initializing the printer information." ) );
299 
300  s_PrintData->SetQuality( wxPRINT_QUALITY_HIGH ); // Default resolution = HIGH;
301  }
302 
303  if( !s_pageSetupData )
304  {
305  const PAGE_INFO& pageInfo = m_settings->m_pageInfo;
306 
307  s_pageSetupData = new wxPageSetupDialogData( *s_PrintData );
308  s_pageSetupData->SetPaperId( pageInfo.GetPaperId() );
309  s_pageSetupData->GetPrintData().SetOrientation( pageInfo.GetWxOrientation() );
310 
311  if( pageInfo.IsCustom() )
312  {
313  if( pageInfo.IsPortrait() )
314  s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetWidthMils() ),
315  Mils2mm( pageInfo.GetHeightMils() ) ) );
316  else
317  s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetHeightMils() ),
318  Mils2mm( pageInfo.GetWidthMils() ) ) );
319  }
320 
321  *s_PrintData = s_pageSetupData->GetPrintData();
322  }
323 }
324 
325 
326 wxPrintData* DIALOG_PRINT_GENERIC::s_PrintData = nullptr;
327 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:236
double getScaleValue()
Return scale value selected in the dialog.
const PAGE_INFO & m_pageInfo
Definition: printout.h:48
wxPrintOrientation GetWxOrientation() const
Function GetWxOrientation.
Definition: page_info.h:127
Class PRINT_PARAMETERS handles the parameters used to print a board drawing.
Definition: printout.h:30
This file is part of the common library.
int GetHeightMils() const
Definition: page_info.h:140
virtual void Save(wxConfigBase *aConfig)
Definition: printout.cpp:23
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
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:65
Class DIALOG_PRINT_GENERIC_BASE.
bool IsCustom() const
Function IsCustom returns true if the type is Custom.
Definition: page_info.cpp:176
The base class for create windows for drawing purpose.
static constexpr double MIN_SCALE
wxPaperSize GetPaperId() const
Function GetPaperId.
Definition: page_info.h:134
double m_scale
Printing scale.
Definition: printout.h:44
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:45
static constexpr double MAX_SCALE
PRINTOUT_SETTINGS * m_settings
Class PAGE_INFO describes the page size and margins of a paper page on which to eventually print or p...
Definition: page_info.h:54
static wxPrintData * s_PrintData
int Mils2mm(double x)
Convert mils to mm.
Definition: base_units.h:54
bool IsQuasiModal()
Definition: dialog_shim.h:127
#define _(s)
virtual void Load(wxConfigBase *aConfig)
Definition: printout.cpp:31
bool m_blackWhite
Print in B&W or Color.
Definition: printout.h:46
bool TransferDataToWindow() override
void EndQuasiModal(int retCode)
bool m_Printing
wxWidgets on MSW tends to crash if you spool up more than one print job at a time.
Definition: pgm_base.h:368
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:205
bool IsPortrait() const
Definition: page_info.h:121
int m_pageCount
Number of pages to print.
Definition: printout.h:47
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:265
void onPrintPreview(wxCommandEvent &event) override
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:137
wxFloatingPointValidator< double > m_scaleValidator