diff --git a/qdlt/CMakeLists.txt b/qdlt/CMakeLists.txt index 80fa297d..2c0ac5e3 100644 --- a/qdlt/CMakeLists.txt +++ b/qdlt/CMakeLists.txt @@ -41,7 +41,8 @@ add_library(qdlt SHARED qdltimporter.cpp fieldnames.cpp dltmessagematcher.cpp - dltmessagematcher.h) + dltmessagematcher.h + qdltlrucache.hpp) target_compile_definitions(qdlt PRIVATE BYTE_ORDER=LITTLE_ENDIAN diff --git a/qdlt/qdltfile.cpp b/qdlt/qdltfile.cpp index 1b97144e..9d9a8359 100644 --- a/qdlt/qdltfile.cpp +++ b/qdlt/qdltfile.cpp @@ -487,7 +487,7 @@ void QDltFile::addFilterIndex (int index) } #ifdef USECOLOR - QColor QDltFile::checkMarker(QDltMsg &msg) + QColor QDltFile::checkMarker(const QDltMsg &msg) { if(!filterFlag) { @@ -498,7 +498,7 @@ void QDltFile::addFilterIndex (int index) } #else - QString QDltFile::checkMarker(QDltMsg &msg) + QString QDltFile::checkMarker(const QDltMsg &msg) { if(!filterFlag) { diff --git a/qdlt/qdltfile.h b/qdlt/qdltfile.h index c07963d8..0ed7dae7 100644 --- a/qdlt/qdltfile.h +++ b/qdlt/qdltfile.h @@ -252,9 +252,9 @@ class QDLT_EXPORT QDltFile : public QDlt \return 0 if message will not be marked, colour if message will be marked */ #ifdef USECOLOR - QColor checkMarker(QDltMsg &msg); + QColor checkMarker(const QDltMsg &msg); #else - QString checkMarker(QDltMsg &msg); + QString checkMarker(const QDltMsg &msg); #endif //! Get file name of the underlying file object diff --git a/qdlt/qdltfilter.cpp b/qdlt/qdltfilter.cpp index 77e25fcb..aa25a26a 100644 --- a/qdlt/qdltfilter.cpp +++ b/qdlt/qdltfilter.cpp @@ -161,7 +161,7 @@ bool QDltFilter::compileRegexps() appidRegularExpression.isValid()); } -bool QDltFilter::match(QDltMsg &msg) const +bool QDltFilter::match(const QDltMsg &msg) const { if( (true == enableEcuid) && (msg.getEcuid() != ecuid)) diff --git a/qdlt/qdltfilter.h b/qdlt/qdltfilter.h index 7cff7a66..ccf4f11b 100644 --- a/qdlt/qdltfilter.h +++ b/qdlt/qdltfilter.h @@ -130,7 +130,7 @@ class QDLT_EXPORT QDltFilter /*! \return true if filter matches the message, else false */ - bool match(QDltMsg &msg) const; + bool match(const QDltMsg &msg) const; //! Save filter parameters in XML file. /*! diff --git a/qdlt/qdltfilterlist.cpp b/qdlt/qdltfilterlist.cpp index 0152585c..00a0da76 100644 --- a/qdlt/qdltfilterlist.cpp +++ b/qdlt/qdltfilterlist.cpp @@ -86,7 +86,7 @@ void QDltFilterList::addFilter(QDltFilter *_filter) #ifdef USECOLOR -QColor QDltFilterList::checkMarker(QDltMsg &msg) +QColor QDltFilterList::checkMarker(const QDltMsg &msg) { QDltFilter *filter; QColor color; @@ -104,7 +104,7 @@ QColor QDltFilterList::checkMarker(QDltMsg &msg) return color; } #else -QString QDltFilterList::checkMarker(QDltMsg &msg) +QString QDltFilterList::checkMarker(const QDltMsg &msg) { QDltFilter *filter; QString color=""; // invalid colour diff --git a/qdlt/qdltfilterlist.h b/qdlt/qdltfilterlist.h index 8d250b53..fe5bb9c7 100644 --- a/qdlt/qdltfilterlist.h +++ b/qdlt/qdltfilterlist.h @@ -83,9 +83,9 @@ class QDLT_EXPORT QDltFilterList \return 0 if message will not be marked, colour if message will be marked */ #ifdef USECOLOR - QColor checkMarker(QDltMsg &msg); + QColor checkMarker(const QDltMsg &msg); #else - QString checkMarker(QDltMsg &msg); + QString checkMarker(const QDltMsg &msg); #endif diff --git a/qdlt/qdltlrucache.hpp b/qdlt/qdltlrucache.hpp new file mode 100644 index 00000000..cf34659e --- /dev/null +++ b/qdlt/qdltlrucache.hpp @@ -0,0 +1,59 @@ +#ifndef QDLTLRUCACHE_HPP +#define QDLTLRUCACHE_HPP + +#include +#include +#include + +template +class QDltLruCache { + + struct CacheEntry { + Key key; + Value value; + }; + + using CacheListIterator = typename std::list::iterator; +public: + + QDltLruCache(size_t capacity) : + m_capacity(capacity) { + } + + void put(const Key& key, const Value& value) { + auto it = m_keyIteratorsMap.find(key); + m_cacheItems.push_front(CacheEntry{key, value}); + if (it != m_keyIteratorsMap.end()) { + m_cacheItems.erase(it->second); + m_keyIteratorsMap.erase(it); + } + m_keyIteratorsMap[key] = m_cacheItems.begin(); + + if (m_keyIteratorsMap.size() > m_capacity) { + auto last = std::prev(m_cacheItems.end()); + m_keyIteratorsMap.erase(last->key); + m_cacheItems.pop_back(); + } + } + + const Value& get(const Key& key) { + auto it = m_keyIteratorsMap.find(key); + if (it == m_keyIteratorsMap.end()) { + throw std::range_error("no such key in cache found"); + } + + m_cacheItems.splice(m_cacheItems.begin(), m_cacheItems, it->second); + return it->second->value; + } + + bool exists(const Key& key) const { + return m_keyIteratorsMap.find(key) != m_keyIteratorsMap.end(); + } + +private: + std::list m_cacheItems; + std::unordered_map m_keyIteratorsMap; + const size_t m_capacity; +}; + +#endif // QDLTLRUCACHE_HPP diff --git a/src/dlttableview.cpp b/src/dlttableview.cpp index 9e272a81..cda392b8 100644 --- a/src/dlttableview.cpp +++ b/src/dlttableview.cpp @@ -1,5 +1,8 @@ #include "dlttableview.h" +#include +#include + DltTableView::DltTableView(QWidget *parent) : QTableView(parent) { @@ -17,6 +20,15 @@ void DltTableView::paintEvent(QPaintEvent *event) } } +void DltTableView::wheelEvent(QWheelEvent *event) +{ + if (event->modifiers().testFlag(Qt::ControlModifier)) { + auto val = event->angleDelta().y(); + emit changeFontSize((0 < val) - (val < 0)); + event->accept(); + } +} + void DltTableView::lock() { paintMutex.lock(); diff --git a/src/dlttableview.h b/src/dlttableview.h index 1adc7458..022c1413 100644 --- a/src/dlttableview.h +++ b/src/dlttableview.h @@ -17,11 +17,15 @@ class DltTableView : public QTableView explicit DltTableView(QWidget *parent = 0); void lock(); void unlock(); + +signals: + void changeFontSize(int delta); private: QMutex paintMutex; protected: - void paintEvent(QPaintEvent *e); + void paintEvent(QPaintEvent *e) override; + void wheelEvent(QWheelEvent *event) override; signals: diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c1cf64c3..9af503d4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -608,6 +608,15 @@ void MainWindow::initSignalConnections() ui->exploreView->scrollTo( proxyModel->mapFromSource(fsModel->index(recentFiles[0]))); }); + + connect(ui->tableView, &DltTableView::changeFontSize, this, [this](int direction){ + QFont font; + font.fromString(settings->fontName); + int fontSize = font.pointSize() + direction; + font.setPointSize(fontSize); + settings->fontName = font.toString(); + ui->tableView->setFont(font); + }); } void MainWindow::initSearchTable() @@ -2066,6 +2075,7 @@ void MainWindow::reloadLogFileFinishFilter() QList list = dltIndexer->getGetLogInfoList(); QDltMsg msg; + // FIXME: this is slow operation running in the main loop for(int num=0;numreset(); statusProgressBar->hide(); - } void MainWindow::reloadLogFileFinishDefaultFilter() diff --git a/src/mainwindow.h b/src/mainwindow.h index de79fb22..a6121bb4 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -382,10 +382,10 @@ class MainWindow : public QMainWindow void writeDLTMessageToFile(QByteArray &bufferHeader,char*bufferPayload,quint32 bufferPayloadSize,EcuItem* ecuitem,quint32 sec=0,quint32 use=0); protected: - void keyPressEvent ( QKeyEvent * event ); - void dragEnterEvent(QDragEnterEvent *event); - void dropEvent(QDropEvent *event); - void closeEvent(QCloseEvent *event); + void keyPressEvent ( QKeyEvent * event ) override; + void dragEnterEvent(QDragEnterEvent *event) override; + void dropEvent(QDropEvent *event) override; + void closeEvent(QCloseEvent *event) override; private slots: void reloadLogFileProgressMax(int num); diff --git a/src/tablemodel.cpp b/src/tablemodel.cpp index d132fbcb..2164ce69 100644 --- a/src/tablemodel.cpp +++ b/src/tablemodel.cpp @@ -27,31 +27,6 @@ #include "dlt_protocol.h" #include "qdltoptmanager.h" -static long int lastrow = -1; // necessary because object tablemodel can not be changed, so no member variable can be used - -void getmessage( int indexrow, long int filterposindex, unsigned int* decodeflag, QDltMsg* msg, QDltMsg* lastmsg, QDltFile* qfile, bool* success ) -{ - if ( indexrow == lastrow) - { - *msg = *lastmsg; - } - else - { - *success = qfile->getMsg(filterposindex, *msg); - *lastmsg = *msg; - *decodeflag = 1; - } - if ( indexrow == 0) - { - lastrow = 0; - } - else - { - lastrow = indexrow; - } -} - - TableModel::TableModel(const QString & /*data*/, QObject *parent) : QAbstractTableModel(parent) { @@ -62,7 +37,6 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) emptyForceFlag = false; loggingOnlyMode = false; searchhit = -1; - lastrow = -1; } TableModel::~TableModel() @@ -78,17 +52,7 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) QVariant TableModel::data(const QModelIndex &index, int role) const { - QByteArray buf; - static QDltMsg msg; - static QDltMsg lastmsg; - static QDltMsg last_decoded_msg; - static unsigned int decodeflag = 0; - static bool success = true; - - long int filterposindex = 0; - - - if (index.isValid() == false) + if (!index.isValid()) { return QVariant(); } @@ -105,13 +69,31 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) return QVariant(); } - filterposindex = qfile->getMsgFilterPos(index.row()); + if (role == Qt::TextAlignmentRole) + { + return FieldNames::getColumnAlignment((FieldNames::Fields)index.column(),project->settings); + } + + long int filterposindex = qfile->getMsgFilterPos(index.row()); + + std::optional msg; + if (m_cache.exists(index.row())) { + msg = m_cache.get(index.row()); + } else { + QDltMsg omsg; + if (bool success = qfile->getMsg(filterposindex, omsg); success) { + msg = std::make_optional(omsg); + if (QDltSettingsManager::getInstance()->value("startup/pluginsEnabled", true).toBool()) { + pluginManager->decodeMsg(*msg, !QDltOptManager::getInstance()->issilentMode()); + } + } + + m_cache.put(index.row(), msg); + } if (role == Qt::DisplayRole) { - - getmessage( index.row(), filterposindex, &decodeflag, &msg, &lastmsg, qfile, &success); - if ( success == false ) + if (!msg.has_value()) { if(index.column() == FieldNames::Index) { @@ -125,21 +107,6 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) return QVariant(); } - if((QDltSettingsManager::getInstance()->value("startup/pluginsEnabled", true).toBool())) - { - if ( decodeflag == 1 ) - { - decodeflag = 0; - last_decoded_msg = msg; - pluginManager->decodeMsg(msg,!QDltOptManager::getInstance()->issilentMode()); - last_decoded_msg = msg; - } - else - { - msg = last_decoded_msg; - } - } - QString visu_data; switch(index.column()) { @@ -148,20 +115,20 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) return QString("%L1").arg(qfile->getMsgFilterPos(index.row())); case FieldNames::Time: if( project->settings->automaticTimeSettings == 0 ) - return QString("%1.%2").arg(msg.getGmTimeWithOffsetString(project->settings->utcOffset,project->settings->dst)).arg(msg.getMicroseconds(),6,10,QLatin1Char('0')); + return QString("%1.%2").arg(msg->getGmTimeWithOffsetString(project->settings->utcOffset,project->settings->dst)).arg(msg->getMicroseconds(),6,10,QLatin1Char('0')); else - return QString("%1.%2").arg(msg.getTimeString()).arg(msg.getMicroseconds(),6,10,QLatin1Char('0')); + return QString("%1.%2").arg(msg->getTimeString()).arg(msg->getMicroseconds(),6,10,QLatin1Char('0')); case FieldNames::TimeStamp: - return QString("%1.%2").arg(msg.getTimestamp()/10000).arg(msg.getTimestamp()%10000,4,10,QLatin1Char('0')); + return QString("%1.%2").arg(msg->getTimestamp()/10000).arg(msg->getTimestamp()%10000,4,10,QLatin1Char('0')); case FieldNames::Counter: - return QString("%1").arg(msg.getMessageCounter()); + return QString("%1").arg(msg->getMessageCounter()); case FieldNames::EcuId: - return msg.getEcuid(); + return msg->getEcuid(); case FieldNames::AppId: switch(project->settings->showApIdDesc) { case 0: - return msg.getApid(); + return msg->getApid(); break; case 1: for(int num = 0; num < project->ecu->topLevelItemCount (); num++) @@ -170,22 +137,22 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) for(int numapp = 0; numapp < ecuitem->childCount(); numapp++) { ApplicationItem * appitem = (ApplicationItem *) ecuitem->child(numapp); - if(appitem->id == msg.getApid() && !appitem->description.isEmpty()) + if(appitem->id == msg->getApid() && !appitem->description.isEmpty()) { return appitem->description; } } } - return QString("Apid: %1 (No description)").arg(msg.getApid()); + return QString("Apid: %1 (No description)").arg(msg->getApid()); break; default: - return msg.getApid(); + return msg->getApid(); } case FieldNames::ContextId: switch(project->settings->showCtIdDesc) { case 0: - return msg.getCtid(); + return msg->getCtid(); break; case 1: for(int num = 0; num < project->ecu->topLevelItemCount (); num++) @@ -198,7 +165,7 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) { ContextItem * conitem = (ContextItem *) appitem->child(numcontext); - if(appitem->id == msg.getApid() && conitem->id == msg.getCtid() + if(appitem->id == msg->getApid() && conitem->id == msg->getCtid() && !conitem->description.isEmpty()) { return conitem->description; @@ -206,41 +173,41 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) } } } - return QString("Ctid: %1 (No description)").arg(msg.getCtid()); + return QString("Ctid: %1 (No description)").arg(msg->getCtid()); break; default: - return msg.getCtid(); + return msg->getCtid(); } case FieldNames::SessionId: switch(project->settings->showSessionName){ case 0: - return QString("%1").arg(msg.getSessionid()); + return QString("%1").arg(msg->getSessionid()); break; case 1: - if(!msg.getSessionName().isEmpty()) + if(!msg->getSessionName().isEmpty()) { - return msg.getSessionName(); + return msg->getSessionName(); } else { - return QString("%1").arg(msg.getSessionid()); + return QString("%1").arg(msg->getSessionid()); } break; default: - return QString("%1").arg(msg.getSessionid()); + return QString("%1").arg(msg->getSessionid()); } case FieldNames::Type: - return msg.getTypeString(); + return msg->getTypeString(); case FieldNames::Subtype: - return msg.getSubtypeString(); + return msg->getSubtypeString(); case FieldNames::Mode: - return msg.getModeString(); + return msg->getModeString(); case FieldNames::ArgCount: - return QString("%1").arg(msg.getNumberOfArguments()); + return QString("%1").arg(msg->getNumberOfArguments()); case FieldNames::Payload: /* display payload */ - visu_data = msg.toStringPayload().simplified().remove(QChar::Null); - if(qfile) qfile->applyRegExString(msg,visu_data); + visu_data = msg->toStringPayload().simplified().remove(QChar::Null); + if(qfile) qfile->applyRegExString(*msg,visu_data); /*if((QDltSettingsManager::getInstance()->value("startup/filtersEnabled", true).toBool())) { for(int num = 0; num < project->filter->topLevelItemCount (); num++) { @@ -259,13 +226,13 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) return visu_data; case FieldNames::MessageId: - return QString::asprintf(project->settings->msgIdFormat.toUtf8() ,msg.getMessageId()); + return QString::asprintf(project->settings->msgIdFormat.toUtf8(), msg->getMessageId()); default: if (index.column()>=FieldNames::Arg0) { int col=index.column()-FieldNames::Arg0; //arguments a zero based QDltArgument arg; - if (msg.getArgument(col,arg)) + if (msg->getArgument(col,arg)) { return arg.toString(); } @@ -280,88 +247,24 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) if ( role == Qt::ForegroundRole ) { - /* get message at current row */ - getmessage( index.row(), filterposindex, &decodeflag, &msg, &lastmsg, qfile, &success); // version2 - - /* decode message if not already decoded */ - if((QDltSettingsManager::getInstance()->value("startup/pluginsEnabled", true).toBool())) - { - if ( decodeflag == 1 ) - { - decodeflag = 0; - last_decoded_msg = msg; - pluginManager->decodeMsg(msg,!QDltOptManager::getInstance()->issilentMode()); - last_decoded_msg = msg; - } - else - { - msg = last_decoded_msg; - } - } - - /* Calculate background color and find optimal forground color */ - return QVariant(QBrush(DltUiUtils::optimalTextColor(getMsgBackgroundColor(msg,index.row(),filterposindex)))); + /* Calculate background color and find optimal foreground color */ + return QBrush(DltUiUtils::optimalTextColor(getMsgBackgroundColor(msg, index.row(),filterposindex))); } if ( role == Qt::BackgroundRole ) { - /* get message at current row */ - getmessage( index.row(), filterposindex, &decodeflag, &msg, &lastmsg, qfile, &success); // version2 - - /* decode message if not already decoded */ - if((QDltSettingsManager::getInstance()->value("startup/pluginsEnabled", true).toBool())) - { - if ( decodeflag == 1 ) - { - decodeflag = 0; - last_decoded_msg = msg; - pluginManager->decodeMsg(msg,!QDltOptManager::getInstance()->issilentMode()); - last_decoded_msg = msg; - } - else - { - msg = last_decoded_msg; - } - } - /* Calculate background color */ - return QVariant(QBrush(getMsgBackgroundColor(msg,index.row(),filterposindex))); + return QBrush(getMsgBackgroundColor(msg, index.row(),filterposindex)); } - if ( role == Qt::TextAlignmentRole ) - { - /*switch(index.column()) - { - //case FieldNames::Index: return QVariant(Qt::AlignRight | Qt::AlignVCenter); - default: - - }*/ - return FieldNames::getColumnAlignment((FieldNames::Fields)index.column(),project->settings); - } - if ( role == Qt::ToolTipRole ) { - getmessage( index.row(), filterposindex, &decodeflag, &msg, &lastmsg, qfile, &success); - if ( success == false ) + if (!msg.has_value()) { return QString("!!CORRUPTED MESSAGE!!"); } - if((QDltSettingsManager::getInstance()->value("startup/pluginsEnabled", true).toBool())) - { - if ( decodeflag == 1 ) - { - decodeflag = 0; - last_decoded_msg = msg; - pluginManager->decodeMsg(msg,!QDltOptManager::getInstance()->issilentMode()); - last_decoded_msg = msg; - } - else - { - msg = last_decoded_msg; - } - } - QString visu_data = msg.toStringPayload().simplified().remove(QChar::Null); + QString visu_data = msg->toStringPayload().simplified().remove(QChar::Null); if((QDltSettingsManager::getInstance()->value("startup/filtersEnabled", true).toBool())) { for(int num = 0; num < project->filter->topLevelItemCount (); num++) { @@ -428,7 +331,6 @@ QVariant TableModel::headerData(int section, Qt::Orientation orientation, index(0, 0); index(0, columnCount() - 1); } - lastrow = -1; /* last search index must be deleted because model changed */ lastSearchIndex = -1; @@ -497,7 +399,7 @@ QSize HtmlDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInd return QSize(doc.idealWidth(), doc.size().height()); } -QColor TableModel::getMsgBackgroundColor(QDltMsg &msg,int index,long int filterposindex) const +QColor TableModel::getMsgBackgroundColor(const std::optional& msg, int index, long int filterposindex) const { /* first check manual markers with highest priority */ if ( selectedMarkerRows.contains(index) ) @@ -505,40 +407,43 @@ QColor TableModel::getMsgBackgroundColor(QDltMsg &msg,int index,long int filterp return manualMarkerColor; } + if (!msg.has_value()) + { + return QColor(1, 2, 3); + } + /* get check marker color */ - QColor color = qfile->checkMarker(msg); - if(color.isValid()) + if(QColor color = qfile->checkMarker(*msg); color.isValid()) { /* Valid marker found, use background color as defined in marker */ return color; } - else + + if(lastSearchIndex != -1 && filterposindex == qfile->getMsgFilterPos(lastSearchIndex)) { - if(lastSearchIndex != -1 && filterposindex == qfile->getMsgFilterPos(lastSearchIndex)) - { - return searchBackgroundColor(); - } - if ( searchhit > -1 && searchhit == index ) - { - return searchhit_higlightColor; - } - if(project->settings->autoMarkFatalError && ( msg.getSubtypeString() == "error" || msg.getSubtypeString() == "fatal") ) - { - /* If automark error is enabled, set red as background color */ - return QColor(255,0,0); - } - if(project->settings->autoMarkWarn && msg.getSubtypeString() == "warn") - { - /* If automark warning is enabled, set red as background color */ - return QColor(255,255,0); - } - if(project->settings->autoMarkMarker && msg.getType()==QDltMsg::DltTypeControl && - msg.getSubtype()==QDltMsg::DltControlResponse && msg.getCtrlServiceId() == DLT_SERVICE_ID_MARKER) - { - /* If automark marker is enabled, set green as background color */ - return QColor(0,255,0); - } + return searchBackgroundColor(); } + if ( searchhit > -1 && searchhit == index ) + { + return searchhit_higlightColor; + } + if(project->settings->autoMarkFatalError && ( msg->getSubtypeString() == "error" || msg->getSubtypeString() == "fatal") ) + { + /* If automark error is enabled, set red as background color */ + return QColor(255,0,0); + } + if(project->settings->autoMarkWarn && msg->getSubtypeString() == "warn") + { + /* If automark warning is enabled, set red as background color */ + return QColor(255,255,0); + } + if(project->settings->autoMarkMarker && msg->getType()==QDltMsg::DltTypeControl && + msg->getSubtype()==QDltMsg::DltControlResponse && msg->getCtrlServiceId() == DLT_SERVICE_ID_MARKER) + { + /* If automark marker is enabled, set green as background color */ + return QColor(0,255,0); + } + /* default return white background color */ QColor brushColor = QColor(255,255,255); diff --git a/src/tablemodel.h b/src/tablemodel.h index edcb4ef2..6fe3cf65 100644 --- a/src/tablemodel.h +++ b/src/tablemodel.h @@ -28,13 +28,11 @@ #include "project.h" #include "qdltpluginmanager.h" +#include -#define DLT_VIEWER_LIST_BUFFER_SIZE 100024 -#define DLT_VIEWER_COLUMN_COUNT FieldNames::Arg0 +#include -extern "C" -{ -} +#define DLT_VIEWER_COLUMN_COUNT FieldNames::Arg0 class TableModel : public QAbstractTableModel { @@ -66,12 +64,16 @@ Q_OBJECT bool emptyForceFlag; bool loggingOnlyMode; + // cache is used in data()-method to avoid decoding of the same message multiple times + // key is a message index in the qdltfile; message can fail to decode, in that case value is empty optional + mutable QDltLruCache> m_cache{1}; + long int searchhit; QColor searchBackgroundColor() const; QColor searchhit_higlightColor; QColor manualMarkerColor; QList selectedMarkerRows; - QColor getMsgBackgroundColor(QDltMsg &msg,int index,long int filterposindex) const; + QColor getMsgBackgroundColor(const std::optional& msg, int index, long int filterposindex) const; }; class HtmlDelegate : public QStyledItemDelegate