KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_print_generic.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018 CERN
3 * Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
4 * Author: Maciej Suminski <[email protected]>
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 <eda_draw_frame.h>
23#include <printout.h>
24#include <pgm_base.h>
25#include <confirm.h>
26
27#include <wx/print.h>
28#include <wx/printdlg.h>
29
30// Define min and max reasonable values for print scale
31static constexpr double MIN_SCALE = 0.01;
32static constexpr double MAX_SCALE = 100.0;
33
34
35
40class KI_PREVIEW_FRAME : public wxPreviewFrame
41{
42public:
43 KI_PREVIEW_FRAME( wxPrintPreview* aPreview, wxWindow* aParent,
44 const wxString& aTitle, const wxPoint& aPos = wxDefaultPosition,
45 const wxSize& aSize = wxDefaultSize ) :
46 wxPreviewFrame( aPreview, aParent, aTitle, aPos, aSize )
47 {
48 }
49
50 bool Show( bool show ) override
51 {
52 bool ret;
53
54 // Show or hide the window. If hiding, save current position and size.
55 // If showing, use previous position and size.
56 if( show )
57 {
58 ret = wxPreviewFrame::Show( show );
59
60 if( s_size.x != 0 && s_size.y != 0 )
61 SetSize( s_pos.x, s_pos.y, s_size.x, s_size.y, 0 );
62 }
63 else
64 {
65 // Save the dialog's position & size before hiding
66 s_size = GetSize();
67 s_pos = GetPosition();
68
69 ret = wxPreviewFrame::Show( show );
70 }
71
72 return ret;
73 }
74
75private:
76 static wxPoint s_pos;
77 static wxSize s_size;
78};
79
80
83
84
86 : DIALOG_PRINT_GENERIC_BASE( aParent ),
87 m_config( nullptr ),
88 m_settings( aSettings )
89{
90 // Note: for the validator, min value is 0.0, to allow typing values like 0.5
91 // that start by 0
92 m_scaleValidator.SetRange( 0.0, MAX_SCALE );
93 m_scaleCustomText->SetValidator( m_scaleValidator );
94
95 SetupStandardButtons( { { wxID_OK, _( "Print" ) },
96 { wxID_APPLY, _( "Print Preview" ) },
97 { wxID_CANCEL, _( "Close" ) } } );
98
99#if defined(__WXMAC__) or defined(__WXGTK__)
100 // Preview does not work well on GTK or Mac,
101 // but these platforms provide native print preview
102 m_sdbSizer1Apply->Hide();
103#endif
104
106 Layout();
108}
109
110
112{
113}
114
115
117{
118 m_titleBlock->SetValue( aValue );
119 m_titleBlock->Hide();
120
121 if( m_config )
122 {
124 m_settings->m_titleBlock = aValue;
126 }
127}
128
129
131{
133 m_settings->m_titleBlock = m_titleBlock->GetValue();
134 m_settings->m_blackWhite = m_outputMode->GetSelection();
135
136 if( m_config )
138}
139
140
142{
143 if( m_scale1->GetValue() )
144 return 1.0;
145
146 if( m_scaleFit->GetValue() )
147 return 0.0;
148
149 if( m_scaleCustom->GetValue() )
150 {
151 double scale = 1.0;;
152
153 if( !m_scaleCustomText->GetValue().ToDouble( &scale ) )
154 {
155 DisplayInfoMessage( nullptr, _( "Warning: scale is not a number." ) );
156 scale = 1.0;
157 }
158
159 if( scale > MAX_SCALE )
160 {
163 DisplayInfoMessage( nullptr, wxString::Format( _( "Warning: scale set to a very large "
164 "value.\nIt will be clamped to %f." ),
165 scale ) );
166 }
167 else if( scale < MIN_SCALE )
168 {
171 DisplayInfoMessage( nullptr, wxString::Format( _( "Warning: scale set to a very small "
172 "value.\nIt will be clamped to %f." ),
173 scale ) );
174 }
175
176 return scale;
177 }
178
179 wxFAIL_MSG( wxT( "No scale option selected." ) );
180 return 1.0;
181}
182
183
185{
186 wxASSERT( aValue >= 0.0 );
187
188 if( aValue == 0.0 ) // fit to page
189 {
190 m_scaleFit->SetValue( true );
191 }
192 else if( aValue == 1.0 )
193 {
194 m_scale1->SetValue( true );
195 }
196 else
197 {
198 // Silently clamp the value (it comes from the config file).
199 if( aValue > MAX_SCALE )
200 aValue = MAX_SCALE;
201 else if( aValue < MIN_SCALE )
202 aValue = MIN_SCALE;
203
204 m_scaleCustom->SetValue( true );
205 m_scaleCustomText->SetValue( wxString::Format( wxT( "%f" ), aValue ) );
206 }
207}
208
209
211{
212 if( !wxDialog::TransferDataToWindow() )
213 return false;
214
215 if( m_config )
217
220 m_outputMode->SetSelection( m_settings->m_blackWhite ? 1 : 0 );
221
222 return true;
223}
224
225
226void DIALOG_PRINT_GENERIC::onPageSetup( wxCommandEvent& event )
227{
228 wxPageSetupDialog pageSetupDialog( this, s_pageSetupData );
229 pageSetupDialog.ShowModal();
230
231 (*s_PrintData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
232 (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
233}
234
235
236void DIALOG_PRINT_GENERIC::onPrintPreview( wxCommandEvent& event )
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 // Pass two printout objects: for preview, and possible printing.
248 wxString title = _( "Print Preview" );
249 wxPrintPreview* preview =
250 new wxPrintPreview( createPrintout( title ), createPrintout( title ), s_PrintData );
251
252 preview->SetZoom( 100 );
253
254 KI_PREVIEW_FRAME* frame = new KI_PREVIEW_FRAME( preview, this, title );
255
256 // On wxGTK, set the flag wxTOPLEVEL_EX_DIALOG is mandatory, if we want
257 // close the frame using the X box in caption, when the preview frame is run
258 // from a dialog
259 frame->SetExtraStyle( frame->GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
260
261 // We use here wxPreviewFrame_WindowModal option to make the wxPrintPreview frame
262 // modal for its caller only.
263 // An other reason is the fact when closing the frame without this option,
264 // all top level frames are reenabled.
265 // With this option, only the parent is reenabled.
266 // Reenabling all top level frames should be made by the parent dialog.
267 frame->InitializeWithModality( wxPreviewFrame_WindowModal );
268
269 // on first invocation in this runtime session, set to 3/4 size of parent,
270 // but will be changed in Show() if not first time as will position.
271 // Must be called after InitializeWithModality because otherwise in some wxWidget
272 // versions it is not always taken in account
273 frame->SetMinSize( wxSize( 650, 500 ) );
274 frame->SetSize( (m_parent->GetSize() * 3) / 4 );
275
276 frame->Raise(); // Needed on Ubuntu/Unity to display the frame
277 frame->Show( true );
278}
279
280
281void DIALOG_PRINT_GENERIC::onPrintButtonClick( wxCommandEvent& event )
282{
283 if( Pgm().m_Printing )
284 {
285 DisplayError( this, _( "Previous print job not yet complete." ) );
286 return;
287 }
288
289 m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
290 saveSettings();
291
292 if( m_settings->m_pageCount == 0 )
293 {
294 DisplayError( this, _( "Nothing to print" ) );
295 return;
296 }
297
298 wxPrintDialogData printDialogData( *s_PrintData );
299 printDialogData.SetMaxPage( m_settings->m_pageCount );
300
301 wxPrinter printer( &printDialogData );
302 auto printout = std::unique_ptr<wxPrintout>( createPrintout( _( "Print" ) ) );
303
304 Pgm().m_Printing = true;
305
306 {
307 if( !printer.Print( this, printout.get(), true ) )
308 {
309 if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
310 DisplayError( this, _( "There was a problem printing." ) );
311 }
312 else
313 {
314 *s_PrintData = printer.GetPrintDialogData().GetPrintData();
315 }
316 }
317
318 Pgm().m_Printing = false;
319}
320
321
322void DIALOG_PRINT_GENERIC::onCancelButtonClick( wxCommandEvent& event )
323{
324 saveSettings();
325
326 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL ) );
327}
328
329
330void DIALOG_PRINT_GENERIC::onClose( wxCloseEvent& event )
331{
332 saveSettings();
333 event.Skip();
334}
335
336
337void DIALOG_PRINT_GENERIC::onSetCustomScale( wxCommandEvent& event )
338{
339 // Select 'custom scale' radio button when user types in a value in the
340 // custom scale text box
341 m_scaleCustom->SetValue( true );
342}
343
344
346{
347 if( !s_PrintData ) // First print
348 {
349 s_PrintData = new wxPrintData();
350
351 if( !s_PrintData->Ok() )
352 DisplayError( this, _( "An error occurred initializing the printer information." ) );
353
354 s_PrintData->SetQuality( wxPRINT_QUALITY_HIGH ); // Default resolution = HIGH;
355 }
356
357 if( !s_pageSetupData )
358 {
359 const PAGE_INFO& pageInfo = m_settings->m_pageInfo;
360
361 s_pageSetupData = new wxPageSetupDialogData( *s_PrintData );
362 s_pageSetupData->SetPaperId( pageInfo.GetPaperId() );
363 s_pageSetupData->GetPrintData().SetOrientation( pageInfo.GetWxOrientation() );
364
365 if( pageInfo.IsCustom() )
366 {
367 if( pageInfo.IsPortrait() )
368 s_pageSetupData->SetPaperSize( wxSize( EDA_UNIT_UTILS::Mils2mm( pageInfo.GetWidthMils() ),
369 EDA_UNIT_UTILS::Mils2mm( pageInfo.GetHeightMils() ) ) );
370 else
371 s_pageSetupData->SetPaperSize( wxSize( EDA_UNIT_UTILS::Mils2mm( pageInfo.GetHeightMils() ),
372 EDA_UNIT_UTILS::Mils2mm( pageInfo.GetWidthMils() ) ) );
373 }
374
375 *s_PrintData = s_pageSetupData->GetPrintData();
376 }
377}
378
379
380wxPrintData* DIALOG_PRINT_GENERIC::s_PrintData = nullptr;
381wxPageSetupDialogData* DIALOG_PRINT_GENERIC::s_pageSetupData = nullptr;
Class DIALOG_PRINT_GENERIC_BASE.
APP_SETTINGS_BASE * m_config
DIALOG_PRINT_GENERIC(EDA_DRAW_FRAME *aParent, PRINTOUT_SETTINGS *aSettings)
void onClose(wxCloseEvent &event) override
void setScaleValue(double aValue)
Select a corresponding scale radio button and update custom scale value if needed.
void onSetCustomScale(wxCommandEvent &event) override
static wxPrintData * s_PrintData
void onCancelButtonClick(wxCommandEvent &aEvent) override
virtual wxPrintout * createPrintout(const wxString &aTitle)=0
Create a printout with a requested title.
bool TransferDataToWindow() override
void onPageSetup(wxCommandEvent &event) override
double getScaleValue()
Return scale value selected in the dialog.
void onPrintButtonClick(wxCommandEvent &event) override
wxFloatingPointValidator< double > m_scaleValidator
void ForcePrintBorder(bool aValue)
Set 'print border and title block' to a requested value and hides the corresponding checkbox.
static wxPageSetupDialogData * s_pageSetupData
void onPrintPreview(wxCommandEvent &event) override
PRINTOUT_SETTINGS * m_settings
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
The base class for create windows for drawing purpose.
Custom print preview frame.
bool Show(bool show) override
KI_PREVIEW_FRAME(wxPrintPreview *aPreview, wxWindow *aParent, const wxString &aTitle, const wxPoint &aPos=wxDefaultPosition, const wxSize &aSize=wxDefaultSize)
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:59
wxPrintOrientation GetWxOrientation() const
Definition: page_info.h:127
double GetHeightMils() const
Definition: page_info.h:141
wxPaperSize GetPaperId() const
Definition: page_info.h:132
double GetWidthMils() const
Definition: page_info.h:136
bool IsCustom() const
Definition: page_info.cpp:183
bool IsPortrait() const
Definition: page_info.h:122
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:386
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:222
This file is part of the common library.
static constexpr double MAX_SCALE
static constexpr double MIN_SCALE
#define _(s)
KICOMMON_API int Mils2mm(double aVal)
Convert mils to mm.
Definition: eda_units.cpp:82
#define MAX_SCALE
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
const int scale
Handle the parameters used to print a board drawing.
Definition: printout.h:32
virtual void Save(APP_SETTINGS_BASE *aConfig)
Definition: printout.cpp:24
bool m_titleBlock
Print frame and title block.
Definition: printout.h:59
bool m_blackWhite
Print in B&W or Color.
Definition: printout.h:60
int m_pageCount
Number of pages to print.
Definition: printout.h:61
const PAGE_INFO & m_pageInfo
Definition: printout.h:63
virtual void Load(APP_SETTINGS_BASE *aConfig)
Definition: printout.cpp:32
double m_scale
Printing scale.
Definition: printout.h:58