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