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.

375 lines
9.6 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 CERN
  5. * Copyright (C) 2015-2018 KiCad Developers, see AUTHORS.txt for contributors.
  6. * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  7. *
  8. * This program is free software: you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation, either version 2 of the License, or (at your
  11. * option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <algorithm>
  22. #include "wx_html_report_panel.h"
  23. #include <wildcards_and_files_ext.h>
  24. #include <gal/color4d.h>
  25. #include <wx/clipbrd.h>
  26. WX_HTML_REPORT_PANEL::WX_HTML_REPORT_PANEL( wxWindow* parent,
  27. wxWindowID id,
  28. const wxPoint& pos,
  29. const wxSize& size,
  30. long style ) :
  31. WX_HTML_REPORT_PANEL_BASE( parent, id, pos, size, style ),
  32. m_reporter( this ),
  33. m_severities( -1 ),
  34. m_lazyUpdate( false )
  35. {
  36. syncCheckboxes();
  37. m_htmlView->SetPage( addHeader( "" ) );
  38. Connect( wxEVT_COMMAND_MENU_SELECTED,
  39. wxMenuEventHandler( WX_HTML_REPORT_PANEL::onMenuEvent ), NULL, this );
  40. }
  41. WX_HTML_REPORT_PANEL::~WX_HTML_REPORT_PANEL()
  42. {
  43. }
  44. void WX_HTML_REPORT_PANEL::MsgPanelSetMinSize( const wxSize& aMinSize )
  45. {
  46. m_fgSizer->SetMinSize( aMinSize );
  47. GetSizer()->SetSizeHints( this );
  48. }
  49. REPORTER& WX_HTML_REPORT_PANEL::Reporter()
  50. {
  51. return m_reporter;
  52. }
  53. void WX_HTML_REPORT_PANEL::Report( const wxString& aText, SEVERITY aSeverity,
  54. REPORTER::LOCATION aLocation )
  55. {
  56. REPORT_LINE line;
  57. line.message = aText;
  58. line.severity = aSeverity;
  59. if( aLocation == REPORTER::LOC_HEAD )
  60. m_reportHead.push_back( line );
  61. else if( aLocation == REPORTER::LOC_TAIL )
  62. m_reportTail.push_back( line );
  63. else
  64. m_report.push_back( line );
  65. if( !m_lazyUpdate )
  66. {
  67. m_htmlView->AppendToPage( generateHtml( line ) );
  68. scrollToBottom();
  69. }
  70. }
  71. void WX_HTML_REPORT_PANEL::SetLazyUpdate( bool aLazyUpdate )
  72. {
  73. m_lazyUpdate = aLazyUpdate;
  74. }
  75. void WX_HTML_REPORT_PANEL::Flush( bool aSort )
  76. {
  77. wxString html;
  78. if( aSort )
  79. {
  80. std::sort( m_report.begin(), m_report.end(),
  81. []( const REPORT_LINE& a, const REPORT_LINE& b)
  82. {
  83. return a.severity < b.severity;
  84. });
  85. }
  86. for( const auto& line : m_reportHead )
  87. html += generateHtml( line );
  88. for( const auto& line : m_report )
  89. html += generateHtml( line );
  90. for( const auto& line : m_reportTail )
  91. html += generateHtml( line );
  92. m_htmlView->SetPage( addHeader( html ) );
  93. scrollToBottom();
  94. }
  95. void WX_HTML_REPORT_PANEL::scrollToBottom()
  96. {
  97. int x, y, xUnit, yUnit;
  98. m_htmlView->GetVirtualSize( &x, &y );
  99. m_htmlView->GetScrollPixelsPerUnit( &xUnit, &yUnit );
  100. m_htmlView->Scroll( 0, y / yUnit );
  101. updateBadges();
  102. }
  103. void WX_HTML_REPORT_PANEL::updateBadges()
  104. {
  105. int count = Count(RPT_SEVERITY_ERROR );
  106. m_errorsBadge->SetBitmap( MakeBadge( RPT_SEVERITY_ERROR, count, m_errorsBadge, 2 ) );
  107. count = Count(RPT_SEVERITY_WARNING );
  108. m_warningsBadge->SetBitmap( MakeBadge( RPT_SEVERITY_WARNING, count, m_warningsBadge, 2 ) );
  109. }
  110. wxString WX_HTML_REPORT_PANEL::addHeader( const wxString& aBody )
  111. {
  112. wxColour bgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
  113. wxColour fgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
  114. return wxString::Format( wxT( "<html><body bgcolor='%s' text='%s'>%s</body></html>" ),
  115. bgcolor.GetAsString( wxC2S_HTML_SYNTAX ),
  116. fgcolor.GetAsString( wxC2S_HTML_SYNTAX ),
  117. aBody );
  118. }
  119. int WX_HTML_REPORT_PANEL::Count( int severityMask )
  120. {
  121. int count = 0;
  122. for( const REPORT_LINE& reportLine : m_report )
  123. if( severityMask & reportLine.severity )
  124. count++;
  125. return count;
  126. }
  127. wxString WX_HTML_REPORT_PANEL::generateHtml( const REPORT_LINE& aLine )
  128. {
  129. wxString retv;
  130. if( !( m_severities & aLine.severity ) )
  131. return retv;
  132. switch( aLine.severity )
  133. {
  134. case RPT_SEVERITY_ERROR:
  135. retv = "<font color=\"red\" size=3>" + _( "Error: " ) + "</font>"
  136. "<font size=3>" + aLine.message + "</font><br>";
  137. break;
  138. case RPT_SEVERITY_WARNING:
  139. retv = "<font size=3>" + _( "Warning: " ) + aLine.message + "</font><br>";
  140. break;
  141. case RPT_SEVERITY_INFO:
  142. retv = "<font color=\"dark gray\" size=3>" + _( "Info: " ) + aLine.message + "</font><br>";
  143. break;
  144. case RPT_SEVERITY_ACTION:
  145. retv = "<font color=\"dark green\" size=3>" + aLine.message + "</font><br>";
  146. break;
  147. default:
  148. retv = "<font size=3>" + aLine.message + "</font><br>";
  149. }
  150. return retv;
  151. }
  152. wxString WX_HTML_REPORT_PANEL::generatePlainText( const REPORT_LINE& aLine )
  153. {
  154. switch( aLine.severity )
  155. {
  156. case RPT_SEVERITY_ERROR:
  157. return _( "Error: " ) + aLine.message + wxT( "\n" );
  158. case RPT_SEVERITY_WARNING:
  159. return _( "Warning: " ) + aLine.message + wxT( "\n" );
  160. case RPT_SEVERITY_INFO:
  161. return _( "Info: " ) + aLine.message + wxT( "\n" );
  162. default:
  163. return aLine.message + wxT( "\n" );
  164. }
  165. }
  166. void WX_HTML_REPORT_PANEL::onRightClick( wxMouseEvent& event )
  167. {
  168. wxMenu popup;
  169. popup.Append( wxID_COPY, "Copy" );
  170. PopupMenu( &popup );
  171. }
  172. void WX_HTML_REPORT_PANEL::onMenuEvent( wxMenuEvent& event )
  173. {
  174. if( event.GetId() == wxID_COPY )
  175. {
  176. if( wxTheClipboard->Open() )
  177. {
  178. bool primarySelection = wxTheClipboard->IsUsingPrimarySelection();
  179. wxTheClipboard->UsePrimarySelection( false ); // required to use the main clipboard
  180. wxTheClipboard->SetData( new wxTextDataObject( m_htmlView->SelectionToText() ) );
  181. wxTheClipboard->Close();
  182. wxTheClipboard->UsePrimarySelection( primarySelection );
  183. }
  184. }
  185. }
  186. // Don't globally define this; different facilities use different definitions of "ALL"
  187. static int RPT_SEVERITY_ALL = RPT_SEVERITY_WARNING | RPT_SEVERITY_ERROR | RPT_SEVERITY_INFO | RPT_SEVERITY_ACTION;
  188. void WX_HTML_REPORT_PANEL::onCheckBoxShowAll( wxCommandEvent& event )
  189. {
  190. if( event.IsChecked() )
  191. m_severities = RPT_SEVERITY_ALL;
  192. else
  193. m_severities = RPT_SEVERITY_ERROR;
  194. syncCheckboxes();
  195. Flush( true );
  196. }
  197. void WX_HTML_REPORT_PANEL::syncCheckboxes()
  198. {
  199. m_checkBoxShowAll->SetValue( m_severities == RPT_SEVERITY_ALL );
  200. m_checkBoxShowWarnings->SetValue( m_severities & RPT_SEVERITY_WARNING );
  201. m_checkBoxShowErrors->SetValue( m_severities & RPT_SEVERITY_ERROR );
  202. m_checkBoxShowInfos->SetValue( m_severities & RPT_SEVERITY_INFO );
  203. m_checkBoxShowActions->SetValue( m_severities & RPT_SEVERITY_ACTION );
  204. }
  205. void WX_HTML_REPORT_PANEL::onCheckBoxShowWarnings( wxCommandEvent& event )
  206. {
  207. if( event.IsChecked() )
  208. m_severities |= RPT_SEVERITY_WARNING;
  209. else
  210. m_severities &= ~RPT_SEVERITY_WARNING;
  211. syncCheckboxes();
  212. Flush( true );
  213. }
  214. void WX_HTML_REPORT_PANEL::onCheckBoxShowErrors( wxCommandEvent& event )
  215. {
  216. if( event.IsChecked() )
  217. m_severities |= RPT_SEVERITY_ERROR;
  218. else
  219. m_severities &= ~RPT_SEVERITY_ERROR;
  220. syncCheckboxes();
  221. Flush( true );
  222. }
  223. void WX_HTML_REPORT_PANEL::onCheckBoxShowInfos( wxCommandEvent& event )
  224. {
  225. if( event.IsChecked() )
  226. m_severities |= RPT_SEVERITY_INFO;
  227. else
  228. m_severities &= ~RPT_SEVERITY_INFO;
  229. syncCheckboxes();
  230. Flush( true );
  231. }
  232. void WX_HTML_REPORT_PANEL::onCheckBoxShowActions( wxCommandEvent& event )
  233. {
  234. if( event.IsChecked() )
  235. m_severities |= RPT_SEVERITY_ACTION;
  236. else
  237. m_severities &= ~RPT_SEVERITY_ACTION;
  238. syncCheckboxes();
  239. Flush( true );
  240. }
  241. void WX_HTML_REPORT_PANEL::onBtnSaveToFile( wxCommandEvent& event )
  242. {
  243. wxFileName fn( "./report.txt" );
  244. wxFileDialog dlg( this, _( "Save Report to File" ), fn.GetPath(), fn.GetFullName(),
  245. TextFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
  246. if( dlg.ShowModal() != wxID_OK )
  247. return;
  248. fn = dlg.GetPath();
  249. if( fn.GetExt().IsEmpty() )
  250. fn.SetExt( "txt" );
  251. wxFile f( fn.GetFullPath(), wxFile::write );
  252. if( !f.IsOpened() )
  253. {
  254. wxString msg;
  255. msg.Printf( _( "Cannot write report to file \"%s\"." ),
  256. fn.GetFullPath().GetData() );
  257. wxMessageBox( msg, _( "File save error" ), wxOK | wxICON_ERROR, this );
  258. return;
  259. }
  260. for( const REPORT_LINE& l : m_report )
  261. {
  262. f.Write( generatePlainText( l ) );
  263. }
  264. f.Close();
  265. }
  266. void WX_HTML_REPORT_PANEL::Clear()
  267. {
  268. m_report.clear();
  269. m_reportHead.clear();
  270. m_reportTail.clear();
  271. }
  272. void WX_HTML_REPORT_PANEL::SetLabel( const wxString& aLabel )
  273. {
  274. m_box->GetStaticBox()->SetLabel( aLabel );
  275. }
  276. void WX_HTML_REPORT_PANEL::SetVisibleSeverities( int aSeverities )
  277. {
  278. if( aSeverities < 0 )
  279. m_severities = RPT_SEVERITY_ALL;
  280. else
  281. m_severities = aSeverities;
  282. syncCheckboxes();
  283. }
  284. int WX_HTML_REPORT_PANEL::GetVisibleSeverities()
  285. {
  286. return m_severities;
  287. }