1 // Gmsh - Copyright (C) 1997-2021 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #ifndef MESSAGE_BROWSER_H
7 #define MESSAGE_BROWSER_H
8 
9 #include "FlGui.h"
10 #include <algorithm>
11 #include <string>
12 #include <regex>
13 
14 class messageBrowser : public Fl_Group {
15 private:
16   Fl_Browser *_browser;
17   Fl_Group *_box;
18   Fl_Check_Button *_autoscroll;
19   Fl_Button *_clear, *_save;
20   Fl_Input *_search;
21 
22 public:
23   messageBrowser(int x, int y, int w, int h, const char *l = 0)
Fl_Group(x,y,w,h,l)24     : Fl_Group(x, y, w, h, l)
25   {
26     int bh = BH - 4; // button height
27     int wb = WB / 2; // border
28     int bb = BB - 3 * WB;
29     int sw = 3 * BB; // search field width
30 
31     _box = new Fl_Group(x, y, w, bh + 2 * wb);
32     _box->box(GMSH_SIMPLE_TOP_BOX);
33 
34     Fl_Group *o = new Fl_Group(x + wb, y + wb, sw, bh);
35     o->tooltip("Filter messages using regular expression");
36     o->box(FL_THIN_DOWN_BOX);
37     o->color(FL_BACKGROUND2_COLOR);
38     _search = new Fl_Input(x + wb + bh, y + wb + 2, sw - bh - 2, bh - 4,
39                            "@-1gmsh_search");
40     _search->box(FL_FLAT_BOX);
41     _search->when(FL_WHEN_CHANGED);
42     _search->textsize(FL_NORMAL_SIZE - 1);
43     o->resizable(_search);
44     o->end();
45 
46     _save = new Fl_Button(x + wb + sw + WB, y + wb, bb, bh, "Save");
47     _save->labelsize(FL_NORMAL_SIZE - 1);
48     _save->box(FL_THIN_UP_BOX);
49 
50     _clear = new Fl_Button(x + sw + bb + 2 * WB, y + wb, bb, bh, "Clear");
51     _clear->labelsize(FL_NORMAL_SIZE - 1);
52     _clear->box(FL_THIN_UP_BOX);
53 
54     _autoscroll = new Fl_Check_Button(x + sw + 2 * bb + 3 * WB, y + wb, 2 * bb,
55                                       bh, "Autoscroll messages");
56     _autoscroll->labelsize(FL_NORMAL_SIZE - 1);
57     _autoscroll->type(FL_TOGGLE_BUTTON);
58     _autoscroll->value(1);
59 
60     _box->end();
61     _box->resizable(0);
62 
63     _browser = new Fl_Browser(x, y + bh + 2 * wb, w, h - bh - 2 * wb, l);
64     _browser->box(GMSH_SIMPLE_TOP_BOX);
65 #if defined(WIN32) // FL_SCREEN seems to be too tiny on most Windows setups
66     _browser->textfont(FL_COURIER);
67 #else
68     _browser->textfont(FL_SCREEN);
69 #endif
70     _browser->type(FL_MULTI_BROWSER);
71     _browser->tooltip("Selected lines are copied to the clipboard");
72     _browser->end();
73     end();
74     resizable(_browser);
75   }
box(Fl_Boxtype new_box)76   void box(Fl_Boxtype new_box) { _browser->box(new_box); }
textfont(Fl_Font font)77   void textfont(Fl_Font font) { _browser->textfont(font); }
textsize(Fl_Fontsize newSize)78   void textsize(Fl_Fontsize newSize) { _browser->textsize(newSize); }
textsize()79   Fl_Fontsize textsize() const { return _browser->textsize(); }
callback(Fl_Callback * cb,void * p)80   void callback(Fl_Callback *cb, void *p) { _browser->callback(cb, p); }
search_callback(Fl_Callback * cb,void * p)81   void search_callback(Fl_Callback *cb, void *p) { _search->callback(cb, p); }
autoscroll_callback(Fl_Callback * cb,void * p)82   void autoscroll_callback(Fl_Callback *cb, void *p)
83   {
84     _autoscroll->callback(cb, p);
85   }
save_callback(Fl_Callback * cb,void * p)86   void save_callback(Fl_Callback *cb, void *p) { _save->callback(cb, p); }
clear_callback(Fl_Callback * cb,void * p)87   void clear_callback(Fl_Callback *cb, void *p) { _clear->callback(cb, p); }
bottomline(int line)88   void bottomline(int line) { _browser->bottomline(line); }
size()89   int size() { return _browser->size(); }
add(const char * newtext)90   void add(const char *newtext)
91   {
92     std::string search = _search->value();
93     if(search.empty()) { _browser->add(newtext); }
94     else {
95       std::string tmp(newtext);
96       try {
97         // icase for case-insensitive search
98         if(std::regex_search(tmp,
99                              std::regex(search, std::regex_constants::icase)))
100           _browser->add(newtext);
101       } catch(...) {
102       }
103     }
104   }
clear()105   void clear() { _browser->clear(); }
text(int line)106   const char *text(int line) const { return _browser->text(line); }
selected(int line)107   int selected(int line) const { return _browser->selected(line); }
108 };
109 
110 #endif
111