Oximetry information cleanup, Gave graphs the ability to fully remove title, Print Daily Report bookmark fixes and cleanup

This commit is contained in:
Mark Watkins 2011-12-25 15:05:12 +10:00
parent 15fa9317be
commit c3738a5b72
11 changed files with 559 additions and 507 deletions

View File

@ -1019,10 +1019,6 @@ bool gGraph::isEmpty()
return empty;
}
void gGraph::showTitle(bool b)
{
m_showTitle=b;
}
float gGraph::printScaleX() { return m_graphview->printScaleX(); }
float gGraph::printScaleY() { return m_graphview->printScaleY(); }
@ -1073,8 +1069,8 @@ void gGraph::paint(int originX, int originY, int width, int height)
int fw,font_height;
GetTextExtent("Wg@",fw,font_height);
m_margintop=font_height+(8*printScaleY());
m_marginbottom=5;
if (m_margintop>0) m_margintop=font_height+(8*printScaleY());
//m_marginbottom=5;
//glColor4f(0,0,0,1);
left=marginLeft(),right=marginRight(),top=marginTop(),bottom=marginBottom();
@ -1664,7 +1660,7 @@ short gGraph::marginRight() { return m_marginright; } //*m_graphview->printScale
short gGraph::marginTop() { return m_margintop; } //*m_graphview->printScaleY(); }
short gGraph::marginBottom() { return m_marginbottom; } //*m_graphview->printScaleY(); }
QPixmap gGraph::renderPixmap(int w, int h, float scale)
QPixmap gGraph::renderPixmap(int w, int h, bool printing)
{
gGraphView *sg=mainwin->snapshotGraph();
@ -1678,13 +1674,17 @@ QPixmap gGraph::renderPixmap(int w, int h, float scale)
QFont fb=*mediumfont;
QFont fc=*bigfont;
sg->setPrintScaleX(3);
sg->setPrintScaleY(3);
fa.setPixelSize(30);
fb.setPointSize(35);
fc.setPointSize(80);
if (printing) {
fa.setPixelSize(30);
fb.setPixelSize(35);
fc.setPixelSize(80);
sg->setPrintScaleX(3);
sg->setPrintScaleY(3);
} else {
sg->setPrintScaleX(1);
sg->setPrintScaleY(1);
}
defaultfont=&fa;
mediumfont=&fb;
bigfont=&fc;
@ -2315,7 +2315,7 @@ bool gGraphView::renderGraphs()
// glEnd();
// glDisable(GL_BLEND);
float px=titleWidth-m_offsetX;
float px=m_offsetX;
float py=-m_offsetY;
int numgraphs=0;
float h,w;
@ -2347,7 +2347,9 @@ bool gGraphView::renderGraphs()
if ((py + h + graphSpacer) >= 0) {
w=width();
queGraph(m_graphs[i],px,py,width()-titleWidth,h);
int tw=(m_graphs[i]->showTitle() ? titleWidth : 0);
queGraph(m_graphs[i],px+tw,py,width()-tw,h);
if (m_showsplitter) {
// draw the splitter handle
@ -2456,10 +2458,10 @@ void gGraphView::fadeIn(bool dir)
}
m_inAnimation=false;
current_day_snapshot=renderPixmap(width(),height(),false);
qDebug() << current_day_snapshot.depth() << "bit image depth";
if (current_day_snapshot.hasAlpha()){
qDebug() << "Snapshots are not storing alpha channel needed for texture blending";
}
// qDebug() << current_day_snapshot.depth() << "bit image depth";
// if (current_day_snapshot.hasAlpha()){
// qDebug() << "Snapshots are not storing alpha channel needed for texture blending";
// }
m_inAnimation=true;
m_animationStarted.start();
@ -2941,6 +2943,21 @@ void gGraphView::keyPressEvent(QKeyEvent * event)
event->ignore();
return;
}
if (event->key()==Qt::Key_PageUp) {
m_offsetY-=PROFILE.appearance->graphHeight()*3*m_scaleY;
m_scrollbar->setValue(m_offsetY);
m_offsetY=m_scrollbar->value();
updateGL();
return;
} else if (event->key()==Qt::Key_PageDown) {
m_offsetY+=PROFILE.appearance->graphHeight()*3*m_scaleY; //PROFILE.appearance->graphHeight();
if (m_offsetY<0) m_offsetY=0;
m_scrollbar->setValue(m_offsetY);
m_offsetY=m_scrollbar->value();
updateGL();
return;
// redraw();
}
gGraph *g=NULL;
int group=0;
// Pick the first valid graph in the primary group

View File

@ -427,7 +427,7 @@ public:
Note if width or height is more than the OpenGL system allows, it could result in a crash
Keeping them under 2048 is a reasonably safe value.
*/
QPixmap renderPixmap(int width, int height, float fontscale=1.0);
QPixmap renderPixmap(int width, int height, bool printing=false);
//! \brief Set Graph visibility status
void setVisible(bool b) { m_visible=b; }
@ -441,15 +441,17 @@ public:
//! \brief Set the height element. (relative to the total of all heights)
void setHeight(float height) { m_height=height; }
//! \brief Can't remember what these are for..
int minHeight() { return m_min_height; }
void setMinHeight(int height) { m_min_height=height; }
int maxHeight() { return m_max_height; }
void setMaxHeight(int height) { m_max_height=height; }
//! \brief Returns true if the vertical graph title is shown
bool showTitle() { return m_showTitle; }
//! \brief Set whether or not to render the vertical graph title
void showTitle(bool b);
void setShowTitle(bool b) { m_showTitle=b; }
//! \brief Returns printScaleX, used for DPI scaling in report printing
float printScaleX();

View File

@ -34,5 +34,6 @@
<file>icons/sheep.png</file>
<file>icons/nodata.png</file>
<file>icons/cubeoximeter.png</file>
<file>icons/smileyface2.png</file>
</qresource>
</RCC>

View File

@ -50,6 +50,10 @@ const QString STR_MACH_ZEO="Zeo";
const QString STR_TR_BMI=QObject::tr("BMI");
const QString STR_TR_Weight=QObject::tr("Weight");
const QString STR_TR_PulseRate=QObject::tr("Pulse Rate");
const QString STR_TR_SpO2=QObject::tr("SpO2");
const QString STR_TR_Plethy=QObject::tr("Plethy");
const QString STR_TR_FlowRate=QObject::tr("Flow Rate");
const QString STR_TR_Daily=QObject::tr("Daily");
const QString STR_TR_Overview=QObject::tr("Overview");

265
daily.cpp
View File

@ -113,9 +113,9 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
TgMV=new gGraph(GraphView,tr("Tgt. Min. Vent"),schema::channel[CPAP_TgMV].description()+"\n("+schema::channel[CPAP_TgMV].units()+")",default_height);
int oxigrp=PROFILE.ExistsAndTrue("SyncOximetry") ? 0 : 1;
PULSE=new gGraph(GraphView,tr("Pulse"),schema::channel[OXI_Pulse].description()+"\n("+schema::channel[OXI_Pulse].units()+")",default_height,oxigrp);
SPO2=new gGraph(GraphView,tr("SpO2"),schema::channel[OXI_SPO2].description()+"\n("+schema::channel[OXI_SPO2].units()+")",default_height,oxigrp);
PLETHY=new gGraph(GraphView,tr("Plethy"),schema::channel[OXI_Plethy].description()+"\n("+schema::channel[OXI_Plethy].units()+")",default_height,oxigrp);
PULSE=new gGraph(GraphView,STR_TR_PulseRate,schema::channel[OXI_Pulse].description()+"\n("+schema::channel[OXI_Pulse].units()+")",default_height,oxigrp);
SPO2=new gGraph(GraphView,STR_TR_SpO2,schema::channel[OXI_SPO2].description()+"\n("+schema::channel[OXI_SPO2].units()+")",default_height,oxigrp);
PLETHY=new gGraph(GraphView,STR_TR_Plethy,schema::channel[OXI_Plethy].description()+"\n("+schema::channel[OXI_Plethy].units()+")",default_height,oxigrp);
// Event Pie Chart (for snapshot purposes)
// TODO: Convert snapGV to generic for snapshotting multiple graphs (like reports does)
@ -412,20 +412,16 @@ void Daily::UpdateEventsTree(QTreeWidget *tree,Day *day)
tree->clear();
if (!day) return;
//return;
tree->setColumnCount(1); // 1 visible common.. (1 hidden)
QTreeWidgetItem *root=NULL;//new QTreeWidgetItem((QTreeWidget *)0,QStringList("Stuff"));
QTreeWidgetItem *root=NULL;
QHash<ChannelID,QTreeWidgetItem *> mcroot;
QHash<ChannelID,int> mccnt;
int total_events=0;
for (QVector<Session *>::iterator s=day->begin();s!=day->end();s++) {
QHash<ChannelID,QVector<EventList *> >::iterator m;
//QTreeWidgetItem * sroot;
for (m=(*s)->eventlist.begin();m!=(*s)->eventlist.end();m++) {
ChannelID code=m.key();
if ((code!=CPAP_Obstructive)
@ -467,15 +463,17 @@ void Daily::UpdateEventsTree(QTreeWidget *tree,Day *day)
for (quint32 o=0;o<m.value()[z]->count();o++) {
qint64 t=m.value()[z]->time(o);
if (code==CPAP_CSR) {
if (code==CPAP_CSR) { // center it in the middle of span
t-=float(m.value()[z]->raw(o)/2.0)*1000.0;
}
QStringList a;
QDateTime d=QDateTime::fromTime_t(t/1000);
QString s=QString("#%1: %2 (%3)").arg((int)++mccnt[code],(int)3,(int)10,QChar('0')).arg(d.toString("HH:mm:ss")).arg(m.value()[z]->raw(o));
QString s=QString("#%1: %2 (%3)").arg((int)(++mccnt[code]),(int)3,(int)10,QChar('0')).arg(d.toString("HH:mm:ss")).arg(m.value()[z]->raw(o));
a.append(s);
a.append(d.toString("yyyy-MM-dd HH:mm:ss"));
mcr->addChild(new QTreeWidgetItem(a));
QTreeWidgetItem *item=new QTreeWidgetItem(a);
item->setData(0,Qt::UserRole,t);
//a.append(d.toString("yyyy-MM-dd HH:mm:ss"));
mcr->addChild(item);
}
}
}
@ -566,8 +564,6 @@ void Daily::on_calendar_selectionChanged()
void Daily::ResetGraphLayout()
{
GraphView->resetLayout();
//splitter->setSizes(splitter_sizes);
}
void Daily::graphtogglebutton_toggled(bool b)
{
@ -596,18 +592,17 @@ void Daily::Load(QDate date)
}
if (cpap && oxi) {
qint64 len=qAbs(cpap->first() - oxi->first());
if (len>30000) {
GraphView->findGraph(tr("Pulse Rate"))->setGroup(1);
GraphView->findGraph(tr("SpO2"))->setGroup(1);
GraphView->findGraph(tr("Plethy"))->setGroup(1);
int gr;
if (qAbs(cpap->first() - oxi->first())>30000) {
mainwin->Notify(tr("Oximetry data exists for this day, however it's timestamps are too different, so the Graphs will not be linked."),"",3000);
} else {
//mainwin->Notify(tr("Oximetry & CPAP graphs are linked for this day"),"",2000);
GraphView->findGraph(tr("Pulse Rate"))->setGroup(0);
GraphView->findGraph(tr("SpO2"))->setGroup(0);
GraphView->findGraph(tr("Plethy"))->setGroup(0);
}
gr=1;
} else
gr=0;
GraphView->findGraph(STR_TR_PulseRate)->setGroup(gr);
GraphView->findGraph(STR_TR_SpO2)->setGroup(gr);
GraphView->findGraph(STR_TR_Plethy)->setGroup(gr);
}
lastcpapday=cpap;
@ -787,6 +782,7 @@ void Daily::Load(QDate date)
"</table></td>";
}
html+="</tr>";
// Note, this may not be a problem since Qt bug 13622 was discovered
@ -794,12 +790,16 @@ void Daily::Load(QDate date)
// ^^ Scratch that.. pie now includes text..
if (PROFILE.appearance->graphSnapshots()) { // AHI Pie Chart
if (ahi+rei+fli>0) {
html+="</tr>\n"; //<tr><td colspan=4 align=center><i>"+tr("Event Breakdown")+"</i></td></tr>\n";
if (oai+hi+cai+uai+rei+fli>0) {
html+="<tr><td colspan=5 align=center>&nbsp;</td></tr>";
html+=QString("<tr><td colspan=4 align=center><b>%1</b></td></tr>").arg(tr("Event Breakdown"));
html+="<tr><td colspan=5 align=center><hr/></td></tr>";
//G_AHI->setFixedSize(gwwidth,120);
//mainwin->snapshotGraph()->setPrintScaleX(1);
//mainwin->snapshotGraph()->setPrintScaleY(1);
QPixmap pixmap=snapGV->renderPixmap(172,172);
GAHI->setShowTitle(false);
//snapGV->setFixedSize(150,150);
QPixmap pixmap=GAHI->renderPixmap(150,150,false);
QByteArray byteArray;
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
buffer.open(QIODevice::WriteOnly);
@ -820,133 +820,106 @@ void Daily::Load(QDate date)
html+="</table>";
} // if (!CPAP)
if (!cpap && oxi) {
html+="<table cellspacing=0 cellpadding=0 border=0 width='100%'>\n";
html+="<tr><td colspan=4 align=center><b>"+oxi->machine->properties[STR_PROP_Brand]+"</b> <br>"+oxi->machine->properties[STR_PROP_Model]+"</td></tr>\n";
html+="<tr><td colspan=4 align=center>&nbsp;</td></tr>";
html+=QString("<tr><td colspan=4 align=center>SpO2 Desaturations: %1 (%2)\%</td></tr>").arg(oxi->count(OXI_SPO2Drop)).arg((100.0/oxi->hours()) * (oxi->sum(OXI_SPO2Drop)/3600.0));
html+=QString("<tr><td colspan=4 align=center>Pulse Change events: %1 (%2)\%</td></tr>").arg(oxi->count(OXI_PulseChange)).arg((100.0/oxi->hours()) * (oxi->sum(OXI_PulseChange)/3600.0));
html+=QString("<tr><td colspan=4 align=center>SpO2 Baseline Used: %1\%</td></tr>").arg(oxi->settings_wavg(OXI_SPO2Drop));
html+="</table>";
html+="<table cellspacing=0 cellpadding=0 border=0 width='100%'>\n";
if (oxi) {
html+="<tr><td colspan=5 align=center>&nbsp;</td></tr>";
html+=QString("<tr><td colspan=5 align=center><b>%1</b></td></tr>\n").arg(tr("Oximeter Information"));
html+="<tr><td colspan=5 align=center><hr/></td></tr>";
html+="<tr><td colspan=5 align=center>"+oxi->machine->properties[STR_PROP_Brand]+" "+oxi->machine->properties[STR_PROP_Model]+"</td></tr>\n";
html+="<tr><td colspan=5 align=center>&nbsp;</td></tr>";
html+=QString("<tr><td colspan=5 align=center>%1: %2 (%3)\%</td></tr>").arg(tr("SpO2 Desaturations")).arg(oxi->count(OXI_SPO2Drop)).arg((100.0/oxi->hours()) * (oxi->sum(OXI_SPO2Drop)/3600.0));
html+=QString("<tr><td colspan=5 align=center>%1: %2 (%3)\%</td></tr>").arg(tr("Pulse Change events")).arg(oxi->count(OXI_PulseChange)).arg((100.0/oxi->hours()) * (oxi->sum(OXI_PulseChange)/3600.0));
html+=QString("<tr><td colspan=5 align=center>%1: %2\%</td></tr>").arg(tr("SpO2 Baseline Used")).arg(oxi->settings_wavg(OXI_SPO2Drop));
}
if ((cpap && !isBrick) || oxi) {
html+="<table cellspacing=0 cellpadding=0 border=0 width='100%'>\n";
if (cpap || oxi) {
html+="<tr height='2'><td colspan=5 height='2'><hr></td></tr>\n";
html+="<tr height='2'><td colspan=5>&nbsp;</td></tr>\n";
//html+=("<tr><td colspan=4 align=center>&nbsp;</td></tr>\n");
html+=("<tr><td> </td><td><b>Min</b></td><td><b>Avg</b></td><td><b>90%</b></td><td><b>Max</b></td></tr>");
ChannelID chans[]={
CPAP_Pressure,CPAP_EPAP,CPAP_IPAP,CPAP_PS,CPAP_PTB,
CPAP_MinuteVent,CPAP_AHI, CPAP_RespRate, CPAP_RespEvent,CPAP_FLG,
CPAP_Leak, CPAP_LeakTotal, CPAP_Snore,CPAP_IE,CPAP_Ti,CPAP_Te, CPAP_TgMV,
CPAP_TidalVolume, OXI_Pulse, OXI_SPO2
};
int numchans=sizeof(chans)/sizeof(ChannelID);
int suboffset=0;
for (int i=0;i<numchans;i++) {
ChannelID code=chans[i];
if (cpap && cpap->channelHasData(code)) {
//if (code==CPAP_LeakTotal) suboffset=PROFILEIntentionalLeak"].toDouble(); else suboffset=0;
QString tooltip=schema::channel[code].description();
if (!schema::channel[code].units().isEmpty()) tooltip+=" ("+schema::channel[code].units()+")";
html+="<tr><td align=left><a href='graph="+QString::number(code)+"' title='"+tooltip+"'>"+schema::channel[code].label()+"</a>";
html+="</td><td>"+a.sprintf("%.2f",cpap->Min(code)-suboffset);
html+="</td><td>"+a.sprintf("%.2f",cpap->wavg(code)-suboffset);
html+="</td><td>"+a.sprintf("%.2f",cpap->p90(code)-suboffset);
html+="</td><td>"+a.sprintf("%.2f",cpap->Max(code)-suboffset);
html+="</td><tr>";
}
if (oxi && oxi->channelHasData(code)) {
QString tooltip=schema::channel[code].description();
if (!schema::channel[code].units().isEmpty()) tooltip+=" ("+schema::channel[code].units()+")";
html+="<tr><td align=left><a href='graph="+QString::number(code)+"' title='"+tooltip+"'>"+schema::channel[code].label()+"</a>";
html+="</td><td>"+a.sprintf("%.2f",oxi->Min(code));
html+="</td><td>"+a.sprintf("%.2f",oxi->wavg(code));
html+="</td><td>"+a.sprintf("%.2f",oxi->p90(code));
html+="</td><td>"+a.sprintf("%.2f",oxi->Max(code));
html+="</td><tr>";
}
}
html+=QString("<tr><td colspan=5 align=center><b>%1</b></td></tr>\n").arg(tr("Statistics"));
html+="<tr height='2'><td colspan=5><hr></td></tr>\n";
html+=QString("<tr><td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td><td><b>%4</b></td><td><b>%5</b></td></tr>")
.arg(tr("Channel"))
.arg(tr("Min"))
.arg(tr("Avg"))
.arg(tr("90%"))
.arg(tr("Max"));
ChannelID chans[]={
CPAP_Pressure,CPAP_EPAP,CPAP_IPAP,CPAP_PS,CPAP_PTB,
CPAP_MinuteVent,CPAP_AHI, CPAP_RespRate, CPAP_RespEvent,CPAP_FLG,
CPAP_Leak, CPAP_LeakTotal, CPAP_Snore,CPAP_IE,CPAP_Ti,CPAP_Te, CPAP_TgMV,
CPAP_TidalVolume, OXI_Pulse, OXI_SPO2
};
int numchans=sizeof(chans)/sizeof(ChannelID);
int suboffset=0;
for (int i=0;i<numchans;i++) {
ChannelID code=chans[i];
if (cpap && cpap->channelHasData(code)) {
//if (code==CPAP_LeakTotal) suboffset=PROFILEIntentionalLeak"].toDouble(); else suboffset=0;
QString tooltip=schema::channel[code].description();
if (!schema::channel[code].units().isEmpty()) tooltip+=" ("+schema::channel[code].units()+")";
html+=QString("<tr><td align=left>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td></tr>")
.arg(QString("<a href='graph=%1' title='%2'>%3</a>")
.arg(QString::number(code)).arg(tooltip).arg(schema::channel[code].label()))
.arg(cpap->Min(code),0,'f',2)
.arg(cpap->wavg(code),0,'f',2)
.arg(cpap->p90(code),0,'f',2)
.arg(cpap->Max(code),0,'f',2);
}
if (oxi && oxi->channelHasData(code)) {
QString tooltip=schema::channel[code].description();
if (!schema::channel[code].units().isEmpty()) tooltip+=" ("+schema::channel[code].units()+")";
html+="<tr><td align=left><a href='graph="+QString::number(code)+"' title='"+tooltip+"'>"+schema::channel[code].label()+"</a>";
html+="</td><td>"+a.sprintf("%.2f",oxi->Min(code));
html+="</td><td>"+a.sprintf("%.2f",oxi->wavg(code));
html+="</td><td>"+a.sprintf("%.2f",oxi->p90(code));
html+="</td><td>"+a.sprintf("%.2f",oxi->Max(code));
html+="</td><tr>";
}
}
} else {
html+="<tr><td colspan=5 align=center><i>"+tr("No data available")+"</i></td></tr>";
html+="<tr><td colspan=5>&nbsp;</td></tr>\n";
}
html+="</table><hr height=2/>";
if (cpap) {
// if ((*profile)["EnableGraphSnapshots"].toBool()) {
/*if (cpap->channelExists(CPAP_Pressure)) {
html+=("<tr><td colspan=4 align=center><i>")+tr("Time@Pressure")+("</i></td></tr>\n");
//TAP->setFixedSize(gwwidth,30);
QPixmap pixmap=TAP->renderPixmap(200,30);
QByteArray byteArray;
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
buffer.open(QIODevice::WriteOnly);
pixmap.save(&buffer, "PNG");
html+="<tr><td colspan=4 align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\"></td></tr>\n";
}
if (cpap->channelExists(CPAP_EPAP)) {
//html+="<tr height='2'><td colspan=4 height='2'><hr></td></tr>\n";
html+=("<tr><td colspan=4 align=center><i>")+tr("Time@EPAP")+("</i></td></tr>\n");
TAP_EAP->setFixedSize(gwwidth,30);
QPixmap pixmap=TAP_EAP->renderPixmap(gwwidth,30,false);
QByteArray byteArray;
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
buffer.open(QIODevice::WriteOnly);
pixmap.save(&buffer, "PNG");
html+="<tr><td colspan=4 align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\"></td></tr>\n";
}
if (cpap->channelExists(CPAP_IPAP)) {
html+=("<tr><td colspan=4 align=center><i>")+tr("Time@IPAP")+("</i></td></tr>\n");
TAP_IAP->setFixedSize(gwwidth,30);
QPixmap pixmap=TAP_IAP->renderPixmap(gwwidth,30,false);
QByteArray byteArray;
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
buffer.open(QIODevice::WriteOnly);
pixmap.save(&buffer, "PNG");
html+="<tr><td colspan=4 align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\"></td></tr>\n";
} */
html+="<table cellpadding=0 cellspacing=0 border=0 width=100%>";
html+="<tr><td colspan=5>&nbsp;</td></tr>";
// html+="<table cellpadding=0 cellspacing=0 border=0 width=100%>";
html+=QString("<tr><td colspan=5 align=center><b>%1</b></td></tr>").arg(tr("Machine Settings"));
html+="<tr><td colspan=5><hr height=2></td></tr>";
if (cpap->machine->GetClass()==STR_MACH_PRS1) {
int i=cpap->settings_max(PRS1_FlexMode);
int j=cpap->settings_max(PRS1_FlexSet);
QString flexstr=(i>1) ? schema::channel[PRS1_FlexMode].option(i)+" "+schema::channel[PRS1_FlexSet].option(j) : "None";
html+="<tr><td colspan=4>"+tr("Pressure Relief:")+" "+flexstr+"</td></tr>";
i=cpap->settings_max(PRS1_HumidSetting);
QString humid=(i==0) ? STR_GEN_Off : "x"+QString::number(i);
html+="<tr><td colspan=4>"+tr("Humidifier Setting:")+" "+humid+"</td></tr>";
html+=QString("<tr><td>%1</td><td colspan=4>%2</td></tr>").arg(tr("Flex"))
.arg(flexstr);
html+=QString("<tr><td>%1</td><td colspan=4>%2</td></tr>").arg(tr("Humidifier"))
.arg(cpap->settings_max(PRS1_HumidSetting) ? STR_GEN_Off : "x"+QString::number(i));
} else if (cpap->machine->GetClass()==STR_MACH_ResMed) {
int epr=cpap->settings_max(RMS9_EPR);
int epr2=cpap->settings_max(RMS9_EPRSet);
html+="<tr><td colspan=4>"+tr("EPR Setting:")+" "+QString::number(epr)+" / "+QString::number(epr2)+"</td></tr>";
//epr=schema::channel[PRS1_FlexSet].optionString(pr)+QString(" x%1").arg((int)cpap->settings_max(PRS1_FlexSet));
html+=QString("<tr>%1</td><td colspan=4>%2 / %3</td></tr>")
.arg(tr("EPR")).arg(epr).arg(epr2);
}
html+="</table><hr height=2>";
}
html+="</table>";
{
//}
if (cpap || oxi) {
html+="<table cellpadding=0 cellspacing=0 border=0 width=100%>";
html+="<tr><td colspan=4 align=center>&nbsp;</td></tr>";
html+=QString("<tr><td colspan=4 align=center><b>%1</b></td></tr>").arg(tr("Session Information"));
html+="<tr><td colspan=4 align=center><hr height=2/></td></tr>";
QDateTime fd,ld;
bool corrupted_waveform=false;
QString tooltip;
if (cpap || oxi)
html+=QString("<tr><td align=left><b>%1</b></td><td align=center><b>%2</b></td><td align=center><b>%3</b></td><td align=center><b>%4</b></td></tr>")
.arg(tr("SessionID"))
.arg(tr("Date"))
.arg(tr("Start"))
.arg(tr("End"));
html+=QString("<tr><td align=left><b>%1</b></td><td align=center><b>%2</b></td><td align=center><b>%3</b></td><td align=center><b>%4</b></td></tr>")
.arg(tr("SessionID"))
.arg(tr("Date"))
.arg(tr("Start"))
.arg(tr("End"));
if (cpap) {
html+=QString("<tr><td align=left colspan=4><i>%1</i></td></tr>").arg(tr("CPAP Sessions"));
for (QVector<Session *>::iterator s=cpap->begin();s!=cpap->end();s++) {
@ -984,10 +957,10 @@ void Daily::Load(QDate date)
html+=tmp;
}
}
html+="</table>";
if (corrupted_waveform) {
html+="<hr><div align=center><i>"+tr("One or more waveform record for this session had faulty source data. Some waveform overlay points may not match up correctly.")+"</i></div>";
html+=QString("<tr><td colspan=4 align=center><i>%1</i></td></tr>").arg(tr("One or more waveform record for this session had faulty source data. Some waveform overlay points may not match up correctly."));
}
html+="</table>";
}
html+="</body></html>";
@ -1241,12 +1214,18 @@ Session * Daily::CreateJournalSession(QDate date)
PROFILE.AddMachine(m);
}
Session *sess=new Session(m,0);
QDateTime dt(date,QTime(17,0));
//dt.setDate(date);
//dt.setTime(QTime(17,0)); //5pm to make sure it goes in the right day
sess->set_first(qint64(dt.toTime_t())*1000L);
dt=dt.addSecs(3600);
sess->set_last(qint64(dt.toTime_t())*1000L);
qint64 st,et;
Day *cday=PROFILE.GetDay(date,MT_CPAP);
if (cday) {
st=cday->first();
et=cday->last();
} else {
QDateTime dt(date,QTime(20,0));
st=qint64(dt.toTime_t())*1000L;
et=st+3600000;
}
sess->set_first(st);
sess->set_last(et);
sess->SetChanged(true);
m->AddSession(sess,p_profile);
return sess;
@ -1295,21 +1274,23 @@ void Daily::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
{
Q_UNUSED(column);
QDateTime d;
if (!item->text(1).isEmpty()) {
d=d.fromString(item->text(1),"yyyy-MM-dd HH:mm:ss");
int winsize=PROFILE.general->eventWindowSize()*60;
if (!item->data(0,Qt::UserRole).isNull()) {
qint64 winsize=qint64(PROFILE.general->eventWindowSize())*60000L;
qint64 t=item->data(0,Qt::UserRole).toLongLong();
double st=t-(winsize/2);
double et=t+(winsize/2);
double st=qint64((d.addSecs(-(winsize/2))).toTime_t())*1000L;
double et=qint64((d.addSecs(winsize/2)).toTime_t())*1000L;
gGraph *g=GraphView->findGraph(STR_TR_EventFlags);
if (!g) return;
if (st<g->rmin_x) {
st=g->rmin_x;
et=st+winsize*1000;
et=st+winsize;
}
if (et>g->rmax_x) {
et=g->rmax_x;
st=et-winsize*1000;
st=et-winsize;
}
GraphView->SetXBounds(st,et);
}

View File

@ -240,7 +240,7 @@ private:
*/
void UpdateCalendarDay(QDate date);
/*! \fn UpdateEventsTree(QDate date)
\brief Refreshes the Events tree from the supplied Day object.
\brief Populates the Events tree from the supplied Day object.
\param QTreeWidget * tree
\param Day *
*/

View File

@ -359,8 +359,8 @@ QString htmlHeader()
"</style>"
"</head>"
"<body leftmargin=0 topmargin=0 rightmargin=0>"
"<div align=center>"
"<h2><img src='qrc:/docs/sheep.png' width=100px height=100px>SleepyHead v"+VersionString+" "+ReleaseStatus+"</h2>"
"<div align=center><table cellpadding=3 cellspacing=0 border=0>"
"<tr><td><img src='qrc:/docs/sheep.png' width=100px height=100px><td valign=center align=center><h1>SleepyHead v"+VersionString+" "+ReleaseStatus+"</h1></td></tr></table>"
"<p><i>This page is being redesigned to be more useful... Please send me your ideas on what you'd like to see here :)</i></p>"
"<p>The plan is to get the content happening first, then make the layout pretty...</p>"
"</div>"
@ -532,15 +532,15 @@ void MainWindow::on_summaryButton_clicked()
} else {
ahitxt=tr("AHI");
}
html+="<div align=center>";
html+=QString("<table cellpadding=2 cellspacing=0 border=1 width=90%>");
if (cpapdays==0) {
html+="<p>No Machine Data Imported</p>";
//html+="<tr><td colspan=6>No Machine Data Imported</td></tr>";
} else {
html+="<div align=center>";
html+=QString("<p><b>Key Statistics as of %1</b></p>").arg(lastcpap.toString(Qt::SystemLocaleLongDate));
html+=QString("<table cellpadding=2 cellspacing=0 border=1 width=90%>");
html+=QString("<tr><td colspan=6><b>CPAP Statistics as of %1</b></td></tr>").arg(lastcpap.toString(Qt::SystemLocaleLongDate));
if (cpap_machines.size()>0) {
html+=QString("<tr><td colspan=6><b>%1</b></td></tr>").arg(tr("CPAP Summary"));
// html+=QString("<tr><td colspan=6><b>%1</b></td></tr>").arg(tr("CPAP Summary"));
if (!cpapdays) {
html+=QString("<tr><td colspan=6><b>%1</b></td></tr>").arg(tr("No CPAP data available."));
@ -569,15 +569,14 @@ void MainWindow::on_summaryButton_clicked()
.arg(formatTime(p_profile->calcHours(MT_CPAP,cpapyear,lastcpap)/float(cpapyeardays)));
if (cpapmode<MODE_BIPAP) {
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Average Pressure"))
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP),0,'f',3)
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapweek,lastcpap),0,'f',3)
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpap6month,lastcpap),0,'f',3)
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapyear,lastcpap),0,'f',3);
if (cpapmode>MODE_CPAP) {
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Average Pressure"))
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP),0,'f',3)
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapweek,lastcpap),0,'f',3)
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpap6month,lastcpap),0,'f',3)
.arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapyear,lastcpap),0,'f',3);
} else if (cpapmode>MODE_CPAP) {
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("95% Pressure"))
.arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP),0,'f',3)
@ -585,7 +584,6 @@ void MainWindow::on_summaryButton_clicked()
.arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
.arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpap6month,lastcpap),0,'f',3)
.arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpapyear,lastcpap),0,'f',3);
}
} else {
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Min EPAP"))
@ -633,232 +631,232 @@ void MainWindow::on_summaryButton_clicked()
.arg(p_profile->calcPercentile(CPAP_Leak,0.5,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
.arg(p_profile->calcPercentile(CPAP_Leak,0.5,MT_CPAP,cpap6month,lastcpap),0,'f',3)
.arg(p_profile->calcPercentile(CPAP_Leak,0.5,MT_CPAP,cpapyear,lastcpap),0,'f',3);
html+="<tr><td colspan=6>What about median leak values? 90% Leaks?</td></tr>";
html+="<tr><td colspan=6>Note, AHI calcs here are different to overview calcs.. Overview shows a average of the dialy AHI's, this shows combined counts divide by combined hours</td></tr>";
}
if (oximeters.size()>0) {
QDate lastoxi=p_profile->LastDay(MT_OXIMETER);
QDate firstoxi=p_profile->FirstDay(MT_OXIMETER);
int days=PROFILE.countDays(MT_OXIMETER,firstcpap,lastcpap);
if (days>0) {
html+=QString("<tr><td colspan=6><b>%1</b></td></tr>").arg(tr("Oximetry Summary"));
if (days==1) {
html+=QString("<tr><td colspan=6>%1</td></tr>").arg(QString(tr("%1 day of Oximetry Data, on %2.")).arg(days).arg(firstoxi.toString(Qt::SystemLocaleShortDate)));
} else {
html+=QString("<tr><td colspan=6>%1</td></tr>").arg(QString(tr("%1 days of Oximetry Data, between %2 and %3")).arg(days).arg(firstoxi.toString(Qt::SystemLocaleShortDate)).arg(lastoxi.toString(Qt::SystemLocaleShortDate)));
}
html+=QString("<tr><td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td><td><b>%4</b></td><td><b>%5</b></td><td><b>%6</td></tr>")
.arg(tr("Details")).arg(tr("Most Recent")).arg(tr("Last 7 Days")).arg(tr("Last 30 Days")).arg(tr("Last 6 months")).arg(tr("Last Year"));
QDate oxiweek=lastcpap.addDays(-7);
QDate oximonth=lastcpap.addDays(-30);
QDate oxi6month=lastcpap.addMonths(-6);
QDate oxiyear=lastcpap.addYears(-12);
if (oxiweek<firstoxi) oxiweek=firstoxi;
if (oximonth<firstoxi) oximonth=firstoxi;
if (oxi6month<firstoxi) oxi6month=firstoxi;
if (oxiyear<firstoxi) oxiyear=firstoxi;
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Average SpO2"))
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Minimum SpO2"))
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("SpO2 Events / Hour"))
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER)/p_profile->calcHours(MT_OXIMETER),0,'f',3)
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxiweek,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oximonth,lastoxi)/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxi6month,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxiyear,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2\%</td><td>%3\%</td><td>%4\%</td><td>%5\%</td><td>%6\%</td></tr>")
.arg(tr("% of time in SpO2 Events"))
.arg(100.0/p_profile->calcHours(MT_OXIMETER)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER)/3600.0,0,'f',3)
.arg(100.0/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxiweek,lastoxi)/3600.0,0,'f',3)
.arg(100.0/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oximonth,lastoxi)/3600.0,0,'f',3)
.arg(100.0/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxi6month,lastoxi)/3600.0,0,'f',3)
.arg(100.0/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxiyear,lastoxi)/3600.0,0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Average Pulse Rate"))
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Minimum Pulse Rate"))
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Maximum Pulse Rate"))
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
}
}
html+="</table>";
html+="</div>";
if (cpap_machines.size()>0) {
QDate first,last=lastcpap;
CPAPMode mode,cmode=MODE_UNKNOWN;
EventDataType cmin=0,cmax=0,min,max;
QDate date=lastcpap;
Day * day;
bool lastchanged;
int cnt=0;
QVector<RXChange> rxchange;
do {
day=PROFILE.GetDay(date,MT_CPAP);
lastchanged=false;
if (day) {
mode=(CPAPMode)round(day->settings_wavg(CPAP_Mode));
min=day->settings_min(CPAP_PressureMin);
if (mode==MODE_CPAP) {
max=day->settings_max(CPAP_PressureMin);
} else max=day->settings_max(CPAP_PressureMax);
if ((mode!=cmode) || (min!=cmin) || (max!=cmax)) {
if (cmode!=MODE_UNKNOWN) {
first=date.addDays(1);
int days=PROFILE.countDays(MT_CPAP,first,last);
RXChange rx;
rx.first=first;
rx.last=last;
rx.days=days;
rx.ahi=calcAHI(first,last);
rx.mode=cmode;
rx.min=cmin;
rx.max=cmax;
if (mode<MODE_BIPAP) {
rx.per1=p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,first,last);
rx.per2=0;
} else {
rx.per1=p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,first,last);
rx.per2=p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,first,last);
}
rx.weighted=float(rx.days)/float(cpapdays)*rx.ahi;
rxchange.push_back(rx);
}
cmode=mode;
cmin=min;
cmax=max;
last=date;
lastchanged=true;
}
}
date=date.addDays(-1);
} while (date>=firstcpap);
if (!lastchanged) {
last=date.addDays(1);
first=firstcpap;
int days=PROFILE.countDays(MT_CPAP,first,last);
RXChange rx;
rx.first=first;
rx.last=last;
rx.days=days;
rx.ahi=calcAHI(first,last);
rx.mode=mode;
rx.min=min;
rx.max=max;
if (mode<MODE_BIPAP) {
rx.per1=p_profile->calcPercentile(CPAP_Pressure,0.9,MT_CPAP,first,last);
rx.per2=0;
} else {
rx.per1=p_profile->calcPercentile(CPAP_EPAP,0.9,MT_CPAP,first,last);
rx.per2=p_profile->calcPercentile(CPAP_IPAP,0.9,MT_CPAP,first,last);
}
rx.weighted=float(rx.days)/float(cpapdays);
//rx.weighted=float(days)*rx.ahi;
rxchange.push_back(rx);
}
QVector<RXChange *> tmpRX;
for (int i=0;i<rxchange.size();i++) {
RXChange & rx=rxchange[i];
if (rx.days>5)
tmpRX.push_back(&rx);
}
RXsort=RX_ahi;
qSort(tmpRX.begin(),tmpRX.end(),RXSort);
tmpRX[0]->highlight=4; // worst
tmpRX[tmpRX.size()-1]->highlight=1; //best
// show the second best and worst..
// if (tmpRX.size()>4) {
// tmpRX[1]->highlight=3; // worst
// tmpRX[tmpRX.size()-2]->highlight=2; //best
// }
//RXsort=RX_first;
//qSort(rxchange);
html+="<div align=center>";
html+=QString("<br/><b>Changes to Prescription Settings</b>");
html+=QString("<table cellpadding=2 cellspacing=0 border=1 width=90%>");
QString extratxt;
if (cpapmode>=MODE_BIPAP) {
extratxt=QString("<td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td><td><b>%4</b></td>")
.arg(tr("EPAP")).arg(tr("EPAP")).arg(tr("%1% EPAP").arg(percentile*100.0)).arg(tr("%1% IPAP").arg(percentile*100.0));
} else if (cpapmode>MODE_CPAP) {
extratxt=QString("<td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td>")
.arg(tr("Min Pressure")).arg(tr("Max Pressure")).arg(tr("%1% Pressure").arg(percentile*100.0));
}
int oxisize=oximeters.size();
if (oxisize>0) {
QDate lastoxi=p_profile->LastDay(MT_OXIMETER);
QDate firstoxi=p_profile->FirstDay(MT_OXIMETER);
int days=PROFILE.countDays(MT_OXIMETER,firstoxi,lastoxi);
if (days>0) {
html+=QString("<tr><td colspan=6><b>%1</b></td></tr>").arg(tr("Oximetry Summary"));
if (days==1) {
html+=QString("<tr><td colspan=6>%1</td></tr>").arg(QString(tr("%1 day of Oximetry Data, on %2.")).arg(days).arg(firstoxi.toString(Qt::SystemLocaleShortDate)));
} else {
extratxt=QString("<td><b>%1</b></td>")
.arg(tr("Pressure"));
html+=QString("<tr><td colspan=6>%1</td></tr>").arg(QString(tr("%1 days of Oximetry Data, between %2 and %3")).arg(days).arg(firstoxi.toString(Qt::SystemLocaleShortDate)).arg(lastoxi.toString(Qt::SystemLocaleShortDate)));
}
html+=QString("<tr><td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td><td><b>%4</b></td><td><b>%5</b></td>%6</tr>")
.arg(tr("First"))
.arg(tr("Last"))
.arg(tr("Days"))
.arg(ahitxt)
.arg(tr("Mode"))
.arg(extratxt);
for (int i=0;i<rxchange.size();i++) {
RXChange rx=rxchange.at(i);
QString color;
if (rx.highlight==1) {
color=" bgcolor='#c0ffc0'";
} else if (rx.highlight==2) {
color=" bgcolor='#e0ffe0'";
} else if (rx.highlight==3) {
color=" bgcolor='#ffe0e0'";
} else if (rx.highlight==4) {
color=" bgcolor='#ffc0c0'";
} else color="";
if (cpapmode>=MODE_BIPAP) {
extratxt=QString("<td>%1</td><td>%2</td><td>%3</td>").arg(rx.max,0,'f',2).arg(rx.per1,0,'f',2).arg(rx.per2,0,'f',2);
} else if (cpapmode>MODE_CPAP) {
extratxt=QString("<td>%1</td><td>%2</td>").arg(rx.max,0,'f',2).arg(rx.per1,0,'f',2);
} else extratxt="";
html+=QString("<tr"+color+"><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td>%7</tr>")
.arg(rx.first.toString(Qt::SystemLocaleShortDate))
.arg(rx.last.toString(Qt::SystemLocaleShortDate))
.arg(rx.days)
.arg(rx.ahi,0,'f',2)
.arg(schema::channel[CPAP_Mode].option(int(rx.mode)-1))
.arg(rx.min,0,'f',2)
.arg(extratxt);
}
html+="</table>";
html+="<i>The above has a threshold which excludes day counts less than it from the best/worst highlighting</i><br/>";
html+="</div>";
html+=QString("<tr><td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td><td><b>%4</b></td><td><b>%5</b></td><td><b>%6</td></tr>")
.arg(tr("Details")).arg(tr("Most Recent")).arg(tr("Last 7 Days")).arg(tr("Last 30 Days")).arg(tr("Last 6 months")).arg(tr("Last Year"));
QDate oxiweek=lastoxi.addDays(-7);
QDate oximonth=lastoxi.addDays(-30);
QDate oxi6month=lastoxi.addMonths(-6);
QDate oxiyear=lastoxi.addYears(-12);
if (oxiweek<firstoxi) oxiweek=firstoxi;
if (oximonth<firstoxi) oximonth=firstoxi;
if (oxi6month<firstoxi) oxi6month=firstoxi;
if (oxiyear<firstoxi) oxiyear=firstoxi;
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Average SpO2"))
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Minimum SpO2"))
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("SpO2 Events / Hour"))
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER)/p_profile->calcHours(MT_OXIMETER),0,'f',3)
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxiweek,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oximonth,lastoxi)/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxi6month,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxiyear,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2\%</td><td>%3\%</td><td>%4\%</td><td>%5\%</td><td>%6\%</td></tr>")
.arg(tr("% of time in SpO2 Events"))
.arg(100.0/p_profile->calcHours(MT_OXIMETER)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER)/3600.0,0,'f',3)
.arg(100.0/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxiweek,lastoxi)/3600.0,0,'f',3)
.arg(100.0/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oximonth,lastoxi)/3600.0,0,'f',3)
.arg(100.0/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxi6month,lastoxi)/3600.0,0,'f',3)
.arg(100.0/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxiyear,lastoxi)/3600.0,0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Average Pulse Rate"))
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Minimum Pulse Rate"))
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
.arg(tr("Maximum Pulse Rate"))
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER),0,'f',3)
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
.arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
}
}
html+="</table>";
html+="</div>";
if (cpapdays>0) {
QDate first,last=lastcpap;
CPAPMode mode,cmode=MODE_UNKNOWN;
EventDataType cmin=0,cmax=0,min,max;
QDate date=lastcpap;
Day * day;
bool lastchanged;
int cnt=0;
QVector<RXChange> rxchange;
do {
day=PROFILE.GetDay(date,MT_CPAP);
lastchanged=false;
if (day) {
mode=(CPAPMode)round(day->settings_wavg(CPAP_Mode));
min=day->settings_min(CPAP_PressureMin);
if (mode==MODE_CPAP) {
max=day->settings_max(CPAP_PressureMin);
} else max=day->settings_max(CPAP_PressureMax);
if ((mode!=cmode) || (min!=cmin) || (max!=cmax)) {
if (cmode!=MODE_UNKNOWN) {
first=date.addDays(1);
int days=PROFILE.countDays(MT_CPAP,first,last);
RXChange rx;
rx.first=first;
rx.last=last;
rx.days=days;
rx.ahi=calcAHI(first,last);
rx.mode=cmode;
rx.min=cmin;
rx.max=cmax;
if (mode<MODE_BIPAP) {
rx.per1=p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,first,last);
rx.per2=0;
} else {
rx.per1=p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,first,last);
rx.per2=p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,first,last);
}
rx.weighted=float(rx.days)/float(cpapdays)*rx.ahi;
rxchange.push_back(rx);
}
cmode=mode;
cmin=min;
cmax=max;
last=date;
lastchanged=true;
}
}
date=date.addDays(-1);
} while (date>=firstcpap);
if (!lastchanged) {
last=date.addDays(1);
first=firstcpap;
int days=PROFILE.countDays(MT_CPAP,first,last);
RXChange rx;
rx.first=first;
rx.last=last;
rx.days=days;
rx.ahi=calcAHI(first,last);
rx.mode=mode;
rx.min=min;
rx.max=max;
if (mode<MODE_BIPAP) {
rx.per1=p_profile->calcPercentile(CPAP_Pressure,0.9,MT_CPAP,first,last);
rx.per2=0;
} else {
rx.per1=p_profile->calcPercentile(CPAP_EPAP,0.9,MT_CPAP,first,last);
rx.per2=p_profile->calcPercentile(CPAP_IPAP,0.9,MT_CPAP,first,last);
}
rx.weighted=float(rx.days)/float(cpapdays);
//rx.weighted=float(days)*rx.ahi;
rxchange.push_back(rx);
}
QVector<RXChange *> tmpRX;
for (int i=0;i<rxchange.size();i++) {
RXChange & rx=rxchange[i];
if (rx.days>5)
tmpRX.push_back(&rx);
}
RXsort=RX_ahi;
qSort(tmpRX.begin(),tmpRX.end(),RXSort);
tmpRX[0]->highlight=4; // worst
tmpRX[tmpRX.size()-1]->highlight=1; //best
//show the second best and worst..
//if (tmpRX.size()>4) {
// tmpRX[1]->highlight=3; // worst
// tmpRX[tmpRX.size()-2]->highlight=2; //best
// }
//RXsort=RX_first;
//qSort(rxchange);
html+="<div align=center>";
html+=QString("<br/><b>Changes to Prescription Settings</b>");
html+=QString("<table cellpadding=2 cellspacing=0 border=1 width=90%>");
QString extratxt;
if (cpapmode>=MODE_BIPAP) {
extratxt=QString("<td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td><td><b>%4</b></td>")
.arg(tr("EPAP")).arg(tr("EPAP")).arg(tr("%1% EPAP").arg(percentile*100.0)).arg(tr("%1% IPAP").arg(percentile*100.0));
} else if (cpapmode>MODE_CPAP) {
extratxt=QString("<td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td>")
.arg(tr("Min Pressure")).arg(tr("Max Pressure")).arg(tr("%1% Pressure").arg(percentile*100.0));
} else {
extratxt=QString("<td><b>%1</b></td>")
.arg(tr("Pressure"));
}
html+=QString("<tr><td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td><td><b>%4</b></td><td><b>%5</b></td>%6</tr>")
.arg(tr("First"))
.arg(tr("Last"))
.arg(tr("Days"))
.arg(ahitxt)
.arg(tr("Mode"))
.arg(extratxt);
for (int i=0;i<rxchange.size();i++) {
RXChange rx=rxchange.at(i);
QString color;
if (rx.highlight==1) {
color=" bgcolor='#c0ffc0'";
} else if (rx.highlight==2) {
color=" bgcolor='#e0ffe0'";
} else if (rx.highlight==3) {
color=" bgcolor='#ffe0e0'";
} else if (rx.highlight==4) {
color=" bgcolor='#ffc0c0'";
} else color="";
if (cpapmode>=MODE_BIPAP) {
extratxt=QString("<td>%1</td><td>%2</td><td>%3</td>").arg(rx.max,0,'f',2).arg(rx.per1,0,'f',2).arg(rx.per2,0,'f',2);
} else if (cpapmode>MODE_CPAP) {
extratxt=QString("<td>%1</td><td>%2</td>").arg(rx.max,0,'f',2).arg(rx.per1,0,'f',2);
} else extratxt="";
html+=QString("<tr"+color+"><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td>%7</tr>")
.arg(rx.first.toString(Qt::SystemLocaleShortDate))
.arg(rx.last.toString(Qt::SystemLocaleShortDate))
.arg(rx.days)
.arg(rx.ahi,0,'f',2)
.arg(schema::channel[CPAP_Mode].option(int(rx.mode)-1))
.arg(rx.min,0,'f',2)
.arg(extratxt);
}
html+="</table>";
html+="<i>The above has a threshold which excludes day counts less than it from the best/worst highlighting</i><br/>";
html+="</div>";
}
if (mach.size()>0) {
@ -1270,10 +1268,12 @@ void MainWindow::PrintReport(gGraphView *gv,QString name, QDate date)
painter.drawText(bounds,userinfo,QTextOption(Qt::AlignLeft | Qt::AlignTop));
if (bounds.height()>maxy) maxy=bounds.height();
}
Day *cpap=NULL, *oxi=NULL;
int graph_slots=0;
if (name==STR_TR_Daily) {
Day *cpap=PROFILE.GetDay(date,MT_CPAP);
cpap=PROFILE.GetDay(date,MT_CPAP);
oxi=PROFILE.GetDay(date,MT_OXIMETER);
QString cpapinfo=date.toString(Qt::SystemLocaleLongDate)+"\n\n";
if (cpap) {
time_t f=cpap->first()/1000L;
@ -1317,22 +1317,11 @@ void MainWindow::PrintReport(gGraphView *gv,QString name, QDate date)
float lki=cpap->count(CPAP_LeakFlag)/cpap->hours();
float exp=cpap->count(CPAP_ExP)/cpap->hours();
int piesize=(2048.0/8.0)*1.4; // 1.5" in size
int piesize=(2048.0/8.0)*1.3; // 1.5" in size
//float fscale=font_scale;
//if (!highres)
// fscale=1;
getDaily()->eventBreakdownPie()->showTitle(false);
getDaily()->eventBreakdownPie()->setMargins(0,0,0,0);
QPixmap ebp;
if (ahi>0) {
ebp=getDaily()->eventBreakdownPie()->renderPixmap(piesize,piesize,1);
} else {
ebp=QPixmap::fromImage(*images["smiley"]);
}
painter.drawPixmap(virt_width-piesize,bounds.height()/2,piesize,piesize,ebp);
getDaily()->eventBreakdownPie()->showTitle(true);
QString stats;
painter.setFont(medium_font);
if (PROFILE.general->calculateRDI())
@ -1342,6 +1331,18 @@ void MainWindow::PrintReport(gGraphView *gv,QString name, QDate date)
QRectF bounds=painter.boundingRect(QRectF(0,0,virt_width,0),stats,QTextOption(Qt::AlignRight));
painter.drawText(bounds,stats,QTextOption(Qt::AlignRight));
getDaily()->eventBreakdownPie()->setShowTitle(false);
getDaily()->eventBreakdownPie()->setMargins(0,0,0,0);
QPixmap ebp;
if (ahi>0) {
ebp=getDaily()->eventBreakdownPie()->renderPixmap(piesize,piesize,true);
} else {
ebp=QPixmap(":/icons/smileyface.png");
}
painter.drawPixmap(virt_width-piesize,bounds.height(),piesize,piesize,ebp);
getDaily()->eventBreakdownPie()->setShowTitle(true);
cpapinfo+="\n\n";
painter.setFont(report_font);
@ -1396,88 +1397,114 @@ void MainWindow::PrintReport(gGraphView *gv,QString name, QDate date)
QStringList labels;
QVector<gGraph *> graphs;
QVector<qint64> start,end;
qint64 st,et;
gv->GetXBounds(st,et);
qint64 savest,saveet;
gv->GetXBounds(savest,saveet);
qint64 st=savest,et=saveet;
gGraph *g;
if (!print_bookmarks) {
if (name==STR_TR_Daily) {
if (!print_bookmarks) {
for (int i=0;i<gv->size();i++) {
gGraph *g=(*gv)[i];
if (g->isEmpty()) continue;
if (!g->visible()) continue;
if (cpap) {
st=cpap->first();
et=cpap->last();
} else if (oxi) {
st=oxi->first();
et=oxi->last();
}
if (g->title()==STR_TR_FlowRate) {
if (!((qAbs(savest-st)<2000) && (qAbs(saveet-et)<2000))) {
start.push_back(st);
end.push_back(et);
graphs.push_back(g);
labels.push_back(tr("Entire Day's Flow Waveform"));
}
}
start.push_back(savest);
end.push_back(saveet);
graphs.push_back(g);
labels.push_back("");
}
} else {
if (journal) {
if (journal->settings.contains(Bookmark_Start)) {
QVariantList st1=journal->settings[Bookmark_Start].toList();
QVariantList et1=journal->settings[Bookmark_End].toList();
QStringList notes=journal->settings[Bookmark_Notes].toStringList();
gGraph *flow=gv->findGraph(STR_TR_FlowRate),
*spo2=gv->findGraph(STR_TR_SpO2),
*pulse=gv->findGraph(STR_TR_PulseRate);
if (cpap && flow && !flow->isEmpty() && flow->visible()) {
labels.push_back("Entire Day");
start.push_back(cpap->first());
end.push_back(cpap->last());
graphs.push_back(flow);
}
if (oxi && spo2 && !spo2->isEmpty() && spo2->visible()) {
labels.push_back("Entire Day");
start.push_back(oxi->first());
end.push_back(oxi->last());
graphs.push_back(spo2);
}
if (oxi && pulse && !pulse->isEmpty() && pulse->visible()) {
labels.push_back("Entire Day");
start.push_back(oxi->first());
end.push_back(oxi->last());
graphs.push_back(pulse);
}
for (int i=0;i<notes.size();i++) {
if (flow && !flow->isEmpty() && flow->visible()) {
labels.push_back(notes.at(i));
start.push_back(st1.at(i).toLongLong());
end.push_back(et1.at(i).toLongLong());
graphs.push_back(flow);
}
if (spo2 && !spo2->isEmpty() && spo2->visible()) {
labels.push_back(notes.at(i));
start.push_back(st1.at(i).toLongLong());
end.push_back(et1.at(i).toLongLong());
graphs.push_back(spo2);
}
if (pulse && !pulse->isEmpty() && pulse->visible()) {
labels.push_back(notes.at(i));
start.push_back(st1.at(i).toLongLong());
end.push_back(et1.at(i).toLongLong());
graphs.push_back(pulse);
}
}
}
}
for (int i=0;i<gv->size();i++) {
gGraph *g=(*gv)[i];
if (g->isEmpty()) continue;
if (!g->visible()) continue;
if ((g->title()!=STR_TR_FlowRate ) && (g->title()!=STR_TR_SpO2) && (g->title()!=STR_TR_PulseRate)) {
start.push_back(st);
end.push_back(et);
graphs.push_back(g);
labels.push_back(tr(""));
}
}
}
} else {
for (int i=0;i<gv->size();i++) {
gGraph *g=(*gv)[i];
if (g->isEmpty()) continue;
if (!g->visible()) continue;
start.push_back(st);
end.push_back(et);
graphs.push_back(g);
labels.push_back("");
//labels.push_back(tr("Current Selection"));
}
} else {
if ((g=gv->findGraph(tr("Event Flags")))!=NULL) {
if ((!g->isEmpty()) && (g->visible())) {
start.push_back(st);
start.push_back(et);
graphs.push_back(g);
labels.push_back("");
}
}
if (journal) {
if (journal->settings.contains(Bookmark_Start)) {
QVariantList st1=journal->settings[Bookmark_Start].toList();
QVariantList et1=journal->settings[Bookmark_End].toList();
QStringList notes=journal->settings[Bookmark_Notes].toStringList();
gGraph *flow=gv->findGraph(tr("Flow Rate")),
*spo2=gv->findGraph(tr("SpO2")),
*pulse=gv->findGraph(tr("Pulse"));
if (flow && !flow->isEmpty() && flow->visible()) {
labels.push_back("");
start.push_back(st);
end.push_back(et);
graphs.push_back(flow);
}
if (spo2 && !spo2->isEmpty() && spo2->visible()) {
labels.push_back("");
start.push_back(st);
end.push_back(et);
graphs.push_back(spo2);
}
if (pulse && !pulse->isEmpty() && pulse->visible()) {
labels.push_back("");
start.push_back(st);
end.push_back(et);
graphs.push_back(pulse);
}
for (int i=0;i<notes.size();i++) {
if (flow && !flow->isEmpty() && flow->visible()) {
labels.push_back(notes.at(i));
start.push_back(st1.at(i).toLongLong());
end.push_back(et1.at(i).toLongLong());
graphs.push_back(flow);
}
if (spo2 && !spo2->isEmpty() && spo2->visible()) {
labels.push_back(notes.at(i));
start.push_back(st1.at(i).toLongLong());
end.push_back(et1.at(i).toLongLong());
graphs.push_back(spo2);
}
if (pulse && !pulse->isEmpty() && pulse->visible()) {
labels.push_back(notes.at(i));
start.push_back(st1.at(i).toLongLong());
end.push_back(et1.at(i).toLongLong());
graphs.push_back(pulse);
}
}
}
}
for (int i=0;i<gv->size();i++) {
gGraph *g=(*gv)[i];
if (g->isEmpty()) continue;
if (!g->visible()) continue;
if ((g->title()!=tr("Flow Rate")) && (g->title()!=tr("SpO2")) && (g->title()!=tr("Pulse"))) {
start.push_back(st);
end.push_back(et);
graphs.push_back(g);
labels.push_back(tr(""));
}
labels.push_back(""); // date range?
}
}
int pages=ceil(float(graphs.size()+graph_slots)/float(graphs_per_page));
@ -1552,6 +1579,7 @@ void MainWindow::PrintReport(gGraphView *gv,QString name, QDate date)
}
}
gv->SetXBounds(savest,saveet);
qprogress->hide();
painter.end();
delete printer;
@ -1798,3 +1826,7 @@ void MainWindow::on_actionAll_Data_for_current_CPAP_machine_triggered()
}
}
void MainWindow::keyPressEvent(QKeyEvent * event)
{
qDebug() << "Keypress:" << event->key();
}

View File

@ -125,6 +125,8 @@ public:
\param QDate date
*/
void PrintReport(gGraphView *gv,QString name, QDate date=QDate::currentDate());
protected:
virtual void keyPressEvent(QKeyEvent * event);
private slots:
/*! \fn void on_action_Import_Data_triggered();
@ -240,6 +242,8 @@ private slots:
void on_summaryButton_clicked();
private:
Ui::MainWindow *ui;

View File

@ -109,7 +109,7 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
PTB=createGraph(tr("Pat. Trig. Br."),tr("Patient\nTriggered\nBreaths\n(%)"));
SES=createGraph(tr("Sessions"),tr("Sessions\n(count)"));
PULSE=createGraph(tr("Pulse Rate"),tr("Pulse Rate\n(bpm)"));
SPO2=createGraph(tr("SpO2"),tr("Oxygen Saturation\n(%)"));
SPO2=createGraph(STR_TR_SpO2,tr("Oxygen Saturation\n(%)"));
WEIGHT=createGraph(STR_TR_Weight,STR_TR_Weight,YT_Weight);
BMI=createGraph(STR_TR_BMI,tr("Body\nMass\nIndex"));
@ -142,7 +142,7 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
pulse->addSlice(OXI_Pulse,QColor("orange"),ST_MAX,true);
PULSE->AddLayer(pulse);
spo2=new SummaryChart(tr("SpO2"),GT_LINE);
spo2=new SummaryChart(STR_TR_SpO2,GT_LINE);
spo2->setMachineType(MT_OXIMETER);
spo2->addSlice(OXI_SPO2,QColor("cyan"),ST_WAVG,true);
spo2->addSlice(OXI_SPO2,QColor("light blue"),ST_90P,true);
@ -213,16 +213,24 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
pr=new SummaryChart(STR_UNIT_CMH2O,GT_LINE);
//PR->setRecMinY(4.0);
//PR->setRecMaxY(12.0);
pr->addSlice(CPAP_Pressure,QColor("dark green"),ST_WAVG,true);
pr->addSlice(CPAP_Pressure,QColor("orange"),ST_MIN,true);
pr->addSlice(CPAP_Pressure,QColor("red"),ST_MAX,true);
//pr->addSlice(CPAP_Pressure,QColor("grey"),ST_90P,true);
pr->addSlice(CPAP_Pressure,QColor("grey"),ST_PERC,true,0.95);
pr->addSlice(CPAP_EPAP,QColor("green"),ST_MIN,true);
pr->addSlice(CPAP_EPAP,QColor("light green"),ST_90P,true);
pr->addSlice(CPAP_IPAP,QColor("blue"),ST_MAX,true);
pr->addSlice(CPAP_IPAP,QColor("light blue"),ST_90P,true);
CPAPMode mode=(CPAPMode)(int)PROFILE.calcSettingsMax(CPAP_Mode,MT_CPAP,PROFILE.FirstDay(MT_CPAP),PROFILE.LastDay(MT_CPAP));
if (mode>=MODE_BIPAP) {
pr->addSlice(CPAP_EPAP,QColor("green"),ST_MIN,true);
pr->addSlice(CPAP_EPAP,QColor("light green"),ST_90P,true);
pr->addSlice(CPAP_IPAP,QColor("blue"),ST_MAX,true);
pr->addSlice(CPAP_IPAP,QColor("light blue"),ST_90P,true);
} else if (mode>MODE_CPAP) {
pr->addSlice(CPAP_Pressure,QColor("dark green"),ST_WAVG,true);
pr->addSlice(CPAP_Pressure,QColor("orange"),ST_MIN,true);
pr->addSlice(CPAP_Pressure,QColor("red"),ST_MAX,true);
//pr->addSlice(CPAP_Pressure,QColor("grey"),ST_90P,true);
pr->addSlice(CPAP_Pressure,QColor("grey"),ST_PERC,true,0.95);
} else {
pr->addSlice(CPAP_PressureMin,QColor("grey"),ST_SETWAVG,true);
}
PR->AddLayer(pr);
lk=new SummaryChart(tr("Avg Leak"),GT_LINE);

View File

@ -247,6 +247,12 @@ void SerialOximeter::addSpO2(qint64 time, EventDataType o2)
void SerialOximeter::addPlethy(qint64 time, EventDataType pleth)
{
if (!plethy) {
plethy=new EventList(EVL_Event);
session->eventlist[OXI_Plethy].push_back(plethy);
session->setFirst(OXI_Plethy,lasttime);
plethy->setFirst(lasttime);
}
plethy->AddEvent(time,pleth);
session->setCount(OXI_Plethy,plethy->count()); // update the cache
session->setMin(OXI_Plethy,plethy->Min());
@ -375,18 +381,15 @@ Session *SerialOximeter::createSession(QDateTime date)
session->set_first(lasttime);
pulse=new EventList(EVL_Event);
spo2=new EventList(EVL_Event);
plethy=new EventList(EVL_Event);
plethy=NULL;
session->eventlist[OXI_Pulse].push_back(pulse);
session->eventlist[OXI_SPO2].push_back(spo2);
session->eventlist[OXI_Plethy].push_back(plethy);
session->setFirst(OXI_Pulse,lasttime);
session->setFirst(OXI_SPO2,lasttime);
session->setFirst(OXI_Plethy,lasttime);
pulse->setFirst(lasttime);
spo2->setFirst(lasttime);
plethy->setFirst(lasttime);
m_callbacks=0;

View File

@ -318,15 +318,15 @@ void PreferencesDialog::Save()
profile->oxi->setSyncOximetry(ui->oximetrySync->isChecked());
int oxigrp=ui->oximetrySync->isChecked() ? 0 : 1;
gGraphView *gv=mainwin->getDaily()->graphView();
gGraph *g=gv->findGraph(tr("Pulse"));
gGraph *g=gv->findGraph(STR_TR_PulseRate);
if (g) {
g->setGroup(oxigrp);
}
g=gv->findGraph(tr("SpO2"));
g=gv->findGraph(STR_TR_SpO2);
if (g) {
g->setGroup(oxigrp);
}
g=gv->findGraph(tr("Plethy"));
g=gv->findGraph(STR_TR_Plethy);
if (g) {
g->setGroup(oxigrp);
}