From 7deb8b10a6dd16d22c3b4823411a031490d1ba8e Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Mon, 22 Feb 2016 15:40:04 +0000 Subject: [PATCH] better message browser with dynamic filter --- Common/CreateFile.cpp | 1 + Common/GmshMessage.cpp | 4 +- Common/GmshMessage.h | 2 +- Common/OpenFile.cpp | 3 +- Fltk/drawContextFltk.h | 1 + Fltk/graphicWindow.cpp | 203 +++++++++++++++++--------------------- Fltk/graphicWindow.h | 13 ++- Fltk/manipWindow.cpp | 1 + Fltk/messageBrowser.h | 98 ++++++++++++++++++ Fltk/visibilityWindow.cpp | 1 + 10 files changed, 210 insertions(+), 117 deletions(-) create mode 100644 Fltk/messageBrowser.h diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp index 57b87fafb8..4a50810cce 100644 --- a/Common/CreateFile.cpp +++ b/Common/CreateFile.cpp @@ -20,6 +20,7 @@ #if defined(HAVE_FLTK) #include "FlGui.h" #include "graphicWindow.h" +#include "openglWindow.h" #include "gl2ps.h" #include "gl2gif.h" #include "gl2jpeg.h" diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp index 8eadda1e06..d9283f963e 100644 --- a/Common/GmshMessage.cpp +++ b/Common/GmshMessage.cpp @@ -763,7 +763,8 @@ void Msg::SetOnelabNumber(std::string name, double val, bool visible, } void Msg::SetOnelabString(std::string name, std::string val, bool visible, - bool persistent, bool readOnly, bool neverChanged) + bool persistent, bool readOnly, bool neverChanged, + const std::string &kind) { #if defined(HAVE_ONELAB) if(_onelabClient){ @@ -778,6 +779,7 @@ void Msg::SetOnelabString(std::string name, std::string val, bool visible, if(persistent) strings[0].setAttribute("Persistent", "1"); strings[0].setReadOnly(readOnly); strings[0].setNeverChanged(neverChanged); + if(kind.size()) strings[0].setKind(kind); _onelabClient->set(strings[0]); } #endif diff --git a/Common/GmshMessage.h b/Common/GmshMessage.h index 4f13a6dc24..a7582c2764 100644 --- a/Common/GmshMessage.h +++ b/Common/GmshMessage.h @@ -121,7 +121,7 @@ class Msg { bool neverChanged=false); static void SetOnelabString(std::string name, std::string val, bool visible=true, bool persistent=false, bool readOnly=false, - bool neverChanged=false); + bool neverChanged=false, const std::string &kind=""); static double GetOnelabNumber(std::string name, double defaultValue=0., bool errorIfMissing=false); static std::string GetOnelabString(std::string name, const std::string &defaultValue="", diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp index ed7047ab8e..a94faa3961 100644 --- a/Common/OpenFile.cpp +++ b/Common/OpenFile.cpp @@ -343,7 +343,8 @@ int MergeFile(const std::string &fileName, bool warnIfMissing, bool setBoundingB std::string solver = getSolverForExtension(ext); if(solver.size()){ int num = defineSolver(solver); - Msg::SetOnelabString(solver + "/Model name", fileName, true, true); + Msg::SetOnelabString(solver + "/Model name", fileName, true, true, + false, false, "file"); if(GModel::current()->getName() == "" || Msg::GetOnelabString("Gmsh/Model name").empty()){ GModel::current()->setFileName(split[0] + split[1] + ".geo"); diff --git a/Fltk/drawContextFltk.h b/Fltk/drawContextFltk.h index 63fba50486..c3d4f21734 100644 --- a/Fltk/drawContextFltk.h +++ b/Fltk/drawContextFltk.h @@ -12,6 +12,7 @@ #include "drawContext.h" #include "graphicWindow.h" #include "optionWindow.h" +#include "openglWindow.h" #include "Context.h" class drawContextFltk : public drawContextGlobal{ diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index c4adfd1509..0840444e78 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -33,6 +33,9 @@ typedef unsigned long intptr_t; #include "fieldWindow.h" #include "pluginWindow.h" #include "helpWindow.h" +#include "openglWindow.h" +#include "onelabGroup.h" +#include "messageBrowser.h" #include "gmshLocalNetworkClient.h" #include "fileDialogs.h" #include "extraDialogs.h" @@ -2776,7 +2779,7 @@ void attach_detach_menu_cb(Fl_Widget *w, void *data) FlGui::instance()->check(); } -static void message_menu_scroll_cb(Fl_Widget *w, void *data) +static void message_menu_autoscroll_cb(Fl_Widget *w, void *data) { graphicWindow *g = (graphicWindow*)data; g->setAutoScroll(!g->getAutoScroll()); @@ -2795,39 +2798,18 @@ static void message_menu_save_cb(Fl_Widget *w, void *data) g->saveMessages(fileChooserGetName(1).c_str()); } -#if 0 -static void message_menu_increase_font_cb(Fl_Widget *w, void *data) +static void message_browser_cb(Fl_Widget *w, void *data) { graphicWindow *g = (graphicWindow*)data; - g->changeMessageFontSize(1); + g->copySelectedMessagesToClipboard(); } -static void message_menu_decrease_font_cb(Fl_Widget *w, void *data) +static void message_menu_search_cb(Fl_Widget *w, void *data) { graphicWindow *g = (graphicWindow*)data; - g->changeMessageFontSize(-1); -} -#endif - -static void message_browser_cb(Fl_Widget *w, void *data) -{ - graphicWindow *g = (graphicWindow*)data; - - if(Fl::event_button() == 3 || Fl::event_state(FL_CTRL) || Fl::event_clicks()){ - Fl_Menu_Item rclick_menu[] = { - { g->getAutoScroll() ? "Disable Auto-Scrolling" : "Enable Auto-Scrolling", 0, - message_menu_scroll_cb, g }, - { "Clear Messages", 0, message_menu_clear_cb, g }, - { "Save Messages...", 0, message_menu_save_cb, g }, - //{ "Increase font size", 0, message_menu_increase_font_cb, g }, - //{ "Decrease font size", 0, message_menu_decrease_font_cb, g }, - { 0 } - }; - const Fl_Menu_Item *m = rclick_menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0); - if(m) m->do_callback(0, m->user_data()); - } - else - g->copySelectedMessagesToClipboard(); + g->getMessageBrowser()->clear(); + for(int i = 0; i < g->getMessages().size(); i++) + g->getMessageBrowser()->add(g->getMessages()[i].c_str()); } static void tile_cb(Fl_Widget *w, void *data) @@ -2895,7 +2877,7 @@ graphicWindow::graphicWindow(bool main, int numTiles, bool detachedMenu) int sh = 2 * FL_NORMAL_SIZE - 3; // status bar height int sw = FL_NORMAL_SIZE + 2; // status button width - int mheight = main ? 10 /* dummy, nonzero! */ : 0; + int mheight = main ? 2 * BH /* nonzero! */ : 0; int glheight = CTX::instance()->glSize[1] - mheight; int height = mh + glheight + mheight + sh; // make sure height < screen height @@ -2950,6 +2932,85 @@ graphicWindow::graphicWindow(bool main, int numTiles, bool detachedMenu) #endif } + // tiled windows (tree menu, opengl, messages) + _tile = new Fl_Tile(0, mh, glwidth + twidth, glheight + mheight); + + int w2 = glwidth / 2, h2 = glheight / 2; + if(numTiles == 2){ + gl.push_back(new openglWindow(twidth, mh, w2, glheight)); + gl.back()->end(); + gl.push_back(new openglWindow(twidth + w2, mh, glwidth - w2, glheight)); + gl.back()->end(); + } + else if(numTiles == 3){ + gl.push_back(new openglWindow(twidth, mh, w2, glheight)); + gl.back()->end(); + gl.push_back(new openglWindow(twidth + w2, mh, glwidth - w2, h2)); + gl.back()->end(); + gl.push_back(new openglWindow(twidth + w2, mh + h2, glwidth - w2, glheight - h2)); + gl.back()->end(); + } + else if(numTiles == 4){ + gl.push_back(new openglWindow(twidth, mh, w2, h2)); + gl.back()->end(); + gl.push_back(new openglWindow(twidth + w2, mh, glwidth - w2, h2)); + gl.back()->end(); + gl.push_back(new openglWindow(twidth, mh + h2, w2, glheight - h2)); + gl.back()->end(); + gl.push_back(new openglWindow(twidth + w2, mh + h2, glwidth - w2, glheight - h2)); + gl.back()->end(); + } + else{ + gl.push_back(new openglWindow(twidth, mh, glwidth, glheight)); + gl.back()->end(); + } + + int mode = FL_RGB | FL_DEPTH | (CTX::instance()->db ? FL_DOUBLE : FL_SINGLE); + if(CTX::instance()->antialiasing) mode |= FL_MULTISAMPLE; + if(CTX::instance()->stereo) { + mode |= FL_DOUBLE; + mode |= FL_STEREO; + } + for(unsigned int i = 0; i < gl.size(); i++) gl[i]->mode(mode); + + if(main){ + _browser = new messageBrowser(twidth, mh + glheight, glwidth, mheight); + int s = CTX::instance()->msgFontSize; +#if defined(WIN32) // screen font on Windows is really small + _browser->textsize(s <= 0 ? FL_NORMAL_SIZE : s); +#else + _browser->textsize(s <= 0 ? FL_NORMAL_SIZE - 2 : s); +#endif + _browser->callback(message_browser_cb, this); + _browser->search_callback(message_menu_search_cb, this); + _browser->autoscroll_callback(message_menu_autoscroll_cb, this); + _browser->save_callback(message_menu_save_cb, this); + _browser->clear_callback(message_menu_clear_cb, this); + } + else{ + _browser = 0; + } + + if(main && !detachedMenu){ + _onelab = new onelabGroup(0, mh, twidth, height - mh - sh); + _onelab->enableTreeWidgetResize(false); + } + else{ + _onelab = 0; + } + + _tile->callback(tile_cb); + _tile->end(); + + // resize the tiles to match the prescribed sizes + _tile->position(0, mh + glheight, 0, mh + CTX::instance()->glSize[1]); + + // if the tree widget is too small it will not be rebuilt correctly (probably + // a bug)... so impose minimum width + int minw = 3 * BB/2 + 4 * WB; + if(CTX::instance()->menuSize[0] < minw) CTX::instance()->menuSize[0] = minw; + _tile->position(twidth, 0, CTX::instance()->menuSize[0], 0); + // bottom button bar _bottom = new Fl_Box(0, mh + glheight + mheight, width, sh); _bottom->box(GMSH_SIMPLE_TOP_BOX); @@ -3033,86 +3094,6 @@ graphicWindow::graphicWindow(bool main, int numTiles, bool detachedMenu) _minWidth = x; _minHeight = 100; _win->size_range(_minWidth, _minHeight); - - // tiled windows (tree menu, opengl, messages) - _tile = new Fl_Tile(0, mh, glwidth + twidth, glheight + mheight); - - int w2 = glwidth / 2, h2 = glheight / 2; - if(numTiles == 2){ - gl.push_back(new openglWindow(twidth, mh, w2, glheight)); - gl.back()->end(); - gl.push_back(new openglWindow(twidth + w2, mh, glwidth - w2, glheight)); - gl.back()->end(); - } - else if(numTiles == 3){ - gl.push_back(new openglWindow(twidth, mh, w2, glheight)); - gl.back()->end(); - gl.push_back(new openglWindow(twidth + w2, mh, glwidth - w2, h2)); - gl.back()->end(); - gl.push_back(new openglWindow(twidth + w2, mh + h2, glwidth - w2, glheight - h2)); - gl.back()->end(); - } - else if(numTiles == 4){ - gl.push_back(new openglWindow(twidth, mh, w2, h2)); - gl.back()->end(); - gl.push_back(new openglWindow(twidth + w2, mh, glwidth - w2, h2)); - gl.back()->end(); - gl.push_back(new openglWindow(twidth, mh + h2, w2, glheight - h2)); - gl.back()->end(); - gl.push_back(new openglWindow(twidth + w2, mh + h2, glwidth - w2, glheight - h2)); - gl.back()->end(); - } - else{ - gl.push_back(new openglWindow(twidth, mh, glwidth, glheight)); - gl.back()->end(); - } - - int mode = FL_RGB | FL_DEPTH | (CTX::instance()->db ? FL_DOUBLE : FL_SINGLE); - if(CTX::instance()->antialiasing) mode |= FL_MULTISAMPLE; - if(CTX::instance()->stereo) { - mode |= FL_DOUBLE; - mode |= FL_STEREO; - } - for(unsigned int i = 0; i < gl.size(); i++) gl[i]->mode(mode); - - if(main){ - _browser = new Fl_Browser(twidth, mh + glheight, glwidth, mheight); - _browser->box(GMSH_SIMPLE_TOP_BOX); - _browser->textfont(FL_SCREEN); - int s = CTX::instance()->msgFontSize; -#if defined(WIN32) // screen font on Windows is really small - _browser->textsize(s <= 0 ? FL_NORMAL_SIZE : s); -#else - _browser->textsize(s <= 0 ? FL_NORMAL_SIZE - 2 : s); -#endif - _browser->type(FL_MULTI_BROWSER); - _browser->callback(message_browser_cb, this); - _browser->scrollbar_size(std::max(10, FL_NORMAL_SIZE - 2)); // thinner scrollbars - } - else{ - _browser = 0; - } - - if(main && !detachedMenu){ - _onelab = new onelabGroup(0, mh, twidth, height - mh - sh); - _onelab->enableTreeWidgetResize(false); - } - else{ - _onelab = 0; - } - - _tile->callback(tile_cb); - _tile->end(); - - // resize the tiles to match the prescribed sizes - _tile->position(0, mh + glheight, 0, mh + CTX::instance()->glSize[1]); - - // if the tree widget is too small it will not be rebuilt correctly (probably - // a bug)... so impose minimum width - int minw = 3 * BB/2 + 4 * WB; - if(CTX::instance()->menuSize[0] < minw) CTX::instance()->menuSize[0] = minw; - _tile->position(twidth, 0, CTX::instance()->menuSize[0], 0); - _win->position(CTX::instance()->glPosition[0], CTX::instance()->glPosition[1]); _win->end(); @@ -3482,13 +3463,15 @@ int graphicWindow::getMessageHeight() void graphicWindow::addMessage(const char *msg) { if(!_browser) return; - _browser->add(msg, 0); + _messages.push_back(msg); + _browser->add(msg); if(_autoScrollMessages && _win->shown() && _browser->h() >= FL_NORMAL_SIZE) _browser->bottomline(_browser->size()); } void graphicWindow::clearMessages() { + _messages.clear(); if(!_browser) return; _browser->clear(); } diff --git a/Fltk/graphicWindow.h b/Fltk/graphicWindow.h index 5a6559396c..e0c415ac9f 100644 --- a/Fltk/graphicWindow.h +++ b/Fltk/graphicWindow.h @@ -18,8 +18,10 @@ #include <FL/Fl_Sys_Menu_Bar.H> #endif #include <FL/Fl_Menu_Bar.H> -#include "openglWindow.h" -#include "onelabGroup.h" + +class openglWindow; +class onelabGroup; +class messageBrowser; class graphicWindow{ private: @@ -30,13 +32,14 @@ class graphicWindow{ Fl_Menu_Bar *_bar; Fl_Tile *_tile; Fl_Window *_win, *_menuwin; - Fl_Browser *_browser; + messageBrowser *_browser; onelabGroup *_onelab; Fl_Box *_bottom; Fl_Button *_butt[14]; Fl_Progress *_label; int _minWidth, _minHeight; - public: + std::vector<std::string> _messages; +public: std::vector<openglWindow*> gl; public: graphicWindow(bool main=true, int numTiles=1, bool detachedMenu=false); @@ -46,6 +49,8 @@ class graphicWindow{ onelabGroup *getMenu(){ return _onelab; } Fl_Progress *getProgress(){ return _label; } Fl_Button *getSelectionButton(){ return _butt[9]; } + messageBrowser *getMessageBrowser(){ return _browser; } + std::vector<std::string> &getMessages(){ return _messages; } int getMinWidth(){ return _minWidth; } int getMinHeight(){ return _minHeight; } void setAutoScroll(bool val){ _autoScrollMessages = val; } diff --git a/Fltk/manipWindow.cpp b/Fltk/manipWindow.cpp index aa3f7dac57..8ecff4bc7c 100644 --- a/Fltk/manipWindow.cpp +++ b/Fltk/manipWindow.cpp @@ -9,6 +9,7 @@ #include "manipWindow.h" #include "paletteWindow.h" #include "graphicWindow.h" +#include "openglWindow.h" #include "Options.h" #include "Context.h" diff --git a/Fltk/messageBrowser.h b/Fltk/messageBrowser.h new file mode 100644 index 0000000000..065c48829c --- /dev/null +++ b/Fltk/messageBrowser.h @@ -0,0 +1,98 @@ +// Gmsh - Copyright (C) 1997-2016 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@onelab.info>. + +#ifndef _MESSAGE_BROWSER_H_ +#define _MESSAGE_BROWSER_H_ + +#include "FlGui.h" + +class messageBrowser : public Fl_Group{ + private: + Fl_Browser *_browser; + Fl_Group *_box; + Fl_Check_Button *_autoscroll; + Fl_Button *_clear, *_save; + Fl_Input *_search; + + public: + messageBrowser(int x, int y, int w, int h, const char *l=0) + : Fl_Group(x, y, w, h, l) + { + int bh = BH - 4; // button height + int wb = WB / 2; // border + int bb = BB - 3 * WB; + int sw = 3 * BB; // search field width + + _box = new Fl_Group(x, y, w, bh + 2 * wb); + _box->box(GMSH_SIMPLE_TOP_BOX); + + Fl_Group* o = new Fl_Group(x + wb, y + wb, sw, bh); + o->tooltip("Filter messages"); + o->box(FL_THIN_DOWN_BOX); + o->color(FL_BACKGROUND2_COLOR); + _search = new Fl_Input(x + wb + bh, y + wb + 2, sw - bh - 2, bh - 4, "@-1gmsh_search"); + _search->box(FL_FLAT_BOX); + _search->when(FL_WHEN_CHANGED); + _search->textsize(FL_NORMAL_SIZE - 1); + o->resizable(_search); + o->end(); + + _save = new Fl_Button(x + wb + sw + WB, y + wb, bb, bh, "Save"); + _save->labelsize(FL_NORMAL_SIZE - 1); + _save->box(FL_THIN_UP_BOX); + + _clear = new Fl_Button(x + sw + bb + 2 * WB, y + wb, bb, bh, "Clear"); + _clear->labelsize(FL_NORMAL_SIZE - 1); + _clear->box(FL_THIN_UP_BOX); + + _autoscroll = new Fl_Check_Button + (x + sw + 2 * bb + 3 * WB, y + wb, 2 * bb, bh, "Autoscroll messages"); + _autoscroll->labelsize(FL_NORMAL_SIZE - 1); + _autoscroll->type(FL_TOGGLE_BUTTON); + _autoscroll->value(1); + + _box->end(); + _box->resizable(0); + + _browser = new Fl_Browser(x, y + bh + 2 * wb, w, h - bh - 2 * wb, l); + _browser->box(GMSH_SIMPLE_TOP_BOX); + _browser->textfont(FL_SCREEN); + _browser->type(FL_MULTI_BROWSER); + _browser->scrollbar_size(std::max(10, FL_NORMAL_SIZE - 2)); // thinner scrollbars + _browser->end(); + end(); + resizable(_browser); + } + void box(Fl_Boxtype new_box) { _browser->box(new_box);} + void textfont(Fl_Font font) { _browser->textfont(font); } + void textsize(Fl_Fontsize newSize){ _browser->textsize(newSize); } + Fl_Fontsize textsize() const { return _browser->textsize(); } + void callback(Fl_Callback* cb, void* p) { _browser->callback(cb, p);} + void search_callback(Fl_Callback* cb, void* p) { _search->callback(cb, p);} + void autoscroll_callback(Fl_Callback* cb, void* p) { _autoscroll->callback(cb, p);} + void save_callback(Fl_Callback* cb, void* p) { _save->callback(cb, p);} + void clear_callback(Fl_Callback* cb, void* p) { _clear->callback(cb, p);} + void bottomline(int line) { _browser->bottomline(line); } + int size(){ return _browser->size(); } + void add(const char* newtext) + { + std::string search = _search->value(); + if(search.empty()){ + _browser->add(newtext); + } + else{ + std::transform(search.begin(), search.end(), search.begin(), ::tolower); + std::string tmp(newtext); + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + if(tmp.find(search) != std::string::npos) + _browser->add(newtext); + } + } + void clear(){ _browser->clear(); } + const char* text(int line) const { return _browser->text(line); } + int selected(int line) const { return _browser->selected(line); } +}; + +#endif diff --git a/Fltk/visibilityWindow.cpp b/Fltk/visibilityWindow.cpp index 334dad2a64..4095b501c6 100644 --- a/Fltk/visibilityWindow.cpp +++ b/Fltk/visibilityWindow.cpp @@ -24,6 +24,7 @@ typedef unsigned long intptr_t; #include "paletteWindow.h" #include "contextWindow.h" #include "graphicWindow.h" +#include "openglWindow.h" #include "GmshDefines.h" #include "GmshMessage.h" #include "GModel.h" -- GitLab