Code::Blocks  SVN r11506
loggers.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3  * http://www.gnu.org/licenses/lgpl-3.0.html
4  *
5  * $Revision: 11436 $
6  * $Id: loggers.cpp 11436 2018-08-07 07:13:27Z fuscated $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/sdk/loggers.cpp $
8  */
9 
10 #include "sdk_precomp.h"
11 #ifndef CB_PRECOMP
12  #include <wx/listctrl.h>
13  #include <wx/textctrl.h>
14  #include <wx/settings.h>
15  #include "cbexception.h"
16  #include "manager.h"
17  #include "configmanager.h"
18 #endif
19 
20 #include <wx/clipbrd.h>
21 #include <wx/dataobj.h>
22 #include <wx/wupdlock.h>
23 
24 #include "loggers.h"
25 #include "cbcolourmanager.h"
26 
27 // Helper function which blends a colour with the default window text colour,
28 // so that text will be readable in bright and dark colour schemes
30 {
33 
34  int dist = (fgCol.Red()*fgCol.Red() + fgCol.Green()*fgCol.Green() + fgCol.Blue()*fgCol.Blue())
35  - (bgCol.Red()*bgCol.Red() + bgCol.Green()*bgCol.Green() + bgCol.Blue()*bgCol.Blue());
36  if (dist > 0)
37  {
38  // If foreground color is brighter than background color, this is a dark theme, so
39  // brighten the text colour.
40  // I would use wxColour::changeLightness(), but it's only available in v2.9.0 or later.
41  int d = int(sqrt(dist)/4);
42  int r = col.Red() + d;
43  int g = col.Green() + d;
44  int b = col.Blue() + d;
45  return wxColour( r>255 ? 255 : r, g>255 ? 255 : g, b>255 ? 255 : b );
46  }
47  return col;
48 }
49 
50 TextCtrlLogger::TextCtrlLogger(bool fixedPitchFont) :
51  control(nullptr), fixed(fixedPitchFont)
52 {
53 }
54 
56 {
57  control = nullptr; // invalidate, do NOT destroy
58 }
59 
61 {
62  if (control && control->GetValue().IsEmpty() == false && wxTheClipboard->Open())
63  {
64  wxTheClipboard->SetData(new wxTextDataObject(selectionOnly ? control->GetStringSelection() : control->GetValue()));
65  wxTheClipboard->Close();
66  }
67 }
68 
70 {
71  if (!control)
72  return;
73 
75 
76  ConfigManager* cfgman = Manager::Get()->GetConfigManager(_T("message_manager"));
77  int size = cfgman->ReadInt(_T("/log_font_size"), platform::macosx ? 10 : 8);
78 
80  wxFont bold_font(default_font);
81  wxFont italic_font(default_font);
82 
83  bold_font.SetWeight(wxFONTWEIGHT_BOLD);
84 
85  wxFont bigger_font(bold_font);
86  bigger_font.SetPointSize(size + 2);
87 
88  wxFont small_font(default_font);
89  small_font.SetPointSize(size - 4);
90 
91  italic_font.SetStyle(wxFONTSTYLE_ITALIC);
92 
93  // might try alternatively
94  //italic_font.SetStyle(wxFONTSTYLE_SLANT);
95 
97  for(unsigned int i = 0; i < num_levels; ++i)
98  {
99  style[i].SetFont(default_font);
100  style[i].SetAlignment(wxTEXT_ALIGNMENT_DEFAULT);
101  style[i].SetTextColour(default_text_colour);
102  style[i].SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
103 
104  // is it necessary to do that?
105  //style[i].SetFlags(...);
106  }
107 
108  style[caption].SetAlignment(wxTEXT_ALIGNMENT_CENTRE);
109  bigger_font.SetUnderlined(true);
110  style[caption].SetFont(bigger_font);
111 
113 
114  style[success].SetTextColour(colours->GetColour(wxT("logs_success_text")));
115 
116  style[warning].SetFont(italic_font);
117  style[warning].SetTextColour(colours->GetColour(wxT("logs_warning_text")));
118 
119  style[error].SetFont(bold_font);
120  style[error].SetTextColour(colours->GetColour(wxT("logs_error_text")));
121 
122  style[critical].SetFont(bold_font);
123  style[critical].SetTextColour(colours->GetColour(wxT("logs_critical_text"))); // we're setting both fore and background colors here
124  style[critical].SetBackgroundColour(colours->GetColour(wxT("logs_critical_back"))); // so we don't have to mix in default colors
125  style[spacer].SetFont(small_font);
126 
127  // Tell control about the font change
128  control->SetFont(default_font);
129 } // end of UpdateSettings
130 
132 {
133  if (!control)
134  {
135  // Do the same as the stdout logger, to prevent loss of messages during start up!
136  fputs(wxSafeConvertWX2MB(msg.wc_str()), lv < error ? stdout : stderr);
137  fputs(::newline_string.mb_str(), lv < error ? stdout : stderr);
138  return;
139  }
140 
141  ::temp_string.assign(msg);
142  ::temp_string.append(_T("\n"));
143 
144  if (lv == caption)
145  {
146  control->SetDefaultStyle(style[info]);
147  control->AppendText(::newline_string);
148 
149  control->SetDefaultStyle(style[lv]);
150  control->AppendText(::temp_string);
151 
152  control->SetDefaultStyle(style[spacer]);
153  control->AppendText(::newline_string);
154  }
155  else
156  {
157  control->SetDefaultStyle(style[lv]);
158  control->AppendText(::temp_string);
159  }
160 }
161 
163 {
164  if (control)
165  control->Clear();
166 }
167 
169 {
170  if (!control)
172  return control;
173 }
174 
175 
177 {
178  switch (feature)
179  {
181  return (control && control->IsMultiLine());
182  case Feature::CanClear:
183  case Feature::CanCopy:
184  return true;
185  default:
186  return false;
187  }
188 }
189 
191 {
192  if (!control)
193  return false;
194 
195  long ctrl_style = control->GetWindowStyle();
196  return ((ctrl_style & wxTE_DONTWRAP)!=wxTE_DONTWRAP);
197 }
198 
200 {
202  return;
203 
204  long ctrl_style = control->GetWindowStyle();
205 
206  // wxTE_DONTWRAP is an equivalent for wxHSCROLL (see <wx/textctrl.h>)
207  bool is_dontwrap = ((ctrl_style & wxTE_DONTWRAP)==wxTE_DONTWRAP);
208  if (is_dontwrap)
209  ctrl_style &= ~wxTE_DONTWRAP; // don't wrap = OFF means wrapping = ON
210  else
211  ctrl_style |= wxTE_DONTWRAP; // don't wrap = ON means wrapping = OFF
212 
213 // On Windows the wrap-style can not easily be changed on the fly, but if the align flags
214 // change wxWidgets recreates the textcontrol, doing this ourselves seems not to be so easy,
215 // so we use this hack here (testing if the centred-flag is set, is not needed for our loggers)
216 #ifdef __WXMSW__
217  bool is_centred = ((ctrl_style & wxALIGN_CENTER)==wxALIGN_CENTER);
218  if (is_centred)
219  {
220  ctrl_style &= ~wxALIGN_CENTRE;
221  control->SetWindowStyleFlag(ctrl_style);
222  ctrl_style |= wxALIGN_CENTRE;
223  }
224  else
225  {
226  ctrl_style |= wxALIGN_CENTRE;
227  control->SetWindowStyleFlag(ctrl_style);
228  ctrl_style &= ~wxALIGN_CENTRE;
229  }
230 #endif
231  control->SetWindowStyleFlag(ctrl_style);
232 }
233 
234 
236 {
237  if (!control)
238  return;
239 
240  wxDateTime timestamp(wxDateTime::UNow());
241  ::temp_string.Printf(_T("[%2.2d:%2.2d:%2.2d.%3.3d] %s\n"), timestamp.GetHour(), timestamp.GetMinute(), timestamp.GetSecond(), timestamp.GetMillisecond(), msg.c_str());
242 
243  control->SetDefaultStyle(style[lv]);
244  control->AppendText(::temp_string);
245 }
246 
247 ListCtrlLogger::ListCtrlLogger(const wxArrayString& titles_in, const wxArrayInt& widths_in, bool fixedPitchFont) :
248  control(nullptr),
249  fixed(fixedPitchFont),
250  titles(titles_in),
251  widths(widths_in)
252 {
253  cbAssert(titles.GetCount() == widths.GetCount());
254 }
255 
257 {
258  control = nullptr; // invalidate, do NOT destroy
259 }
260 
262 {
263  if (control && control->GetItemCount() > 0 && wxTheClipboard->Open())
264  {
265  wxString text;
266  if (selectionOnly)
267  {
269  text = GetItemAsText(i);
270  }
271  else
272  {
273  for (int i = 0; i < control->GetItemCount(); ++i)
274  {
275  text << GetItemAsText(i);
276  if (platform::windows)
277  {
278  text << _T('\r'); // Add CR for Windows clipboard
279  }
280  text << _T('\n');
281  }
282  }
283  wxTheClipboard->SetData(new wxTextDataObject(text));
284  wxTheClipboard->Close();
285  }
286 }
287 
289 {
290  if (!control)
291  return wxEmptyString;
292 
293  wxString text;
294 
295  wxListItem li_info;
296  li_info.m_itemId = item;
297  li_info.m_mask = wxLIST_MASK_TEXT;
298 
299  for (size_t i = 0; i < titles.GetCount(); ++i)
300  {
301  li_info.m_col = i;
302  control->GetItem(li_info);
303  text << li_info.m_text << _T('|');
304  }
305  return text;
306 } // end of GetItemAsText
307 
309 {
310  if (!control)
311  return;
312 
313  ConfigManager* cfgman = Manager::Get()->GetConfigManager(_T("message_manager"));
314  int size = cfgman->ReadInt(_T("/log_font_size"), platform::macosx ? 10 : 8);
316  wxFont bold_font(default_font);
317  wxFont italic_font(default_font);
318 
319  bold_font.SetWeight(wxFONTWEIGHT_BOLD);
320 
321  wxFont bigger_font(bold_font);
322  bigger_font.SetPointSize(size + 2);
323 
324  wxFont small_font(default_font);
325  small_font.SetPointSize(size - 4);
326 
327  italic_font.SetStyle(wxFONTSTYLE_ITALIC);
328 
330  for(unsigned int i = 0; i < num_levels; ++i)
331  {
332  style[i].font = default_font;
333  style[i].colour = default_text_colour;
334  }
335 
337 
338  style[caption].font = bigger_font;
339  style[success].colour = colours->GetColour(wxT("logs_success_text"));
340  style[failure].colour = colours->GetColour(wxT("logs_failure_text"));
341 
342  style[warning].font = italic_font;
343  style[warning].colour = colours->GetColour(wxT("logs_warning_text"));
344 
345  style[error].colour = colours->GetColour(wxT("logs_error_text"));
346 
347  style[critical].font = bold_font;
348  style[critical].colour = colours->GetColour(wxT("logs_critical_text_listctrl"));
349 
350  style[spacer].font = small_font;
352 
353  // Tell control and items about the font change
354  control->SetFont(default_font);
355  for (int i = 0; i < control->GetItemCount(); ++i)
356  {
357  wxFont font = control->GetItemFont(i);
358  font.SetPointSize(size);
359  control->SetItemFont( i, font );
360  }//for
361 } // end of UpdateSettings
362 
364 {
365  if (!control)
366  return;
367 
368  int idx = control->GetItemCount();
369 
370  control->Freeze();
371  control->InsertItem(idx, msg);
372  control->SetItemFont(idx, style[lv].font);
373  control->SetItemTextColour(idx, style[lv].colour);
374  control->Thaw();
375 }
376 
377 void ListCtrlLogger::Append(const wxArrayString& colValues, Logger::level lv, int autoSize)
378 {
379  if (!control)
380  return;
381 
382  if (colValues.GetCount() == 0 || colValues.GetCount() > titles.GetCount())
383  return;
384 
385  control->Freeze();
386  Append(colValues[0], lv);
387  int idx = control->GetItemCount() - 1;
388  for (size_t i = 1; i < colValues.GetCount(); ++i)
389  control->SetItem(idx, i, colValues[i]);
390  AutoFitColumns(autoSize);
391  control->Thaw();
392 }
393 
395 {
396  return control ? control->GetItemCount() : 0;
397 }
398 
400 {
401  if (control)
403 }
404 
406 {
407  if (control)
408  return control;
409 
411  for (size_t i = 0; i < titles.GetCount(); ++i)
413 
414  return control;
415 }
416 
418 {
419  switch (feature)
420  {
421  case Feature::CanClear:
422  return true;
423  case Feature::CanCopy:
424  return true;
425  default:
426  return false;
427  }
428 }
429 
431 {
432  if (column != -1)
434 }
435 
437  caption (_T("font-size: 12pt;")),
439  warning (_T("margin-left: 2em;")),
441  error (_T("margin-left: 2em; border-left: 1px solid ")),
442  critical (_T("color: ")),
443  failure (_T("color: ")),
444  pagetitle(_T("font-size: 16pt;")),
446  asterisk (_T("font-family: Arial, Helvetica, \"Bitstream Vera Sans\", sans;"))
447 {
449  critical += BlendTextColour(*wxRED).GetAsString(wxC2S_HTML_SYNTAX) + _T("; font-weight: bold;");
450  failure += BlendTextColour(wxColour(0x80, 0x00, 0x00)).GetAsString(wxC2S_HTML_SYNTAX) + _T(";");
451 }
452 
453 CSS::operator wxString()
454 {
455  wxString tmp(_T('\0'), 300);
456  return tmp;
457 }
458 
460 {
461  Open(filename);
462 }
463 
464 
465 
466 void HTMLFileLogger::Append(const wxString& msg, cb_unused Logger::level lv)
467 {
468  fputs(wxSafeConvertWX2MB(msg.wc_str()), f.fp());
469  fputs(::newline_string.mb_str(), f.fp());
470 }
471 
472 typedef const char* wxStringSucks;
473 
474 
475 void HTMLFileLogger::Open(const wxString& filename)
476 {
477  FileLogger::Open(filename);
478  fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en-US\" lang=\"en-US\">\n<head>\n<title>Build log</title>\n<style>\n", f.fp());
479 
480  if (!!css.asterisk)
481  fprintf(f.fp(), "* { %s }\n", (wxStringSucks) wxSafeConvertWX2MB(css.asterisk.wc_str()));
482  if (!!css.pagetitle)
483  fprintf(f.fp(), "h1 { %s }\n", (wxStringSucks) wxSafeConvertWX2MB(css.pagetitle.wc_str()));
484  if (!!css.caption)
485  fprintf(f.fp(), "h2 { %s }\n", (wxStringSucks) wxSafeConvertWX2MB(css.caption.wc_str()));
486  if (!!css.info)
487  fprintf(f.fp(), ".info { %s }\n", (wxStringSucks) wxSafeConvertWX2MB(css.info.wc_str()));
488  if (!!css.warning)
489  fprintf(f.fp(), ".warn { %s }\n", (wxStringSucks) wxSafeConvertWX2MB(css.warning.wc_str()));
490  if (!!css.error)
491  fprintf(f.fp(), ".error { %s }\n", (wxStringSucks) wxSafeConvertWX2MB(css.error.wc_str()));
492  if (!!css.success)
493  fprintf(f.fp(), ".success { %s }\n", (wxStringSucks) wxSafeConvertWX2MB(css.success.wc_str()));
494  if (!!css.failure)
495  fprintf(f.fp(), ".failure { %s }\n", (wxStringSucks) wxSafeConvertWX2MB(css.failure.wc_str()));
496  if (!!css.critical)
497  fprintf(f.fp(), ".critical { %s }\n", (wxStringSucks) wxSafeConvertWX2MB(css.critical.wc_str()));
498  fputs("</style>\n</head>\n\n<body>", f.fp());
499 }
500 
502 {
503  fputs("</body>\n</html>\n", f.fp());
505 }
void Append(const wxString &msg, Logger::level lv=info) override
Definition: loggers.cpp:363
wxArrayString titles
Definition: loggers.h:126
const char * wxStringSucks
Definition: loggers.cpp:472
wxString GetItemAsText(long item) const
Definition: loggers.cpp:288
#define wxTE_READONLY
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
int ReadInt(const wxString &name, int defaultVal=0)
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
long GetNextItem(long item, int geometry=wxLIST_NEXT_ALL, int state=wxLIST_STATE_DONTCARE) const
#define wxTE_MULTILINE
virtual unsigned char Red() const
#define wxLC_REPORT
virtual void ToggleWrapMode()
Definition: loggers.cpp:199
wxString failure
Definition: loggers.h:67
wxCStrData c_str() const
#define wxLIST_STATE_SELECTED
void Close() override
Definition: loggers.cpp:501
wxWindow * CreateControl(wxWindow *parent) override
Definition: loggers.cpp:168
virtual void SetPointSize(int pointSize)
#define _T(string)
void Append(const wxString &msg, Logger::level lv=info) override
Definition: loggers.cpp:131
virtual size_t GetItemsCount() const
Definition: loggers.cpp:394
wxFont GetItemFont(long item) const
wxString critical
Definition: loggers.h:66
#define wxTheClipboard
virtual void SetWeight(wxFontWeight weight)
virtual void Close()
Definition: loggers.h:55
virtual void Open(const wxString &filename)
Definition: loggers.h:54
#define wxT(string)
static wxDateTime UNow()
~TextCtrlLogger() override
Definition: loggers.cpp:55
#define wxLIST_MASK_TEXT
void Clear() override
Definition: loggers.cpp:399
long InsertItem(wxListItem &info)
void SetItemFont(long item, const wxFont &font)
#define wxTE_NOHIDESEL
CSS()
Definition: loggers.cpp:436
void Append(const wxString &msg, Logger::level lv=info) override
Definition: loggers.cpp:235
bool HasFeature(Feature::Enum feature) const override
Definition: loggers.cpp:176
void CopyContentsToClipboard(bool selectionOnly=false) override
Definition: loggers.cpp:261
null_pointer_t nullptr
Definition: nullptr.cpp:16
bool HasFeature(Feature::Enum feature) const override
Definition: loggers.cpp:417
wxColour GetColour(const wxString &id) const
void Clear() override
Definition: loggers.cpp:162
void Open(const wxString &filename) override
Definition: loggers.cpp:475
TextCtrlLogger(bool fixedPitchFont=false)
Definition: loggers.cpp:50
void Append(const wxString &msg, Logger::level lv) override
Definition: loggers.cpp:466
#define wxTE_AUTO_URL
virtual unsigned char Green() const
void SetItemTextColour(long item, const wxColour &col)
const wxSize wxDefaultSize
const wxPoint wxDefaultPosition
unsigned short GetSecond(const TimeZone &tz=Local) const
bool GetWrapMode() const override
Definition: loggers.cpp:190
void UpdateSettings() override
Definition: loggers.cpp:69
static wxColour GetColour(wxSystemColour index)
bool DeleteAllItems()
#define wxTE_RICH
wxTextCtrl * control
Definition: loggers.h:94
HTMLFileLogger(const wxString &filename)
Definition: loggers.cpp:459
virtual unsigned char Blue() const
int GetItemCount() const
wxString wxEmptyString
const wchar_t * wc_str() const
~ListCtrlLogger() override
Definition: loggers.cpp:256
wxListCtrl * control
Definition: loggers.h:124
#define wxLC_SINGLE_SEL
virtual void SetUnderlined(bool underlined)
#define cbAssert(expr)
Definition: cbexception.h:48
wxWindow * CreateControl(wxWindow *parent) override
Definition: loggers.cpp:405
wxArray< int > wxArrayInt
ListCtrlLogger(const wxArrayString &titles, const wxArrayInt &widths, bool fixedPitchFont=false)
Definition: loggers.cpp:247
ColourManager * GetColourManager() const
Definition: manager.cpp:489
unsigned short GetMillisecond(const TimeZone &tz=Local) const
virtual void SetStyle(wxFontStyle style)
level
Definition: logger.h:37
unsigned short GetMinute(const TimeZone &tz=Local) const
ListStyles style[num_levels]
Definition: loggers.h:134
wxArrayInt widths
Definition: loggers.h:127
long InsertColumn(long col, const wxListItem &info)
virtual void AutoFitColumns(int column)
Definition: loggers.cpp:430
bool SetItem(wxListItem &info)
bool SetColumnWidth(int col, int width)
wxTextAttr style[num_levels]
Definition: loggers.h:96
wxString error
Definition: loggers.h:65
size_t GetCount() const
#define wxTE_DONTWRAP
bool fixed
Definition: loggers.h:95
unsigned short GetHour(const TimeZone &tz=Local) const
virtual wxString GetAsString(long flags=wxC2S_NAME|wxC2S_CSS_SYNTAX) const
void UpdateSettings() override
Definition: loggers.cpp:308
void CopyContentsToClipboard(bool selectionOnly=false) override
Definition: loggers.cpp:60
wxColour BlendTextColour(wxColour col)
Definition: loggers.cpp:29
bool GetItem(wxListItem &info) const