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=2><b>" + _( "Error: " ) + "</b></font><font size=2>" +
178  aLine.message + "</font><br>";
179  break;
181  retv = "<font color=\"orange\" size=2><b>" + _( "Warning: " ) +
182  "</b></font><font size=2>" + aLine.message + "</font><br>";
183  break;
184  case RPT_SEVERITY_INFO:
185  retv = "<font color=\"dark gray\" size=2><b>" + _( "Info: " ) + "</b>" + aLine.message +
186  "</font><br>";
187  break;
188  case RPT_SEVERITY_ACTION:
189  retv = "<font color=\"dark green\" size=2>" + aLine.message + "</font><br>";
190  break;
191  default:
192  retv = "<font size=2>" + 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( "./report.txt" );
316 
317  wxFileDialog dlg( this, _( "Save Report to File" ), fn.GetPath(), fn.GetFullName(),
318  TextFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
319 
320  if( dlg.ShowModal() != wxID_OK )
321  return;
322 
323  fn = dlg.GetPath();
324 
325  if( fn.GetExt().IsEmpty() )
326  fn.SetExt( "txt" );
327 
328  wxFile f( fn.GetFullPath(), wxFile::write );
329 
330  if( !f.IsOpened() )
331  {
332  wxString msg;
333 
334  msg.Printf( _( "Cannot write report to file \"%s\"." ),
335  fn.GetFullPath().GetData() );
336  wxMessageBox( msg, _( "File save error" ), wxOK | wxICON_ERROR, this );
337  return;
338  }
339 
340  for( const REPORT_LINE& l : m_report )
341  {
342  f.Write( generatePlainText( l ) );
343  }
344 
345  f.Close();
346 }
347 
348 
350 {
351  m_report.clear();
352  m_reportHead.clear();
353  m_reportTail.clear();
354 }
355 
356 
357 void WX_HTML_REPORT_PANEL::SetLabel( const wxString& aLabel )
358 {
359  m_box->GetStaticBox()->SetLabel( aLabel );
360 }
361 
362 
364 {
365  if( aSeverities < 0 )
367  else
368  m_severities = aSeverities;
369 
370  syncCheckboxes();
371 }
372 
373 
375 {
376  return m_severities;
377 }
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:62
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:71
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:34
#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