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