Merge Summary Files

This commit is contained in:
Mark Watkins 2014-09-05 00:59:54 +10:00
parent faba312edb
commit ea96303cc1
13 changed files with 480 additions and 136 deletions

View File

@ -19,6 +19,10 @@
#endif #endif
const quint16 filetype_summary = 0;
const quint16 filetype_data = 1;
const quint16 filetype_sessenabled = 5;
enum UnitSystem { US_Undefined, US_Metric, US_Archiac }; enum UnitSystem { US_Undefined, US_Metric, US_Archiac };
typedef float EventDataType; typedef float EventDataType;

View File

@ -182,7 +182,7 @@ EventDataType Day::timeAboveThreshold(ChannelID code, EventDataType threshold)
for (QList<Session *>::iterator it = sessions.begin(); it != end; ++it) { for (QList<Session *>::iterator it = sessions.begin(); it != end; ++it) {
Session &sess = *(*it); Session &sess = *(*it);
if (sess.enabled()) { if (sess.enabled() && sess.m_availableChannels.contains(code)) {
val += sess.timeAboveThreshold(code,threshold); val += sess.timeAboveThreshold(code,threshold);
} }
} }
@ -1212,7 +1212,8 @@ bool Day::channelHasData(ChannelID id)
void Day::OpenEvents() void Day::OpenEvents()
{ {
Q_FOREACH(Session * session, sessions) { Q_FOREACH(Session * session, sessions) {
session->OpenEvents(); if (session->machine()->type() != MT_JOURNAL)
session->OpenEvents();
} }
} }

View File

@ -108,12 +108,9 @@ bool JournalEntry::Save()
session->settings[Bookmark_End] = end; session->settings[Bookmark_End] = end;
session->settings[Bookmark_Notes] = notes; session->settings[Bookmark_Notes] = notes;
QString path = session->machine()->getDataPath();
QString filename = path + "/" + QString().sprintf("%08lx", session->session()) + ".000";
session->settings[LastUpdated] = QDateTime::currentDateTime().toTime_t(); session->settings[LastUpdated] = QDateTime::currentDateTime().toTime_t();
session->StoreSummary(filename); session->StoreSummary();
return true; return true;
} }
return false; return false;

View File

@ -13,7 +13,6 @@
// that change loader behaviour or modify channels. // that change loader behaviour or modify channels.
//******************************************************************************************** //********************************************************************************************
#include <QProgressBar>
#include <QApplication> #include <QApplication>
#include <QDir> #include <QDir>
#include <QString> #include <QString>
@ -33,8 +32,6 @@ using namespace std;
#include "SleepLib/machine.h" #include "SleepLib/machine.h"
#include "SleepLib/session.h" #include "SleepLib/session.h"
extern QProgressBar *qprogress;
CMS50Loader::CMS50Loader() CMS50Loader::CMS50Loader()
{ {
m_type = MT_OXIMETER; m_type = MT_OXIMETER;
@ -338,9 +335,7 @@ int CMS50Loader::doImportMode()
// TODO: Store the data to the session // TODO: Store the data to the session
m_itemCnt++; emit updateProgress(0, 0);
m_itemCnt = m_itemCnt % m_itemTotal;
emit updateProgress(m_itemCnt, m_itemTotal);
idx += 3; idx += 3;
} else if (!started_reading) { // have not got a valid trio yet, skip... } else if (!started_reading) { // have not got a valid trio yet, skip...

View File

@ -12,6 +12,8 @@
#include <QString> #include <QString>
#include <QObject> #include <QObject>
#include <QThreadPool> #include <QThreadPool>
#include <QFile>
#include <QDataStream>
#include <QDialog> #include <QDialog>
#include <QHBoxLayout> #include <QHBoxLayout>
@ -58,6 +60,7 @@ Machine::Machine(MachineID id)
} }
Machine::~Machine() Machine::~Machine()
{ {
saveSessionInfo();
qDebug() << "Destroy Machine" << info.loadername << hex << m_id; qDebug() << "Destroy Machine" << info.loadername << hex << m_id;
} }
Session *Machine::SessionExists(SessionID session) Session *Machine::SessionExists(SessionID session)
@ -69,6 +72,82 @@ Session *Machine::SessionExists(SessionID session)
} }
} }
const quint16 sessinfo_version = 0;
bool Machine::saveSessionInfo()
{
QFile file(getDataPath() + "Sessions.info");
file.open(QFile::WriteOnly);
QDataStream out(&file);
out.setByteOrder(QDataStream::LittleEndian);
out.setVersion(QDataStream::Qt_5_0);
out << magic;
out << filetype_sessenabled;
out << sessinfo_version;
QHash<SessionID, Session *>::iterator s;
out << (int)sessionlist.size();
for (s = sessionlist.begin(); s != sessionlist.end(); ++s) {
Session * sess = s.value();
out << (quint32) sess->session();
out << (bool)(sess->enabled());
}
return true;
}
bool Machine::loadSessionInfo()
{
QHash<SessionID, Session *>::iterator s;
QFile file(getDataPath() + "Sessions.info");
if (!file.open(QFile::ReadOnly)) {
for (s = sessionlist.begin(); s!= sessionlist.end(); ++s) {
Session * sess = s.value();
QHash<ChannelID, QVariant>::iterator it = sess->settings.find(SESSION_ENABLED);
bool b = true;
if (it != sess->settings.end()) {
b = it.value().toBool();
}
sess->setEnabled(b); // Extract from session settings and save..
}
saveSessionInfo();
return true;
}
QDataStream in(&file);
in.setByteOrder(QDataStream::LittleEndian);
in.setVersion(QDataStream::Qt_5_0);
quint32 mag32;
in >> mag32;
quint16 ft16, version;
in >> ft16;
in >> version;
int size;
in >> size;
quint32 sid;
bool b;
for (int i=0; i< size; ++i) {
in >> sid;
in >> b;
s = sessionlist.find(sid);
if (s != sessionlist.end()) {
Session * sess = s.value();
sess->setEnabled(b);
}
}
return true;
}
// Find date this session belongs in // Find date this session belongs in
QDate Machine::pickDate(qint64 first) QDate Machine::pickDate(qint64 first)
{ {
@ -102,6 +181,8 @@ QDate Machine::pickDate(qint64 first)
bool Machine::AddSession(Session *s) bool Machine::AddSession(Session *s)
{ {
invalidateCache();
Q_ASSERT(s != nullptr); Q_ASSERT(s != nullptr);
Q_ASSERT(p_profile); Q_ASSERT(p_profile);
Q_ASSERT(p_profile->isOpen()); Q_ASSERT(p_profile->isOpen());
@ -304,6 +385,9 @@ bool Machine::Purge(int secret)
QFile impfile(getDataPath()+"/imported_files.csv"); QFile impfile(getDataPath()+"/imported_files.csv");
impfile.remove(); impfile.remove();
QFile sumfile(getDataPath()+"Summaries.dat");
sumfile.remove();
// Create a copy of the list so the hash can be manipulated // Create a copy of the list so the hash can be manipulated
QList<Session *> sessions = sessionlist.values(); QList<Session *> sessions = sessionlist.values();
@ -321,6 +405,12 @@ bool Machine::Purge(int secret)
delete sess; delete sess;
} }
// Remove EVERYTHING under Events folder..
QString eventspath = getEventsPath();
QDir evdir(eventspath);
evdir.removeRecursively();
// Clean up any straggling files (like from short sessions not being loaded...) // Clean up any straggling files (like from short sessions not being loaded...)
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Name); dir.setSorting(QDir::Name);
@ -348,9 +438,9 @@ bool Machine::Purge(int secret)
qDebug() << "Didn't bother deleting cruft file" << fullpath; qDebug() << "Didn't bother deleting cruft file" << fullpath;
// cruft file.. // cruft file..
} }
} }
if (could_not_kill > 0) { if (could_not_kill > 0) {
qWarning() << "Could not purge path" << could_not_kill << "files in " << path; qWarning() << "Could not purge path" << could_not_kill << "files in " << path;
return false; return false;
@ -378,6 +468,10 @@ const QString Machine::getDataPath()
{ {
return p_profile->Get("{" + STR_GEN_DataFolder + "}/" + info.loadername + "_" + (info.serial.isEmpty() ? hexid() : info.serial)) + "/"; return p_profile->Get("{" + STR_GEN_DataFolder + "}/" + info.loadername + "_" + (info.serial.isEmpty() ? hexid() : info.serial)) + "/";
} }
const QString Machine::getEventsPath()
{
return getDataPath() + "Events/";
}
const QString Machine::getBackupPath() const QString Machine::getBackupPath()
{ {
@ -406,60 +500,94 @@ bool Machine::Load()
QProgressBar * progress = popup->progress; QProgressBar * progress = popup->progress;
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); if (!LoadSummary()) {
dir.setSorting(QDir::Name); QTime time;
time.start();
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Name);
QFileInfoList list = dir.entryInfoList(); QFileInfoList list = dir.entryInfoList();
typedef QVector<QString> StringList; typedef QVector<QString> StringList;
QMap<SessionID, StringList> sessfiles; QMap<SessionID, StringList> sessfiles;
QMap<SessionID, StringList>::iterator s; QMap<SessionID, StringList>::iterator s;
QString fullpath, ext_s, sesstr; QString fullpath, ext_s, sesstr;
int ext; int ext;
SessionID sessid; SessionID sessid;
bool ok; bool ok;
for (int i = 0; i < list.size(); i++) {
QFileInfo fi = list.at(i);
fullpath = fi.canonicalFilePath();
ext_s = fi.fileName().section(".", -1);
ext = ext_s.toInt(&ok, 10);
if (!ok) { continue; }
sesstr = fi.fileName().section(".", 0, -2); for (int i = 0; i < list.size(); i++) {
sessid = sesstr.toLong(&ok, 16); QFileInfo fi = list.at(i);
fullpath = fi.canonicalFilePath();
ext_s = fi.fileName().section(".", -1);
ext = ext_s.toInt(&ok, 10);
if (!ok) { continue; } if (!ok) { continue; }
if (sessfiles[sessid].capacity() == 0) { sessfiles[sessid].resize(3); } sesstr = fi.fileName().section(".", 0, -2);
sessid = sesstr.toLong(&ok, 16);
sessfiles[sessid][ext] = fi.canonicalFilePath(); if (!ok) { continue; }
}
int size = sessfiles.size(); if (sessfiles[sessid].capacity() == 0) { sessfiles[sessid].resize(3); }
int cnt = 0;
for (s = sessfiles.begin(); s != sessfiles.end(); s++) { sessfiles[sessid][ext] = fi.canonicalFilePath();
if ((++cnt % 50) == 0) { // This is slow.. :-/
if (progress) { progress->setValue((float(cnt) / float(size) * 100.0)); }
QApplication::processEvents();
} }
Session *sess = new Session(this, s.key()); int size = sessfiles.size();
int cnt = 0;
if (sess->LoadSummary(s.value()[0])) { bool haveevents = false;
sess->SetEventFile(s.value()[1]); for (s = sessfiles.begin(); s != sessfiles.end(); s++) {
if (!s.value()[1].isEmpty()) {
AddSession(sess); haveevents = true;
} else { break;
qWarning() << "Error unpacking summary data"; }
delete sess;
} }
}
QString eventpath = getEventsPath();
if (haveevents) {
QDir dir;
dir.mkpath(eventpath);
}
for (s = sessfiles.begin(); s != sessfiles.end(); s++) {
if ((++cnt % 50) == 0) { // This is slow.. :-/
if (progress) { progress->setValue((float(cnt) / float(size) * 100.0)); }
QApplication::processEvents();
}
Session *sess = new Session(this, s.key());
if (haveevents && !s.value()[1].isEmpty()) {
QFile::copy(s.value()[1], eventpath+s.value()[1].section("/",-1));
QFile::remove(s.value()[1]);
}
if (sess->LoadSummary(s.value()[0])) {
AddSession(sess);
} else {
qWarning() << "Error unpacking summary data";
delete sess;
}
}
if (hasModifiedSessions()) {
SaveSummary();
for (s = sessfiles.begin(); s != sessfiles.end(); s++) {
QString summary = s.value()[0];
QFile file(summary);
file.remove();
}
}
qDebug() << "Loaded" << info.model << "data in" << time.elapsed() << "ms";
}
loadSessionInfo();
if (progress) { progress->setValue(100); } if (progress) { progress->setValue(100); }
QApplication::processEvents(); QApplication::processEvents();
popup->hide(); popup->hide();
@ -650,6 +778,96 @@ void Machine::runTasks()
QThreadPool::globalInstance()->waitForDone(-1); QThreadPool::globalInstance()->waitForDone(-1);
} }
bool Machine::hasModifiedSessions()
{
QHash<SessionID, Session *>::iterator s;
for (s = sessionlist.begin(); s != sessionlist.end(); s++) {
if (s.value()->IsChanged()) {
return true;
}
}
return false;
}
const QString summaryFileName = "Summaries.dat";
bool Machine::LoadSummary()
{
QTime time;
time.start();
qDebug() << "Loading Summaries";
QString filename = getDataPath() + summaryFileName;
QFile file(filename);
if (!file.exists() || !file.open(QFile::ReadOnly)) {
qDebug() << "Couldn't open" << filename;
return false;
}
QByteArray compressed = file.readAll();
file.close();
QTime time2;
time2.start();
QByteArray data = qUncompress(compressed);
qDebug() << "Uncompressed Summary Length" << data.size() << "in" << time2.elapsed() << "ms";
QDataStream in(&data, QIODevice::ReadOnly);
in.setVersion(QDataStream::Qt_5_0);
in.setByteOrder(QDataStream::LittleEndian);
quint32 mag32;
quint16 ftype;
in >> mag32;
in >> ftype;
int session_count;
in >> session_count;
for (int i=0; i< session_count; ++i) {
Session * sess = new Session(this,0);
in >> *sess;
AddSession(sess);
}
qDebug() << "Loaded" << info.model << "data in" << time.elapsed() << "ms";
return true;
}
bool Machine::SaveSummary()
{
qDebug() << "Saving Summaries";
QString filename = getDataPath() + summaryFileName;
QByteArray data;
QDataStream out(&data, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_0);
out.setByteOrder(QDataStream::LittleEndian);
out << (quint32)magic;
out << (quint16)filetype_summary;
out << (int)sessionlist.size();
QHash<SessionID, Session *>::iterator s;
for (s = sessionlist.begin(); s != sessionlist.end(); s++) {
Session * sess = s.value();
out << *sess;
}
QFile file(filename);
file.open(QIODevice::WriteOnly);
qDebug() << "Uncompressed Summary Length" << data.size();
QByteArray compressed = qCompress(data);
file.write(compressed);
file.close();
return true;
}
bool Machine::Save() bool Machine::Save()
{ {
//int size; //int size;
@ -666,6 +884,7 @@ bool Machine::Save()
m_savelist.clear(); m_savelist.clear();
// store any event summaries..
for (s = sessionlist.begin(); s != sessionlist.end(); s++) { for (s = sessionlist.begin(); s != sessionlist.end(); s++) {
cnt++; cnt++;
@ -675,11 +894,23 @@ bool Machine::Save()
} }
runTasks(); runTasks();
return true; return true;
} }
QList<ChannelID> Machine::availableChannels(quint32 chantype) void Machine::invalidateCache()
{ {
availableCache.clear();
}
QList<ChannelID> & Machine::availableChannels(quint32 chantype)
{
QHash<quint32, QList<ChannelID> >::iterator ac = availableCache.find(chantype);
if (ac != availableCache.end()) {
return ac.value();
}
QHash<ChannelID, int> chanhash; QHash<ChannelID, int> chanhash;
// look through the daylist and return a list of available channels for this machine // look through the daylist and return a list of available channels for this machine
@ -692,17 +923,18 @@ QList<ChannelID> Machine::availableChannels(quint32 chantype)
Session * sess = (*sit); Session * sess = (*sit);
if (sess->machine() != this) continue; if (sess->machine() != this) continue;
int size = sess->availableChannels().size(); int size = sess->m_availableChannels.size();
for (int i=0; i < size; ++i) { for (int i=0; i < size; ++i) {
ChannelID code = sess->availableChannels().at(i); ChannelID code = sess->m_availableChannels.at(i);
const schema::Channel & chan = schema::channel[code]; QHash<ChannelID, schema::Channel *>::iterator ch = schema::channel.channels.find(code);
if (chan.type() & chantype) { schema::Channel * chan = ch.value();
if (chan->type() & chantype) {
chanhash[code]++; chanhash[code]++;
} }
} }
} }
} }
return chanhash.keys(); return availableCache[chantype] = chanhash.keys();
} }

View File

@ -86,8 +86,11 @@ class Machine
//! \brief Load all Machine summary data //! \brief Load all Machine summary data
bool Load(); bool Load();
bool LoadSummary();
//! \brief Save all Sessions where changed bit is set. //! \brief Save all Sessions where changed bit is set.
bool Save(); bool Save();
bool SaveSummary();
//! \brief Save individual session //! \brief Save individual session
bool SaveSession(Session *sess); bool SaveSession(Session *sess);
@ -119,6 +122,7 @@ class Machine
QDate pickDate(qint64 start); QDate pickDate(qint64 start);
const QString getDataPath(); const QString getDataPath();
const QString getEventsPath();
const QString getBackupPath(); const QString getBackupPath();
//! \brief Returns the machineID as a lower case hexadecimal string //! \brief Returns the machineID as a lower case hexadecimal string
@ -141,6 +145,8 @@ class Machine
//! \brief Add a new task to the multithreaded save code //! \brief Add a new task to the multithreaded save code
void queSaveList(Session * sess); void queSaveList(Session * sess);
bool hasModifiedSessions();
//! \brief Grab the next task in the multithreaded save code //! \brief Grab the next task in the multithreaded save code
Session *popSaveList(); Session *popSaveList();
@ -190,9 +196,13 @@ class Machine
inline void setType(MachineType type) { info.type = type; } inline void setType(MachineType type) { info.type = type; }
inline void setCap(quint32 value) { info.cap = value; } inline void setCap(quint32 value) { info.cap = value; }
bool saveSessionInfo();
bool loadSessionInfo();
void setLoaderName(QString value); void setLoaderName(QString value);
QList<ChannelID> availableChannels(quint32 chantype); QHash<quint32, QList<ChannelID> > availableCache;
QList<ChannelID> & availableChannels(quint32 chantype);
MachineLoader * loader() { return m_loader; } MachineLoader * loader() { return m_loader; }
@ -223,6 +233,8 @@ class Machine
volatile bool m_save_threads_running; volatile bool m_save_threads_running;
QList<ImportTask *> m_tasklist; QList<ImportTask *> m_tasklist;
void invalidateCache();
}; };

View File

@ -161,7 +161,17 @@ void MachineLoader::finishAddingSessions()
Machine * mach = sess->machine(); Machine * mach = sess->machine();
mach->AddSession(sess); mach->AddSession(sess);
} }
new_sessions.clear(); new_sessions.clear();
QHash<QString, QHash<QString, Machine *> >::iterator mlit = MachineList.find(loaderName());
if (mlit != MachineList.end()) {
for(QHash<QString, Machine *>::iterator mit = mlit.value().begin(); mit!=mlit.value().end(); ++mit) {
mit.value()->SaveSummary();
}
}
} }
bool compressFile(QString inpath, QString outpath) bool compressFile(QString inpath, QString outpath)

View File

@ -21,9 +21,6 @@
using namespace std; using namespace std;
const quint16 filetype_summary = 0;
const quint16 filetype_data = 1;
// This is the uber important database version for SleepyHeads internal storage // This is the uber important database version for SleepyHeads internal storage
// Increment this after stuffing with Session's save & load code. // Increment this after stuffing with Session's save & load code.
const quint16 summary_version = 15; const quint16 summary_version = 15;
@ -45,7 +42,6 @@ Session::Session(Machine *m, SessionID session)
s_enabled = -1; s_enabled = -1;
s_first = s_last = 0; s_first = s_last = 0;
s_eventfile = "";
s_evchecksum_checked = false; s_evchecksum_checked = false;
s_summaryOnly = false; s_summaryOnly = false;
@ -88,6 +84,11 @@ void Session::TrashEvents()
eventlist.squeeze(); eventlist.squeeze();
} }
QString Session::eventFile() const
{
return s_machine->getEventsPath()+QString().sprintf("%08lx.001", s_session);
}
//const int max_pack_size=128; //const int max_pack_size=128;
bool Session::OpenEvents() bool Session::OpenEvents()
{ {
@ -101,15 +102,15 @@ bool Session::OpenEvents()
return true; return true;
} }
if (!s_eventfile.isEmpty()) {
bool b = LoadEvents(s_eventfile);
if (!b) { QString filename = eventFile();
qWarning() << "Error Unpacking Events" << s_eventfile; bool b = LoadEvents(filename);
return false;
} if (!b) {
// qWarning() << "Error Loading Events" << filename;
return false;
} }
qDebug() << "opening" << filename;
return s_events_loaded = true; return s_events_loaded = true;
} }
@ -139,18 +140,14 @@ bool Session::Store(QString path)
dir.mkpath(path); dir.mkpath(path);
} }
QString base;
base.sprintf("%08lx", s_session);
base = path + "/" + base;
//qDebug() << "Storing Session: " << base; //qDebug() << "Storing Session: " << base;
bool a; bool a;
a = StoreSummary(base + ".000"); // if actually has events a = StoreSummary(); // if actually has events
//qDebug() << " Summary done"; //qDebug() << " Summary done";
if (eventlist.size() > 0) { if (eventlist.size() > 0) {
s_eventfile = base + ".001"; StoreEvents();
StoreEvents(s_eventfile);
} else { // who cares.. } else { // who cares..
//qDebug() << "Trying to save empty events file"; //qDebug() << "Trying to save empty events file";
} }
@ -165,12 +162,109 @@ bool Session::Store(QString path)
return a; return a;
} }
QDataStream & operator<<(QDataStream & out, const Session & session)
bool Session::StoreSummary(QString filename)
{ {
if (filename.isEmpty()) { session.StoreSummaryData(out);
filename = machine()->getDataPath() + QString().sprintf("%08lx.000", s_session); return out;
} }
void Session::StoreSummaryData(QDataStream & out) const
{
out << summary_version;
out << (quint32)s_session;
out << s_first; // Session Start Time
out << s_last; // Duration of sesion in seconds.
out << settings;
out << m_cnt;
out << m_sum;
out << m_avg;
out << m_wavg;
out << m_min;
out << m_max;
out << m_physmin;
out << m_physmax;
out << m_cph;
out << m_sph;
out << m_firstchan;
out << m_lastchan;
out << m_valuesummary;
out << m_timesummary;
out << m_gain;
out << m_availableChannels;
out << m_timeAboveTheshold;
out << m_upperThreshold;
out << m_timeBelowTheshold;
out << m_lowerThreshold;
out << s_summaryOnly;
}
QDataStream & operator>>(QDataStream & in, Session & session)
{
session.LoadSummaryData(in);
return in;
}
void Session::LoadSummaryData(QDataStream & in)
{
quint16 version;
in >> version;
quint32 t32;
in >> t32; // Sessionid;
s_session = t32;
in >> s_first; // Start time
in >> s_last; // Duration
in >> settings;
in >> m_cnt;
in >> m_sum;
in >> m_avg;
in >> m_wavg;
in >> m_min;
in >> m_max;
in >> m_physmin;
in >> m_physmax;
in >> m_cph;
in >> m_sph;
in >> m_firstchan;
in >> m_lastchan;
in >> m_valuesummary;
in >> m_timesummary;
in >> m_gain;
in >> m_availableChannels;
in >> m_timeAboveTheshold;
in >> m_upperThreshold;
in >> m_timeBelowTheshold;
in >> m_lowerThreshold;
in >> s_summaryOnly;
s_enabled = 1;
}
bool Session::StoreSummary()
{
// don't really want to call this anymore
return true;
QString filename = s_machine->getDataPath() + QString().sprintf("%08lx.000", s_session);
QFile file(filename); QFile file(filename);
file.open(QIODevice::WriteOnly); file.open(QIODevice::WriteOnly);
@ -190,9 +284,11 @@ bool Session::StoreSummary(QString filename)
out << settings; out << settings;
out << m_cnt; out << m_cnt;
out << m_sum; out << m_sum;
out << m_avg; out << m_avg;
out << m_wavg; out << m_wavg;
out << m_min; out << m_min;
out << m_max; out << m_max;
out << m_physmin; out << m_physmin;
@ -217,9 +313,7 @@ bool Session::StoreSummary(QString filename)
out << m_upperThreshold; out << m_upperThreshold;
out << m_timeBelowTheshold; out << m_timeBelowTheshold;
out << m_lowerThreshold; out << m_lowerThreshold;
// 15 ->
// <- 13
out << s_summaryOnly; out << s_summaryOnly;
// 13 -> // 13 ->
@ -227,8 +321,11 @@ bool Session::StoreSummary(QString filename)
return true; return true;
} }
bool Session::LoadSummary(QString filename) bool Session::LoadSummary(QString filename)
{ {
s_changed = true;
if (filename.isEmpty()) { if (filename.isEmpty()) {
qDebug() << "Empty summary filename"; qDebug() << "Empty summary filename";
return false; return false;
@ -464,11 +561,13 @@ bool Session::LoadSummary(QString filename)
qDebug() << "Upgrading Summary file to version" << summary_version; qDebug() << "Upgrading Summary file to version" << summary_version;
if (!s_summaryOnly) { if (!s_summaryOnly) {
OpenEvents();
UpdateSummaries(); UpdateSummaries();
TrashEvents();
} else { } else {
// summary only upgrades go here. // summary only upgrades go here.
} }
StoreSummary(filename); SetChanged(true);
} }
return true; return true;
@ -476,11 +575,12 @@ bool Session::LoadSummary(QString filename)
const quint16 compress_method = 1; const quint16 compress_method = 1;
bool Session::StoreEvents(QString filename) bool Session::StoreEvents()
{ {
if (filename.isEmpty()) { QString path = s_machine->getEventsPath();
filename = machine()->getDataPath() + QString().sprintf("%08lx.001", s_session); QDir dir;
} dir.mkpath(path);
QString filename = path+QString().sprintf("%08lx.001", s_session);
QFile file(filename); QFile file(filename);
file.open(QIODevice::WriteOnly); file.open(QIODevice::WriteOnly);
@ -627,7 +727,7 @@ bool Session::LoadEvents(QString filename)
QFile file(filename); QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Couldn't open file" << filename; qDebug() << "No Event/Waveform data available for" << s_session;
return false; return false;
} }
@ -812,7 +912,7 @@ bool Session::LoadEvents(QString filename)
if (version < events_version) { if (version < events_version) {
qDebug() << "Upgrading Events file" << filename << "to version" << events_version; qDebug() << "Upgrading Events file" << filename << "to version" << events_version;
UpdateSummaries(); UpdateSummaries();
StoreEvents(filename); StoreEvents();
} }
return true; return true;
@ -931,7 +1031,6 @@ void Session::updateCountSummary(ChannelID code)
void Session::UpdateSummaries() void Session::UpdateSummaries()
{ {
ChannelID id; ChannelID id;
calcAHIGraph(this); calcAHIGraph(this);
@ -1069,30 +1168,6 @@ EventDataType Session::SearchValue(ChannelID code, qint64 time, bool square)
return 0; return 0;
} }
bool Session::enabled()
{
if (s_enabled >= 0) {
return s_enabled != 0;
}
if (!settings.contains(SESSION_ENABLED)) {
bool b = true;
settings[SESSION_ENABLED] = b;
s_enabled = b ? 1 : 0;
return b;
}
s_enabled = settings[SESSION_ENABLED].toBool() ? 1 : 0;
return s_enabled;
}
void Session::setEnabled(bool b)
{
settings[SESSION_ENABLED] = s_enabled = b;
SetChanged(true);
}
QString Session::dimension(ChannelID id) QString Session::dimension(ChannelID id)
{ {
// Cheat for now // Cheat for now
@ -1837,9 +1912,12 @@ EventDataType Session::timeAboveThreshold(ChannelID id, EventDataType threshold)
} }
bool loaded = s_events_loaded; bool loaded = s_events_loaded;
this->OpenEvents(); OpenEvents();
QHash<ChannelID, QVector<EventList *> >::iterator j = eventlist.find(id); QHash<ChannelID, QVector<EventList *> >::iterator j = eventlist.find(id);
if (j == eventlist.end()) { if (j == eventlist.end()) {
if (!loaded) {
TrashEvents();
}
return 0.0f; return 0.0f;
} }

View File

@ -69,13 +69,19 @@ class Session
bool Store(QString path); bool Store(QString path);
//! \brief Writes the Sessions Summary Indexes to filename, in SleepLibs custom data format. //! \brief Writes the Sessions Summary Indexes to filename, in SleepLibs custom data format.
bool StoreSummary(QString filename = QString()); bool StoreSummary();
//! \brief Save the Sessions Summary Indexes to the stream
void StoreSummaryData(QDataStream & out) const;
//! \brief Writes the Sessions EventLists to filename, in SleepLibs custom data format. //! \brief Writes the Sessions EventLists to filename, in SleepLibs custom data format.
bool StoreEvents(QString filename = QString()); bool StoreEvents();
//bool Load(QString path); //bool Load(QString path);
//! \brief Loads the Sessions Summary Indexes from stream
void LoadSummaryData(QDataStream & in);
//! \brief Loads the Sessions Summary Indexes from filename, from SleepLibs custom data format. //! \brief Loads the Sessions Summary Indexes from filename, from SleepLibs custom data format.
bool LoadSummary(QString filename); bool LoadSummary(QString filename);
@ -99,12 +105,11 @@ class Session
return s_session; return s_session;
} }
//! \brief Returns whether or not session is being used. //! \brief Returns whether or not session is being used.
bool enabled(); inline bool enabled() const { return s_enabled; }
//! \brief Sets whether or not session is being used. //! \brief Sets whether or not session is being used.
void setEnabled(bool b); void setEnabled(bool b) { s_enabled = b; }
//! \brief Return the start of this sessions time range (in milliseconds since epoch) //! \brief Return the start of this sessions time range (in milliseconds since epoch)
qint64 first(); qint64 first();
@ -321,9 +326,6 @@ class Session
bool eventsLoaded() { return s_events_loaded; } bool eventsLoaded() { return s_events_loaded; }
//! \brief Sets the event file linked to the summary (during load, for ondemand loading)
void SetEventFile(QString &filename) { s_eventfile = filename; }
//! \brief Update this sessions first time if it's less than the current record //! \brief Update this sessions first time if it's less than the current record
inline void updateFirst(qint64 v) { if (!s_first) { s_first = v; } else if (s_first > v) { s_first = v; } } inline void updateFirst(qint64 v) { if (!s_first) { s_first = v; } else if (s_first > v) { s_first = v; } }
@ -367,7 +369,8 @@ class Session
m_cnt.clear(); m_cnt.clear();
} }
const QString & eventFile() { return s_eventfile; }
QString eventFile() const;
#if defined(SESSION_DEBUG) #if defined(SESSION_DEBUG)
QStringList session_files; QStringList session_files;
@ -386,12 +389,13 @@ protected:
bool s_summaryOnly; bool s_summaryOnly;
bool s_events_loaded; bool s_events_loaded;
char s_enabled; bool s_enabled;
QString s_eventfile;
// for debugging // for debugging
bool destroyed; bool destroyed;
}; };
QDataStream & operator<<(QDataStream & out, const Session & session);
QDataStream & operator>>(QDataStream & in, Session & session);
#endif // SESSION_H #endif // SESSION_H

View File

@ -451,7 +451,6 @@ void Daily::closeEvent(QCloseEvent *event)
void Daily::doToggleSession(Session * sess) void Daily::doToggleSession(Session * sess)
{ {
sess->setEnabled(!sess->enabled()); sess->setEnabled(!sess->enabled());
sess->StoreSummary();
LoadDate(previous_date); LoadDate(previous_date);
} }
@ -471,7 +470,6 @@ void Daily::Link_clicked(const QUrl &url)
return; return;
int i=webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-webView->page()->mainFrame()->scrollBarValue(Qt::Vertical); int i=webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-webView->page()->mainFrame()->scrollBarValue(Qt::Vertical);
sess->setEnabled(!sess->enabled()); sess->setEnabled(!sess->enabled());
sess->StoreSummary();
// Reload day // Reload day
LoadDate(previous_date); LoadDate(previous_date);
@ -484,8 +482,6 @@ void Daily::Link_clicked(const QUrl &url)
int i=webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-webView->page()->mainFrame()->scrollBarValue(Qt::Vertical); int i=webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-webView->page()->mainFrame()->scrollBarValue(Qt::Vertical);
sess->setEnabled(!sess->enabled()); sess->setEnabled(!sess->enabled());
sess->StoreSummary();
// Reload day // Reload day
LoadDate(previous_date); LoadDate(previous_date);
webView->page()->mainFrame()->setScrollBarValue(Qt::Vertical, webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-i); webView->page()->mainFrame()->setScrollBarValue(Qt::Vertical, webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-i);
@ -1831,7 +1827,7 @@ void Daily::Unload(QDate date)
// blah.. was updating overview graphs here.. Was too slow. // blah.. was updating overview graphs here.. Was too slow.
} }
Machine *jm=p_profile->GetMachine(MT_JOURNAL); Machine *jm=p_profile->GetMachine(MT_JOURNAL);
if (jm) jm->SaveSession(journal); if (jm) jm->SaveSummary(); //(journal);
} }
UpdateCalendarDay(date); UpdateCalendarDay(date);
} }

View File

@ -1867,6 +1867,7 @@ void MainWindow::on_action_Rebuild_Oximetry_Index_triggered()
for (int i = 0; i < machines.size(); i++) { for (int i = 0; i < machines.size(); i++) {
Machine *m = machines[i]; Machine *m = machines[i];
m->Save(); m->Save();
m->SaveSummary();
} }
getDaily()->LoadDate(getDaily()->getDate()); getDaily()->LoadDate(getDaily()->getDate());

View File

@ -290,7 +290,9 @@ void OximeterImport::doImport()
updateStatus(tr("Waiting for the device to start the upload process...")); updateStatus(tr("Waiting for the device to start the upload process..."));
} else { } else {
ui->connectLabel->setText("<h2>"+tr("Select upload option on %1").arg(oximodule->loaderName())+"</h2>"); ui->connectLabel->setText("<h2>"+tr("Select upload option on %1").arg(oximodule->loaderName())+"</h2>");
updateStatus(tr("Waiting for you to start the upload process...")); ui->logBox->appendPlainText(tr("You need to tell your oximeter to begin sending data to the computer."));
updateStatus(tr("Please connect your oximeter, enter it's menu and select upload to commence data transfer..."));
} }
connect(oximodule, SIGNAL(updateProgress(int,int)), this, SLOT(doUpdateProgress(int,int))); connect(oximodule, SIGNAL(updateProgress(int,int)), this, SLOT(doUpdateProgress(int,int)));
@ -952,6 +954,7 @@ void OximeterImport::on_saveButton_clicked()
mach->AddSession(session); mach->AddSession(session);
mach->Save(); mach->Save();
mach->SaveSummary();
mainwin->getDaily()->LoadDate(mainwin->getDaily()->getDate()); mainwin->getDaily()->LoadDate(mainwin->getDaily()->getDate());
mainwin->getOverview()->ReloadGraphs(); mainwin->getOverview()->ReloadGraphs();

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>986</width> <width>1312</width>
<height>623</height> <height>623</height>
</rect> </rect>
</property> </property>
@ -647,7 +647,7 @@ border-radius: 0px;</string>
<item> <item>
<widget class="QStackedWidget" name="stackedWidget"> <widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>2</number>
</property> </property>
<widget class="QWidget" name="welcomePage"> <widget class="QWidget" name="welcomePage">
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
@ -970,15 +970,26 @@ background: qlineargradient( x1:0 y1:0, x2:1 y2:0, stop:0 white, stop:1 #cccccc)
</item> </item>
<item> <item>
<widget class="QLabel" name="directImportStatus"> <widget class="QLabel" name="directImportStatus">
<property name="font">
<font>
<pointsize>15</pointsize>
</font>
</property>
<property name="text"> <property name="text">
<string/> <string notr="true">placeholder</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QProgressBar" name="progressBar"> <widget class="QProgressBar" name="progressBar">
<property name="maximum">
<number>0</number>
</property>
<property name="value"> <property name="value">
<number>24</number> <number>0</number>
</property> </property>
</widget> </widget>
</item> </item>