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