/*! * * Copyright (c) 2021-2022 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.cpp * \author (last) Behrouz NematiPour * \date (last) 15-Aug-2022 * \author (original) Behrouz NematiPour * \date (original) 29-Mar-2021 * */ // Qt #include #include #include // Project #include "StorageGlobals.h" #include "FileHandler.h" #include "MSettings.h" #include "Logger.h" // namespace using namespace Storage; #include "Settings.h" bool Settings::isValid(const QString &vSettingFile) { if (! QFileInfo::exists(vSettingFile)) { LOG_DEBUG("Setting file " + vSettingFile + " does not exist."); return false; } return true; } /*! * \brief Settings::fileName * \details returns the conf file by the settings information provided. * \return QString configuration/settings file name */ QString Settings::fileName(const QString &vCategory) { return QString("%1%2.%3").arg(Storage::Settings_Path_Name).arg(vCategory).arg(_settingsExt); } /*! * \brief Settings::doRead * \details Reads all the configuration files */ int Settings::read() { QStringList fileFilter = QStringList() << QString("*.%1").arg(_settingsExt); QFileInfoList settingFiles = FileHandler::find (Storage::Settings_Path_Name, fileFilter); QStringList settingFolders = FileHandler::subFolders(Storage::Settings_Path_Name); if ( ! settingFolders.count() ) { LOG_DEBUG(QObject::tr("No setting folder in the %1").arg(Storage::Settings_Path_Name)); return 1; // TODO : Define an error enum when completed } for ( QString &settingFolder : settingFolders ) { QString folder = settingFolder.prepend(Storage::Settings_Path_Name); settingFiles += FileHandler::find(folder, fileFilter); } // DEBUG: // settingFiles = // { // QFileInfo("/home/denali/Projects/application/resources/settings/Confirm/Confirm.conf"), // QFileInfo("/home/denali/Projects/application/resources/settings/Alarms/Alarms.conf") // }; if ( ! settingFiles.count() ) { LOG_DEBUG(QObject::tr("No setting files in the %1").arg(Storage::Settings_Path_Name)); return 2; // TODO : Define an error enum when completed } QList details; for (const auto &settingFile: settingFiles) { if (! isValid(settingFile.absoluteFilePath())) continue; QFile file(settingFile.absoluteFilePath()); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { Detail detail; detail.content = file.readAll().trimmed(); if (detail.content.isEmpty()) continue; detail.location = settingFile.absolutePath() + "/"; detail.category = QString(detail.location + settingFile.baseName()).remove(Storage::Settings_Path_Name); details += detail; } } for (const auto &detail : details) { bool enableDuplicateKey = false; QString attribute = QString("%1%2").arg(_config_attribute_tag); QString group = ""; QStringList lines = detail.content.split('\n'); for (QString line : lines) { // ----- trim the line line = line.trimmed(); // ----- ignore empty lines if ( line.isEmpty() ) continue; // ----- find comments int commentPosition = line.indexOf('#'); // ----- ignore comment line or find attributes if ( commentPosition == 0 ) { // ----- find the configuration file attribute int attributeTagPosition = line.indexOf(_config_attribute_tag); if ( attributeTagPosition == 0 ) { // ----- find the attribute : duplicate_key_... if ( line == attribute.arg( _duplicate_key_on ) ) { enableDuplicateKey = true ;} else if ( line == attribute.arg(_duplicate_key_off ) ) { enableDuplicateKey = false ;} else { LOG_APPED_UI(( "Unknown '" + line + "' attribute in %1").arg(detail.category)); } } // next line continue; } // ----- remove inline comment if ( commentPosition > 0 ) line.truncate(commentPosition); line = line.trimmed(); // ----- find group if (line.contains("[") && line.contains("]")) { line.replace("[","").replace("]", ""); group = line; } else { if ( group.isEmpty() ) { continue; } else { if ( ! line.isEmpty() ) { QString key = ""; QString value = ""; if ( line.contains('=') ) { QStringList keyValue = line.split('='); key = keyValue[0].trimmed().replace("\\n","\n"); value = keyValue[1].trimmed().replace("\\n","\n"); } else { key = line; } _Settings.add(detail.category, group, key, QVariant(value), enableDuplicateKey); // DEBUG: qDebug() << group << key << value << location << category; } } } // DEBUG: qDebug() << group << line; } } return 0; } /*! * \brief Settings::save * \details Writes the setting in the configuration files * \return */ int Settings::save(const QString &vCategory, const QString &vGroup, const QString &vKey, const QString &vValue) { // qDebug() << vCategory // << vGroup // << vKey // << vValue; QString mFileName = fileName(vCategory); QString mContent; // -------------------------------------------------------------------------------------------------------------- //Note: the configuration files which can be saved, are like settings and should not have duplicate values. // as an example the Alarm volume can't have two separate duplicate entry in the settings. // -------------------------------------------------------------------------------------------------------------- _Settings.add(vCategory, vGroup, vKey, vValue, false); QString mPath = QFileInfo(mFileName).absolutePath(); if ( mPath.trimmed().isEmpty() ) { LOG_DEBUG("The settings path is empty."); return 1; // TODO: define enum } if ( ! FileHandler::makeFolder(mPath) ) { LOG_DEBUG(QString("The settings path %1 can't be created.").arg(mPath)); return 2; // TODO: define enum } for ( const auto &group : _Settings.groups(vCategory) ) { mContent += QString("\n[%1]\n").arg(group); for ( const auto &key : _Settings.keys(vCategory, group) ) { mContent += QString("%1 = %2\n").arg(key).arg(_Settings.value(vCategory, group, key).toString()); } } if ( ! FileHandler::write(mFileName,mContent, false) ) { LOG_DEBUG(QString("The settings file %1 can't be written.").arg(mFileName)); return 3; // TODO: define enum } return 0; }