diff --git a/qdlt/qdlt.pro b/qdlt/qdlt.pro index 244b2a90..610123fa 100644 --- a/qdlt/qdlt.pro +++ b/qdlt/qdlt.pro @@ -68,6 +68,7 @@ SOURCES += \ fieldnames.cpp \ qdltimporter.cpp \ dltmessagematcher.cpp \ + qdltctrlmsg.cpp \ HEADERS += qdlt.h \ export_rules.h \ @@ -101,6 +102,7 @@ HEADERS += qdlt.h \ fieldnames.h \ qdltimporter.h \ dltmessagematcher.h \ + qdltctrlmsg.h \ unix:VERSION = 1.0.0 diff --git a/qdlt/qdltctrlmsg.h b/qdlt/qdltctrlmsg.h index c9fe634b..7bca75ca 100644 --- a/qdlt/qdltctrlmsg.h +++ b/qdlt/qdltctrlmsg.h @@ -1,6 +1,8 @@ #ifndef QDLTCTRLMSG_H #define QDLTCTRLMSG_H +#include "export_rules.h" + #include #include @@ -57,7 +59,7 @@ struct UnregisterContext { using Type = std::variant; -Type parse(const QByteArray&, bool isBigEndian); +QDLT_EXPORT Type parse(const QByteArray&, bool isBigEndian); } // namespace qdlt::msg::payload diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 30b215dc..73678316 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,7 +51,9 @@ add_executable(dlt-viewer searchform.cpp ${UI_RESOURCES_RCC} resources/dlt_viewer.rc - ) + ecutree.h + ecutree.cpp +) target_link_libraries(dlt-viewer qdlt diff --git a/src/ecutree.cpp b/src/ecutree.cpp new file mode 100644 index 00000000..dd4b56ce --- /dev/null +++ b/src/ecutree.cpp @@ -0,0 +1,17 @@ +#include "ecutree.h" + +void EcuTree::add(const QString& ecuId, const qdlt::msg::payload::GetLogInfo& info) +{ + for (const auto& app : info.apps) { + App appData; + appData.description = app.description; + for (const auto& ctx : app.ctxs) { + Ctx ctxData; + ctxData.description = ctx.description; + ctxData.logLevel = ctx.logLevel; + ctxData.traceStatus = ctx.traceStatus; + appData.contexts[ctx.id] = std::move(ctxData); + } + ecus[ecuId][app.id] = std::move(appData); + } +} diff --git a/src/ecutree.h b/src/ecutree.h new file mode 100644 index 00000000..12b7c933 --- /dev/null +++ b/src/ecutree.h @@ -0,0 +1,27 @@ +#ifndef ECUTREEBUILDER_H +#define ECUTREEBUILDER_H + +#include + +#include + +struct EcuTree +{ + void add(const QString& ecuId, const qdlt::msg::payload::GetLogInfo&); + + using EcuId = QString; + using AppId = QString; + using CtxId = QString; + struct Ctx { + QString description; + int8_t logLevel; + int8_t traceStatus; + }; + struct App { + QString description; + std::map contexts; + }; + std::map> ecus; +}; + +#endif // ECUTREEBUILDER_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d3c911ec..f950b9fb 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -88,6 +88,7 @@ extern "C" { #include "sortfilterproxymodel.h" #include "qdltoptmanager.h" #include "qdltctrlmsg.h" +#include "ecutree.h" MainWindow::MainWindow(QWidget *parent) : @@ -1893,45 +1894,52 @@ void MainWindow::on_action_menuFile_Clear_triggered() return; } -void MainWindow::contextLoadingFile(const QDltMsg &msg) +void MainWindow::populateEcusTree(EcuTree&& ecuTree) { - /* find ecu item */ - EcuItem *ecuitemFound = 0; - for(int num = 0; num < project.ecu->topLevelItemCount (); num++) - { - EcuItem *ecuitem = (EcuItem*)project.ecu->topLevelItem(num); - if(ecuitem->id == msg.getEcuid()) - { - ecuitemFound = ecuitem; - break; - } - } + QList ecus; + // populate ECUs tree view + for (auto& [ecuid, apps] : ecuTree.ecus) { + EcuItem* ecuItem = new EcuItem(nullptr); - if(!ecuitemFound) - { - /* no Ecuitem found, create a new one */ - ecuitemFound = new EcuItem(0); + ecuItem->id = ecuid; - /* update ECU item */ - ecuitemFound->id = msg.getEcuid(); - ecuitemFound->update(); + QList appsItems; + for(const auto& [appid, appdata] : apps) { + ApplicationItem* appItem = new ApplicationItem(ecuItem); + appItem->id = appid; + appItem->description = appdata.description; + appItem->update(); - /* add ECU to configuration */ - project.ecu->addTopLevelItem(ecuitemFound); + QList contextsItems; + for(const auto& [ctxid, ctxdata] : appdata.contexts) { + ContextItem* conItem = new ContextItem(appItem); + conItem->id = ctxid; + conItem->loglevel = ctxdata.logLevel; + conItem->tracestatus = ctxdata.traceStatus; + conItem->description = ctxdata.description; + conItem->status = ContextItem::valid; + conItem->update(); - /* Update the ECU list in control plugins */ - updatePluginsECUList(); + contextsItems.append(conItem); + } - pluginManager.stateChanged(project.ecu->indexOfTopLevelItem(ecuitemFound), QDltConnection::QDltConnectionOffline,ecuitemFound->getHostname()); + appItem->addChildren(contextsItems); + appsItems.append(appItem); + } - } + ecuItem->addChildren(appsItems); + ecuItem->update(); - controlMessage_ReceiveControlMessage(ecuitemFound, msg); -} + pluginManager.stateChanged(ecus.size(), QDltConnection::QDltConnectionOffline, + ecuItem->getHostname()); -void MainWindow::reloadLogFileStop() -{ + ecus.append(ecuItem); + } + + project.ecu->addTopLevelItems(ecus); + /* Update the ECU list in control plugins */ + updatePluginsECUList(); } void MainWindow::reloadLogFileProgressMax(int num) @@ -2062,13 +2070,21 @@ void MainWindow::reloadLogFileFinishFilter() settings->updateContextLoadingFile) { const QList &msgIndexList = dltIndexer->getGetLogInfoList(); - // FIXME: this is slow operation running in the main loop QDltMsg msg; + EcuTree ecuTree; for (const auto msgIndex : msgIndexList) { if (qfile.getMsg(msgIndex, msg)) { - contextLoadingFile(msg); + auto ctrlMsg = qdlt::msg::payload::parse(msg.getPayload(), msg.getEndianness() == QDltMsg::DltEndiannessBigEndian); + std::visit([&ecuTree, ecuId = msg.getEcuid()](auto&& payload) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + ecuTree.add(ecuId, payload); + } + }, ctrlMsg); } } + project.ecu->clear(); + populateEcusTree(std::move(ecuTree)); } // reconnect ecus again diff --git a/src/mainwindow.h b/src/mainwindow.h index fd560c98..ea426557 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -96,6 +96,8 @@ namespace Ui { class MainWindow; } +struct EcuTree; + class MainWindow : public QMainWindow { Q_OBJECT @@ -236,13 +238,8 @@ class MainWindow : public QMainWindow void getSelectedItems(EcuItem **ecuitem,ApplicationItem** appitem,ContextItem** conitem); - /** - * @brief Reload the complete log file - * @param update if this parameter is false, the file is loaded the first time, if true the reload is performed because of a changed configuration - * - */ - void reloadLogFileStop(); void reloadLogFile(bool update=false, bool multithreaded = true); + void populateEcusTree(EcuTree&& ecuTree); void reloadLogFileDefaultFilter(); @@ -275,7 +272,6 @@ class MainWindow : public QMainWindow void updatePluginsECUList(); void updatePlugins(); void updatePlugin(PluginItem *item); - void contextLoadingFile(const QDltMsg &msg); void versionString(const QDltMsg &msg); void pluginsAutoload(QString version); diff --git a/src/src.pro b/src/src.pro index 3b42f1ea..b1f056b0 100644 --- a/src/src.pro +++ b/src/src.pro @@ -149,6 +149,7 @@ SOURCES += main.cpp \ dltmsgqueue.cpp \ dltfileindexerthread.cpp \ dltfileindexerdefaultfilterthread.cpp \ + ecutree.cpp \ # Show these headers in the project HEADERS += mainwindow.h \ @@ -180,7 +181,8 @@ HEADERS += mainwindow.h \ dltmsgqueue.h \ dltfileindexerthread.h \ dltfileindexerdefaultfilterthread.h \ - mcudpsocket.h + mcudpsocket.h \ + ecutree.h \ # Compile these UI files FORMS += mainwindow.ui \