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 
31  wxWindowID id,
32  const wxPoint& pos,
33  const wxSize& size,
34  long style ) :
35  WX_HTML_REPORT_PANEL_BASE( parent, id, pos, size, style ),
36  m_reporter( this ),
37  m_severities( -1 ),
38  m_lazyUpdate( false )
39 {
41  m_htmlView->SetPage( addHeader( "" ) );
42 
43  Connect( wxEVT_COMMAND_MENU_SELECTED,
44  wxMenuEventHandler( WX_HTML_REPORT_PANEL::onMenuEvent ), NULL, this );
45 }
46 
47 
49 {
50 }
51 
52 
53 void WX_HTML_REPORT_PANEL::MsgPanelSetMinSize( const wxSize& aMinSize )
54 {
55  m_fgSizer->SetMinSize( aMinSize );
56  GetSizer()->SetSizeHints( this );
57 }
58 
59 
61 {
62  return m_reporter;
63 }
64 
65 
66 void WX_HTML_REPORT_PANEL::Report( const wxString& aText, SEVERITY aSeverity,
67  REPORTER::LOCATION aLocation )
68 {
69  REPORT_LINE line;
70  line.message = aText;
71  line.severity = aSeverity;
72 
73  if( aLocation == REPORTER::LOC_HEAD )
74  m_reportHead.push_back( line );
75  else if( aLocation == REPORTER::LOC_TAIL )
76  m_reportTail.push_back( line );
77  else
78  m_report.push_back( line );
79 
80  if( !m_lazyUpdate )
81  {
82  m_htmlView->AppendToPage( generateHtml( line ) );
84  }
85 }
86 
87 
88 void WX_HTML_REPORT_PANEL::SetLazyUpdate( bool aLazyUpdate )
89 {
90  m_lazyUpdate = aLazyUpdate;
91 }
92 
93 
94 void WX_HTML_REPORT_PANEL::Flush( bool aSort )
95 {
96  wxString html;
97 
98  if( aSort )
99  {
100  std::sort( m_report.begin(), m_report.end(),
101  []( const REPORT_LINE& a, const REPORT_LINE& b)
102  {
103  return a.severity < b.severity;
104  });
105  }
106 
107  for( const auto& line : m_reportHead )
108  html += generateHtml( line );
109 
110  for( const auto& line : m_report )
111  html += generateHtml( line );
112 
113  for( const auto& line : m_reportTail )
114  html += generateHtml( line );
115 
116  m_htmlView->SetPage( addHeader( html ) );
117  scrollToBottom();
118 }
119 
120 
122 {
123  int x, y, xUnit, yUnit;
124 
125  m_htmlView->GetVirtualSize( &x, &y );
126  m_htmlView->GetScrollPixelsPerUnit( &xUnit, &yUnit );
127  m_htmlView->Scroll( 0, y / yUnit );
128 
129  updateBadges();
130 }
131 
132 
134 {
135  int count = Count(RPT_SEVERITY_ERROR );
136  m_errorsBadge->SetBitmap( MakeBadge( RPT_SEVERITY_ERROR, count, m_errorsBadge, 2 ) );
137 
138  count = Count(RPT_SEVERITY_WARNING );
140 }
141 
142 
143 wxString WX_HTML_REPORT_PANEL::addHeader( const wxString& aBody )
144 {
145  wxColour bgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
146  wxColour fgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
147 
148  return wxString::Format( wxT( "<html><body bgcolor='%s' text='%s'>%s</body></html>" ),
149  bgcolor.GetAsString( wxC2S_HTML_SYNTAX ),
150  fgcolor.GetAsString( wxC2S_HTML_SYNTAX ),
151  aBody );
152 }
153 
154 
155 int WX_HTML_REPORT_PANEL::Count( int severityMask )
156 {
157  int count = 0;
158 
159  for( const REPORT_LINE& reportLine : m_report )
160  if( severityMask & reportLine.severity )
161  count++;
162 
163  return count;
164 }
165 
166 
168 {
169  wxString retv;
170 
171  if( !( m_severities & aLine.severity ) )
172  return retv;
173 
174  switch( aLine.severity )
175  {
176  case RPT_SEVERITY_ERROR:
177  retv = "<font color=\"red\" size=3>" + _( "Error: " ) + "</font>"
178  "<font size=3>" + aLine.message + "</font><br>";
179  break;
181  retv = "<font size=3>" + _( "Warning: " ) + aLine.message + "</font><br>";
182  break;
183  case RPT_SEVERITY_INFO:
184  retv = "<font color=\"dark gray\" size=3>" + _( "Info: " ) + aLine.message + "</font><br>";
185  break;
186  case RPT_SEVERITY_ACTION:
187  retv = "<font color=\"dark green\" size=3>" + aLine.message + "</font><br>";
188  break;
189  default:
190  retv = "<font size=3>" + aLine.message + "</font><br>";
191  }
192 
193  return retv;
194 }
195 
196 
198 {
199  switch( aLine.severity )
200  {
201  case RPT_SEVERITY_ERROR:
202  return _( "Error: " ) + aLine.message + wxT( "\n" );
204  return _( "Warning: " ) + aLine.message + wxT( "\n" );
205  case RPT_SEVERITY_INFO:
206  return _( "Info: " ) + aLine.message + wxT( "\n" );
207  default:
208  return aLine.message + wxT( "\n" );
209  }
210 }
211 
212 
213 void WX_HTML_REPORT_PANEL::onRightClick( wxMouseEvent& event )
214 {
215  wxMenu popup;
216  popup.Append( wxID_COPY, "Copy" );
217  PopupMenu( &popup );
218 }
219 
220 
221 void WX_HTML_REPORT_PANEL::onMenuEvent( wxMenuEvent& event )
222 {
223  if( event.GetId() == wxID_COPY )
224  {
225  if( wxTheClipboard->Open() )
226  {
227  bool primarySelection = wxTheClipboard->IsUsingPrimarySelection();
228  wxTheClipboard->UsePrimarySelection( false ); // required to use the main clipboard
229  wxTheClipboard->SetData( new wxTextDataObject( m_htmlView->SelectionToText() ) );
230  wxTheClipboard->Close();
231  wxTheClipboard->UsePrimarySelection( primarySelection );
232  }
233  }
234 }
235 
236 
237 // Don't globally define this; different facilities use different definitions of "ALL"
239 
240 
241 void WX_HTML_REPORT_PANEL::onCheckBoxShowAll( wxCommandEvent& event )
242 {
243  if( event.IsChecked() )
245  else
247 
248  syncCheckboxes();
249  Flush( true );
250 }
251 
252 
254 {
260 }
261 
262 
263 void WX_HTML_REPORT_PANEL::onCheckBoxShowWarnings( wxCommandEvent& event )
264 {
265  if( event.IsChecked() )
267  else
269 
270  syncCheckboxes();
271  Flush( true );
272 }
273 
274 
275 void WX_HTML_REPORT_PANEL::onCheckBoxShowErrors( wxCommandEvent& event )
276 {
277  if( event.IsChecked() )
279  else
281 
282  syncCheckboxes();
283  Flush( true );
284 }
285 
286 
287 void WX_HTML_REPORT_PANEL::onCheckBoxShowInfos( wxCommandEvent& event )
288 {
289  if( event.IsChecked() )
291  else
293 
294  syncCheckboxes();
295  Flush( true );
296 }
297 
298 
299 void WX_HTML_REPORT_PANEL::onCheckBoxShowActions( wxCommandEvent& event )
300 {
301  if( event.IsChecked() )
303  else
305 
306  syncCheckboxes();
307  Flush( true );
308 }
309 
310 
311 void WX_HTML_REPORT_PANEL::onBtnSaveToFile( wxCommandEvent& event )
312 {
313  wxFileName fn( "./report.txt" );
314 
315  wxFileDialog dlg( this, _( "Save Report to File" ), fn.GetPath(), fn.GetFullName(),
316  TextFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
317 
318  if( dlg.ShowModal() != wxID_OK )
319  return;
320 
321  fn = dlg.GetPath();
322 
323  if( fn.GetExt().IsEmpty() )
324  fn.SetExt( "txt" );
325 
326  wxFile f( fn.GetFullPath(), wxFile::write );
327 
328  if( !f.IsOpened() )
329  {
330  wxString msg;
331 
332  msg.Printf( _( "Cannot write report to file \"%s\"." ),
333  fn.GetFullPath().GetData() );
334  wxMessageBox( msg, _( "File save error" ), wxOK | wxICON_ERROR, this );
335  return;
336  }
337 
338  for( const REPORT_LINE& l : m_report )
339  {
340  f.Write( generatePlainText( l ) );
341  }
342 
343  f.Close();
344 }
345 
346 
348 {
349  m_report.clear();
350  m_reportHead.clear();
351  m_reportTail.clear();
352 }
353 
354 
355 void WX_HTML_REPORT_PANEL::SetLabel( const wxString& aLabel )
356 {
357  m_box->GetStaticBox()->SetLabel( aLabel );
358 }
359 
360 
362 {
363  if( aSeverities < 0 )
365  else
366  m_severities = aSeverities;
367 
368  syncCheckboxes();
369 }
370 
371 
373 {
374  return m_severities;
375 }
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
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
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.
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:205
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:
void SetLabel(const wxString &aLabel) override
sets the frame label
void onMenuEvent(wxMenuEvent &event)
int m_severities
message severities to display (mask)
static int RPT_SEVERITY_ALL