LogViewer.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package ArmarX::
17* @author Mirko Waechter ( mirko.waechter at kit dot edu)
18* @date 2012
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
23#include "LogViewer.h"
24
25#include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h>
26
27#include <ArmarXGui/gui-plugins/LoggingPlugin/ui_FilterDialog.h>
28
29#include "FilterDialog.h"
30#include "LogTable.h"
31#include "LogTableModel.h"
32
33// C++ includes
34#include <sstream>
35
36// Qt includes
37#include <boost/algorithm/string/regex.hpp>
38
39#include <QInputDialog>
40#include <QMainWindow>
41#include <QScrollBar>
42#include <QStatusBar>
43#include <QTimer>
44#include <QToolBar>
45
46
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"
52
53namespace armarx
54{
55 LogViewer::LogViewer() : logTable(NULL), loggingPaused(false), customToolbar(0)
56
57 {
58 qRegisterMetaType<Qt::Orientation>("Qt::Orientation");
59 qRegisterMetaType<std::string>("std::string");
60 ui.setupUi(getWidget());
61
62 for (int i = 0; i < eLogLevelCount; i++)
63 {
64 ui.cbVerbosityLevel->addItem(LogSender::levelToString((MessageTypeT)i).c_str());
65 }
66
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);
74
75 connect(pendingEntriesTimer, SIGNAL(timeout()), this, SLOT(insertPendingEntries()));
76 connect(this, SIGNAL(componentConnected()), pendingEntriesTimer, SLOT(start()));
77
78
79 QList<int> sizes;
80 sizes.push_back(80);
81 sizes.push_back(400);
82 ui.splitter->setSizes(sizes);
84 "Warning+",
85 "Warning+",
86 "",
87 "",
88 "",
89 eWARN,
90 "",
91 "",
92 ""); // add additional filters after splitter->setSizes-> otherwise they have a width of NULL
93
94
95 qRegisterMetaType<LogMessage>("LogMessage");
96
97 // SIGNALS AND SLOTS CONNECTIONS
98 connect(this, SIGNAL(newEntry(LogMessage)), this, SLOT(addNewEntry(LogMessage)));
99 connect(
100 ui.edtLiveFilter, SIGNAL(textChanged(QString)), this, SLOT(performLiveFilter(QString)));
101 connect(
102 ui.edtLiveSearch, SIGNAL(textChanged(QString)), this, SLOT(performLiveSearch(QString)));
103 connect(ui.btnAddFilter, SIGNAL(clicked()), this, SLOT(addFilter()));
104 connect(ui.btnRemoveFilter, SIGNAL(clicked()), this, SLOT(removeSelectedFilter()));
105 connect(ui.btnPause, SIGNAL(toggled(bool)), this, SLOT(pauseLogging(bool)));
106 connect(ui.btnClearLog, SIGNAL(clicked()), this, SLOT(clearSelectedLog()));
107 connect(ui.btnClearAllLogs, SIGNAL(clicked()), this, SLOT(clearAllLogs()));
108 connect(ui.lvFilters,
109 SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
110 this,
111 SLOT(filterSelectionChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
112 connect(ui.lvFilters,
113 SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
114 this,
115 SLOT(editFilter(QTreeWidgetItem*, int)));
116 connect(
117 ui.cbSearchType, SIGNAL(currentIndexChanged(int)), this, SLOT(searchTypeChanged(int)));
118 connect(this, SIGNAL(updateFilterListSignal()), this, SLOT(updateFilterList()));
119 connect(ui.btnNextItem, SIGNAL(clicked()), this, SLOT(selectNextSearchResult()));
120 connect(ui.btnPreviousItem, SIGNAL(clicked()), this, SLOT(selectPreviousSearchResult()));
121
122 ui.edtLiveFilter->hide();
123 ui.edtLiveSearch->setFocus();
124 }
125
127 {
128 // ARMARX_VERBOSE << "~LogViewer";
129 }
130
131 void
133 {
134 ui.cbVerbosityLevel->setCurrentIndex(settings->value("verbosityLevel", 2).toInt());
135 ui.cbAutoComponentFilters->setChecked(settings->value("autoFilterAdding", true).toBool());
136 }
137
138 void
140 {
141
142 settings->setValue("verbosityLevel", ui.cbVerbosityLevel->currentIndex());
143
144 settings->setValue("autoFilterAdding", ui.cbAutoComponentFilters->isChecked());
145
146
147 // // saving filters
148
149 // QString filterName = ui.lvFilters->items()->data(USERROLE_LOGTABLEID).toString();
150 // for(unsigned int i= 0; i< logTable->getModel()->getFilters().size(); i++)
151 // {
152 // std::string columnName = logTable->getModel()->getFilters()[i].first;
153 // std::string filter = logTable->getModel()->getFilters()[i].second;
154 // if(columnName == ARMARX_LOG_COMPONENTSTR)
155 // filterDialog.ui->editComponent->setText(filter.c_str());
156 // else if(columnName == ARMARX_LOG_TAGSTR)
157 // filterDialog.ui->edtTag->setText(filter.c_str());
158 // else if(columnName == ARMARX_LOG_VERBOSITYSTR){
159
160 // filterDialog.ui->cbVerbosity->setCurrentIndex(QString(filter.c_str()).toInt());
161 // }
162 // else if(columnName == ARMARX_LOG_MESSAGESTR)
163 // filterDialog.ui->edtMessage->setText(filter.c_str());
164 // else if(columnName == ARMARX_LOG_FILESTR)
165 // filterDialog.ui->edtFile->setText(filter.c_str());
166 // else if(columnName == ARMARX_LOG_FUNCTIONSTR)
167 // filterDialog.ui->edtFunction->setText(filter.c_str());
168 // }
169 }
170
171 void
176
177 void
182
183 bool
185 {
186 // QInputDialog dialog;
187 // if(dialog.exec() == QDialog::Rejected)
188 // return false;
189
191 }
192
193 QString
194 LogViewer::loggingGroupNameToFilterName(const QString& loggingGroupName) const
195 {
196 return loggingGroupName.isEmpty() ? "" : ("_" + loggingGroupName);
197 }
198
199 void
203
204 void
205 LogViewer::write(const std::string& who,
206 Ice::Long time,
207 const std::string& tag,
208 MessageType severity,
209 const std::string& message,
210 const std::string& file,
211 Ice::Int line,
212 const std::string& function,
213 const Ice::Current&)
214 {
215 LogMessage msg;
216 msg.who = who;
217 msg.time = time;
218 msg.tag = tag;
219 msg.type = severity;
220 msg.what = message;
221 msg.file = file;
222 msg.line = line;
223 msg.function = function;
224
225 writeLog(msg);
226 }
227
228 void
229 LogViewer::writeLog(const LogMessage& msg, const Ice::Current&)
230 {
231 if (loggingPaused)
232 {
233 return;
234 }
235
236 if (ui.cbVerbosityLevel->currentIndex() <= msg.type)
237 {
238 std::unique_lock lock(pendingEntriesMutex);
239 pendingEntries.push_back(msg);
240 }
241 }
242
243 void
244 LogViewer::setRow(const LogMessage& msg, int rowIndex)
245 {
246 }
247
248 void
249 LogViewer::addNewEntry(const LogMessage& msg)
250 {
251 }
252
253 void
254 LogViewer::performLiveFilter(QString filterStr, int startRow)
255 {
256 // if((IceUtil::Time::now() - lastLiveSearchEditChangeTime).toSeconds() < 1)
257 // return;
258 if (filterStr.length() == 0)
259 {
260 logTable->resetLiveFilter();
261 }
262 else if (filterStr.length() < 3)
263 {
264 return;
265 }
266
267 // LogSearch search(logTable);
268 // search.search(searchStr);
269 logTable->liveFilter(filterStr, startRow);
270 lastLiveSearchEditChangeTime = IceUtil::Time::now();
271 }
272
273 void
275 {
276 if (searchStr.length() == 0)
277 {
278 logTable->resetLiveSearch();
279 ui.btnNextItem->setEnabled(false);
280 ui.btnPreviousItem->setEnabled(false);
281 }
282 // else if(searchStr.length() < 3)
283 // return;
284 else
285 {
286 if (!logTable->liveSearch(searchStr))
287 {
288 getMainWindow()->statusBar()->showMessage(
289 "Could not find '" + logTable->getModel()->getCurrentSearchStr() +
290 "' in the log!",
291 5000);
292 ui.btnNextItem->setEnabled(false);
293 ui.btnPreviousItem->setEnabled(false);
294 }
295 else
296 {
297 ui.btnNextItem->setEnabled(true);
298 ui.btnPreviousItem->setEnabled(true);
299 }
300 }
301 }
302
303 void
305 {
306 if (logTable)
307 {
308 logTable->getModel()->clearData();
309 }
310 }
311
312 void
314 {
315 std::map<QString, LogTable*>::iterator it = filterMap.begin();
316
317 for (; it != filterMap.end(); it++)
318 {
319 it->second->getModel()->clearData();
320 }
321
323 }
324
325 void
327 {
328 loggingPaused = pause;
329 }
330
331 LogTable*
333 {
334 LogTable* newLogTable = new LogTable();
335 // newLogTable->setColumns(standardColumns);
336 QTreeWidgetItem* item = new QTreeWidgetItem(ui.lvFilters);
337 QString standardFilterStr = ALL_MESSAGES_FILTER;
338 item->setText(0, standardFilterStr);
339 item->setData(0, USERROLE_LOGTABLEID, standardFilterStr);
340 item->setData(0, USERROLE_BASENAME, standardFilterStr);
341 // item->setData(USERROLE_LOGTABLEPTR, qVariantFromValue((void*)newLogTable));
342 // ui.lvFilters->addItem(item);
343 filterMap[standardFilterStr] = newLogTable;
344 ui.splitter->addWidget(newLogTable);
345
346 return newLogTable;
347 }
348
349 LogTable*
350 LogViewer::addFilter(QString filterId,
351 QString filterName,
352 QString loggingGroup,
353 QString componentFilter,
354 QString tagFilter,
355 MessageType minimumVerbosity,
356 QString messageFilter,
357 QString fileFilter,
358 QString functionFilter)
359 {
360
361 if (filterMap.find(filterId) != filterMap.end())
362 {
363 QString msg = "A filter with the id " + filterId + " exists already";
364 showMessageBox(msg);
365 return NULL;
366 }
367
368 LogTable* newLogTable = new LogTable();
369 newLogTable->hide();
370
371 if (loggingGroup.length())
372 {
374 loggingGroup.toStdString());
375 }
376
377 // newLogTable->setColumns(standardColumns);
378 if (componentFilter.length())
379 {
381 componentFilter.toStdString());
382 }
383
384 if (tagFilter.length())
385 {
386 newLogTable->getModel()->addFilter(ARMARX_LOG_TAGSTR, tagFilter.toStdString());
387 }
388
389 if (messageFilter.length())
390 {
391 newLogTable->getModel()->addFilter(ARMARX_LOG_MESSAGESTR, messageFilter.toStdString());
392 }
393
394 if (fileFilter.length())
395 {
396 newLogTable->getModel()->addFilter(ARMARX_LOG_FILESTR, fileFilter.toStdString());
397 }
398
399 if (functionFilter.length())
400 {
402 functionFilter.toStdString());
403 }
404
406 QString::number(minimumVerbosity).toStdString());
407
408 QTreeWidgetItem* item = new QTreeWidgetItem();
409 item->setText(0, filterName);
410 // item->setData(USERROLE_LOGTABLEPTR, qVariantFromValue((void*)newLogTable));
411 item->setData(0, USERROLE_LOGTABLEID, filterId);
412 item->setData(0, USERROLE_BASENAME, filterName);
413 filterMap[filterId] = newLogTable;
414 Ice::StringSeq children;
415 for (int i = 0; i < ui.lvFilters->invisibleRootItem()->childCount(); i++)
416 {
417 children.push_back(ui.lvFilters->invisibleRootItem()->child(i)->text(0).toStdString());
418 }
419
420 QTreeWidgetItem* grpItem = NULL;
421 auto grpFilterId = loggingGroupNameToFilterName(loggingGroup);
422 for (int i = 0; i < ui.lvFilters->invisibleRootItem()->childCount(); i++)
423 {
424 if (ui.lvFilters->invisibleRootItem()
425 ->child(i)
426 ->data(0, USERROLE_BASENAME)
427 .toString() == grpFilterId)
428 {
429 grpItem = ui.lvFilters->invisibleRootItem()->child(i);
430 break;
431 }
432 }
433 if (grpItem)
434 {
435 grpItem->addChild(item);
436 // items.at(0)->sortChildren(0, Qt::AscendingOrder);
437 }
438 else
439 {
440 // ARMARX_INFO << loggingGroup.toStdString() << " group not found - adding " << filterId.toStdString() << " as toplevel\n" << children;
441 ui.lvFilters->insertTopLevelItem(0, item);
442 // ui.lvFilters->invisibleRootItem()->sortChildren(0, Qt::AscendingOrder);
443 }
444
445 ui.splitter->addWidget(newLogTable);
446 return newLogTable;
447 }
448
449 bool
450 LogViewer::checkAndAddNewFilter(const QString& loggingGroupName, const QString& componentName)
451 {
452 if (componentName.length() == 0 && loggingGroupName.length() == 0)
453 {
454 return false;
455 }
456
457 if (!ui.cbAutoComponentFilters->isChecked())
458 {
459 return false;
460 }
461 QString filler = (loggingGroupName.length() > 0 && componentName.length() > 0) ? "_" : "";
462 auto filterId = loggingGroupNameToFilterName(loggingGroupName) + filler + componentName;
463 auto filterName = componentName.length() > 0
464 ? componentName
465 : loggingGroupNameToFilterName(loggingGroupName);
466 ARMARX_CHECK_EXPRESSION(!filterName.isEmpty());
467 if (filterMap.count(filterId))
468 {
469 return false;
470 }
471
472 addFilter(filterId, filterName, loggingGroupName, componentName, "", eDEBUG, "", "", "");
473 return true;
474 }
475
476 void
478 {
479 FilterDialog filterDialog;
480
481 if (!filterDialog.exec())
482 {
483 return;
484 }
485
486 QString filterName = filterDialog.ui->edtFilterName->text();
487
488 if (filterMap.find(filterName) != filterMap.end())
489 {
490 QString msg = "A filter with this name already exists";
491 showMessageBox(msg);
492 return;
493 }
494
495 LogTable* newLogTable = new LogTable();
496 newLogTable->hide();
497
498 // newLogTable->setColumns(standardColumns);
499 if (filterDialog.ui->editComponent->text().length())
500 {
501 newLogTable->getModel()->addFilter(
502 ARMARX_LOG_COMPONENTSTR, filterDialog.ui->editComponent->text().toStdString());
503 }
504
505 if (filterDialog.ui->edtTag->text().length())
506 {
507 newLogTable->getModel()->addFilter(ARMARX_LOG_TAGSTR,
508 filterDialog.ui->edtTag->text().toStdString());
509 }
510
511 if (filterDialog.ui->edtMessage->text().length())
512 {
514 filterDialog.ui->edtMessage->text().toStdString());
515 }
516
517 if (filterDialog.ui->edtFile->text().length())
518 {
519 newLogTable->getModel()->addFilter(ARMARX_LOG_FILESTR,
520 filterDialog.ui->edtFile->text().toStdString());
521 }
522
523 if (filterDialog.ui->edtFunction->text().length())
524 {
526 filterDialog.ui->edtFunction->text().toStdString());
527 }
528
529 if (filterDialog.ui->cbVerbosity->currentIndex() != -1)
530 {
531 newLogTable->getModel()->addFilter(
533 QString::number(filterDialog.ui->cbVerbosity->currentIndex()).toStdString());
534 }
535
536 QTreeWidgetItem* item = new QTreeWidgetItem();
537 item->setText(0, filterName);
538 // item->setData(USERROLE_LOGTABLEPTR, qVariantFromValue((void*)newLogTable));
539 item->setData(0, USERROLE_LOGTABLEID, filterName);
540 item->setData(0, USERROLE_BASENAME, filterName);
541 filterMap[filterName] = newLogTable;
542 ui.lvFilters->insertTopLevelItem(ui.lvFilters->invisibleRootItem()->childCount(), item);
543 // ui.lvFilters->invisibleRootItem()->sortChildren(0, Qt::AscendingOrder);
544 ui.splitter->addWidget(newLogTable);
545 }
546
547 void
548 LogViewer::editFilter(QTreeWidgetItem* item, int column)
549 {
550 QString filterId = item->data(0, USERROLE_LOGTABLEID).toString();
551 FilterDialog filterDialog;
552 filterDialog.ui->edtFilterName->setText(item->data(0, USERROLE_BASENAME).toString());
553
554 if (filterMap.find(filterId) == filterMap.end())
555 {
556 ARMARX_WARNING << "filter " << filterId.toStdString() << " does not exist" << flush;
557 return;
558 }
559
560 LogTable* logTable = filterMap.find(filterId)->second;
561
562 if (!logTable)
563 {
564 ARMARX_WARNING << "logtable ptr is NULL " << flush;
565 return;
566 }
567
568 for (unsigned int i = 0; i < logTable->getModel()->getFilters().size(); i++)
569 {
570 std::string columnName = logTable->getModel()->getFilters()[i].first;
571 std::string filter = logTable->getModel()->getFilters()[i].second;
572
573 if (columnName == ARMARX_LOG_COMPONENTSTR)
574 {
575 filterDialog.ui->editComponent->setText(filter.c_str());
576 }
577 else if (columnName == ARMARX_LOG_TAGSTR)
578 {
579 filterDialog.ui->edtTag->setText(filter.c_str());
580 }
581 else if (columnName == ARMARX_LOG_VERBOSITYSTR)
582 {
583
584 filterDialog.ui->cbVerbosity->setCurrentIndex(QString(filter.c_str()).toInt());
585 }
586 else if (columnName == ARMARX_LOG_MESSAGESTR)
587 {
588 filterDialog.ui->edtMessage->setText(filter.c_str());
589 }
590 else if (columnName == ARMARX_LOG_FILESTR)
591 {
592 filterDialog.ui->edtFile->setText(filter.c_str());
593 }
594 else if (columnName == ARMARX_LOG_FUNCTIONSTR)
595 {
596 filterDialog.ui->edtFunction->setText(filter.c_str());
597 }
598 }
599
600
601 if (!filterDialog.exec())
602 {
603 return;
604 }
605 item->setText(0, filterDialog.ui->edtFilterName->text());
606 item->setData(0, USERROLE_BASENAME, filterDialog.ui->edtFilterName->text());
607 logTable->getModel()->resetFilters();
608
609 if (filterDialog.ui->editComponent->text().length())
610 {
611 logTable->getModel()->addFilter(ARMARX_LOG_COMPONENTSTR,
612 filterDialog.ui->editComponent->text().toStdString());
613 }
614
615 if (filterDialog.ui->edtTag->text().length())
616 {
617 logTable->getModel()->addFilter(ARMARX_LOG_TAGSTR,
618 filterDialog.ui->edtTag->text().toStdString());
619 }
620
621 if (filterDialog.ui->edtMessage->text().length())
622 {
623 logTable->getModel()->addFilter(ARMARX_LOG_MESSAGESTR,
624 filterDialog.ui->edtMessage->text().toStdString());
625 }
626
627 if (filterDialog.ui->edtFile->text().length())
628 {
629 logTable->getModel()->addFilter(ARMARX_LOG_FILESTR,
630 filterDialog.ui->edtFile->text().toStdString());
631 }
632
633 if (filterDialog.ui->edtFunction->text().length())
634 {
635 logTable->getModel()->addFilter(ARMARX_LOG_FUNCTIONSTR,
636 filterDialog.ui->edtFunction->text().toStdString());
637 }
638
639 if (filterDialog.ui->cbVerbosity->currentIndex() != -1)
640 {
641 logTable->getModel()->addFilter(
643 QString::number(filterDialog.ui->cbVerbosity->currentIndex()).toStdString());
644 }
645
646 logTable->getModel()->reapplyAllFilters();
647 logTable->update();
648 }
649
650 void
652 {
653 if (ui.lvFilters->invisibleRootItem()->childCount() == 1)
654 {
655 return;
656 }
657
658 auto item = ui.lvFilters->currentItem();
659 removeFilter(item);
660 }
661
662 void
663 LogViewer::removeFilter(QTreeWidgetItem* item)
664 {
665 if (!item)
666 {
667 return;
668 }
669
670 std::map<QString, LogTable*>::iterator it =
671 filterMap.find(item->data(0, USERROLE_LOGTABLEID).toString());
672
673 if (it == filterMap.end())
674 {
675 return;
676 }
677 QList<QTreeWidgetItem*> itemsToDelete, iterationList({item});
678 while (!iterationList.isEmpty())
679 {
680 auto curItem = iterationList.front();
681 itemsToDelete << curItem;
682 iterationList.pop_front();
683 iterationList << curItem->takeChildren();
684 }
685 ui.lvFilters->setCurrentItem(ui.lvFilters->invisibleRootItem()->child(0));
686 for (auto& item : itemsToDelete)
687 {
688 auto parent = item->parent();
689 if (parent)
690 {
691 parent->removeChild(item);
692 }
693 else
694 {
695 ui.lvFilters->invisibleRootItem()->removeChild(item);
696 }
697 std::map<QString, LogTable*>::iterator it =
698 filterMap.find(item->data(0, USERROLE_LOGTABLEID).toString());
699 delete item;
700
701 if (it == filterMap.end())
702 {
703 continue;
704 }
705 LogTable* logTable = it->second;
706 delete logTable;
707 filterMap.erase(it);
708 }
709 }
710
711 void
712 LogViewer::filterSelectionChanged(QTreeWidgetItem* item, QTreeWidgetItem* previous)
713 {
714 if (!item)
715 {
716 return;
717 }
718 LogTable* oldLogTable = logTable;
719 QString filterId = item->data(0, USERROLE_LOGTABLEID).toString();
720 // item->setText(0, filterId); Why?
721 QFont font;
722 font.setBold(false);
723 item->setFont(0, font);
724
725 if (filterMap.find(filterId) == filterMap.end())
726 {
727 showMessageBox("Filtername " + filterId + " not found.");
728 return;
729 }
730
731 logTable = filterMap[filterId];
732
733 if (!logTable)
734 {
735 ARMARX_ERROR << "logTable ptr is NULL" << flush;
736 return;
737 }
738
739
740 if (oldLogTable)
741 {
742 oldLogTable->hide();
743 }
744
745 logTable->show();
746 ui.edtLiveFilter->setText(logTable->getLiveFilterStr());
747 ui.edtLiveSearch->setText(logTable->getModel()->getCurrentSearchStr());
748 }
749
750 void
752 {
753 static QFont font;
754 QList<QTreeWidgetItem*> itemsToUpdate, iterationList({ui.lvFilters->invisibleRootItem()});
755 while (!iterationList.isEmpty())
756 {
757 auto curItem = iterationList.front();
758 itemsToUpdate << curItem;
759 iterationList.pop_front();
760 for (int i = 0; i < curItem->childCount(); ++i)
761 {
762 iterationList << curItem->child(i);
763 }
764 }
765 // Update new message count in filter list box
766 for (auto item : itemsToUpdate)
767 {
768 auto filterId = item->data(0, USERROLE_LOGTABLEID).toString();
769 LogTable* curLogtable = filterMap.find(filterId)->second;
770 if (!curLogtable)
771 {
772 continue;
773 }
774 QString newContent;
775
776 if (curLogtable == logTable || curLogtable->getNewMessageCount() == 0)
777 {
778 font.setBold(false);
779 item->setFont(0, font);
780 newContent = item->data(0, USERROLE_BASENAME).toString();
781 item->setBackgroundColor(0, ui.lvFilters->palette().base().color());
782 }
783 else
784 {
785 font.setBold(true);
786 item->setFont(0, font);
787 newContent = item->data(0, USERROLE_BASENAME).toString() + "(" +
788 QString::number(curLogtable->getNewMessageCount()) + ")";
789
790 if (curLogtable->getMaxNewLogLevelType() == eWARN)
791 {
792 item->setBackgroundColor(0, QColor(216, 120, 50));
793 }
794 else if (curLogtable->getMaxNewLogLevelType() == eERROR)
795 {
796 item->setBackgroundColor(0, QColor(255, 90, 80));
797 }
798 else if (curLogtable->getMaxNewLogLevelType() == eFATAL)
799 {
800 item->setBackgroundColor(0, QColor(255, 60, 50));
801 }
802 else
803 {
804 item->setBackgroundColor(0, ui.lvFilters->palette().base().color());
805 }
806 }
807
808 item->setText(0, newContent);
809 item->setToolTip(0, newContent);
810 }
811 }
812
813 void
815 {
816 throw LocalException() << "Not yet implemented";
817 }
818
819 void
821 {
822
823 if (getState() >= eManagedIceObjectExiting)
824 {
825 return;
826 }
827
828 std::vector<LogMessage> pendingEntriesTemp;
829 {
830 std::unique_lock lock(pendingEntriesMutex);
831 pendingEntriesTemp.swap(pendingEntries);
832 }
833
834
835 unsigned int size = pendingEntriesTemp.size();
836 boost::regex re(REGEX_COLORS);
837 // check for new components, that are sending log messages and perform auto scroll
838 for (unsigned int i = 0; i < size; i++)
839 {
840 LogMessage& msg = pendingEntriesTemp[i];
841 msg.what = boost::regex_replace(msg.what, re, "");
842
843 if (!getWidget() || ui.cbVerbosityLevel->currentIndex() > msg.type)
844 {
845 continue;
846 }
847 checkAndAddNewFilter(msg.group.c_str(), "");
848 checkAndAddNewFilter(msg.group.c_str(), msg.who.c_str());
849
850 std::map<QString, LogTable*>::iterator it = filterMap.begin();
851
852 for (; it != filterMap.end(); ++it)
853 {
854 LogTable* log = it->second;
855
856 if (!log)
857 {
858 std::cerr << "log ptr is NULL" << std::endl;
859 return;
860 }
861
862 //setRow(msg, currentRow);
863 bool autoScroll = false;
864
865 if (log->verticalScrollBar()->value() == log->verticalScrollBar()->maximum())
866 {
867 autoScroll = true;
868 }
869
870 //int row = log->addEntry(msg);
871
872 if (autoScroll)
873 {
874 log->scrollToBottom();
875 }
876
877 //dynamic_cast<LogTableModel*> (logTable->model())->updateView();
878 }
879 }
880
881 bool autoScroll = false;
882
883 if (logTable->verticalScrollBar()->value() == logTable->verticalScrollBar()->maximum())
884 {
885 autoScroll = true;
886 }
887
888 std::map<QString, LogTable*>::iterator it = filterMap.begin();
889
890 for (; it != filterMap.end(); ++it)
891 {
892 LogTable* log = it->second;
893 int row = log->getModel()->rowCount();
894 int rowsAdded =
895 log->getModel()->addEntries(pendingEntriesTemp, log->getCurrentLiveFilter());
896 if (rowsAdded > 0)
897 {
898 int count = log->getModel()->rowCount();
899 int r;
900 for (r = row; r < count; r++)
901 {
902 log->liveFilterRow(log->getCurrentLiveFilter(), r);
903 }
904 }
905 bool autoScroll = false;
906
907 if (log->verticalScrollBar()->value() == log->verticalScrollBar()->maximum())
908 {
909 autoScroll = true;
910 }
911
912
913 if (autoScroll)
914 {
915 log->scrollToBottom();
916 }
917 }
918
919
920 if (autoScroll)
921 {
922 logTable->scrollToBottom();
923 }
924
926 }
927
928 void
930 {
931 if (index == 0)
932 {
933 ui.edtLiveSearch->show();
934 ui.btnPreviousItem->show();
935 ui.btnNextItem->show();
936 ui.edtLiveFilter->hide();
937 }
938 else
939 {
940 ui.edtLiveSearch->hide();
941 ui.btnPreviousItem->hide();
942 ui.btnNextItem->hide();
943 ui.edtLiveFilter->show();
944 }
945 }
946
947 void
949 {
950
951 if (logTable)
952 {
953 if (!logTable->selectNextSearchResult(false))
954 {
955 getMainWindow()->statusBar()->showMessage(
956 "Could not find '" + logTable->getModel()->getCurrentSearchStr() +
957 "' in the log!",
958 5000);
959 }
960 }
961 }
962
963 void
965 {
966 if (logTable)
967 if (!logTable->selectNextSearchResult(true))
968 {
969 getMainWindow()->statusBar()->showMessage(
970 "Could not find '" + logTable->getModel()->getCurrentSearchStr() +
971 "' in the log!",
972 5000);
973 }
974 }
975
976 QPointer<QWidget>
978 {
979 if (customToolbar)
980 {
981 if (parent != customToolbar->parent())
982 {
983 customToolbar->setParent(parent);
984 }
985
986 return customToolbar;
987 }
988
989 customToolbar = new QToolBar(parent);
990 customToolbar->setIconSize(QSize(16, 16));
991 customToolbar->addAction(
992 QIcon(":/icons/configure-3.png"), "Configure", this, SLOT(OpenConfigureDialog()));
993
994 return customToolbar;
995 }
996} // namespace armarx
uint8_t index
#define ARMARX_LOG_VERBOSITYSTR
Definition LogTable.h:43
#define ARMARX_LOG_COMPONENTSTR
Definition LogTable.h:41
#define ARMARX_LOG_FILESTR
Definition LogTable.h:45
#define ARMARX_LOG_TAGSTR
Definition LogTable.h:42
#define ARMARX_LOG_MESSAGESTR
Definition LogTable.h:44
#define ARMARX_LOG_LOGGINGGROUPSTR
Definition LogTable.h:47
#define ARMARX_LOG_FUNCTIONSTR
Definition LogTable.h:46
#define USERROLE_BASENAME
Definition LogViewer.cpp:49
#define ALL_MESSAGES_FILTER
Definition LogViewer.cpp:51
#define USERROLE_LOGTABLEID
Definition LogViewer.cpp:47
#define REGEX_COLORS
Definition LogViewer.cpp:50
bool onClose() override
If you overwrite this method, make sure to call this implementation at the end of your implementation...
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
virtual QMainWindow * getMainWindow()
Returns the ArmarX MainWindow.
static int showMessageBox(const QString &msg)
Ui::FilterDialog * ui
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()
Definition LogTable.h:80
void liveFilterRow(const QString &filterStr, int row)
Definition LogTable.cpp:121
LogTableModel * getModel()
Definition LogTable.cpp:234
QString getCurrentLiveFilter() const
Definition LogTable.cpp:115
int getNewMessageCount()
Definition LogTable.h:74
void pauseLogging(bool pause=false)
LogTable * logTable
Definition LogViewer.h:149
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)
Ui_LogViewer ui
Definition LogViewer.h:148
void OpenConfigureDialog()
~LogViewer() override
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.
Definition Logging.h:196
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
This file offers overloads of toIce() and fromIce() functions for STL container types.
const LogSender::manipulator flush
Definition LogSender.h:251
MessageTypeT
Definition LogSender.h:46