You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

301 lines
8.6 KiB

  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. #include "dialog_print_generic.h"
  19. #include <confirm.h>
  20. #include <draw_frame.h>
  21. #include <printout.h>
  22. #include <enabler.h>
  23. // Define min and max reasonable values for print scale
  24. static constexpr double MIN_SCALE = 0.01;
  25. static constexpr double MAX_SCALE = 100.0;
  26. DIALOG_PRINT_GENERIC::DIALOG_PRINT_GENERIC( EDA_DRAW_FRAME* aParent, PRINTOUT_SETTINGS* aSettings )
  27. : DIALOG_PRINT_GENERIC_BASE( aParent ), m_config( nullptr ), m_settings( aSettings )
  28. {
  29. m_scaleValidator.SetRange( MIN_SCALE, MAX_SCALE );
  30. m_scaleCustomText->SetValidator( m_scaleValidator );
  31. // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
  32. // that requires us to correct the button labels here.
  33. m_sdbSizer1OK->SetLabel( _( "Print" ) );
  34. m_sdbSizer1Apply->SetLabel( _( "Print Preview" ) );
  35. m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
  36. m_sdbSizer1->Layout();
  37. m_sdbSizer1OK->SetDefault();
  38. #if defined(__WXMAC__) or defined(__WXGTK__)
  39. // Preview does not work well on GTK or Mac,
  40. // but these platforms provide native print preview
  41. m_sdbSizer1Apply->Hide();
  42. #endif
  43. FinishDialogSettings();
  44. Layout();
  45. initPrintData();
  46. }
  47. DIALOG_PRINT_GENERIC::~DIALOG_PRINT_GENERIC()
  48. {
  49. }
  50. void DIALOG_PRINT_GENERIC::ForcePrintBorder( bool aValue )
  51. {
  52. m_titleBlock->SetValue( aValue );
  53. m_titleBlock->Hide();
  54. if( m_config )
  55. {
  56. m_settings->Load( m_config );
  57. m_settings->m_titleBlock = aValue;
  58. m_settings->Save( m_config );
  59. }
  60. }
  61. void DIALOG_PRINT_GENERIC::saveSettings()
  62. {
  63. m_settings->m_scale = getScaleValue();
  64. m_settings->m_titleBlock = m_titleBlock->GetValue();
  65. m_settings->m_blackWhite = m_outputMode->GetSelection();
  66. if( m_config )
  67. m_settings->Save( m_config );
  68. }
  69. double DIALOG_PRINT_GENERIC::getScaleValue() const
  70. {
  71. if( m_scale1->GetValue() )
  72. return 1.0;
  73. if( m_scaleFit->GetValue() )
  74. return 0.0;
  75. if( m_scaleCustom->GetValue() )
  76. {
  77. double scale;
  78. wxCHECK( m_scaleCustomText->GetValue().ToDouble( &scale ), 1.0 );
  79. return scale;
  80. }
  81. wxCHECK( false, 1.0 );
  82. }
  83. void DIALOG_PRINT_GENERIC::setScaleValue( double aValue )
  84. {
  85. wxASSERT( aValue >= 0.0 );
  86. if( aValue == 0.0 ) // fit to page
  87. {
  88. m_scaleFit->SetValue( true );
  89. }
  90. else if( aValue == 1.0 )
  91. {
  92. m_scale1->SetValue( true );
  93. }
  94. else
  95. {
  96. if( aValue > MAX_SCALE )
  97. {
  98. DisplayInfoMessage( nullptr, _( "Warning: Scale option set to a very large value" ) );
  99. }
  100. else if( aValue < MIN_SCALE )
  101. {
  102. DisplayInfoMessage( nullptr, _( "Warning: Scale option set to a very small value" ) );
  103. }
  104. m_scaleCustom->SetValue( true );
  105. m_scaleCustomText->SetValue( wxString::Format( wxT( "%f" ), aValue ) );
  106. }
  107. }
  108. bool DIALOG_PRINT_GENERIC::TransferDataToWindow()
  109. {
  110. if( !wxDialog::TransferDataToWindow() )
  111. return false;
  112. if( m_config )
  113. m_settings->Load( m_config );
  114. setScaleValue( m_settings->m_scale );
  115. m_titleBlock->SetValue( m_settings->m_titleBlock );
  116. m_outputMode->SetSelection( m_settings->m_blackWhite ? 1 : 0 );
  117. return true;
  118. }
  119. void DIALOG_PRINT_GENERIC::onPageSetup( wxCommandEvent& event )
  120. {
  121. wxPageSetupDialog pageSetupDialog( this, s_pageSetupData );
  122. pageSetupDialog.ShowModal();
  123. (*s_PrintData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
  124. (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
  125. }
  126. void DIALOG_PRINT_GENERIC::onPrintPreview( wxCommandEvent& event )
  127. {
  128. m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
  129. saveSettings();
  130. if( m_settings->m_pageCount == 0 )
  131. {
  132. DisplayError( this, _( "Nothing to print" ) );
  133. return;
  134. }
  135. // Pass two printout objects: for preview, and possible printing.
  136. wxString title = _( "Print Preview" );
  137. wxPrintPreview* preview =
  138. new wxPrintPreview( createPrintout( title ), createPrintout( title ), s_PrintData );
  139. preview->SetZoom( 100 );
  140. wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, m_parent->GetPosition(),
  141. m_parent->GetSize() );
  142. frame->SetMinSize( wxSize( 550, 350 ) );
  143. frame->Center();
  144. // On wxGTK, set the flag wxTOPLEVEL_EX_DIALOG is mandatory, if we want
  145. // close the frame using the X box in caption, when the preview frame is run
  146. // from a dialog
  147. frame->SetExtraStyle( frame->GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
  148. // We use here wxPreviewFrame_WindowModal option to make the wxPrintPreview frame
  149. // modal for its caller only.
  150. // An other reason is the fact when closing the frame without this option,
  151. // all top level frames are reenabled.
  152. // With this option, only the parent is reenabled.
  153. // Reenabling all top level frames should be made by the parent dialog.
  154. frame->InitializeWithModality( wxPreviewFrame_WindowModal );
  155. frame->Raise(); // Needed on Ubuntu/Unity to display the frame
  156. frame->Show( true );
  157. }
  158. void DIALOG_PRINT_GENERIC::onPrintButtonClick( wxCommandEvent& event )
  159. {
  160. m_settings->m_pageCount = 0; // it needs to be set by a derived dialog
  161. saveSettings();
  162. if( m_settings->m_pageCount == 0 )
  163. {
  164. DisplayError( this, _( "Nothing to print" ) );
  165. return;
  166. }
  167. wxPrintDialogData printDialogData( *s_PrintData );
  168. printDialogData.SetMaxPage( m_settings->m_pageCount );
  169. wxPrinter printer( &printDialogData );
  170. auto printout = std::unique_ptr<wxPrintout>( createPrintout( _( "Print" ) ) );
  171. // Disable 'Print' button to prevent issuing another print
  172. // command before the previous one is finished (causes problems on Windows)
  173. ENABLER printBtnDisable( *m_sdbSizer1OK, false );
  174. if( !printer.Print( this, printout.get(), true ) )
  175. {
  176. if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
  177. DisplayError( this, _( "There was a problem printing." ) );
  178. }
  179. else
  180. {
  181. *s_PrintData = printer.GetPrintDialogData().GetPrintData();
  182. }
  183. }
  184. void DIALOG_PRINT_GENERIC::onCloseButton( wxCommandEvent& event )
  185. {
  186. saveSettings();
  187. if( IsQuasiModal() )
  188. EndQuasiModal( wxID_CANCEL );
  189. if( IsModal() )
  190. EndModal( wxID_CANCEL );
  191. Close();
  192. }
  193. void DIALOG_PRINT_GENERIC::onClose( wxCloseEvent& event )
  194. {
  195. saveSettings();
  196. event.Skip();
  197. }
  198. void DIALOG_PRINT_GENERIC::onSetCustomScale( wxCommandEvent& event )
  199. {
  200. // Select 'custom scale' radio button when user types in a value in the
  201. // custom scale text box
  202. m_scaleCustom->SetValue( true );
  203. }
  204. void DIALOG_PRINT_GENERIC::initPrintData()
  205. {
  206. if( !s_PrintData ) // First print
  207. {
  208. s_PrintData = new wxPrintData();
  209. if( !s_PrintData->Ok() )
  210. DisplayError( this, _( "An error occurred initializing the printer information." ) );
  211. s_PrintData->SetQuality( wxPRINT_QUALITY_HIGH ); // Default resolution = HIGH;
  212. }
  213. if( !s_pageSetupData )
  214. {
  215. const PAGE_INFO& pageInfo = m_settings->m_pageInfo;
  216. s_pageSetupData = new wxPageSetupDialogData( *s_PrintData );
  217. s_pageSetupData->SetPaperId( pageInfo.GetPaperId() );
  218. s_pageSetupData->GetPrintData().SetOrientation( pageInfo.GetWxOrientation() );
  219. if( pageInfo.IsCustom() )
  220. {
  221. if( pageInfo.IsPortrait() )
  222. s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetWidthMils() ),
  223. Mils2mm( pageInfo.GetHeightMils() ) ) );
  224. else
  225. s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetHeightMils() ),
  226. Mils2mm( pageInfo.GetWidthMils() ) ) );
  227. }
  228. *s_PrintData = s_pageSetupData->GetPrintData();
  229. }
  230. }
  231. wxPrintData* DIALOG_PRINT_GENERIC::s_PrintData = nullptr;
  232. wxPageSetupDialogData* DIALOG_PRINT_GENERIC::s_pageSetupData = nullptr;