From 936a21cefd3038adc00b88e301179e92739066cd Mon Sep 17 00:00:00 2001 From: Mark Watkins Date: Sat, 26 Jul 2014 22:46:11 +1000 Subject: [PATCH] Renamed Purge menu to Rebuild, automatically reimport from backups if present, fixed vertical scroll bug --- sleepyhead/Graphs/gGraphView.cpp | 19 +++-- .../SleepLib/loader_plugins/resmed_loader.cpp | 11 ++- sleepyhead/SleepLib/machine.cpp | 4 + sleepyhead/SleepLib/profiles.cpp | 1 + sleepyhead/SleepLib/profiles.h | 4 + sleepyhead/SleepLib/session.cpp | 4 +- sleepyhead/mainwindow.cpp | 74 ++++++++++++------- sleepyhead/mainwindow.ui | 22 +++--- sleepyhead/welcome.cpp | 6 +- 9 files changed, 94 insertions(+), 51 deletions(-) diff --git a/sleepyhead/Graphs/gGraphView.cpp b/sleepyhead/Graphs/gGraphView.cpp index 3e5f199d..a4e80160 100644 --- a/sleepyhead/Graphs/gGraphView.cpp +++ b/sleepyhead/Graphs/gGraphView.cpp @@ -1405,7 +1405,7 @@ void gGraphView::mousePressEvent(QMouseEvent *event) m_sizer_point.setX(x); m_sizer_point.setY(py); // point at top of graph.. this->setCursor(Qt::ClosedHandCursor); - } + } else { if (m_metaselect) { @@ -1508,6 +1508,11 @@ void gGraphView::mouseReleaseEvent(QMouseEvent *event) float h, py = 0, pinned_height = 0; bool done = false; + + // Copy to a local variable to make sure this gets cleared + bool button_down = m_button_down; + m_button_down = false; + // Handle pinned graphs first for (int i = 0; i < m_graphs.size(); i++) { gGraph *g = m_graphs[i]; @@ -1599,8 +1604,8 @@ void gGraphView::mouseReleaseEvent(QMouseEvent *event) } // The graph that got the button press gets the release event - if (m_button_down) { - m_button_down = false; + if (button_down) { +// m_button_down = false; m_metaselect = event->modifiers() & Qt::AltModifier; saveHistory(); @@ -1739,7 +1744,9 @@ void gGraphView::wheelEvent(QWheelEvent *event) { // Hmm.. I could optionalize this to change mousewheel behaviour without affecting the scrollbar now.. - if (m_button_down) return; + if (m_button_down) + return; + if ((event->modifiers() & Qt::ControlModifier)) { int x = event->x(); int y = event->y(); @@ -1763,9 +1770,7 @@ void gGraphView::wheelEvent(QWheelEvent *event) // What to do when ctrl+wheel is used on the graph title ?? } else { // send event to graph.. - if (!m_button_down) { - g->wheelEvent(event); - } + g->wheelEvent(event); } } else if ((y >= py + h) && (y <= py + h + graphSpacer + 1)) { // What to do when the wheel is used on the resize handle? diff --git a/sleepyhead/SleepLib/loader_plugins/resmed_loader.cpp b/sleepyhead/SleepLib/loader_plugins/resmed_loader.cpp index 943e07f6..072cec92 100644 --- a/sleepyhead/SleepLib/loader_plugins/resmed_loader.cpp +++ b/sleepyhead/SleepLib/loader_plugins/resmed_loader.cpp @@ -503,7 +503,8 @@ bool EDFParser::Parse() long recs = sig.nr * num_data_records; if (num_data_records < 0) { - return false; + sig.data = nullptr; + continue; } sig.data = new qint16 [recs]; @@ -622,7 +623,6 @@ void ResmedImport::run() if (sess->summaryOnly()) { sess->Destroy(); - //mach->sessionlist.remove(sess->session()); delete sess; } } @@ -646,11 +646,14 @@ void ResmedImport::run() } if (sess->first() == 0) { + // loader->saveMutex.lock(); + //if (mach->sessionlist.contains(sess->session())) { - sess->Destroy(); + // sess->Destroy(); //mach->sessionlist.remove(sess->session()); //} delete sess; + //loader->saveMutex.unlock(); return; } @@ -1681,6 +1684,8 @@ bool ResmedLoader::LoadBRP(Session *sess, const QString & path) EDFSignal &es = edf.edfsignals[s]; long recs = es.nr * edf.GetNumDataRecords(); + if (recs < 0) + continue; ChannelID code; if (matchSignal(CPAP_FlowRate, es.label)) { diff --git a/sleepyhead/SleepLib/machine.cpp b/sleepyhead/SleepLib/machine.cpp index c0e04f21..9b6b9bd2 100644 --- a/sleepyhead/SleepLib/machine.cpp +++ b/sleepyhead/SleepLib/machine.cpp @@ -201,6 +201,10 @@ bool Machine::AddSession(Session *s) for (QList::iterator i = nextday.value()->begin(); i != nextday.value()->end(); i++) { // i may need to do something here unlinkSession(*i); + // Add it back + + sessionlist[(*i)->session()] = *i; + dd->AddSession(*i); } diff --git a/sleepyhead/SleepLib/profiles.cpp b/sleepyhead/SleepLib/profiles.cpp index aef3c14e..7c87e36c 100644 --- a/sleepyhead/SleepLib/profiles.cpp +++ b/sleepyhead/SleepLib/profiles.cpp @@ -79,6 +79,7 @@ Profile::~Profile() delete session; delete general; + for (QHash::iterator it = machlist.begin(); it != machlist.end(); it++) { delete it.value(); } diff --git a/sleepyhead/SleepLib/profiles.h b/sleepyhead/SleepLib/profiles.h index 3091b8f0..f36fe825 100644 --- a/sleepyhead/SleepLib/profiles.h +++ b/sleepyhead/SleepLib/profiles.h @@ -785,6 +785,10 @@ class UserSettings : public ProfileSettings void setStatReportMode(int i) { setPref(STR_US_StatReportMode, i); } }; +//! \brief Returns a count of all files & directories in a supplied folder +int dirCount(QString path); + + namespace Profiles { extern QMap profiles; diff --git a/sleepyhead/SleepLib/session.cpp b/sleepyhead/SleepLib/session.cpp index 51364e2e..1080e560 100644 --- a/sleepyhead/SleepLib/session.cpp +++ b/sleepyhead/SleepLib/session.cpp @@ -117,8 +117,6 @@ bool Session::Destroy() { QString path = p_profile->Get(s_machine->properties[STR_PROP_Path]); - s_machine->unlinkSession(this); - QDir dir(path); QString base; base.sprintf("%08lx", s_session); @@ -127,7 +125,7 @@ bool Session::Destroy() dir.remove(base + ".000"); dir.remove(base + ".001"); - return !dir.exists(base + ".000") && !dir.exists(base + ".001"); + return s_machine->unlinkSession(this); //!dir.exists(base + ".000") && !dir.exists(base + ".001"); } bool Session::Store(QString path) diff --git a/sleepyhead/mainwindow.cpp b/sleepyhead/mainwindow.cpp index 6fd448d5..aeefc0bf 100644 --- a/sleepyhead/mainwindow.cpp +++ b/sleepyhead/mainwindow.cpp @@ -430,11 +430,11 @@ void MyStatsPage::javaScriptAlert(QWebFrame *frame, const QString &msg) void MainWindow::PopulatePurgeMenu() { - QList actions = ui->menu_Purge_CPAP_Data->actions(); + QList actions = ui->menu_Rebuild_CPAP_Data->actions(); - ui->menu_Purge_CPAP_Data->disconnect(ui->menu_Purge_CPAP_Data, SIGNAL(triggered(QAction*)), this, SLOT(on_actionPurgeMachine(QAction *))); + ui->menu_Rebuild_CPAP_Data->disconnect(ui->menu_Rebuild_CPAP_Data, SIGNAL(triggered(QAction*)), this, SLOT(on_actionPurgeMachine(QAction *))); - ui->menu_Purge_CPAP_Data->clear(); + ui->menu_Rebuild_CPAP_Data->clear(); QList machines = p_profile->GetMachines(MT_CPAP); for (int i=0; i < machines.size(); ++i) { @@ -443,12 +443,13 @@ void MainWindow::PopulatePurgeMenu() mach->properties[STR_PROP_Model]+" "+ mach->properties[STR_PROP_Serial]; - QAction * action = new QAction(name.replace("&","&&"), ui->menu_Purge_CPAP_Data); + QAction * action = new QAction(name.replace("&","&&"), ui->menu_Rebuild_CPAP_Data); action->setData(mach->GetClass()+":"+mach->properties[STR_PROP_Serial]); - ui->menu_Purge_CPAP_Data->addAction(action); + ui->menu_Rebuild_CPAP_Data->addAction(action); } - ui->menu_Purge_CPAP_Data->connect(ui->menu_Purge_CPAP_Data, SIGNAL(triggered(QAction*)), this, SLOT(on_actionPurgeMachine(QAction*))); + ui->menu_Rebuild_CPAP_Data->connect(ui->menu_Rebuild_CPAP_Data, SIGNAL(triggered(QAction*)), this, SLOT(on_actionPurgeMachine(QAction*))); } + QString GenerateWelcomeHTML(); void MainWindow::Startup() @@ -525,7 +526,6 @@ void MainWindow::finishCPAPImport() void MainWindow::importCPAPBackups() { - // Get BackupPaths for all CPAP machines QList machlist = p_profile->GetMachines(MT_CPAP); QStringList paths; @@ -1822,15 +1822,37 @@ void MainWindow::on_actionPurgeMachine(QAction *action) void MainWindow::purgeMachine(Machine * mach) { + // detect backups + bool backups = false; + if (mach->properties.contains(STR_PROP_BackupPath)) { + QString bpath = p_profile->Get(mach->properties[STR_PROP_BackupPath]); + int cnt = dirCount(bpath); + if (cnt > 0) backups = true; + } - if (QMessageBox::question(this, + if (backups) { + if (QMessageBox::question(this, STR_MessageBox_Question, - tr("Are you sure you want to purge all CPAP data for the following machine:")+ "\n\n" + + tr("Are you sure you want to rebuild all CPAP data for the following machine:")+ "\n\n" + mach->properties[STR_PROP_Brand] + " " + mach->properties[STR_PROP_Model] + " " + - mach->properties[STR_PROP_ModelNumber] + " (" + mach->properties[STR_PROP_Serial] + ")", + mach->properties[STR_PROP_ModelNumber] + " (" + mach->properties[STR_PROP_Serial] + ")" + "\n\n"+ + tr("Please note, that this could result in loss of graph data if SleepyHead's internal backups have been disabled or interfered with in any way."), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) { - return; + return; + } + } else { + if (QMessageBox::question(this, + STR_MessageBox_Warning, + "

"+STR_MessageBox_Warning+": "+tr("For some reason, SleepyHead does not have internal backups for the following machine:")+ "

" + + "

"+mach->properties[STR_PROP_Brand] + " " + mach->properties[STR_PROP_Model] + " " + + mach->properties[STR_PROP_ModelNumber] + " (" + mach->properties[STR_PROP_Serial] + ")" + "

"+ + "

"+tr("Provided you have made your own backups for ALL of your CPAP data, you can still complete this operation, but you will have to restore from your backups manually.")+"

" + "

"+tr("Are you really sure you want to do this?")+"

", + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::No) { + return; + } } daily->Unload(daily->getDate()); @@ -1840,7 +1862,7 @@ void MainWindow::purgeMachine(Machine * mach) mach->day.clear(); } else { QMessageBox::warning(this, STR_MessageBox_Error, - tr("Not all session data could be removed, you have to delete the following folder manually.") + tr("A file permission error or simillar screwed up the purge process, you will have to delete the following folder manually:") +"\n\n"+ QDir::toNativeSeparators(p_profile->Get(mach->properties[STR_PROP_Path])), QMessageBox::Ok, QMessageBox::Ok); if (overview) overview->ReloadGraphs(); @@ -1862,23 +1884,23 @@ void MainWindow::purgeMachine(Machine * mach) GenerateStatistics(); QApplication::processEvents(); - if (QMessageBox::question(this, - STR_MessageBox_Question, - tr("Machine data has been successfully purged.") + "\n\n" + - tr("Would you like to reimport from the backup folder?") + "\n\n" + - QDir::toNativeSeparators(p_profile->Get(mach->properties[STR_PROP_BackupPath])), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::Yes) == QMessageBox::No) { - p_profile->machlist.erase(p_profile->machlist.find(mach->id())); - delete mach; - } else { + + if (backups) { importCPAP(p_profile->Get(mach->properties[STR_PROP_BackupPath]),tr("Please wait, importing...")); - if (overview) overview->ReloadGraphs(); - if (daily) { - daily->clearLastDay(); // otherwise Daily will crash - daily->ReloadGraphs(); + } else { + if (QMessageBox::information(this, STR_MessageBox_Warning, + tr("Because there are no internal backups to rebuild from, you will have to restore from your own.")+"\n\n"+ + tr("Would you like to import from your own backups now? (you will have no data visible for this machine until you do)"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) { + } else { + on_action_Import_Data_triggered(); } } + if (overview) overview->ReloadGraphs(); + if (daily) { + daily->clearLastDay(); // otherwise Daily will crash + daily->ReloadGraphs(); + } GenerateStatistics(); p_profile->Save(); } diff --git a/sleepyhead/mainwindow.ui b/sleepyhead/mainwindow.ui index 5c9a1ae3..57bc7f5c 100644 --- a/sleepyhead/mainwindow.ui +++ b/sleepyhead/mainwindow.ui @@ -3185,23 +3185,21 @@ border-radius: 10px; &Advanced - - - &Purge CPAP Data - - - Purge Oximetery Data - + + + Rebuild CPAP Data + + @@ -3209,8 +3207,9 @@ border-radius: 10px; - + + @@ -3366,7 +3365,7 @@ border-radius: 10px; - &Rebuild Oximetry Indices + &Automatic Oximetry Cleanup @@ -3463,6 +3462,11 @@ border-radius: 10px; Ctrl+S + + + Foo + + diff --git a/sleepyhead/welcome.cpp b/sleepyhead/welcome.cpp index 12f222a4..1f71fd6b 100644 --- a/sleepyhead/welcome.cpp +++ b/sleepyhead/welcome.cpp @@ -99,7 +99,7 @@ QString GenerateWelcomeHTML() html+=QString("").arg(cols)+ - ""+((havecpapdata || haveoximeterdata) ? QObject::tr("Would you like to import more data?") : QObject::tr("Please Import Some Data")) +"" + ""+((havecpapdata || haveoximeterdata) ? QObject::tr("What would you like to do?") : QObject::tr("Please Import Some Data")) +"" "" "" "" @@ -134,9 +134,9 @@ QString GenerateWelcomeHTML() else if (day->machine->GetClass() == STR_MACH_PRS1) cpapimage = "qrc:/icons/prs1.png"; else if (day->machine->GetClass() == STR_MACH_Intellipap) cpapimage = "qrc:/icons/intellipap.png"; } - html += "

"; + html += "

"; - html+="
"+ + html+="
"+ QString("
").arg(date.toString(Qt::ISODate))+""+ QObject::tr("The last time you used your %1...").arg(day->machine->properties[STR_PROP_Brand]+" "+day->machine->properties[STR_PROP_Model])+"
";