From 7c7836b9d7d35ada869a7d55a84e69d9455c986c Mon Sep 17 00:00:00 2001
From: jonymt <johanmt@yandex.ru>
Date: Tue, 17 Sep 2019 15:09:26 +0200
Subject: [PATCH] [*] changed console widget. added writing to a file

---
 KelvinDashboardGUI/DapCommandController.cpp   |  13 ++
 KelvinDashboardGUI/DapCommandController.h     |   6 +
 KelvinDashboardGUI/DapConsoleModel.cpp        |  32 ++++-
 KelvinDashboardGUI/DapConsoleModel.h          |   7 ++
 KelvinDashboardGUI/DapServiceController.cpp   |   6 +
 KelvinDashboardGUI/DapServiceController.h     |   2 +-
 .../DapUiQmlScreenConsoleForm.qml             |  80 ++++++++++++
 .../DapUiQmlScreenConsoleForm.ui.qml          |  25 ----
 .../DapUiQmlScreenMainWindowForm.ui.qml       |   2 +-
 .../DapUiQmlWidgetConsoleForm.qml             | 118 +++++++++++-------
 KelvinDashboardGUI/main.cpp                   |   1 +
 KelvinDashboardGUI/qml.qrc                    |   2 +-
 .../DapChainConsoleHandler.cpp                |  38 +++++-
 .../DapChainConsoleHandler.h                  |   6 +
 .../DapChainDashboardService.cpp              |   5 +
 .../DapChainDashboardService.h                |   2 +
 16 files changed, 270 insertions(+), 75 deletions(-)
 create mode 100644 KelvinDashboardGUI/DapUiQmlScreenConsoleForm.qml
 delete mode 100644 KelvinDashboardGUI/DapUiQmlScreenConsoleForm.ui.qml

diff --git a/KelvinDashboardGUI/DapCommandController.cpp b/KelvinDashboardGUI/DapCommandController.cpp
index b02dfaa31..e429cc325 100755
--- a/KelvinDashboardGUI/DapCommandController.cpp
+++ b/KelvinDashboardGUI/DapCommandController.cpp
@@ -69,6 +69,12 @@ void DapCommandController::requestConsole(const QString& aQueue)
     connect(reply, SIGNAL(finished()), this, SLOT(processResponseConsole()));
 }
 
+void DapCommandController::getCmdHistory()
+{
+    DapRpcServiceReply *reply = m_DAPRpcSocket->invokeRemoteMethod("RPCServer.getCmdHistory");
+    connect(reply, SIGNAL(finished()), this, SLOT(processGetCmdHistory()));
+}
+
 void DapCommandController::processChangedLog()
 {
 //    QStringList tempLogModel;
@@ -205,6 +211,13 @@ void DapCommandController::processResponseConsole()
     emit responseConsole(result);
 }
 
+void DapCommandController::processGetCmdHistory()
+{
+    DapRpcServiceReply *reply = static_cast<DapRpcServiceReply *>(sender());
+    QString result = reply->response().result().toVariant().toString();
+    emit sigCmdHistory(result);
+}
+
 /// Show or hide GUI client by clicking on the tray icon.
 /// @param aIsActivated Accepts true - when requesting to 
 /// display a client, falso - when requesting to hide a client.
diff --git a/KelvinDashboardGUI/DapCommandController.h b/KelvinDashboardGUI/DapCommandController.h
index 1739ac95b..7596180dc 100755
--- a/KelvinDashboardGUI/DapCommandController.h
+++ b/KelvinDashboardGUI/DapCommandController.h
@@ -51,6 +51,8 @@ signals:
 
     void responseConsole(const QString& aResponse);
 
+    void sigCmdHistory(const QString& aHistory);
+
 public:
     /// Overloaded constructor.
     /// @param apIODevice Data transfer device.
@@ -82,6 +84,8 @@ private slots:
 
     void processResponseConsole();
 
+    void processGetCmdHistory();
+
 public slots:
     /// Show or hide GUI client by clicking on the tray icon.
     /// @param aIsActivated Accepts true - when requesting to 
@@ -116,6 +120,8 @@ public slots:
     void setNewHistory(const QVariant& aData);
 
     void requestConsole(const QString& aQueue);
+
+    void getCmdHistory();
 };
 
 #endif // COMMANDCONTROLLER_H
diff --git a/KelvinDashboardGUI/DapConsoleModel.cpp b/KelvinDashboardGUI/DapConsoleModel.cpp
index 04e4b89c2..631ac4483 100644
--- a/KelvinDashboardGUI/DapConsoleModel.cpp
+++ b/KelvinDashboardGUI/DapConsoleModel.cpp
@@ -14,6 +14,7 @@ DapConsoleModel& DapConsoleModel::getInstance()
 
 void DapConsoleModel::receiveResponse(const QString& aResponse)
 {
+    m_History.append(aResponse);
     emit sendResponse(aResponse);
 }
 
@@ -59,8 +60,37 @@ QString DapConsoleModel::getCommandDown()
 void DapConsoleModel::receiveRequest(const QString& aCommand)
 {
     beginResetModel();
-    m_CommandList.append(aCommand);
+    if(!m_CommandList.contains(aCommand))
+        m_CommandList.append(aCommand);
     endResetModel();
     m_CommandIndex = m_CommandList.end();
+
+    QString returnSymbol = "\n";
+
+#ifdef Q_OS_WIN
+    returnSymbol.prepend("\r");
+#endif
+
+    m_History.append(returnSymbol + "> " + aCommand + returnSymbol);
     emit sendRequest(aCommand);
 }
+
+QString DapConsoleModel::getCmdHistory()
+{
+    return m_History;
+}
+
+void DapConsoleModel::receiveCmdHistory(const QString& aHistory)
+{
+    m_History.append(aHistory);
+    QRegExp rx("^([\\w+\\s+])$");
+
+    int pos = 0;
+    while ((pos = rx.indexIn(m_History, pos)) != -1)
+    {
+        if(!m_CommandList.contains(rx.cap(1)))
+            m_CommandList.append(rx.cap(1));
+        pos += rx.matchedLength();
+    }
+    emit cmdHistoryChanged(m_History);
+}
diff --git a/KelvinDashboardGUI/DapConsoleModel.h b/KelvinDashboardGUI/DapConsoleModel.h
index cc2d5f64e..1eb9b3322 100644
--- a/KelvinDashboardGUI/DapConsoleModel.h
+++ b/KelvinDashboardGUI/DapConsoleModel.h
@@ -17,6 +17,7 @@ public:
     };
 
 private:
+    QString m_History;
     QStringList m_CommandList;
     QStringList::iterator m_CommandIndex;
 
@@ -46,6 +47,10 @@ public slots:
     /// @param command request
     Q_INVOKABLE void receiveRequest(const QString& aCommand);
 
+    Q_INVOKABLE QString getCmdHistory();
+
+    void receiveCmdHistory(const QString& aHistory);
+
 signals:
     /// Signal to send request to the service
     /// @param command
@@ -53,6 +58,8 @@ signals:
     /// Signal for getting response from service
     /// @param result of command
     void sendResponse(QString response);
+
+    void cmdHistoryChanged(QString history);
 };
 
 #endif // DAPUIQMLSCREENCONSOLEFORM_H
diff --git a/KelvinDashboardGUI/DapServiceController.cpp b/KelvinDashboardGUI/DapServiceController.cpp
index d82608f0f..521710206 100755
--- a/KelvinDashboardGUI/DapServiceController.cpp
+++ b/KelvinDashboardGUI/DapServiceController.cpp
@@ -62,6 +62,7 @@ void DapServiceController::init(DapServiceClient *apDapServiceClient)
 
     connect(&DapConsoleModel::getInstance(), &DapConsoleModel::sendRequest, m_pDapCommandController, &DapCommandController::requestConsole);
     connect(m_pDapCommandController, &DapCommandController::responseConsole, &DapConsoleModel::getInstance(), &DapConsoleModel::receiveResponse);
+    connect(m_pDapCommandController, &DapCommandController::sigCmdHistory, &DapConsoleModel::getInstance(), &DapConsoleModel::receiveCmdHistory);
 }
 
 QString DapServiceController::getBrand() const
@@ -174,6 +175,11 @@ void DapServiceController::getWalletInfo(const QString &asWalletName)
     m_pDapCommandController->getWalletInfo(asWalletName);
 }
 
+void DapServiceController::getCmdHistory()
+{
+    m_pDapCommandController->getCmdHistory();
+}
+
 void DapServiceController::getHistory()
 {
     m_pDapCommandController->getHistory();
diff --git a/KelvinDashboardGUI/DapServiceController.h b/KelvinDashboardGUI/DapServiceController.h
index 472d304a7..7dc055314 100755
--- a/KelvinDashboardGUI/DapServiceController.h
+++ b/KelvinDashboardGUI/DapServiceController.h
@@ -81,7 +81,7 @@ public:
 
     void getWalletInfo(const QString& asWalletName);
 
-
+    void getCmdHistory();
 
 signals:
     /// The signal is emitted when the Brand company property changes.
diff --git a/KelvinDashboardGUI/DapUiQmlScreenConsoleForm.qml b/KelvinDashboardGUI/DapUiQmlScreenConsoleForm.qml
new file mode 100644
index 000000000..e748059e1
--- /dev/null
+++ b/KelvinDashboardGUI/DapUiQmlScreenConsoleForm.qml
@@ -0,0 +1,80 @@
+import QtQuick 2.13
+import QtQml 2.12
+import QtQuick.Controls 2.2
+import QtQuick.Layouts 1.12
+
+Page {
+
+    DapUiQmlWidgetConsoleForm {
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+        anchors.left: parent.left
+        anchors.right: lastActionsPanel.right
+
+        anchors.topMargin: 30 * pt
+        anchors.leftMargin: 30 * pt
+        anchors.rightMargin: 30 * pt
+    }
+
+//    Text {
+//        id: promt
+//        anchors.left: parent.left
+//        anchors.top: consoleCmd.top
+//        anchors.bottom: parent.bottom
+//        verticalAlignment: Qt.AlignVCenter
+//        text: ">"
+//        color: "#707070"
+//        font.family: "Roboto"
+//        font.pixelSize: 20 * pt
+//        anchors.leftMargin: 30 * pt
+//    }
+
+//    TextArea {
+//        id: consoleCmd
+//        anchors.left: promt.right
+//        anchors.bottom: parent.bottom
+//        anchors.right: lastActionsPanel.left
+//        height: contentChildren.height
+//        wrapMode: TextArea.Wrap
+//        color: "#707070"
+//        font.family: "Roboto"
+//        font.pixelSize: 20 * pt
+//        anchors.rightMargin: 30 * pt
+//        focus: true
+
+//        Keys.onUpPressed: {
+//            consoleCmd.text = dapConsoleModel.getCommandUp();
+//        }
+
+//        Keys.onDownPressed: {
+//            consoleCmd.text = dapConsoleModel.getCommandDown();
+//        }
+
+//        Keys.onReturnPressed: {
+//            dapConsoleModel.receiveRequest(consoleCmd.text);
+//            txtCommand.append("> " + consoleCmd.text);
+//        }
+//    }
+
+//    Flickable {
+//        anchors.left: parent.left
+//        anchors.top: parent.top
+//        anchors.right: lastActionsPanel.left
+//        anchors.bottom: consoleCmd.top
+
+//        leftMargin: 30 * pt
+//        topMargin: 30 * pt
+//        rightMargin: 30 * pt
+
+//        TextArea.flickable: DapUiQmlWidgetConsoleForm
+//        {
+//            id: txtCommand
+//        }
+
+//        ScrollBar.vertical: ScrollBar{}
+//    }
+
+    DapUiQmlWidgetConsoleLastActionsForm {
+        id: lastActionsPanel
+    }
+}
diff --git a/KelvinDashboardGUI/DapUiQmlScreenConsoleForm.ui.qml b/KelvinDashboardGUI/DapUiQmlScreenConsoleForm.ui.qml
deleted file mode 100644
index 3d05c3ae2..000000000
--- a/KelvinDashboardGUI/DapUiQmlScreenConsoleForm.ui.qml
+++ /dev/null
@@ -1,25 +0,0 @@
-import QtQuick 2.13
-import QtQml 2.12
-import QtQuick.Controls 2.2
-import QtQuick.Layouts 1.12
-
-Page {
-    Flickable {
-        anchors.left: parent.left
-        anchors.top: parent.top
-        anchors.right: lastActionsPanel.left
-        anchors.bottom: parent.bottom
-
-        leftMargin: 30 * pt
-        topMargin: 30 * pt
-        rightMargin: 30 * pt
-
-        TextArea.flickable: DapUiQmlWidgetConsoleForm {}
-
-        ScrollBar.vertical: ScrollBar{}
-    }
-
-    DapUiQmlWidgetConsoleLastActionsForm {
-        id: lastActionsPanel
-    }
-}
diff --git a/KelvinDashboardGUI/DapUiQmlScreenMainWindowForm.ui.qml b/KelvinDashboardGUI/DapUiQmlScreenMainWindowForm.ui.qml
index da3b890a6..2604654a6 100644
--- a/KelvinDashboardGUI/DapUiQmlScreenMainWindowForm.ui.qml
+++ b/KelvinDashboardGUI/DapUiQmlScreenMainWindowForm.ui.qml
@@ -64,7 +64,7 @@ Page {
                     }
                     ListElement {
                         name:  qsTr("Console")
-                        page: "DapUiQmlScreenConsoleForm.ui.qml"
+                        page: "DapUiQmlScreenConsoleForm.qml"
                         source: "qrc:/Resources/Icons/defaul_icon.png"
                     }
                     ListElement {
diff --git a/KelvinDashboardGUI/DapUiQmlWidgetConsoleForm.qml b/KelvinDashboardGUI/DapUiQmlWidgetConsoleForm.qml
index 49b8d5faf..5c11bd902 100644
--- a/KelvinDashboardGUI/DapUiQmlWidgetConsoleForm.qml
+++ b/KelvinDashboardGUI/DapUiQmlWidgetConsoleForm.qml
@@ -1,59 +1,87 @@
 import QtQuick 2.13
 import QtQuick.Controls 2.5
 
-TextArea {
-    property int positionLine: 2
-
-    id: txtCommands
-    anchors.fill: parent
-
-    text: "> "
-    wrapMode: TextArea.Wrap
-    color: "#707070"
-    font.family: "Roboto"
-    font.pixelSize: 20 * pt
-
-    Keys.onPressed: {
-
-        switch(event.key)
-        {
-        case Qt.Key_Backspace:
-            event.accepted = (txtCommands.cursorPosition <= txtCommands.positionLine);
-            return;
-        default: break;
-        }
+Rectangle {
+    Text {
+        id: promt
+        anchors.left: parent.left
+        anchors.top: consoleCmd.top
+        anchors.bottom: parent.bottom
+        verticalAlignment: Qt.AlignVCenter
+        text: ">"
+        color: "#707070"
+        font.family: "Roboto"
+        font.pixelSize: 20 * pt
     }
 
-    Keys.onUpPressed: {
-        if(txtCommands.positionLine != txtCommands.text.length)
-            txtCommands.remove(txtCommands.positionLine, txtCommands.text.length);
-        txtCommands.text += dapConsoleModel.getCommandUp();
-    }
+    TextArea {
+        id: consoleCmd
+        anchors.left: promt.right
+        anchors.bottom: parent.bottom
+        anchors.right: parent.right
+        height: contentChildren.height
+        wrapMode: TextArea.Wrap
+        color: "#707070"
+        font.family: "Roboto"
+        font.pixelSize: 20 * pt
+        focus: true
 
-    Keys.onDownPressed: {
-        if(txtCommands.positionLine != txtCommands.text.length)
-            txtCommands.remove(txtCommands.positionLine, txtCommands.text.length);
-        txtCommands.text += dapConsoleModel.getCommandDown();
-    }
+        Keys.onUpPressed: {
+            consoleCmd.text = dapConsoleModel.getCommandUp();
+        }
 
-    Keys.onReturnPressed: {
-        txtCommands.readOnly = true;
-        dapConsoleModel.receiveRequest(txtCommands.text.slice(positionLine, txtCommands.text.length));
-    }
+        Keys.onDownPressed: {
+            consoleCmd.text = dapConsoleModel.getCommandDown();
+        }
 
-    onCursorPositionChanged: {
-        if(txtCommands.cursorPosition <= txtCommands.positionLine) {
-            txtCommands.cursorPosition = txtCommands.positionLine;
+        Keys.onReturnPressed: {
+            dapConsoleModel.receiveRequest(consoleCmd.text);
+            txtCommand.append("> " + consoleCmd.text);
+            consoleCmd.text = "";
         }
     }
 
-    Connections {
-        target: dapConsoleModel
-        onSendResponse: {
-            txtCommands.readOnly = false;
-            txtCommands.append(response);
-            txtCommands.append("> ");
-            txtCommands.positionLine = txtCommands.cursorPosition;
+    ScrollView {
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.right: parent.right
+        anchors.bottom: consoleCmd.top
+
+        /*TextArea.flickable: */TextArea {
+            id: txtCommand
+            text: dapConsoleModel.getCmdHistory();
+            wrapMode: TextArea.Wrap
+            color: "#707070"
+            font.family: "Roboto"
+            font.pixelSize: 20 * pt
+            focus: false
+
+//            Keys.onPressed: {
+//                switch(event.key)
+//                {
+//                case Qt.Key_Left: break;
+//                case Qt.Key_Right: break;
+//                case Qt.Key_Shift: break;
+//                case Qt.Key_Control: break;
+//                case Qt.Key_Up: break;
+//                case Qt.Key_Down: break;
+//                default: event.accepted = true; break;
+//                }
+//            }
+
+        }
+
+//        ScrollBar.vertical: ScrollBar{}
+
+        Connections {
+            target: dapConsoleModel
+            onSendResponse: {
+                txtCommand.append(response);
+            }
+
+            onCmdHistoryChanged: {
+                txtCommand.append(history);
+            }
         }
     }
 }
diff --git a/KelvinDashboardGUI/main.cpp b/KelvinDashboardGUI/main.cpp
index 7e765e08e..1032786fc 100755
--- a/KelvinDashboardGUI/main.cpp
+++ b/KelvinDashboardGUI/main.cpp
@@ -53,6 +53,7 @@ int main(int argc, char *argv[])
     dapServiceClient.init();
     controller.getWallets();
     controller.getHistory();
+    controller.getCmdHistory();
 
     DapScreenHistoryFilterModel::getInstance()
             .setSourceModel(&DapScreenHistoryModel::getInstance());
diff --git a/KelvinDashboardGUI/qml.qrc b/KelvinDashboardGUI/qml.qrc
index 4ad984167..908f54038 100755
--- a/KelvinDashboardGUI/qml.qrc
+++ b/KelvinDashboardGUI/qml.qrc
@@ -56,7 +56,7 @@
         <file>DapUiQmlWidgetLastActions.qml</file>
         <file>DapUiQmlWidgetLastActionsForm.ui.qml</file>
         <file>DapUiQmlScreenHistoryForm.ui.qml</file>
-        <file>DapUiQmlScreenConsoleForm.ui.qml</file>
+        <file>DapUiQmlScreenConsoleForm.qml</file>
         <file>DapUiQmlWidgetConsoleForm.qml</file>
         <file>DapUiQmlWidgetConsoleLastActionsForm.qml</file>
         <file>DapUiQmlWidgetConsoleLastActionsDelegateForm.qml</file>
diff --git a/KelvinDashboardService/DapChainConsoleHandler.cpp b/KelvinDashboardService/DapChainConsoleHandler.cpp
index 8b3403e7c..ce3706d48 100644
--- a/KelvinDashboardService/DapChainConsoleHandler.cpp
+++ b/KelvinDashboardService/DapChainConsoleHandler.cpp
@@ -1,8 +1,33 @@
 #include "DapChainConsoleHandler.h"
 
+#define MAX_COUNT_CMD 50
+
 DapChainConsoleHandler::DapChainConsoleHandler(QObject *parent) : QObject(parent)
 {
+    m_File = new QFile("cmd_log.txt", this);
+    m_File->open(QIODevice::Append | QIODevice::ReadWrite);
+}
+
+QString DapChainConsoleHandler::getHistory() const
+{
+    if(!m_File->isOpen()) return QString();
+
+    quint8 countCmd = 0;
+    while (m_File->pos() > 0)
+    {
+        QByteArray symbol =  m_File->read(1);
+        if(symbol == ">")
+        {
+            ++countCmd;
+            if(countCmd == MAX_COUNT_CMD) break;
+        }
 
+        m_File->seek(m_File->pos() - 2);
+    }
+
+    QByteArray lastCmd = m_File->read(m_File->size() - m_File->pos());
+
+    return QString::fromStdString(lastCmd.toStdString());
 }
 
 QString DapChainConsoleHandler::getResult(const QString& aQuery) const
@@ -11,5 +36,16 @@ QString DapChainConsoleHandler::getResult(const QString& aQuery) const
     process.start(QString(CLI_PATH) + " " + aQuery);
     process.waitForFinished(-1);
 
-    return QString::fromStdString(process.readAll().toStdString());
+    QByteArray returnSymbol = "\n";
+
+#ifdef Q_OS_WIN
+    returnSymbol.prepend("\r");
+#endif
+
+    QByteArray result = process.readAll();
+    m_File->write("> " + aQuery.toUtf8() + returnSymbol);
+    m_File->write(result + returnSymbol);
+    m_File->flush();
+
+    return QString::fromStdString(result.toStdString());
 }
diff --git a/KelvinDashboardService/DapChainConsoleHandler.h b/KelvinDashboardService/DapChainConsoleHandler.h
index 6864a5d90..f64fe62cf 100644
--- a/KelvinDashboardService/DapChainConsoleHandler.h
+++ b/KelvinDashboardService/DapChainConsoleHandler.h
@@ -3,14 +3,20 @@
 
 #include <QObject>
 #include <QProcess>
+#include <QDebug>
+#include <QFile>
 
 class DapChainConsoleHandler : public QObject
 {
     Q_OBJECT
 
+private:
+    QFile * m_File;
+
 public:
     explicit DapChainConsoleHandler(QObject *parent = nullptr);
 
+    QString getHistory() const;
     QString getResult(const QString& aQuery) const;
 };
 
diff --git a/KelvinDashboardService/DapChainDashboardService.cpp b/KelvinDashboardService/DapChainDashboardService.cpp
index cdc89599d..c9b7b6494 100755
--- a/KelvinDashboardService/DapChainDashboardService.cpp
+++ b/KelvinDashboardService/DapChainDashboardService.cpp
@@ -96,6 +96,11 @@ QString DapChainDashboardService::getQueryResult(const QString& aQuery) const
     return m_pDapChainConsoleHandler->getResult(aQuery);
 }
 
+QString DapChainDashboardService::getCmdHistory() const
+{
+    return m_pDapChainConsoleHandler->getHistory();
+}
+
 void DapChainDashboardService::doRequestWallets()
 {
     m_pDapChainHistoryHandler->onRequestNewHistory(m_pDapChainWalletHandler->getWallets());
diff --git a/KelvinDashboardService/DapChainDashboardService.h b/KelvinDashboardService/DapChainDashboardService.h
index d2448c87d..5f9837d0d 100755
--- a/KelvinDashboardService/DapChainDashboardService.h
+++ b/KelvinDashboardService/DapChainDashboardService.h
@@ -108,6 +108,8 @@ public slots:
 
     QString getQueryResult(const QString& aQuery) const;
 
+    QString getCmdHistory() const;
+
 private slots:
     void doRequestWallets();
     void doSendNewHistory(const QVariant& aData);
-- 
GitLab