Merge branch 'master' into translations

This commit is contained in:
ArieKlerk 2020-05-28 13:09:37 +02:00
commit a58ad16e38
13 changed files with 344 additions and 193 deletions

View File

@ -29,16 +29,12 @@ Run the installer, accepting options to install inno script studio (for possible
Go to <https://gitforwindows.org/> and click on the Download button. Run the installer, which presents lots of options: Go to <https://gitforwindows.org/> and click on the Download button. Run the installer, which presents lots of options:
- Select whichever editor you desire. - Select whichever editor you desire.
- Select “Use Git from the command line and also from 3rd-party software.” - Select “Use Git from the command line and also from 3rd-party software.”
- Select “Use the OpenSSL library.” - Select “Use the OpenSSL library.”
- Select “Checkout Windows-style, commit Unix-style line endings.” - Select “Checkout Windows-style, commit Unix-style line endings.”
- Select “Use Windows default console window.” I find the Windows default console to be satisfactory on Windows 10. - Select “Use Windows default console window.” I find the Windows default console to be satisfactory on Windows 10.
- Select "Enable symbolic links"
- Leave extra options as they default (enable file system caching, enable Git credential manager, but not symbolic links). - Leave other extra options as they default (enable file system caching, enable Git credential manager).
GIT for Windows adds itself to your path. GIT for Windows adds itself to your path.

View File

@ -106,7 +106,7 @@
</message> </message>
<message> <message>
<source> i </source> <source> i </source>
<translation type="unfinished">Italique</translation> <translation> Italique </translation>
</message> </message>
<message> <message>
<source>Big</source> <source>Big</source>
@ -266,7 +266,7 @@
</message> </message>
<message> <message>
<source>&quot;Nothing&apos;s here!&quot;</source> <source>&quot;Nothing&apos;s here!&quot;</source>
<translation>Rien ici !</translation> <translation>&quot;Rien ici !&quot;</translation>
</message> </message>
<message> <message>
<source>Awesome</source> <source>Awesome</source>
@ -442,7 +442,7 @@
</message> </message>
<message> <message>
<source>This bookmark is in a currently disabled area..</source> <source>This bookmark is in a currently disabled area..</source>
<translation>Ce favori est actuellement en zone désactivée...</translation> <translation>Ce favori est actuellement en zone désactivée..</translation>
</message> </message>
</context> </context>
<context> <context>
@ -533,7 +533,7 @@
</message> </message>
<message> <message>
<source>Last Month</source> <source>Last Month</source>
<translation>Dernier mois</translation> <translation>Mois dernier</translation>
</message> </message>
<message> <message>
<source>Last 6 Months</source> <source>Last 6 Months</source>
@ -1507,7 +1507,7 @@
</message> </message>
<message> <message>
<source>D.O.B.</source> <source>D.O.B.</source>
<translation> le</translation> <translation> le.</translation>
</message> </message>
<message> <message>
<source>Female</source> <source>Female</source>
@ -1743,7 +1743,7 @@ respiratoires</translation>
</message> </message>
<message> <message>
<source>Last Three Months</source> <source>Last Three Months</source>
<translation>Derniers 3 mois</translation> <translation>3 derniers mois</translation>
</message> </message>
<message> <message>
<source>Total Time in Apnea <source>Total Time in Apnea
@ -1775,7 +1775,7 @@ respiratoires</translation>
</message> </message>
<message> <message>
<source>Last Month</source> <source>Last Month</source>
<translation>Dernier mois</translation> <translation>Mois dernier</translation>
</message> </message>
<message> <message>
<source>Apnea <source>Apnea
@ -1801,7 +1801,7 @@ corporelle</translation>
</message> </message>
<message> <message>
<source>Last Two Weeks</source> <source>Last Two Weeks</source>
<translation>Dernières 2 semaines</translation> <translation>2 dernières semaines</translation>
</message> </message>
<message> <message>
<source>Everything</source> <source>Everything</source>
@ -1813,7 +1813,7 @@ corporelle</translation>
</message> </message>
<message> <message>
<source>Last Year</source> <source>Last Year</source>
<translation>Dernière année</translation> <translation>Année dernière</translation>
</message> </message>
<message> <message>
<source>Toggle Graph Visibility</source> <source>Toggle Graph Visibility</source>
@ -1825,7 +1825,7 @@ corporelle</translation>
</message> </message>
<message> <message>
<source>Last Two Months</source> <source>Last Two Months</source>
<translation>Derniers 2 mois</translation> <translation>2 derniers mois</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1884,7 +1884,7 @@ corporelle</translation>
</message> </message>
<message> <message>
<source>Oximeter import completed..</source> <source>Oximeter import completed..</source>
<translation>Import terminé...</translation> <translation>Import terminé..</translation>
</message> </message>
<message> <message>
<source>&amp;Retry</source> <source>&amp;Retry</source>
@ -3241,7 +3241,7 @@ To use it with ResScan will require the .gz files to be uncompressed first..</so
Format courant sous Linux et Mac. Format courant sous Linux et Mac.
OSCAR peut importer de ce répertoire de sauvegarde compressé en mode natif. OSCAR peut importer de ce répertoire de sauvegarde compressé en mode natif.
Pour l&apos;utiliser avec ResScan, il faudra d&apos;abord décompresser les fichiers *.gz...</translation> Pour l&apos;utiliser avec ResScan, il faudra d&apos;abord décompresser les fichiers *.gz..</translation>
</message> </message>
<message> <message>
<source>The following options affect the amount of disk space OSCAR uses, and have an effect on how long import takes.</source> <source>The following options affect the amount of disk space OSCAR uses, and have an effect on how long import takes.</source>
@ -3269,7 +3269,7 @@ OSCAR can keep a copy of this data if you ever need to reinstall.
<translation>Garde un copie de la carte SD des appareils ResMed. <translation>Garde un copie de la carte SD des appareils ResMed.
Les appareils ResMed effacent les données précises après 7 jours, et les graphiques de plus de 30 jours... Les appareils ResMed effacent les données précises après 7 jours, et les graphiques de plus de 30 jours...
OSCAR peut garder ces données au cas vous devriez réinstaller (Hautement recommandé, à moins que vous n&apos;ayez pas de place disque ou que les graphiques ne vous intéressent pas).</translation> OSCAR peut garder ces données au cas vous devriez réinstaller (Hautement recommandé, à moins que vous n&apos;ayez pas de place disque ou que les graphiques ne vous intéressent pas)</translation>
</message> </message>
<message> <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Makes starting OSCAR a bit slower, by pre-loading all the summary data in advance, which speeds up overview browsing and a few other calculations later on. &lt;/p&gt;&lt;p&gt;If you have a large amount of data, it might be worth keeping this switched off, but if you typically like to view &lt;span style=&quot; font-style:italic;&quot;&gt;everything&lt;/span&gt; in overview, all the summary data still has to be loaded anyway. &lt;/p&gt;&lt;p&gt;Note this setting doesn&apos;t affect waveform and event data, which is always demand loaded as needed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source> <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Makes starting OSCAR a bit slower, by pre-loading all the summary data in advance, which speeds up overview browsing and a few other calculations later on. &lt;/p&gt;&lt;p&gt;If you have a large amount of data, it might be worth keeping this switched off, but if you typically like to view &lt;span style=&quot; font-style:italic;&quot;&gt;everything&lt;/span&gt; in overview, all the summary data still has to be loaded anyway. &lt;/p&gt;&lt;p&gt;Note this setting doesn&apos;t affect waveform and event data, which is always demand loaded as needed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
@ -3814,7 +3814,7 @@ p, li { white-space: pre-wrap; }
</message> </message>
<message> <message>
<source>Kg</source> <source>Kg</source>
<translation> Kg</translation> <translation>Kg</translation>
</message> </message>
<message> <message>
<source>O2</source> <source>O2</source>
@ -6844,7 +6844,7 @@ corporelle</translation>
</message> </message>
<message> <message>
<source>Last 30 Days</source> <source>Last 30 Days</source>
<translation>Dernier mois</translation> <translation>Mois dernier</translation>
</message> </message>
<message> <message>
<source>%1 Index</source> <source>%1 Index</source>
@ -6892,7 +6892,7 @@ corporelle</translation>
</message> </message>
<message> <message>
<source>Last 6 Months</source> <source>Last 6 Months</source>
<translation>6 Derniers mois</translation> <translation>6 derniers mois</translation>
</message> </message>
<message> <message>
<source>Average %1</source> <source>Average %1</source>
@ -6924,7 +6924,7 @@ corporelle</translation>
</message> </message>
<message> <message>
<source>Last Year</source> <source>Last Year</source>
<translation>Dernière année</translation> <translation>Année dernière</translation>
</message> </message>
<message> <message>
<source>Details</source> <source>Details</source>

View File

@ -116,7 +116,9 @@ void gLineChart::SetDay(Day *d)
Session *sess = d->sessions[i]; Session *sess = d->sessions[i];
if (!sess->enabled()) continue; if (!sess->enabled()) continue;
CPAPMode mode = (CPAPMode)sess->settings[CPAP_Mode].toInt(); // Don't use operator[] here or else it will insert a default-constructed entry
// into sess->settings if it's not present.
CPAPMode mode = (CPAPMode)sess->settings.value(CPAP_Mode).toInt();
if (mode >= MODE_BILEVEL_FIXED) { if (mode >= MODE_BILEVEL_FIXED) {
m_enabled[CPAP_Pressure] = true; // probably a confusion of Pressure and IPAP somewhere m_enabled[CPAP_Pressure] = true; // probably a confusion of Pressure and IPAP somewhere

View File

@ -223,7 +223,10 @@ void gLineOverlayBar::paint(QPainter &painter, gGraph &w, const QRegion &region)
painter.drawRect(rect); painter.drawRect(rect);
// Queue tooltip // Queue tooltip
QString lab2 = QString("%1 (%2)").arg(schema::channel[m_code].fullname()).arg(raw); QString lab2 = QString("%1").arg(schema::channel[m_code].fullname());
if (raw != 0) // Hide duration when it is zero
lab2 += QString(" (%1)").arg(raw);
w.ToolTip(lab2, x1 - 10, start_py + 24 + (3 * w.printScaleY()), TT_AlignRight, AppSetting->tooltipTimeout()); w.ToolTip(lab2, x1 - 10, start_py + 24 + (3 * w.printScaleY()), TT_AlignRight, AppSetting->tooltipTimeout());
painter.setPen(QPen(col,3)); painter.setPen(QPen(col,3));

View File

@ -308,6 +308,13 @@ EventDataType Day::settings_wavg(ChannelID code)
auto set = sess->settings.find(code); auto set = sess->settings.find(code);
if (set != sess->settings.end()) { if (set != sess->settings.end()) {
if (code == CPAP_Mode && sess->type() != MT_CPAP) {
// There used to be a bug in gLineChart::SetDay that inserted a CPAP_Mode
// setting in any session that didn't already have one. That shouldn't
// happen any more, but leave this diagnostic message here in case it does.
qWarning() << sess->session() << "non-CPAP session with CPAP mode setting";
continue;
}
s0 = sess->hours(); s0 = sess->hours();
tmp = set.value().toDouble(); tmp = set.value().toDouble();
s1 += tmp * s0; s1 += tmp * s0;

View File

@ -16,6 +16,11 @@
#include <QDir> #include <QDir>
#include <QMessageBox> #include <QMessageBox>
#define NEWXML
#ifdef NEWXML
#include <QXmlStreamWriter>
#endif
const int journal_data_version = 1; const int journal_data_version = 1;
JournalEntry::JournalEntry(QDate date) JournalEntry::JournalEntry(QDate date)
@ -205,7 +210,105 @@ void JournalEntry::delBookmark(qint64 start, qint64 end)
// if I wanted to be nice above, I could add the note string to the search as well.. // if I wanted to be nice above, I could add the note string to the search as well..
// (some users might be suprised to see the lot go with the same start and end index) // (some users might be suprised to see the lot go with the same start and end index)
} }
#ifdef NEWXML
void BackupJournal(QString filename)
{
QString outBuf;
QXmlStreamWriter stream(&outBuf);
stream.setAutoFormatting(true);
stream.setAutoFormattingIndent(2);
stream.writeStartDocument();
stream.writeStartElement("OSCAR");
stream.writeStartElement("Journal");
stream.writeAttribute("username", p_profile->user->userName());
QDate first = p_profile->FirstDay(MT_JOURNAL);
QDate last = p_profile->LastDay(MT_JOURNAL);
QDate date = first.addDays(-1);
do {
date = date.addDays(1);
Day * journal = p_profile->GetDay(date, MT_JOURNAL);
if (!journal) continue;
Session * sess = journal->firstSession(MT_JOURNAL);
if (!sess) continue;
if ( !journal->settingExists(Journal_Notes)
&& !journal->settingExists(Journal_Weight)
&& !journal->settingExists(Journal_ZombieMeter)
&& !journal->settingExists(LastUpdated)
&& !journal->settingExists(Bookmark_Start)) {
continue;
}
stream.writeStartElement("day");
stream.writeAttribute("date", date.toString());
if (journal->settingExists(Journal_Weight)) {
QString weight = sess->settings[Journal_Weight].toString();
stream.writeAttribute("weight", weight);
}
if (journal->settingExists(Journal_ZombieMeter)) {
QString zombie = sess->settings[Journal_ZombieMeter].toString();
stream.writeAttribute("zombie", zombie);
}
if (journal->settingExists(LastUpdated)) {
QDateTime dt = sess->settings[LastUpdated].toDateTime();
#if QT_VERSION < QT_VERSION_CHECK(5,8,0)
qint64 dtx = dt.toMSecsSinceEpoch()/1000L;
#else
qint64 dtx = dt.toSecsSinceEpoch();
#endif
QString dts = QString::number(dtx);
stream.writeAttribute("lastupdated", dts);
}
if (journal->settingExists(Journal_Notes)) {
stream.writeStartElement("note");
stream.writeTextElement("text", sess->settings[Journal_Notes].toString());
stream.writeEndElement(); // notes
}
if (journal->settingExists(Bookmark_Start)) {
QVariantList start=sess->settings[Bookmark_Start].toList();
QVariantList end=sess->settings[Bookmark_End].toList();
QStringList notes=sess->settings[Bookmark_Notes].toStringList();
stream.writeStartElement("bookmarks");
int size = start.size();
for (int i=0; i< size; i++) {
stream.writeStartElement("bookmark");
stream.writeAttribute("notes",notes.at(i));
stream.writeAttribute("start",start.at(i).toString());
stream.writeAttribute("end",end.at(i).toString());
stream.writeEndElement(); // bookmark
}
stream.writeEndElement(); // bookmarks
}
stream.writeEndElement(); // day
} while (date <= last);
stream.writeEndElement(); // Journal
stream.writeEndElement(); // OSCAR
stream.writeEndDocument();
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
return;
}
QTextStream ts(&file);
ts << outBuf;
file.close();
}
#else
void BackupJournal(QString filename) void BackupJournal(QString filename)
{ {
QDomDocument doc("OSCAR Journal"); QDomDocument doc("OSCAR Journal");
@ -281,6 +384,7 @@ void BackupJournal(QString filename)
ts << doc.toString(); ts << doc.toString();
file.close(); file.close();
} }
#endif
DayController::DayController() DayController::DayController()
{ {

View File

@ -145,7 +145,7 @@ public:
date=QDate(); date=QDate();
} }
STRRecord(const STRRecord & copy) = default; STRRecord(const STRRecord & /*copy*/) = default;
// All the data members // All the data members
@ -232,7 +232,7 @@ public:
filename(QString()), days(0), edf(nullptr) {} filename(QString()), days(0), edf(nullptr) {}
STRFile(QString name, long int recCnt, ResMedEDFInfo *str) : STRFile(QString name, long int recCnt, ResMedEDFInfo *str) :
filename(name), days(recCnt), edf(str) {} filename(name), days(recCnt), edf(str) {}
STRFile(const STRFile & copy) = default; STRFile(const STRFile & /*copy*/) = default;
virtual ~STRFile() {} virtual ~STRFile() {}

View File

@ -245,9 +245,10 @@ MachineInfo ResmedLoader::PeekInfo(const QString & path)
long event_cnt = 0; long event_cnt = 0;
bool parseIdentTGT( QString path, MachineInfo * info, QHash<QString, QString> & idmap ); // forward bool parseIdentTGT( QString path, MachineInfo * info, QHash<QString, QString> & idmap ); // forward
void BackupSTRfiles( const QString strpath, const QString path, const QString strBackupPath, void backupSTRfiles( const QString strpath, const QString importPath, const QString backupPath,
MachineInfo & info, QMap<QDate, STRFile> & STRmap ); // forward MachineInfo & info, QMap<QDate, STRFile> & STRmap ); // forward
ResMedEDFInfo * fetchSTRandVerify( QString filename, QString serialNumber ); // forward
int ResmedLoader::Open(const QString & dirpath, ResDaySaveCallback s) // alternate for unit testing int ResmedLoader::Open(const QString & dirpath, ResDaySaveCallback s) // alternate for unit testing
{ {
@ -263,24 +264,24 @@ int ResmedLoader::Open(const QString & dirpath)
QString datalogPath; QString datalogPath;
QHash<QString, QString> idmap; // Temporary machine ID properties hash QHash<QString, QString> idmap; // Temporary machine ID properties hash
QString path(dirpath); QString importPath(dirpath);
path = path.replace("\\", "/"); importPath = importPath.replace("\\", "/");
// Strip off end "/" if any // Strip off end "/" if any
if (path.endsWith("/")) { if (importPath.endsWith("/")) {
path = path.section("/", 0, -2); importPath = importPath.section("/", 0, -2);
} }
// Strip off DATALOG from path, and set newpath to the path containing DATALOG // Strip off DATALOG from importPath, and set newimportPath to the importPath containing DATALOG
if (path.endsWith(RMS9_STR_datalog)) { if (importPath.endsWith(RMS9_STR_datalog)) {
datalogPath = path + "/"; datalogPath = importPath + "/";
path = path.section("/", 0, -2); importPath = importPath.section("/", 0, -2);
} else { } else {
datalogPath = path + "/" + RMS9_STR_datalog + "/"; datalogPath = importPath + "/" + RMS9_STR_datalog + "/";
} }
// Add separator back // Add separator back
path += "/"; importPath += "/";
// Check DATALOG folder exists and is readable // Check DATALOG folder exists and is readable
if (!QDir().exists(datalogPath)) { if (!QDir().exists(datalogPath)) {
@ -291,7 +292,7 @@ int ResmedLoader::Open(const QString & dirpath)
m_abort = false; m_abort = false;
MachineInfo info = newInfo(); MachineInfo info = newInfo();
if ( ! parseIdentTGT(path, & info, idmap) ) { if ( ! parseIdentTGT(importPath, & info, idmap) ) {
qDebug() << "Failed to parse Identification.tgt"; qDebug() << "Failed to parse Identification.tgt";
return -1; return -1;
} }
@ -311,7 +312,7 @@ int ResmedLoader::Open(const QString & dirpath)
} }
// Early check for STR.edf file, so we can early exit before creating faulty machine record. // Early check for STR.edf file, so we can early exit before creating faulty machine record.
QString strpath = path + RMS9_STR_strfile + STR_ext_EDF; // STR.edf file QString strpath = importPath + "STR.edf"; // STR.edf file
QFile f(strpath); QFile f(strpath);
if (!f.exists()) { // No STR.edf.. Do we have a STR.edf.gz? if (!f.exists()) { // No STR.edf.. Do we have a STR.edf.gz?
@ -348,27 +349,55 @@ int ResmedLoader::Open(const QString & dirpath)
firstImportDay = ignoreBefore.date(); firstImportDay = ignoreBefore.date();
qDebug() << "First day to import: " << firstImportDay.toString(); qDebug() << "First day to import: " << firstImportDay.toString();
bool importing_backups = false; bool rebuild_from_backups = false;
bool create_backups = p_profile->session->backupCardData(); bool create_backups = p_profile->session->backupCardData();
bool compress_backups = p_profile->session->compressBackupData(); bool compress_backups = p_profile->session->compressBackupData();
QString backup_path = mach->getBackupPath(); QString backup_path = mach->getBackupPath();
if (path == backup_path) { if (importPath == backup_path) {
// Don't create backups if importing from backup folder // Don't create backups if importing from backup folder
importing_backups = true; rebuild_from_backups = true;
create_backups = false; create_backups = false;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Parse the idmap into machine objects properties, (overwriting any old values) // Copy the idmap into machine objects properties, (overwriting any old values)
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
for (auto i=idmap.begin(), idend=idmap.end(); i != idend; i++) { for (auto i=idmap.begin(), idend=idmap.end(); i != idend; i++) {
mach->properties[i.key()] = i.value(); mach->properties[i.key()] = i.value();
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Open and Parse STR.edf files (including those listed in STR_Backup) // Create the backup folder structure for storing a copy of everything in..
// (Unless we are importing from this backup folder)
///////////////////////////////////////////////////////////////////////////////////
QDir dir;
if (create_backups) {
if ( ! dir.exists(backup_path)) {
if ( ! dir.mkpath(backup_path) ) {
qDebug() << "Could not create ResMed backup directory :-/";
}
}
// Create the STR_Backup folder if it doesn't exist
QString strBackupPath = backup_path + "STR_Backup";
if ( ! dir.exists(strBackupPath) )
dir.mkpath(strBackupPath);
QString newpath = backup_path + "DATALOG";
if ( ! dir.exists(newpath) )
dir.mkpath(newpath);
// Copy Identification files to backup folder
QFile::copy(importPath + RMS9_STR_idfile + STR_ext_TGT, backup_path + RMS9_STR_idfile + STR_ext_TGT);
QFile::copy(importPath + RMS9_STR_idfile + STR_ext_CRC, backup_path + RMS9_STR_idfile + STR_ext_CRC);
}
///////////////////////////////////////////////////////////////////////////////////
// Open and Process STR.edf files (including those listed in STR_Backup)
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
resdayList.clear(); resdayList.clear();
@ -380,45 +409,64 @@ int ResmedLoader::Open(const QString & dirpath)
QMap<QDate, STRFile> STRmap; QMap<QDate, STRFile> STRmap;
// Create the STR_Backup folder if it doesn't exist if ( ( ! rebuild_from_backups) /* && create_backups */ ) {
QString strBackupPath = backup_path + "STR_Backup"; // first we copy any STR_yyyymmdd.edf files and the Backup/STR.edf into STR_Backup and the STRmap
QDir dir; backupSTRfiles( strpath, importPath, backup_path, info, STRmap );
if ( ! dir.exists(strBackupPath)) //Then we copy the new imported STR.edf into Backup/STR.edf and add it to the STRmap
dir.mkpath(strBackupPath); QString importFile(importPath+"STR.edf");
QString backupFile(backup_path + "STR.edf");
QString newpath = backup_path + "DATALOG"; ResMedEDFInfo * stredf = fetchSTRandVerify( importFile, info.serial );
if ( ! dir.exists(newpath) ) if ( stredf != nullptr ) {
dir.mkpath(newpath); bool addToSTRmap = true;
QDate date = stredf->edfHdr.startdate_orig.date();
if ( ! importing_backups ) { long int days = stredf->GetNumDataRecords();
BackupSTRfiles( strpath, path, strBackupPath, info, STRmap ); qDebug() << importFile.section("/",-2,-1) << "starts at" << date << "for" << days << "ends" << date.addDays(days-1);
} else { // get the STR file that is in the BACKUP folder if (STRmap.contains(date)) { // Keep the longer of the two STR files
ResMedEDFInfo * stredf = new ResMedEDFInfo(); qDebug() << importFile.section("/",-3,-1) << "overlaps" << STRmap[date].filename.section("/",-3,-1) << "for" << days << "ends" << date.addDays(days-1);
if ( stredf->Open(strpath) ) { if (days > STRmap[date].days) {
if ( stredf->Parse()) { qDebug() << "Removing" << STRmap[date].filename.section("/",-3,-1) << "with" << STRmap[date].days;
if (stredf->serialnumber != info.serial) { STRmap.remove(date);
qDebug() << "Identification.tgt Serial number doesn't match" << strpath; } else {
qDebug() << "Skipping" << importFile.section("/",-3,-1);
qWarning() << "New import is shorter than exisiting files - should never happen";
delete stredf; delete stredf;
} else { // passed the tests, stuff it into the map addToSTRmap = false;
QDate date = stredf->edfHdr.startdate_orig.date();
long int days = stredf->GetNumDataRecords();
qDebug() << strpath.section("/",-2,-1) << "starts at" << date << "for" << days << "ends" << date.addDays(days-1);
STRmap[date] = STRFile(strpath, days, stredf);
} }
} else {
qDebug() << "Faulty STR file" << strpath;
delete stredf;
} }
if ( addToSTRmap ) {
if ( compress_backups ) {
backupFile += ".gz";
if ( QFile::exists( backupFile ) )
QFile::remove( backupFile );
compressFile(importFile, backupFile);
}
else {
if ( QFile::exists( backupFile ) )
QFile::remove( backupFile );
if ( ! QFile::copy(importFile, backupFile) )
qWarning() << "Failed to copy" << importFile << "to" << backupFile;
}
STRmap[date] = STRFile(backupFile, days, stredf);
// Meh.. these can be calculated if ever needed for ResScan SDcard export
QFile::copy(importPath + "STR.crc", backup_path + "STR.crc");
}
}
} else { // get the STR file that is in the BACKUP folder that we are rebuilding from
ResMedEDFInfo * stredf = fetchSTRandVerify( strpath, info.serial );
if ( stredf != nullptr ) {
QDate date = stredf->edfHdr.startdate_orig.date();
long int days = stredf->GetNumDataRecords();
qDebug() << strpath.section("/",-2,-1) << "starts at" << date << "for" << days << "ends" << date.addDays(days-1);
STRmap[date] = STRFile(strpath, days, stredf);
} else { } else {
qDebug() << "Failed to open" << strpath; qDebug() << "Failed to open" << strpath;
delete stredf;
} }
} // end if not importing the backup files } // end if not importing the backup files
#ifdef STR_DEBUG #ifdef STR_DEBUG
qDebug() << "STRmap size is " << STRmap.size(); qDebug() << "STRmap size is " << STRmap.size();
#endif #endif
// Now we open the REAL STR_Backup, and open the rest for later parsing // Now we open the REAL destination STR_Backup, and open the rest for later parsing
dir.setPath(backup_path + "STR_Backup"); dir.setPath(backup_path + "STR_Backup");
dir.setFilter(QDir::Files | QDir::Hidden | QDir::Readable); dir.setFilter(QDir::Files | QDir::Hidden | QDir::Readable);
@ -429,6 +477,7 @@ int ResmedLoader::Open(const QString & dirpath)
qDebug() << "STR_Backup folder size is " << flist.size(); qDebug() << "STR_Backup folder size is " << flist.size();
#endif #endif
qDebug() << "Add files in STR_Backup to STRmap (unless they are already there)";
// Add any STR_Backup versions to the file list // Add any STR_Backup versions to the file list
for (auto & fi : flist) { for (auto & fi : flist) {
QString filename = fi.fileName(); QString filename = fi.fileName();
@ -437,46 +486,27 @@ int ResmedLoader::Open(const QString & dirpath)
if (!(filename.endsWith("edf.gz", Qt::CaseInsensitive) || filename.endsWith("edf", Qt::CaseInsensitive))) if (!(filename.endsWith("edf.gz", Qt::CaseInsensitive) || filename.endsWith("edf", Qt::CaseInsensitive)))
continue; continue;
QString datestr = filename.section("STR-",-1).section(".edf",0,0); // +"01"; QString datestr = filename.section("STR-",-1).section(".edf",0,0); // +"01";
// date = QDate().fromString(datestr,"yyyyMMdd");
//
// if (STRmap.contains(date)) {
// qDebug() << filename << "overlaps anothor STR file";
// continue;
// }
ResMedEDFInfo * stredf = new ResMedEDFInfo(); ResMedEDFInfo * stredf = fetchSTRandVerify( fi.canonicalFilePath(), info.serial );
if ( ! stredf->Open(fi.canonicalFilePath() ) ) { if ( stredf == nullptr )
qDebug() << "Failed to open" << fi.canonicalFilePath();
delete stredf;
continue; continue;
}
if ( ! stredf->Parse()) {
qDebug() << "Faulty STR file" << filename;
delete stredf;
continue;
}
if (stredf->serialnumber != info.serial) {
qDebug() << "Identification.tgt Serial number doesn't match" << filename;
delete stredf;
continue;
}
// Don't trust the filename date, pick the one inside the STR... // Don't trust the filename date, pick the one inside the STR...
date = stredf->edfHdr.startdate_orig.date(); date = stredf->edfHdr.startdate_orig.date();
days = stredf->GetNumDataRecords(); days = stredf->GetNumDataRecords();
if (STRmap.contains(date)) { // Keep the longer of the two STR files if (STRmap.contains(date)) { // Keep the longer of the two STR files
qDebug() << filename << "overlaps" << STRmap[date].filename.section("/",-2,-1) << "for" << days << "ends" << date.addDays(days-1); qDebug() << fi.canonicalFilePath().section("/",-3,-1) << "overlaps" << STRmap[date].filename.section("/",-3,-1) << "for" << days << "ends" << date.addDays(days-1);
if (days <= STRmap[date].days) { if (days <= STRmap[date].days) {
qDebug() << "Skipping" << filename; qDebug() << "Skipping" << fi.canonicalFilePath().section("/",-3,-1);
delete stredf; delete stredf;
continue; continue;
} else {
qDebug() << "Removing" << STRmap[date].filename.section("/",-3,-1);
STRmap.remove(date);
} }
} }
// qDebug() << "Resetting STR date from" << date.toString() << "to first of month ... WHY???";
// date = QDate(date.year(), date.month(), 1);
qDebug() << fi.canonicalFilePath().section("/", -2,-1) << "starts at" << date << "for" << days; qDebug() << "Adding" << fi.canonicalFilePath().section("/", -2,-1) << "starts at" << date << "for" << days;
STRmap[date] = STRFile(fi.canonicalFilePath(), days, stredf); STRmap[date] = STRFile(fi.canonicalFilePath(), days, stredf);
} // end for walking the STR_Backup directory } // end for walking the STR_Backup directory
#ifdef STR_DEBUG #ifdef STR_DEBUG
@ -496,7 +526,7 @@ int ResmedLoader::Open(const QString & dirpath)
for (auto it=STRmap.begin(), end=STRmap.end(); it != end; ++it) { for (auto it=STRmap.begin(), end=STRmap.end(); it != end; ++it) {
QString fullname = it.value().filename; QString fullname = it.value().filename;
#ifdef STR_DEBUG #ifdef STR_DEBUG
qDebug() << "Deleting edf of" << fullname; qDebug() << "Deleting edf object of" << fullname;
#endif #endif
QString datepart = fullname.section("STR-",-1).section(".edf",0,0); QString datepart = fullname.section("STR-",-1).section(".edf",0,0);
if (datepart.size() == 6 ) { // old style name, change to full date if (datepart.size() == 6 ) { // old style name, change to full date
@ -505,9 +535,9 @@ int ResmedLoader::Open(const QString & dirpath)
QString newName = fullname.replace(datepart, newdate); QString newName = fullname.replace(datepart, newdate);
qDebug() << "Renaming" << it.value().filename << "to" << newName; qDebug() << "Renaming" << it.value().filename << "to" << newName;
if ( str.rename(newName) ) if ( str.rename(newName) )
qDebug() << "Success"; qDebug() << "Rename Success";
else else
qDebug() << "Failed"; qDebug() << "Rename Failed";
} }
delete it.value().edf; delete it.value().edf;
} }
@ -515,31 +545,6 @@ int ResmedLoader::Open(const QString & dirpath)
qDebug() << "Finished STRmap cleanup"; qDebug() << "Finished STRmap cleanup";
#endif #endif
///////////////////////////////////////////////////////////////////////////////////
// Create the backup folder for storing a copy of everything in..
// (Unless we are importing from this backup folder)
///////////////////////////////////////////////////////////////////////////////////
dir.setPath(datalogPath);
if (create_backups) {
if ( ! dir.exists(backup_path)) {
if ( ! dir.mkpath(backup_path + RMS9_STR_datalog)) {
qDebug() << "Could not create ResMed backup directory :-/";
}
}
if ( compress_backups )
compressFile(path + "STR.edf", backup_path + "STR.edf.gz");
else
QFile::copy(path + "STR.edf", backup_path + "STR.edf");
// Copy Identification files to backup folder
QFile::copy(path + RMS9_STR_idfile + STR_ext_TGT, backup_path + RMS9_STR_idfile + STR_ext_TGT);
QFile::copy(path + RMS9_STR_idfile + STR_ext_CRC, backup_path + RMS9_STR_idfile + STR_ext_CRC);
// Meh.. these can be calculated if ever needed for ResScan SDcard export
QFile::copy(path + "STR.crc", backup_path + "STR.crc");
}
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Scan DATALOG files, sort, and import any new sessions // Scan DATALOG files, sort, and import any new sessions
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -557,6 +562,7 @@ int ResmedLoader::Open(const QString & dirpath)
qDebug() << "Starting scan of DATALOG"; qDebug() << "Starting scan of DATALOG";
// sleep(1); // sleep(1);
dir.setPath(datalogPath);
ScanFiles(mach, datalogPath, firstImportDay); ScanFiles(mach, datalogPath, firstImportDay);
if (isAborted()) if (isAborted())
return 0; return 0;
@ -644,6 +650,28 @@ int ResmedLoader::Open(const QString & dirpath)
return num_new_sessions; return num_new_sessions;
} // end Open() } // end Open()
ResMedEDFInfo * fetchSTRandVerify( QString filename, QString serialNumber)
{
ResMedEDFInfo * stredf = new ResMedEDFInfo();
if ( ! stredf->Open(filename ) ) {
qDebug() << "Failed to open" << filename;
delete stredf;
return nullptr;
}
if ( ! stredf->Parse()) {
qDebug() << "Faulty STR file" << filename;
delete stredf;
return nullptr;
}
if (stredf->serialnumber != serialNumber) {
qDebug() << "Identification.tgt Serial number doesn't match" << filename;
delete stredf;
return nullptr;
}
return stredf;
}
void StoreSettings(Session * sess, STRRecord & R); // forward void StoreSettings(Session * sess, STRRecord & R); // forward
void ResmedLoader::checkSummaryDay( ResMedDay & resday, QDate date, Machine * mach ) void ResmedLoader::checkSummaryDay( ResMedDay & resday, QDate date, Machine * mach )
{ {
@ -953,7 +981,7 @@ bool ResmedLoader::ProcessSTRfiles(Machine *mach, QMap<QDate, STRFile> & STRmap,
int days = str.GetNumDataRecords(); int days = str.GetNumDataRecords();
totalRecs += days; totalRecs += days;
#ifdef STR_DEBUG #ifdef STR_DEBUG
qDebug() << "STR file is" << file.filename; qDebug() << "STR file is" << file.filename.section("/", -3, -1);
qDebug() << "First day" << QDateTime::fromMSecsSinceEpoch(str.startdate, EDFInfo::localNoDST).date().toString() << "for" << days << "days"; qDebug() << "First day" << QDateTime::fromMSecsSinceEpoch(str.startdate, EDFInfo::localNoDST).date().toString() << "for" << days << "days";
#endif #endif
} }
@ -974,12 +1002,12 @@ bool ResmedLoader::ProcessSTRfiles(Machine *mach, QMap<QDate, STRFile> & STRmap,
QDate lastDay = date.addDays(size-1); QDate lastDay = date.addDays(size-1);
#ifdef STR_DEBUG #ifdef STR_DEBUG
qDebug() << "Processing" << strfile << date.toString() << size << str.GetNumSignals(); qDebug() << "Processing" << strfile.section("/", -3, -1) << date.toString() << size << str.GetNumSignals();
qDebug() << "Last day is" << lastDay; qDebug() << "Last day is" << lastDay;
#endif #endif
if ( lastDay < firstImport ) { if ( lastDay < firstImport ) {
qDebug() << "LastDay before firstImport, skipping" << strfile; qDebug() << "LastDay before firstImport, skipping" << strfile.section("/", -3, -1);
continue; continue;
} }
@ -1477,21 +1505,25 @@ bool parseIdentTGT( QString path, MachineInfo * info, QHash<QString, QString> &
return true; return true;
} }
void BackupSTRfiles( const QString strpath, const QString path, const QString strBackupPath, void backupSTRfiles( const QString strpath, const QString importPath, const QString backupPath,
MachineInfo & info, QMap<QDate, STRFile> & STRmap ) MachineInfo & info, QMap<QDate, STRFile> & STRmap )
{ {
QStringList strfiles; Q_UNUSED(strpath);
// add primary STR.edf qDebug() << "Entering backupSTRfiles during new IMPORT";
strfiles.push_back(strpath);
// Just in case we are importing into a new folder, process OSCAR backup structures
QDir dir; QDir dir;
dir.setPath(path + "STR_Backup"); // Qstring strBackupPath(backupPath+"STR_Backup");
QStringList strfiles;
// add Backup/STR.edf - make sure it ends up in the STRmap
strfiles.push_back(backupPath+"STR.edf");
// Just in case we are importing from a Backup folder in a different Profile, process OSCAR backup structures
QString strBackupPath(importPath + "STR_Backup");
dir.setPath(strBackupPath);
dir.setFilter(QDir::Files | QDir::Hidden | QDir::Readable); dir.setFilter(QDir::Files | QDir::Hidden | QDir::Readable);
QFileInfoList flist = dir.entryInfoList(); QFileInfoList flist = dir.entryInfoList();
// Add any STR_Backup versions to the file list // Add any STR_Backup versions to the file list
for (auto & fi : flist) { for (auto & fi : flist) { // this is empty if imprting from an SD card
QString filename = fi.fileName(); QString filename = fi.fileName();
if ( ! filename.startsWith("STR", Qt::CaseInsensitive)) if ( ! filename.startsWith("STR", Qt::CaseInsensitive))
continue; continue;
@ -1503,38 +1535,32 @@ void BackupSTRfiles( const QString strpath, const QString path, const QString st
qDebug() << "STR file list size is" << strfiles.size(); qDebug() << "STR file list size is" << strfiles.size();
#endif #endif
// Now place any of these files in the Backup folder sorted by the file date // Now copy any of these files to the Backup folder adding the file date to the file name
// and put it into the STRmap structure
for (auto & filename : strfiles) { for (auto & filename : strfiles) {
ResMedEDFInfo * stredf = new ResMedEDFInfo(); QDate date;
if ( ! stredf->Open(filename) ) { long int days;
qDebug() << "Failed to open" << filename; ResMedEDFInfo * stredf = fetchSTRandVerify( filename, info.serial );
delete stredf; if ( stredf == nullptr )
continue; continue;
} date = stredf->edfHdr.startdate_orig.date();
if ( ! stredf->Parse()) { days = stredf->GetNumDataRecords();
qDebug() << "Faulty STR file" << filename;
delete stredf;
continue;
}
if (stredf->serialnumber != info.serial) {
qDebug() << "Identification.tgt Serial number doesn't match" << filename;
delete stredf;
continue;
}
QDate date = stredf->edfHdr.startdate_orig.date();
long int days = stredf->GetNumDataRecords();
// date = QDate(date.year(), date.month(), 1);
if (STRmap.contains(date)) { if (STRmap.contains(date)) {
qDebug() << "STRmap already contains" << date.toString("YYYY-MM-dd"); qDebug() << "STRmap already contains" << date.toString("yyyy-MM-dd") << "for" << STRmap[date].days << "ending" << date.addDays(STRmap[date].days-1);
qDebug() << filename.section("/",-2,-1) << "has" << days << "ending" << date.addDays(days-1);
if ( days <= STRmap[date].days ) { if ( days <= STRmap[date].days ) {
qDebug() << "Skipping" << filename; qDebug() << "Skipping" << filename.section("/",-2,-1) << "Keeping" << STRmap[date].filename.section("/",-2,-1);
delete stredf; delete stredf;
continue; continue;
} else {
qDebug() << "Dropping" << STRmap[date].filename.section("/", -2, -1) << "Keeping" << filename.section("/",-2,-1);
delete STRmap[date].edf;
STRmap.remove(date); // new one gets added after we know its new name
} }
} }
// now create the new backup name
QString newname = "STR-"+date.toString("yyyyMMdd")+"."+STR_ext_EDF; QString newname = "STR-"+date.toString("yyyyMMdd")+"."+STR_ext_EDF;
QString backupfile = backupPath+"/STR_Backup/"+newname;
QString backupfile = strBackupPath+"/"+newname;
QString gzfile = backupfile + STR_ext_gz; QString gzfile = backupfile + STR_ext_gz;
QString nongzfile = backupfile; QString nongzfile = backupfile;
@ -1542,35 +1568,39 @@ void BackupSTRfiles( const QString strpath, const QString path, const QString st
bool compress_backups = p_profile->session->compressBackupData(); bool compress_backups = p_profile->session->compressBackupData();
backupfile = compress_backups ? gzfile : nongzfile; backupfile = compress_backups ? gzfile : nongzfile;
if ( ! QFile::exists(backupfile)) { STRmap[date] = STRFile(backupfile, days, stredf);
#ifdef STR_DEBUG qDebug() << "Adding" << filename.section("/",-3,-1) << "with" << days << "days as" << backupfile.section("/", -3, -1) << "to STRmap";
qDebug() << "Copying" << filename << "to" << backupfile;
#endif if ( QFile::exists(backupfile)) {
if (filename.endsWith(STR_ext_gz,Qt::CaseInsensitive)) { // we have a compressed file QFile::remove(backupfile);
if (compress_backups) { // fine, copy it to backup folder }
QFile::copy(filename, backupfile); // #ifdef STR_DEBUG
} else { // oops, uncompress it to the backup folder qDebug() << "Copying" << filename.section("/",-3,1) << "to" << backupfile.section("/",-3,-1);
uncompressFile(filename, backupfile); // #endif
} if (filename.endsWith(STR_ext_gz,Qt::CaseInsensitive)) { // we have a compressed file
} else { // file is not compressed if (compress_backups) { // fine, copy it to backup folder
if (compress_backups) { // so compress it into the backup folder QFile::copy(filename, backupfile);
compressFile(filename, backupfile); } else { // oops, uncompress it to the backup folder
} else { // and that's OK, just copy it over uncompressFile(filename, backupfile);
QFile::copy(filename, backupfile); }
} } else { // file is not compressed
if (compress_backups) { // so compress it into the backup folder
compressFile(filename, backupfile);
} else { // and that's OK, just copy it over
QFile::copy(filename, backupfile);
} }
} }
// Remove any duplicate compressed/uncompressed backup file // Remove any duplicate compressed/uncompressed backup file
if (compress_backups) if (compress_backups)
QFile::exists(nongzfile) && QFile::remove(nongzfile); QFile::exists(nongzfile) && QFile::remove(nongzfile);
else else
QFile::exists(gzfile) && QFile::remove(gzfile); QFile::exists(gzfile) && QFile::remove(gzfile);
STRmap[date] = STRFile(backupfile, days, stredf);
} // end for walking the STR files list } // end for walking the STR files list
#ifdef STR_DEBUG #ifdef STR_DEBUG
qDebug() << "STRmap has" << STRmap.size() << "entries"; qDebug() << "STRmap has" << STRmap.size() << "entries";
#endif #endif
qDebug() << "Leaving backupSTRfiles during new IMPORT";
} }
QHash<QString, QString> parseIdentLine( const QString line, MachineInfo * info) QHash<QString, QString> parseIdentLine( const QString line, MachineInfo * info)
@ -2469,7 +2499,7 @@ bool ResmedLoader::LoadBRP(Session *sess, const QString & path)
QString filename = path.section(-2, -1); QString filename = path.section(-2, -1);
ResMedEDFInfo edf; ResMedEDFInfo edf;
if ( ! edf.Open(path) ) { if ( ! edf.Open(path) ) {
qDebug() << "LoadBRP failed to open" << filename; qDebug() << "LoadBRP failed to open" << filename.section("/", -2, -1);
return false; return false;
} }
#ifdef DEBUG_EFFICIENCY #ifdef DEBUG_EFFICIENCY
@ -2477,7 +2507,9 @@ bool ResmedLoader::LoadBRP(Session *sess, const QString & path)
time.start(); time.start();
#endif #endif
if (!edf.Parse()) { if (!edf.Parse()) {
qDebug() << "LoadBRP failed to parse" << filename; #ifdef EDF_DEBUG
qDebug() << "LoadBRP failed to parse" << filename.section("/", -2, -1);
#endif
return false; return false;
} }
#ifdef DEBUG_EFFICIENCY #ifdef DEBUG_EFFICIENCY
@ -2571,7 +2603,7 @@ bool ResmedLoader::LoadSAD(Session *sess, const QString & path)
QString filename = path.section(-2, -1); QString filename = path.section(-2, -1);
ResMedEDFInfo edf; ResMedEDFInfo edf;
if ( ! edf.Open(path) ) { if ( ! edf.Open(path) ) {
qDebug() << "LoadSAD failed to open" << filename; qDebug() << "LoadSAD failed to open" << filename.section("/", -2, -1);
return false; return false;
} }
@ -2581,7 +2613,9 @@ bool ResmedLoader::LoadSAD(Session *sess, const QString & path)
#endif #endif
if (!edf.Parse()) { if (!edf.Parse()) {
qDebug() << "LoadSAD failed to parse" << filename; #ifdef EDF_DEBUG
qDebug() << "LoadSAD failed to parse" << filename.section("/", -2, -1);
#endif
return false; return false;
} }
@ -2646,7 +2680,7 @@ bool ResmedLoader::LoadPLD(Session *sess, const QString & path)
QString filename = path.section(-2, -1); QString filename = path.section(-2, -1);
ResMedEDFInfo edf; ResMedEDFInfo edf;
if ( ! edf.Open(path) ) { if ( ! edf.Open(path) ) {
qDebug() << "LoadPLD failed to open" << filename; qDebug() << "LoadPLD failed to open" << filename.section("/", -2, -1);
return false; return false;
} }
#ifdef DEBUG_EFFICIENCY #ifdef DEBUG_EFFICIENCY
@ -2655,7 +2689,9 @@ bool ResmedLoader::LoadPLD(Session *sess, const QString & path)
#endif #endif
if (!edf.Parse()) { if (!edf.Parse()) {
qDebug() << "LoadPLD failed to parse" << filename; #ifdef EDF_DEBUG
qDebug() << "LoadPLD failed to parse" << filename.section("/", -2, -1);
#endif
return false; return false;
} }

View File

@ -109,7 +109,7 @@ enum PRTimeModes { //:short
struct MachineInfo { struct MachineInfo {
MachineInfo() { type = MT_UNKNOWN; version = 0; cap=0; } MachineInfo() { type = MT_UNKNOWN; version = 0; cap=0; }
MachineInfo(const MachineInfo & copy) = default; MachineInfo(const MachineInfo & /*copy*/) = default;
MachineInfo(MachineType type, quint32 cap, QString loadername, QString brand, QString model, QString modelnumber, QString serial, QString series, QDateTime lastimported, int version) : MachineInfo(MachineType type, quint32 cap, QString loadername, QString brand, QString model, QString modelnumber, QString serial, QString series, QDateTime lastimported, int version) :
type(type), cap(cap), loadername(loadername), brand(brand), model(model), modelnumber(modelnumber), serial(serial), series(series), lastimported(lastimported), version(version) {} type(type), cap(cap), loadername(loadername), brand(brand), model(model), modelnumber(modelnumber), serial(serial), series(series), lastimported(lastimported), version(version) {}

View File

@ -27,7 +27,7 @@ public:
color = Qt::black; color = Qt::black;
type = Calc_Zero; type = Calc_Zero;
} }
ChannelCalc(const ChannelCalc & copy) = default; ChannelCalc(const ChannelCalc & /*copy*/) = default;
ChannelCalc(ChannelID code, ChannelCalcType type, QColor color, bool enabled): ChannelCalc(ChannelID code, ChannelCalcType type, QColor color, bool enabled):
code(code), type(type), color(color), enabled(enabled) {} code(code), type(type), color(color), enabled(enabled) {}

View File

@ -1,5 +1,5 @@
// Update the string below to set OSCAR's version and release status. // Update the string below to set OSCAR's version and release status.
// See https://semver.org/spec/v2.0.0.html for details on format. // See https://semver.org/spec/v2.0.0.html for details on format.
#define VERSION "1.1.1-rc-1" #define VERSION "1.1.1-rc-3"

View File

@ -233,7 +233,7 @@ void ExportCSV::on_exportButton_clicked()
ui->progressBar->setValue(ui->progressBar->value() + 1); ui->progressBar->setValue(ui->progressBar->value() + 1);
QApplication::processEvents(); QApplication::processEvents();
Day *day = p_profile->GetDay(date, MT_CPAP); Day *day = p_profile->GetDay(date, MT_CPAP); // Only export days with CPAP data.
if (day) { if (day) {
QString data; QString data;
@ -280,6 +280,9 @@ void ExportCSV::on_exportButton_clicked()
} else if (ui->rb1_Sessions->isChecked()) { } else if (ui->rb1_Sessions->isChecked()) {
for (int i = 0; i < day->size(); i++) { for (int i = 0; i < day->size(); i++) {
Session *sess = (*day)[i]; Session *sess = (*day)[i];
if (sess->type() != MT_CPAP) {
continue; // Not every session in a day with CPAP data will be a CPAP session.
}
QDateTime start = QDateTime::fromTime_t(sess->first() / 1000L); QDateTime start = QDateTime::fromTime_t(sess->first() / 1000L);
QDateTime end = QDateTime::fromTime_t(sess->last() / 1000L); QDateTime end = QDateTime::fromTime_t(sess->last() / 1000L);

View File

@ -43,7 +43,7 @@ class Update
*/ */
struct Release { struct Release {
Release() {} Release() {}
Release(const Release &copy) = default; Release(const Release & /*copy*/) = default;
Release(QString ver, QString code, UpdateStatus stat) { version = ver; codename = code; status = stat; } Release(QString ver, QString code, UpdateStatus stat) { version = ver; codename = code; status = stat; }
QString version; QString version;
@ -87,7 +87,7 @@ class UpdateParser: public QXmlDefaultHandler
class PackageUpdate { class PackageUpdate {
public: public:
PackageUpdate() {} PackageUpdate() {}
PackageUpdate(const PackageUpdate & copy) = default; PackageUpdate(const PackageUpdate & /*copy*/) = default;
QString name; QString name;
QString displayName; QString displayName;