KiCad PCB EDA Suite
wx_html_report_panel.cpp
Go to the documentation of this file.
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 
22 #include <algorithm>
23 
24 #include "wx_html_report_panel.h"
25 
27 #include <gal/color4d.h>
28 #include <wx/clipbrd.h>
29 #include <kicad_string.h>
30 
32  wxWindowID id,
33  const wxPoint& pos,
34  const wxSize& size,
35  long style ) :
36  WX_HTML_REPORT_PANEL_BASE( parent, id, pos, size, style ),
37  m_reporter( this ),
38  m_severities( -1 ),
39  m_lazyUpdate( false ),
40  m_PrintInfo( true )
41 {
43  m_htmlView->SetPage( addHeader( "" ) );
44 
45  Connect( wxEVT_COMMAND_MENU_SELECTED,
46  wxMenuEventHandler( WX_HTML_REPORT_PANEL::onMenuEvent ), NULL, this );
47 }
48 
49 
51 {
52 }
53 
54 
55 void WX_HTML_REPORT_PANEL::MsgPanelSetMinSize( const wxSize& aMinSize )
56 {
57  m_fgSizer->SetMinSize( aMinSize );
58  GetSizer()->SetSizeHints( this );
59 }
60 
61 
63 {
64  return m_reporter;
65 }
66 
67 
68 void WX_HTML_REPORT_PANEL::Report( const wxString& aText, SEVERITY aSeverity,
69  REPORTER::LOCATION aLocation )
70 {
71  REPORT_LINE line;
72  line.message = aText;
73  line.severity = aSeverity;
74 
75  if( aLocation == REPORTER::LOC_HEAD )
76  m_reportHead.push_back( line );
77  else if( aLocation == REPORTER::LOC_TAIL )
78  m_reportTail.push_back( line );
79  else
80  m_report.push_back( line );
81 
82  if( !m_lazyUpdate )
83  {
84  m_htmlView->AppendToPage( generateHtml( line ) );
86  }
87 }
88 
89 
90 void WX_HTML_REPORT_PANEL::SetLazyUpdate( bool aLazyUpdate )
91 {
92  m_lazyUpdate = aLazyUpdate;
93 }
94 
95 
96 void WX_HTML_REPORT_PANEL::Flush( bool aSort )
97 {
98  wxString html;
99 
100  if( aSort )
101  {
102  std::sort( m_report.begin(), m_report.end(),
103  []( const REPORT_LINE& a, const REPORT_LINE& b)
104  {
105  return a.severity < b.severity;
106  });
107  }
108 
109  for( const auto& line : m_reportHead )
110  html += generateHtml( line );
111 
112  for( const auto& line : m_report )
113  html += generateHtml( line );
114 
115  for( const auto& line : m_reportTail )
116  html += generateHtml( line );
117 
118  m_htmlView->SetPage( addHeader( html ) );
119  scrollToBottom();
120 }
121 
122 
124 {
125  int x, y, xUnit, yUnit;
126 
127  m_htmlView->GetVirtualSize( &x, &y );
128  m_htmlView->GetScrollPixelsPerUnit( &xUnit, &yUnit );
129  m_htmlView->Scroll( 0, y / yUnit );
130 
131  updateBadges();
132 }
133 
134 
136 {
137  int count = Count(RPT_SEVERITY_ERROR );
138  m_errorsBadge->SetBitmap( MakeBadge( RPT_SEVERITY_ERROR, count, m_errorsBadge, 2 ) );
139 
140  count = Count(RPT_SEVERITY_WARNING );
142 }
143 
144 
145 wxString WX_HTML_REPORT_PANEL::addHeader( const wxString& aBody )
146 {
147  wxColour bgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
148  wxColour fgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
149 
150  return wxString::Format( wxT( "<html><body bgcolor='%s' text='%s'>%s</body></html>" ),
151  bgcolor.GetAsString( wxC2S_HTML_SYNTAX ),
152  fgcolor.GetAsString( wxC2S_HTML_SYNTAX ),
153  aBody );
154 }
155 
156 
157 int WX_HTML_REPORT_PANEL::Count( int severityMask )
158 {
159  int count = 0;
160 
161  for( const REPORT_LINE& reportLine : m_report )
162  if( severityMask & reportLine.severity )
163  count++;
164 
165  return count;
166 }
167 
168 
170 {
171  wxString retv;
172 
173  if( !( m_severities & aLine.severity ) )
174  return retv;
175 
176  switch( aLine.severity )
177  {
178  case RPT_SEVERITY_ERROR:
179  retv = "<font color=\"red\" size=3>" + _( "Error: " ) + "</font>"
180  "<font size=3>" + aLine.message + "</font><br>";
181  break;
183  retv = "<font size=3>" + _( "Warning: " ) + aLine.message + "</font><br>";
184  break;
185  case RPT_SEVERITY_INFO:
186  retv = "<font color=\"dark gray\" size=3>" + _( "Info: " ) + aLine.message + "</font><br>";
187  break;
188  case RPT_SEVERITY_ACTION:
189  retv = "<font color=\"dark green\" size=3>" + aLine.message + "</font><br>";
190  break;
191  default:
192  retv = "<font size=3>" + aLine.message + "</font><br>";
193  }
194 
195  return retv;
196 }
197 
198 
200 {
201  switch( aLine.severity )
202  {
203  case RPT_SEVERITY_ERROR:
204  return _( "Error: " ) + aLine.message + wxT( "\n" );
206  return _( "Warning: " ) + aLine.message + wxT( "\n" );
207  case RPT_SEVERITY_INFO:
208  return _( "Info: " ) + aLine.message + wxT( "\n" );
209  default:
210  return aLine.message + wxT( "\n" );
211  }
212 }
213 
214 
215 void WX_HTML_REPORT_PANEL::onRightClick( wxMouseEvent& event )
216 {
217  wxMenu popup;
218  popup.Append( wxID_COPY, "Copy" );
219  PopupMenu( &popup );
220 }
221 
222 
223 void WX_HTML_REPORT_PANEL::onMenuEvent( wxMenuEvent& event )
224 {
225  if( event.GetId() == wxID_COPY )
226  {
227  if( wxTheClipboard->Open() )
228  {
229  bool primarySelection = wxTheClipboard->IsUsingPrimarySelection();
230  wxTheClipboard->UsePrimarySelection( false ); // required to use the main clipboard
231  wxTheClipboard->SetData( new wxTextDataObject( m_htmlView->SelectionToText() ) );
232  wxTheClipboard->Close();
233  wxTheClipboard->UsePrimarySelection( primarySelection );
234  }
235  }
236 }
237 
238 
239 // Don't globally define this; different facilities use different definitions of "ALL"
241 
242 
243 void WX_HTML_REPORT_PANEL::onCheckBoxShowAll( wxCommandEvent& event )
244 {
245  if( event.IsChecked() )
247  else
249 
250  syncCheckboxes();
251  Flush( true );
252 }
253 
254 
256 {
262 }
263 
264 
265 void WX_HTML_REPORT_PANEL::onCheckBoxShowWarnings( wxCommandEvent& event )
266 {
267  if( event.IsChecked() )
269  else
271 
272  syncCheckboxes();
273  Flush( true );
274 }
275 
276 
277 void WX_HTML_REPORT_PANEL::onCheckBoxShowErrors( wxCommandEvent& event )
278 {
279  if( event.IsChecked() )
281  else
283 
284  syncCheckboxes();
285  Flush( true );
286 }
287 
288 
289 void WX_HTML_REPORT_PANEL::onCheckBoxShowInfos( wxCommandEvent& event )
290 {
291  if( event.IsChecked() )
293  else
295 
296  syncCheckboxes();
297  Flush( true );
298 }
299 
300 
301 void WX_HTML_REPORT_PANEL::onCheckBoxShowActions( wxCommandEvent& event )
302 {
303  if( event.IsChecked() )
305  else
307 
308  syncCheckboxes();
309  Flush( true );
310 }
311 
312 
313 void WX_HTML_REPORT_PANEL::onBtnSaveToFile( wxCommandEvent& event )
314 {
315  wxFileName fn;
316 
317  if( m_ReportFileName.empty() )
318  fn = wxT( "./report.txt" );
319  else
320  fn = m_ReportFileName;
321 
322  wxFileDialog dlg( this, _( "Save Report to File" ), fn.GetPath(), fn.GetFullName(),
323  TextFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
324 
325  if( dlg.ShowModal() != wxID_OK )
326  return;
327 
328  fn = dlg.GetPath();
329 
330  if( fn.GetExt().IsEmpty() )
331  fn.SetExt( "txt" );
332 
333  wxFile f( fn.GetFullPath(), wxFile::write );
334 
335  if( !f.IsOpened() )
336  {
337  wxString msg;
338 
339  msg.Printf( _( "Cannot write report to file \"%s\"." ),
340  fn.GetFullPath().GetData() );
341  wxMessageBox( msg, _( "File save error" ), wxOK | wxICON_ERROR, this );
342  return;
343  }
344 
345  for( const REPORT_LINE& l : m_report )
346  {
347  wxString s = generatePlainText( l );
348 
350  f.Write( s );
351  }
352  m_ReportFileName = fn.GetFullPath();
353  f.Close();
354 }
355 
356 
358 {
359  m_report.clear();
360  m_reportHead.clear();
361  m_reportTail.clear();
362 }
363 
364 
365 void WX_HTML_REPORT_PANEL::SetLabel( const wxString& aLabel )
366 {
367  m_box->GetStaticBox()->SetLabel( aLabel );
368 }
369 
370 
372 {
373  if( aSeverities < 0 )
375  else
376  m_severities = aSeverities;
377 
378  syncCheckboxes();
379 }
380 
381 
383 {
384  return m_severities;
385 }
386 
387 
388 void WX_HTML_REPORT_PANEL::SetFileName( wxString& aReportFileName )
389 {
390  m_ReportFileName = aReportFileName;
391 }
392 
393 
395 {
396  return ( m_ReportFileName );
397 }
398 
399 
400 void WX_HTML_REPORT_PANEL::SetPrintInfo( bool aPrintInfo )
401 {
402  m_PrintInfo = aPrintInfo;
403 }
404 
405 
406 void WX_HTML_REPORT_PANEL::SetShowSeverity( SEVERITY aSeverity, bool aValue )
407 {
408  switch( aSeverity )
409  {
410  case RPT_SEVERITY_INFO:
411  m_checkBoxShowInfos->SetValue( aValue );
412  break;
413 
414  case RPT_SEVERITY_ACTION:
415  m_checkBoxShowActions->SetValue( aValue );
416  break;
417 
419  m_checkBoxShowWarnings->SetValue( aValue );
420  break;
421 
422  default:
423  m_checkBoxShowErrors->SetValue( aValue );
424  break;
425  }
426 }
void SetVisibleSeverities(int aSeverities)
Set the visible severity filter.
void onCheckBoxShowInfos(wxCommandEvent &event) override
void onBtnSaveToFile(wxCommandEvent &event) override
wxString addHeader(const wxString &aBody)
void SetLazyUpdate(bool aLazyUpdate)
Sets the lasy update.
void onCheckBoxShowActions(wxCommandEvent &event) override
wxString generatePlainText(const REPORT_LINE &aLine)
Class WX_HTML_REPORT_PANEL_BASE.
SEVERITY
Definition: ui_common.h:45
void Flush(bool aSort=false)
Forces updating the HTML page, after the report is built in lazy mode If aSort = true,...
void onCheckBoxShowWarnings(wxCommandEvent &event) override
void onCheckBoxShowErrors(wxCommandEvent &event) override
REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
bool m_PrintInfo
Print "Info:" at the front of Info messages (default)
void onRightClick(wxMouseEvent &event) override
WX_HTML_REPORT_PANEL(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(500, 300), long style=wxTAB_TRAVERSAL)
REPORT_LINES m_reportHead
Lines to print at the very beginning of the report, regardless of sorting
#define NULL
void SetPrintInfo(bool aPrintInfo)
If true prints Info: at the beginning of each Info severity line (Default)
REPORTER & Reporter()
returns the reporter object that reports to this panel
WX_HTML_PANEL_REPORTER m_reporter
the reporter
void SetFileName(wxString &aReportFileName)
Set the report full file name to the string
REPORT_LINES m_reportTail
Lines to print at the very end of the report, regardless of sorting
int Count(int severityMask)
return the number of messages matching the given severity mask.
Definition of file extensions used in Kicad.
void SetShowSeverity(SEVERITY aSeverity, bool aValue)
REPORT_LINES m_report
copy of the report, stored for filtering
void Report(const wxString &aText, SEVERITY aSeverity, REPORTER::LOCATION aLocation=REPORTER::LOC_BODY)
Reports the string.
LOCATION
Location where the message is to be reported.
Definition: reporter.h:73
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:201
void Clear()
clears the report panel
wxBitmap MakeBadge(SEVERITY aStyle, int aCount, wxWindow *aWindow, int aDepth)
Definition: ui_common.cpp:36
#define _(s)
Definition: 3d_actions.cpp:33
void onCheckBoxShowAll(wxCommandEvent &event) override
wxString TextFileWildcard()
wxString generateHtml(const REPORT_LINE &aLine)
void MsgPanelSetMinSize(const wxSize &aMinSize)
Set the min size of the area which displays html messages:
wxString m_ReportFileName
Use this as the filename instead of /bin/report.txt (default)
void SetLabel(const wxString &aLabel) override
sets the frame label
void onMenuEvent(wxMenuEvent &event)
bool ConvertSmartQuotesAndDashes(wxString *aString)
Converts curly quotes and em/en dashes to straight quotes and dashes.
Definition: string.cpp:43
int m_severities
message severities to display (mask)
static int RPT_SEVERITY_ALL