3 #include <QProgressDialog>
7 #include "cetlib/filepath_maker.h"
8 #include "fhiclcpp/ParameterSet.h"
9 #include "fhiclcpp/make_ParameterSet.h"
11 #include "mfextensions/Binaries/mvdlg.hh"
13 #if GCC_VERSION >= 701000 || defined(__clang__)
14 #pragma GCC diagnostic push
15 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
18 #define TRACE_NAME "MessageViewer"
21 #if GCC_VERSION >= 701000 || defined(__clang__)
22 #pragma GCC diagnostic pop
29 static void process_fname(std::string& fname)
31 size_t sub_start = fname.find(
"${");
32 size_t sub_end = fname.find(
"}");
34 const size_t npos = std::string::npos;
36 if ((sub_start == npos && sub_end != npos) || (sub_start != npos && sub_end == npos) || (sub_start > sub_end))
38 throw std::runtime_error(
"Unrecognized configuration file. Use default configuration instead.");
41 if (sub_start == npos)
return;
43 std::string env = std::string(getenv(fname.substr(sub_start + 2, sub_end - sub_start - 2).c_str()));
44 fname.replace(sub_start, sub_end - sub_start + 1, env);
49 static fhicl::ParameterSet readConf(std::string
const& fname)
51 if (fname.empty())
return fhicl::ParameterSet();
53 std::string filename = fname;
54 process_fname(filename);
56 std::string env(
"FHICL_FILE_PATH=");
58 if (filename[0] ==
'/')
67 char* mfe_path = getenv(
"MFEXTENSIONS_DIR");
68 if (mfe_path) env.append(
":").append(mfe_path).append(
"/config");
76 cet::filepath_lookup policy(
"FHICL_FILE_PATH");
79 fhicl::ParameterSet pset;
80 fhicl::make_ParameterSet(filename, policy, pset);
86 : QDialog(parent), paused(false), shortMode_(false), nMsgs(0), nSupMsgs(0), nThrMsgs(0), nFilters(0), nDeleted(0), simpleRender(true), searchStr(
""), msg_pool_(), host_msgs_(), cat_msgs_(), app_msgs_(), sup_menu(new QMenu(this)), thr_menu(new QMenu(this)), receivers_(readConf(conf).get<fhicl::ParameterSet>(
"receivers", fhicl::ParameterSet()))
94 fhicl::ParameterSet pset = readConf(conf);
100 btnSuppression->setMenu(sup_menu);
101 btnThrottling->setMenu(thr_menu);
104 connect(btnPause, SIGNAL(clicked()),
this, SLOT(
pause()));
105 connect(btnScrollToBottom, SIGNAL(clicked()),
this, SLOT(scrollToBottom()));
106 connect(btnExit, SIGNAL(clicked()),
this, SLOT(
exit()));
107 connect(btnClear, SIGNAL(clicked()),
this, SLOT(
clear()));
109 connect(btnRMode, SIGNAL(clicked()),
this, SLOT(renderMode()));
110 connect(btnDisplayMode, SIGNAL(clicked()),
this, SLOT(
shortMode()));
112 connect(btnSearch, SIGNAL(clicked()),
this, SLOT(searchMsg()));
113 connect(btnSearchClear, SIGNAL(clicked()),
this, SLOT(searchClear()));
115 connect(btnFilter, SIGNAL(clicked()),
this, SLOT(setFilter()));
117 connect(btnError, SIGNAL(clicked()),
this, SLOT(setSevError()));
118 connect(btnWarning, SIGNAL(clicked()),
this, SLOT(setSevWarning()));
119 connect(btnInfo, SIGNAL(clicked()),
this, SLOT(setSevInfo()));
120 connect(btnDebug, SIGNAL(clicked()),
this, SLOT(setSevDebug()));
122 connect(sup_menu, SIGNAL(triggered(QAction*)),
this, SLOT(setSuppression(QAction*)));
124 connect(thr_menu, SIGNAL(triggered(QAction*)),
this, SLOT(setThrottling(QAction*)));
126 connect(vsSeverity, SIGNAL(valueChanged(
int)),
this, SLOT(
changeSeverity(
int)));
128 connect(&receivers_, SIGNAL(newMessage(msg_ptr_t)),
this, SLOT(onNewMsg(msg_ptr_t)));
130 connect(tabWidget, SIGNAL(currentChanged(
int)),
this, SLOT(tabWidgetCurrentChanged(
int)));
131 connect(tabWidget, SIGNAL(tabCloseRequested(
int)),
this, SLOT(tabCloseRequested(
int)));
132 MsgFilterDisplay allMessages;
133 allMessages.txtDisplay = txtMessages;
134 allMessages.nDisplayMsgs = 0;
135 allMessages.filterExpression =
"";
136 allMessages.nDisplayedDeletedMsgs = 0;
137 allMessages.sevThresh = SINFO;
138 msgFilters_.push_back(allMessages);
141 auto tabBar = tabWidget->findChild<QTabBar*>();
142 tabBar->setTabButton(0, QTabBar::RightSide,
nullptr);
143 tabBar->setTabButton(0, QTabBar::LeftSide,
nullptr);
146 btnRMode->setChecked(
true);
148 btnRMode->setChecked(
false);
150 btnRMode->setEnabled(
false);
154 auto doc =
new QTextDocument(txtMessages);
155 txtMessages->setDocument(doc);
160 msgViewerDlg::~msgViewerDlg()
166 static void str_to_suppress(std::vector<std::string>
const& vs, std::vector<suppress>& s, QMenu* menu)
172 act = menu->addAction(
"None");
173 act->setEnabled(
false);
177 s.reserve(vs.size());
179 for (
size_t i = 0; i < vs.size(); ++i)
181 s.emplace_back(vs[i]);
182 act = menu->addAction(QString(vs[i].c_str()));
183 act->setCheckable(
true);
184 act->setChecked(
true);
185 QVariant v = qVariantFromValue(static_cast<void*>(&s[i]));
190 static void pset_to_throttle(std::vector<fhicl::ParameterSet>
const& ps, std::vector<throttle>& t, QMenu* menu)
196 act = menu->addAction(
"None");
197 act->setEnabled(
false);
201 t.reserve(ps.size());
203 for (
size_t i = 0; i < ps.size(); ++i)
205 auto name = ps[i].get<std::string>(
"name");
206 t.emplace_back(name, ps[i].get<int>(
"limit", -1), ps[i].get<int64_t>(
"timespan", -1));
207 act = menu->addAction(QString(name.c_str()));
208 act->setCheckable(
true);
209 act->setChecked(
true);
210 QVariant v = qVariantFromValue(static_cast<void*>(&t[i]));
215 void msgViewerDlg::parseConf(fhicl::ParameterSet
const& conf)
217 fhicl::ParameterSet nulp;
221 auto sup = conf.get<fhicl::ParameterSet>(
"suppress", nulp);
223 auto sup_host = sup.get<std::vector<std::string>>(
"hosts", std::vector<std::string>());
224 auto sup_app = sup.get<std::vector<std::string>>(
"applications", std::vector<std::string>());
225 auto sup_cat = sup.get<std::vector<std::string>>(
"categories", std::vector<std::string>());
227 str_to_suppress(sup_host, e_sup_host, sup_menu);
228 sup_menu->addSeparator();
230 str_to_suppress(sup_app, e_sup_app, sup_menu);
231 sup_menu->addSeparator();
233 str_to_suppress(sup_cat, e_sup_cat, sup_menu);
236 auto thr = conf.get<fhicl::ParameterSet>(
"throttle", nulp);
238 auto thr_host = thr.get<std::vector<fhicl::ParameterSet>>(
"hosts", std::vector<fhicl::ParameterSet>());
239 auto thr_app = thr.get<std::vector<fhicl::ParameterSet>>(
"applications", std::vector<fhicl::ParameterSet>());
240 auto thr_cat = thr.get<std::vector<fhicl::ParameterSet>>(
"categories", std::vector<fhicl::ParameterSet>());
242 pset_to_throttle(thr_host, e_thr_host, thr_menu);
243 thr_menu->addSeparator();
245 pset_to_throttle(thr_app, e_thr_app, thr_menu);
246 thr_menu->addSeparator();
248 pset_to_throttle(thr_cat, e_thr_cat, thr_menu);
250 maxMsgs = conf.get<
size_t>(
"max_message_buffer_size", 100000);
251 maxDeletedMsgs = conf.get<
size_t>(
"max_displayed_deleted_messages", 100000);
254 bool msgViewerDlg::msg_throttled(msg_ptr_t
const& msg)
260 for (
size_t i = 0; i < e_sup_host.size(); ++i)
261 if (e_sup_host[i].match(msg->host().toStdString()))
return true;
263 for (
size_t i = 0; i < e_sup_app.size(); ++i)
264 if (e_sup_app[i].match(msg->app().toStdString()))
return true;
266 for (
size_t i = 0; i < e_sup_cat.size(); ++i)
267 if (e_sup_cat[i].match(msg->cat().toStdString()))
return true;
275 for (
size_t i = 0; i < e_thr_host.size(); ++i)
276 if (e_thr_host[i].reach_limit(msg->host().toStdString(), msg->time()))
return true;
278 for (
size_t i = 0; i < e_thr_app.size(); ++i)
279 if (e_thr_app[i].reach_limit(msg->app().toStdString(), msg->time()))
return true;
281 for (
size_t i = 0; i < e_thr_cat.size(); ++i)
282 if (e_thr_cat[i].reach_limit(msg->cat().toStdString(), msg->time()))
return true;
289 void msgViewerDlg::writeSettings()
291 QSettings settings(
"ARTDAQ",
"MsgViewer");
293 settings.beginGroup(
"MainWindow");
294 settings.setValue(
"size", size());
295 settings.setValue(
"pos", pos());
299 void msgViewerDlg::readSettings()
301 QSettings settings(
"ARTDAQ",
"MsgViewer");
303 settings.beginGroup(
"MainWindow");
304 QPoint pos = settings.value(
"pos", QPoint(100, 100)).toPoint();
305 QSize size = settings.value(
"size", QSize(660, 760)).toSize();
311 void msgViewerDlg::onNewMsg(msg_ptr_t
const& msg)
318 lcdMsgs->display(nMsgs);
321 if (msg_throttled(msg))
323 lcdSuppressionCount->display(nSupMsgs);
324 lcdThrottlingCount->display(nThrMsgs);
330 std::lock_guard<std::mutex> lk(msg_pool_mutex_);
331 msg_pool_.emplace_back(msg);
339 for (
size_t d = 0; d < msgFilters_.size(); ++d)
342 msgFilters_[d].hostFilter.contains(msg->host(), Qt::CaseInsensitive) || msgFilters_[d].hostFilter.empty();
344 msgFilters_[d].appFilter.contains(msg->app(), Qt::CaseInsensitive) || msgFilters_[d].appFilter.empty();
346 msgFilters_[d].catFilter.contains(msg->cat(), Qt::CaseInsensitive) || msgFilters_[d].catFilter.empty();
349 if (hostMatch && appMatch && catMatch)
352 std::lock_guard<std::mutex> lk(filter_mutex_);
353 msgFilters_[d].msgs.push_back(msg);
355 if ((
int)d == tabWidget->currentIndex())
361 void msgViewerDlg::trim_msg_pool()
363 bool host_list_update =
false;
364 bool app_list_update =
false;
365 bool cat_list_update =
false;
367 std::lock_guard<std::mutex> lk(msg_pool_mutex_);
368 while (maxMsgs > 0 && msg_pool_.size() > maxMsgs)
370 QString
const& app = msg_pool_.front()->app();
371 QString
const& cat = msg_pool_.front()->cat();
372 QString
const& host = msg_pool_.front()->host();
376 auto catIter = std::find(cat_msgs_[cat].begin(), cat_msgs_[cat].end(), msg_pool_.front());
377 auto hostIter = std::find(host_msgs_[host].begin(), host_msgs_[host].end(), msg_pool_.front());
378 auto appIter = std::find(app_msgs_[app].begin(), app_msgs_[app].end(), msg_pool_.front());
379 if (catIter != cat_msgs_[cat].end()) cat_msgs_[cat].erase(catIter);
380 if (hostIter != host_msgs_[host].end()) host_msgs_[host].erase(hostIter);
381 if (appIter != app_msgs_[app].end()) app_msgs_[app].erase(appIter);
383 if (app_msgs_[app].empty())
385 app_msgs_.erase(app);
386 app_list_update =
true;
388 if (cat_msgs_[cat].empty())
390 cat_msgs_.erase(cat);
391 cat_list_update =
true;
393 if (host_msgs_[host].empty())
395 host_msgs_.erase(host);
396 host_list_update =
true;
401 msg_pool_.erase(msg_pool_.begin());
406 std::lock_guard<std::mutex> lk(msg_classification_mutex_);
407 if (host_list_update)
408 updateList(lwHost, host_msgs_);
410 updateList(lwApplication, app_msgs_);
412 updateList(lwCategory, cat_msgs_);
415 for (
size_t d = 0; d < msgFilters_.size(); ++d)
418 std::lock_guard<std::mutex> lk(filter_mutex_);
419 while (msgFilters_[d].msgs.size() > maxMsgs)
421 if ((*msgFilters_[d].msgs.begin())->sev() >= msgFilters_[d].sevThresh)
422 msgFilters_[d].nDisplayedDeletedMsgs++;
423 msgFilters_[d].msgs.erase(msgFilters_[d].msgs.begin());
427 if ((
int)d == tabWidget->currentIndex())
429 if (maxDeletedMsgs > 0 && msgFilters_[d].nDisplayedDeletedMsgs > static_cast<int>(maxDeletedMsgs))
433 lcdDisplayedDeleted->display(msgFilters_[d].nDisplayedDeletedMsgs);
437 lcdDeletedCount->display(nDeleted);
440 void msgViewerDlg::update_index(msg_ptr_t
const& it)
442 std::lock_guard<std::mutex> lk(msg_classification_mutex_);
443 QString
const& app = it->app();
444 QString
const& cat = it->cat();
445 QString
const& host = it->host();
447 if (cat_msgs_.find(cat) == cat_msgs_.end())
449 cat_msgs_[cat].push_back(it);
450 updateList(lwCategory, cat_msgs_);
454 cat_msgs_[cat].push_back(it);
457 if (host_msgs_.find(host) == host_msgs_.end())
459 host_msgs_[host].push_back(it);
460 updateList(lwHost, host_msgs_);
464 host_msgs_[host].push_back(it);
467 if (app_msgs_.find(app) == app_msgs_.end())
469 app_msgs_[app].push_back(it);
470 updateList(lwApplication, app_msgs_);
474 app_msgs_[app].push_back(it);
478 void msgViewerDlg::displayMsg(msg_ptr_t
const& it,
int display)
480 if (it->sev() < msgFilters_[display].sevThresh)
return;
482 msgFilters_[display].nDisplayMsgs++;
483 if (display == tabWidget->currentIndex())
485 lcdDisplayedMsgs->display(msgFilters_[display].nDisplayMsgs);
488 auto txt = it->text(shortMode_);
491 UpdateTextAreaDisplay(txts, msgFilters_[display].txtDisplay);
494 void msgViewerDlg::displayMsgs(
int display)
497 msgFilters_[display].txtDisplay->clear();
498 msgFilters_[display].nDisplayMsgs = 0;
499 msgFilters_[display].nDisplayedDeletedMsgs = 0;
503 std::lock_guard<std::mutex> lk(filter_mutex_);
504 n = msgFilters_[display].msgs.size();
506 QProgressDialog progress(
"Fetching data...",
"Cancel", 0, n / 1000,
this);
508 progress.setWindowModality(Qt::WindowModal);
509 progress.setMinimumDuration(2000);
513 for (
auto it = msgFilters_[display].msgs.begin(); it != msgFilters_[display].msgs.end(); ++it, ++i)
515 if ((*it)->sev() >= msgFilters_[display].sevThresh)
517 txts.push_back((*it)->text(shortMode_));
518 ++msgFilters_[display].nDisplayMsgs;
525 progress.setValue(prog);
528 if (progress.wasCanceled())
break;
531 if (display == tabWidget->currentIndex())
533 lcdDisplayedMsgs->display(msgFilters_[display].nDisplayMsgs);
535 UpdateTextAreaDisplay(txts, msgFilters_[display].txtDisplay);
539 void msgViewerDlg::UpdateTextAreaDisplay(QStringList
const& texts, QPlainTextEdit* widget)
541 const QTextCursor old_cursor = widget->textCursor();
542 const int old_scrollbar_value = widget->verticalScrollBar()->value();
543 const bool is_scrolled_down =
544 old_scrollbar_value >= widget->verticalScrollBar()->maximum() * 0.95;
546 if (!paused && !is_scrolled_down)
551 QTextCursor new_cursor = QTextCursor(widget->document());
553 new_cursor.beginEditBlock();
554 new_cursor.movePosition(QTextCursor::End);
556 for (
int i = 0; i < texts.size(); i++)
558 new_cursor.insertBlock();
559 new_cursor.insertHtml(texts.at(i));
560 if (!shortMode_) new_cursor.insertBlock();
562 new_cursor.endEditBlock();
564 if (old_cursor.hasSelection() || paused)
567 widget->setTextCursor(old_cursor);
568 widget->verticalScrollBar()->setValue(old_scrollbar_value);
573 widget->moveCursor(QTextCursor::End);
574 widget->verticalScrollBar()->setValue(widget->verticalScrollBar()->maximum());
575 widget->horizontalScrollBar()->setValue(0);
579 void msgViewerDlg::scrollToBottom()
581 int display = tabWidget->currentIndex();
582 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::End);
583 msgFilters_[display].txtDisplay->verticalScrollBar()->setValue(
584 msgFilters_[display].txtDisplay->verticalScrollBar()->maximum());
585 msgFilters_[display].txtDisplay->horizontalScrollBar()->setValue(0);
588 void msgViewerDlg::updateDisplays()
590 for (
size_t ii = 0; ii < msgFilters_.size(); ++ii)
596 bool msgViewerDlg::updateList(QListWidget* lw, msgs_map_t
const& map)
598 bool nonSelectedBefore = (lw->currentRow() == -1);
599 bool nonSelectedAfter =
true;
601 QString item = nonSelectedBefore ?
"" : lw->currentItem()->text();
605 auto it = map.begin();
607 while (it != map.end())
609 lw->addItem(it->first);
610 if (!nonSelectedBefore && nonSelectedAfter)
612 if (item == it->first)
614 lw->setCurrentRow(row);
615 nonSelectedAfter =
false;
622 if (!nonSelectedBefore && nonSelectedAfter)
return true;
627 msgs_t msgViewerDlg::list_intersect(msgs_t
const& l1, msgs_t
const& l2)
630 auto it1 = l1.begin();
631 auto it2 = l2.begin();
633 while (it1 != l1.end() && it2 != l2.end())
639 else if (*it2 < *it1)
645 output.push_back(*it1);
651 TLOG(10) <<
"list_intersect: output list has " << output.size() <<
" entries";
655 std::string sev_to_string(sev_code_t s)
671 void msgViewerDlg::setFilter()
673 auto hostFilter = toQStringList(lwHost->selectedItems());
674 auto appFilter = toQStringList(lwApplication->selectedItems());
675 auto catFilter = toQStringList(lwCategory->selectedItems());
677 lwHost->setCurrentRow(-1, QItemSelectionModel::Clear);
678 lwApplication->setCurrentRow(-1, QItemSelectionModel::Clear);
679 lwCategory->setCurrentRow(-1, QItemSelectionModel::Clear);
681 if (hostFilter.isEmpty() && appFilter.isEmpty() && catFilter.isEmpty())
687 QString catFilterExpression =
"";
688 QString hostFilterExpression =
"";
689 QString appFilterExpression =
"";
692 for (
auto app = 0; app < appFilter.size(); ++app)
694 appFilterExpression += QString(first ?
"" :
" || ") + appFilter[app];
697 TLOG(10) <<
"setFilter: result contains %zu messages", result.size();
700 if (!hostFilter.isEmpty())
703 for (
auto host = 0; host < hostFilter.size(); ++host)
705 hostFilterExpression += QString(first ?
"" :
" || ") + hostFilter[host];
711 if (!catFilter.isEmpty())
714 for (
auto cat = 0; cat < catFilter.size(); ++cat)
716 catFilterExpression += QString(first ?
"" :
" || ") + catFilter[cat];
722 auto nFilterExpressions =
723 (appFilterExpression !=
"" ? 1 : 0) + (hostFilterExpression !=
"" ? 1 : 0) + (catFilterExpression !=
"" ? 1 : 0);
724 QString filterExpression =
"";
725 if (nFilterExpressions == 1)
727 filterExpression = catFilterExpression + hostFilterExpression + appFilterExpression;
731 filterExpression =
"(" + (catFilterExpression !=
"" ? catFilterExpression +
") && (" :
"") + hostFilterExpression +
732 (hostFilterExpression !=
"" && appFilterExpression !=
"" ?
") && (" :
"") + appFilterExpression +
736 for (
size_t d = 0; d < msgFilters_.size(); ++d)
738 if (msgFilters_[d].filterExpression == filterExpression)
740 tabWidget->setCurrentIndex(d);
746 std::lock_guard<std::mutex> lk(msg_classification_mutex_);
747 for (
auto app = 0; app < appFilter.size(); ++app)
749 auto it = app_msgs_.find(appFilter[app]);
750 if (it != app_msgs_.end())
752 msgs_t temp(it->second);
753 TLOG(10) <<
"setFilter: app " << appFilter[app].toStdString() <<
" has " << temp.size() <<
" messages";
757 TLOG(10) <<
"setFilter: result contains %zu messages", result.size();
759 if (!hostFilter.isEmpty())
762 for (
auto host = 0; host < hostFilter.size(); ++host)
764 auto it = host_msgs_.find(hostFilter[host]);
765 if (it != host_msgs_.end())
767 msgs_t temp(it->second);
768 TLOG(10) <<
"setFilter: host " << hostFilter[host].toStdString() <<
" has " << temp.size() <<
" messages";
769 hostResult.merge(temp);
778 result = list_intersect(result, hostResult);
780 TLOG(10) <<
"setFilter: result contains " << result.size() <<
" messages";
783 if (!catFilter.isEmpty())
786 for (
auto cat = 0; cat < catFilter.size(); ++cat)
788 auto it = cat_msgs_.find(catFilter[cat]);
789 if (it != cat_msgs_.end())
791 msgs_t temp(it->second);
792 TLOG(10) <<
"setFilter: cat " << catFilter[cat].toStdString() <<
" has " << temp.size() <<
" messages";
793 catResult.merge(temp);
802 result = list_intersect(result, catResult);
804 TLOG(10) <<
"setFilter: result contains " << result.size() <<
" messages";
810 auto newTabTitle = QString(
"Filter ") + QString::number(++nFilters);
811 auto newTab =
new QWidget();
813 auto txtDisplay =
new QPlainTextEdit(newTab);
814 auto doc =
new QTextDocument(txtDisplay);
815 txtDisplay->setDocument(doc);
817 auto layout =
new QVBoxLayout();
818 layout->addWidget(txtDisplay);
819 layout->setContentsMargins(0, 0, 0, 0);
820 newTab->setLayout(layout);
822 MsgFilterDisplay filteredMessages;
823 filteredMessages.msgs = result;
824 filteredMessages.hostFilter = hostFilter;
825 filteredMessages.appFilter = appFilter;
826 filteredMessages.catFilter = catFilter;
827 filteredMessages.filterExpression = filterExpression;
828 filteredMessages.txtDisplay = txtDisplay;
829 filteredMessages.nDisplayMsgs = result.size();
830 filteredMessages.nDisplayedDeletedMsgs = 0;
831 filteredMessages.sevThresh = SINFO;
833 std::lock_guard<std::mutex> lk(filter_mutex_);
834 msgFilters_.push_back(filteredMessages);
836 tabWidget->addTab(newTab, newTabTitle);
837 tabWidget->setTabToolTip(tabWidget->count() - 1, filterExpression);
838 tabWidget->setCurrentIndex(tabWidget->count() - 1);
840 displayMsgs(msgFilters_.size() - 1);
848 btnPause->setText(
"Resume Scrolling");
854 btnPause->setText(
"Pause Scrolling");
864 QMessageBox::question(
this, tr(
"Message Viewer"), tr(
"Are you sure you want to clear all received messages?"),
865 QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
868 case QMessageBox::Yes:
874 std::lock_guard<std::mutex> lk(msg_pool_mutex_);
878 std::lock_guard<std::mutex> lk(msg_classification_mutex_);
882 updateList(lwApplication, app_msgs_);
883 updateList(lwCategory, cat_msgs_);
884 updateList(lwHost, host_msgs_);
886 for (
auto& display : msgFilters_)
888 std::lock_guard<std::mutex> lk(filter_mutex_);
889 display.txtDisplay->clear();
890 display.msgs.clear();
891 display.nDisplayMsgs = 0;
892 display.nDisplayedDeletedMsgs = 0;
895 lcdMsgs->display(nMsgs);
896 lcdDisplayedMsgs->display(0);
898 case QMessageBox::No:
909 btnDisplayMode->setText(
"Long View");
914 btnDisplayMode->setText(
"Compact View");
921 auto display = tabWidget->currentIndex();
940 displayMsgs(display);
943 void msgViewerDlg::setSevError()
945 auto display = tabWidget->currentIndex();
946 msgFilters_[display].sevThresh = SERROR;
947 btnError->setChecked(
true);
948 btnWarning->setChecked(
false);
949 btnInfo->setChecked(
false);
950 btnDebug->setChecked(
false);
951 vsSeverity->setValue(SERROR);
954 void msgViewerDlg::setSevWarning()
956 auto display = tabWidget->currentIndex();
957 msgFilters_[display].sevThresh = SWARNING;
958 btnError->setChecked(
false);
959 btnWarning->setChecked(
true);
960 btnInfo->setChecked(
false);
961 btnDebug->setChecked(
false);
962 vsSeverity->setValue(SWARNING);
965 void msgViewerDlg::setSevInfo()
967 auto display = tabWidget->currentIndex();
968 msgFilters_[display].sevThresh = SINFO;
969 btnError->setChecked(
false);
970 btnWarning->setChecked(
false);
971 btnInfo->setChecked(
true);
972 btnDebug->setChecked(
false);
973 vsSeverity->setValue(SINFO);
976 void msgViewerDlg::setSevDebug()
978 auto display = tabWidget->currentIndex();
979 msgFilters_[display].sevThresh = SDEBUG;
980 btnError->setChecked(
false);
981 btnWarning->setChecked(
false);
982 btnInfo->setChecked(
false);
983 btnDebug->setChecked(
true);
984 vsSeverity->setValue(SDEBUG);
987 void msgViewerDlg::renderMode()
989 simpleRender = !simpleRender;
993 btnRMode->setChecked(
true);
994 for (
auto display : msgFilters_)
996 display.txtDisplay->setPlainText(display.txtDisplay->toPlainText());
1001 btnRMode->setChecked(
false);
1006 void msgViewerDlg::searchMsg()
1008 QString search = editSearch->text();
1010 if (search.isEmpty())
return;
1012 auto display = tabWidget->currentIndex();
1013 if (search != searchStr)
1015 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::Start);
1016 if (!msgFilters_[display].txtDisplay->find(search))
1018 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::End);
1026 if (!msgFilters_[display].txtDisplay->find(search))
1028 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::Start);
1029 if (!msgFilters_[display].txtDisplay->find(search))
1031 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::End);
1038 void msgViewerDlg::searchClear()
1040 auto display = tabWidget->currentIndex();
1041 editSearch->setText(
"");
1043 msgFilters_[display].txtDisplay->find(
"");
1044 msgFilters_[display].txtDisplay->moveCursor(QTextCursor::End);
1047 void msgViewerDlg::setSuppression(QAction* act)
1049 bool status = act->isChecked();
1050 auto sup =
static_cast<suppress*
>(act->data().value<
void*>());
1054 void msgViewerDlg::setThrottling(QAction* act)
1056 bool status = act->isChecked();
1057 auto thr =
static_cast<throttle*
>(act->data().value<
void*>());
1061 void msgViewerDlg::tabWidgetCurrentChanged(
int newTab)
1063 displayMsgs(newTab);
1064 lcdDisplayedMsgs->display(msgFilters_[newTab].nDisplayMsgs);
1066 lwHost->setCurrentRow(-1, QItemSelectionModel::Clear);
1067 lwApplication->setCurrentRow(-1, QItemSelectionModel::Clear);
1068 lwCategory->setCurrentRow(-1, QItemSelectionModel::Clear);
1070 for (
auto const& host : msgFilters_[newTab].hostFilter)
1072 auto items = lwHost->findItems(host, Qt::MatchExactly);
1075 items[0]->setSelected(
true);
1078 for (
auto const& app : msgFilters_[newTab].appFilter)
1080 auto items = lwApplication->findItems(app, Qt::MatchExactly);
1083 items[0]->setSelected(
true);
1086 for (
auto const& cat : msgFilters_[newTab].catFilter)
1088 auto items = lwCategory->findItems(cat, Qt::MatchExactly);
1091 items[0]->setSelected(
true);
1095 switch (msgFilters_[newTab].sevThresh)
1112 void msgViewerDlg::tabCloseRequested(
int tabIndex)
1114 if (tabIndex == 0 || static_cast<size_t>(tabIndex) >= msgFilters_.size())
return;
1116 auto widget = tabWidget->widget(tabIndex);
1117 tabWidget->removeTab(tabIndex);
1120 msgFilters_.erase(msgFilters_.begin() + tabIndex);
1125 QStringList msgViewerDlg::toQStringList(QList<QListWidgetItem*> in)
1129 for (
auto i = 0; i < in.size(); ++i)
1131 out << in[i]->text();
void use(bool flag)
Enable or disable this throttle
void exit()
Exit the program.
void start()
Start all receivers
Suppress messages based on a regular expression
void clear()
Clear the message buffer.
void use(bool flag)
Set whether the suppression is active
Throttle messages based on name and time limits. Separate from MessageFacility limiting.
msgViewerDlg(std::string const &conf, QDialog *parent=nullptr)
Message Viewer Dialog Constructor.
void stop()
Stop all receivers
void pause()
Pause message receiving.
void changeSeverity(int sev)
Change the severity threshold.
void shortMode()
Switch to/from Short message mode.
void closeEvent(QCloseEvent *event)
Perform actions on window close.