/*! * * Copyright (c) 2021-2024 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 RxProfiles.cpp * \author (last) Behrouz NematiPour * \date (last) 13-Mar-2024 * \author (original) Behrouz NematiPour * \date (original) 04-May-2021 * */ #include "RxProfilesController.h" // Qt #include // Project #include "StorageGlobals.h" #include "FileHandler.h" #include "ApplicationController.h" #include "Logger.h" #include "Settings.h" #include "DeviceController.h" #include "MRxProfilesData.h" using namespace Storage; #define NONE "N/A" #define FLOAT3 0,'f',3 #define ADDTITLE(vTITLE) logContent += QString("[%1]\n").arg(vTITLE) #define ADDALINE(vTEXT ) logContent += QString("%1\n" ).arg(vTEXT ) //#define ADDTOLOG( vINDEX ) index = vINDEX; logContent += title(index) + _sep + value(index) + _sep + unit(index) + "\n"; #define ADDTOLOG_MT(vINDEX, vVALUE, vTITLES ) \ logContent += vTITLES[vINDEX] + _equal + \ "\"" + ( vVALUE[vINDEX].toString() ) + "\"\n"; /*! * \brief RxProfiles::RxProfiles * The constructor to initial the Treatment Log * \param parent */ RxProfiles::RxProfiles(QObject *parent) : QObject(parent) { initConnections(); } /*! \brief Connection Initializer \details All the class signal/slot connections are defined here. */ void RxProfiles::initConnections() { connect(&_exportWatcher , SIGNAL(finished()), this , SLOT(onExport())); connect(&_saveWatcher , SIGNAL(finished()), this , SLOT(onSave ())); connect(&_importWatcher , SIGNAL(finished()), this , SLOT(onImport())); connect(&_DeviceController , SIGNAL(didReadFilesList(const QFileInfoList &)), this , SLOT(onReceieveRxProfileList(const QFileInfoList &))); } void RxProfiles::doInitRxProfiles() { emit didFilesList(rxProfilesPath(), { QString("*.%1").arg(_rxProfiles) }); } void RxProfiles::doDeleteRxProfile(QString vRxProfileName) { qDebug() < mFuture = QtConcurrent::run(this, &RxProfiles::saveLog); _saveWatcher.setFuture(mFuture); } /*! * \brief RxProfiles::saveLog * The actual treatment log save function which does the save into the Prescription log * \return true on successful save and false otherwise. */ bool RxProfiles::saveLog() { bool ok ; QString logContent ; if (vPreviousRxProfileName != ""){ QString fileName = QString("%1%2.%3").arg(_rxProfilesPath, vPreviousRxProfileName, _rxProfiles); fileName.replace(" ", _underscore); QFile::remove(fileName); clearPreviousRxProfileName(); } if (vRxProfileHash[Model::RxProfilesIndex::eProfileName].toString() == ""){LOG_DEBUG("Profile Name cannot be empty"); return false;} QString fileName = QString("%1%2.%3").arg(_rxProfilesPath, vRxProfileHash[Model::RxProfilesIndex::eProfileName].toString(), _rxProfiles); fileName.replace(" ", _underscore); ADDTOLOG_MT( Model::RxProfilesIndex::eBloodFlowRate , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eDialysateFlowRate , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eTreatmentDuration , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eAcidConcentrateType , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eBicarbonateConcentrateType , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eDialysateTemperature , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eDialyzerType , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eHeparinConcentration , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eHeparinBolusVolume , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eHeparinDispenseRate , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eHeparinStop , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eSalineVolume , vRxProfileHash , Model::MRxProfilesData::titles() ); ADDTOLOG_MT( Model::RxProfilesIndex::eVitalSigns , vRxProfileHash , Model::MRxProfilesData::titles() ); // qDebug() << "WRITING FILE: " < mFuture = QtConcurrent::run(this, &RxProfiles::exportLog); _exportWatcher.setFuture(mFuture); } /*! * \brief RxProfiles::exportLog * \details The actual treatment log export function which does the export of the treatment log into the USB drive. * \return true on successful export. */ bool RxProfiles::exportLog() { bool ok = true; QString status = ""; QString dstPath = Storage::USB_Mount_Point ; dstPath += Storage::Rx_Folder_Profiles ; QString srcFile = "meow.txr" ;//TODO: adjust for filename variable QString srcFileName = QFileInfo(srcFile).fileName() ; QString dstFile = dstPath + srcFileName; // HERE: expose to the UI dialog as the rejection/notification result if ( ! Storage::FileHandler::makeFolder ( dstPath ) ) { status = QString( "Couldn't create folder on USB drive to export TxLog" ); ok = false; goto lOut; } if ( ! QFileInfo::exists ( srcFile ) ) { status = QString( "Prescription Log '%1' doesn't exist" ).arg( srcFile ); ok = false; goto lOut; } if ( QFileInfo::exists ( dstFile ) ) { status = QString( "Prescription Log '%1' already exists" ).arg( dstFile ); ok = false; goto lOut; } if ( ! QFile::copy (srcFile, dstFile ) ) { status = QString( "Unable to Export RxLog '%1' to '%2'" ).arg( srcFile ).arg( dstFile ); ok = false; goto lOut; } lOut: if ( ! ok ) { LOG_DEBUG(status); // The log debug order in this block is by design status = "Unable to export Prescription log '" + srcFileName +"'"; } else { status = "Prescription log '" + srcFileName + "' exported successfully"; LOG_APPED_UI(status); } emit didNotification(status); return ok; } /*! * \brief RxProfiles::onExport * The private export slot which is called after the export process is finished exporting. */ void RxProfiles::onExport() { LOG_DEBUG(QString("Export Prescription Log Ended: %1").arg(_exportWatcher.result())); isIdle(true); } // ----- Import /*! * \brief RxProfiles::doImport * The export treatment log slot to be exposed to the UI to be able to request for the import. */ void RxProfiles::doImport() { if (_importWatcher.isRunning()) return; isIdle(false); importLogConcurrent(); } /*! * \brief RxProfiles::importLogConcurrent * The treatment log import which is using a thread pool to run the save process. */ void RxProfiles::importLogConcurrent() { LOG_DEBUG("Import Prescription Log Started"); QFuture mFuture = QtConcurrent::run(this, &RxProfiles::importLog); _importWatcher.setFuture(mFuture); } /*! * \brief RxProfiles::importLog * \details The actual treatment log import function which does the import of the treatment log into the USB drive. * \return true on successful import. */ bool RxProfiles::importLog() { bool ok = true; // QString srcFile = Storage::USB_Mount_Point + Storage::Log_Folder_Rx; // QString dstPath = _rxProfilesPath ; // QString status = ""; // TODO: implement import return ok; } /*! * \brief RxProfiles::onImport * The private import slot which is called after the import process is finished importing. */ void RxProfiles::onImport() { LOG_DEBUG(QString("Import Prescription Log Ended: %1").arg(_exportWatcher.result())); isIdle(true); } void RxProfiles::onReceieveRxProfileList(const QFileInfoList &vRxProfileList) { QList vRxProfileDataList; for (const QFileInfo fileInfo:vRxProfileList){ RxProfilesData rxData = initModel(fileInfo) ; if (rxData.rxProfileContent.size() == Model::RxProfilesIndex::eRxProfilesIndexCount ) { vRxProfileDataList.append(rxData); } else LOG_DEBUG(QString("Bad Prescription Log Given: %1, %2").arg(fileInfo.baseName(), QString::number( rxData.rxProfileContent.size() ))); } emit didRxProfileList(vRxProfileDataList); }