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 The 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
41class KI_PREVIEW_FRAME : public wxPreviewFrame
42{
43public:
44 KI_PREVIEW_FRAME( wxPrintPreview* aPreview, wxWindow* aParent,
45 const wxString& aTitle, const wxPoint& aPos = wxDefaultPosition,
46 const wxSize& aSize = wxDefaultSize ) :
47 wxPreviewFrame( aPreview, aParent, aTitle, aPos, aSize )
48 {
49 }
50
51 bool Show( bool show ) override
52 {
53 bool ret;
54
55 // Show or hide the window. If hiding, save current position and size.
56 // If showing, use previous position and size.
57 if( show )
58 {
59 ret = wxPreviewFrame::Show( show );
60
61 if( s_size.x != 0 && s_size.y != 0 )
62 SetSize( s_pos.x, s_pos.y, s_size.x, s_size.y, 0 );
63 }
64 else
65 {
66 // Save the dialog's position & size before hiding
67 s_size = GetSize();
68 s_pos = GetPosition();
69
70 ret = wxPreviewFrame::Show( show );
71 }
72
73 return ret;
74 }
75
76private:
77 static wxPoint s_pos;
78 static wxSize s_size;
79};
80
81
84
85
87 : DIALOG_PRINT_GENERIC_BASE( aParent ),
88 m_config( nullptr ),
89 m_settings( aSettings )
90{
91 // Note: for the validator, min value is 0.0, to allow typing values like 0.5
92 // that start by 0
93 m_scaleValidator.SetRange( 0.0, MAX_SCALE );
94 m_scaleCustomText->SetValidator( m_scaleValidator );
95
96 SetupStandardButtons( { { wxID_OK, _( "Print" ) },
97 { wxID_APPLY, _( "Print Preview" ) },
98 { wxID_CANCEL, _( "Close" ) } } );
99
100#if defined(__WXMAC__) or defined(__WXGTK__)
101 // Preview does not work well on GTK or Mac,
102 // but these platforms provide native print preview
103 m_sdbSizer1Apply->Hide();
104#endif
105
107 Layout();
109}
110
111
113{
114}
115
116
118{
119 m_titleBlock->SetValue( aValue );
120 m_titleBlock->Hide();
121
122 if( m_config )
123 {
125 m_settings->m_titleBlock = aValue;
127 }
128}
129
130
132{
134 m_settings->m_titleBlock = m_titleBlock->GetValue();
135 m_settings->m_blackWhite = m_outputMode->GetSelection();
136
137 if( m_config )
139}
140
141
143{
144 if( m_scale1->GetValue() )
145 return 1.0;
146
147 if( m_scaleFit->GetValue() )
148 return 0.0;
149
150 if( m_scaleCustom->GetValue() )
151 {
152 double scale = 1.0;;
153
154 if( !m_scaleCustomText->GetValue().ToDouble( &scale ) )
155 {
156 DisplayInfoMessage( nullptr, _( "Warning: scale is not a number." ) );
157 scale = 1.0;
158 }
159
160 if( scale > MAX_SCALE )
161 {
164 DisplayInfoMessage( nullptr, wxString::Format( _( "Warning: scale set to a very large "
165 "value.\nIt will be clamped to %f." ),
166 scale ) );
167 }
168 else if( scale < MIN_SCALE )
169 {
172 DisplayInfoMessage( nullptr, wxString::Format( _( "Warning: scale set to a very small "
173 "value.\nIt will be clamped to %f." ),
174 scale ) );
175 }
176
177 return scale;
178 }
179
180 wxFAIL_MSG( wxT( "No scale option selected." ) );
181 return 1.0;
182}
183
184
186{
187 wxASSERT( aValue >= 0.0 );
188
189 if( aValue == 0.0 ) // fit to page
190 {
191 m_scaleFit->SetValue( true );
192 }
193 else if( aValue == 1.0 )
194 {
195 m_scale1->SetValue( true );
196 }
197 else
198 {
199 // Silently clamp the value (it comes from the config file).
200 if( aValue > MAX_SCALE )
201 aValue = MAX_SCALE;
202 else if( aValue < MIN_SCALE )
203 aValue = MIN_SCALE;
204
205 m_scaleCustom->SetValue( true );
206 m_scaleCustomText->SetValue( wxString::Format( wxT( "%f" ), aValue ) );
207 }
208}
209
210
212{
213 if( !wxDialog::TransferDataToWindow() )
214 return false;
215
216 if( m_config )
218
221 m_outputMode->SetSelection( m_settings->m_blackWhite ? 1 : 0 );
222
223 return true;
224}
225
226
227void DIALOG_PRINT_GENERIC::onPageSetup( wxCommandEvent& event )
228{
229 wxPageSetupDialog pageSetupDialog( this, s_pageSetupData );
230 pageSetupDialog.ShowModal();
231
232 (*s_PrintData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
233 (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
234}
235
236
237void DIALOG_PRINT_GENERIC::onPrintPreview( wxCommandEvent& event )
238{
239 m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
240 saveSettings();
241
242 if( m_settings->m_pageCount == 0 )
243 {
244 DisplayError( this, _( "Nothing to print" ) );
245 return;
246 }
247
248 // Pass two printout objects: for preview, and possible printing.
249 wxString title = _( "Print Preview" );
250 wxPrintPreview* preview =
251 new wxPrintPreview( createPrintout( title ), createPrintout( title ), s_PrintData );
252
253 preview->SetZoom( 100 );
254
255 KI_PREVIEW_FRAME* frame = new KI_PREVIEW_FRAME( preview, this, title );
256
257 // On wxGTK, set the flag wxTOPLEVEL_EX_DIALOG is mandatory, if we want
258 // close the frame using the X box in caption, when the preview frame is run
259 // from a dialog
260 frame->SetExtraStyle( frame->GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
261
262 // We use here wxPreviewFrame_WindowModal option to make the wxPrintPreview frame
263 // modal for its caller only.
264 // An other reason is the fact when closing the frame without this option,
265 // all top level frames are reenabled.
266 // With this option, only the parent is reenabled.
267 // Reenabling all top level frames should be made by the parent dialog.
268 frame->InitializeWithModality( wxPreviewFrame_WindowModal );
269
270 // on first invocation in this runtime session, set to 3/4 size of parent,
271 // but will be changed in Show() if not first time as will position.
272 // Must be called after InitializeWithModality because otherwise in some wxWidget
273 // versions it is not always taken in account
274 frame->SetMinSize( wxSize( 650, 500 ) );
275 frame->SetSize( ( m_parent->GetSize() * 3 ) / 4 );
276
277 frame->Raise(); // Needed on Ubuntu/Unity to display the frame
278 frame->Show( true );
279}
280
281
282void DIALOG_PRINT_GENERIC::onPrintButtonClick( wxCommandEvent& event )
283{
284 if( Pgm().m_Printing )
285 {
286 DisplayError( this, _( "Previous print job not yet complete." ) );
287 return;
288 }
289
290 m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
291 saveSettings();
292
293 if( m_settings->m_pageCount == 0 )
294 {
295 DisplayError( this, _( "Nothing to print" ) );
296 return;
297 }
298
299 wxPrintDialogData printDialogData( *s_PrintData );
300 printDialogData.SetMaxPage( m_settings->m_pageCount );
301
302 wxPrinter printer( &printDialogData );
303 auto printout = std::unique_ptr<wxPrintout>( createPrintout( _( "Print" ) ) );
304
305 Pgm().m_Printing = true;
306
307 {
308 if( !printer.Print( this, printout.get(), true ) )
309 {
310 if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
311 DisplayError( this, _( "There was a problem printing." ) );
312 }
313 else
314 {
315 *s_PrintData = printer.GetPrintDialogData().GetPrintData();
316 }
317 }
318
319 Pgm().m_Printing = false;
320}
321
322
323void DIALOG_PRINT_GENERIC::onCancelButtonClick( wxCommandEvent& event )
324{
325 saveSettings();
326
327 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL ) );
328}
329
330
331void DIALOG_PRINT_GENERIC::onClose( wxCloseEvent& event )
332{
333 saveSettings();
334 event.Skip();
335}
336
337
338void DIALOG_PRINT_GENERIC::onSetCustomScale( wxCommandEvent& event )
339{
340 // Select 'custom scale' radio button when user types in a value in the
341 // custom scale text box
342 m_scaleCustom->SetValue( true );
343}
344
345
347{
348 if( !s_PrintData ) // First print
349 {
350 s_PrintData = new wxPrintData();
351
352 if( !s_PrintData->Ok() )
353 DisplayError( this, _( "An error occurred initializing the printer information." ) );
354
355 s_PrintData->SetQuality( wxPRINT_QUALITY_HIGH ); // Default resolution = HIGH;
356 }
357
358 if( !s_pageSetupData )
359 {
360 const PAGE_INFO& pageInfo = m_settings->m_pageInfo;
361
362 s_pageSetupData = new wxPageSetupDialogData( *s_PrintData );
363 s_pageSetupData->SetPaperId( pageInfo.GetPaperId() );
364 s_pageSetupData->GetPrintData().SetOrientation( pageInfo.GetWxOrientation() );
365
366 if( pageInfo.IsCustom() )
367 {
368 if( pageInfo.IsPortrait() )
369 s_pageSetupData->SetPaperSize( wxSize( EDA_UNIT_UTILS::Mils2mm( pageInfo.GetWidthMils() ),
370 EDA_UNIT_UTILS::Mils2mm( pageInfo.GetHeightMils() ) ) );
371 else
372 s_pageSetupData->SetPaperSize( wxSize( EDA_UNIT_UTILS::Mils2mm( pageInfo.GetHeightMils() ),
373 EDA_UNIT_UTILS::Mils2mm( pageInfo.GetWidthMils() ) ) );
374 }
375
376 *s_PrintData = s_pageSetupData->GetPrintData();
377 }
378}
379
380
381wxPrintData* DIALOG_PRINT_GENERIC::s_PrintData = nullptr;
382wxPageSetupDialogData* 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:182
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:378
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:1073
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