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 <draw_frame.h>
23 #include <printout.h>
24 #include <enabler.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 {
34  m_scaleCustomText->SetValidator( m_scaleValidator );
35 
36  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
37  // that requires us to correct the button labels here.
38  m_sdbSizer1OK->SetLabel( _( "Print" ) );
39  m_sdbSizer1Apply->SetLabel( _( "Print Preview" ) );
40  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
41  m_sdbSizer1->Layout();
42 
43  m_sdbSizer1OK->SetDefault();
44 
45 #if defined(__WXMAC__) or defined(__WXGTK__)
46  // Preview does not work well on GTK or Mac,
47  // but these platforms provide native print preview
48  m_sdbSizer1Apply->Hide();
49 #endif
50 
52  Layout();
53  initPrintData();
54 }
55 
56 
58 {
59 }
60 
61 
63 {
64  m_titleBlock->SetValue( aValue );
65  m_titleBlock->Hide();
66 
67  if( m_config )
68  {
70  m_settings->m_titleBlock = aValue;
72  }
73 }
74 
75 
77 {
79  m_settings->m_titleBlock = m_titleBlock->GetValue();
80  m_settings->m_blackWhite = m_outputMode->GetSelection();
81 
82  if( m_config )
84 }
85 
86 
88 {
89  if( m_scale1->GetValue() )
90  return 1.0;
91 
92  if( m_scaleFit->GetValue() )
93  return 0.0;
94 
95  if( m_scaleCustom->GetValue() )
96  {
97  double scale;
98 
99  wxCHECK( m_scaleCustomText->GetValue().ToDouble( &scale ), 1.0 );
100  return scale;
101  }
102 
103  wxCHECK( false, 1.0 );
104 }
105 
106 
108 {
109  wxASSERT( aValue >= 0.0 );
110 
111  if( aValue == 0.0 ) // fit to page
112  {
113  m_scaleFit->SetValue( true );
114  }
115  else if( aValue == 1.0 )
116  {
117  m_scale1->SetValue( true );
118  }
119  else
120  {
121  if( aValue > MAX_SCALE )
122  {
123  DisplayInfoMessage( nullptr, _( "Warning: Scale option set to a very large value" ) );
124  }
125  else if( aValue < MIN_SCALE )
126  {
127  DisplayInfoMessage( nullptr, _( "Warning: Scale option set to a very small value" ) );
128  }
129 
130  m_scaleCustom->SetValue( true );
131  m_scaleCustomText->SetValue( wxString::Format( wxT( "%f" ), aValue ) );
132  }
133 }
134 
135 
137 {
138  if( !wxDialog::TransferDataToWindow() )
139  return false;
140 
141  if( m_config )
143 
145  m_titleBlock->SetValue( m_settings->m_titleBlock );
146  m_outputMode->SetSelection( m_settings->m_blackWhite ? 1 : 0 );
147 
148  return true;
149 }
150 
151 
152 void DIALOG_PRINT_GENERIC::onPageSetup( wxCommandEvent& event )
153 {
154  wxPageSetupDialog pageSetupDialog( this, s_pageSetupData );
155  pageSetupDialog.ShowModal();
156 
157  (*s_PrintData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
158  (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
159 }
160 
161 
162 void DIALOG_PRINT_GENERIC::onPrintPreview( wxCommandEvent& event )
163 {
164  m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
165  saveSettings();
166 
167  if( m_settings->m_pageCount == 0 )
168  {
169  DisplayError( this, _( "Nothing to print" ) );
170  return;
171  }
172 
173  // Pass two printout objects: for preview, and possible printing.
174  wxString title = _( "Print Preview" );
175  wxPrintPreview* preview =
176  new wxPrintPreview( createPrintout( title ), createPrintout( title ), s_PrintData );
177 
178  preview->SetZoom( 100 );
179 
180  wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, m_parent->GetPosition(),
181  m_parent->GetSize() );
182  frame->SetMinSize( wxSize( 550, 350 ) );
183  frame->Center();
184 
185  // On wxGTK, set the flag wxTOPLEVEL_EX_DIALOG is mandatory, if we want
186  // close the frame using the X box in caption, when the preview frame is run
187  // from a dialog
188  frame->SetExtraStyle( frame->GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
189 
190  // We use here wxPreviewFrame_WindowModal option to make the wxPrintPreview frame
191  // modal for its caller only.
192  // An other reason is the fact when closing the frame without this option,
193  // all top level frames are reenabled.
194  // With this option, only the parent is reenabled.
195  // Reenabling all top level frames should be made by the parent dialog.
196  frame->InitializeWithModality( wxPreviewFrame_WindowModal );
197 
198  frame->Raise(); // Needed on Ubuntu/Unity to display the frame
199  frame->Show( true );
200 }
201 
202 
203 void DIALOG_PRINT_GENERIC::onPrintButtonClick( wxCommandEvent& event )
204 {
205  m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
206  saveSettings();
207 
208  if( m_settings->m_pageCount == 0 )
209  {
210  DisplayError( this, _( "Nothing to print" ) );
211  return;
212  }
213 
214  wxPrintDialogData printDialogData( *s_PrintData );
215  printDialogData.SetMaxPage( m_settings->m_pageCount );
216 
217  wxPrinter printer( &printDialogData );
218  auto printout = std::unique_ptr<wxPrintout>( createPrintout( _( "Print" ) ) );
219 
220  // Disable 'Print' button to prevent issuing another print
221  // command before the previous one is finished (causes problems on Windows)
222  ENABLER printBtnDisable( *m_sdbSizer1OK, false );
223 
224  if( !printer.Print( this, printout.get(), true ) )
225  {
226  if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
227  DisplayError( this, _( "There was a problem printing." ) );
228  }
229  else
230  {
231  *s_PrintData = printer.GetPrintDialogData().GetPrintData();
232  }
233 }
234 
235 
236 void DIALOG_PRINT_GENERIC::onCloseButton( wxCommandEvent& event )
237 {
238  saveSettings();
239 
240  if( IsQuasiModal() )
241  EndQuasiModal( wxID_CANCEL );
242 
243  if( IsModal() )
244  EndModal( wxID_CANCEL );
245 
246  Close();
247 }
248 
249 
250 void DIALOG_PRINT_GENERIC::onClose( wxCloseEvent& event )
251 {
252  saveSettings();
253  event.Skip();
254 }
255 
256 
257 void DIALOG_PRINT_GENERIC::onSetCustomScale( wxCommandEvent& event )
258 {
259  // Select 'custom scale' radio button when user types in a value in the
260  // custom scale text box
261  m_scaleCustom->SetValue( true );
262 }
263 
264 
266 {
267  if( !s_PrintData ) // First print
268  {
269  s_PrintData = new wxPrintData();
270 
271  if( !s_PrintData->Ok() )
272  DisplayError( this, _( "An error occurred initializing the printer information." ) );
273 
274  s_PrintData->SetQuality( wxPRINT_QUALITY_HIGH ); // Default resolution = HIGH;
275  }
276 
277  if( !s_pageSetupData )
278  {
279  const PAGE_INFO& pageInfo = m_settings->m_pageInfo;
280 
281  s_pageSetupData = new wxPageSetupDialogData( *s_PrintData );
282  s_pageSetupData->SetPaperId( pageInfo.GetPaperId() );
283  s_pageSetupData->GetPrintData().SetOrientation( pageInfo.GetWxOrientation() );
284 
285  if( pageInfo.IsCustom() )
286  {
287  if( pageInfo.IsPortrait() )
288  s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetWidthMils() ),
289  Mils2mm( pageInfo.GetHeightMils() ) ) );
290  else
291  s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetHeightMils() ),
292  Mils2mm( pageInfo.GetWidthMils() ) ) );
293  }
294 
295  *s_PrintData = s_pageSetupData->GetPrintData();
296  }
297 }
298 
299 
300 wxPrintData* DIALOG_PRINT_GENERIC::s_PrintData = nullptr;
301 wxPageSetupDialogData* DIALOG_PRINT_GENERIC::s_pageSetupData = nullptr;
const PAGE_INFO & m_pageInfo
Definition: printout.h:48
Class PRINT_PARAMETERS handles the parameters used to print a board drawing.
Definition: printout.h:30
This file is part of the common library.
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
Class DIALOG_PRINT_GENERIC_BASE.
The base class for create windows for drawing purpose.
Definition: draw_frame.h:78
static constexpr double MIN_SCALE
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
bool IsPortrait() const
Definition: page_info.h:121
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:52
bool IsQuasiModal()
Definition: dialog_shim.h:124
int GetWidthMils() const
Definition: page_info.h:137
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 IsCustom() const
Function IsCustom returns true if the type is Custom.
Definition: page_info.cpp:176
const int scale
wxPaperSize GetPaperId() const
Function GetPaperId.
Definition: page_info.h:134
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
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 &#39;print border and title block&#39; to a requested value and hides the corresponding checkbox...
wxPrintOrientation GetWxOrientation() const
Function GetWxOrientation.
Definition: page_info.h:127
double getScaleValue() const
Return scale value selected in the dialog.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:277
void onPrintPreview(wxCommandEvent &event) override
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
void onSetCustomScale(wxCommandEvent &event) override
int GetHeightMils() const
Definition: page_info.h:140
Simple class to automatically enable/disable widgets.
Definition: enabler.h:29
wxStdDialogButtonSizer * m_sdbSizer1
virtual wxPrintout * createPrintout(const wxString &aTitle)=0
Create a printout with a requested title.
wxFloatingPointValidator< double > m_scaleValidator