25#include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h>
27#include <ArmarXGui/gui-plugins/LoggingPlugin/ui_FilterDialog.h>
37#include <boost/algorithm/string/regex.hpp>
39#include <QInputDialog>
47#define USERROLE_LOGTABLEID Qt::UserRole + 1
48#define USERROLE_LOGTABLEPTR Qt::UserRole + 2
49#define USERROLE_BASENAME Qt::UserRole + 3
50#define REGEX_COLORS "\033\\[(\\d|\\w?)[;]?(\\d+)m"
51#define ALL_MESSAGES_FILTER "All Messages"
58 qRegisterMetaType<Qt::Orientation>(
"Qt::Orientation");
59 qRegisterMetaType<std::string>(
"std::string");
62 for (
int i = 0; i < eLogLevelCount; i++)
67 ui.cbVerbosityLevel->setCurrentIndex(1);
69 ui.lvFilters->setCurrentItem(
ui.lvFilters->invisibleRootItem()->child(0));
70 ui.lvFilters->setSortingEnabled(
true);
71 ui.lvFilters->sortByColumn(0, Qt::AscendingOrder);
72 pendingEntriesTimer =
new QTimer(
getWidget());
73 pendingEntriesTimer->setInterval(50);
82 ui.splitter->setSizes(sizes);
95 qRegisterMetaType<LogMessage>(
"LogMessage");
103 connect(
ui.btnAddFilter, SIGNAL(clicked()),
this, SLOT(
addFilter()));
105 connect(
ui.btnPause, SIGNAL(toggled(
bool)),
this, SLOT(
pauseLogging(
bool)));
107 connect(
ui.btnClearAllLogs, SIGNAL(clicked()),
this, SLOT(
clearAllLogs()));
108 connect(
ui.lvFilters,
109 SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
112 connect(
ui.lvFilters,
113 SIGNAL(itemDoubleClicked(QTreeWidgetItem*,
int)),
122 ui.edtLiveFilter->hide();
123 ui.edtLiveSearch->setFocus();
134 ui.cbVerbosityLevel->setCurrentIndex(settings->value(
"verbosityLevel", 2).toInt());
135 ui.cbAutoComponentFilters->setChecked(settings->value(
"autoFilterAdding",
true).toBool());
142 settings->setValue(
"verbosityLevel",
ui.cbVerbosityLevel->currentIndex());
144 settings->setValue(
"autoFilterAdding",
ui.cbAutoComponentFilters->isChecked());
194 LogViewer::loggingGroupNameToFilterName(
const QString& loggingGroupName)
const
196 return loggingGroupName.isEmpty() ?
"" : (
"_" + loggingGroupName);
207 const std::string&
tag,
208 MessageType severity,
209 const std::string& message,
210 const std::string& file,
212 const std::string& function,
223 msg.function = function;
236 if (
ui.cbVerbosityLevel->currentIndex() <= msg.type)
238 std::unique_lock lock(pendingEntriesMutex);
239 pendingEntries.push_back(msg);
258 if (filterStr.length() == 0)
262 else if (filterStr.length() < 3)
269 logTable->liveFilter(filterStr, startRow);
270 lastLiveSearchEditChangeTime = IceUtil::Time::now();
276 if (searchStr.length() == 0)
279 ui.btnNextItem->setEnabled(
false);
280 ui.btnPreviousItem->setEnabled(
false);
286 if (!
logTable->liveSearch(searchStr))
289 "Could not find '" +
logTable->getModel()->getCurrentSearchStr() +
292 ui.btnNextItem->setEnabled(
false);
293 ui.btnPreviousItem->setEnabled(
false);
297 ui.btnNextItem->setEnabled(
true);
298 ui.btnPreviousItem->setEnabled(
true);
315 std::map<QString, LogTable*>::iterator it = filterMap.begin();
317 for (; it != filterMap.end(); it++)
319 it->second->getModel()->clearData();
328 loggingPaused = pause;
336 QTreeWidgetItem* item =
new QTreeWidgetItem(
ui.lvFilters);
338 item->setText(0, standardFilterStr);
343 filterMap[standardFilterStr] = newLogTable;
344 ui.splitter->addWidget(newLogTable);
352 QString loggingGroup,
353 QString componentFilter,
355 MessageType minimumVerbosity,
356 QString messageFilter,
358 QString functionFilter)
361 if (filterMap.find(filterId) != filterMap.end())
363 QString msg =
"A filter with the id " + filterId +
" exists already";
371 if (loggingGroup.length())
374 loggingGroup.toStdString());
378 if (componentFilter.length())
381 componentFilter.toStdString());
384 if (tagFilter.length())
389 if (messageFilter.length())
394 if (fileFilter.length())
399 if (functionFilter.length())
402 functionFilter.toStdString());
406 QString::number(minimumVerbosity).toStdString());
408 QTreeWidgetItem* item =
new QTreeWidgetItem();
409 item->setText(0, filterName);
413 filterMap[filterId] = newLogTable;
414 Ice::StringSeq children;
415 for (
int i = 0; i <
ui.lvFilters->invisibleRootItem()->childCount(); i++)
417 children.push_back(
ui.lvFilters->invisibleRootItem()->child(i)->text(0).toStdString());
420 QTreeWidgetItem* grpItem = NULL;
421 auto grpFilterId = loggingGroupNameToFilterName(loggingGroup);
422 for (
int i = 0; i <
ui.lvFilters->invisibleRootItem()->childCount(); i++)
424 if (
ui.lvFilters->invisibleRootItem()
427 .toString() == grpFilterId)
429 grpItem =
ui.lvFilters->invisibleRootItem()->child(i);
435 grpItem->addChild(item);
441 ui.lvFilters->insertTopLevelItem(0, item);
445 ui.splitter->addWidget(newLogTable);
452 if (componentName.length() == 0 && loggingGroupName.length() == 0)
457 if (!
ui.cbAutoComponentFilters->isChecked())
461 QString filler = (loggingGroupName.length() > 0 && componentName.length() > 0) ?
"_" :
"";
462 auto filterId = loggingGroupNameToFilterName(loggingGroupName) + filler + componentName;
463 auto filterName = componentName.length() > 0
465 : loggingGroupNameToFilterName(loggingGroupName);
467 if (filterMap.count(filterId))
472 addFilter(filterId, filterName, loggingGroupName, componentName,
"", eDEBUG,
"",
"",
"");
481 if (!filterDialog.exec())
486 QString filterName = filterDialog.
ui->edtFilterName->text();
488 if (filterMap.find(filterName) != filterMap.end())
490 QString msg =
"A filter with this name already exists";
499 if (filterDialog.
ui->editComponent->text().length())
505 if (filterDialog.
ui->edtTag->text().length())
508 filterDialog.
ui->edtTag->text().toStdString());
511 if (filterDialog.
ui->edtMessage->text().length())
514 filterDialog.
ui->edtMessage->text().toStdString());
517 if (filterDialog.
ui->edtFile->text().length())
520 filterDialog.
ui->edtFile->text().toStdString());
523 if (filterDialog.
ui->edtFunction->text().length())
526 filterDialog.
ui->edtFunction->text().toStdString());
529 if (filterDialog.
ui->cbVerbosity->currentIndex() != -1)
533 QString::number(filterDialog.
ui->cbVerbosity->currentIndex()).toStdString());
536 QTreeWidgetItem* item =
new QTreeWidgetItem();
537 item->setText(0, filterName);
541 filterMap[filterName] = newLogTable;
542 ui.lvFilters->insertTopLevelItem(
ui.lvFilters->invisibleRootItem()->childCount(), item);
544 ui.splitter->addWidget(newLogTable);
554 if (filterMap.find(filterId) == filterMap.end())
568 for (
unsigned int i = 0; i <
logTable->getModel()->getFilters().size(); i++)
570 std::string columnName =
logTable->getModel()->getFilters()[i].first;
571 std::string filter =
logTable->getModel()->getFilters()[i].second;
575 filterDialog.
ui->editComponent->setText(filter.c_str());
579 filterDialog.
ui->edtTag->setText(filter.c_str());
584 filterDialog.
ui->cbVerbosity->setCurrentIndex(QString(filter.c_str()).toInt());
588 filterDialog.
ui->edtMessage->setText(filter.c_str());
592 filterDialog.
ui->edtFile->setText(filter.c_str());
596 filterDialog.
ui->edtFunction->setText(filter.c_str());
601 if (!filterDialog.exec())
605 item->setText(0, filterDialog.
ui->edtFilterName->text());
607 logTable->getModel()->resetFilters();
609 if (filterDialog.
ui->editComponent->text().length())
612 filterDialog.
ui->editComponent->text().toStdString());
615 if (filterDialog.
ui->edtTag->text().length())
618 filterDialog.
ui->edtTag->text().toStdString());
621 if (filterDialog.
ui->edtMessage->text().length())
624 filterDialog.
ui->edtMessage->text().toStdString());
627 if (filterDialog.
ui->edtFile->text().length())
630 filterDialog.
ui->edtFile->text().toStdString());
633 if (filterDialog.
ui->edtFunction->text().length())
636 filterDialog.
ui->edtFunction->text().toStdString());
639 if (filterDialog.
ui->cbVerbosity->currentIndex() != -1)
643 QString::number(filterDialog.
ui->cbVerbosity->currentIndex()).toStdString());
646 logTable->getModel()->reapplyAllFilters();
653 if (
ui.lvFilters->invisibleRootItem()->childCount() == 1)
658 auto item =
ui.lvFilters->currentItem();
670 std::map<QString, LogTable*>::iterator it =
673 if (it == filterMap.end())
677 QList<QTreeWidgetItem*> itemsToDelete, iterationList({item});
678 while (!iterationList.isEmpty())
680 auto curItem = iterationList.front();
681 itemsToDelete << curItem;
682 iterationList.pop_front();
683 iterationList << curItem->takeChildren();
685 ui.lvFilters->setCurrentItem(
ui.lvFilters->invisibleRootItem()->child(0));
686 for (
auto& item : itemsToDelete)
688 auto parent = item->parent();
691 parent->removeChild(item);
695 ui.lvFilters->invisibleRootItem()->removeChild(item);
697 std::map<QString, LogTable*>::iterator it =
701 if (it == filterMap.end())
723 item->setFont(0, font);
725 if (filterMap.find(filterId) == filterMap.end())
746 ui.edtLiveFilter->setText(
logTable->getLiveFilterStr());
747 ui.edtLiveSearch->setText(
logTable->getModel()->getCurrentSearchStr());
754 QList<QTreeWidgetItem*> itemsToUpdate, iterationList({
ui.lvFilters->invisibleRootItem()});
755 while (!iterationList.isEmpty())
757 auto curItem = iterationList.front();
758 itemsToUpdate << curItem;
759 iterationList.pop_front();
760 for (
int i = 0; i < curItem->childCount(); ++i)
762 iterationList << curItem->child(i);
766 for (
auto item : itemsToUpdate)
769 LogTable* curLogtable = filterMap.find(filterId)->second;
779 item->setFont(0, font);
781 item->setBackgroundColor(0,
ui.lvFilters->palette().base().color());
786 item->setFont(0, font);
792 item->setBackgroundColor(0, QColor(216, 120, 50));
796 item->setBackgroundColor(0, QColor(255, 90, 80));
800 item->setBackgroundColor(0, QColor(255, 60, 50));
804 item->setBackgroundColor(0,
ui.lvFilters->palette().base().color());
808 item->setText(0, newContent);
809 item->setToolTip(0, newContent);
816 throw LocalException() <<
"Not yet implemented";
823 if (
getState() >= eManagedIceObjectExiting)
828 std::vector<LogMessage> pendingEntriesTemp;
830 std::unique_lock lock(pendingEntriesMutex);
831 pendingEntriesTemp.swap(pendingEntries);
835 unsigned int size = pendingEntriesTemp.size();
838 for (
unsigned int i = 0; i < size; i++)
840 LogMessage& msg = pendingEntriesTemp[i];
841 msg.what = boost::regex_replace(msg.what, re,
"");
843 if (!
getWidget() ||
ui.cbVerbosityLevel->currentIndex() > msg.type)
850 std::map<QString, LogTable*>::iterator it = filterMap.begin();
852 for (; it != filterMap.end(); ++it)
858 std::cerr <<
"log ptr is NULL" << std::endl;
863 bool autoScroll =
false;
865 if (log->verticalScrollBar()->value() == log->verticalScrollBar()->maximum())
874 log->scrollToBottom();
881 bool autoScroll =
false;
883 if (
logTable->verticalScrollBar()->value() ==
logTable->verticalScrollBar()->maximum())
888 std::map<QString, LogTable*>::iterator it = filterMap.begin();
890 for (; it != filterMap.end(); ++it)
900 for (r = row; r < count; r++)
905 bool autoScroll =
false;
907 if (log->verticalScrollBar()->value() == log->verticalScrollBar()->maximum())
915 log->scrollToBottom();
933 ui.edtLiveSearch->show();
934 ui.btnPreviousItem->show();
935 ui.btnNextItem->show();
936 ui.edtLiveFilter->hide();
940 ui.edtLiveSearch->hide();
941 ui.btnPreviousItem->hide();
942 ui.btnNextItem->hide();
943 ui.edtLiveFilter->show();
953 if (!
logTable->selectNextSearchResult(
false))
956 "Could not find '" +
logTable->getModel()->getCurrentSearchStr() +
967 if (!
logTable->selectNextSearchResult(
true))
970 "Could not find '" +
logTable->getModel()->getCurrentSearchStr() +
981 if (parent != customToolbar->parent())
983 customToolbar->setParent(parent);
986 return customToolbar;
989 customToolbar =
new QToolBar(parent);
990 customToolbar->setIconSize(QSize(16, 16));
991 customToolbar->addAction(
994 return customToolbar;
#define ARMARX_LOG_VERBOSITYSTR
#define ARMARX_LOG_COMPONENTSTR
#define ARMARX_LOG_FILESTR
#define ARMARX_LOG_TAGSTR
#define ARMARX_LOG_MESSAGESTR
#define ARMARX_LOG_LOGGINGGROUPSTR
#define ARMARX_LOG_FUNCTIONSTR
#define USERROLE_BASENAME
#define ALL_MESSAGES_FILTER
#define USERROLE_LOGTABLEID
static std::string levelToString(MessageTypeT type)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
int addEntries(const std::vector< LogMessage > &entryList, const QString &filterStr)
void addFilter(const std::string &columnName, const std::string &filter)
MessageType getMaxNewLogLevelType()
void liveFilterRow(const QString &filterStr, int row)
LogTableModel * getModel()
QString getCurrentLiveFilter() const
void pauseLogging(bool pause=false)
void componentConnected()
void selectPreviousSearchResult()
void onInitComponent() override
Pure virtual hook for the subclass.
void editFilter(QTreeWidgetItem *item, int column)
void insertPendingEntries()
bool onClose() override
If you overwrite this method, make sure to call this implementation at the end of your implementation...
QPointer< QWidget > getCustomTitlebarWidget(QWidget *parent) override
getTitleToolbar returns a pointer to the a toolbar widget of this controller.
void selectNextSearchResult()
void removeSelectedFilter()
LogTable * addEmptyFilter()
void removeFilter(QTreeWidgetItem *item)
void loadSettings(QSettings *settings) override
Implement to load the settings that are part of the GUI configuration.
void saveSettings(QSettings *settings) override
Implement to save the settings as part of the GUI configuration.
void updateFilterListSignal()
void performLiveSearch(QString searchStr)
void OpenConfigureDialog()
void onConnectComponent() override
Pure virtual hook for the subclass.
void setRow(const LogMessage &msg, int rowIndex)
void newEntry(const LogMessage &msg)
void addNewEntry(const LogMessage &msg)
void write(const std::string &who, Ice::Long time, const std::string &tag, MessageType severity, const std::string &message, const std::string &file, Ice::Int line, const std::string &function, const Ice::Current &=Ice::emptyCurrent)
void filterSelectionChanged(QTreeWidgetItem *item, QTreeWidgetItem *previous)
bool checkAndAddNewFilter(const QString &loggingGroupName, const QString &componentName)
This function checks, if there are new components in the log and if so, it creates new filters for th...
void onExitComponent() override
Hook for subclass.
void writeLog(const LogMessage &msg, const Ice::Current &=Ice::emptyCurrent) override
void performLiveFilter(QString searchStr, int startRow=0)
void searchTypeChanged(int index)
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
int getState() const
Retrieve current state of the ManagedIceObject.
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
This file offers overloads of toIce() and fromIce() functions for STL container types.
const LogSender::manipulator flush