From 115f7bc8db3fc49ce21dd3be80019acd43ddd159 Mon Sep 17 00:00:00 2001
From: "littletux89@gmail.com" <littletux89@gmail.com>
Date: Tue, 21 May 2019 01:59:47 +0300
Subject: [PATCH] [+] Added model for screen node logs.

---
 KelvinDashboardGUI/DapServiceController.cpp   |  25 ++++-
 KelvinDashboardGUI/DapServiceController.h     |   4 +
 .../DapUiQmlWidgetChainNodeLogs.ui.qml        |  69 ++++++------
 KelvinDashboardGUI/Resources/Icons/dialog.png | Bin 0 -> 408 bytes
 KelvinDashboardGUI/main.cpp                   |   4 +
 KelvinDashboardGUI/qml.qrc                    |   1 +
 .../DapChainDashboardService.h                |   3 +
 KelvinDashboardService/DapLogReader.cpp       |  12 +--
 KelvinDashboardService/DapLogReader.h         |   3 +
 libKelvinDashboardCommon/DapLogMessage.cpp    |  57 ++++++++++
 libKelvinDashboardCommon/DapLogMessage.h      |  53 ++++++++++
 libKelvinDashboardCommon/DapLogModel.cpp      |  98 ++++++++++++++++++
 libKelvinDashboardCommon/DapLogModel.h        |  55 ++++++++++
 .../libKelvinDashboardCommon.pri              |   8 +-
 14 files changed, 347 insertions(+), 45 deletions(-)
 create mode 100644 KelvinDashboardGUI/Resources/Icons/dialog.png
 create mode 100644 libKelvinDashboardCommon/DapLogMessage.cpp
 create mode 100644 libKelvinDashboardCommon/DapLogMessage.h
 create mode 100644 libKelvinDashboardCommon/DapLogModel.cpp
 create mode 100644 libKelvinDashboardCommon/DapLogModel.h

diff --git a/KelvinDashboardGUI/DapServiceController.cpp b/KelvinDashboardGUI/DapServiceController.cpp
index f3859cdd2..e43d06d15 100644
--- a/KelvinDashboardGUI/DapServiceController.cpp
+++ b/KelvinDashboardGUI/DapServiceController.cpp
@@ -1,6 +1,8 @@
 #include "DapServiceController.h"
 #include "DapUiQmlWidgetModel.h"
-DapServiceController::DapServiceController(QObject *apParent) 
+#include "DapLogMessage.h"
+
+DapServiceController::DapServiceController(QObject *apParent)
     : QObject(apParent)
 {
     
@@ -64,7 +66,28 @@ void DapServiceController::getNodeLogs(int aiTimeStamp, int aiRowCount) const
 void DapServiceController::processGetNodeLogs(const QStringList &aNodeLogs)
 {
     for(QString s : aNodeLogs)
+    {
         qDebug() << s;
+        QStringList tempList = s.split(" ");
+        DapLogMessage message;
+        if(tempList.at(1) == "[INF]")
+            message.setType(Type::Info);
+        else if(tempList.at(1) == "[WRN]")
+            message.setType(Type::Warning);
+        else if(tempList.at(1) == "[DBG]")
+            message.setType(Type::Debug);
+        else if(tempList.at(1) == "[ERR]")
+            message.setType(Type::Error);
+        QString str = tempList.at(0);
+        message.setTimeStamp(str.remove("[").remove("]"));
+        QStringList tempList2 = tempList.at(2).split("\t");
+        QString str2 = tempList2.at(0);
+        message.setFile(str2.remove("[").remove("]"));
+        QString str3 = s.split("\t").at(1);
+        int pos = str3.indexOf('\n');
+        message.setMessage(str3.remove(pos, str3.size()-pos));
+        DapLogModel::getInstance().append(message);
+    }
 }
 
 /// Get an instance of a class.
diff --git a/KelvinDashboardGUI/DapServiceController.h b/KelvinDashboardGUI/DapServiceController.h
index 645700372..cc18d7312 100644
--- a/KelvinDashboardGUI/DapServiceController.h
+++ b/KelvinDashboardGUI/DapServiceController.h
@@ -9,6 +9,7 @@
 
 #include "DapCommandController.h"
 #include "DapServiceClient.h"
+#include "DapLogModel.h"
 
 class DapServiceController : public QObject
 {
@@ -57,6 +58,9 @@ public:
     /// @param aiRowCount Number of lines displayed.
     void getNodeLogs(int aiTimeStamp, int aiRowCount) const;
     
+    DapLogModel getLogModel() const;
+    void setLogModel(const DapLogModel &dapLogModel);
+
 signals:
     /// The signal is emitted when the Brand company property changes.
     void brandChanged(const QString &brand);
diff --git a/KelvinDashboardGUI/DapUiQmlWidgetChainNodeLogs.ui.qml b/KelvinDashboardGUI/DapUiQmlWidgetChainNodeLogs.ui.qml
index ffb7b6afb..98096425e 100644
--- a/KelvinDashboardGUI/DapUiQmlWidgetChainNodeLogs.ui.qml
+++ b/KelvinDashboardGUI/DapUiQmlWidgetChainNodeLogs.ui.qml
@@ -7,24 +7,6 @@ Page {
     id: dapUiQmlWidgetChainNodeLogs
     title: "Logs"
     
-    
-    ListModel {
-            id: dataModel
-    
-            ListElement {
-                    name: "Apple"
-                    cost: 2.45
-                }
-                ListElement {
-                    name: "Orange"
-                    cost: 3.25
-                }
-                ListElement {
-                    name: "Banana"
-                    cost: 1.95
-                }
-        }
-    
         TabView
         {
             id: tabViewLogs
@@ -48,47 +30,62 @@ Page {
 //                        anchors.bottom: parent.bottom
 //                        anchors.left: parent.left
 //                        anchors.right: parent.right
-                        model: dataModel
+                        model: dapLogModel
                 clip: true
                 
                         TableViewColumn {
                             id: columnType
-                            role: "type"
+//                            role: "type"
                             title: "Type"
                             
                              delegate:
+                                 Item{
                                          Image {
                                              id: names
-                                             source: "qrc:/Resources/Icons/icon.png"
+                                             anchors.centerIn: parent
+                                             source: "qrc:/Resources/Icons/dialog.png"
+                                             width: 14
+                                             height: 14
                                          }
-                        }
-                        TableViewColumn {
-                            id: columnDate
-                            role: "name"
-                            title: "Date"
+                             }
                         }
                         TableViewColumn {
                             id: columnTime
-                            role: "cost"
-                            title: "Time"
+                            role: "timestamp"
+                            title: "Timestamp"
+                            delegate: Item {
+                                        Text {
+                                            anchors.centerIn: parent
+                                            renderType: Text.NativeRendering
+                                            text: styleData.value
+                                        }
+                                    }
                         }
                         TableViewColumn {
                             id: columnFile
                             role: "file"
                             title: "File"
+                            delegate: Item {
+                                        Text {
+                                            anchors.centerIn: parent
+                                            renderType: Text.NativeRendering
+                                            text: styleData.value
+                                        }
+                                    }
                         }
                         TableViewColumn {
                             id: columnMessage
-                            role: "Message"
+                            role: "message"
                             title: "Message"
-                        }
-                        itemDelegate: Item {
-                                    Text {
-                                        anchors.centerIn: parent
-                                        renderType: Text.NativeRendering
-                                        text: styleData.value
+                            delegate: Item {
+                                        Text {
+                                            renderType: Text.NativeRendering
+                                            text: styleData.value
+                                        }
                                     }
-                                }
+                        }
+
+
                         headerDelegate: Rectangle {
                             height: 20
                             color: "red"
diff --git a/KelvinDashboardGUI/Resources/Icons/dialog.png b/KelvinDashboardGUI/Resources/Icons/dialog.png
new file mode 100644
index 0000000000000000000000000000000000000000..176bc26d4962885d56ed46d4c7fb9c62f195529e
GIT binary patch
literal 408
zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xawj^(N7l!{JxM1({$v_d#0*}aI
zppNSx%;=;sy8<Z4UgGKN%Kn&DM9kcDYJ>Sh1_nk|PZ!4!jq_V4?e}7K6gXC2yq$9r
zv#U#YiCs&tnVDIbn4P=SN7fvX8m9Pz>H;+^+#7vTHC_G)Pcq)Q_qJrWwche{2bTH`
zXW!L)uC?a*BglAT-&ud(8$YKW*imisBF2j0>n?5?Q*N_ehmL6PdlQ>{fw6<(#M;tt
z!soBO;jPKo&&<cb-&Xt5X3mj4=b55<Cf<|k2&tdk8t~c3dGg+`GhVJvp2K!QWEW>g
zLg=Scfzi$<HZ?qBl1kp$SaqZ{o1H!3UX;^(M-8Pl0Ub$4lzhZXmnJW~BB`~mo%No!
zfbx!_zJm@@eg9Ic`dzp#cviJ5Xm3uiTT+!Q#1t42G1Kk}_k|_(hLvVluNwHXFW&s`
y>L%BM`}!u_t>^677Jq)aNdBfxrPVY0pDY(e`aItVUKIj{A%mx@pUXO@geCwFIi6+!

literal 0
HcmV?d00001

diff --git a/KelvinDashboardGUI/main.cpp b/KelvinDashboardGUI/main.cpp
index 5d39cd220..f2d8ca3f4 100755
--- a/KelvinDashboardGUI/main.cpp
+++ b/KelvinDashboardGUI/main.cpp
@@ -16,6 +16,8 @@
 #include "DapServiceClient.h"
 #include "DapServiceController.h"
 #include "DapLogger.h"
+#include "DapLogMessage.h"
+#include "DapLogModel.h"
 
 int main(int argc, char *argv[])
 {
@@ -45,12 +47,14 @@ int main(int argc, char *argv[])
     
     qmlRegisterType<DapScreenDialog>("KelvinDashboard", 1, 0, "DapScreenDialog");
     qmlRegisterType<DapScreenDialogChangeWidget>("KelvinDashboard", 1, 0, "DapScreenDialogChangeWidget");
+    qmlRegisterType<DapLogMessage>("LogMessage", 1, 0, "DapLogMessage");
     qmlRegisterSingletonType<DapServiceController>("KelvinDashboard", 1, 0, "DapServiceController", DapServiceController::singletonProvider);
     qmlRegisterSingletonType<DapUiQmlWidgetModel>("KelvinDashboard", 1, 0, "DapUiQmlWidgetModel", DapUiQmlWidgetModel::singletonProvider);
     
     QQmlApplicationEngine engine;
     engine.rootContext()->setContextProperty("dapServiceController", &DapServiceController::getInstance());
     engine.rootContext()->setContextProperty("dapUiQmlWidgetModel", &DapUiQmlWidgetModel::getInstance());
+    engine.rootContext()->setContextProperty("dapLogModel", &DapLogModel::getInstance());
     engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
     
 //    DapSettings &settings = DapSettings::getInstance("Settings.json");
diff --git a/KelvinDashboardGUI/qml.qrc b/KelvinDashboardGUI/qml.qrc
index 8d93e1b02..9d4d9bc86 100755
--- a/KelvinDashboardGUI/qml.qrc
+++ b/KelvinDashboardGUI/qml.qrc
@@ -22,5 +22,6 @@
         <file>DapUiQmlWidgetChainNodeLogs.ui.qml</file>
         <file>Resources/Icons/add.png</file>
         <file>Resources/Icons/icon.ico</file>
+        <file>Resources/Icons/dialog.png</file>
     </qresource>
 </RCC>
diff --git a/KelvinDashboardService/DapChainDashboardService.h b/KelvinDashboardService/DapChainDashboardService.h
index 43d453b74..5527ef925 100755
--- a/KelvinDashboardService/DapChainDashboardService.h
+++ b/KelvinDashboardService/DapChainDashboardService.h
@@ -33,8 +33,11 @@ class DapChainDashboardService : public DapRpcService
 {
     Q_OBJECT
     Q_CLASSINFO("serviceName", "RPCServer")
+    /// Service core.
     DapUiService            * m_pServer {nullptr};
+    /// Socket of client connection with the service.
     DapUiSocketServer       * m_pSocketService {nullptr};
+    /// Log reader.
     DapLogReader            * m_pDapLogReader {nullptr};
 public:
     /// Standard сonstructor.
diff --git a/KelvinDashboardService/DapLogReader.cpp b/KelvinDashboardService/DapLogReader.cpp
index fb2fc13b1..9907b1c83 100644
--- a/KelvinDashboardService/DapLogReader.cpp
+++ b/KelvinDashboardService/DapLogReader.cpp
@@ -9,14 +9,14 @@ DapLogReader::DapLogReader(QObject *parent) : QObject(parent)
 
 QStringList DapLogReader::parse(const QByteArray &aLogMessages)
 {
-    auto list = QString::fromLatin1(aLogMessages).split(";");
+    QStringList list = QString::fromLatin1(aLogMessages).split(";");
 
-    for(QString l : list)
+    auto resultEnd = std::remove_if(list.begin(), list.end(),
+    [] (const QString& aLogMessage)
     {
-        if(l.contains("["))
-            qDebug() << l;
-    }
-
+        return !aLogMessage.contains('[');
+    });
+    list.erase(resultEnd, list.end());
     return list;
 }
 
diff --git a/KelvinDashboardService/DapLogReader.h b/KelvinDashboardService/DapLogReader.h
index d14bf5c94..a164d3598 100644
--- a/KelvinDashboardService/DapLogReader.h
+++ b/KelvinDashboardService/DapLogReader.h
@@ -4,8 +4,11 @@
 #include <QObject>
 #include <QString>
 #include <QProcess>
+#include <algorithm>
 #include <QDebug>
 
+#include "DapLogMessage.h"
+
 class DapLogReader : public QObject
 {
     Q_OBJECT
diff --git a/libKelvinDashboardCommon/DapLogMessage.cpp b/libKelvinDashboardCommon/DapLogMessage.cpp
new file mode 100644
index 000000000..fec32450b
--- /dev/null
+++ b/libKelvinDashboardCommon/DapLogMessage.cpp
@@ -0,0 +1,57 @@
+#include "DapLogMessage.h"
+
+DapLogMessage::DapLogMessage(const Type &type, const QString &timestamp, const QString &file, const QString &message, QObject *parent) : QObject(parent)
+{
+    m_type = type;
+    m_sTimeStamp = timestamp;
+    m_sFile = file;
+    m_sMessage = message;
+}
+
+Type DapLogMessage::getType() const
+{
+    return m_type;
+}
+
+void DapLogMessage::setType(const Type &type)
+{
+    m_type = type;
+
+    emit typeChanged(m_type);
+}
+
+QString DapLogMessage::getTimeStamp() const
+{
+    return m_sTimeStamp;
+}
+
+void DapLogMessage::setTimeStamp(const QString &sTimeStamp)
+{
+    m_sTimeStamp = sTimeStamp;
+
+    emit timeStampChanged(m_sTimeStamp);
+}
+
+QString DapLogMessage::getFile() const
+{
+    return m_sFile;
+}
+
+void DapLogMessage::setFile(const QString &sFile)
+{
+    m_sFile = sFile;
+
+    emit fileChanged(m_sFile);
+}
+
+QString DapLogMessage::getMessage() const
+{
+    return m_sMessage;
+}
+
+void DapLogMessage::setMessage(const QString &sMessage)
+{
+    m_sMessage = sMessage;
+
+    emit messageChanged(m_sMessage);
+}
diff --git a/libKelvinDashboardCommon/DapLogMessage.h b/libKelvinDashboardCommon/DapLogMessage.h
new file mode 100644
index 000000000..c3e0d2d4a
--- /dev/null
+++ b/libKelvinDashboardCommon/DapLogMessage.h
@@ -0,0 +1,53 @@
+#ifndef DAPLOGMESSAGE_H
+#define DAPLOGMESSAGE_H
+
+#include <QObject>
+
+enum Type
+{
+    Info,
+    Warning,
+    Debug,
+    Error
+};
+
+class DapLogMessage : public QObject
+{
+    Q_OBJECT
+
+    Type m_type;
+    QString m_sTimeStamp;
+    QString m_sFile;
+    QString m_sMessage;
+
+public:
+    explicit DapLogMessage(QObject *parent = nullptr) {}
+    DapLogMessage(const Type &type, const QString &timestamp, const QString  &file, const QString &message, QObject *parent = nullptr);
+
+
+    Q_PROPERTY(Type type READ getType WRITE setType NOTIFY typeChanged)
+    Q_PROPERTY(QString timestamp READ getTimeStamp WRITE setTimeStamp NOTIFY timeStampChanged)
+    Q_PROPERTY(QString file READ getFile WRITE setFile NOTIFY fileChanged)
+    Q_PROPERTY(QString message READ getMessage WRITE setMessage NOTIFY messageChanged)
+
+    Type getType() const;
+    void setType(const Type &type);
+
+    QString getTimeStamp() const;
+    void setTimeStamp(const QString &sTimeStamp);
+
+    QString getFile() const;
+    void setFile(const QString &sFile);
+
+    QString getMessage() const;
+    void setMessage(const QString &sMessage);
+
+signals:
+    void typeChanged(Type aType);
+    void timeStampChanged(const QString& aTimeStamp);
+    void fileChanged(const QString& aFile);
+    void messageChanged(const QString& aMessage);
+
+};
+
+#endif // DAPLOGMESSAGE_H
diff --git a/libKelvinDashboardCommon/DapLogModel.cpp b/libKelvinDashboardCommon/DapLogModel.cpp
new file mode 100644
index 000000000..ad8d7d4f3
--- /dev/null
+++ b/libKelvinDashboardCommon/DapLogModel.cpp
@@ -0,0 +1,98 @@
+#include "DapLogModel.h"
+
+DapLogModel::DapLogModel(QObject *parent) : QAbstractListModel(parent)
+{
+
+}
+
+DapLogModel &DapLogModel::getInstance()
+{
+    static DapLogModel instance;
+    return instance;
+}
+
+int DapLogModel::rowCount(const QModelIndex &) const
+{
+    return m_dapLogMessage.count();
+}
+
+QVariant DapLogModel::data(const QModelIndex &index, int role) const
+{
+    if (index.row() < rowCount())
+            switch (role) {
+            case TypeRole: return m_dapLogMessage.at(index.row())->getType();
+            case TimeStampRole: return m_dapLogMessage.at(index.row())->getTimeStamp();
+            case FileRole: return m_dapLogMessage.at(index.row())->getFile();
+            case MessageRole: return m_dapLogMessage.at(index.row())->getMessage();
+            default:
+                return QVariant();
+        }
+    return QVariant();
+}
+
+QHash<int, QByteArray> DapLogModel::roleNames() const
+{
+    static const QHash<int, QByteArray> roles {
+            { TypeRole, "type" },
+            { TimeStampRole, "timestamp" },
+            { FileRole, "file" },
+            { MessageRole, "message" }
+        };
+
+    return roles;
+}
+
+QVariantMap DapLogModel::get(int row) const
+{
+    const DapLogMessage *widget = m_dapLogMessage.value(row);
+    return { {"type", widget->getType()}, {"timestamp", widget->getTimeStamp()}, {"file", widget->getFile()}, {"message", widget->getMessage()} };
+}
+
+void DapLogModel::append(const DapLogMessage &message)
+{
+    this->append(message.getType(), message.getTimeStamp(), message.getFile(), message.getMessage());
+}
+
+void DapLogModel::append(const Type &type, const QString &timestamp, const QString &file, const QString &message)
+{
+    int row = 0;
+    while (row < m_dapLogMessage.count() && timestamp > m_dapLogMessage.at(row)->getTimeStamp())
+        ++row;
+    beginInsertRows(QModelIndex(), row, row);
+    m_dapLogMessage.insert(row, new DapLogMessage(type, timestamp, file, message));
+    endInsertRows();
+}
+
+void DapLogModel::set(int row, const Type &type, const QString &timestamp, const QString &file, const QString &message)
+{
+    if (row < 0 || row >= m_dapLogMessage.count())
+            return;
+
+        DapLogMessage *widget = m_dapLogMessage.value(row);
+        widget->setType(type);
+        widget->setTimeStamp(timestamp);
+        widget->setFile(file);
+        widget->setMessage(message);
+        dataChanged(index(row, 0), index(row, 0), { TypeRole, TimeStampRole, FileRole, MessageRole });
+}
+
+void DapLogModel::remove(int row)
+{
+    if (row < 0 || row >= m_dapLogMessage.count())
+            return;
+
+        beginRemoveRows(QModelIndex(), row, row);
+        m_dapLogMessage.removeAt(row);
+        endRemoveRows();
+}
+
+/// Method that implements the singleton pattern for the qml layer.
+/// @param engine QML application.
+/// @param scriptEngine The QJSEngine class provides an environment for evaluating JavaScript code.
+QObject *DapLogModel::singletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+    Q_UNUSED(engine)
+    Q_UNUSED(scriptEngine)
+
+    return &getInstance();
+}
diff --git a/libKelvinDashboardCommon/DapLogModel.h b/libKelvinDashboardCommon/DapLogModel.h
new file mode 100644
index 000000000..0bb8decba
--- /dev/null
+++ b/libKelvinDashboardCommon/DapLogModel.h
@@ -0,0 +1,55 @@
+#ifndef DAPLOGMODEL_H
+#define DAPLOGMODEL_H
+
+#include <QObject>
+#include <QAbstractListModel>
+#include <QList>
+#include <QQmlEngine>
+#include <QJSEngine>
+#include <QXmlStreamWriter>
+#include <QXmlStreamReader>
+#include <QXmlStreamAttribute>
+
+#include "DapLogMessage.h"
+
+enum DapLogRole {
+        TypeRole = Qt::DisplayRole,
+        TimeStampRole = Qt::UserRole,
+        FileRole,
+        MessageRole
+    };
+
+class DapLogModel : public QAbstractListModel
+{
+    Q_OBJECT
+
+    QList<DapLogMessage*>    m_dapLogMessage;
+
+    DapLogModel(QObject *parent = nullptr);
+public:
+
+    /// Get an instance of a class.
+    /// @return Instance of a class.
+    Q_INVOKABLE static DapLogModel &getInstance();
+
+
+    Q_ENUM(DapLogRole)
+
+    int rowCount(const QModelIndex & = QModelIndex()) const;
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+    QHash<int, QByteArray> roleNames() const;
+
+    Q_INVOKABLE QVariantMap get(int row) const;
+    Q_INVOKABLE void append(const DapLogMessage &message);
+    Q_INVOKABLE void append(const Type &type, const QString &timestamp, const QString  &file, const QString &message);
+    Q_INVOKABLE void set(int row, const Type &type, const QString &timestamp, const QString  &file, const QString &message);
+    Q_INVOKABLE void remove(int row);
+
+public slots:
+    /// Method that implements the singleton pattern for the qml layer.
+    /// @param engine QML application.
+    /// @param scriptEngine The QJSEngine class provides an environment for evaluating JavaScript code.
+    static QObject *singletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine);
+};
+
+#endif // DAPLOGMODEL_H
diff --git a/libKelvinDashboardCommon/libKelvinDashboardCommon.pri b/libKelvinDashboardCommon/libKelvinDashboardCommon.pri
index 3dfc99342..ee6bc4c89 100755
--- a/libKelvinDashboardCommon/libKelvinDashboardCommon.pri
+++ b/libKelvinDashboardCommon/libKelvinDashboardCommon.pri
@@ -14,9 +14,13 @@ QT += quick quickwidgets
 SOURCES +=\
     $$PWD/DapHalper.cpp \
     $$PWD/DapSettings.cpp \
-    $$PWD/DapSettingsCipher.cpp
+    $$PWD/DapSettingsCipher.cpp \
+    $$PWD/DapLogMessage.cpp \
+    $$PWD/DapLogModel.cpp
 
 HEADERS +=\
     $$PWD/DapHalper.h \
     $$PWD/DapSettings.h \
-    $$PWD/DapSettingsCipher.h
+    $$PWD/DapSettingsCipher.h \
+    $$PWD/DapLogMessage.h \
+    $$PWD/DapLogModel.h
-- 
GitLab