/*! * * Copyright (c) 2021-2023 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 VLogFilesModel.cpp * \author (last) Vy * \date (last) 16-May-2023 * \author (original) Behrouz NematiPour * \date (original) 11-May-2021 * */ // Qt #include // Project #include "VLogFilesModel.h" #include "Logger.h" #include "StorageGlobals.h" #include "DeviceController.h" using namespace View; /*! * \brief VLogFilesModel::VLogFilesModel * Constructor of the VLogFilesModel class */ VLogFilesModel::VLogFilesModel(QAbstractListModel *parent) : QAbstractListModel(parent) { initConnections(); } /*! * \brief VLogFilesModel::initConnections * Makes the necessary connections. Called inside VIEW_DEF_CLASS */ void VLogFilesModel::initConnections() { connect(&_DeviceController , SIGNAL(didWatchDirectoryChange (const QString &)), this , SLOT( onWatchDirectoryChange (const QString &))); // The model gets a total refresh when Logger class emits didRemoveLogs connect(&_Logger , SIGNAL( didRemoveLogs (bool)), this , SLOT(onTotalModelRefresh (bool))); } /*! * \brief VLogFilesModel::doInit * \details Initializes the view or what needs to be done */ void VLogFilesModel::doInit() { refreshModel(); } /*! * \brief VLogFilesModel::rowCount * Gets the number of networks * \param parent - (QModelIndex) the parent QModelIndex * \return (int) - the number of networks */ int VLogFilesModel::rowCount(const QModelIndex & parent) const { Q_UNUSED(parent); return _logFiles.count(); } /*! * \brief VLogFilesModel::data * Returns the sd card file properties at the specified index * \param index (QModelIndex) contains the row of data to lookup * \param role - (int) the property index to return. See SDCardFileDataRole * \return (QVariant) - the value for the specified network property */ QVariant VLogFilesModel::data(const QModelIndex & index, int role) const { if (index.row() < 0 || index.row() >= _logFiles.count()) return QVariant(); const LogFileData &logFile = _logFiles[index.row()]; switch (role) { case FilePathRole: return logFile.filePath(); case FileNameRole: return logFile.fileName(); case FileSizeRole: return logFile.fileSize_bytes(); case FileLogTypeRole : return logFile.logType(); case FileModificationDateTimeRole: return logFile.lastModificationDateTime(); } return QVariant(); } /*! * \brief VLogFilesModel::roleNames * Translates how to access specific properties of the data for QML from the NetworkDataRole enum * \return (QHash) - maps enums to property names */ QHash VLogFilesModel::roleNames() const { QHash roles; roles[FilePathRole] = "filePath"; roles[FileNameRole] = "fileName"; roles[FileSizeRole] = "fileSize_bytes"; roles[FileLogTypeRole] = "fileLogType"; roles[FileModificationDateTimeRole] = "fileModDateTime"; return roles; } /*! * \brief VLogFilesModel::getLogListFromDir * A helper function to traverse a given directory of a log type and produce a * list of LogFileData that are pre-existing (if vCheckPreInclude is true) else, everything from * the directory * \param vType - the log type to assign the LogFileData * \param vDirectory - the directory to traverse * \param vCheckPreInclude - true - only include in return list if the file discover does not already exist * in the model list; false - include every file found * \return A list of LogFileData representing files from the directory */ QList VLogFilesModel::getLogListFromDir(Storage::Logger::LogType vType, const QString &vDirectory, bool vCheckPreInclude){ QList temp; // iterate through directory and subdirectories, looking for files only and no symlinks. QDirIterator dirIterator(vDirectory, QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); QString absolutePath; while(dirIterator.hasNext()) { absolutePath = dirIterator.next(); if(!dirIterator.fileName().isEmpty()) { LogFileData currentLog(vType, dirIterator.fileInfo()); if(!vCheckPreInclude || !_logFiles.contains(currentLog)) { //DEBUG qDebug() << " adding " << absolutePath << dirIterator.fileInfo().fileName(); temp.append(currentLog); } } } return temp; } /*! * \brief VLogFilesModel::updateLogModel * This log updates the underlying file list with missing files from the * targeted directory * \param vDirectory - the target directory */ void VLogFilesModel::updateLogModel(const QString &vDirectory) { Storage::Logger::LogType type = _Logger.getLogType(vDirectory); //DEBUG: qDebug() << Q_FUNC_INFO << " dir changed : " << vDirectory << " type " << type; QList temp = getLogListFromDir(type, vDirectory, true); if(temp.count() == 0) return; // No new files, exit // Update the model beginInsertRows(QModelIndex(), _logFiles.count(), _logFiles.count() + temp.count()-1); _logFiles.append(temp); endInsertRows(); } /*! * \brief VLogFilesModel::refreshModel * Does a complete clear and repopulate the model */ void VLogFilesModel::refreshModel() { //DEBUG qDebug()< logTypes = Storage::Logger::getLogTypeList(); foreach(Storage::Logger::LogType type , logTypes) { // determine where the corresponding log folders live for each log type QString folderPath = QString("%1%2").arg(Storage::Log_Folder_Base).arg(_Logger.getPathOfLogType(type)); // Add to systemWatcher to monitor for changes _DeviceController.doAddDirectoryWatch(folderPath); // Update the underlying list of log files with data from the log directory _logFiles.append(getLogListFromDir(type, folderPath)); } } // ============================== VUSBLogFilesModel /*! * \brief VUSBLogFilesModel::VUSBLogFilesModel * Constructor */ VUSBLogFilesModel::VUSBLogFilesModel(QAbstractListModel *parent) : VLogFilesModel(parent) { // add some additional connections initConnections(); } /*! * \brief VUSBLogFilesModel::initConnections * Do all the necessary signal-slot connections */ void VUSBLogFilesModel::initConnections() { connect(&_DeviceController , SIGNAL( didUSBDriveMount ()), this , SLOT( refreshModel ())); connect(&_DeviceController , SIGNAL( didUSBDriveUmount ()), this , SLOT( removeAllRows ())); connect(&_DeviceController , SIGNAL( didUSBDriveRemove ()), this , SLOT( removeAllRows ())); } /*! * \brief VUSBLogFilesModel::updateModelOnDirChange * Override of the base class updateModelOnDirChange virtual function * This function's purpose is to update the model when the particular * log folder at Storage::USB_Mount_Point has changed * \param vDirectory - the directory that has changed based on watcher */ void VUSBLogFilesModel::updateModelOnDirChange(const QString &vDirectory) { qDebug()< logTypes = Storage::Logger::getLogTypeList(); foreach(Storage::Logger::LogType type , logTypes) { // determine where the corresponding log folders live for each log type QString folderPath = QString("%1%2").arg(Storage::USB_Mount_Point).arg(_Logger.getPathOfLogType(type)); // Add to systemWatcher to monitor for changes _DeviceController.doAddDirectoryWatch(folderPath); // Update the underlying list of log files with data from the log directory _logFiles.append(getLogListFromDir(type, folderPath)); } }