Initial Multi-Profile stuff.

This commit is contained in:
Mark Watkins 2011-10-01 22:54:20 +10:00
parent aa43837d52
commit b147d33beb
19 changed files with 1218 additions and 59 deletions

View File

@ -67,6 +67,48 @@ GLBuffer::~GLBuffer()
}
///////
void GLShortBuffer::add(GLshort x, GLshort y)
{
if (m_cnt<m_max+2) {
mutex.lock();
buffer[m_cnt++]=x;
buffer[m_cnt++]=y;
mutex.unlock();
} else {
qDebug() << "GLBuffer overflow";
}
}
void GLShortBuffer::add(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
{
if (m_cnt<m_max+4) {
mutex.lock();
buffer[m_cnt++]=x1;
buffer[m_cnt++]=y1;
buffer[m_cnt++]=x2;
buffer[m_cnt++]=y2;
mutex.unlock();
} else {
qDebug() << "GLBuffer overflow";
}
}
void GLShortBuffer::add(GLshort x1, GLshort y1, GLshort x2, GLshort y2,GLshort x3, GLshort y3, GLshort x4, GLshort y4)
{
if (m_cnt<m_max+8) {
mutex.lock();
buffer[m_cnt++]=x1;
buffer[m_cnt++]=y1;
buffer[m_cnt++]=x2;
buffer[m_cnt++]=y2;
buffer[m_cnt++]=x3;
buffer[m_cnt++]=y3;
buffer[m_cnt++]=x4;
buffer[m_cnt++]=y4;
mutex.unlock();
} else {
qDebug() << "GLBuffer overflow";
}
}
GLShortBuffer::GLShortBuffer(int max,int type)
:GLBuffer(max,type)
{
@ -180,14 +222,19 @@ void GLShortBuffer::draw()
glVertexPointer(2, GL_SHORT, 0, buffer);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
if (m_colcnt>0) {
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
glEnableClientState(GL_COLOR_ARRAY);
} else {
glColor4ub(m_color.red(),m_color.green(),m_color.blue(),m_color.alpha());
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(m_type, 0, m_cnt >> 1);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
if (m_colcnt>0) {
glDisableClientState(GL_COLOR_ARRAY);
}
//qDebug() << "I Drawed" << m_cnt << "vertices";
m_cnt=0;

View File

@ -46,11 +46,13 @@ public:
void setSize(float f) { m_size=f; }
void setAntiAlias(bool b) { m_antialias=b; }
void forceAntiAlias(bool b) { m_forceantialias=b; }
void setColor(QColor col) { m_color=col; }
protected:
int m_max;
int m_type; // type (GL_LINES, GL_QUADS, etc)
int m_cnt; // cnt
int m_colcnt;
QColor m_color;
float m_size;
int s1,s2,s3,s4;
bool m_scissor;
@ -64,10 +66,14 @@ class GLShortBuffer:public GLBuffer
public:
GLShortBuffer(int max=2048,int type=GL_LINES);
virtual ~GLShortBuffer();
//void add(GLshort s);
//void add(GLshort x, GLshort y);
//void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
// use one or the other.. can't use both
// color free version is faster
void add(GLshort x, GLshort y);
void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2, GLshort x3, GLshort y3, GLshort x4, GLshort y4);
// color per vertex version
void add(GLshort x, GLshort y,QColor & col); // add with vertex color
void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2,QColor & col); // add with vertex colors
void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2,GLshort x3, GLshort y3, GLshort x4, GLshort y4,QColor & col); // add with vertex colors

View File

@ -17,7 +17,7 @@ gLineChart::gLineChart(ChannelID code,QColor col,bool square_plot, bool disable_
m_line_color=col;
m_report_empty=false;
addGLBuf(lines=new GLShortBuffer(100000,GL_LINES));
lines->setColor(col);
lines->setAntiAlias(true);
}
gLineChart::~gLineChart()
@ -328,7 +328,7 @@ void gLineChart::paint(gGraph & w,int left, int top, int width, int height)
// ay1=(m_drawlist[i-1].y()+m_drawlist[i].y()+m_drawlist[i+1].y())/3.0;
ax1=m_drawlist[i].x();
ay1=m_drawlist[i].y();
lines->add(xst+i,yst-ax1,xst+i,yst-ay1,m_line_color);
lines->add(xst+i,yst-ax1,xst+i,yst-ay1);
if (lines->full()) break;
}
@ -357,7 +357,7 @@ void gLineChart::paint(gGraph & w,int left, int top, int width, int height)
firstpx=false;
continue;
}
lines->add(lastpx,lastpy,px,py,m_line_color);
lines->add(lastpx,lastpy,px,py);
if (lines->full()) {
done=true;
@ -401,10 +401,9 @@ void gLineChart::paint(gGraph & w,int left, int top, int width, int height)
firstpx=false;
} else {
if (square_plot) {
lines->add(lastpx,lastpy,px,lastpy,m_line_color);
lines->add(px,lastpy,px,py,m_line_color);
lines->add(lastpx,lastpy,px,lastpy,px,lastpy,px,py);
} else {
lines->add(lastpx,lastpy,px,py,m_line_color);
lines->add(lastpx,lastpy,px,py);
}
//lines->add(px,py,m_line_color);

View File

@ -13,10 +13,12 @@ gLineOverlayBar::gLineOverlayBar(ChannelID code,QColor color,QString label,FlagT
{
addGLBuf(points=new GLShortBuffer(1024,GL_POINTS));
points->setSize(4);
points->setColor(m_flag_color);
addGLBuf(quads=new GLShortBuffer(2048,GL_QUADS));
//addGLBuf(lines=new GLBuffer(color,1024,GL_LINES));
points->setAntiAlias(true);
quads->setAntiAlias(true);
quads->setColor(m_flag_color);
//lines->setAntiAlias(true);
}
gLineOverlayBar::~gLineOverlayBar()
@ -78,12 +80,12 @@ void gLineOverlayBar::paint(gGraph & w, int left, int topp, int width, int heigh
if (x2<left) x2=left;
if (x1>width+left) x1=width+left;
//double w1=x2-x1;
quads->add(x1,start_py,x2,start_py,x2,start_py+height,x1,start_py+height,m_flag_color);
quads->add(x1,start_py,x2,start_py,x2,start_py+height,x1,start_py+height);
if (quads->full()) { verts_exceeded=true; break; }
} else if (m_flt==FT_Dot) {
if ((pref["AlwaysShowOverlayBars"].toInt()==0) || (xx<3600000)) {
// show the fat dots in the middle
points->add(x1,double(height)/double(yy)*double(-20-w.min_y)+topp,m_flag_color);
points->add(x1,double(height)/double(yy)*double(-20-w.min_y)+topp);
if (points->full()) { verts_exceeded=true; break; }
} else {
// thin lines down the bottom
@ -96,7 +98,7 @@ void gLineOverlayBar::paint(gGraph & w, int left, int topp, int width, int heigh
if ((pref["AlwaysShowOverlayBars"].toInt()==0) || (xx<3600000)) {
z=top;
points->add(x1,top,m_flag_color);
points->add(x1,top);
lines->add(x1,top,x1,bottom,m_flag_color);
if (points->full()) { verts_exceeded=true; break; }
} else {

View File

@ -40,7 +40,7 @@ Machine::Machine(Profile *p,MachineID id)
m_id=temp;
} else m_id=id;
qDebug() << "Create Machine: " << hex << m_id; //%lx",m_id);
//qDebug() << "Create Machine: " << hex << m_id; //%lx",m_id);
m_type=MT_UNKNOWN;
firstsession=true;
}

View File

@ -157,7 +157,7 @@ bool Preferences::Open(QString filename)
QDomDocument doc(p_name);
QFile file(p_filename);
qDebug() << "Opening " << p_filename;
qDebug() << "Scanning " << p_filename;
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Could not open" << p_filename;
return false;

View File

@ -319,7 +319,7 @@ Profile *Get(QString name)
return NULL;
}
Profile *Create(QString name,QString realname,QString password)
Profile *Create(QString name)
{
QString path=pref.Get("{home}/Profiles/")+name;
QDir dir(path);
@ -330,7 +330,7 @@ Profile *Create(QString name,QString realname,QString password)
profiles[name]=prof;
prof->Set("Username",name);
//prof->Set("Realname",realname);
if (!password.isEmpty()) prof->Set("Password",SHA1(password));
//if (!password.isEmpty()) prof->Set("Password",SHA1(password));
prof->Set("DataFolder","{home}/Profiles/{Username}");
Machine *m=new Machine(prof,0);
@ -369,9 +369,9 @@ void Scan()
QDir dir(path);
if (!dir.exists(path)) {
dir.mkpath(path);
//dir.mkpath(path);
// Just silently create a new user record and get on with it.
Create(getUserName(),getUserName(),"");
//Create(getUserName(),getUserName(),"");
return;
}
if (!dir.isReadable()) {
@ -384,11 +384,11 @@ void Scan()
QFileInfoList list=dir.entryInfoList();
QString username=getUserName();
if (list.size()==0) { // No profiles.. Create one.
Create(username,username,"");
return;
}
//QString username=getUserName();
//if (list.size()==0) { // No profiles.. Create one.
//Create(username,username,"");
//return;
//}
// Iterate through subdirectories and load profiles..
for (int i=0;i<list.size();i++) {

View File

@ -78,7 +78,7 @@ extern QHash<QString,Profile *> profiles;
void Scan(); // Initialize and load Profile
void Done(); // Save all Profile objects and clear list
Profile *Create(QString name,QString realname,QString password);
Profile *Create(QString name);
Profile *Get(QString name);
Profile *Get();

View File

@ -54,7 +54,9 @@ SOURCES += main.cpp\
Graphs/gStatsLine.cpp \
report.cpp \
Graphs/gSummaryChart.cpp \
SleepLib/schema.cpp
SleepLib/schema.cpp \
profileselect.cpp \
newprofile.cpp
unix:SOURCES += qextserialport/posix_qextserialport.cpp
unix:!macx:SOURCES += qextserialport/qextserialenumerator_unix.cpp
@ -105,7 +107,9 @@ HEADERS += \
Graphs/gStatsLine.h \
report.h \
Graphs/gSummaryChart.h \
SleepLib/schema.h
SleepLib/schema.h \
profileselect.h \
newprofile.h
FORMS += \
@ -114,7 +118,9 @@ FORMS += \
mainwindow.ui \
oximetry.ui \
preferencesdialog.ui \
report.ui
report.ui \
profileselect.ui \
newprofile.ui
RESOURCES += \
Resources.qrc

View File

@ -6,6 +6,7 @@
//#include <QtPlugin>
#include <QtGui/QApplication>
#include <QMessageBox>
#include <QFontDatabase>
#include <QStringList>
#include <QDebug>
@ -13,6 +14,14 @@
#include "SleepLib/schema.h"
#include "mainwindow.h"
#include "SleepLib/profiles.h"
#include "profileselect.h"
#include "newprofile.h"
#include "SleepLib/loader_plugins/prs1_loader.h"
#include "SleepLib/loader_plugins/cms50_loader.h"
#include "SleepLib/loader_plugins/zeo_loader.h"
#include "SleepLib/loader_plugins/resmed_loader.h"
#ifdef Q_WS_X11
#include <X11/Xlib.h>
@ -60,6 +69,38 @@ int main(int argc, char *argv[])
a.setApplicationName("SleepyHead");
initialize();
PRS1Loader::Register();
CMS50Loader::Register();
ZEOLoader::Register();
ResmedLoader::Register();
Profiles::Scan();
pref["AppName"]="SleepyHead";
QString Version=QString("%1.%2.%3").arg(major_version).arg(minor_version).arg(revision_number);
if (!Profiles::profiles.size()) {
NewProfile newprof(0);
if (newprof.exec()==NewProfile::Rejected)
return 0;
// Show New User wizard..
} else {
if (pref.Exists("VersionString")) {
QString V=pref["VersionString"].toString();
if (V!=Version) {
QMessageBox::warning(0,"New Version Warning","This is a new version of SleepyHead. If you experience a crash right after clicking Ok, you will need to manually delete the SleepApp folder (it's located in your Documents folder) and reimport your data. After this things should work normally.",QMessageBox::Ok);
}
}
ProfileSelect profsel(0);
if (profsel.exec()==ProfileSelect::Rejected) {
exit(1);
}
}
pref["VersionString"]=Version;
//if (!pref.Exists("Profile")) pref["Profile"]=getUserName();
/*int id=QFontDatabase::addApplicationFont(":/fonts/FreeSans.ttf");
QStringList ffam=QFontDatabase::applicationFontFamilies(id);
for (QStringList::iterator i=ffam.begin();i!=ffam.end();i++) {
@ -69,9 +110,9 @@ int main(int argc, char *argv[])
a.setFont(QFont("Sans Serif",10));
qInstallMsgHandler(MyOutputHandler);
MainWindow w;
mainwin=&w;
w.show();
return a.exec();
}

View File

@ -15,10 +15,6 @@
#include <QTimer>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "SleepLib/loader_plugins/prs1_loader.h"
#include "SleepLib/loader_plugins/cms50_loader.h"
#include "SleepLib/loader_plugins/zeo_loader.h"
#include "SleepLib/loader_plugins/resmed_loader.h"
#include "preferencesdialog.h"
#include "SleepLib/schema.h"
@ -60,13 +56,9 @@ MainWindow::MainWindow(QWidget *parent) :
{
logtime.start();
ui->setupUi(this);
this->setWindowTitle(tr("SleepyHead")+QString(" v%1.%2.%3").arg(major_version).arg(minor_version).arg(revision_number));
this->setWindowTitle(tr("SleepyHead")+QString(" v%1.%2.%3 (%4)").arg(major_version).arg(minor_version).arg(revision_number).arg(pref["Profile"].toString()));
ui->tabWidget->setCurrentIndex(0);
PRS1Loader::Register();
CMS50Loader::Register();
ZEOLoader::Register();
ResmedLoader::Register();
/* QGLFormat fmt;
fmt.setDepth(false);
@ -99,19 +91,6 @@ MainWindow::MainWindow(QWidget *parent) :
ui->statusbar->addPermanentWidget(qstatus,0);
ui->statusbar->addPermanentWidget(qprogress,1);
ui->statusbar->addPermanentWidget(qstatus2,0);
Profiles::Scan();
pref["AppName"]="SleepyHead";
QString Version=QString("%1.%2.%3").arg(major_version).arg(minor_version).arg(revision_number);
if (pref.Exists("VersionString")) {
QString V=pref["VersionString"].toString();
if (V!=Version) {
QMessageBox::warning(this,"New Version Warning","This is a new version of SleepyHead. If you experience a crash right after clicking Ok, you will need to manually delete the SleepApp folder (it's located in your Documents folder) and reimport your data. After this things should work normally.",QMessageBox::Ok);
}
}
pref["VersionString"]=Version;
if (!pref.Exists("Profile")) pref["Profile"]=getUserName();
if (!pref.Exists("ShowDebug")) pref["ShowDebug"]=true;
ui->actionDebug->setChecked(pref["ShowDebug"].toBool());

162
newprofile.cpp Normal file
View File

@ -0,0 +1,162 @@
#include <QMessageBox>
#include <QCryptographicHash>
#include "SleepLib/profiles.h"
#include "newprofile.h"
#include "ui_newprofile.h"
NewProfile::NewProfile(QWidget *parent) :
QDialog(parent),
ui(new Ui::NewProfile)
{
ui->setupUi(this);
ui->userNameEdit->setText(getUserName());
QLocale locale=QLocale::system();
QString shortformat=locale.dateFormat(QLocale::ShortFormat);
if (!shortformat.toLower().contains("yyyy")) {
shortformat.replace("yy","yyyy");
}
ui->dobEdit->setDisplayFormat(shortformat);
ui->dateDiagnosedEdit->setDisplayFormat(shortformat);
m_firstPage=0;
ui->backButton->setEnabled(false);
ui->nextButton->setEnabled(false);
ui->stackedWidget->setCurrentIndex(0);
on_cpapModeCombo_activated(0);
}
NewProfile::~NewProfile()
{
delete ui;
}
void NewProfile::on_nextButton_clicked()
{
if (!ui->agreeCheckbox->isChecked())
return;
int index=ui->stackedWidget->currentIndex();
switch(index) {
case 1:
if (ui->userNameEdit->text().isEmpty()) {
QMessageBox::information(this,"Error","Empty Username",QMessageBox::Ok);
return;
}
if (ui->genderCombo->currentIndex()==0) {
//QMessageBox::information(this,"Notice","You did not specify Gender.",QMessageBox::Ok);
}
if (ui->passwordGroupBox->isChecked()) {
if (ui->passwordEdit1->text()!=ui->passwordEdit2->text()) {
QMessageBox::information(this,"Error","Passwords don't match",QMessageBox::Ok);
return;
}
if (ui->passwordEdit1->text().isEmpty())
ui->passwordGroupBox->setChecked(false);
}
break;
case 2:
break;
case 3:
break;
default:
break;
}
int max_pages=ui->stackedWidget->count()-1;
if (index<max_pages) {
index++;
ui->stackedWidget->setCurrentIndex(index);
} else {
// Finish button clicked.
if (QMessageBox::question(this,"Profile Changes","Accept and save this information?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes) {
Profile *profile=Profiles::Get(ui->userNameEdit->text());
if (!profile) { // No profile, create one.
profile=Profiles::Create(ui->userNameEdit->text());
}
Profile &prof=*profile;
prof["FirstName"]=ui->firstNameEdit->text();
prof["LastName"]=ui->lastNameEdit->text();
prof["DOB"]=ui->dobEdit->date();
prof["Height"]=ui->heightEdit->value();
prof["EmailAddress"]=ui->emailEdit->text();
prof["Phone"]=ui->phoneEdit->text();
prof["Address"]=ui->addressEdit->toPlainText();
if (ui->passwordGroupBox->isChecked()) {
QByteArray ba=ui->passwordEdit1->text().toUtf8();
prof["Password"]=QString(QCryptographicHash::hash(ba,QCryptographicHash::Sha1).toHex());
}
prof["Password"]="";
if (ui->genderCombo->currentIndex()==1) {
prof["Gender"]="Male";
} else if (ui->genderCombo->currentIndex()==2) {
prof["Gender"]="Female";
}
prof["DateDiagnosed"]=ui->dateDiagnosedEdit->date();
prof["UntreatedAHI"]=ui->untreatedAHIEdit->value();
prof["CPAPPrescribedMode"]=ui->cpapModeCombo->currentIndex();
prof["CPAPPrescribedMinPressure"]=ui->minPressureEdit->value();
prof["CPAPPrescribedMaxPressure"]=ui->minPressureEdit->value();
prof["CPAPNotes"]=ui->cpapNotes->toPlainText();
prof["DoctorName"]=ui->doctorNameEdit->text();
prof["DcotorPractice"]=ui->doctorPracticeEdit->text();
prof["DoctorAddress"]=ui->doctorAddressEdit->toPlainText();
prof["DoctorPhone"]=ui->doctorPhoneEdit->text();
prof["DoctorEmail"]=ui->doctorEmailEdit->text();
prof["DoctorPatientID"]=ui->doctorPatientIDEdit->text();
pref["Profile"]=ui->userNameEdit->text();
this->accept();
}
}
if (index>=max_pages) {
ui->nextButton->setText("&Finish");
} else {
ui->nextButton->setText("&Next");
}
ui->backButton->setEnabled(true);
}
void NewProfile::on_backButton_clicked()
{
ui->nextButton->setText("&Next");
if (ui->stackedWidget->currentIndex()>m_firstPage) {
ui->stackedWidget->setCurrentIndex(ui->stackedWidget->currentIndex()-1);
}
if (ui->stackedWidget->currentIndex()==m_firstPage) {
ui->backButton->setEnabled(false);
} else {
ui->backButton->setEnabled(true);
}
}
void NewProfile::on_cpapModeCombo_activated(int index)
{
if (index==0) {
ui->maxPressureEdit->setVisible(false);
} else {
ui->maxPressureEdit->setVisible(true);
}
}
void NewProfile::on_agreeCheckbox_clicked(bool checked)
{
ui->nextButton->setEnabled(checked);
}
void NewProfile::skipWelcomeScreen()
{
ui->agreeCheckbox->setChecked(true);
ui->stackedWidget->setCurrentIndex(m_firstPage=1);
ui->backButton->setEnabled(false);
ui->nextButton->setEnabled(true);
}

33
newprofile.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef NEWPROFILE_H
#define NEWPROFILE_H
#include <QDialog>
namespace Ui {
class NewProfile;
}
class NewProfile : public QDialog
{
Q_OBJECT
public:
explicit NewProfile(QWidget *parent = 0);
~NewProfile();
void skipWelcomeScreen();
private slots:
void on_nextButton_clicked();
void on_backButton_clicked();
void on_cpapModeCombo_activated(int index);
void on_agreeCheckbox_clicked(bool checked);
private:
Ui::NewProfile *ui;
bool m_editMode;
int m_firstPage;
};
#endif // NEWPROFILE_H

674
newprofile.ui Normal file
View File

@ -0,0 +1,674 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NewProfile</class>
<widget class="QDialog" name="NewProfile">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>605</width>
<height>374</height>
</rect>
</property>
<property name="windowTitle">
<string>Edit User Profile</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>4</number>
</property>
<widget class="QWidget" name="page_5">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;Welcome to SleepyHead&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This software is being designed to help you review data related to your CPAP treatment.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;It's intended as merely a data viewer, and not a substitute for competent medical guidance from your Doctor. &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This software has been released freely under the &lt;a href=&quot;http://www.gnu.org/copyleft/gpl.html&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;GNU Public License&lt;/span&gt;&lt;/a&gt;, and comes with no warranty, and without ANY claims to fitness for any purpose.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Accuracy of any data displayed is not and can not be gauranteed. &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The author will not be held liable for &lt;span style=&quot; text-decoration: underline;&quot;&gt;anything&lt;/span&gt; related to the use or misuse of this software. &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Use at your own risk. &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This software is copyright ©2011 Mark Watkins &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="agreeCheckbox">
<property name="text">
<string>I agree to all the conditions above.</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Personal &amp;&amp; User Information</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>User Name</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="userNameEdit"/>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="passwordGroupBox">
<property name="toolTip">
<string>Keep the kids out.. Nothing more.. This isn't meant to be uber security.</string>
</property>
<property name="title">
<string>Password Protect Profile</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="1">
<widget class="QLineEdit" name="passwordEdit1">
<property name="echoMode">
<enum>QLineEdit::PasswordEchoOnEdit</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="passwordEdit2">
<property name="echoMode">
<enum>QLineEdit::PasswordEchoOnEdit</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>...twice...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>First Name</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="firstNameEdit"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Last Name</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lastNameEdit"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>D.O.B.</string>
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QDateEdit" name="dobEdit"/>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Gender</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="genderCombo">
<item>
<property name="text">
<string/>
</property>
</item>
<item>
<property name="text">
<string>Male</string>
</property>
</item>
<item>
<property name="text">
<string>Female</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Height</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QDoubleSpinBox" name="heightEdit">
<property name="maximum">
<double>350.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Contact Information</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Address</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QTextEdit" name="addressEdit">
<property name="tabChangesFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Email</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="emailEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Phone</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="phoneEdit"/>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>250</width>
<height>2</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_15">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:italic;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;(This information is just used in reports.)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>CPAP Treatment Information</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Date Diagnosed</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDateEdit" name="dateDiagnosedEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Untreated AHI</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="untreatedAHIEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>CPAP Mode</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="cpapModeCombo">
<item>
<property name="text">
<string>CPAP</string>
</property>
</item>
<item>
<property name="text">
<string>APAP</string>
</property>
</item>
<item>
<property name="text">
<string>Bi-Level</string>
</property>
</item>
<item>
<property name="text">
<string>ASV</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>RX Pressure</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QDoubleSpinBox" name="minPressureEdit"/>
</item>
<item>
<widget class="QDoubleSpinBox" name="maxPressureEdit"/>
</item>
</layout>
</item>
<item row="5" column="0" colspan="2">
<widget class="QPlainTextEdit" name="cpapNotes">
<property name="tabChangesFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_4">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Doctors Information</string>
</property>
<layout class="QFormLayout" name="formLayout_5">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="doctorNameEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_23">
<property name="text">
<string>Practice</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="doctorPracticeEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Address</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QTextEdit" name="doctorAddressEdit">
<property name="tabChangesFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Phone</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="doctorPhoneEdit"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Email</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="doctorEmailEdit"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Patient ID</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLineEdit" name="doctorPatientIDEdit"/>
</item>
<item row="8" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
<weight>75</weight>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>SleepyHead</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="Resources.qrc">:/docs/sheep.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>&amp;Cancel</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="backButton">
<property name="text">
<string>&amp;Back</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="nextButton">
<property name="text">
<string>&amp;Next</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="Resources.qrc"/>
</resources>
<connections>
<connection>
<sender>cancelButton</sender>
<signal>clicked()</signal>
<receiver>NewProfile</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>425</x>
<y>373</y>
</hint>
<hint type="destinationlabel">
<x>288</x>
<y>197</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -146,10 +146,10 @@ void Oximetry::on_RefreshPortsButton_clicked()
}
}
//qDebug() << "Serial Port:" << ports.at(i).qesPORTNAME << ports.at(i).friendName;
qDebug() << "port name:" << ports.at(i).portName;
qDebug() << "phys name:" << ports.at(i).physName;
qDebug() << "friendly name:" << ports.at(i).friendName;
qDebug() << "enumerator name:" << ports.at(i).enumName;
//qDebug() << "port name:" << ports.at(i).portName;
//qDebug() << "phys name:" << ports.at(i).physName;
//qDebug() << "friendly name:" << ports.at(i).friendName;
//qDebug() << "enumerator name:" << ports.at(i).enumName;
}
if (z>0) {
ui->RunButton->setEnabled(true);

View File

@ -29,7 +29,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>3</number>
<number>2</number>
</property>
<widget class="QWidget" name="profileTab">
<attribute name="title">

98
profileselect.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "profileselect.h"
#include <QDebug>
#include <QStringListModel>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QDialog>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QCryptographicHash>
#include <QMessageBox>
#include "ui_profileselect.h"
#include "SleepLib/profiles.h"
#include "newprofile.h"
ProfileSelect::ProfileSelect(QWidget *parent) :
QDialog(parent),
ui(new Ui::ProfileSelect)
{
ui->setupUi(this);
//ui->listView->setViewMode(QListView::IconMode);
QStringList str;
QStandardItemModel *model=new QStandardItemModel (0,0);
//QList<QStandardItem *> items;
int i=0;
for (QHash<QString,Profile *>::iterator p=Profiles::profiles.begin();p!=Profiles::profiles.end();p++) {
//str.append(p.key());
Profile &profile=**p;
QString name=p.key();
// if (!profile["FirstName"].toString().isEmpty())
// name+=" ("+profile["FirstName"].toString()+" "+profile["LastName"].toString()+")";
QStandardItem *item=new QStandardItem(*new QIcon(":/icons/moon.png"),name);
item->setData(p.key());
item->setEditable(false);
item->setFont(QFont("Sans Serif",18,QFont::Bold,false));
model->appendRow(item);
i++;
}
ui->listView->setModel(model);
ui->listView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->listView->setSelectionMode(QAbstractItemView::SingleSelection);
m_tries=0;
}
ProfileSelect::~ProfileSelect()
{
delete ui;
}
void ProfileSelect::on_selectButton_clicked()
{
on_listView_activated(ui->listView->currentIndex());
}
void ProfileSelect::on_newProfileButton_clicked()
{
NewProfile newprof(this);
newprof.skipWelcomeScreen();
newprof.exec();
accept();
}
void ProfileSelect::on_listView_activated(const QModelIndex &index)
{
QString name=index.data().toString();
Profile *profile=Profiles::profiles[name];
if (!profile) return;
if ((*profile)["Password"].toString().isEmpty()) {
m_selectedProfile=name;
pref["Profile"]=name;
} else {
QDialog dialog(this,Qt::Dialog);
QLineEdit *e=new QLineEdit(&dialog);
e->setEchoMode(QLineEdit::Password);
dialog.connect(e,SIGNAL(returnPressed()),&dialog,SLOT(accept()));
dialog.setWindowTitle("Enter Password");
QVBoxLayout *lay=new QVBoxLayout();
dialog.setLayout(lay);
lay->addWidget(e);
dialog.exec();
QByteArray ba=e->text().toUtf8();
if (QCryptographicHash::hash(ba,QCryptographicHash::Sha1).toHex()==(*profile)["Password"]) {
m_selectedProfile=name;
pref["Profile"]=name;
} else {
m_tries++;
if (m_tries>2) {
QMessageBox::warning(this,"Error","You entered an Incorrect Password too many times. Exiting!",QMessageBox::Ok);
this->reject();
} else {
QMessageBox::warning(this,"Error","Incorrect Password",QMessageBox::Ok);
}
return;
}
}
accept();
}

33
profileselect.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef PROFILESELECT_H
#define PROFILESELECT_H
#include <QDialog>
#include <QModelIndex>
namespace Ui {
class ProfileSelect;
}
class ProfileSelect : public QDialog
{
Q_OBJECT
public:
explicit ProfileSelect(QWidget *parent = 0);
~ProfileSelect();
QString selectedProfile();
private slots:
void on_selectButton_clicked();
void on_newProfileButton_clicked();
void on_listView_activated(const QModelIndex &index);
private:
Ui::ProfileSelect *ui;
QString m_selectedProfile;
int m_tries;
};
#endif // PROFILESELECT_H

79
profileselect.ui Normal file
View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProfileSelect</class>
<widget class="QDialog" name="ProfileSelect">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Select Profile</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListView" name="listView"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="quitButton">
<property name="text">
<string>&amp;Quit</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="newProfileButton">
<property name="text">
<string>New Profile</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="selectButton">
<property name="text">
<string>&amp;Select User</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>quitButton</sender>
<signal>clicked()</signal>
<receiver>ProfileSelect</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>52</x>
<y>276</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>