Index: denali.pro =================================================================== diff -u -ra53bdf104b52cae3a49705a4cc8bd886530084c9 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- denali.pro (.../denali.pro) (revision a53bdf104b52cae3a49705a4cc8bd886530084c9) +++ denali.pro (.../denali.pro) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -118,10 +118,8 @@ \ # Controllers sources/ApplicationController.h \ sources/device/DeviceController.h \ - sources/model/settings/MSDCardFile.h \ sources/storage/Settings.h \ sources/storage/TreatmentLog.h \ - sources/view/settings/VSDCardFilesModel.h \ sources/wifi/WifiInterface.h \ sources/bluetooth/BluetoothInterface.h \ sources/cloudsync/CloudSyncController.h \ @@ -289,6 +287,9 @@ sources/view/settings/VAdjustmentDGCleaningUsage.h \ sources/view/settings/VDuetRoWaterDG.h \ sources/view/settings/VCloudSync.h \ + sources/model/settings/MSDCardFile.h \ + sources/view/settings/VLogSortFilterProxyModel.h \ + sources/view/settings/VSDCardFilesModel.h \ \ # ---------- Views - Alarm sources/view/hd/alarm/VAlarmStatus.h \ sources/view/hd/alarm/VAlarmActiveList.h \ @@ -395,7 +396,6 @@ sources/storage/Settings.cpp \ sources/storage/TreatmentLog.cpp \ sources/view/hd/data/post/VHDPOSTData.cpp \ - sources/view/settings/VSDCardFilesModel.cpp \ sources/wifi/WifiInterface.cpp \ sources/bluetooth/BluetoothInterface.cpp \ sources/cloudsync/CloudSyncController.cpp \ @@ -554,6 +554,8 @@ sources/view/settings/VDuetRoWaterDG.cpp \ sources/view/settings/VCloudSync.cpp \ sources/view/settings/VAdjustmentDGCleaningUsage.cpp \ + sources/view/settings/VLogSortFilterProxyModel.cpp \ + sources/view/settings/VSDCardFilesModel.cpp \ \ # ---------- Views - HD - Adjustment sources/view/VAdjustmentResponseBase.cpp \ \ # ---------- Views - HD - Adjustment - common Index: sources/device/DeviceController.cpp =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -107,6 +107,8 @@ connect(&_fileSystemWatcher , SIGNAL( fileChanged(const QString &)), this , SLOT( onWatchFileChanged(const QString &))); + connect(&_fileSystemWatcher , SIGNAL( directoryChanged(const QString &)), + this , SLOT( onWatchDirectoryChanged(const QString &))); connect(&_ApplicationController , SIGNAL(didPOSTEthernetData (const QString &)), this , SLOT( onPOSTEthernetData (const QString &))); @@ -777,6 +779,23 @@ } /*! + * \brief DeviceController::ondoAddDirWatch + * \details The thread safe add directory watch method + * \param vDirectory - The folder to add to watch. + */ +void DeviceController::ondoAddDirectoryWatch(const QString &vDirectory) +{ + QDir directory(vDirectory); + if ( !directory.exists()) { + LOG_DEBUG(DeviceError::deviceErrorText(DeviceError::eDevice_Watch_Error_NotFound, 0)); + return; + } + if ( ! _fileSystemWatcher.addPath(vDirectory) ) { + LOG_DEBUG(DeviceError::deviceErrorText(DeviceError::eDevice_Watch_Error_NotAdded, 0)); + } +} + +/*! * \brief DeviceController::onWatchFileChanged * \details This slot is called once the files being watched is updated. * \param vFile - the file name. @@ -787,6 +806,16 @@ } /*! + * \brief DeviceController::onWatchDirectoryChanged + * \details This slot is called once the folders being watched is updated. + * \param vDirectory - the name of the directory + */ +void DeviceController::onWatchDirectoryChanged(const QString &vDirectory) +{ + emit didWatchDirectoryChange(vDirectory); +} + +/*! * \brief DeviceController::onEventThreadChange * \details The signal handler for the DeviceController(this)::didEventThreadChange * to start checking for the Encrypted partition readyness. Index: sources/device/DeviceController.h =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/device/DeviceController.h (.../DeviceController.h) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/device/DeviceController.h (.../DeviceController.h) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -133,8 +133,8 @@ void onUSBDriveUmount(); void onWatchFileChanged(const QString &vFile); + void onWatchDirectoryChanged(const QString &vDirectory); - void onEventThreadChange (); /*! @@ -168,6 +168,7 @@ DeviceError::Scripts_Error_Enum checkScript(QString &vScript, const QString &vShellScript); bool addWatch(const QString &vFilePath); + bool addDirectoryWatch(const QString &vDirectoryPath); void checkConfugurationMountReady(); @@ -234,6 +235,7 @@ void didActionReceive( const DeviceRootSSHAccessResponseData &vRootSSHAccess); void didWatchFileChange(const QString &vFile); + void didWatchDirectoryChange(const QString &vDirectory); /*! * \brief didEventThreadChange @@ -266,5 +268,6 @@ void usbSpaceCheck(); SAFE_CALL_EX(doAddWatch, const QString &) + SAFE_CALL_EX(doAddDirectoryWatch, const QString &) }; } Index: sources/gui/GuiGlobals.cpp =================================================================== diff -u -ra53bdf104b52cae3a49705a4cc8bd886530084c9 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/gui/GuiGlobals.cpp (.../GuiGlobals.cpp) (revision a53bdf104b52cae3a49705a4cc8bd886530084c9) +++ sources/gui/GuiGlobals.cpp (.../GuiGlobals.cpp) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -50,6 +50,7 @@ #include "VDuetRoWaterDG.h" #include "VCloudSync.h" #include "VSDCardFilesModel.h" +#include "VLogSortFilterProxyModel.h" // states data #include "VHDOperationModeData.h" #include "VPreTreatmentStatesData.h" Index: sources/gui/qml/main.qml =================================================================== diff -u -ra53bdf104b52cae3a49705a4cc8bd886530084c9 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/gui/qml/main.qml (.../main.qml) (revision a53bdf104b52cae3a49705a4cc8bd886530084c9) +++ sources/gui/qml/main.qml (.../main.qml) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -47,7 +47,7 @@ import VDuetRoWaterDG 0.1 import VCloudSync 0.1 import VSDCardFilesModel 0.1 - +import VLogSortFilterProxyModel 0.1 // States views import VHDOperationMode 0.1 import VPreTreatmentStates 0.1 @@ -149,7 +149,9 @@ VDuetRoWaterDG { id: vDuetRoWaterDG } VCloudSync { id: vCloudSync } VSDCardFilesModel { id: vSDCardFiles } - + VLogSortFilterProxyModel {id: vSDCardLogProxyModel + sourceModel: vSDCardFiles + } // ---- States VHDOperationMode { id: vHDOperationMode onStandbyChanged: { Index: sources/gui/qml/pages/settings/SettingsExportLogs.qml =================================================================== diff -u -ra53bdf104b52cae3a49705a4cc8bd886530084c9 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/gui/qml/pages/settings/SettingsExportLogs.qml (.../SettingsExportLogs.qml) (revision a53bdf104b52cae3a49705a4cc8bd886530084c9) +++ sources/gui/qml/pages/settings/SettingsExportLogs.qml (.../SettingsExportLogs.qml) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -109,27 +109,22 @@ property bool isUpdatePanels: false function updatePanels (vIndex) { isUpdatePanels = true - +// TODO remove also when give USB a CPP model _GuiView.doExportListRemove() - _sdcFolderColumn.clearModel() _usbFolderColumn.clearModel() switch (vIndex) { case typeIndexApplication: - _sdcFolderColumn.currentTypeFolderApplication = typeFolderApplicationSrc _usbFolderColumn.currentTypeFolderApplication = typeFolderApplicationDst break case typeIndexService: - _sdcFolderColumn.currentTypeFolderApplication = typeFolderServiceSrc _usbFolderColumn.currentTypeFolderApplication = typeFolderServiceDst break case typeIndexTreatment: - _sdcFolderColumn.currentTypeFolderApplication = typeFolderTreatmentSrc _usbFolderColumn.currentTypeFolderApplication = typeFolderTreatmentDst break } - _sdcFolderColumn.updateModel() _usbFolderColumn.updateModel() isUpdatePanels = false @@ -186,7 +181,9 @@ // FIXME: This combobox needs to be a global Component ComboBox { id : _logTypeCombo onCurrentIndexChanged : { - _root.updatePanels(currentIndex) + //_root.updatePanels(currentIndex) + vLogSortFilterProxyModel.setFilterLogType(currentIndex) + //DEBUG console.log(">>>Index " + currentIndex) } enabled : ! _GuiView.exportRunning && ! isUpdatePanels currentIndex : 0 @@ -304,17 +301,6 @@ } Column { id : _sdcFolderColumn property string currentTypeFolderApplication : _root.typeFolderApplicationSrc - - // FIXME: there has to be a View for this, and the timer should be removed and an event driven signal should be implemented there. - function updateModel() { -// _sdcFolderModel.folder = currentTypeFolderApplication // FIXME: there has to be a View for this which also get changed by log type. -// _sdcFolderModel.nameFilters = _root.typeFilterAll - } - function clearModel() { -// _sdcFolderModel.folder = _root.typePathClr -// _sdcFolderModel.nameFilters = _root.typeFilterClr - } - spacing : 5 width : _contentRect.columnWidthFolder height : parent.height @@ -347,20 +333,6 @@ anchors.leftMargin : 5 anchors.rightMargin : 5 spacing : 3 -// FolderListModel { id : _sdcFolderModel -// onStatusChanged: { -// // onFolderChanged does not get emitted when switching folders, but status change does. -// // Reset the displayed file counter when the state of the model is null -// if (_sdcFolderModel.status == FolderListModel.Null) -// { -// _sdcFolderView.visibleFileCounter = 0 -// } -// } -// showDirs : false -// sortField : FolderListModel.Time -// folder : _sdcFolderColumn.currentTypeFolderApplication // FIXME: there has to be a View for this which also get changed by log type. -// } - Component { id : _sdcFileDelegate ProgressBar { id : _sdcItemBackground // *** IMPORTANT *** @@ -374,15 +346,14 @@ : 0 onExportPercentChanged : console.log( "%", exportPercent) - property bool isShownInList : true//!_GuiView.isPathSymLink(_sdcFolderColumn.currentTypeFolderApplication.replace(typePathPrefix, "") + "/" + fileName) - //DEBUG: onInExportListChanged: console.debug(" * ", index, inExportList) function exportListUpdate() { if (_GuiView.doExportListSelect( index ) ) { _GuiView.doExportListDelete( index ) } else { _GuiView.doExportListInsert( index , fileName ) + console.log("doExportListInsert ( " + index + "," +fileName +") filePath: " + filePath) } } @@ -399,23 +370,23 @@ // Setting height and width to 0 when the file is not shown in the list because // it is a symlink or other conditions - width : isShownInList ? _sdcFolderView.width : 0 - height : isShownInList ? 40 : 0 + width : _sdcFolderView.width + height : 40 bgColor : Colors.transparent color : inExportList ? Colors.borderButtonSelected : Colors.transparent radius : 5 Row { id : _sdcFileRow // Setting height and width to 0 when the file is not shown in the list because // it is a symlink or other conditions - width : isShownInList ? parent.width : 0 - height : isShownInList ? 40 : 0 + width : parent.width + height : 40 leftPadding : 5 Text { id : _sdcFileNameText x : 2 clip : true - width : isShownInList ? (_contentRect.columnWidthFileName - 2) : 0 + width : _contentRect.columnWidthFileName - 2 text : fileName color : Colors.textMain font.pixelSize : Fonts.fontPixelTextRectExtra @@ -424,12 +395,12 @@ } Rectangle { id : _sdcColumnVerticalLine color : Colors.borderButtonUnselected - width : isShownInList ? 1 : 0 + width : 1 height : parent.height + _usbFolderColumn.spacing } Text { id : _sdcFileSizeText clip : true - width : isShownInList ? _contentRect.columnWidthFileSize : 0 + width : _contentRect.columnWidthFileSize text : Variables.sizeConverted( fileSize_bytes, 1000, 3) color : Colors.textMain font.pixelSize : Fonts.fontPixelTextRectExtra @@ -439,7 +410,7 @@ } } } - model : vSDCardFiles + model : vSDCardLogProxyModel delegate : _sdcFileDelegate } } Index: sources/model/settings/MSDCardFile.h =================================================================== diff -u -ra53bdf104b52cae3a49705a4cc8bd886530084c9 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/model/settings/MSDCardFile.h (.../MSDCardFile.h) (revision a53bdf104b52cae3a49705a4cc8bd886530084c9) +++ sources/model/settings/MSDCardFile.h (.../MSDCardFile.h) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -17,8 +17,11 @@ // Qt #include #include +#include // Project +#include "StorageGlobals.h" +#include "Logger.h" // forward declarations class tst_models; @@ -49,14 +52,17 @@ } explicit Data() {} + explicit Data(Storage::Logger::LogType vLogType, const QFileInfo &vFileInfo) : _fileInfo(vFileInfo), _logType(vLogType) { } explicit Data(const QString &vFilePath) : _fileInfo(QFileInfo(vFilePath)) { } QString filePath() const { return _fileInfo.path(); } QString fileName() const { return _fileInfo.fileName (); } qint64 fileSize_bytes() const { return _fileInfo.size (); } - bool isSymLink() { return _fileInfo.isSymbolicLink(); } + int logType () const { return _logType; } + QDateTime lastModificationDateTime() const {return _fileInfo.fileTime(QFile::FileModificationTime);} private: QFileInfo _fileInfo; + Storage::Logger::LogType _logType; }; }; Index: sources/storage/Logger.cpp =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/storage/Logger.cpp (.../Logger.cpp) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/storage/Logger.cpp (.../Logger.cpp) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -643,3 +643,14 @@ } return result >= 0; // refer to QProcess::execute(hit F1 on execute) doc. } + +Logger::LogType Logger::getLogType(const QString &vPath) +{ + foreach (const char* path, _logBasePathNames.values()) { + if(vPath.contains(path)) { + return _logBasePathNames.key(path); + } + } + + return LogType::eLogNone; +} Index: sources/storage/Logger.h =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/storage/Logger.h (.../Logger.h) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/storage/Logger.h (.../Logger.h) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -90,6 +90,10 @@ }; Q_ENUM(LogType) + static QList getLogTypeList ( ) { return {LogType::eLogAppED, LogType::eLogDebug, LogType::eLogTrtmt};} + const char* getPathOfLogType (LogType vType) { return _logBasePathNames.value(vType); } + LogType getLogType(const QString &vPath); + private: bool _logStorageReady = true; Index: sources/view/VView.h =================================================================== diff -u -ra53bdf104b52cae3a49705a4cc8bd886530084c9 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/view/VView.h (.../VView.h) (revision a53bdf104b52cae3a49705a4cc8bd886530084c9) +++ sources/view/VView.h (.../VView.h) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -121,6 +121,7 @@ REGISTER_TYPE( VDuetRoWaterDG ) \ REGISTER_TYPE( VCloudSync ) \ REGISTER_TYPE( VSDCardFilesModel ) \ + REGISTER_TYPE( VLogSortFilterProxyModel ) \ /* Alarm */ \ REGISTER_TYPE( VAlarmStatus ) \ REGISTER_TYPE( VAlarmActiveList ) \ Index: sources/view/settings/VLogSortFilterProxyModel.cpp =================================================================== diff -u --- sources/view/settings/VLogSortFilterProxyModel.cpp (revision 0) +++ sources/view/settings/VLogSortFilterProxyModel.cpp (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -0,0 +1,61 @@ +/*! + * + * 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 VLogSortFilterProxyModel.cpp + * \author (last) Vy + * \date (last) 16-May-2023 + * \author (original) Behrouz NematiPour + * \date (original) 11-May-2021 + * + */ + +// Qt +#include + +// Project +#include "VLogSortFilterProxyModel.h" +#include "VSDCardFilesModel.h" + +using namespace View; + +VLogSortFilterProxyModel::VLogSortFilterProxyModel(QObject *vParent) + : QSortFilterProxyModel(vParent) +{ + setDynamicSortFilter(true); // enable automatic sorting when source model changes (eg: file add/removed) + + sort(0, Qt::DescendingOrder); + setFilterLogType(0); +} + +void VLogSortFilterProxyModel::setFilterLogType(int vLogTypeKey) +{ + // TODO need to add a check that the log type is correct or need some sort of enum system + _logType = vLogTypeKey; + invalidateFilter(); +} + +bool VLogSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + // column index to match index placement of FileLogType in SDCardFileDataRole + QModelIndex modelCellLogType = sourceModel()->index(source_row, 0, source_parent); + int rowDataLogType = sourceModel()->data(modelCellLogType, VSDCardFilesModel::FileLogTypeRole).toInt(); + return isLogOfType(rowDataLogType); +} + +bool VLogSortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const +{ + QVariant leftData = sourceModel()->data(source_left, VSDCardFilesModel::FileModificationDateTimeRole); + QVariant rightData = sourceModel()->data(source_right, VSDCardFilesModel::FileModificationDateTimeRole); + + // sorting by the last modification date + return leftData.toDateTime() < rightData.toDateTime(); +} + +bool VLogSortFilterProxyModel::isLogOfType(int vLogType) const +{ + return vLogType == _logType; +} Index: sources/view/settings/VLogSortFilterProxyModel.h =================================================================== diff -u --- sources/view/settings/VLogSortFilterProxyModel.h (revision 0) +++ sources/view/settings/VLogSortFilterProxyModel.h (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -0,0 +1,44 @@ +/*! + * + * 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 VLogSortFilterProxyModel.h + * \author (last) Behrouz NematiPour + * \date (last) 18-Jul-2023 + * \author (original) Behrouz NematiPour + * \date (original) 07-Jun-2021 + * + */ +#pragma once + +#include +#include + +// Project +#include "main.h" // Doxygen : do not remove + +namespace View { +class VLogSortFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + VLogSortFilterProxyModel(QObject *vParent = nullptr); + int filterLogType() const {return _logType;} + +public slots: + void setFilterLogType(int vLogTypeKey); + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const; + +private: + bool isLogOfType(int vLogType) const; + + int _logType; +}; +} Index: sources/view/settings/VSDCardFilesModel.cpp =================================================================== diff -u -ra53bdf104b52cae3a49705a4cc8bd886530084c9 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/view/settings/VSDCardFilesModel.cpp (.../VSDCardFilesModel.cpp) (revision a53bdf104b52cae3a49705a4cc8bd886530084c9) +++ sources/view/settings/VSDCardFilesModel.cpp (.../VSDCardFilesModel.cpp) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -14,13 +14,15 @@ */ // Qt -#include +#include // Project #include "VSDCardFilesModel.h" -#include "WifiInterface.h" #include "Logger.h" +#include "StorageGlobals.h" +#include "DeviceController.h" + using namespace View; VSDCardFilesModel::VSDCardFilesModel(QAbstractListModel *parent) : QAbstractListModel(parent) { @@ -35,83 +37,22 @@ */ void VSDCardFilesModel::initConnections() { - // incoming + 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 VSDCardFilesModel::addSDCardFile - * Adds a network to the network model - * \param network (Network) - the network to add to the model - */ -void VSDCardFilesModel::addSDCardFile(const SDCardFileData &vFileData) -{ - qDebug()<< "adding to SD card list : "<< vFileData.filePath() << "/" << vFileData.fileName(); - beginInsertRows(QModelIndex(), rowCount(), rowCount()); - _sdCardFiles << vFileData; - endInsertRows(); -} - -///*! -// * \brief VNetworkModel::removeRows -// * Removes all rows from the model -// */ -//void VSDCardFilesModel::removeAllRows() -//{ -// beginRemoveRows(QModelIndex(), 0, rowCount()); -// _networks.clear(); -// endRemoveRows(); -//} - -/*! * \brief VSDCardFilesModel::doInit * \details Initializes the view or what needs to be done when for example getting into the WiFi setting screen (do scan for now). */ void VSDCardFilesModel::doInit() { // Do the first population - - // WIP ! - QDir dir("/media/sd-card/log/"); - dir.setFilter(QDir::NoDotAndDotDot | QDir::Files); // not using "| QDir::NoSymLinks" dur to performance - dir.setSorting(QDir::Time); - QStringList listOfFiles = dir.entryList(); - - listOfFiles.append(listOfFiles); - - /******* - * // TODO - * NOTE TO FUTURE VY : TODO -------------------------- - * - * Need a QSortFilterProxyModel that can sort the file list - * - * To get all files in parent and subdir, use QDirIterator with : - * - * QDirIterator it("/etc", QDirIterator::Subdirectories); - * while (it.hasNext()) { .... } - * - * this will give us files from top and subdir, but it does not sort...This is - * where the ProxyModel comes in for sorting. - * - * The result from the QDirIterator will be the "source model". the source model will add/remove - * the added/removed files and the proxymodel will do the automatic sorting/filtering - * - * Need to figure out how to use one model for 3 directories, then use the proxy model to filter based on - * log category this will improve the performance since we are not re-creating the model each time - * - * The exposed model to the QML is the proxyModel. The proxyModel and the abstractlistmodel are both - * derived from the abstractItemModel. - * - * Get this ^^^ to work first and then refactor to re-use in USB - maybe - * - * Need to add a folder/file watcher to the log directories to monitor file add or remove and then update the source model - */ - qDebug()<= _sdCardFiles.count()) - return QVariant(); + if (index.row() < 0 || index.row() >= _sdCardFiles.count()) return QVariant(); const SDCardFileData &sdCardFile = _sdCardFiles[index.row()]; switch (role) { - case FilePathRole: return sdCardFile.filePath(); - case FileNameRole: return sdCardFile.fileName(); - case FileSizeRole: return sdCardFile.fileSize_bytes(); - -// case FilePathRole: return QString("somePath %1").arg(index.column());//sdCardFile.filePath(); -// case FileNameRole: return QString("someFilename %1").arg(index.column());//sdCardFile.fileName(); -// case FileSizeRole: return 150100;//sdCardFile.fileSize_bytes(); - + case FilePathRole: + return sdCardFile.filePath(); + case FileNameRole: + return sdCardFile.fileName(); + case FileSizeRole: + return sdCardFile.fileSize_bytes(); + case FileLogTypeRole : + return sdCardFile.logType(); + case FileModificationDateTimeRole: + return sdCardFile.lastModificationDateTime(); } return QVariant(); @@ -164,34 +106,67 @@ roles[FilePathRole] = "filePath"; roles[FileNameRole] = "fileName"; roles[FileSizeRole] = "fileSize_bytes"; + roles[FileLogTypeRole] = "fileLogType"; + roles[FileModificationDateTimeRole] = "fileModDateTime"; return roles; } /*! - * \brief VSDCardFilesModel::onAddSDCardFile - * Slot that receives a request to add a new file - * \param vFileData - the new sd card file data + * \brief VSDCardFilesModel::timerEvent + * \details The overloaded parent QObject timer event handler function */ -void VSDCardFilesModel::onAddSDCardFile(const SDCardFileData &vFileData) +void VSDCardFilesModel::timerEvent(QTimerEvent *) { - if (!_sdCardFiles.contains(vFileData)) - { - qDebug() < logTypes = Storage::Logger::getLogTypeList(); + foreach(Storage::Logger::LogType type , logTypes) + { + QString folderPath = QString("%1%2").arg(Storage::Log_Folder_Base).arg(_Logger.getPathOfLogType(type)); + + // Add to systemWatcher to update for changes + _DeviceController.doAddDirectoryWatch(folderPath); + + QDirIterator dirIterator(folderPath, QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + QString absolutePath; + absolutePath = dirIterator.path(); + while(dirIterator.hasNext()) { + absolutePath = dirIterator.next(); + if(!dirIterator.fileName().isEmpty()) + { + //DEBUG: qDebug() << " FOUND " << absolutePath + dirIterator.fileName(); + _sdCardFiles.append(SDCardFileData(type, dirIterator.fileInfo())); + } + } + } } Index: sources/view/settings/VSDCardFilesModel.h =================================================================== diff -u -ra53bdf104b52cae3a49705a4cc8bd886530084c9 -r61f87c52ccba9ce140fd8039915e025b6c790575 --- sources/view/settings/VSDCardFilesModel.h (.../VSDCardFilesModel.h) (revision a53bdf104b52cae3a49705a4cc8bd886530084c9) +++ sources/view/settings/VSDCardFilesModel.h (.../VSDCardFilesModel.h) (revision 61f87c52ccba9ce140fd8039915e025b6c790575) @@ -17,6 +17,7 @@ // Qt #include #include +#include // Project #include "main.h" @@ -36,15 +37,13 @@ * References: https://doc.qt.io/qt-5.12/qtquick-modelviewsdata-cppmodels.html * */ + +// TODO need to rename to a more generic and derive for USB case too class VSDCardFilesModel : public QAbstractListModel { Q_OBJECT int _interval = 1000; - - PROPERTY(QString , fileName , "") - PROPERTY(qint64 , fileSize , 0) - public: // Note: VIEW_DEC_CLASS(VSDCardFilesModel) requires QObject as the parent, so it's necessary to define it here // Otherwise a VIEW_DEC_CLASS macro could allow specifying the parent class with QObject as the default @@ -54,6 +53,8 @@ FilePathRole = Qt::UserRole + 1 , FileNameRole , FileSizeRole , + FileLogTypeRole , + FileModificationDateTimeRole , }; void addSDCardFile (const SDCardFileData &vFileData); @@ -68,12 +69,13 @@ private: void initConnections(); - void clearSelectedNetwork(); + void populateLogModel(); + void resetModel(); QList _sdCardFiles; private slots: - void onAddSDCardFile(const SDCardFileData &vFileData); -// void updateList(const QString &vPathChanged); + void onWatchDirectoryChange(const QString &vDirectory); + void onTotalModelRefresh(bool vIsStrillProcessing); }; }