diff --git a/Graphs/gGraphView.cpp b/Graphs/gGraphView.cpp index 5b8c1cc7..e8f7f76d 100644 --- a/Graphs/gGraphView.cpp +++ b/Graphs/gGraphView.cpp @@ -591,12 +591,12 @@ gToolTip::~gToolTip() disconnect(timer,SLOT(timerDone())); delete timer; } -void gToolTip::calcSize(QString text,int &w, int &h) -{ +//void gToolTip::calcSize(QString text,int &w, int &h) +//{ /*GetTextExtent(text,w,h); w+=m_spacer*2; h+=m_spacer*2; */ -} +//} void gToolTip::display(QString text, int x, int y, int timeout) { @@ -2163,7 +2163,7 @@ void gGraphView::paintGL() #ifdef ENABLED_THREADED_DRAWING } #endif - int elapsed=time.elapsed(); + //int elapsed=time.elapsed(); QColor col=Qt::black; if (!numgraphs) { int x,y; diff --git a/Graphs/gGraphView.h b/Graphs/gGraphView.h index 8f60503c..782a0fe0 100644 --- a/Graphs/gGraphView.h +++ b/Graphs/gGraphView.h @@ -245,7 +245,7 @@ class gToolTip: public QObject public: gToolTip(gGraphView * graphview); virtual ~gToolTip(); - void calcSize(QString text, int & w, int & h); + //void calcSize(QString text, int & w, int & h); virtual void display(QString text, int x, int y, int timeout=2000); virtual void paint(); //actually paints it. void cancel(); diff --git a/main.cpp b/main.cpp index 6e37bfd5..6f37417d 100644 --- a/main.cpp +++ b/main.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "SleepLib/schema.h" #include "mainwindow.h" diff --git a/mainwindow.h b/mainwindow.h index cea29be1..b3908f61 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -16,7 +16,6 @@ #include "daily.h" #include "overview.h" #include "oximetry.h" -#include "report.h" #include "preferencesdialog.h" const int major_version=0; diff --git a/overview.cpp b/overview.cpp index 35a1c917..7feaf79d 100644 --- a/overview.cpp +++ b/overview.cpp @@ -219,8 +219,6 @@ Overview::Overview(QWidget *parent,gGraphView * shared) : npb->addSlice(CPAP_CSR,QColor("light green"),ST_SPH,false); // <--- The code to the previous marker is crap - report=NULL; - GraphView->LoadSettings("Overview"); } Overview::~Overview() @@ -228,10 +226,6 @@ Overview::~Overview() GraphView->SaveSettings("Overview"); disconnect(this,SLOT(dateStart_currentPageChanged(int,int))); disconnect(this,SLOT(dateEnd_currentPageChanged(int,int))); - if (report) { - report->close(); - delete report; - } delete ui; } gGraph * Overview::createGraph(QString name,QString units) @@ -333,30 +327,9 @@ void Overview::on_toolButton_clicked() GraphView->SetXBounds(d1,d2); } -QString Overview::GetHTML() -{ - if (!report) { - report=new Report(this,m_shared,this); - report->hide(); - } - - QString html; - if (report) { - GraphView->deselect(); - - report->ReloadGraphs(); - QString reportname="overview"; - html=report->GenerateReport(reportname,ui->dateStart->date(),ui->dateEnd->date()); - if (html.isEmpty()) { - qDebug() << "Faulty Report" << reportname; - } - } - return html; -} void Overview::on_printButton_clicked() { mainwin->PrintReport(GraphView,"Overview"); - //report->Print(GetHTML()); } void Overview::ResetGraphLayout() diff --git a/overview.h b/overview.h index 49ebf0d7..b4bac543 100644 --- a/overview.h +++ b/overview.h @@ -14,7 +14,6 @@ #include "SleepLib/profiles.h" #include "Graphs/gGraphView.h" #include "Graphs/gSummaryChart.h" -#include "report.h" namespace Ui { class Overview; @@ -67,14 +66,11 @@ private: MyScrollBar *scrollbar; QHBoxLayout *layout; gGraphView * m_shared; - Report * report; void UpdateHTML(); void UpdateCalendarDay(QDateEdit * calendar,QDate date); - QString GetHTML(); - //SessionTimes *session_times; //,*PRESSURE,*LEAK,*SESSTIMES; diff --git a/oximetry.cpp b/oximetry.cpp index 385fbb69..4b9b2910 100644 --- a/oximetry.cpp +++ b/oximetry.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -170,14 +171,15 @@ void SerialOximeter::setStopBits(StopBitsType stopbits) void SerialOximeter::addPulse(qint64 time, EventDataType pr) { - static EventDataType lastpr=0; //EventDataType min=0,max=0; if (pr>0) { if (lastpr==0) { if (pulse->count()==0) { pulse->setFirst(time); - if (session->eventlist[OXI_Pulse].size()==1) { + if (session->eventlist[OXI_Pulse].size()<=1) { session->setFirst(OXI_Pulse,time); + if (session->first()==0) + session->set_first(time); } } else { @@ -187,6 +189,7 @@ void SerialOximeter::addPulse(qint64 time, EventDataType pr) pulse->AddEvent(time,pr); session->setCount(OXI_Pulse,session->count(OXI_Pulse)+1); session->setLast(OXI_Pulse,time); + session->set_last(time); } else { if (lastpr!=0) { if (pulse->count() > 0) { @@ -197,21 +200,21 @@ void SerialOximeter::addPulse(qint64 time, EventDataType pr) } } } - session->set_last(time); lastpr=pr; emit(updatePulse(pr)); } void SerialOximeter::addSpO2(qint64 time, EventDataType o2) { - static EventDataType lasto2=0; //EventDataType min=0,max=0; if (o2>0) { if (lasto2==0) { if (spo2->count()==0) { spo2->setFirst(time); - if (session->eventlist[OXI_SPO2].size()==1) { + if (session->eventlist[OXI_SPO2].size()<=1) { session->setFirst(OXI_SPO2,time); + if (session->first()==0) + session->set_first(time); } } else { qDebug() << "Shouldn't happen in addSpO2()"; @@ -221,6 +224,7 @@ void SerialOximeter::addSpO2(qint64 time, EventDataType o2) spo2->AddEvent(time,o2); session->setCount(OXI_SPO2,session->count(OXI_SPO2)+1); session->setLast(OXI_SPO2,time); + session->set_last(time); } else { if (lasto2!=0) { if (spo2->count() > 0) { @@ -231,7 +235,6 @@ void SerialOximeter::addSpO2(qint64 time, EventDataType o2) } } } - session->set_last(time); lasto2=o2; emit(updateSpO2(o2)); @@ -244,7 +247,7 @@ void SerialOximeter::addPlethy(qint64 time, EventDataType pleth) session->setMin(OXI_Plethy,plethy->min()); session->setMax(OXI_Plethy,plethy->max()); session->setLast(OXI_Plethy,time); - session->set_last(lasttime); + session->set_last(time); plethy->setLast(time); } void SerialOximeter::compactToWaveform(EventList *el) @@ -299,13 +302,14 @@ void SerialOximeter::compactAll() } } -Session *SerialOximeter::createSession() +Session *SerialOximeter::createSession(QDateTime date) { if (session) { delete session; } - int sid=QDateTime::currentDateTime().toTime_t(); + int sid=date.toTime_t(); lasttime=qint64(sid)*1000L; + lasto2=lastpr=0; session=new Session(machine,sid); session->SetChanged(true); @@ -336,6 +340,7 @@ bool SerialOximeter::startLive() { import_mode=false; m_mode=SO_LIVE; + lastpr=lasto2=0; if (!m_opened && !Open(QextSerialPort::EventDriven)) return false; createSession(); @@ -1217,3 +1222,321 @@ void Oximetry::update_progress(float f) QApplication::processEvents(); } } + +bool Oximetry::openSPOFile(QString filename) +{ + if (oximeter->getSession() && oximeter->getSession()->IsChanged()) { + int res=QMessageBox::question(this,"Save Session?","Opening this oximetry file will destroy the current session.\nWould you like to keep it?","Save","Destroy It","Cancel",0,2); + if (res==0) { + on_saveButton_clicked(); + return false; + } else if (res==2) { + return false; + } + } // else it's already saved. + //GraphView->setEmptyText("Please Wait"); + //GraphView->updateGL(); + QFile f(filename); + if (!f.open(QFile::ReadOnly)) return false; + + QByteArray data; + + data=f.readAll(); + long size=data.size(); + + int pos=((unsigned char)data.at(1) << 8) | (unsigned char)data.at(0); + char dchr[20]; + int j=0; + for (int i=0;i<18*2;i+=2) { + dchr[j++]=data.at(8+i); + } + dchr[j]=0; + QString dstr(dchr); + QDateTime date=QDateTime::fromString(dstr,"MM/dd/yy HH:mm:ss"); + if (date.date().year()<2000) date=date.addYears(100); + qDebug() << date << pos; + + day->getSessions().clear(); + oximeter->createSession(date); + Session *session=oximeter->getSession(); + day->AddSession(session); + session->set_first(0); + + PLETHY->setRecMinY(0); + PLETHY->setRecMaxY(128); + PULSE->setRecMinY(60); + PULSE->setRecMaxY(100); + SPO2->setRecMinY(90); + SPO2->setRecMaxY(100); + + firstPulseUpdate=true; + firstSPO2Update=true; + secondPulseUpdate=true; + secondSPO2Update=true; + + unsigned char o2,pr; + quint16 pl; + qint64 tt=qint64(date.toTime_t())*1000L; + + + /*session->set_first(tt); + day->setFirst(tt); + plethy->setMinX(tt); + pulse->setMinX(tt); + spo2->setMinX(tt); + PLETHY->SetMinX(tt); + CONTROL->SetMinX(tt); + PULSE->SetMinX(tt); + SPO2->SetMinX(tt); */ + + for (int i=pos;isetLastTime(tt); + oximeter->addPulse(tt,pr); + oximeter->addSpO2(tt,o2); + pl=(unsigned char)(data.at(i+1)); + //oximeter->addPlethy(tt,pl); + //pl=(unsigned char)(data.at(i+1)); + //oximeter->addPlethy(tt,pl); + //pl=(unsigned char)(data.at(i+2)); + //oximeter->addPlethy(tt,pl); + i+=5; + //data_changed(); + tt+=1000; + } + qint64 t1=session->first(OXI_Pulse); + qint64 t2=session->first(OXI_SPO2); + qint64 t3=qMin(t1,t2); + session->set_first(t3); + day->setFirst(t3); + t1=session->last(OXI_Pulse); + t2=session->last(OXI_SPO2); + t3=qMax(t1,t2); + session->set_last(t3); + day->setLast(t3); + //session->setLast(OXI_Pulse,tt); + //session->setLast(OXI_Plethy,tt); + //session->setLast(OXI_SPO2,tt); + //session->set_last(tt); + + ui->pulseLCD->display(session->min(OXI_Pulse)); + ui->spo2LCD->display(session->min(OXI_SPO2)); + + pulse->setMinY(session->min(OXI_Pulse)); + pulse->setMaxY(session->max(OXI_Pulse)); + spo2->setMinY(session->min(OXI_SPO2)); + spo2->setMaxY(session->max(OXI_SPO2)); + + PULSE->setRecMinY(60); + PULSE->setRecMaxY(100); + SPO2->setRecMinY(90); + SPO2->setRecMaxY(100); + + //PLETHY->setVisible(false); + CONTROL->setVisible(false); + + { + qint64 f=session->first(); + qint64 l=session->last(); + day->setFirst(f); + day->setLast(l); + + plethy->setMinX(f); + pulse->setMinX(f); + spo2->setMinX(f); + PLETHY->SetMinX(f); + CONTROL->SetMinX(f); + PULSE->SetMinX(f); + SPO2->SetMinX(f); + + plethy->setMaxX(l); + pulse->setMaxX(l); + spo2->setMaxX(l); + PLETHY->SetMaxX(l); + CONTROL->SetMaxX(l); + PULSE->SetMaxX(l); + SPO2->SetMaxX(l); + + PULSE->setDay(day); + SPO2->setDay(day); + session->UpdateSummaries(); + + for (int i=0;isize();i++) { + (*GraphView)[i]->SetXBounds(f,l); + } + + { + int len=(l-f)/1000L; + int h=len/3600; + int m=(len /60) % 60; + int s=(len % 60); + if (qstatus2) qstatus2->setText(QString().sprintf("%02i:%02i:%02i",h,m,s)); + } + GraphView->updateScale(); + + GraphView->updateGL(); + } + f.close(); + ui->saveButton->setEnabled(true); + return true; +} + +bool Oximetry::openSPORFile(QString filename) +{ + if (oximeter->getSession() && oximeter->getSession()->IsChanged()) { + int res=QMessageBox::question(this,"Save Session?","Opening this oximetry file will destroy the current session.\nWould you like to keep it?","Save","Destroy It","Cancel",0,2); + if (res==0) { + on_saveButton_clicked(); + return false; + } else if (res==2) { + return false; + } + } // else it's already saved. + //GraphView->setEmptyText("Please Wait"); + //GraphView->updateGL(); + QFile f(filename); + if (!f.open(QFile::ReadOnly)) return false; + + QByteArray data; + + data=f.readAll(); + long size=data.size(); + + int pos=((unsigned char)data.at(1) << 8) | (unsigned char)data.at(0); + char dchr[20]; + int j=0; + for (int i=0;i<18*2;i+=2) { + dchr[j++]=data.at(8+i); + } + dchr[j]=0; + QString dstr(dchr); + QDateTime date=QDateTime::fromString(dstr,"MM/dd/yy HH:mm:ss"); + if (date.date().year()<2000) date=date.addYears(100); + qDebug() << date << pos; + + day->getSessions().clear(); + oximeter->createSession(date); + Session *session=oximeter->getSession(); + day->AddSession(session); + session->set_first(0); + + PLETHY->setRecMinY(0); + PLETHY->setRecMaxY(128); + PULSE->setRecMinY(60); + PULSE->setRecMaxY(100); + SPO2->setRecMinY(90); + SPO2->setRecMaxY(100); + + firstPulseUpdate=true; + firstSPO2Update=true; + secondPulseUpdate=true; + secondSPO2Update=true; + + unsigned char o2,pr; + quint16 pl; + qint64 tt=qint64(date.toTime_t())*1000L; + + for (int i=pos;iaddPulse(tt,pr); + oximeter->addSpO2(tt,o2); + pl=(unsigned char)(data.at(i+1)); + i+=2; + tt+=1000; + } + qint64 t1=session->first(OXI_Pulse); + qint64 t2=session->first(OXI_SPO2); + qint64 t3=qMin(t1,t2); + session->set_first(t3); + day->setFirst(t3); + t1=session->last(OXI_Pulse); + t2=session->last(OXI_SPO2); + t3=qMax(t1,t2); + session->set_last(t3); + day->setLast(t3); + + ui->pulseLCD->display(session->min(OXI_Pulse)); + ui->spo2LCD->display(session->min(OXI_SPO2)); + + pulse->setMinY(session->min(OXI_Pulse)); + pulse->setMaxY(session->max(OXI_Pulse)); + spo2->setMinY(session->min(OXI_SPO2)); + spo2->setMaxY(session->max(OXI_SPO2)); + + PULSE->setRecMinY(60); + PULSE->setRecMaxY(100); + SPO2->setRecMinY(90); + SPO2->setRecMaxY(100); + + //PLETHY->setVisible(false); + CONTROL->setVisible(false); + + { + qint64 f=session->first(); + qint64 l=session->last(); + day->setFirst(f); + day->setLast(l); + + plethy->setMinX(f); + pulse->setMinX(f); + spo2->setMinX(f); + PLETHY->SetMinX(f); + CONTROL->SetMinX(f); + PULSE->SetMinX(f); + SPO2->SetMinX(f); + + plethy->setMaxX(l); + pulse->setMaxX(l); + spo2->setMaxX(l); + PLETHY->SetMaxX(l); + CONTROL->SetMaxX(l); + PULSE->SetMaxX(l); + SPO2->SetMaxX(l); + + PULSE->setDay(day); + SPO2->setDay(day); + session->UpdateSummaries(); + + for (int i=0;isize();i++) { + (*GraphView)[i]->SetXBounds(f,l); + } + + { + int len=(l-f)/1000L; + int h=len/3600; + int m=(len /60) % 60; + int s=(len % 60); + if (qstatus2) qstatus2->setText(QString().sprintf("%02i:%02i:%02i",h,m,s)); + } + GraphView->updateScale(); + + GraphView->updateGL(); + } + f.close(); + ui->saveButton->setEnabled(true); + return true; +} + +void Oximetry::on_openButton_clicked() +{ + QString dir=""; + QFileDialog fd(this,"Select an oximetry file",dir,"Oximetry Files (*.spo *.spoR)"); + fd.setAcceptMode(QFileDialog::AcceptOpen); + fd.setFileMode(QFileDialog::ExistingFile); + if (fd.exec()!=QFileDialog::Accepted) return; + QStringList filenames=fd.selectedFiles(); + if (filenames.size()>1) { + qDebug() << "Can only open one oximetry file at a time"; + } + QString filename=filenames[0]; + bool r=false; + if (filename.toLower().endsWith(".spo")) r=openSPOFile(filename); + else if (filename.toLower().endsWith(".spor")) r=openSPORFile(filename); + + if (!r) { + mainwin->Notify("Couldn't open oximetry file \""+filename+"\"."); + } + qDebug() << "opening" << filename; +} diff --git a/oximetry.h b/oximetry.h index 5748990a..9f866758 100644 --- a/oximetry.h +++ b/oximetry.h @@ -47,9 +47,10 @@ public: int callbacks() { return m_callbacks; } qint64 lastTime() { return lasttime; } + void setLastTime(qint64 t) { lasttime=t; } Machine * getMachine() { return machine; } - Session *createSession(); + Session *createSession(QDateTime date=QDateTime::currentDateTime()); Session * getSession() { return session; } void compactToWaveform(EventList *el); @@ -73,6 +74,9 @@ public: EventList * Pulse() { return pulse; } EventList * Spo2() { return spo2; } EventList * Plethy() { return plethy; } + virtual void addPulse(qint64 time, EventDataType pr); + virtual void addSpO2(qint64 time, EventDataType o2); + virtual void addPlethy(qint64 time, EventDataType pleth); signals: void sessionCreated(Session *); @@ -95,11 +99,6 @@ protected slots: protected: //virtual void addEvents(EventDataType pr, EventDataType o2, EventDataType pleth=-1000000); - virtual void addPulse(qint64 time, EventDataType pr); - virtual void addSpO2(qint64 time, EventDataType o2); - virtual void addPlethy(qint64 time, EventDataType pleth); - - Session * session; EventList * pulse; @@ -124,6 +123,8 @@ protected: int m_callbacks; bool done_import; QTimer *timer; + EventDataType lasto2,lastpr; + }; class CMS50Serial:public SerialOximeter @@ -190,7 +191,11 @@ private slots: void oximeter_running_check(); void live_stopped(Session *session); + void on_openButton_clicked(); + private: + bool openSPOFile(QString filename); + bool openSPORFile(QString filename); void import_finished(); Ui::Oximetry *ui; diff --git a/oximetry.ui b/oximetry.ui index b761c6a8..2e8c2f6b 100644 --- a/oximetry.ui +++ b/oximetry.ui @@ -248,6 +248,13 @@ + + + + &Open + + + diff --git a/preferencesdialog.cpp b/preferencesdialog.cpp index 3363a5bb..4166b9ff 100644 --- a/preferencesdialog.cpp +++ b/preferencesdialog.cpp @@ -102,13 +102,13 @@ PreferencesDialog::PreferencesDialog(QWidget *parent,Profile * _profile) : bool ok; double v; v=(*profile)["SPO2DropPercentage"].toDouble(&ok); - if (!ok) v=4; + if (!ok) v=3; ui->spo2Drop->setValue(v); v=(*profile)["SPO2DropDuration"].toDouble(&ok); - if (!ok) v=5; + if (!ok) v=10; ui->spo2DropTime->setValue(v); v=(*profile)["PulseChangeBPM"].toDouble(&ok); - if (!ok) v=5; + if (!ok) v=8; ui->pulseChange->setValue(v); v=(*profile)["PulseChangeDuration"].toDouble(&ok); if (!ok) v=5;