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 #include <wx/ffile.h>
31 
33  wxWindowID id,
34  const wxPoint& pos,
35  const wxSize& size,
36  long style ) :
37  WX_HTML_REPORT_PANEL_BASE( parent, id, pos, size, style ),
38  m_reporter( this ),
39  m_severities( -1 ),
40  m_lazyUpdate( false ),
41  m_printInfo( true )
42 {
44  m_htmlView->SetPage( addHeader( "" ) );
45 
46  Connect( wxEVT_COMMAND_MENU_SELECTED,
47  wxMenuEventHandler( WX_HTML_REPORT_PANEL::onMenuEvent ), NULL, this );
48 }
49 
50 
52 {
53 }
54 
55 
56 void WX_HTML_REPORT_PANEL::MsgPanelSetMinSize( const wxSize& aMinSize )
57 {
58  m_fgSizer->SetMinSize( aMinSize );
59  GetSizer()->SetSizeHints( this );
60 }
61 
62 
64 {
65  return m_reporter;
66 }
67 
68 
69 void WX_HTML_REPORT_PANEL::Report( const wxString& aText, SEVERITY aSeverity,
70  REPORTER::LOCATION aLocation )
71 {
72  REPORT_LINE line;
73  line.message = aText;
74  line.severity = aSeverity;
75 
76  if( aLocation == REPORTER::LOC_HEAD )
77  m_reportHead.push_back( line );
78  else if( aLocation == REPORTER::LOC_TAIL )
79  m_reportTail.push_back( line );
80  else
81  m_report.push_back( line );
82 
83  if( !m_lazyUpdate )
84  {
85  m_htmlView->AppendToPage( generateHtml( line ) );
87  }
88 }
89 
90 
91 void WX_HTML_REPORT_PANEL::SetLazyUpdate( bool aLazyUpdate )
92 {
93  m_lazyUpdate = aLazyUpdate;
94 }
95 
96 
97 void WX_HTML_REPORT_PANEL::Flush( bool aSort )
98 {
99  wxString html;
100 
101  if( aSort )
102  {
103  std::sort( m_report.begin(), m_report.end(),
104  []( const REPORT_LINE& a, const REPORT_LINE& b)
105  {
106  return a.severity < b.severity;
107  });
108  }
109 
110  for( const auto& line : m_reportHead )
111  html += generateHtml( line );
112 
113  for( const auto& line : m_report )
114  html += generateHtml( line );
115 
116  for( const auto& line : m_reportTail )
117  html += generateHtml( line );
118 
119  m_htmlView->SetPage( addHeader( html ) );
120  scrollToBottom();
121 }
122 
123 
125 {
126  int x, y, xUnit, yUnit;
127 
128  m_htmlView->GetVirtualSize( &x, &y );
129  m_htmlView->GetScrollPixelsPerUnit( &xUnit, &yUnit );
130  m_htmlView->Scroll( 0, y / yUnit );
131 
132  updateBadges();
133 }
134 
135 
137 {
138  int count = Count(RPT_SEVERITY_ERROR );
140 
141  count = Count(RPT_SEVERITY_WARNING );
143 }
144 
145 
146 wxString WX_HTML_REPORT_PANEL::addHeader( const wxString& aBody )
147 {
148  wxColour bgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
149  wxColour fgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
150 
151  return wxString::Format( wxT( "<html><body bgcolor='%s' text='%s'>%s</body></html>" ),
152  bgcolor.GetAsString( wxC2S_HTML_SYNTAX ),
153  fgcolor.GetAsString( wxC2S_HTML_SYNTAX ),
154  aBody );
155 }
156 
157 
158 int WX_HTML_REPORT_PANEL::Count( int severityMask )
159 {
160  int count = 0;
161 
162  for( const auto& reportLineArray : { m_report, m_reportHead, m_reportTail } )
163  {
164  for( const REPORT_LINE& reportLine : reportLineArray )
165  {
166  if( severityMask & reportLine.severity )
167  count++;
168  }
169  }
170 
171  return count;
172 }
173 
174 
176 {
177  wxString retv;
178 
179  if( !( m_severities & aLine.severity ) )
180  return retv;
181 
182  switch( aLine.severity )
183  {
184  case RPT_SEVERITY_ERROR:
185  retv = "<font color=\"red\" size=3>" + _( "Error:" ) + " </font>"
186  "<font size=3>" + aLine.message + "</font><br>";
187  break;
189  retv = "<font size=3>" + _( "Warning:" ) + wxS( " " ) + aLine.message + "</font><br>";
190  break;
191  case RPT_SEVERITY_INFO:
192  retv = "<font color=\"dark gray\" size=3>" + aLine.message + "</font><br>";
193  break;
194  case RPT_SEVERITY_ACTION:
195  retv = "<font color=\"dark green\" size=3>" + aLine.message + "</font><br>";
196  break;
197  default:
198  retv = "<font size=3>" + aLine.message + "</font><br>";
199  }
200 
201  return retv;
202 }
203 
204 
206 {
207  switch( aLine.severity )
208  {
209  case RPT_SEVERITY_ERROR:
210  return _( "Error:" ) + wxS( " " )+ aLine.message + wxT( "\n" );
212  return _( "Warning:" ) + wxS( " " )+ aLine.message + wxT( "\n" );
213  case RPT_SEVERITY_INFO:
214  return _( "Info:" ) + wxS( " " )+ aLine.message + wxT( "\n" );
215  default:
216  return aLine.message + wxT( "\n" );
217  }
218 }
219 
220 
221 void WX_HTML_REPORT_PANEL::onRightClick( wxMouseEvent& event )
222 {
223  wxMenu popup;
224  popup.Append( wxID_COPY, "Copy" );
225  PopupMenu( &popup );
226 }
227 
228 
229 void WX_HTML_REPORT_PANEL::onMenuEvent( wxMenuEvent& event )
230 {
231  if( event.GetId() == wxID_COPY )
232  {
233  if( wxTheClipboard->Open() )
234  {
235  bool primarySelection = wxTheClipboard->IsUsingPrimarySelection();
236  wxTheClipboard->UsePrimarySelection( false ); // required to use the main clipboard
237  wxTheClipboard->SetData( new wxTextDataObject( m_htmlView->SelectionToText() ) );
238  wxTheClipboard->Close();
239  wxTheClipboard->UsePrimarySelection( primarySelection );
240  }
241  }
242 }
243 
244 
245 // Don't globally define this; different facilities use different definitions of "ALL"
247 
248 
249 void WX_HTML_REPORT_PANEL::onCheckBoxShowAll( wxCommandEvent& event )
250 {
251  if( event.IsChecked() )
253  else
255 
256  syncCheckboxes();
257  Flush( true );
258 }
259 
260 
262 {
268 }
269 
270 
271 void WX_HTML_REPORT_PANEL::onCheckBoxShowWarnings( wxCommandEvent& event )
272 {
273  if( event.IsChecked() )
275  else
277 
278  syncCheckboxes();
279  Flush( true );
280 }
281 
282 
283 void WX_HTML_REPORT_PANEL::onCheckBoxShowErrors( wxCommandEvent& event )
284 {
285  if( event.IsChecked() )
287  else
289 
290  syncCheckboxes();
291  Flush( true );
292 }
293 
294 
295 void WX_HTML_REPORT_PANEL::onCheckBoxShowInfos( wxCommandEvent& event )
296 {
297  if( event.IsChecked() )
299  else
301 
302  syncCheckboxes();
303  Flush( true );
304 }
305 
306 
307 void WX_HTML_REPORT_PANEL::onCheckBoxShowActions( wxCommandEvent& event )
308 {
309  if( event.IsChecked() )
311  else
313 
314  syncCheckboxes();
315  Flush( true );
316 }
317 
318 
319 void WX_HTML_REPORT_PANEL::onBtnSaveToFile( wxCommandEvent& event )
320 {
321  wxFileName fn;
322 
323  if( m_reportFileName.empty() )
324  fn = wxT( "./report.txt" );
325  else
326  fn = m_reportFileName;
327 
328  wxFileDialog dlg( this, _( "Save Report to File" ), fn.GetPath(), fn.GetFullName(),
329  TextFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
330 
331  if( dlg.ShowModal() != wxID_OK )
332  return;
333 
334  fn = dlg.GetPath();
335 
336  if( fn.GetExt().IsEmpty() )
337  fn.SetExt( "txt" );
338 
339  wxFFile f( fn.GetFullPath(), "wb" );
340 
341  if( !f.IsOpened() )
342  {
343  wxString msg;
344 
345  msg.Printf( _( "Cannot write report to file \"%s\"." ),
346  fn.GetFullPath().GetData() );
347  wxMessageBox( msg, _( "File save error" ), wxOK | wxICON_ERROR, this );
348  return;
349  }
350 
351  for( const REPORT_LINE& l : m_report )
352  {
353  wxString s = generatePlainText( l );
354 
356  f.Write( s );
357  }
358  m_reportFileName = fn.GetFullPath();
359  f.Close();
360 }
361 
362 
364 {
365  m_report.clear();
366  m_reportHead.clear();
367  m_reportTail.clear();
368 }
369 
370 
371 void WX_HTML_REPORT_PANEL::SetLabel( const wxString& aLabel )
372 {
373  m_box->GetStaticBox()->SetLabel( aLabel );
374 }
375 
376 
378 {
379  if( aSeverities < 0 )
381  else
382  m_severities = aSeverities;
383 
384  syncCheckboxes();
385 }
386 
387 
389 {
390  return m_severities;
391 }
392 
393 
394 void WX_HTML_REPORT_PANEL::SetFileName( const wxString& aReportFileName )
395 {
396  m_reportFileName = aReportFileName;
397 }
398 
399 
401 {
402  return ( m_reportFileName );
403 }
404 
405 
406 void WX_HTML_REPORT_PANEL::SetPrintInfo( bool aPrintInfo )
407 {
408  m_printInfo = aPrintInfo;
409 }
410 
411 
412 void WX_HTML_REPORT_PANEL::SetShowSeverity( SEVERITY aSeverity, bool aValue )
413 {
414  switch( aSeverity )
415  {
416  case RPT_SEVERITY_INFO:
417  m_checkBoxShowInfos->SetValue( aValue );
418  break;
419 
420  case RPT_SEVERITY_ACTION:
421  m_checkBoxShowActions->SetValue( aValue );
422  break;
423 
425  m_checkBoxShowWarnings->SetValue( aValue );
426  break;
427 
428  default:
429  m_checkBoxShowErrors->SetValue( aValue );
430  break;
431  }
432 }
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:83
void UpdateNumber(int aNumber, SEVERITY aSeverity)
Update the number displayed on the badge.
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
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
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
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.
bool m_printInfo
Print "Info:" at the front of Info messages (default)
wxString m_reportFileName
Use this as the filename instead of /bin/report.txt (default)
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, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void Clear()
clears the report panel
#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:
void SetFileName(const wxString &aReportFileName)
Set the report full file name to the string
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