/*! * * Copyright (c) 2021-2025 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 Settings.h * \author (last) Behrouz NematiPour * \date (last) 13-Sep-2023 * \author (original) Behrouz NematiPour * \date (original) 29-Mar-2021 * */ #pragma once // Qt #include #include #include // Project #include "main.h" // Doxygen : do not remove #include "StorageGlobals.h" #include "Threads.h" // forward declarations class tst_initializations; namespace Storage { // TODO - IMPORTANT: this MVC needs to change to configurations in oppose to Settings. // It named settings because it suppose to be like QSettings, // but since we have settings it is mixing up with that and is very confusing. // FIXME- IMPORTANT: This set of Settings (MVC) design is not correct: // - the data structure should change in Model from column based (keys, values) to tree/map based // - the singleton should be the controller not the Model, to protect the model usage, and avoid the shared memory issues. // - the model class should be private class, or an object defined in this class, not a global class. class Settings { // Settings const char *_config_attribute_tag = "#--"; const char *_duplicate_key_on = "duplicate_key_on"; const char *_duplicate_key_off = "duplicate_key_off"; const char *_settingsExt = "conf"; const char *_settingsFormat = "%1/%2.%3"; struct Detail { QString category; QString location; QString content; }; // TODO make this the SettingsError class // { Class SettingsError public: enum Settings_Error { eError_None = 0 , // always has to be 0 eError_POST , eError_PathEmpty , eError_MkDir , eError_Write , eError_Read , eError_Empty , eError_Copy , eError_Remove , eError_No_SettingsFolder , eError_No_SettingsFile , eError_SettingNotExists , }; private: const QHash settingsError_Message { // no translation for the error. My experience shows the error messages if translated is not useful for serviceability and debugging. { eError_None , "" }, { eError_POST , "The configuration source check failed." }, { eError_PathEmpty , "The settings path is empty." }, { eError_MkDir , "The configuration folder '%1' cannot be created." }, { eError_Write , "The settings file %1 can't be written." }, { eError_Read , "The settings file %1 can't be read." }, { eError_Empty , "The settings file %1 is empty." }, { eError_Copy , "The configuration folder '%1' cannot be copied." }, { eError_Remove , "The configuration folder '%1' cannot be removed." }, { eError_No_SettingsFolder , "No settings folder in the %1 path found." }, { eError_No_SettingsFile , "No settings file in the %1 folder found." }, { eError_SettingNotExists , "The setting file %1 doesn't exists." }, }; public: const QString errorMessage(int vErr, QString vArg1 = "", QString vArg2 = "") { if ( settingsError_Message.contains(vErr) ) { if ( ! vArg1.isEmpty() ) return QString(settingsError_Message[vErr]).arg(vArg1); if ( ! vArg2.isEmpty() ) return QString(settingsError_Message[vErr]).arg(vArg1).arg(vArg2); /* default */ return QString(settingsError_Message[vErr]); } return "[unknown]"; } // } Class SettingsError private: const QString makeSetting(const char *vPath, const char *vFile) { QString literal(_settingsFormat); return QString(literal.arg(vPath).arg(vFile).arg(_settingsExt)); } bool isValid(const QString &vSettingFile); QString fileName(const QString &vCategory); void update(); public: Settings() {} enum Category_Enum { eInstructions , eConfigurationsDataList , // TODO: the category for this conf is not used. may need to be merged into the Settings, but since it is list, It needs a little more thought. eAlarms , eEvents , eMessagesUnhandled , eSettingsSystem , eGenericConfirm , }; enum Key_Enum { eKeyTitle , eKeyMessage , eKeyListTitle , eKeyConfirm , eKeyCancel , }; enum Location_Enum { eInit , eSecured , }; int read (); int save (const QString &vCategory, const QString &vGroup, const QString &vKey, const QString &vValue); int configurationsMove (QString *vMessage = nullptr, bool vIsUpdate = false); int configurationsPOST (Location_Enum vLoc = Location_Enum::eSecured) { Q_UNUSED(vLoc); return true; } static QString category(Category_Enum vCategory) { switch (vCategory) { // NOTE: don't use default case eInstructions : return Storage::Settings_Category_Instructions ; case eConfigurationsDataList : return Storage::Settings_Category_ConfigurationsDataList ; case eAlarms : return Storage::Settings_Category_Alarms ; case eEvents : return Storage::Settings_Category_Events ; case eMessagesUnhandled : return Storage::Settings_Category_MessagesUnhandled ; case eSettingsSystem : return Storage::Settings_Category_SettingsSystem ; case eGenericConfirm : return Storage::Settings_Category_GenericConfirm ; } return ""; } static QString key(Key_Enum vKey) { switch (vKey) { // NOTE: don't use default case eKeyTitle : return Storage::Settings_Key_Title ; case eKeyMessage : return Storage::Settings_Key_Message ; case eKeyListTitle : return Storage::Settings_Key_ListTitle ; case eKeyConfirm : return Storage::Settings_Key_Confirm ; case eKeyCancel : return Storage::Settings_Key_Cancel ; } return ""; } //Note: this funtion is specific to the settings and should not use the StorageGlobals function. static QString location(Location_Enum vLoc) { switch (vLoc) { // NOTE: don't use default case eInit : return Storage::Settings_Path_Init; case eSecured : return Storage::Settings_Path_Name; } return Storage::Settings_Path_Name; } static bool isCategoryInstructions (const QString &vCategory) { return vCategory == category( eInstructions ); } static bool isCategoryConfigurationsDataList (const QString &vCategory) { return vCategory == category( eConfigurationsDataList ); } static bool isCategoryAlarms (const QString &vCategory) { return vCategory == category( eAlarms ); } static bool isCategoryMessagesUnhandled (const QString &vCategory) { return vCategory == category( eMessagesUnhandled ); } static bool isCategorySettingsSystem (const QString &vCategory) { return vCategory == category( eSettingsSystem ); } static bool isCategoryConfirm (const QString &vCategory) { return vCategory == category( eGenericConfirm ); } static bool isKeyTitle (const QString &vKey ) { return vKey == key ( eKeyTitle ); } static bool isKeyMessage (const QString &vKey ) { return vKey == key ( eKeyMessage ); } static bool isKeyListTitle (const QString &vKey ) { return vKey == key ( eKeyListTitle ); } static bool isKeyConfirm (const QString &vKey ) { return vKey == key ( eKeyConfirm ); } static bool isKeyCancel (const QString &vKey ) { return vKey == key ( eKeyCancel ); } }; }