00001 #include <QtGui>
00002 #include <QMenu>
00003 #include <QMessageBox>
00004 #include <QProgressDialog>
00005 #include <QScrollBar>
00006
00007 #include "cetlib/filepath_maker.h"
00008 #include "fhiclcpp/make_ParameterSet.h"
00009 #include "fhiclcpp/ParameterSet.h"
00010
00011 #include "mfextensions/Binaries/mvdlg.hh"
00012
00013
00014 #if GCC_VERSION >= 701000 || defined(__clang__)
00015 #pragma GCC diagnostic push
00016 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
00017 #endif
00018
00019 #include "trace.h"
00020
00021 #if GCC_VERSION >= 701000 || defined(__clang__)
00022 #pragma GCC diagnostic pop
00023 #endif
00024
00025
00026 #include "mvdlg.hh"
00027
00028
00029
00030 static void
00031 process_fname(std::string& fname)
00032 {
00033 size_t sub_start = fname.find("${");
00034 size_t sub_end = fname.find("}");
00035
00036 const size_t npos = std::string::npos;
00037
00038 if ((sub_start == npos && sub_end != npos)
00039 || (sub_start != npos && sub_end == npos)
00040 || (sub_start > sub_end))
00041 {
00042 throw std::runtime_error("Unrecognized configuration file. Use default configuration instead.");
00043 }
00044
00045 if (sub_start == npos) return;
00046
00047 std::string env = std::string(getenv(fname.substr(sub_start + 2, sub_end - sub_start - 2).c_str()));
00048 fname.replace(sub_start, sub_end - sub_start + 1, env);
00049
00050
00051 }
00052
00053 static fhicl::ParameterSet
00054 readConf(std::string const& fname)
00055 {
00056 if (fname.empty()) return fhicl::ParameterSet();
00057
00058 std::string filename = fname;
00059 process_fname(filename);
00060
00061 std::string env("FHICL_FILE_PATH=");
00062
00063 if (filename[0] == '/')
00064 {
00065 env.append("/");
00066 }
00067 else
00068 {
00069 env.append(".");
00070 }
00071
00072 char* mfe_path = getenv("MFEXTENSIONS_DIR");
00073 if (mfe_path) env.append(":").append(mfe_path).append("/config");
00074
00075 putenv((char *)env.c_str());
00076
00077
00078
00079 cet::filepath_lookup policy("FHICL_FILE_PATH");
00080
00081
00082 fhicl::ParameterSet pset;
00083 fhicl::make_ParameterSet(filename, policy, pset);
00084
00085 return pset;
00086 }
00087
00088 msgViewerDlg::msgViewerDlg(std::string const& conf, QDialog* parent)
00089 : QDialog(parent)
00090 , updating(false)
00091 , paused(false)
00092 , shortMode_(false)
00093 , nMsgs(0)
00094 , nSupMsgs(0)
00095 , nThrMsgs(0)
00096 , nFilters(0)
00097 , simpleRender(true)
00098 , sevThresh(SINFO)
00099 , searchStr("")
00100 , msg_pool_()
00101 , host_msgs_()
00102 , cat_msgs_()
00103 , app_msgs_()
00104 , sup_menu(new QMenu(this))
00105 , thr_menu(new QMenu(this))
00106 , receivers_(readConf(conf).get<fhicl::ParameterSet>("receivers", fhicl::ParameterSet()))
00107 {
00108 setupUi(this);
00109
00110
00111 readSettings();
00112
00113
00114 fhicl::ParameterSet pset = readConf(conf);
00115
00116
00117 parseConf(pset);
00118
00119
00120 btnSuppression->setMenu(sup_menu);
00121 btnThrottling->setMenu(thr_menu);
00122
00123
00124 connect(btnPause, SIGNAL(clicked()), this, SLOT(pause()));
00125 connect(btnExit, SIGNAL(clicked()), this, SLOT(exit()));
00126 connect(btnClear, SIGNAL(clicked()), this, SLOT(clear()));
00127
00128 connect(btnRMode, SIGNAL(clicked()), this, SLOT(renderMode()));
00129 connect(btnDisplayMode, SIGNAL(clicked()), this, SLOT(shortMode()));
00130
00131 connect(btnSearch, SIGNAL(clicked()), this, SLOT(searchMsg()));
00132 connect(btnSearchClear,
00133 SIGNAL(clicked()), this, SLOT(searchClear()));
00134
00135 connect(btnFilter, SIGNAL(clicked()), this, SLOT(setFilter()));
00136
00137 connect(btnError, SIGNAL(clicked()), this, SLOT(setSevError()));
00138 connect(btnWarning, SIGNAL(clicked()), this, SLOT(setSevWarning()));
00139 connect(btnInfo, SIGNAL(clicked()), this, SLOT(setSevInfo()));
00140 connect(btnDebug, SIGNAL(clicked()), this, SLOT(setSevDebug()));
00141
00142 connect(sup_menu
00143 , SIGNAL(triggered(QAction*))
00144 , this
00145 , SLOT(setSuppression(QAction*)));
00146
00147 connect(thr_menu
00148 , SIGNAL(triggered(QAction*))
00149 , this
00150 , SLOT(setThrottling(QAction*)));
00151
00152 connect(vsSeverity
00153 , SIGNAL(valueChanged(int))
00154 , this
00155 , SLOT(changeSeverity(int)));
00156
00157 connect(&receivers_
00158 , SIGNAL(newMessage(qt_mf_msg const &))
00159 , this
00160 , SLOT(onNewMsg(qt_mf_msg const &)));
00161
00162 connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabWidgetCurrentChanged(int)));
00163 connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int)));
00164 MsgFilterDisplay allMessages;
00165 allMessages.txtDisplay = txtMessages;
00166 msgFilters_.push_back(allMessages);
00167
00168
00169 QTabBar *tabBar = tabWidget->findChild<QTabBar *>();
00170 tabBar->setTabButton(0, QTabBar::RightSide, 0);
00171 tabBar->setTabButton(0, QTabBar::LeftSide, 0);
00172
00173 if (simpleRender) btnRMode->setChecked(true);
00174 else btnRMode->setChecked(false);
00175
00176 btnRMode->setEnabled(false);
00177
00178 changeSeverity(sevThresh);
00179
00180 QTextDocument* doc = new QTextDocument(txtMessages);
00181 txtMessages->setDocument(doc);
00182
00183 receivers_.start();
00184 }
00185
00186 msgViewerDlg::~msgViewerDlg()
00187 {
00188 receivers_.stop();
00189 writeSettings();
00190 }
00191
00192 static void str_to_suppress(std::vector<std::string> const& vs, std::vector<suppress>& s, QMenu* menu)
00193 {
00194 QAction* act;
00195
00196 if (vs.empty())
00197 {
00198 act = menu->addAction("None");
00199 act->setEnabled(false);
00200 return;
00201 }
00202
00203 s.reserve(vs.size());
00204
00205 for (size_t i = 0; i < vs.size(); ++i)
00206 {
00207 s.push_back(suppress(vs[i]));
00208 act = menu->addAction(QString(vs[i].c_str()));
00209 act->setCheckable(true);
00210 act->setChecked(true);
00211 QVariant v = qVariantFromValue((void*)&s[i]);
00212 act->setData(v);
00213 }
00214 }
00215
00216 static void pset_to_throttle(std::vector<fhicl::ParameterSet> const& ps, std::vector<throttle>& t, QMenu* menu)
00217 {
00218 QAction* act;
00219
00220 if (ps.empty())
00221 {
00222 act = menu->addAction("None");
00223 act->setEnabled(false);
00224 return;
00225 }
00226
00227 t.reserve(ps.size());
00228
00229 for (size_t i = 0; i < ps.size(); ++i)
00230 {
00231 std::string name = ps[i].get<std::string>("name");
00232 t.push_back(throttle(name
00233 , ps[i].get<int>("limit", -1)
00234 , ps[i].get<long>("timespan", -1)));
00235 act = menu->addAction(QString(name.c_str()));
00236 act->setCheckable(true);
00237 act->setChecked(true);
00238 QVariant v = qVariantFromValue((void*)&t[i]);
00239 act->setData(v);
00240 }
00241 }
00242
00243 void msgViewerDlg::parseConf(fhicl::ParameterSet const& conf)
00244 {
00245 fhicl::ParameterSet nulp;
00246
00247
00248
00249 fhicl::ParameterSet sup = conf.get<fhicl::ParameterSet>("suppress", nulp);
00250
00251 auto sup_host = sup.get<std::vector<std::string>>("hosts", std::vector<std::string>());
00252 auto sup_app = sup.get<std::vector<std::string>>("applications", std::vector<std::string>());
00253 auto sup_cat = sup.get<std::vector<std::string>>("categories", std::vector<std::string>());
00254
00255 str_to_suppress(sup_host, e_sup_host, sup_menu);
00256 sup_menu->addSeparator();
00257
00258 str_to_suppress(sup_app, e_sup_app, sup_menu);
00259 sup_menu->addSeparator();
00260
00261 str_to_suppress(sup_cat, e_sup_cat, sup_menu);
00262
00263
00264 auto thr = conf.get<fhicl::ParameterSet>("throttle", nulp);
00265
00266 auto thr_host = thr.get<std::vector<fhicl::ParameterSet>>("hosts", std::vector<fhicl::ParameterSet>());
00267 auto thr_app = thr.get<std::vector<fhicl::ParameterSet>>("applications", std::vector<fhicl::ParameterSet>());
00268 auto thr_cat = thr.get<std::vector<fhicl::ParameterSet>>("categories", std::vector<fhicl::ParameterSet>());
00269
00270 pset_to_throttle(thr_host, e_thr_host, thr_menu);
00271 thr_menu->addSeparator();
00272
00273 pset_to_throttle(thr_app, e_thr_app, thr_menu);
00274 thr_menu->addSeparator();
00275
00276 pset_to_throttle(thr_cat, e_thr_cat, thr_menu);
00277
00278 auto lvl = conf.get<std::string>("threshold", "INFO");
00279 if (lvl == "DEBUG" || lvl == "debug" || lvl == "0") { sevThresh = SDEBUG; }
00280 if (lvl == "INFO" || lvl == "info" || lvl == "1") { sevThresh = SINFO; }
00281 if (lvl == "WARN" || lvl == "warn" || lvl == "2") { sevThresh = SWARNING; }
00282 if (lvl == "ERROR" || lvl == "error" || lvl == "3") { sevThresh = SERROR; }
00283 }
00284
00285 bool msgViewerDlg::msg_throttled(qt_mf_msg const& mfmsg)
00286 {
00287
00288
00289 ++nSupMsgs;
00290
00291 for (size_t i = 0; i < e_sup_host.size(); ++i)
00292 if (e_sup_host[i].match(mfmsg.host().toStdString()))
00293 return true;
00294
00295 for (size_t i = 0; i < e_sup_app.size(); ++i)
00296 if (e_sup_app[i].match(mfmsg.app().toStdString()))
00297 return true;
00298
00299 for (size_t i = 0; i < e_sup_cat.size(); ++i)
00300 if (e_sup_cat[i].match(mfmsg.cat().toStdString()))
00301 return true;
00302
00303 --nSupMsgs;
00304
00305
00306
00307 ++nThrMsgs;
00308
00309 for (size_t i = 0; i < e_thr_host.size(); ++i)
00310 if (e_thr_host[i].reach_limit(mfmsg.host().toStdString(), mfmsg.time()))
00311 return true;
00312
00313 for (size_t i = 0; i < e_thr_app.size(); ++i)
00314 if (e_thr_app[i].reach_limit(mfmsg.app().toStdString(), mfmsg.time()))
00315 return true;
00316
00317 for (size_t i = 0; i < e_thr_cat.size(); ++i)
00318 if (e_thr_cat[i].reach_limit(mfmsg.cat().toStdString(), mfmsg.time()))
00319 return true;
00320
00321 --nThrMsgs;
00322
00323 return false;
00324 }
00325
00326 void msgViewerDlg::writeSettings()
00327 {
00328 QSettings settings("ARTDAQ", "MsgViewer");
00329
00330 settings.beginGroup("MainWindow");
00331 settings.setValue("size", size());
00332 settings.setValue("pos", pos());
00333 settings.endGroup();
00334 }
00335
00336 void msgViewerDlg::readSettings()
00337 {
00338 QSettings settings("ARTDAQ", "MsgViewer");
00339
00340 settings.beginGroup("MainWindow");
00341 QPoint pos = settings.value("pos", QPoint(100, 100)).toPoint();
00342 QSize size = settings.value("size", QSize(660, 760)).toSize();
00343 resize(size);
00344 move(pos);
00345 settings.endGroup();
00346 }
00347
00348 void msgViewerDlg::onNewMsg(qt_mf_msg const& mfmsg)
00349 {
00350
00351
00352
00353
00354 ++nMsgs;
00355 lcdMsgs->display(nMsgs);
00356
00357
00358 if (msg_throttled(mfmsg))
00359 {
00360 lcdSuppressionCount->display(nSupMsgs);
00361 lcdThrottlingCount->display(nThrMsgs);
00362 return;
00363 }
00364
00365
00366 msg_pool_.emplace_back(mfmsg);
00367 msgs_t::iterator it = --msg_pool_.end();
00368
00369
00370 unsigned int flag = update_index(it);
00371
00372
00373 if (flag & LIST_APP) updateList<msg_iters_map_t>(lwApplication, app_msgs_);
00374 if (flag & LIST_CAT) updateList<msg_iters_map_t>(lwCategory, cat_msgs_);
00375 if (flag & LIST_HOST) updateList<msg_iters_map_t>(lwHost, host_msgs_);
00376
00377 for (size_t d = 0; d < msgFilters_.size(); ++d)
00378 {
00379 bool hostMatch = msgFilters_[d].hostFilter.contains(it->host(), Qt::CaseInsensitive) || msgFilters_[d].hostFilter.size() == 0;
00380 bool appMatch = msgFilters_[d].appFilter.contains(it->app(), Qt::CaseInsensitive) || msgFilters_[d].appFilter.size() == 0;
00381 bool catMatch = msgFilters_[d].catFilter.contains(it->cat(), Qt::CaseInsensitive) || msgFilters_[d].catFilter.size() == 0;
00382
00383
00384 if (hostMatch && appMatch && catMatch)
00385 {
00386 msgFilters_[d].msgs.push_back(it);
00387 displayMsg(it, d);
00388 }
00389 }
00390 }
00391
00392 unsigned int msgViewerDlg::update_index(msgs_t::iterator it)
00393 {
00394 QString const& app = it->app();
00395 QString const& cat = it->cat();
00396 QString const& host = it->host();
00397
00398 unsigned int update = 0x0;
00399
00400 if (cat_msgs_.find(cat) == cat_msgs_.end()) update |= LIST_CAT;
00401 if (host_msgs_.find(host) == host_msgs_.end()) update |= LIST_HOST;
00402 if (app_msgs_.find(app) == app_msgs_.end()) update |= LIST_APP;
00403
00404 cat_msgs_[cat].push_back(it);
00405 host_msgs_[host].push_back(it);
00406 app_msgs_[app].push_back(it);
00407
00408 return update;
00409 }
00410
00411
00412 void msgViewerDlg::displayMsg(msgs_t::const_iterator it, int display)
00413 {
00414 if (it->sev() < sevThresh) return;
00415
00416 msgFilters_[display].nDisplayMsgs++;
00417 if (display == tabWidget->currentIndex())
00418 {
00419 lcdDisplayedMsgs->display(msgFilters_[display].nDisplayMsgs);
00420 }
00421
00422 auto txt = it->text(shortMode_);
00423 UpdateTextAreaDisplay(txt, msgFilters_[display].txtDisplay);
00424 }
00425
00426 void msgViewerDlg::displayMsg(int display)
00427 {
00428 int n = 0;
00429 msgFilters_[display].txtDisplay->clear();
00430 msgFilters_[display].nDisplayMsgs = 0;
00431
00432 msg_iters_t::const_iterator it;
00433
00434 n = msgFilters_[display].msgs.size();
00435 it = msgFilters_[display].msgs.begin();
00436 QProgressDialog progress("Fetching data...", "Cancel"
00437 , 0, n / 1000, this);
00438
00439 progress.setWindowModality(Qt::WindowModal);
00440 progress.setMinimumDuration(2000);
00441
00442 QString txt;
00443 int i = 0, prog = 0;
00444
00445 updating = true;
00446
00447 for (; it != msgFilters_[display].msgs.end(); ++it, ++i)
00448 {
00449 if (it->get()->sev() >= sevThresh)
00450 {
00451 txt += it->get()->text(shortMode_);
00452 ++msgFilters_[display].nDisplayMsgs;
00453 }
00454
00455 if (i == 1000)
00456 {
00457 i = 0;
00458 ++prog;
00459 progress.setValue(prog);
00460
00461 UpdateTextAreaDisplay(txt, msgFilters_[display].txtDisplay);
00462 txt.clear();
00463 }
00464
00465 if (progress.wasCanceled())
00466 break;
00467 }
00468
00469 if (display == tabWidget->currentIndex())
00470 {
00471 lcdDisplayedMsgs->display(msgFilters_[display].nDisplayMsgs);
00472 }
00473
00474 UpdateTextAreaDisplay(txt, msgFilters_[display].txtDisplay);
00475
00476 updating = false;
00477 }
00478
00479
00480 void msgViewerDlg::UpdateTextAreaDisplay(QString text, QTextEdit* widget)
00481 {
00482 const QTextCursor old_cursor = widget->textCursor();
00483 const int old_scrollbar_value = widget->verticalScrollBar()->value();
00484 const bool is_scrolled_down = old_scrollbar_value >= widget->verticalScrollBar()->maximum() * 0.95;
00485
00486
00487 widget->append(text);
00488
00489 if (old_cursor.hasSelection() || !is_scrolled_down)
00490 {
00491
00492 widget->setTextCursor(old_cursor);
00493 widget->verticalScrollBar()->setValue(old_scrollbar_value);
00494 }
00495 else
00496 {
00497
00498 widget->moveCursor(QTextCursor::End);
00499 widget->verticalScrollBar()->setValue(widget->verticalScrollBar()->maximum());
00500 widget->horizontalScrollBar()->setValue(0);
00501 }
00502 }
00503
00504 void msgViewerDlg::updateDisplays()
00505 {
00506 for (size_t ii = 0; ii < msgFilters_.size(); ++ii)
00507 {
00508 displayMsg(ii);
00509 }
00510 }
00511
00512 template <typename M>
00513 bool msgViewerDlg::updateList(QListWidget* lw, M const& map)
00514 {
00515 bool nonSelectedBefore = (lw->currentRow() == -1);
00516 bool nonSelectedAfter = true;
00517
00518 QString item = nonSelectedBefore ? "" : lw->currentItem()->text();
00519
00520 lw->clear();
00521 int row = 0;
00522 typename M::const_iterator it = map.begin();
00523
00524 while (it != map.end())
00525 {
00526 lw->addItem(it->first);
00527 if (!nonSelectedBefore && nonSelectedAfter)
00528 {
00529 if (item == it->first)
00530 {
00531 lw->setCurrentRow(row);
00532 nonSelectedAfter = false;
00533 }
00534 }
00535 ++row;
00536 ++it;
00537 }
00538
00539 if (!nonSelectedBefore && nonSelectedAfter) return true;
00540
00541 return false;
00542 }
00543
00544 msg_iters_t msgViewerDlg::list_intersect(msg_iters_t const& l1, msg_iters_t const& l2)
00545 {
00546 msg_iters_t output;
00547 msg_iters_t::const_iterator it1 = l1.begin();
00548 msg_iters_t::const_iterator it2 = l2.begin();
00549
00550 while (it1 != l1.end() && it2 != l2.end())
00551 {
00552 if (*it1 < *it2) { ++it1; }
00553 else if (*it2 < *it1) { ++it2; }
00554 else
00555 {
00556 output.push_back(*it1);
00557 ++it1;
00558 ++it2;
00559 }
00560 }
00561
00562 TLOG(10) << "list_intersect: output list has " << output.size() << " entries";
00563 return output;
00564 }
00565
00566 std::string sev_to_string(sev_code_t s)
00567 {
00568 switch (s)
00569 {
00570 case SDEBUG:
00571 return "DEBUG";
00572 case SINFO:
00573 return "INFO";
00574 case SWARNING:
00575 return "WARNING";
00576 case SERROR:
00577 return "ERROR";
00578 }
00579 return "UNKNOWN";
00580 }
00581
00582 void msgViewerDlg::setFilter()
00583 {
00584 auto hostFilter = toQStringList(lwHost->selectedItems());
00585 auto appFilter = toQStringList(lwApplication->selectedItems());
00586 auto catFilter = toQStringList(lwCategory->selectedItems());
00587
00588 lwHost->setCurrentRow(-1, QItemSelectionModel::Clear);
00589 lwApplication->setCurrentRow(-1, QItemSelectionModel::Clear);
00590 lwCategory->setCurrentRow(-1, QItemSelectionModel::Clear);
00591
00592 if (hostFilter.isEmpty()
00593 && appFilter.isEmpty()
00594 && catFilter.isEmpty())
00595 {
00596 return;
00597 }
00598
00599 msg_iters_t result;
00600 QString catFilterExpression = "";
00601 QString hostFilterExpression = "";
00602 QString appFilterExpression = "";
00603 bool first = true;
00604
00605 for (auto app = 0; app < appFilter.size(); ++app)
00606 {
00607 msg_iters_map_t::const_iterator it = app_msgs_.find(appFilter[app]);
00608 appFilterExpression += QString(first ? "" : " || ") + appFilter[app];
00609 first = false;
00610 if (it != app_msgs_.end())
00611 {
00612 msg_iters_t temp(it->second);
00613 TLOG(10) << "setFilter: app " << appFilter[app].toStdString() << " has " << temp.size() << " messages";
00614 result.merge(temp);
00615 }
00616 }
00617 TLOG(10) << "setFilter: result contains %zu messages", result.size();
00618
00619 first = true;
00620 if (!hostFilter.isEmpty())
00621 {
00622 msg_iters_t hostResult;
00623 for (auto host = 0; host < hostFilter.size(); ++host)
00624 {
00625 hostFilterExpression += QString(first ? "" : " || ") + hostFilter[host];
00626 first = false;
00627 msg_iters_map_t::const_iterator it = host_msgs_.find(hostFilter[host]);
00628 if (it != host_msgs_.end())
00629 {
00630 msg_iters_t temp(it->second);
00631 TLOG(10) << "setFilter: host " << hostFilter[host].toStdString() << " has " << temp.size() << " messages";
00632 hostResult.merge(temp);
00633 }
00634 }
00635 if (result.empty()) { result = hostResult; }
00636 else { result = list_intersect(result, hostResult); }
00637 TLOG(10) << "setFilter: result contains " << result.size() << " messages";
00638 }
00639
00640 first = true;
00641 if (!catFilter.isEmpty())
00642 {
00643 msg_iters_t catResult;
00644 for (auto cat = 0; cat < catFilter.size(); ++cat)
00645 {
00646 catFilterExpression += QString(first ? "" : " || ") + catFilter[cat];
00647 first = false;
00648 msg_iters_map_t::const_iterator it = cat_msgs_.find(catFilter[cat]);
00649 if (it != cat_msgs_.end())
00650 {
00651 msg_iters_t temp(it->second);
00652 TLOG(10) << "setFilter: cat " << catFilter[cat].toStdString() << " has " << temp.size() << " messages";
00653 catResult.merge(temp);
00654 }
00655 }
00656 if (result.empty()) { result = catResult; }
00657 else { result = list_intersect(result, catResult); }
00658 TLOG(10) << "setFilter: result contains " << result.size() << " messages";
00659 }
00660
00661
00662 auto nFilterExpressions = (appFilterExpression != "" ? 1 : 0) + (hostFilterExpression != "" ? 1 : 0) + (catFilterExpression != "" ? 1 : 0);
00663 QString filterExpression = "";
00664 if (nFilterExpressions == 1)
00665 {
00666 filterExpression = catFilterExpression + hostFilterExpression + appFilterExpression;
00667 }
00668 else
00669 {
00670 filterExpression = "(" + (catFilterExpression != "" ? catFilterExpression + ") && (" : "")
00671 + hostFilterExpression
00672 + (hostFilterExpression != "" && appFilterExpression != "" ? ") && (" : "")
00673 + appFilterExpression + ")";
00674 }
00675
00676
00677
00678 auto newTabTitle = QString("Filter ") + QString::number(++nFilters);
00679 QWidget* newTab = new QWidget();
00680
00681 QTextEdit* txtDisplay = new QTextEdit(newTab);
00682 QTextDocument* doc = new QTextDocument(txtDisplay);
00683 txtDisplay->setDocument(doc);
00684
00685 QVBoxLayout* layout = new QVBoxLayout();
00686 layout->addWidget(txtDisplay);
00687 layout->setContentsMargins(0, 0, 0, 0);
00688 newTab->setLayout(layout);
00689
00690 MsgFilterDisplay filteredMessages;
00691 filteredMessages.msgs = result;
00692 filteredMessages.hostFilter = hostFilter;
00693 filteredMessages.appFilter = appFilter;
00694 filteredMessages.catFilter = catFilter;
00695 filteredMessages.txtDisplay = txtDisplay;
00696 filteredMessages.nDisplayMsgs = result.size();
00697 msgFilters_.push_back(filteredMessages);
00698
00699 tabWidget->addTab(newTab, newTabTitle);
00700 tabWidget->setTabToolTip(tabWidget->count() - 1, filterExpression);
00701 tabWidget->setCurrentIndex(tabWidget->count() - 1);
00702
00703 displayMsg(msgFilters_.size() - 1);
00704 }
00705
00706 void msgViewerDlg::pause()
00707 {
00708 if (!paused)
00709 {
00710 paused = true;
00711 btnPause->setText("Resume");
00712
00713 }
00714 else
00715 {
00716 paused = false;
00717 btnPause->setText("Pause");
00718 }
00719 }
00720
00721 void msgViewerDlg::exit()
00722 {
00723 close();
00724 }
00725
00726 void msgViewerDlg::clear()
00727 {
00728 int ret = QMessageBox::question(this, tr("Message Viewer"), tr("Are you sure you want to clear all received messages?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
00729 switch (ret)
00730 {
00731 case QMessageBox::Yes:
00732 nMsgs = 0;
00733 nSupMsgs = 0;
00734 nThrMsgs = 0;
00735 msg_pool_.clear();
00736 host_msgs_.clear();
00737 cat_msgs_.clear();
00738 app_msgs_.clear();
00739 updateList<msg_iters_map_t>(lwApplication, app_msgs_);
00740 updateList<msg_iters_map_t>(lwCategory, cat_msgs_);
00741 updateList<msg_iters_map_t>(lwHost, host_msgs_);
00742 for (auto& display : msgFilters_)
00743 {
00744 display.txtDisplay->clear();
00745 display.msgs.clear();
00746 display.nDisplayMsgs = 0;
00747 }
00748
00749 lcdMsgs->display(nMsgs);
00750 lcdDisplayedMsgs->display(0);
00751 break;
00752 case QMessageBox::No:
00753 default:
00754 break;
00755 }
00756 }
00757
00758 void msgViewerDlg::shortMode()
00759 {
00760 if (!shortMode_)
00761 {
00762 shortMode_ = true;
00763 btnDisplayMode->setText("Long View");
00764 }
00765 else
00766 {
00767 shortMode_ = false;
00768 btnDisplayMode->setText("Compact View");
00769 }
00770 updateDisplays();
00771 }
00772
00773 void msgViewerDlg::changeSeverity(int sev)
00774 {
00775 switch (sev)
00776 {
00777 case SERROR:
00778 setSevError();
00779 break;
00780
00781 case SWARNING:
00782 setSevWarning();
00783 break;
00784
00785 case SINFO:
00786 setSevInfo();
00787 break;
00788
00789 default: setSevDebug();
00790 }
00791
00792 updateDisplays();
00793 }
00794
00795 void msgViewerDlg::setSevError()
00796 {
00797 sevThresh = SERROR;
00798 btnError->setChecked(true);
00799 btnWarning->setChecked(false);
00800 btnInfo->setChecked(false);
00801 btnDebug->setChecked(false);
00802 vsSeverity->setValue(sevThresh);
00803 }
00804
00805 void msgViewerDlg::setSevWarning()
00806 {
00807 sevThresh = SWARNING;
00808 btnError->setChecked(false);
00809 btnWarning->setChecked(true);
00810 btnInfo->setChecked(false);
00811 btnDebug->setChecked(false);
00812 vsSeverity->setValue(sevThresh);
00813 }
00814
00815 void msgViewerDlg::setSevInfo()
00816 {
00817 sevThresh = SINFO;
00818 btnError->setChecked(false);
00819 btnWarning->setChecked(false);
00820 btnInfo->setChecked(true);
00821 btnDebug->setChecked(false);
00822 vsSeverity->setValue(sevThresh);
00823 }
00824
00825 void msgViewerDlg::setSevDebug()
00826 {
00827 sevThresh = SDEBUG;
00828 btnError->setChecked(false);
00829 btnWarning->setChecked(false);
00830 btnInfo->setChecked(false);
00831 btnDebug->setChecked(true);
00832 vsSeverity->setValue(sevThresh);
00833 }
00834
00835 void msgViewerDlg::renderMode()
00836 {
00837 simpleRender = !simpleRender;
00838
00839 if (simpleRender)
00840 {
00841 btnRMode->setChecked(true);
00842 for (auto display : msgFilters_)
00843 {
00844 display.txtDisplay->setPlainText(display.txtDisplay->toPlainText());
00845 }
00846 }
00847 else
00848 {
00849 btnRMode->setChecked(false);
00850 updateDisplays();
00851 }
00852 }
00853
00854 void msgViewerDlg::searchMsg()
00855 {
00856 QString search = editSearch->text();
00857
00858 if (search.isEmpty())
00859 return;
00860
00861 auto display = tabWidget->currentIndex();
00862 if (search != searchStr)
00863 {
00864 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::Start);
00865 if (!msgFilters_[display].txtDisplay->find(search))
00866 {
00867 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::End);
00868 searchStr = "";
00869 }
00870 else
00871 searchStr = search;
00872 }
00873 else
00874 {
00875 if (!msgFilters_[display].txtDisplay->find(search))
00876 {
00877 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::Start);
00878 if (!msgFilters_[display].txtDisplay->find(search))
00879 {
00880 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::End);
00881 searchStr = "";
00882 }
00883 }
00884 }
00885 }
00886
00887 void msgViewerDlg::searchClear()
00888 {
00889 auto display = tabWidget->currentIndex();
00890 editSearch->setText("");
00891 searchStr = "";
00892 msgFilters_[display].txtDisplay->find("");
00893 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::End);
00894 }
00895
00896 void msgViewerDlg::setSuppression(QAction* act)
00897 {
00898 bool status = act->isChecked();
00899 suppress* sup = (suppress *)act->data().value<void*>();
00900 sup->use(status);
00901 }
00902
00903 void msgViewerDlg::setThrottling(QAction* act)
00904 {
00905 bool status = act->isChecked();
00906 throttle* thr = (throttle *)act->data().value<void*>();
00907 thr->use(status);
00908 }
00909
00910 void msgViewerDlg::tabWidgetCurrentChanged(int newTab)
00911 {
00912 lcdDisplayedMsgs->display(msgFilters_[newTab].nDisplayMsgs);
00913
00914 lwHost->setCurrentRow(-1, QItemSelectionModel::Clear);
00915 lwApplication->setCurrentRow(-1, QItemSelectionModel::Clear);
00916 lwCategory->setCurrentRow(-1, QItemSelectionModel::Clear);
00917
00918 for (auto host : msgFilters_[newTab].hostFilter)
00919 {
00920 auto items = lwHost->findItems(host, Qt::MatchExactly);
00921 if (items.size() > 0)
00922 {
00923 items[0]->setSelected(true);
00924 }
00925 }
00926 for (auto app : msgFilters_[newTab].appFilter)
00927 {
00928 auto items = lwApplication->findItems(app, Qt::MatchExactly);
00929 if (items.size() > 0)
00930 {
00931 items[0]->setSelected(true);
00932 }
00933 }
00934 for (auto cat : msgFilters_[newTab].catFilter)
00935 {
00936 auto items = lwCategory->findItems(cat, Qt::MatchExactly);
00937 if (items.size() > 0)
00938 {
00939 items[0]->setSelected(true);
00940 }
00941 }
00942 }
00943
00944 void msgViewerDlg::tabCloseRequested(int tabIndex)
00945 {
00946 if (tabIndex == 0 || static_cast<size_t>(tabIndex) >= msgFilters_.size()) return;
00947
00948 auto widget = tabWidget->widget(tabIndex);
00949 tabWidget->removeTab(tabIndex);
00950 delete widget;
00951
00952 msgFilters_.erase(msgFilters_.begin() + tabIndex);
00953 }
00954
00955 void msgViewerDlg::closeEvent(QCloseEvent* event)
00956 {
00957 event->accept();
00958 }
00959
00960 QStringList msgViewerDlg::toQStringList(QList<QListWidgetItem *> in)
00961 {
00962 QStringList out;
00963
00964 for (auto i = 0; i < in.size(); ++i)
00965 {
00966 out << in[i]->text();
00967 }
00968
00969 return out;
00970 }