From 2f009db53c237b043e79a9d3d2111dd7a9c503b2 Mon Sep 17 00:00:00 2001 From: Alexander <aleksandr.martynov@demlabs.net> Date: Wed, 16 Oct 2019 06:19:56 -0400 Subject: [PATCH] [*] update class DapSettings - fix arguments according to inner code style - add guard for geetting/setting group/value - delete useless temporary objects - delete useless virtual methods encrypt/decrypt. This method will added to future in special class --- CellFrameDashboard.pro | 3 +- .../CellFrameDashboardGUI.pro | 1 + .../DapServiceController.cpp | 28 +++ CellFrameDashboardGUI/DapServiceController.h | 11 + .../DapChainDashboardService.cpp | 3 + .../DapChainDashboardService.h | 3 + .../DapChainNodeNetworkHandler.cpp | 5 + .../DapChainNodeNetworkHandler.h | 5 + CellFrameDashboardService/main.cpp | 2 + CellFrameDashboardTests/.gitignore | 73 ++++++ .../CellFrameDashboardTests.pro | 18 ++ CellFrameDashboardTests/DapSettingsTests.cpp | 158 ++++++++++++ CellFrameDashboardTests/gtest_dependency.pri | 32 +++ CellFrameDashboardTests/main.cpp | 9 + libCellFrameDashboardCommon/DapSettings.cpp | 232 ++++++++++-------- libCellFrameDashboardCommon/DapSettings.h | 53 ++-- .../DapSettingsCipher.cpp | 6 +- .../DapSettingsCipher.h | 4 +- 18 files changed, 510 insertions(+), 136 deletions(-) create mode 100644 CellFrameDashboardTests/.gitignore create mode 100644 CellFrameDashboardTests/CellFrameDashboardTests.pro create mode 100644 CellFrameDashboardTests/DapSettingsTests.cpp create mode 100644 CellFrameDashboardTests/gtest_dependency.pri create mode 100644 CellFrameDashboardTests/main.cpp diff --git a/CellFrameDashboard.pro b/CellFrameDashboard.pro index 14df6c1..c8b3e54 100755 --- a/CellFrameDashboard.pro +++ b/CellFrameDashboard.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs -SUBDIRS = CellFrameDashboardGUI CellFrameDashboardService +SUBDIRS = CellFrameDashboardGUI CellFrameDashboardService \ + CellFrameDashboardTests CellFrameDashboardGUI.subdir = CellFrameDashboardGUI CellFrameDashboardService.subdir = CellFrameDashboardService diff --git a/CellFrameDashboardGUI/CellFrameDashboardGUI.pro b/CellFrameDashboardGUI/CellFrameDashboardGUI.pro index f59cc93..733747a 100755 --- a/CellFrameDashboardGUI/CellFrameDashboardGUI.pro +++ b/CellFrameDashboardGUI/CellFrameDashboardGUI.pro @@ -33,6 +33,7 @@ DEFINES += QT_DEPRECATED_WARNINGS DEFINES += DAP_BRAND=\\\"$$BRAND\\\" DEFINES += DAP_SERVICE_NAME=\\\"CellFrameDashboardService\\\" DEFINES += DAP_VERSION=\\\"$$VERSION\\\" +DEFINES += DAP_SETTINGS_FILE=\\\"settings.json\\\" ICON = icon.ico # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. diff --git a/CellFrameDashboardGUI/DapServiceController.cpp b/CellFrameDashboardGUI/DapServiceController.cpp index 3792b81..25aece1 100755 --- a/CellFrameDashboardGUI/DapServiceController.cpp +++ b/CellFrameDashboardGUI/DapServiceController.cpp @@ -2,6 +2,7 @@ #include "DapUiQmlWidgetModel.h" #include "DapLogMessage.h" #include "DapChainWallet.h" +#include "DapSettings.h" #include <QRegularExpression> @@ -33,6 +34,7 @@ void DapServiceController::init(DapServiceClient *apDapServiceClient) m_pDapServiceClient = apDapServiceClient; connect(m_pDapServiceClient, SIGNAL(sigDisconnected()), SLOT(clearLogModel())); + connect(m_pDapServiceClient, SIGNAL(sigConnected()), SLOT(loadUserSettings())); // Creating rpc controller m_pDapCommandController = new DapCommandController(apDapServiceClient->getClientSocket(), this); @@ -84,6 +86,11 @@ QString DapServiceController::getVersion() const return m_sVersion; } +QString DapServiceController::getSettingFile() const +{ + return m_sSettingFile; +} + QString DapServiceController::getResult() { return m_sResult; @@ -238,6 +245,27 @@ void DapServiceController::getNetworkList() m_pDapCommandController->getNetworkList(); } +void DapServiceController::loadUserSettings() +{ + const QString networkName = DapSettings::getInstance(m_sSettingFile) + .getKeyValue("network").toString(); + qInfo() << "get settings name: " << networkName; + int currentIndex = DapSettingsNetworkModel::getInstance().getCurrentIndex(); + qInfo() << "current index is " << currentIndex; + DapSettingsNetworkModel::getInstance().setCurrentNetwork(networkName, ++currentIndex); + qInfo() << "change Current Network: " << DapSettingsNetworkModel::getInstance().getCurrentNetwork(); + emit userSettingsLoaded(); +} + +void DapServiceController::saveUserSettings() +{ + DapSettings::getInstance().setFileName(m_sSettingFile); + QJsonObject networkObject; + networkObject["network"] = DapSettingsNetworkModel::getInstance().getCurrentNetwork(); + qInfo() << "Save to file: " << networkObject; + DapSettings::getInstance().writeFile(QJsonDocument(networkObject)); + emit userSettingsSaved(); +} /// Get an instance of a class. /// @return Instance of a class. diff --git a/CellFrameDashboardGUI/DapServiceController.h b/CellFrameDashboardGUI/DapServiceController.h index e93daea..a7bf7ae 100755 --- a/CellFrameDashboardGUI/DapServiceController.h +++ b/CellFrameDashboardGUI/DapServiceController.h @@ -26,6 +26,8 @@ class DapServiceController : public QObject QString m_sBrand {DAP_BRAND}; /// Application version. QString m_sVersion {DAP_VERSION}; + /// Settings file. + QString m_sSettingFile {DAP_SETTINGS_FILE}; /// Result execute. QString m_sResult; @@ -62,6 +64,9 @@ public: /// Get app version. /// @return Application version. QString getVersion() const; + /// Get setting file name. + /// @return Setting file name + QString getSettingFile() const; /// Get result command execute. /// @return Result execute. QString getResult(); @@ -101,6 +106,8 @@ signals: void sendToQML(QString); void logCompleted(); void sendNodeNetwork(const QVariant& aData); + void userSettingsLoaded(); + void userSettingsSaved(); private slots: /// Handling service response for receiving node logs. @@ -140,6 +147,10 @@ public slots: void activateClient(bool aIsActivated); /// Shut down client. void closeClient(); + /// Load user settings from settings file + void loadUserSettings(); + /// Save user settings to file + void saveUserSettings(); /// 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. diff --git a/CellFrameDashboardService/DapChainDashboardService.cpp b/CellFrameDashboardService/DapChainDashboardService.cpp index d12ef45..42f1493 100755 --- a/CellFrameDashboardService/DapChainDashboardService.cpp +++ b/CellFrameDashboardService/DapChainDashboardService.cpp @@ -1,5 +1,7 @@ #include "DapChainDashboardService.h" +#include "DapSettings.h" + DapChainDashboardService::DapChainDashboardService() : DapRpcService(nullptr) { // Log reader @@ -20,6 +22,7 @@ DapChainDashboardService::DapChainDashboardService() : DapRpcService(nullptr) m_pDapChainConsoleHandler = new DapChainConsoleHandler(this); + } bool DapChainDashboardService::start() diff --git a/CellFrameDashboardService/DapChainDashboardService.h b/CellFrameDashboardService/DapChainDashboardService.h index 85144bd..5b3ce78 100755 --- a/CellFrameDashboardService/DapChainDashboardService.h +++ b/CellFrameDashboardService/DapChainDashboardService.h @@ -64,6 +64,9 @@ public: signals: /// The signal is emitted in case of successful connection of a new client. void onNewClientConnected(); + // TODO get structure Settings which has method fill from jsonDocument + /// The signal is emitted in case of need to save setting + void onSaveSetting(); public slots: void changedLogModel(); diff --git a/CellFrameDashboardService/DapChainNodeNetworkHandler.cpp b/CellFrameDashboardService/DapChainNodeNetworkHandler.cpp index 52fda11..88edcd2 100644 --- a/CellFrameDashboardService/DapChainNodeNetworkHandler.cpp +++ b/CellFrameDashboardService/DapChainNodeNetworkHandler.cpp @@ -6,6 +6,11 @@ DapChainNodeNetworkHandler::DapChainNodeNetworkHandler(QObject *parent) : QObjec } +const QString &DapChainNodeNetworkHandler::getCurrentNetwork() const +{ + return m_CurrentNetwork; +} + QVariant DapChainNodeNetworkHandler::getNodeNetwork() const { QProcess process; diff --git a/CellFrameDashboardService/DapChainNodeNetworkHandler.h b/CellFrameDashboardService/DapChainNodeNetworkHandler.h index ab57a37..258ab1e 100644 --- a/CellFrameDashboardService/DapChainNodeNetworkHandler.h +++ b/CellFrameDashboardService/DapChainNodeNetworkHandler.h @@ -19,6 +19,11 @@ private: public: explicit DapChainNodeNetworkHandler(QObject *parent = nullptr); +public: + /// Get current network name + /// @return name of current network + const QString& getCurrentNetwork() const; + public slots: /// Change status of a node /// @param it is true if a node is online diff --git a/CellFrameDashboardService/main.cpp b/CellFrameDashboardService/main.cpp index 29d3122..af8c771 100755 --- a/CellFrameDashboardService/main.cpp +++ b/CellFrameDashboardService/main.cpp @@ -9,6 +9,7 @@ #include "DapChainDashboardService.h" #include "DapLogger.h" #include "DapChainLogHandler.h" +#include "DapSettings.h" void processArgs(); @@ -44,6 +45,7 @@ int main(int argc, char *argv[]) processArgs(); DapChainDashboardService service; service.start(); + // Initialization of the application in the system tray // service.initTray(); diff --git a/CellFrameDashboardTests/.gitignore b/CellFrameDashboardTests/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/CellFrameDashboardTests/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/CellFrameDashboardTests/CellFrameDashboardTests.pro b/CellFrameDashboardTests/CellFrameDashboardTests.pro new file mode 100644 index 0000000..42b3c41 --- /dev/null +++ b/CellFrameDashboardTests/CellFrameDashboardTests.pro @@ -0,0 +1,18 @@ +include(gtest_dependency.pri) +include (../libCellFrameDashboardCommon/libCellFrameDashboardCommon.pri) + +QT += core network +QT -= gui +QT += qml + +TEMPLATE = app +CONFIG += console c++11 +CONFIG -= app_bundle +CONFIG += thread +CONFIG += qt + +SOURCES += \ + DapSettingsTests.cpp \ + main.cpp + +INCLUDEPATH += $$_PRO_FILE_PWD_/../libCellFrameDashboardCommon/ diff --git a/CellFrameDashboardTests/DapSettingsTests.cpp b/CellFrameDashboardTests/DapSettingsTests.cpp new file mode 100644 index 0000000..a21c88c --- /dev/null +++ b/CellFrameDashboardTests/DapSettingsTests.cpp @@ -0,0 +1,158 @@ +#include "gtest/gtest.h" + +#include "DapSettings.h" + +#include <QJsonDocument> +#include <QJsonObject> + +TEST(DapSettingsTest, settingFileName) +{ + // set filename to setting file + // 1. set filename to settings + // 2. check what filename in DapSettings equal + + // 1. set filename to settings + const QString filename = "settings.json"; + DapSettings::getInstance().setFileName(filename); + + // 2. check what filename in DapSettings equal + EXPECT_EQ(DapSettings::getInstance().getFileName(), filename); +} + +TEST(DapSettingsTest, writeFile) +{ + // test for check write and read data in file + // 1. Write to file data + // 2. Read from file data + // 3. Compare data + + // 1. Write to file data + QJsonObject object; + const QString networkName = "test"; + object["network"] = networkName; + const QString filename = "settings.json"; + DapSettings::getInstance(filename).writeFile(QJsonDocument(object)); + + // 2. Read from file data + const QJsonDocument dataFromFile = DapSettings::getInstance(filename).readFile(); + + // 3. Compare data + EXPECT_EQ(dataFromFile.object(), object); + +} + +TEST(DapSettingsTest, FailedReadFromNotExistingFile) +{ + // test for check failed reading when file doesn't exist + // 1. Read from empty file. Example: "notexist.json" + // 2. Check what readed jsonDocument is null + + // 1. Read from empty file. Example: "notexist.json" + const QString filename = "notexist.json"; + DapSettings::getInstance(filename).setFileName(filename); + const QJsonDocument notExistingDocument = DapSettings::getInstance(filename).readFile(); + + // 2. Check what readed jsonDocument is empty + EXPECT_TRUE(notExistingDocument.isNull()); +} + +TEST(DapSettingsTest, FailedReadFromEmptyFile) +{ + // test for check failed reading when file is empty + // 1. Creating empty file + // 2. Read from empty file. Example: "empty.json". Create this file + // 3. Check what readed jsonDocument is empty + + // 1. Creating empty file + const QString filename = "empty.json"; + DapSettings::getInstance(filename).writeFile(QJsonDocument()); + + // 2. Read from empty file. Example: "empty.json" + QJsonDocument emptyDocument = DapSettings::getInstance(filename).readFile(); + + // 3. Check what readed jsonDocument is empty + EXPECT_TRUE(emptyDocument.isEmpty()); +} + +TEST(DapSettingsTest, FailedWriteEmptyData) +{ + // test for check failed write empty data + // 1. Check what Failed write empty data to file. Example: "emptyData.json" + + // 1. Check what Failed write empty data to file. Example: "emptyData.json" + EXPECT_FALSE(DapSettings::getInstance("emptyData.json").writeFile(QJsonDocument())); +} + +TEST(DapSettingsTest, SetKeyValue) +{ + // test for check set key value to file + // 1. Set key value to file. Example: "keys.json" + // 2. Get value from file + // 3. Comparing values are equal + + // 1. Set key value to file. Example: "keys.json" + const QString filename = "keys.json"; + DapSettings::getInstance(filename).setFileName(filename); + const QString key = "key"; + const QString value = "value"; + DapSettings::getInstance(filename).setKeyValue(key, value); + + // 2. Get value from file + const QVariant gettingValue = DapSettings::getInstance(filename).getKeyValue(key); + + // 3. Comparing values are equal + EXPECT_EQ(value, gettingValue.toString()); +} + +TEST(DapSettingsTest, FailedSetKeyValueByEmptyKey) +{ + // test for check failed set key value by empty key + // 1. Check what value doesn't write to file by empty key. Example: "keys.json" + + // 1. Check what value doesn't write to file by empty key. Example: "keys.json" + EXPECT_FALSE(DapSettings::getInstance("keys.json").setKeyValue("", "value")); +} + +TEST(DapSettingsTest, FailedSetEmptyKeyValue) +{ + // test for check failed set empty key value + // 1. Check what empty value doesn't write to file. Example: "keys.json" + + // 1. Check what empty value doesn't write to file. Example: "keys.json" + EXPECT_FALSE(DapSettings::getInstance("keys.json").setKeyValue("key", QVariant())); +} + +TEST(DapSettingsTest, SetGroupValue) +{ + // test check for setting group value in file + // 1. Set group value in file. Example: "group.json" + // 2. Get group value from file + // 3. Compare two values + + // 1. Set group value in file. Example: "group.json" + const QVariantMap map { {"1", "A"}, {"2", "B"} }; + QList<QVariantMap> list; + list.append(map); + const QString filename = "group.json"; + const QString key = "group"; + DapSettings::getInstance(filename).setGroupValue(key, list); + + // 2. Get group value from file + auto gettingList = DapSettings::getInstance(filename).getGroupValue(key); + + // 3. Compare two values + EXPECT_EQ(list, gettingList); +} + +TEST(DapSettingsTest, FailedSetGroupValueByEmptyGroupName) +{ + // test check for failed set group value because group name is empty + // 1. Check failed set group value by empty group name + + // 1. Check failed set group value by empty group name + const QVariantMap map { {"1", "A"}, {"2", "B"} }; + QList<QVariantMap> list; + list.append(map); + const QString filename = "group.json"; + EXPECT_FALSE(DapSettings::getInstance("group.json").setGroupValue(QString(), list)); +} diff --git a/CellFrameDashboardTests/gtest_dependency.pri b/CellFrameDashboardTests/gtest_dependency.pri new file mode 100644 index 0000000..b51e665 --- /dev/null +++ b/CellFrameDashboardTests/gtest_dependency.pri @@ -0,0 +1,32 @@ +isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR) + +message("_PRO_FILE_PWD_" = $$_PRO_FILE_PWD_/../../3dparty/googletest) + + +isEmpty(GOOGLETEST_DIR) { + warning("Using googletest src dir specified at Qt Creator wizard") + message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message") + GOOGLETEST_DIR = $$_PRO_FILE_PWD_/../../3dparty/googletest +} + +!isEmpty(GOOGLETEST_DIR): { + GTEST_SRCDIR = $$GOOGLETEST_DIR/googletest + GMOCK_SRCDIR = $$GOOGLETEST_DIR/googlemock +} + +requires(exists($$GTEST_SRCDIR):exists($$GMOCK_SRCDIR)) + +!exists($$GOOGLETEST_DIR):message("No googletest src dir found - set GOOGLETEST_DIR to enable.") + +DEFINES += \ + GTEST_LANG_CXX11 + +INCLUDEPATH *= \ + $$GTEST_SRCDIR \ + $$GTEST_SRCDIR/include \ + $$GMOCK_SRCDIR \ + $$GMOCK_SRCDIR/include + +SOURCES += \ + $$GTEST_SRCDIR/src/gtest-all.cc \ + $$GMOCK_SRCDIR/src/gmock-all.cc diff --git a/CellFrameDashboardTests/main.cpp b/CellFrameDashboardTests/main.cpp new file mode 100644 index 0000000..09bf49a --- /dev/null +++ b/CellFrameDashboardTests/main.cpp @@ -0,0 +1,9 @@ +#include "tst_settings.h" + +#include <gtest/gtest.h> + +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/libCellFrameDashboardCommon/DapSettings.cpp b/libCellFrameDashboardCommon/DapSettings.cpp index 9cbf5b9..aa56b45 100644 --- a/libCellFrameDashboardCommon/DapSettings.cpp +++ b/libCellFrameDashboardCommon/DapSettings.cpp @@ -1,5 +1,9 @@ #include "DapSettings.h" +#include <QJsonObject> +#include <QJsonArray> +#include <QIODevice> + /// Standart constructor. DapSettings::DapSettings(QObject *parent) : QObject(parent) { @@ -11,33 +15,52 @@ DapSettings::DapSettings(QObject *parent) : QObject(parent) /// Overloaded constructor. /// @param fileName Settings file name. /// @param parent Parent. -DapSettings::DapSettings(const QString &fileName, QObject *parent) +DapSettings::DapSettings(const QString &asFileName, QObject *parent) { Q_UNUSED(parent) init(); - setFileName(fileName); + setFileName(asFileName); } /// Initialize the components. void DapSettings::init() { - connect(this, &DapSettings::fileNameChanged, this, [=] (const QString &fileName) + connect(this, &DapSettings::fileNameChanged, this, [=] (const QString &asFileName) { - m_file.setFileName(fileName); + m_file.setFileName(asFileName); }); + + connect(this, &DapSettings::fileNeedClosed, [=] () { m_file.close(); }); } /// Read settings file. -/// @return Virtual json file. +/// @return Virtual json file. If failed read return default json document QJsonDocument DapSettings::readFile() { - qDebug() << "File name " << m_file.fileName(); - m_file.open(QIODevice::ReadOnly | QIODevice::Text); - QString textFile = decrypt(m_file.readAll()); - m_file.close(); - return QJsonDocument::fromJson(textFile.toUtf8()); + if(!m_file.exists()) { + qWarning() << "File doesn't exist." << "Creating file with name " << m_fileName; + m_file.open(QIODevice::ReadOnly | QIODevice::Text); + emit fileNeedClosed(); + return QJsonDocument(); + } + + if(!m_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning() << "Failed to read file " << m_file.errorString(); + emit fileNeedClosed(); + return QJsonDocument(); + } + + const QByteArray data = m_file.readAll(); + if(data.isEmpty()) { + qWarning() << "Failed to read data. File " << m_fileName << " is empty"; + return QJsonDocument(); + } + + emit fileNeedClosed(); + + return QJsonDocument::fromJson(data); } /// Write settings to file. @@ -45,28 +68,21 @@ QJsonDocument DapSettings::readFile() /// @return Returns true if the recording was successful, false if the recording failed. bool DapSettings::writeFile(const QJsonDocument &json) { - if(!m_file.open(QIODevice::WriteOnly)) - { - qDebug() << "Couldn't open write file." << m_file.errorString(); + if(!m_file.open(QIODevice::WriteOnly)) { + qWarning() << "Couldn't open write file." << m_file.errorString(); return false; } - else - { - m_file.open(QIODevice::WriteOnly); - m_file.write(encrypt(json.toJson())); - m_file.close(); - return true; + + const qint64 bytes = m_file.write(json.toJson()); + if(bytes <= 0) { + qWarning() << "Failed to write file with error: " << m_file.errorString(); + return false; } -} -QByteArray DapSettings::encrypt(const QByteArray &byteArray) const -{ - return byteArray; -} + qDebug() << "write bytes " << bytes << " to file " << m_fileName; + emit fileNeedClosed(); -QByteArray DapSettings::decrypt(const QByteArray &byteArray) const -{ - return byteArray; + return true; } /// Get an instance of a class. @@ -79,9 +95,9 @@ DapSettings &DapSettings::getInstance() /// Get an instance of a class. /// @return Instance of a class. -DapSettings &DapSettings::getInstance(const QString &fileName) +DapSettings &DapSettings::getInstance(const QString &asFileName) { - static DapSettings instance(fileName); + static DapSettings instance(asFileName); return instance; } @@ -98,19 +114,24 @@ DapSettings &DapSettings::getInstance(const QString &fileName) /// @param valueKeyProperty Key property value. /// @param property Settable property. /// @param valuePropery The value of the property being set. -void DapSettings::setGroupPropertyValue(const QString &group, const QString &keyProperty, - const QVariant &valueKeyProperty, const QString &property, const QVariant &valuePropery) +bool DapSettings::setGroupPropertyValue(const QString &asGroup, const QString &asKeyProperty, + const QVariant &aValueKeyProperty, const QString &asProperty, + const QVariant &aValueProperty) { - if(group.isEmpty() || group.isNull()) - return; - - auto list = getGroupValue(group); - - for(QMap<QString, QVariant> &map : list) - if(map.find(keyProperty) != map.end() && map.value(keyProperty) == valueKeyProperty) - map.insert(property, valuePropery); + if(asGroup.isEmpty() || asGroup.isNull()) + return false; - setGroupValue(group, list); + auto list = getGroupValue(asGroup); + if(list.empty()) { + QVariantMap map { {asProperty, aValueProperty} }; + list.append(map); + } else { + for(auto &map : list) + if(map.find(asKeyProperty) != map.end() && map.value(asKeyProperty) == aValueKeyProperty) + map.insert(asProperty, aValueProperty); + } + + return setGroupValue(asGroup, list); } /// Get property value from group by key property value. @@ -128,118 +149,121 @@ void DapSettings::setGroupPropertyValue(const QString &group, const QString &key /// @param property Settable property. /// @param defaultValue The key value to be inserted in case the key is not found. /// The default is non-valid value. -QVariant DapSettings::getGroupPropertyValue(const QString &group, const QString &keyProperty, const QString &valueKeyProperty, const QString &property, const QVariant& defaultValue) +QVariant DapSettings::getGroupPropertyValue(const QString &asGroup, const QString &aKeyProperty, + const QString &aValueKeyProperty, const QString &asProperty) { - for(QMap<QString, QVariant> &map : getGroupValue(group)) - if(map.find(keyProperty) != map.end() && map.value(keyProperty) == valueKeyProperty) - return map.value(property); - return defaultValue; + for(const QMap<QString, QVariant> &map : getGroupValue(asGroup)) + if(map.find(aKeyProperty) != map.end() && map.value(aKeyProperty) == aValueKeyProperty) + return map.value(asProperty); + return QVariant(); } /// Get key value. /// @details If the key does not exist, the function returns an invalid value. /// @param key Key name. -/// @param defaultValue The key value to be inserted in case the key is not found. -/// The default is non-valid value. -QVariant DapSettings::getKeyValue(const QString &key, const QVariant& defaultValue) +QVariant DapSettings::getKeyValue(const QString &asKey) { - QJsonObject root = readFile().object(); - - QJsonValue jv = root.value(key); - - if(!jv.isArray()) - { - return jv.toVariant(); - } - - return defaultValue; + const QJsonValue value = readFile().object().value(asKey); + if(value.isNull() || value.isUndefined()) + return QVariant(); + + return value.toVariant(); } /// Set key value. /// @param key Key. /// @param value Key value. -void DapSettings::setKeyValue(const QString &key, const QVariant &value) +bool DapSettings::setKeyValue(const QString &asKey, const QVariant &aValue) { - if(key.isEmpty() || key.isNull()) - return; + if(asKey.isEmpty() || asKey.isNull()) + return false; - QJsonDocument jsonDocument = readFile(); - QJsonObject jsonObject = jsonDocument.object(); - jsonObject.insert(key, value.toJsonValue()); - QJsonDocument jsonDocumentSave(jsonObject); - writeFile(jsonDocumentSave); + if(aValue.isNull() || !aValue.isValid()) + return false; + + QJsonObject jsonObject = readFile().object(); + jsonObject.insert(asKey, aValue.toJsonValue()); + return writeFile(QJsonDocument(jsonObject)); } /// Get a collection of values by name group. /// @details If the group is not found, the function returns an empty list. /// @param group Group name. /// @return Group values collection. -QList<QMap<QString, QVariant>> DapSettings::getGroupValue(const QString &group) +QList<QVariantMap> DapSettings::getGroupValue(const QString &asGroup) { - QJsonObject root = readFile().object(); - - QJsonValue jv = root.value(group); - - QList<QMap<QString, QVariant>> arrayValue; - - if(jv.isArray()) + if(asGroup.isEmpty() || asGroup.isNull()) { + qWarning() << "Failed get group value because group's name is undefined"; + return QList<QVariantMap>(); + } + + const QJsonValue jsonGroupValue = readFile().object().value(asGroup); + if(jsonGroupValue.isNull() || jsonGroupValue.isUndefined()) { + qWarning() << "Failed get group value because group " << asGroup << " doesn't exist"; + return QList<QVariantMap>(); + } + + if(!jsonGroupValue.isArray()) { + qWarning() << "Failed get group value because group " << asGroup << " isn't array of values"; + return QList<QVariantMap>(); + } + + QList<QVariantMap> collection; + const QJsonArray jsonGroupArray = jsonGroupValue.toArray(); + for(const QJsonValue &jsonValue : jsonGroupArray) { - QJsonArray ja = jv.toArray(); - for(QJsonValue jsonValue : ja) - { - QJsonObject jsonObject = jsonValue.toObject(); - QMap<QString, QVariant> object; - for(QString key : jsonObject.keys()) - { - object.insert(key, jsonObject.value(key).toVariant()); - } - arrayValue.push_back(object); + const QJsonObject jsonObject = jsonValue.toObject(); + if(!jsonValue.isObject()) { + qDebug() << jsonObject << " isn't object. Read next field..."; + continue; } + + QVariantMap map; + for(const QString &key : jsonObject.keys()) + map.insert(key, jsonObject.value(key).toVariant()); + + collection.push_back(map); } - - return arrayValue; + + return collection; } /// Set key values for group. /// @param group Group name. /// @param values Collection of group values. -void DapSettings::setGroupValue(const QString &group, const QList<QMap<QString, QVariant> > &values) +bool DapSettings::setGroupValue(const QString &asGroup, const QList<QVariantMap> &aValues) { - if(group.isEmpty() || group.isNull()) - return; - - QJsonDocument jsonDocument = readFile(); - QJsonObject jsonObject = jsonDocument.object(); + if(asGroup.isEmpty() || asGroup.isNull()) + return false; QJsonArray groupValues; - for(QMap<QString,QVariant> var : values) + for(const auto & map : aValues) { QJsonObject itemObject; - for(auto key : var.keys()) - { - itemObject.insert(key, var.value(key).toJsonValue()); - } + for(const auto &key : map.keys()) + itemObject.insert(key, map.value(key).toJsonValue()); + groupValues.append(itemObject); } - jsonObject.insert(group, groupValues); - QJsonDocument jsonDocumentSave(jsonObject); - writeFile(jsonDocumentSave); + return setKeyValue(asGroup, groupValues); } /// Get the name of the settings file. /// @return The name of the settings file. -QString DapSettings::getFileName() const +const QString &DapSettings::getFileName() const { return m_fileName; } /// Set the name of the settings file. /// @param fileName The name of the settings file. -void DapSettings::setFileName(const QString &fileName) +/// @return Reference of changed object DapSettings +DapSettings &DapSettings::setFileName(const QString &asFileName) { - m_fileName = fileName; - emit fileNameChanged(m_fileName); + m_fileName = asFileName; + emit fileNameChanged(asFileName); + return *this; } /// Method that implements the singleton pattern for the qml layer. diff --git a/libCellFrameDashboardCommon/DapSettings.h b/libCellFrameDashboardCommon/DapSettings.h index 4983bf8..7469a25 100644 --- a/libCellFrameDashboardCommon/DapSettings.h +++ b/libCellFrameDashboardCommon/DapSettings.h @@ -17,22 +17,18 @@ #include <QQmlEngine> #include <QJSEngine> #include <QJsonDocument> -#include <QJsonObject> -#include <QJsonArray> -#include <QIODevice> #include <QDebug> class DapSettings : public QObject { Q_OBJECT - protected: /// Standart constructor. explicit DapSettings(QObject *parent = nullptr); /// Overloaded constructor. - /// @param fileName Settings file name. + /// @param asFileName Settings file name. /// @param parent Parent. - explicit DapSettings(const QString &fileName, QObject *parent = nullptr); + explicit DapSettings(const QString &asFileName, QObject *parent = nullptr); /// Settings file. QFile m_file; @@ -41,21 +37,17 @@ protected: /// Initialize the components. virtual void init(); + +public: /// Read settings file. - /// @return Virtual json file. + /// @return Virtual json file. If failed read return default json document virtual QJsonDocument readFile(); /// Write settings to file. /// @param json Virtual json file. /// @return Returns true if the recording was successful, false if the recording failed. virtual bool writeFile(const QJsonDocument& json); - - public: - virtual QByteArray encrypt(const QByteArray &byteArray) const; - - virtual QByteArray decrypt(const QByteArray &byteArray) const; - /// Removed as part of the implementation of the pattern sington. DapSettings(const DapSettings&) = delete; DapSettings& operator= (const DapSettings &) = delete; @@ -64,8 +56,9 @@ public: /// @return Instance of a class. Q_INVOKABLE static DapSettings &getInstance(); /// Get an instance of a class. + /// @param asFileName Settings file name /// @return Instance of a class. - Q_INVOKABLE static DapSettings &getInstance(const QString &fileName); + Q_INVOKABLE static DapSettings &getInstance(const QString &asFileName); ///******************************************** /// Property @@ -91,7 +84,10 @@ public: /// @param valueKeyProperty Key property value. /// @param property Settable property. /// @param valuePropery The value of the property being set. - Q_INVOKABLE void setGroupPropertyValue(const QString &group, const QString &keyProperty, const QVariant &valueKeyProperty, const QString &property, const QVariant &valuePropery); + /// @return true if successfull set group value. False is group empty or null + Q_INVOKABLE bool setGroupPropertyValue(const QString &asGroup, const QString &asKeyProperty, + const QVariant &aValueKeyProperty, const QString &asProperty, + const QVariant &aValuePropery); /// Get property value from group by key property value. /// @details The search in the group is carried out according to the signs /// defining the object: the name of the key property and its value. @@ -105,39 +101,42 @@ public: /// @param keyProperty Key property. /// @param valueKeyProperty Key property value. /// @param property Settable property. - /// @param defaultValue The key value to be inserted in case the key is not found. /// The default is non-valid value. - Q_INVOKABLE QVariant getGroupPropertyValue(const QString &group, const QString &keyProperty, const QString &valueKeyProperty, const QString &property, const QVariant &defaultValue = QVariant()); + Q_INVOKABLE QVariant getGroupPropertyValue(const QString &asGroup, const QString &asKeyProperty, + const QString &aValueKeyProperty, const QString &asProperty); /// Get key value. /// @details If the key does not exist, the function returns an invalid value. /// @param key Key name. - /// @param defaultValue The key value to be inserted in case the key is not found. - /// The default is non-valid value. - Q_INVOKABLE QVariant getKeyValue(const QString &key, const QVariant &defaultValue = QVariant()); + Q_INVOKABLE QVariant getKeyValue(const QString &asKey); /// Set key value. /// @param key Key. /// @param value Key value. - Q_INVOKABLE void setKeyValue(const QString &key, const QVariant &value); + /// @return true if successfull set value. False is key empty or null + Q_INVOKABLE bool setKeyValue(const QString &asKey, const QVariant &aValue); /// Get a collection of values by name group. /// @details If the group is not found, the function returns an empty list. /// @param group Group name. /// @return Group values collection. - Q_INVOKABLE QList<QMap<QString, QVariant> > getGroupValue(const QString &group); + Q_INVOKABLE QList<QVariantMap> getGroupValue(const QString &asGroup); /// Set key values for group. /// @param group Group name. /// @param values Collection of group values. - Q_INVOKABLE void setGroupValue(const QString &group, const QList<QMap<QString, QVariant>> &values); + /// @return true if successfull set group value. False is group empty or null + Q_INVOKABLE bool setGroupValue(const QString &asGroup, const QList<QVariantMap> &aValues); /// Get the name of the settings file. /// @return The name of the settings file. - QString getFileName() const; + const QString &getFileName() const; /// Set the name of the settings file. /// @param fileName The name of the settings file. - void setFileName(const QString &fileName); + /// @return Reference of changed object DapSettings + DapSettings &setFileName(const QString &asFileName); signals: /// The signal is emitted when the FileName property changes. - /// @param fileName The name of the settings file. - void fileNameChanged(const QString &fileName); + /// @param asFileName The name of the settings file. + void fileNameChanged(const QString &asFileName); + /// The signal is emitted when file needs to close; + void fileNeedClosed(); public slots: /// Method that implements the singleton pattern for the qml layer. diff --git a/libCellFrameDashboardCommon/DapSettingsCipher.cpp b/libCellFrameDashboardCommon/DapSettingsCipher.cpp index c0129be..60e8946 100644 --- a/libCellFrameDashboardCommon/DapSettingsCipher.cpp +++ b/libCellFrameDashboardCommon/DapSettingsCipher.cpp @@ -8,12 +8,14 @@ DapSettingsCipher::DapSettingsCipher(const DapSettings& settings) QByteArray DapSettingsCipher::encrypt(const QByteArray &byteArray) const { - return m_settings.encrypt(byteArray); +// TODO: implement encryption to next iteration. +// return m_settings.encrypt(byteArray); } QByteArray DapSettingsCipher::decrypt(const QByteArray &byteArray) const { - return m_settings.decrypt(byteArray); +// TODO: implement decryption to next iteration. +// return m_settings.decrypt(byteArray); } DapSettingsCipher &DapSettingsCipher::getInstance(const DapSettings& settings) diff --git a/libCellFrameDashboardCommon/DapSettingsCipher.h b/libCellFrameDashboardCommon/DapSettingsCipher.h index b0d9beb..1bc3666 100644 --- a/libCellFrameDashboardCommon/DapSettingsCipher.h +++ b/libCellFrameDashboardCommon/DapSettingsCipher.h @@ -16,9 +16,9 @@ protected: DapSettingsCipher(const DapSettings& settings); public: - virtual QByteArray encrypt(const QByteArray &byteArray) const override; + virtual QByteArray encrypt(const QByteArray &byteArray) const; - virtual QByteArray decrypt(const QByteArray &byteArray) const override; + virtual QByteArray decrypt(const QByteArray &byteArray) const; /// Removed as part of the implementation of the pattern sington. DapSettingsCipher(const DapSettingsCipher&) = delete; -- GitLab