7#include "ui_mainwindow.h"
16#include <QAbstractItemModel>
17#include <QStandardItemModel>
18#include <QDesktopServices>
20#include <QSignalMapper>
25void MainWindow::updateMain()
28 std::list<yarp::yarpLogger::LogEntryInfo> infos;
30 std::list<yarp::yarpLogger::LogEntryInfo>::iterator it;
32 QStandardItem *itemsRoot = model_yarprunports->invisibleRootItem();
33 for (it=infos.begin(); it!=infos.end(); it++)
35 const size_t string_size= 50;
36 char time_text[string_size];
37 if (it->last_update!=-1)
39 std::tm* tm = localtime(&it->last_update);
40 sprintf(time_text,
"%02d:%02d:%02d %02d/%02d/%02d", tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_mday, tm->tm_mon, tm->tm_year+1900);
42 sprintf(time_text,
"no data received yet");
45 char logsize_text[10];
46 sprintf (logsize_text,
"%d", it->logsize);
48 char logerrors_text[10];
49 sprintf (logerrors_text,
"%d", it->get_number_of_errors());
51 char logwarnings_text[10];
52 sprintf (logwarnings_text,
"%d", it->get_number_of_warnings());
57 bool existing =
false;
59 for (i=0; i<model_yarprunports->rowCount(); i++)
61 QStandardItem *item = model_yarprunports->item(i,1);
62 if (item && item->text()==it->port_complete.c_str())
64 model_yarprunports->item(i,2)->setText(time_text);
65 model_yarprunports->item(i,3)->setText(logsize_text);
66 model_yarprunports->item(i,4)->setText(logerrors_text);
67 model_yarprunports->item(i,5)->setText(logwarnings_text);
69 QColor rowcolor = QColor(Qt::white);
76 rowcolor = QColor(
"#FF7070");
78 rowcolor = QColor(
"#FFFF70");
80 for (
int j = 0; j < model_yarprunports->columnCount(); j++) {
81 model_yarprunports->item(i, j)->setBackground(rowcolor);
86 if (it->last_update==-1 && !ui->actionShow_Mute_Ports->isChecked()) {model_yarprunports->removeRow(i);}
90 if (existing ==
false)
92 QList<QStandardItem *> rowItems;
93 rowItems <<
new QStandardItem(it->ip_address.c_str())
94 <<
new QStandardItem(it->port_complete.c_str())
95 <<
new QStandardItem(time_text)
96 <<
new QStandardItem(logsize_text)
97 <<
new QStandardItem(logerrors_text)
98 <<
new QStandardItem (logwarnings_text);
99 if (ui->actionShow_Mute_Ports->isChecked() || it->last_update!=-1)
101 itemsRoot->appendRow(rowItems);
106 bool level1_exists =
false;
107 bool level2_exists =
false;
108 for (
int i=0; i<model_yarprunports->rowCount(); i++)
110 QStandardItem *item_level1 = model_yarprunports->item(i,0);
111 if (item_level1 && item_level1->text() == it->port_prefix.c_str())
113 level1_exists =
true;
114 for (
int j=0; j<item_level1->rowCount(); j++)
116 QStandardItem *item_level2 = item_level1->child(j,0);
117 if (item_level2 && item_level1->child(j,1)->text() == it->port_complete.c_str())
119 level2_exists =
true;
120 item_level1->child(j,2)->text() = time_text;
124 if (level2_exists ==
false)
126 QList<QStandardItem *> rowItems;
127 rowItems <<
new QStandardItem(it->port_prefix.c_str())
128 <<
new QStandardItem(it->port_complete.c_str())
129 <<
new QStandardItem(time_text);
130 item_level1->appendRow(rowItems);
135 if (level1_exists ==
false)
143 QList<QStandardItem *> rowItems_l1;
144 rowItems_l1 <<
new QStandardItem(it->port_prefix.c_str());
145 itemsRoot->appendRow(rowItems_l1);
171void MainWindow::on_enableLogTab(
int model_row)
173 std::string logname = model_yarprunports->item(model_row,1)->text().toStdString();
179 for (
int j = 0; j < model_yarprunports->columnCount(); j++) {
180 model_yarprunports->item(model_row, j)->setBackground(QColor(
"#808080"));
182 QString message = logname.c_str() + QString(
" log disabled");
188 for (
int j = 0; j < model_yarprunports->columnCount(); j++) {
189 model_yarprunports->item(model_row, j)->setBackground(QColor(Qt::white));
191 QString message = logname.c_str() + QString(
" log enabled");
196void MainWindow::on_enableLogTab_action()
198 QModelIndex pre_index = ui->yarprunTreeView->selectionModel()->currentIndex();
199 QModelIndex index = proxyModel->mapToSource(pre_index);
200 int model_row=index.row();
206 on_enableLogTab(model_row);
209void MainWindow::on_clearLogTab(
int model_row)
211 QString logname = model_yarprunports->item(model_row,1)->text();
213 for (
int i=0; i<ui->logtabs->count(); i++)
215 if (ui->logtabs->tabText(i) == logname)
217 auto* l = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
224 QString message = logname + QString(
" log cleared");
228void MainWindow::on_clearLogTab_action()
230 QModelIndex pre_index = ui->yarprunTreeView->selectionModel()->currentIndex();
231 QModelIndex index = proxyModel->mapToSource(pre_index);
232 int model_row=index.row();
238 on_clearLogTab(model_row);
241void MainWindow::on_resetCountersLogTab(
int model_row)
243 std::string logname = model_yarprunports->item(model_row,1)->text().toStdString();
244 system_message->
addMessage(QString(
"Counters reset for log ") + QString(logname.c_str()));
247void MainWindow::on_saveLogTab(
int model_row)
249 std::string logname = model_yarprunports->item(model_row,1)->text().toStdString();
250 std::string preferred_filename=logname;
251 std::replace(preferred_filename.begin(), preferred_filename.end(),
'/',
'_');
252 preferred_filename.erase(0,1);
253 QString fileName = QFileDialog::getSaveFileName(
this, tr(
"Export log to text file"),preferred_filename.c_str(), tr(
"Text Files (*.txt)"));
254 if (fileName.size()!=0)
257 system_message->
addMessage(QString(
"Current log successfully exported to file: ") + fileName);
262void MainWindow::on_saveLogTab_action()
264 QModelIndex pre_index = ui->yarprunTreeView->selectionModel()->currentIndex();
265 QModelIndex index = proxyModel->mapToSource(pre_index);
266 int model_row=index.row();
272 on_saveLogTab(model_row);
275void MainWindow::on_resetCountersLogTab_action()
277 QModelIndex pre_index = ui->yarprunTreeView->selectionModel()->currentIndex();
278 QModelIndex index = proxyModel->mapToSource(pre_index);
279 int model_row=index.row();
285 on_resetCountersLogTab(model_row);
288void MainWindow::ctxMenu(
const QPoint &pos)
290 QModelIndex pre_index = ui->yarprunTreeView->selectionModel()->currentIndex();
291 QModelIndex index = proxyModel->mapToSource(pre_index);
292 int model_row=index.row();
298 std::string logname = model_yarprunports->item(model_row,1)->text().toStdString();
301 auto* menu =
new QMenu;
302 menu->addAction(tr(
"Clear current log"),
this, SLOT(on_clearLogTab_action()));
303 menu->addAction(tr(
"Export current log to text file"),
this, SLOT(on_saveLogTab_action()));
304 menu->addAction(log_enabled ? tr(
"Disable current log") : tr(
"Enable current log"), this, SLOT(on_enableLogTab_action()));
305 menu->addAction(tr(
"Reset errors/warning counters"),
this, SLOT(on_resetCountersLogTab_action()));
306 menu->exec(ui->yarprunTreeView->mapToGlobal(pos));
320 system_message = ui->tab->findChild<
MessageWidget*>(
"system_message");
321 system_message->
addMessage(
"Application Started");
323 model_yarprunports =
new QStandardItemModel(
this);
326 proxyModel->setSourceModel(model_yarprunports);
328 mainTimer =
new QTimer(
this);
329 connect(mainTimer,
SIGNAL(timeout()),
this, SLOT(updateMain()));
330 mainTimer->start(500);
332 ui->yarprunTreeView->setModel(proxyModel);
333 ui->yarprunTreeView->expandAll();
334 selection_yarprunports=ui->yarprunTreeView->selectionModel();
336 connect(ui->yarprunTreeView,
SIGNAL(customContextMenuRequested(
const QPoint &)),
this, SLOT(ctxMenu(
const QPoint &)));
338 bool autostart = rf.
check(
"start");
341 system_message->
addMessage(
"start option found");
342 on_actionStart_Logger_triggered();
345 bool unlimited = rf.
check(
"unlimited_size");
348 system_message->
addMessage(
"unlimited_size option found");
354 resetMainWindowHeaders();
356 setAcceptDrops(
true);
362 if (mainTimer) {
delete mainTimer; mainTimer=
nullptr;}
363 if (ui) {
delete ui; ui=
nullptr;}
366void MainWindow::loadTextFile()
382void MainWindow::on_filterLineEdit_textChanged(
const QString &text)
385 QString filter =
"*";
388 QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::Wildcard);
390 auto* logtab = ui->logtabs->currentWidget()->findChild<
LogTab*>(
"logtab");
397void MainWindow::on_logtabs_tabCloseRequested(
int index)
399 delete ui->logtabs->widget(index);
402void MainWindow::on_yarprunTreeView_doubleClicked(
const QModelIndex &pre_index)
404 QModelIndex index = proxyModel->mapToSource(pre_index);
405 int model_row=index.row();
411 QString tabname = model_yarprunports->item(model_row,1)->text();
414 for (
int i = 0; i < ui->logtabs->count(); i++) {
415 if (ui->logtabs->tabText(i) == tabname) {
422 ui->logtabs->setCurrentIndex(exists);
426 auto* tab =
new QTabWidget(
this);
427 auto* l =
new QVBoxLayout(tab);
428 l->setContentsMargins(0, 0, 0, 0);
430 LogTab* tmpLogTab =
new LogTab(theLogger, system_message, tabname.toStdString(),
this);
438 tmpLogTab->
displayLine(ui->actionShow_Line_Number->isChecked());
441 tmpLogTab->
displayPid(ui->actionShow_Pid->isChecked());
442 tmpLogTab->
displayCmd(ui->actionShow_Cmd->isChecked());
443 tmpLogTab->
displayArgs(ui->actionShow_Args->isChecked());
446 tmpLogTab->
displayId(ui->actionShow_Id->isChecked());
447 tmpLogTab->
displayGrid(ui->actionShow_Grid->isChecked());
448 tmpLogTab->
displayColors(ui->actionShow_Colors->isChecked());
449 l->addWidget(tmpLogTab);
450 tmpLogTab->setObjectName(
"logtab");
452 int newtab_index = ui->logtabs->addTab(tab, tabname);
453 ui->logtabs->setCurrentIndex(newtab_index);
455 apply_button_filters();
458QString MainWindow::recomputeFilters()
461 bool e_trace = this->ui->DisplayTraceEnable->isChecked();
462 bool e_debug = this->ui->DisplayDebugEnable->isChecked();
463 bool e_info = this->ui->DisplayInfoEnable->isChecked();
464 bool e_warning = this->ui->DisplayWarningEnable->isChecked();
465 bool e_error = this->ui->DisplayErrorEnable->isChecked();
466 bool e_all = this->ui->DisplayUnformattedEnable->isChecked();
468 if (e_trace) {filter = filter +
"^TRACE$"; f++;}
471 filter = filter +
"|";
473 filter = filter +
"^DEBUG$";
478 filter = filter +
"|";
480 filter = filter +
"^INFO$";
485 filter = filter +
"|";
487 filter = filter +
"^WARNING$";
492 filter = filter +
"|";
494 filter = filter +
"^ERROR$";
499 filter = filter +
"|";
501 filter = filter +
"^$";
506 filter = filter +
"|";
508 filter = filter +
"^FATAL$";
511 std::string
debug = filter.toStdString();
515void MainWindow::apply_button_filters()
518 QRegExp regExp (
"*", Qt::CaseInsensitive, QRegExp::RegExp);
519 regExp.setPattern(recomputeFilters());
520 for (
int i=0; i<ui->logtabs->count(); i++)
522 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
531void MainWindow::on_DisplayErrorEnable_toggled(
bool checked)
533 apply_button_filters();
536void MainWindow::on_DisplayWarningEnable_toggled(
bool checked)
538 apply_button_filters();
541void MainWindow::on_DisplayDebugEnable_toggled(
bool checked)
543 apply_button_filters();
546void MainWindow::on_DisplayInfoEnable_toggled(
bool checked)
548 apply_button_filters();
551void MainWindow::on_DisplayTraceEnable_toggled(
bool checked)
553 apply_button_filters();
556void MainWindow::on_DisplayUnformattedEnable_toggled(
bool checked)
558 apply_button_filters();
561void MainWindow::on_actionShow_YarprunTimestamps_toggled(
bool checked)
563 for (
int i=0; i<ui->logtabs->count(); i++)
565 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
573void MainWindow::on_actionShow_LocalTimestamps_toggled(
bool checked)
575 for (
int i=0; i<ui->logtabs->count(); i++)
577 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
585void MainWindow::on_actionShow_System_Time_toggled(
bool checked)
587 for (
int i=0; i<ui->logtabs->count(); i++)
589 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
597void MainWindow::on_actionShow_Network_Time_toggled(
bool checked)
599 for (
int i=0; i<ui->logtabs->count(); i++)
601 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
609void MainWindow::on_actionShow_Custom_Time_toggled(
bool checked)
611 for (
int i=0; i<ui->logtabs->count(); i++)
613 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
621void MainWindow::on_actionShow_Log_Level_toggled(
bool checked)
623 for (
int i=0; i<ui->logtabs->count(); i++)
625 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
633void MainWindow::on_actionShow_Filename_toggled(
bool checked)
635 for (
int i=0; i<ui->logtabs->count(); i++)
637 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
645void MainWindow::on_actionShow_Line_Number_toggled(
bool checked)
647 for (
int i=0; i<ui->logtabs->count(); i++)
649 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
657void MainWindow::on_actionShow_Function_toggled(
bool checked)
659 for (
int i=0; i<ui->logtabs->count(); i++)
661 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
669void MainWindow::on_actionShow_Hostname_toggled(
bool checked)
671 for (
int i=0; i<ui->logtabs->count(); i++)
673 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
681void MainWindow::on_actionShow_Pid_toggled(
bool checked)
683 for (
int i=0; i<ui->logtabs->count(); i++)
685 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
693void MainWindow::on_actionShow_Cmd_toggled(
bool checked)
695 for (
int i=0; i<ui->logtabs->count(); i++)
697 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
705void MainWindow::on_actionShow_Args_toggled(
bool checked)
707 for (
int i=0; i<ui->logtabs->count(); i++)
709 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
717void MainWindow::on_actionShow_Thread_Id_toggled(
bool checked)
719 for (
int i=0; i<ui->logtabs->count(); i++)
721 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
729void MainWindow::on_actionShow_Component_toggled(
bool checked)
731 for (
int i=0; i<ui->logtabs->count(); i++)
733 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
741void MainWindow::on_actionShow_Id_toggled(
bool checked)
743 for (
int i=0; i<ui->logtabs->count(); i++)
745 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
753void MainWindow::on_actionShow_Grid_toggled(
bool checked)
755 for (
int i=0; i<ui->logtabs->count(); i++)
757 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
765void MainWindow::on_actionShow_Colors_toggled(
bool checked)
767 for (
int i=0; i<ui->logtabs->count(); i++)
769 auto* logtab = ui->logtabs->widget(i)->findChild<
LogTab*>(
"logtab");
777void MainWindow::on_actionShow_Mute_Ports_toggled(
bool checked)
782void MainWindow::on_actionAbout_QtYarpLogger_triggered()
784 QDesktopServices::openUrl(QUrl(
"https://www.yarp.it/latest/yarp_logging.html"));
787void MainWindow::on_actionSave_Log_triggered(
bool checked)
789 QString dateformat =
"dd_MM_yyyy_hh_mm_ss";
790 QDateTime currDate = QDateTime::currentDateTime();
791 QString preferred_filename =
"yarprunlog_" + currDate.toString(dateformat) +
".log";
792 QString fileName = QFileDialog::getSaveFileName(
this, tr(
"Save to log file"),preferred_filename, tr(
"Log Files (*.log)"));
793 if (fileName.size()!=0)
796 system_message->
addMessage(QString(
"Log saved to file: ") + fileName);
803void MainWindow::on_actionLoad_Log_triggered()
805 QString fileName = QFileDialog::getOpenFileName(
this, tr(
"Load log file"),
"./", tr(
"Log Files (*.log)"));
806 if (fileName.size()!=0)
808 on_actionStop_Logger_triggered();
809 on_actionClear_triggered();
811 system_message->
addMessage(QString(
"Log loaded from file: ") + fileName);
818void MainWindow::on_actionAdvanced_triggered()
824void MainWindow::on_actionStart_Logger_triggered()
828 ui->actionStart_Logger->setEnabled(
false);
829 ui->actionStop_Logger->setEnabled(
true);
830 ui->actionRefresh->setEnabled(
true);
835 system_message->
addMessage(
"Unable to start: maybe logger port is conflicting with another running process?\nOnly one logger can be executed on the same network.",
MESSAGE_LEVEL_ERROR);
839void MainWindow::on_actionStop_Logger_triggered()
843 ui->actionStart_Logger->setEnabled(
true);
844 ui->actionStop_Logger->setEnabled(
false);
845 ui->actionRefresh->setEnabled(
false);
854void MainWindow::on_actionRefresh_triggered()
856 system_message->
addMessage(
"Searching for yarprun ports");
857 std::list<std::string> ports;
862 sprintf (text,
"found %zd ports, logger running", ports.size());
866void MainWindow::resetMainWindowHeaders()
868 model_yarprunports->setHorizontalHeaderItem(0,
new QStandardItem(
"ip"));
869 model_yarprunports->setHorizontalHeaderItem(1,
new QStandardItem(
"process"));
870 model_yarprunports->setHorizontalHeaderItem(2,
new QStandardItem(
"last heard"));
871 model_yarprunports->setHorizontalHeaderItem(3,
new QStandardItem(
"log size"));
872 model_yarprunports->setHorizontalHeaderItem(4,
new QStandardItem(
"errors"));
873 model_yarprunports->setHorizontalHeaderItem(5,
new QStandardItem(
"warnings"));
874 ui->yarprunTreeView->setColumnWidth(0, 100);
875 ui->yarprunTreeView->setColumnWidth(1, 200);
876 ui->yarprunTreeView->setColumnWidth(2, 150);
877 ui->yarprunTreeView->setColumnWidth(3, 80);
878 ui->yarprunTreeView->setColumnWidth(4, 60);
879 ui->yarprunTreeView->setColumnWidth(5, 60);
882void MainWindow::on_actionClear_triggered()
884 if (theLogger->
clear())
886 if (model_yarprunports)
888 model_yarprunports->clear();
889 resetMainWindowHeaders();
892 ui->logtabs->clear();
899void MainWindow::on_actionClear_current_log_triggered()
901 QModelIndex pre_index = ui->yarprunTreeView->selectionModel()->currentIndex();
902 QModelIndex index = proxyModel->mapToSource(pre_index);
903 int model_row=index.row();
909 on_clearLogTab(model_row);
912void MainWindow::on_actionExport_current_log_to_text_file_triggered()
914 QModelIndex pre_index = ui->yarprunTreeView->selectionModel()->currentIndex();
915 QModelIndex index = proxyModel->mapToSource(pre_index);
916 int model_row=index.row();
922 on_saveLogTab(model_row);
925void MainWindow::on_actionDisable_current_log_triggered()
927 QModelIndex pre_index = ui->yarprunTreeView->selectionModel()->currentIndex();
928 QModelIndex index = proxyModel->mapToSource(pre_index);
929 int model_row=index.row();
935 on_enableLogTab(model_row);
938void MainWindow::on_actionReset_current_log_error_warning_counters_triggered()
940 QModelIndex pre_index = ui->yarprunTreeView->selectionModel()->currentIndex();
941 QModelIndex index = proxyModel->mapToSource(pre_index);
942 int model_row=index.row();
948 on_resetCountersLogTab(model_row);
951void MainWindow::dragEnterEvent(QDragEnterEvent *e)
953 if (e->mimeData()->hasUrls()) {
954 e->acceptProposedAction();
958void MainWindow::dropEvent(QDropEvent *e)
960 const QUrl url = e->mimeData()->urls().first();
962 QString fileName = url.toLocalFile();
964 on_actionStop_Logger_triggered();
965 on_actionClear_triggered();
968 system_message->
addMessage(QString(
"Log loaded from file: ") + fileName);
int SIGNAL(int pid, int signum)
static constexpr int LOGLEVEL_COLUMN
void displayGrid(bool enabled)
void displayPid(bool enabled)
void displayLocalTimestamp(bool enabled)
void displaySystemTime(bool enabled)
void displayExternalTime(bool enabled)
void displayLine(bool enabled)
void displayYarprunTimestamp(bool enabled)
void displayFunction(bool enabled)
void displayLogLevel(bool enabled)
LogSortFilterProxyModel * proxyModelButtons
void displayId(bool enabled)
void displayHostname(bool enabled)
void displayColors(bool enabled)
void displayFilename(bool enabled)
LogSortFilterProxyModel * proxyModelSearch
void displayCmd(bool enabled)
void displayArgs(bool enabled)
void displayThreadId(bool enabled)
void displayNetworkTime(bool enabled)
void displayComponent(bool enabled)
MainWindow(const yarp::os::ResourceFinder &rf, yarp::dev::IBattery *ibat, QWidget *parent=0, double refresh_period=10.0)
Helper class for finding config files and other external resources.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
static ResourceFinder & getResourceFinderSingleton()
Access a ResourceFinder singleton whose lifetime will match that of the YARP library.
A single value (typically within a Bottle).
void set_log_list_max_size(bool enabled, int new_size)
void connect(const std::list< std::string > &ports)
bool get_log_enable_by_port_complete(std::string port)
void clear_messages_by_port_complete(std::string port)
void set_log_lines_max_size(bool enabled, int new_size)
void discover(std::list< std::string > &ports)
bool load_all_logs_from_file(std::string filename)
bool save_all_logs_to_file(std::string filename)
bool export_log_to_text_file(std::string filename, std::string portname)
void get_infos(std::list< LogEntryInfo > &infos)
void set_log_enable_by_port_complete(std::string port, bool enable)