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.

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