Index: denali.pro =================================================================== diff -u -r561055268da68e24fe91a1148b76bf1785dae14d -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- denali.pro (.../denali.pro) (revision 561055268da68e24fe91a1148b76bf1785dae14d) +++ denali.pro (.../denali.pro) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -74,7 +74,8 @@ sources/storage/logger.cpp \ sources/storage/settings.cpp \ sources/utility/crc.cpp \ - sources/utility/format.cpp + sources/utility/format.cpp \ + sources/utility/types.cpp RESOURCES += \ denali.qrc Index: denali.qrc =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- denali.qrc (.../denali.qrc) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ denali.qrc (.../denali.qrc) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -29,6 +29,7 @@ sources/gui/qml/components/ModalDialog.qml sources/gui/qml/components/BackButton.qml sources/gui/qml/components/USBButton.qml + sources/gui/qml/components/ExportButton.qml qtquickcontrols2.conf Index: main.cpp =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- main.cpp (.../main.cpp) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ main.cpp (.../main.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -26,6 +26,7 @@ #include #include #include +#include // Project #include "maintimer.h" @@ -34,6 +35,7 @@ #include "messagedispatcher.h" #include "applicationcontroller.h" #include "guicontroller.h" +#include "logger.h" #ifdef UNIT_TEST #include TEST_CLASS_INCLUDE @@ -51,6 +53,8 @@ // Qt Core Application Initialization QApplication app(argc, argv); + app.thread()->setObjectName("Main Thread"); + qDebug() << app.thread()->objectName(); QApplication::setApplicationName(QLatin1String("Denali")); QApplication::setOrganizationName(QLatin1String("Diality Inc.")); @@ -89,19 +93,35 @@ //! - Initializing File Handler _FileHandler->init(); + //! - Initializing Logger + //QThread _Logger_Thread; + //_Logger_Thread.setObjectName("Logger Thread"); + _Logger->init(); + //_Logger->moveToThread(&_Logger_Thread); + //QObject::connect(&_Logger_Thread, SIGNAL(finished()), _Logger, SLOT(deleteLater())); + //_Logger_Thread.start(); + + LOG_EVENT(QObject::tr("Application Started")); + //! - Initializing Main Timer _MainTimer->init(); + LOG_EVENT(QObject::tr("Main Timer Initialized")); //! - Initializing CanBus Interface _CanInterface->init(); _CanInterface->enableConsoleOut(_consoleoutCanInterface); + LOG_EVENT(QObject::tr("CanInterface Initialized")); + LOG_EVENT(QObject::tr("console out CanInterface %1").arg(_consoleoutCanInterface)); //! - Initializing CanBus Message Handler _FrameInterface->init(); + LOG_EVENT(QObject::tr("FrameInterface Initialized")); //! - Initializing CanBus Message Dispatcher _MessageDispatcher->init(); _MessageDispatcher->enableConsoleOut(_consoleoutFrameInterface); + LOG_EVENT(QObject::tr("MessageDispatcher Initialized")); + LOG_EVENT(QObject::tr("console out MessageDispatcher %1").arg(_consoleoutFrameInterface)); //! - Initializing Application Controller _ApplicationController->init(); @@ -116,6 +136,7 @@ ////! - Initializing GUI Controller _GuiController->init(); + LOG_EVENT(QObject::tr("Gui Controller Initialized")); //! - Initialize the Qml Viewer and starts GUI startGui(); Index: sources/applicationcontroller.cpp =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/applicationcontroller.cpp (.../applicationcontroller.cpp) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/applicationcontroller.cpp (.../applicationcontroller.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -20,6 +20,7 @@ #include "maintimer.h" #include "guicontroller.h" #include "messagedispatcher.h" +#include "logger.h" // Singleton SINGLETON_INIT(ApplicationController) @@ -67,7 +68,10 @@ connect(_FileHandler , SIGNAL(didUSBDriveRemove()), this , SLOT( onUSBDriveRemove())); + connect(_GuiController , SIGNAL(didExportLog()), + this , SLOT( onExportLog())); + } /*! @@ -117,6 +121,11 @@ emit didUSBDriveRemove(); } +void ApplicationController::onExportLog() +{ + _Logger->doExportLog(); +} + /*! * \brief ApplicationController::keepAlive * \details This is the message which has to be send over the CANBUS Index: sources/applicationcontroller.h =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/applicationcontroller.h (.../applicationcontroller.h) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/applicationcontroller.h (.../applicationcontroller.h) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -57,6 +57,8 @@ void onUSBDriveUmount(); void onUSBDriveRemove(); + void onExportLog (); + signals: void didActionReceive (GuiActionType vAction, const QVariantList &vData); // UI <= HD/DG void didActionTransmit(GuiActionType vAction, const QVariantList &vData); // UI => HD/DG Index: sources/canbus/caninterface.cpp =================================================================== diff -u -r561055268da68e24fe91a1148b76bf1785dae14d -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/canbus/caninterface.cpp (.../caninterface.cpp) (revision 561055268da68e24fe91a1148b76bf1785dae14d) +++ sources/canbus/caninterface.cpp (.../caninterface.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -17,6 +17,7 @@ #include // Project +#include "logger.h" #include "frameinterface.h" // namespace @@ -41,7 +42,8 @@ QString mError; _canDevice = QCanBus::instance()->createDevice(_canType, _canInterface, &mError); if (!_canDevice) { - status(tr("Error: Device Creation"),mError); + status(tr("Device Creation"), mError); + LOG_ERROR(status()); return false; } @@ -50,12 +52,14 @@ initConnections(); if (!_canDevice->connectDevice()) { - status(tr("Error: Connection")); + status(tr("Connection")); + LOG_ERROR(status()); delete _canDevice; _canDevice = nullptr; return false; } status(tr("Connected")); + LOG_EVENT(status()); return true; } Index: sources/canbus/frameinterface.cpp =================================================================== diff -u -r9552cc674525d9496d02b104a2ba86b37472964d -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/canbus/frameinterface.cpp (.../frameinterface.cpp) (revision 9552cc674525d9496d02b104a2ba86b37472964d) +++ sources/canbus/frameinterface.cpp (.../frameinterface.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -18,6 +18,7 @@ #include // Project +#include "logger.h" #include "maintimer.h" #include "messagedispatcher.h" #include "caninterface.h" @@ -74,7 +75,7 @@ QCanBusFrame mFrame; mFrame.setFrameId(vFrameId); if (vData.length() > Can::eLenCanFrame) { - qDebug() << "Error :" << tr("Payload can't be larger than %1 bytes").arg(Can::eLenCanFrame); + LOG_ERROR(tr("Payload can't be larger than %1 bytes").arg(Can::eLenCanFrame)); return; } mFrame.setPayload(vData); @@ -154,8 +155,8 @@ ChannelGroup channelGroup = checkChannel(mFrameId, &ok); if (!ok){ - qDebug() << "ERROR :" << "Unexpected Channel"; - qDebug() << Format::toHexString(mFrameId, false, eLenChannelDigits) + " -- " + vFrame.payload().toHex(' '); + LOG_ERROR("Unexpected Channel\r\n" + + Format::toHexString(mFrameId, false, eLenChannelDigits) + " -- " + vFrame.payload().toHex(' ')); return; } Index: sources/canbus/messagebuilder.cpp =================================================================== diff -u -r48379ed048f0ed52263ae3e042fe3cd076895e32 -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/canbus/messagebuilder.cpp (.../messagebuilder.cpp) (revision 48379ed048f0ed52263ae3e042fe3cd076895e32) +++ sources/canbus/messagebuilder.cpp (.../messagebuilder.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -17,6 +17,7 @@ #include // Project +#include "logger.h" #include "crc.h" #include "format.h" @@ -90,7 +91,7 @@ vPayload += mAction & 0xFF; // low byte } else { QString mHexString = Format::toHexString(vAction, false, eLenMessageIDDigits); - qDebug() << "ERROR :" << tr("Incorrect Action ID '%1'").arg(mHexString); + LOG_ERROR(tr("Incorrect Action ID '%1'").arg(mHexString)); return false; } return true; @@ -118,8 +119,8 @@ } if (vData.length() < len) { QString mHexString = Format::toHexString(vAction, false, eLenMessageIDDigits); - qDebug() << "ERROR :" << tr("Not enough data has been provided for the Message ID '%1'").arg(mHexString); - qDebug() << vData.toHex('.'); + LOG_ERROR(tr("Not enough data has been provided for the Message ID '%1'").arg(mHexString)); + LOG_ERROR(vData.toHex('.')); return false; } vPayload += len; @@ -213,7 +214,7 @@ vMessage.data = getData (mPayload, vMessage.length); vMessage.initialized = true; } else { // Expected Header but got pure data - qDebug() << "ERROR :" << tr("Expected Header, got frame without Sync byte"); + LOG_ERROR(tr("Expected Header, got frame without Sync byte")); printPayload(vPayload, false ,vCan_Id); return false; } @@ -231,9 +232,9 @@ quint8 mExpected = 0; quint8 mBeenRead = 0; if ( ! checkCRC(crcData, mExpected, mBeenRead ) ) { // CRC is always next byte after Data - qDebug() << "ERROR :" << tr("CRC error, expected %1 but got %2") + LOG_ERROR(tr("CRC error, expected %1 but got %2") .arg(Format::toHexString(mExpected, true, eLenCRCDigits)) - .arg(Format::toHexString(mBeenRead, true, eLenCRCDigits)); + .arg(Format::toHexString(mBeenRead, true, eLenCRCDigits))); return false; } } Index: sources/canbus/messagedispatcher.cpp =================================================================== diff -u -rd3f98384e9400f8acb84c88dee75f1c480986998 -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/canbus/messagedispatcher.cpp (.../messagedispatcher.cpp) (revision d3f98384e9400f8acb84c88dee75f1c480986998) +++ sources/canbus/messagedispatcher.cpp (.../messagedispatcher.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -16,6 +16,7 @@ // Qt // Project +#include "logger.h" #include "applicationcontroller.h" #include "frameinterface.h" @@ -113,13 +114,13 @@ { QByteArray mData; if (! _interpreter.interpretMessage(vActionId, vData, mData)) { - qDebug() << "Error :" << tr("Incorrect Message can't be interpreted"); + LOG_ERROR(tr("Incorrect Message, can't be interpreted")); return; } FrameList frameList; if ( ! _builder.buildFrames(vActionId, mData, frameList) ) { - qDebug() << "Error :" << tr("Incorrect Message can't be built"); + LOG_ERROR(tr("Incorrect Message can't be built")); return; } for (const auto &frame : frameList) { Index: sources/canbus/messageglobals.h =================================================================== diff -u -r2fdeb1c461dde1b7b8bffcc5b814736190f98988 -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/canbus/messageglobals.h (.../messageglobals.h) (revision 2fdeb1c461dde1b7b8bffcc5b814736190f98988) +++ sources/canbus/messageglobals.h (.../messageglobals.h) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -30,7 +30,7 @@ const QHash payloadLen { {GuiActionType::PowerOff , 1 }, {GuiActionType::KeepAlive , 0 }, - {GuiActionType::BloodFlow , 7 * 4 } , // 6 parameters each 4bytes + {GuiActionType::BloodFlow , 7 * 4 } , // 7 parameters each 4bytes {GuiActionType::String , 255 }, }; Index: sources/canbus/messageinterpreter.cpp =================================================================== diff -u -r2fdeb1c461dde1b7b8bffcc5b814736190f98988 -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/canbus/messageinterpreter.cpp (.../messageinterpreter.cpp) (revision 2fdeb1c461dde1b7b8bffcc5b814736190f98988) +++ sources/canbus/messageinterpreter.cpp (.../messageinterpreter.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -16,6 +16,7 @@ // Qt // Project +#include "logger.h" #include "format.h" @@ -53,7 +54,7 @@ vPayload += tmp; } else { QString mActionIdHexString = Format::toHexString(vActionId); - qDebug() << "ERROR :" << tr("Incorrect data for Message ID (UI) '%1'").arg(mActionIdHexString); + LOG_ERROR(tr("Incorrect data for Message ID (UI) '%1'").arg(mActionIdHexString)); ok = false; } break; @@ -69,7 +70,7 @@ default: QString mActionIdHexString = Format::toHexString(vActionId); - qDebug() << "ERROR :" << tr("Unknown Message ID (UI) '%1'").arg(mActionIdHexString); + LOG_ERROR(tr("Unknown Message ID (UI) '%1'").arg(mActionIdHexString)); ok = false; break; } @@ -130,6 +131,7 @@ if (ok) { vData += mShowHide; } + LOG_DATUM(QString("Power Off (%1)").arg(mShowHide)); break; } @@ -142,6 +144,15 @@ types::F32 mMotorCtlCurrent ; types::F32 mPWMDtCycle ; ok = getBloodFlowData(vMessage, mFlowSetPoint, mMeasuredFlow, mRotorSpeed, mMotorSpeed, mMotorCtlSpeed, mMotorCtlCurrent, mPWMDtCycle); + LOG_DATUM(QString("Blood Flow(%1, %2, %3, %4, %5, %6, %7)") + .arg(mFlowSetPoint .value) + .arg(mMeasuredFlow .value) + .arg(mRotorSpeed .value) + .arg(mMotorSpeed .value) + .arg(mMotorCtlSpeed .value) + .arg(mMotorCtlCurrent .value) + .arg(mPWMDtCycle .value) + ); if (ok) { vData += mFlowSetPoint .value; vData += mMeasuredFlow .value; @@ -220,7 +231,7 @@ } if ( vMessage.data.length() < payloadLen[GuiActionType::BloodFlow] ) { QString mActionIdHexString = Format::toHexString(vMessage.actionId); - qDebug() << "ERROR :" << tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString); + LOG_ERROR(tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString)); return false; } int i = 0; @@ -306,7 +317,7 @@ vShowHide = tmp; } else { QString mActionIdHexString = Format::toHexString(vMessage.actionId); - qDebug() << "ERROR :" << tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString); + LOG_ERROR(tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString)); ok = false; } return ok; Index: sources/gui/guicontroller.cpp =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/gui/guicontroller.cpp (.../guicontroller.cpp) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/gui/guicontroller.cpp (.../guicontroller.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -120,6 +120,11 @@ emit didUSBDriveUmount(); } +void GuiController::doExportLog() +{ + emit didExportLog(); +} + void GuiController::onUSBDriveRemove() { emit didUSBDriveRemove(); Index: sources/gui/guicontroller.h =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/gui/guicontroller.h (.../guicontroller.h) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/gui/guicontroller.h (.../guicontroller.h) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -43,6 +43,7 @@ void doActionTransmit(GuiActionType vAction, const QVariantList &vData); // UI => HD/DG void doUSBDriveUmount(); // UI => OS + void doExportLog (); // UI => OS private slots: // Should be private for thread safety and is connected internally. @@ -58,6 +59,8 @@ void didUSBDriveMount (); void didUSBDriveUmount(); void didUSBDriveRemove(); + + void didExportLog(); }; } Index: sources/gui/guiglobals.cpp =================================================================== diff -u -r3a68ae894549f9b0664ddb817458ca771ec3dd30 -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/gui/guiglobals.cpp (.../guiglobals.cpp) (revision 3a68ae894549f9b0664ddb817458ca771ec3dd30) +++ sources/gui/guiglobals.cpp (.../guiglobals.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -17,6 +17,7 @@ #include // Project +#include "logger.h" #include "guiview.h" namespace Gui { @@ -59,7 +60,7 @@ } else if (vStatus == QQuickView::Error || vStatus == QQuickView::Null) { for (const auto &error : _viewer->errors()) { - qDebug() << "ERROR :" << QObject::tr("Application Terminated: %1").arg(error.toString()); + LOG_ERROR(QObject::tr("Application Terminated: %1").arg(error.toString())); } QCoreApplication::exit(-1); } Index: sources/gui/guiview.cpp =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/gui/guiview.cpp (.../guiview.cpp) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/gui/guiview.cpp (.../guiview.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -49,6 +49,10 @@ this , SLOT( doUSBDriveMount ())); connect(_GuiController, SIGNAL(didUSBDriveRemove()), this , SLOT( doUSBDriveRemove())); + + // From UI : Export Log + connect(this , SIGNAL(didExportLog()), + _GuiController, SLOT( doExportLog())); } void GuiView::onActionReceive (GuiActionType vAction, const QVariantList &vData) @@ -84,3 +88,8 @@ { emit didUSBDriveUmount(); } + +void GuiView::doExportLog() +{ + emit didExportLog(); +} Index: sources/gui/guiview.h =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/gui/guiview.h (.../guiview.h) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/gui/guiview.h (.../guiview.h) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -45,6 +45,7 @@ void doActionTransmit(GuiActionType vAction, const QVariantList &vData); // UI => HD/DG void doActionTransmit(GuiActionType vAction, const QVariant &vData); // UI => HD/DG void doUSBDriveUmount(); + void doExportLog (); signals: void didActionReceive (GuiActionType vAction, const QVariantList &vData); // UI <= HD/DG @@ -53,5 +54,7 @@ void didUSBDriveMount (); void didUSBDriveUmount(); void didUSBDriveRemove(); + + void didExportLog(); }; } Index: sources/gui/qml/components/ExportButton.qml =================================================================== diff -u --- sources/gui/qml/components/ExportButton.qml (revision 0) +++ sources/gui/qml/components/ExportButton.qml (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -0,0 +1,47 @@ +/*! + * + * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. + * \copyright \n + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, \n + * IN PART OR IN WHOLE, \n + * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. \n + * + * \file ExportButton.qml + * \date 2019/12/26 + * \author Behrouz NematiPour + * + */ + +// Qt +import QtQuick 2.12 + +// Qml imports +import "qrc:/globals" +import "qrc:/components" + +TouchRect { id : _root + width: 50 + height: width + x: width - 10 + animated: true + + text.text: qsTr("Export") + text.font.pixelSize: Fonts.fontPixelButton * 0.75 + button.onPressed: { + _GuiView.doExportLog() + //animate(true) + } + + Connections { target: _GuiView + onDidUSBDriveUmount: { + _root.disabled = true + } + onDidUSBDriveRemove: { + //_root.animate(false) + _root.disabled = true + } + onDidUSBDriveMount: { + _root.disabled = false + } + } +} Index: sources/gui/qml/components/USBButton.qml =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/gui/qml/components/USBButton.qml (.../USBButton.qml) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/gui/qml/components/USBButton.qml (.../USBButton.qml) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -27,11 +27,6 @@ loops: Animation.Infinite duration: 1000 // 1 sec - anchors { - top : parent.top - topMargin : (Variables.headerHeight - Variables.logoHeight) / 2 - rightMargin : (Variables.headerHeight - Variables.logoHeight) / 2 - } text.text: qsTr("USB") text.font.pixelSize: Fonts.fontPixelButton * 0.75 button.onPressed: { Index: sources/gui/qml/pages/TreatmentHome.qml =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/gui/qml/pages/TreatmentHome.qml (.../TreatmentHome.qml) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/gui/qml/pages/TreatmentHome.qml (.../TreatmentHome.qml) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -35,7 +35,24 @@ // exported properties // - USBButton { } + USBButton { + x: 50 + anchors { + top : parent.top + topMargin : (Variables.headerHeight - Variables.logoHeight) / 2 + rightMargin : (Variables.headerHeight - Variables.logoHeight) / 2 + } + } + ExportButton { + x: 150 + width: 150 + height: 50 + anchors { + top : parent.top + topMargin : (Variables.headerHeight - Variables.logoHeight) / 2 + rightMargin : (Variables.headerHeight - Variables.logoHeight) / 2 + } + } TreatmentStart { id : _treatmentStart onBackPressed: { Index: sources/main.h =================================================================== diff -u -r781e62c996e81897517fbdb1bc79fe3bbcf165c1 -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/main.h (.../main.h) (revision 781e62c996e81897517fbdb1bc79fe3bbcf165c1) +++ sources/main.h (.../main.h) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -19,13 +19,19 @@ // Qt #include +#include // Project #define SINGLETON_DECL(vCLASS) \ private: \ static vCLASS *_instance; \ explicit vCLASS(QObject *parent = nullptr); \ + virtual ~vCLASS() { \ + delete _instance; \ + } \ + vCLASS(vCLASS const &) = delete; \ + vCLASS & operator = (vCLASS const &) = delete; \ public: \ static vCLASS *I() { \ if (!_instance) \ Index: sources/storage/filehandler.cpp =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/storage/filehandler.cpp (.../filehandler.cpp) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/storage/filehandler.cpp (.../filehandler.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -21,6 +21,7 @@ //Qt #include #include +#include // Project #include "maintimer.h" @@ -49,10 +50,16 @@ return true; } +void FileHandler::quit() +{ +} + void FileHandler::initConnections() { connect(_MainTimer , SIGNAL( didTimeout()), this , SLOT(onMainTimerTimeout())); + //connect(&_processCopyFolder, SIGNAL(finished(int)), + // this , SLOT(copyFolder)); } bool FileHandler::usbSeek(QString &vDevice) { @@ -68,6 +75,34 @@ return false; } +bool FileHandler::write(const QString &vFileName, const QString &vContent, bool vAppend) +{ + QFile file(vFileName); + QIODevice::OpenMode openMode = vAppend ? + QFile::Text | QFile::Append : + QFile::Text | QFile::WriteOnly; + if (! file.open(openMode)) { + qDebug() << "ERROR :" << tr("Can't open file for write (%1)").arg(vFileName); + return false; + } + QTextStream out(&file); + out << vContent; + out.flush(); + return true; +} + +bool FileHandler::read(const QString &vFileName, QString &vContent) +{ + QFile file(vFileName); + if (! file.open(QFile::Text | QFile::ReadOnly)) { + qDebug() << "ERROR :" << tr("Can't open file for read (%1)").arg(vFileName); + return false; + } + QTextStream in(&file); + vContent = in.readAll(); + return true; +} + void FileHandler::doUSBDriveMount() { QString device = ""; @@ -83,11 +118,43 @@ } } +bool FileHandler::doWrite(const QString &vFileName, const QString &vContent, bool vAppend) +{ + bool ok = write(vFileName, vContent, vAppend); + if (ok) { + emit didWrite(vFileName); + } + return ok; +} + +bool FileHandler::doRead(const QString &vFileName) +{ + QString mContent; + bool ok = read(vFileName, mContent); + if (ok) { + emit didRead(vFileName, mContent); + } + return ok; +} + +bool FileHandler::doExportFolder(const QString &vFolder) +{ + if ( _mounted ) { + QString cp = "cp"; + QStringList arguments; + arguments << "-r" << vFolder << _usbMount; + _processCopyFolder.start(cp, arguments); + return true; + } + return false; +} + void FileHandler::usbError(const QString &vDevice) { switch (errno) { case EBUSY: qDebug() << tr("%1 - Device or resource busy (%2)").arg(errno).arg(vDevice); + _mounted = true; break; default: qDebug() << tr("%1 - %2 (%3 , %4)").arg(errno).arg(strerror(errno)).arg(vDevice).arg(_usbMount); @@ -101,7 +168,7 @@ _usbDrive = vDevice.toLatin1().constData(); ok = mount(_usbDrive, _usbMount, _usbfsys, 0, "") == 0; if (ok) { - _mounted = false; + _mounted = true; qDebug() << tr("USB flash drive %1 has been mounted on %2").arg(vDevice).arg(_usbMount); emit didUSBDriveMount(); } else { @@ -115,6 +182,7 @@ bool ok; ok = umount(vDevice.toLatin1().constData()) == 0; if (ok) { + _mounted = false; emit didUSBDriveUmount(); } else { // the error is irrelevant, commented out for now Index: sources/storage/filehandler.h =================================================================== diff -u -rfbeafa0714f065bce0403e2e8ce68f6d8fbea6bd -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/storage/filehandler.h (.../filehandler.h) (revision fbeafa0714f065bce0403e2e8ce68f6d8fbea6bd) +++ sources/storage/filehandler.h (.../filehandler.h) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -15,7 +15,7 @@ // Qt #include -#include +#include // Project #include "main.h" @@ -35,15 +35,14 @@ bool _umounted = false; const char *_usbDrive = ""; + QProcess _processCopyFolder; + // Singleton SINGLETON_DECL(FileHandler) public: bool init(); void quit(); - bool doExport(); - bool doImport(); - bool umounted( ) const; void umounted(bool vUmounted); @@ -52,14 +51,25 @@ bool usbSeek(QString &vDevice); + bool write(const QString &vFileName, const QString &vContent, bool vAppend); + bool read (const QString &vFileName, QString &vContent); + signals: void didUSBDriveMount (); void didUSBDriveUmount(); void didUSBDriveRemove(); + void didWrite(const QString &vFileName); + void didRead (const QString &vFileName, const QString &vContent); + public slots: void doUSBDriveMount (); + bool doWrite(const QString &vFileName, const QString &vContent, bool vAppend = true); + bool doRead (const QString &vFileName); + + bool doExportFolder(const QString &vFolder); + private slots: bool usbMount (const QString &vDevice); bool usbUmount(const QString &vDevice); Index: sources/storage/logger.cpp =================================================================== diff -u -r781e62c996e81897517fbdb1bc79fe3bbcf165c1 -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/storage/logger.cpp (.../logger.cpp) (revision 781e62c996e81897517fbdb1bc79fe3bbcf165c1) +++ sources/storage/logger.cpp (.../logger.cpp) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -13,9 +13,103 @@ */ #include "logger.h" +// Qt +#include +#include +#include +#include + +// Project +#include "filehandler.h" + using namespace Storage; -Logger::Logger(QObject *parent) : QObject(parent) +// Singleton +SINGLETON_INIT(Logger) + + +Logger::Logger(QObject *parent) : QObject(parent) { } + +bool Logger::init() { + checkLogPath(); + initConnections(); + return true; +} +void Logger::initConnections() { } + +void Logger::checkLogPath() +{ + setLogBasePath(); // try to use /media/sd_card on device + if (! setLogPath()) { // check and create log folders & if unsuccessful then + setLogBasePath(true); // try to use application folder + setLogPath ( ); // check and create log folders // Note: it may require to check for write access regarding device setup + } } + +void Logger::setLogBasePath(bool vUseApplicationDirPath) +{ + if (vUseApplicationDirPath) { + _dir.setPath(qApp->applicationDirPath()); + qDebug() << "WARNING :" << tr("Application Dir Path used for events logging (%1)").arg(_dir.path()); + } else { + _dir.setPath(_logBasePathName); + } +} + +bool Logger::setLogPath() +{ + bool ok = true; + ok = ok && setLogPath(eLogDatum); + ok = ok && setLogPath(eLogEvent); + ok = ok && setLogPath(eLogError); + return ok; +} + +bool Logger::setLogPath(Logger::LogType_Enum vLogType) +{ + _logPathNames[vLogType] = _dir.path() + "/" + _logBasePathNames[vLogType]; + if ( ! _dir.exists(_logBasePathNames[vLogType]) ) { + if ( ! _dir.mkpath(_logBasePathNames[vLogType]) ) { + qDebug() << "ERROR :" << tr("Can't create %1 log path (%2)") + .arg(_logPrefix[vLogType]) + .arg(_logPathNames[vLogType]) + ; + return false; + } + } + return true; +} + +bool Logger::log(const QString &vContent, LogType_Enum vLogType) { + QString date = QDate::currentDate().toString(_dateFormat); + QString mContent; + + switch (vLogType) { + case eLogDatum: + case eLogEvent: + case eLogError: + break; + default: + Q_ASSERT_X(false, "Logger::log", "Incorrect type of logging"); + } + mContent += _logPrefix[vLogType]; + mContent += _prefixSeparator; + mContent += QTime::currentTime().toString(_timeFormat); + mContent += _timeSeparator + vContent + "\r\n"; + QString fileName = date + _dateSeparator + _logFileName; + _FileHandler->doWrite(_logPathNames[vLogType] + fileName, mContent); + qDebug() << mContent; + return true; +} + +void Logger::doLog(const QString &vContent, LogType_Enum vLogType) +{ + emit didLog(log(vContent, vLogType)); +} + +void Logger::doExportLog() +{ + _FileHandler->doExportFolder(_logBasePathNameExport); +} Index: sources/storage/logger.h =================================================================== diff -u -r781e62c996e81897517fbdb1bc79fe3bbcf165c1 -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/storage/logger.h (.../logger.h) (revision 781e62c996e81897517fbdb1bc79fe3bbcf165c1) +++ sources/storage/logger.h (.../logger.h) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -13,19 +13,84 @@ */ #pragma once +// Qt #include +#include +// Project +#include "main.h" + +// Define +#define _Logger Storage::Logger::I() +#define LOG_DATUM(vCONTENT) _Logger->doLog(vCONTENT, Storage::Logger::eLogDatum) +#define LOG_EVENT(vCONTENT) _Logger->doLog(vCONTENT, Storage::Logger::eLogEvent) +#define LOG_ERROR(vCONTENT) _Logger->doLog(vCONTENT, Storage::Logger::eLogError) + namespace Storage { class Logger : public QObject { Q_OBJECT + public: - explicit Logger(QObject *parent = nullptr); + enum LogType_Enum { + eLogDatum, + eLogEvent, + eLogError, + }; +private: + QDir _dir; + QHash _logPathNames; + QHash _logBasePathNames { + { eLogDatum, "log/event/" }, // "log/datum/" + { eLogEvent, "log/event/" }, + { eLogError, "log/error/" }, + }; + QHash _logPrefix { + { eLogDatum, "Datum" }, + { eLogEvent, "Event" }, + { eLogError, "Error" }, + }; + + const char *_logBasePathName = "/media/sd-card/"; + const char *_logBasePathNameExport = "/media/sd-card/log/"; + + const char *_logFileName = "denali.log"; + + const char *_dateFormat = "yyyy_MM_dd"; + const char *_timeFormat = "HH:mm:ss"; + + const char *_prefixSeparator = ": "; + const char *_dateSeparator = "_"; + const char *_timeSeparator = " , "; + + + + // Singleton + SINGLETON_DECL(Logger) + +public: + bool init(); + void quit(); + +private: + void initConnections(); + + void checkLogPath (); + void setLogBasePath(bool vUseApplicationDirPath = false); + bool setLogPath (); + bool setLogPath (LogType_Enum vLogType); + + bool log(const QString &vContent, LogType_Enum vLogType); + signals: + void didLog(bool ok); public slots: + void doLog(const QString &vContent, LogType_Enum vLogType); + void doExportLog(); }; } + Index: sources/utility/types.cpp =================================================================== diff -u --- sources/utility/types.cpp (revision 0) +++ sources/utility/types.cpp (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -0,0 +1,28 @@ +/*! + * + * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. + * copyright + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, + * IN PART OR IN WHOLE, + * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * file types.cpp + * date 12/26/2019 + * author Behrouz NematiPour + * + */ +#include "types.h" + +// Qt +#include + +// Project + +using namespace types; + +bool floatCompare(float f1, float f2) { + static constexpr auto epsilon = 1.0e-05f; + if (qAbs(f1 - f2) <= epsilon) + return true; + return qAbs(f1 - f2) <= epsilon * qMax(qAbs(f1), qAbs(f2)); +} Index: sources/utility/types.h =================================================================== diff -u -rfee7fabf49befb065c89248c19e15efc9ca194e4 -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 --- sources/utility/types.h (.../types.h) (revision fee7fabf49befb065c89248c19e15efc9ca194e4) +++ sources/utility/types.h (.../types.h) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) @@ -13,6 +13,11 @@ */ #pragma once +// Qt +#include + +// Project + namespace types { /*! @@ -35,4 +40,16 @@ quint8 bytes[sizeof(quint32)]; }; +/*! + * \brief The S32 union + * \details This is the union which will be used to extract the bytes of an signed int type value + * 4 bytes + */ +union S32 { + qint32 value = 0; + quint8 bytes[sizeof(qint32)]; +}; + +extern bool floatCompare(float f1, float f2); + }