Merge branch 'master' into prs1-fixes-2

This commit is contained in:
sawinglogz 2019-06-21 15:26:57 -04:00
commit 581515e595
12 changed files with 243 additions and 312 deletions

View File

@ -71,13 +71,13 @@ bool CMS50F37Loader::openDevice()
b = scanDevice("rfcomm", 0, 0); // Linux
}
if (!b) {
qWarning() << "No oximeter found";
qWarning() << "cms50f37 - No oximeter found";
return false;
}
}
serial.setPortName(port);
if (!serial.open(QSerialPort::ReadWrite)) {
qDebug() << "Failed to open oximeter";
qDebug() << "cms50f37 - Failed to open oximeter";
return false;
}
@ -198,7 +198,7 @@ QString CMS50F37Loader::getUser()
QApplication::processEvents();
} while (userName.isEmpty() && (time.elapsed() < TIMEOUT));
qDebug() << "User " << userIdx << " is " << userName;
qDebug() << "cms50f37 - User " << userIdx << " is " << userName;
return userName;
}
@ -214,7 +214,7 @@ QString CMS50F37Loader::getVendor()
QApplication::processEvents();
} while (vendor.isEmpty() && (time.elapsed() < TIMEOUT));
qDebug() << "Vendor is " << vendor;
qDebug() << "cms50f37 - Vendor is " << vendor;
return vendor;
}
@ -241,14 +241,14 @@ QString CMS50F37Loader::getModel()
duration_divisor = 2;
}
qDebug() << "Model is " << model;
qDebug() << "cms50f37 - Model is " << model;
return model;
}
QString CMS50F37Loader::getDeviceString()
{
QString VendDev = QString("%1 %2").arg(getVendor()).arg(getModel());
qDebug() << "USB Device String is " << VendDev;
qDebug() << "cms50f37 - USB Device String is " << VendDev;
return VendDev;
}
@ -264,7 +264,7 @@ QString CMS50F37Loader::getDeviceID()
QApplication::processEvents();
} while (devid.isEmpty() && (time.elapsed() < TIMEOUT));
qDebug() << "Device Id is " << devid;
qDebug() << "cms50f37 - Device Id is " << devid;
return devid;
}
@ -279,7 +279,7 @@ int CMS50F37Loader::getUserCount() // for future use, check, then add select us
QApplication::processEvents();
} while ((userCount < 0) && (time.elapsed() < TIMEOUT));
qDebug() << "User count is " << userCount;
qDebug() << "cms50f37 - User count is " << userCount;
return userCount;
}
@ -294,7 +294,7 @@ int CMS50F37Loader::getSessionCount()
QApplication::processEvents();
} while ((session_count < 0) && (time.elapsed() < TIMEOUT));
qDebug() << "Session count is " << session_count;
qDebug() << "cms50f37 - Session count is " << session_count;
return session_count;
}
@ -308,7 +308,7 @@ int CMS50F37Loader::getOximeterInfo()
QApplication::processEvents();
} while ((device_info < 0) && (time.elapsed() < TIMEOUT));
qDebug() << "Device Info is " << device_info;
qDebug() << "cms50f37 - Device Info is " << device_info;
return device_info;
}
@ -325,7 +325,7 @@ int CMS50F37Loader::getDuration(int session)
QApplication::processEvents();
} while ((duration < 0) && (time.elapsed() < TIMEOUT));
qDebug() << "Session duration is " << duration << "Divided by " << duration_divisor;
qDebug() << "cms50f37 - Session duration is " << duration << "Divided by " << duration_divisor;
return duration / duration_divisor;
}
@ -351,7 +351,7 @@ QDateTime CMS50F37Loader::getDateTime(int session)
else
datetime = QDateTime(imp_date, imp_time);
qDebug() << "Oximeter DateTime is " << datetime.toString("yyyy-MMM-dd HH:mm:ssap");
qDebug() << "cms50f37 - Oximeter DateTime is " << datetime.toString("yyyy-MMM-dd HH:mm:ssap");
return datetime;
}
@ -397,7 +397,7 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
if (res == resimport) break;
}
// add a dummy to make up for it.
qDebug() << "pB: lost sync, padding...";
qDebug() << "cms50f37 - pB: lost sync, padding...";
oxirec->append(OxiRecord(0,0,0));
}
continue;
@ -418,24 +418,24 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
QString extra = QString(buffer.mid(idx+3, 6));
model += extra.trimmed();
modelsegments++;
qDebug() << "pB: Model:" << model;
qDebug() << "cms50f37 - pB: Model:" << model;
}
break;
case 0x03: // Vendor string
vendor = QString(buffer.mid(idx+2, 7));
qDebug() << "pB: Vendor:" << vendor;
qDebug() << "cms50f37 - pB: Vendor:" << vendor;
break;
case 0x04: // Device Identifiers
devid = QString(buffer.mid(idx+2, 7));
qDebug() << "pB: Device ID:" << devid;
qDebug() << "cms50f37 - pB: Device ID:" << devid;
break;
// COMMAND_GET_USER_INFO
case 0x05: // 5,80,80,f5,f3,e5,f2,80,80
userIdx = buffer.at(idx+2); // for future use
userName = QString(buffer.mid(idx+3).trimmed());
qDebug() << "pB: 0x05:" << userName;
qDebug() << "cms50f37 - pB: 0x05:" << userName;
break;
// Command GET_VERSION
@ -456,7 +456,8 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
}
else
imp_date = QDate(year,month,day);
qDebug() << "pB: ymd " << year << month << day << " impDate " << imp_date;
qDebug() << "cms50f37 - cms50D+ detected: " << (cms50dplus ? "yes" : "no");
qDebug() << "cms50f37 - pB: ymd " << year << month << day << " impDate: " << imp_date;
break;
// COMMAND_GET_SESSION_DURATION
@ -502,7 +503,7 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
case 0x12: // 12,80,80,80,82,a6,92,80
tmpstr = QString().sprintf("%02i:%02i:%02i",buffer.at(idx+4), buffer.at(idx+5), buffer.at(idx+6));
imp_time = QTime::fromString(tmpstr, "HH:mm:ss");
qDebug() << "pB: tmpStr:" << tmpstr << " impTime " << imp_time;
qDebug() << "cms50f37 - pB: tmpStr:" << tmpstr << " impTime: " << imp_time;
break;
case 0x13: // 13,80,a0,a0,a0,a0,a0,a0,a0
@ -513,7 +514,7 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
case 0x09: // cms50i data sequence
case 0x0f: // f,80,de,c2,de,c2,de,c2 cms50F data...
if (!started_import) {
qDebug() << "pB: Starting import";
qDebug() << "cms50f37 - pB: Starting import";
started_import = true;
started_reading = true;
finished_import = false;
@ -538,7 +539,7 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
break;
default:
qDebug() << "pB: unknown cms50F result?" << hex << (int)res;
qDebug() << "cms50f37 - pB: unknown cms50F result?" << hex << (int)res;
break;
}
@ -548,7 +549,7 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
pi = buffer.at(idx+4) | (buffer.at(idx+5) << 8);
pulse = buffer.at(idx+3);
spo2 = buffer.at(idx+2);
qDebug() << "pB: Pulse=" << pulse << "SPO2=" << spo2 << "PI=" << pi;
// qDebug() << "cms50f37 - pB: Pulse=" << pulse << "SPO2=" << spo2 << "PI=" << pi;
oxirec->append(((spo2 == 0) || (pulse == 0)) ? OxiRecord(0,0,0) : OxiRecord(pulse, spo2, pi));
} else if (res == 0x0f) {
@ -556,17 +557,17 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
pulse = buffer.at(idx+3);
spo2 = buffer.at(idx+2);
qDebug() << "pB: Pulse=" << pulse << "SPO2=" << spo2;
// qDebug() << "cms50f37 - pB: Pulse=" << pulse << "SPO2=" << spo2;
oxirec->append((pulse == 0xff) ? OxiRecord(0,0) : OxiRecord(pulse, spo2));
pulse = buffer.at(idx+5);
spo2 = buffer.at(idx+4);
qDebug() << "pB: Pulse=" << pulse << "SPO2=" << spo2;
// qDebug() << "cms50f37 - pB: Pulse=" << pulse << "SPO2=" << spo2;
oxirec->append((pulse == 0xff) ? OxiRecord(0,0) : OxiRecord(pulse, spo2));
pulse = buffer.at(idx+7);
spo2 = buffer.at(idx+6);
qDebug() << "pB: Pulse=" << pulse << "SPO2=" << spo2;
// qDebug() << "cms50f37 - pB: Pulse=" << pulse << "SPO2=" << spo2;
oxirec->append((pulse == 0xff) ? OxiRecord(0,0) : OxiRecord(pulse, spo2));
}
@ -577,9 +578,11 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
if (!started_import) {
// startTimer.singleShot(2000, this, SLOT(requestData()));
qDebug() << "pB: Read:" << len << size << str.join(",");
importCount = 0;
qDebug() << "cms50f37 - pB: Read:" << len << size << str.join(",");
} else {
qDebug() << "pB: Import:" << len << size << str.join(",");
importCount++;
// qDebug() << "cms50f37 - pB: Import:" << len << size << str.join(",");
}
idx += len;
@ -602,10 +605,10 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
//{
// if (oxirec == nullptr) { // warn
//}
//
// int available = buffer.size();
// int idx = 0;
//
// QByteArray plethy;
// while (idx < available-5) {
// if (((unsigned char)buffer.at(idx) & 0x80) != 0x80) {
@ -616,14 +619,14 @@ void CMS50F37Loader::processBytes(QByteArray bytes)
// int pbeat=(unsigned char)buffer.at(idx + 2);
// int pulse=((unsigned char)buffer.at(idx + 3) & 0x7f) | ((pbeat & 0x40) << 1);
// int spo2=(unsigned char)buffer.at(idx + 4) & 0x7f;
//
// oxirec->append(OxiRecord(pulse, spo2));
// plethy.append(pwave);
//
// idx += 5;
// }
// emit updatePlethy(plethy);
//
// return idx;
//}
@ -636,10 +639,10 @@ void CMS50F37Loader::sendCommand(quint8 c)
QString out;
for (int i=0;i < 9;i++)
out += QString().sprintf("%02X ",cmd[i]);
qDebug() << "Write:" << out;
qDebug() << "cms50f37 - Write:" << out;
if (serial.write((char *)cmd, 9) == -1) {
qDebug() << "Couldn't write data bytes to CMS50F";
qDebug() << "cms50f37 - Couldn't write data bytes to CMS50F";
}
}
@ -652,10 +655,10 @@ void CMS50F37Loader::sendCommand(quint8 c, quint8 c2)
QString out;
for (int i=0; i < 9; ++i)
out += QString().sprintf("%02X ",cmd[i]);
qDebug() << "Write:" << out;
qDebug() << "cms50f37 - Write:" << out;
if (serial.write((char *)cmd, 9) == -1) {
qDebug() << "Couldn't write data bytes to CMS50F";
qDebug() << "cms50f37 - Couldn't write data bytes to CMS50F";
}
}
@ -669,10 +672,10 @@ void CMS50F37Loader::eraseSession(int user, int session)
QString out;
for (int i=0; i < 9; ++i)
out += QString().sprintf("%02X ",cmd[i]);
qDebug() << "Erase Session: Write:" << out;
qDebug() << "cms50f37 - Erase Session: Write:" << out;
if (serial.write((char *)cmd, 9) == -1) {
qDebug() << "Couldn't write Erase session bytes to CMS50F";
qDebug() << "cms50f37 - Couldn't write Erase session bytes to CMS50F";
}
int z = timectr;
@ -707,10 +710,10 @@ void CMS50F37Loader::setDeviceID(const QString & newid)
QString out;
for (int i=0; i < 9; ++i)
out += QString().sprintf("%02X ",cmd[i]);
qDebug() << "setDeviceID: Write:" << out;
qDebug() << "cms50f37 - setDeviceID: Write:" << out;
if (serial.write((char *)cmd, 9) == -1) {
qDebug() << "Couldn't write DeviceID data bytes to CMS50F";
qDebug() << "cms50f37 - Couldn't write DeviceID data bytes to CMS50F";
}
// Supposed to return 0x04 command, so reset devid..
@ -737,7 +740,7 @@ void CMS50F37Loader::syncClock()
timectr = 0;
if (serial.write((char *)datecmd, 9) == -1) {
qDebug() << "Couldn't write date bytes to CMS50F";
qDebug() << "cms50f37 - Couldn't write date bytes to CMS50F";
}
QTime time;
@ -759,7 +762,7 @@ void CMS50F37Loader::syncClock()
timectr = 0;
if (serial.write((char *)timecmd, 9) == -1) {
qDebug() << "Couldn't write time bytes to CMS50F";
qDebug() << "cms50f37 - Couldn't write time bytes to CMS50F";
}
time.start();
@ -776,7 +779,7 @@ void CMS50F37Loader::nextCommand()
// Send the next command packet in sequence
sendCommand(cms50_sequence[sequence]);
} else {
qDebug() << "Run out of startup tasks to do and import failed!";
qDebug() << "cms50f37 - Run out of startup tasks to do and import failed!";
}
}
@ -789,7 +792,7 @@ void CMS50F37Loader::getSessionData(int session)
void CMS50F37Loader::resetDevice()
{
qDebug() << "Resetting oximeter";
qDebug() << "cms50f37 - Resetting oximeter";
sendCommand(COMMAND_CMS50_HELLO1);
QThread::msleep(100);
QApplication::processEvents();
@ -800,7 +803,7 @@ void CMS50F37Loader::resetDevice()
void CMS50F37Loader::requestData()
{
qDebug() << "Requesting session data";
qDebug() << "cms50f37 - Requesting session data";
sendCommand(COMMAND_GET_SESSION_DATA, selected_session);
}
@ -822,16 +825,18 @@ void CMS50F37Loader::resetImportTimeout()
if (imp_callbacks != cb_reset) {
// Still receiving data.. reset timer
qDebug() << "Still receiving data in resetImportTimeout()" << imp_callbacks << cb_reset;
qDebug() << "cms50f37 - Still receiving data in resetImportTimeout()" << imp_callbacks << cb_reset;
if (resetTimer.isActive())
resetTimer.stop();
if (!finished_import) resetTimer.singleShot(2000, this, SLOT(resetImportTimeout()));
if (!finished_import)
resetTimer.singleShot(2000, this, SLOT(resetImportTimeout()));
} else {
qDebug() << "Oximeter device stopped transmitting.. Transfer complete";
qDebug() << "cms50f37 - Oximeter device stopped transmitting.. Transfer complete";
qDebug() << "cms50f37 - Import packet count: " << importCount;
// We were importing, but now are done
if (!finished_import && (started_import && started_reading)) {
qDebug() << "Switching CMS50F37 back to live mode and finalizing import";
qDebug() << "cms50f37 - Switching CMS50F37 back to live mode and finalizing import";
// Turn back on live streaming so the end of capture can be dealt with
@ -851,7 +856,7 @@ void CMS50F37Loader::resetImportTimeout()
return;
}
qDebug() << "Should CMS50F37 resetImportTimeout reach here?";
qDebug() << "cms50f37 - Should CMS50F37 resetImportTimeout reach here?";
// else what???
}
cb_reset = imp_callbacks;
@ -869,23 +874,23 @@ bool CMS50F37Loader::readSpoRFile(const QString & path)
{
QFile file(path);
if (!file.exists()) {
qWarning() << "Can't find the oximeter file: " << path;
qWarning() << "cms50f37 - Can't find the oximeter file: " << path;
QMessageBox::warning(nullptr, STR_MessageBox_Error, "<h2>"+tr("Could not find the oximeter file:")+"<br/><br/>"+path+"</h2>");
return false;
}
if (!file.open(QFile::ReadOnly)) {
qWarning() << "Can't open the oximeter file: " << path;
qWarning() << "cms50f37 - Can't open the oximeter file: " << path;
QMessageBox::warning(nullptr, STR_MessageBox_Error, "<h2>"+tr("Could not open the oximeter file:")+"<br/><br/>"+path+"</h2>");
return false;
}
bool spo2header = false;
QString ext = path.section('.', -1);
qDebug() << "Oximeter file extention is " << ext;
qDebug() << "cms50f37 - Oximeter file extention is " << ext;
if (ext.compare("spo2",Qt::CaseInsensitive) == 0) {
spo2header = true;
qDebug() << "Oximeter file looks like an SpO2 type" ;
qDebug() << "cms50f37 - Oximeter file looks like an SpO2 type" ;
}
QByteArray data;
@ -918,7 +923,9 @@ bool CMS50F37Loader::readSpoRFile(const QString & path)
if (dchr[0]) {
QString dstr(dchr);
m_startTime = QDateTime::fromString(dstr, "MM/dd/yy HH:mm:ss");
if (m_startTime.date().year() < 2000) { m_startTime = m_startTime.addYears(100); }
if (m_startTime.date().year() < 2000) {
m_startTime = m_startTime.addYears(100);
}
} else { // this should probaly find the most recent SH data day
m_startTime = QDateTime(QDate::currentDate(), QTime(0,0,0)); // make it today at midnight
cms50dplus = true;
@ -931,7 +938,7 @@ bool CMS50F37Loader::readSpoRFile(const QString & path)
quint32 hour, minute, second;
if (data.at(pos) != 1) {
qWarning() << ".spo2 file" << path << "might be a different";
qWarning() << "cms50f37 - .spo2 file" << path << "might be a different";
}
// Unknown cruft header...
@ -955,7 +962,7 @@ bool CMS50F37Loader::readSpoRFile(const QString & path)
int remainder = filesize - pos;
bytes_per_record = remainder / samples;
qDebug() << samples << "samples of" << bytes_per_record << "bytes each";
qDebug() << "cms50f37 - " << samples << "samples of" << bytes_per_record << "bytes each";
// CMS50I .spo2 data have 4 digits, a 16bit, followed by spo2 then pulse
@ -1019,7 +1026,7 @@ void CMS50F37Loader::Register()
{
if (cms50f37_initialized) { return; }
qDebug() << "Registering CMS50F37Loader";
qDebug() << "cms50f37 - Registering CMS50F37Loader";
RegisterLoader(new CMS50F37Loader());
cms50f37_initialized = true;
}

View File

@ -82,14 +82,10 @@ protected slots:
virtual void resetImportTimeout();
virtual void startImportTimeout();
virtual void shutdownPorts();
void nextCommand();
protected:
bool readSpoRFile(const QString & path);
virtual void processBytes(QByteArray bytes);
@ -100,12 +96,9 @@ protected:
void sendCommand(quint8 c);
void sendCommand(quint8 c, quint8 c2);
// Switch device to live streaming mode
virtual void resetDevice();
private:
int sequence;
@ -125,6 +118,7 @@ protected:
int cb_reset,imp_callbacks;
int received_bytes;
int importCount;
int m_itemCnt;
int m_itemTotal;

View File

@ -30,7 +30,7 @@ bool SerialOximeter::scanDevice(QString keyword, quint16 vendor_id, quint16 prod
static bool dumponce = true;
QStringList ports;
qDebug() << "Scanning for USB Serial devices";
qDebug() << "seroxi - Scanning for USB Serial devices";
QList<QSerialPortInfo> list=QSerialPortInfo::availablePorts();
// How does the mac detect this as a SPO2 device?
@ -51,7 +51,7 @@ bool SerialOximeter::scanDevice(QString keyword, quint16 vendor_id, quint16 prod
if (info->hasVendorIdentifier()) // 4292
dbg += QString(" VID: %1").arg(info->vendorIdentifier());
qDebug() << dbg.toLocal8Bit().data();
qDebug() << "seroxi - " << dbg.toLocal8Bit().data();
break;
} else if (dumponce) {
QString dbg=QString("Other Serial Port: Name: %1 Desc: %2 Manufacturer: %3 Location: %4").arg(name).arg(desc).arg(info->manufacturer()).arg(info->systemLocation());
@ -61,7 +61,7 @@ bool SerialOximeter::scanDevice(QString keyword, quint16 vendor_id, quint16 prod
if (info->hasVendorIdentifier()) // 4292
dbg += QString(" VID: %1").arg(info->vendorIdentifier());
qDebug() << dbg.toLocal8Bit().data();
qDebug() << "seroxi - " << dbg.toLocal8Bit().data();
}
}
dumponce = false;
@ -69,7 +69,7 @@ bool SerialOximeter::scanDevice(QString keyword, quint16 vendor_id, quint16 prod
return false;
}
if (ports.size()>1) {
qDebug() << "More than one serial device matching these parameters was found, choosing the first by default";
qDebug() << "seroxi - More than one serial device matching these parameters was found, choosing the first by default";
}
port=ports.at(0);
return true;
@ -81,7 +81,7 @@ void SerialOximeter::closeDevice()
disconnect(&serial,SIGNAL(readyRead()), this, SLOT(dataAvailable()));
serial.close();
m_streaming = false;
qDebug() << "Port" << port << "closed";
qDebug() << "seroxi - Port" << port << "closed";
}
bool SerialOximeter::openDevice()

View File

@ -1,8 +0,0 @@
#!/bin/bash
#
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
sed -i s/PlaceholderText/Text/ mainwindow.ui
#

View File

@ -42,11 +42,6 @@
#include "SleepLib/loader_plugins/icon_loader.h"
#include "SleepLib/loader_plugins/weinmann_loader.h"
#ifdef Q_WS_X11
#include <X11/Xlib.h>
#endif
MainWindow *mainwin = nullptr;
int compareVersion(QString version);
@ -257,9 +252,6 @@ int main(int argc, char* argv[])
#else
int main(int argc, char *argv[]) {
#ifdef Q_WS_X11
XInitThreads();
#endif
QString homeDocs = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)+"/";
QCoreApplication::setApplicationName(getAppName());

View File

@ -160,15 +160,6 @@
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
@ -306,15 +297,6 @@
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
@ -452,15 +434,6 @@
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
@ -663,15 +636,6 @@
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
@ -809,15 +773,6 @@
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
@ -955,15 +910,6 @@
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
@ -2002,15 +1948,6 @@ border: 2px solid #56789a; border-radius: 30px;
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
@ -2181,15 +2118,6 @@ border: 2px solid #56789a; border-radius: 30px;
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
@ -2360,15 +2288,6 @@ border: 2px solid #56789a; border-radius: 30px;
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
@ -2471,15 +2390,6 @@ border: 2px solid #56789a; border-radius: 30px;
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
@ -2545,15 +2455,6 @@ border: 2px solid #56789a; border-radius: 30px;
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
@ -2619,15 +2520,6 @@ border: 2px solid #56789a; border-radius: 30px;
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="NoBrush">
<color alpha="128">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>

View File

@ -117,12 +117,15 @@ OximeterImport::OximeterImport(QWidget *parent) :
OximeterImport::~OximeterImport()
{
if (!dummyday) {
if (dummyday != nullptr) {
delete dummyday;
}
if (!session) {
if (session != nullptr) {
delete session;
}
if (ELplethy != nullptr) {
delete ELplethy;
}
disconnect(sessbar, SIGNAL(sessionClicked(Session*)), this, SLOT(onSessionSelected(Session*)));
delete ui;
@ -146,17 +149,14 @@ void OximeterImport::on_nextButton_clicked()
break;
default:
ui->informationButton->setVisible(true);
ui->nextButton->setVisible(true);
}
ui->stackedWidget->setCurrentIndex(i);
}
void OximeterImport::updateStatus(QString msg)
{
qDebug() << "updateStatus to " << msg;
qDebug() << "oximod - updateStatus to " << msg;
ui->logBox->appendPlainText(msg);
ui->directImportStatus->setText(msg);
ui->liveStatusLabel->setText(msg);
@ -168,7 +168,7 @@ SerialOximeter * OximeterImport::detectOximeter()
const int PORTSCAN_TIMEOUT=30000;
const int delay=100;
qDebug() << "Attempt to detect Oximeter";
qDebug() << "oximod - Attempt to detect Oximeter";
ui->retryButton->setVisible(false);
QList<SerialOximeter *> loaders; // GetOxiLoaders();
@ -201,9 +201,9 @@ SerialOximeter * OximeterImport::detectOximeter()
oximodule = oxi;
break;
}
}
}
if (oximodule)
if (oximodule)
break;
QThread::msleep(delay);
@ -237,7 +237,7 @@ void OximeterImport::on_directImportButton_clicked()
ui->informationButton->setVisible(false);
ui->stackedWidget->setCurrentWidget(ui->directImportPage);
qDebug() << "Direct Import button clicked" ;
qDebug() << "oximod - Direct Import button clicked" ;
oximodule = detectOximeter();
if (!oximodule)
return;
@ -263,6 +263,9 @@ void OximeterImport::on_directImportButton_clicked()
oximodule->resetDevice();
int session_count = oximodule->getSessionCount();
QDateTime startTime = QDateTime();
int duration = 0;
qDebug() << "oximod - Session count: " << session_count;
if (session_count > 1) {
ui->stackedWidget->setCurrentWidget(ui->chooseSessionPage);
@ -279,13 +282,13 @@ void OximeterImport::on_directImportButton_clicked()
int h, m, s;
for (int i=0; i< session_count; ++i) {
int duration = oximodule->getDuration(i);
QDateTime datetime = oximodule->getDateTime(i);
duration = oximodule->getDuration(i);
startTime = oximodule->getDateTime(i);
h = duration / 3600;
m = (duration / 60) % 60;
s = duration % 60;
item = new QTableWidgetItem(datetime.date().toString(Qt::SystemLocaleShortDate)+" "+datetime.time().toString("HH:mm:ss"));
item = new QTableWidgetItem(startTime.date().toString(Qt::SystemLocaleShortDate)+" "+startTime.time().toString("HH:mm:ss"));
ui->tableOxiSessions->setItem(i, 0, item);
// item->setData(Qt::UserRole+1, datetime);
// item->setData(Qt::UserRole, i);
@ -306,20 +309,22 @@ void OximeterImport::on_directImportButton_clicked()
return;
} else if (session_count > 0) {
chosen_sessions.push_back(0);
oximodule->getDuration(0);
oximodule->setStartTime(oximodule->getDateTime(0));
duration = oximodule->getDuration(0);
startTime = oximodule->getDateTime(0);
oximodule->setStartTime(startTime);
qDebug() << "oximod - Session start time: " << startTime.toString();
}
doImport();
}
void OximeterImport::doImport()
{
qDebug() << "Starting doImport";
qDebug() << "oximod - Starting doImport";
if (oximodule->commandDriven()) {
if (chosen_sessions.size() == 0) {
qDebug() << "oximod - Chosen session size is zero - quitting";
ui->connectLabel->setText("<h2>"+tr("Nothing to import")+"</h2>");
updateStatus(tr("Your oximeter did not have any valid sessions."));
ui->cancelButton->setText(tr("Close"));
return;
@ -329,12 +334,10 @@ void OximeterImport::doImport()
} else {
ui->connectLabel->setText("<h2>"+tr("Select upload option on %1").arg(oximodule->loaderName())+"</h2>");
ui->logBox->appendPlainText(tr("You need to tell your oximeter to begin sending data to the computer."));
updateStatus(tr("Please connect your oximeter, enter it's menu and select upload to commence data transfer..."));
}
connect(oximodule, SIGNAL(updateProgress(int,int)), this, SLOT(doUpdateProgress(int,int)));
oximodule->Open("import");
if (oximodule->commandDriven()) {
@ -376,7 +379,7 @@ void OximeterImport::finishedImport(SerialOximeter * oxi)
{
Q_UNUSED(oxi);
qDebug() << "finished Import ";
qDebug() << "oximod - finished Import ";
connect(oximodule, SIGNAL(importComplete(SerialOximeter*)), this, SLOT(finishedImport(SerialOximeter*)));
ui->cancelButton->setVisible(true);
@ -403,7 +406,7 @@ void OximeterImport::on_fileImportButton_clicked()
const QString documentsFolder = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
qDebug() << "File Import button clicked";
qDebug() << "oximod - File Import button clicked";
QString filename = QFileDialog::getOpenFileName(nullptr , tr("Select a valid oximetry data file"), documentsFolder, tr("Oximetry Files (*.spo *.spor *.spo2 *.SpO2 *.dat)"));
@ -413,7 +416,7 @@ void OximeterImport::on_fileImportButton_clicked()
// Make sure filename dialog had time to close properly..
QApplication::processEvents();
qDebug() << "Chosen filename is " << filename;
qDebug() << "oximod - Chosen filename is " << filename;
QList<SerialOximeter *> loaders = GetOxiLoaders();
bool success = false;
@ -430,7 +433,7 @@ void OximeterImport::on_fileImportButton_clicked()
QMessageBox::warning(this, STR_MessageBox_Warning, tr("No Oximetry module could parse the given file:")+QString("\n\n%1").arg(filename), QMessageBox::Ok);
return;
}
qDebug() << "Using loader " << oximodule->loaderName();
qDebug() << "oximod - Using loader " << oximodule->loaderName();
ui->informationButton->setVisible(false);
importMode = IM_FILE;
@ -442,14 +445,14 @@ void OximeterImport::on_fileImportButton_clicked()
// oximodule->setStartTime( ??? ); Nope, it was set in the loader module by the file import routime
on_syncButton_clicked();
}
qDebug() << "Finished file import: Oximodule startTime is " << oximodule->startTime().toString("yyyy-MMM-dd HH:mm:ss");
qDebug() << "oximod - Finished file import: Oximodule startTime is " << oximodule->startTime().toString("yyyy-MMM-dd HH:mm:ss");
}
void OximeterImport::on_liveImportButton_clicked()
{
ui->informationButton->setVisible(false);
qDebug() << "Live Import button clicked";
qDebug() << "oximod - Live Import button clicked";
ui->stackedWidget->setCurrentWidget(ui->liveImportPage);
ui->liveImportPage->layout()->addWidget(ui->progressBar);
QApplication::processEvents();
@ -515,7 +518,7 @@ void OximeterImport::on_liveImportButton_clicked()
void OximeterImport::finishedRecording()
{
qDebug() << "Finished Recording";
qDebug() << "oximod - Finished Recording";
updateTimer.stop();
oximodule->closeDevice();
@ -539,7 +542,7 @@ void OximeterImport::finishedRecording()
void OximeterImport::on_retryButton_clicked()
{
qDebug() << "Retry button clicked";
qDebug() << "oximod - Retry button clicked";
if (ui->stackedWidget->currentWidget() == ui->directImportPage) {
on_directImportButton_clicked();
} else if (ui->stackedWidget->currentWidget() == ui->liveImportPage) {
@ -549,7 +552,7 @@ void OximeterImport::on_retryButton_clicked()
void OximeterImport::on_stopButton_clicked()
{
qDebug() << "Stop button clicked";
qDebug() << "oximod - Stop button clicked";
if (oximodule) {
oximodule->abort();
}
@ -557,8 +560,9 @@ void OximeterImport::on_stopButton_clicked()
void OximeterImport::on_calendarWidget_clicked(const QDate &date)
{
qDebug() << "Calendar widget clicked " << date.toString("yyyy-MMM-dd");
qDebug() << "oximod - Calendar widget clicked " << date.toString("yyyy-MMM-dd");
if (ui->radioSyncCPAP->isChecked()) {
qDebug() << "oximod - Syncing to a CPAP session";
Day * day = p_profile->GetGoodDay(date, MT_CPAP);
sessbar->clear();
@ -580,13 +584,13 @@ void OximeterImport::on_calendarWidget_clicked(const QDate &date)
ui->dateTimeEdit->setDateTime(time);
} else {
ui->sessbarLabel->setText(tr("No CPAP data available on %1").arg(date.toString(Qt::SystemLocaleLongDate)));
qDebug() << "Using oximeter time " << oximodule->startTime().toString("yyyy-MMM-dd hh:mm:ssap") << "on date " << date.toString(Qt::SystemLocaleLongDate);
qDebug() << "oximod - Using oximeter time " << oximodule->startTime().toString("yyyy-MMM-dd hh:mm:ssap") << "on date " << date.toString(Qt::SystemLocaleLongDate);
ui->dateTimeEdit->setDateTime(QDateTime(date,oximodule->startTime().time()));
}
sessbar->update();
} else if (ui->radioSyncOximeter) {
qDebug() << "Using oximeter date and time";
qDebug() << "oximod - Using oximeter date and time";
ui->sessbarLabel->setText(tr("%1").arg(date.toString(Qt::SystemLocaleLongDate)));
ui->dateTimeEdit->setDateTime(QDateTime(date, ui->dateTimeEdit->dateTime().time()));
}
@ -600,13 +604,13 @@ void OximeterImport::on_calendarWidget_selectionChanged()
void OximeterImport::onSessionSelected(Session * session)
{
QDateTime time=QDateTime::fromMSecsSinceEpoch(session->first(), Qt::LocalTime);
qDebug() << "Selected session starts at " << time.toString("yyyy-MMM-dd hh:mm:ssap");
qDebug() << "oximod - Selected session starts at " << time.toString("yyyy-MMM-dd hh:mm:ssap");
ui->dateTimeEdit->setDateTime(time);
}
void OximeterImport::on_sessionBackButton_clicked()
{
qDebug() << "Session Back button clicked";
qDebug() << "oximod - Session Back button clicked";
int idx = (sessbar->selected()-1);
if (idx >= 0) {
sessbar->setSelected(idx);
@ -618,7 +622,7 @@ void OximeterImport::on_sessionBackButton_clicked()
void OximeterImport::on_sessionForwardButton_clicked()
{
qDebug() << "Session Forward button clicked";
qDebug() << "oximod - Session Forward button clicked";
int idx = (sessbar->selected()+1);
if (idx < sessbar->count()) {
sessbar->setSelected(idx);
@ -630,6 +634,7 @@ void OximeterImport::on_sessionForwardButton_clicked()
void OximeterImport::on_radioSyncCPAP_clicked()
{
qDebug() << "oximod - Use CPAP Time button clicked";
on_calendarWidget_clicked(oximodule->startTime().date());
ui->syncCPAPGroup->setVisible(true);
@ -638,15 +643,18 @@ void OximeterImport::on_radioSyncCPAP_clicked()
void OximeterImport::on_radioSyncOximeter_clicked()
{
qDebug() << "Use OximeterTime button clicked";
qDebug() << "oximod - Use OximeterTime button clicked";
ui->syncCPAPGroup->setVisible(false);
if ( oximodule ) {
if (oximodule->isStartTimeValid()) {
qDebug() << "Oximeter time is valid " << oximodule->startTime().toString("yyyy-MMM-dd HH:mm:ssap");
qDebug() << "oximod - Oximeter time is " << oximodule->startTime().toString("yyyy-MMM-dd HH:mm:ssap");
ui->calendarWidget->setSelectedDate(oximodule->startTime().date());
ui->dateTimeEdit->setDateTime(oximodule->startTime());
} else
qDebug() << "Oximeter time is not valid";
} else {
qDebug() << "oximod - Oximeter time is faked" << oximodule->startTime().toString("yyyy-MMM-dd HH:mm:ssap");
ui->calendarWidget->setSelectedDate(oximodule->startTime().date());
ui->dateTimeEdit->setDateTime(oximodule->startTime());
}
}
}
@ -745,7 +753,7 @@ void OximeterImport::updateLiveDisplay()
void OximeterImport::on_cancelButton_clicked()
{
qDebug() << "Cancel button clicked";
qDebug() << "oximod - Cancel button clicked";
if (oximodule && oximodule->isStreaming()) {
oximodule->closeDevice();
oximodule->trashRecords();
@ -779,12 +787,12 @@ void OximeterImport::on_informationButton_clicked()
void OximeterImport::on_syncButton_clicked()
{
qDebug() << "Sync button clicked";
qDebug() << "oximod - Sync button clicked";
if (oximodule == nullptr) {
qCritical() << "OximeterImport::on_syncButton_clicked called when oximodule is null";
qCritical() << "oximod - OximeterImport::on_syncButton_clicked called when oximodule is null";
return;
}
qDebug() << "Oximodule Start Time is " << oximodule->startTime().toString("yyyy-MMM-dd HH.mm.ss") << "Duration: " << oximodule->getDuration(/* dummy */ 0 );
qDebug() << "oximod Start Time is " << oximodule->startTime().toString("yyyy-MMM-dd HH.mm.ss") << "Duration: " << oximodule->getDuration(/* dummy */ 0 );
ui->stackedWidget->setCurrentWidget(ui->syncPage);
@ -795,7 +803,7 @@ void OximeterImport::on_syncButton_clicked()
QDate last = p_profile->LastDay();
QDate oxidate = oximodule->startTime().date();
qDebug() << "Oximodule start date is " << oxidate.toString("yyyy-MMM-dd");
qDebug() << "oximod - start date is " << oxidate.toString("yyyy-MMM-dd");
if ((oxidate >= first) && (oxidate <= last)) {
@ -826,7 +834,7 @@ void OximeterImport::on_syncButton_clicked()
void OximeterImport::on_saveButton_clicked()
{
qDebug() << "Oximeter Save button clicked";
qDebug() << "oximod - Oximeter Save button clicked";
if (!oximodule) return;
QVector<OxiRecord> * oxirec = nullptr;
@ -837,8 +845,10 @@ void OximeterImport::on_saveButton_clicked()
return;
}
oxirec = oximodule->oxisessions[oximodule->startTime()];
if (oxirec->size() < 10)
if (oxirec->size() < 10) {
qDebug() << "oximod - oxirec size less than 10 - quitting";
return;
}
// this can move to SerialOximeter class process function...
@ -890,6 +900,7 @@ void OximeterImport::on_saveButton_clicked()
int size = oxirec->size();
// why was I skipping the first sample? not priming it anymore..
qDebug() << "oximod = Creating event list for pulse and O2 saturation";
for (int i=0; i < size; ++i) {
OxiRecord * rec = &(*oxirec)[i];
@ -973,7 +984,6 @@ void OximeterImport::on_saveButton_clicked()
session->setLast(OXI_SPO2, ti);
}
if (haveperf && ELperf && lastperf > 0) {
ELperf->AddEvent(ti, lastperf);
session->setLast(OXI_Perf, ti);
@ -990,6 +1000,8 @@ void OximeterImport::on_saveButton_clicked()
calcSPO2Drop(session);
calcPulseChange(session);
qDebug() << "oximod - Setting up machine and session";
mach->setModel(oximodule->getModel());
mach->setBrand(oximodule->getVendor());
@ -1023,11 +1035,15 @@ void OximeterImport::on_saveButton_clicked()
session->setOpened(true);
qDebug() << "oximod - Adding session to machine";
mach->AddSession(session);
qDebug() << "oximod - Saving machine";
mach->Save();
mach->SaveSummaryCache();
p_profile->StoreMachines();
mainwin->EnableTabs(true); // somebody has to do it...
mainwin->getDaily()->LoadDate(mainwin->getDaily()->getDate());
mainwin->getOverview()->ReloadGraphs();
@ -1040,7 +1056,7 @@ void OximeterImport::on_saveButton_clicked()
void OximeterImport::chooseSession()
{
qDebug() << "Oximeter Choose Session called";
qDebug() << "oximod - Oximeter Choose Session called";
selecting_session = false;
ui->stackedWidget->setCurrentWidget(ui->chooseSessionPage);
@ -1084,7 +1100,7 @@ void OximeterImport::chooseSession()
void OximeterImport::on_chooseSessionButton_clicked()
{
qDebug() << "Chosen session clicked";
qDebug() << "oximod - Chosen session clicked";
ui->chooseSessionButton->setVisible(false);
QTableWidgetItem * item_0 = ui->tableOxiSessions->item(ui->tableOxiSessions->currentRow(),0);
@ -1151,7 +1167,7 @@ void OximeterImport::on_oximeterType_currentIndexChanged(int index)
ui->oldCMS50specific->setVisible(false);
ui->newCMS50settingsPanel->setVisible(true);
break;
case 1: // Olds CMS50's
case 1: // Old CMS50's
ui->directImportButton->setEnabled(true);
ui->liveImportButton->setEnabled(true);
ui->fileImportButton->setEnabled(true);

View File

@ -918,7 +918,7 @@ background: qlineargradient( x1:0 y1:0, x2:1 y2:0, stop:0 white, stop:1 #cccccc)
</property>
<item>
<property name="text">
<string>CMS50Fv3.7+/H/I, Pulox PO-400/500</string>
<string>CMS50Fv3.7+/H/I, CMS50D+v4.6, Pulox PO-400/500</string>
</property>
</item>
<item>
@ -1033,7 +1033,7 @@ background: qlineargradient( x1:0 y1:0, x2:1 y2:0, stop:0 white, stop:1 #cccccc)
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Here you can enter a 7 character pet name for this oximeter.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Here you can enter a 7 character name for this oximeter.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="inputMask">
<string notr="true">nnnnnnn</string>
@ -1074,7 +1074,7 @@ background: qlineargradient( x1:0 y1:0, x2:1 y2:0, stop:0 white, stop:1 #cccccc)
<item>
<widget class="QCheckBox" name="cms50EraseAfterwards">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option will erase the imported session from your oximeter after import has completed. &lt;/p&gt;&lt;p&gt;Use with caution, becauseif something goes wrong before OSCAR saves your session, you won't get it back.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option will erase the imported session from your oximeter after import has completed. &lt;/p&gt;&lt;p&gt;Use with caution, because if something goes wrong before OSCAR saves your session, you can't get it back.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Erase session after successful upload</string>
@ -1103,7 +1103,7 @@ background: qlineargradient( x1:0 y1:0, x2:1 y2:0, stop:0 white, stop:1 #cccccc)
<item>
<widget class="QPushButton" name="directImportButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option allows you to import (via cable) from your oximeters internal recordings.&lt;/p&gt;&lt;p&gt;After selecting on this option, some oximeters will require you to do something in the devices menu to initiate the upload.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option allows you to import (via cable) from your oximeters internal recordings.&lt;/p&gt;&lt;p&gt;After selecting on this option, old Contec oximeters will require you to use the device's menu to initiate the upload.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="styleSheet">
<string notr="true"/>
@ -1316,7 +1316,7 @@ background: qlineargradient( x1:0 y1:0, x2:1 y2:0, stop:0 white, stop:1 #cccccc)
</font>
</property>
<property name="text">
<string>Please connect your oximeter device</string>
<string>Please connect your oximeter device, turn it on, and enter the menu</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>

View File

@ -1,5 +1,6 @@
/* OSCAR Preferences Dialog Implementation
/* OSCAR Preferences Dialog Implementation
*
* Copyright (c) 2019 The OSCAR Team
* Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
*
* This file is subject to the terms and conditions of the GNU General Public
@ -165,7 +166,16 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, Profile *_profile) :
ui->LockSummarySessionSplitting->setChecked(profile->session->lockSummarySessions());
ui->applicationFont->setCurrentFont(QApplication::font());
// macOS default system fonts are not in QFontCombobox because they are "private":
// See https://github.com/musescore/MuseScore/commit/0eecb165664a0196c2eee12e42fb273dcfc9c637
// The below makes sure any default system font is present in QFontComboBox.
QString systemFontFamily = QFontDatabase::systemFont(QFontDatabase::GeneralFont).family();
if (-1 == ui->applicationFont->findText(systemFontFamily)) {
ui->applicationFont->addItem(systemFontFamily);
}
// If the current font is the system font, setCurrentFont() won't work as intended,
// so select the font by searching for its name, which will always work.
ui->applicationFont->setCurrentIndex(ui->applicationFont->findText(QApplication::font().family()));
//ui->applicationFont->setFont(QApplication::font());
ui->applicationFontSize->setValue(QApplication::font().pointSize());
ui->applicationFontBold->setChecked(QApplication::font().weight() == QFont::Bold);

View File

@ -39,8 +39,6 @@ void Report::PrintReport(gGraphView *gv, QString name, QDate date)
return;
}
//QString username = p_profile->Get(QString("_{") + QString(STR_UI_UserName) + "}_");
bool print_bookmarks = false;
if (name == STR_TR_Daily) {
@ -69,7 +67,8 @@ void Report::PrintReport(gGraphView *gv, QString name, QDate date)
printer = new QPrinter(QPrinter::HighResolution);
#ifdef Q_WS_X11
#ifdef Q_OS_LINUX
QString username = p_profile->Get(QString("_{") + QString(STR_UI_UserName) + "}_");
printer->setPrinterName("Print to File (PDF)");
printer->setOutputFormat(QPrinter::PdfFormat);
QString filename = p_pref->Get("{home}/") + name + username + date.toString(Qt::ISODate) + ".pdf";

View File

@ -24,6 +24,7 @@ extern MainWindow *mainwin;
// HTML components that make up Statistics page and printed report
QString htmlReportHeader = ""; // Page header
QString htmlReportHeaderPrint = ""; // Page header
QString htmlUsage = ""; // CPAP and Oximetry
QString htmlMachineSettings = ""; // Machine (formerly Rx) changes
QString htmlMachines = ""; // Machines used in this profile
@ -551,6 +552,7 @@ Statistics::Statistics(QObject *parent) :
rows.push_back(StatisticsRow("IPAP", SC_MIN, MT_CPAP));
rows.push_back(StatisticsRow("IPAP", SC_MAX, MT_CPAP));
rows.push_back(StatisticsRow("", SC_HEADING, MT_OXIMETER)); // Just adds some space
rows.push_back(StatisticsRow(tr("Oximeter Statistics"), SC_HEADING, MT_OXIMETER));
rows.push_back(StatisticsRow("", SC_DAYS, MT_OXIMETER));
rows.push_back(StatisticsRow("", SC_COLUMNHEADERS, MT_OXIMETER));
@ -596,7 +598,7 @@ QString Statistics::getUserInfo () {
QString address = p_profile->user->address();
address.replace("\n", "<br/>");
QString userinfo;
QString userinfo = "";
if (!p_profile->user->firstName().isEmpty()) {
userinfo = tr("Name: %1, %2").arg(p_profile->user->lastName()).arg(p_profile->user->firstName()) + "<br/>";
@ -614,40 +616,79 @@ QString Statistics::getUserInfo () {
}
}
while (userinfo.length() > 0 && userinfo.endsWith("<br/>")) // Strip trailing newlines
userinfo = userinfo.mid(0, userinfo.length()-5);
return userinfo;
}
const QString table_width = "width=99%";
// Create the page header in HTML. Includes everything from <head> through <body>
QString Statistics::htmlHeader(bool showheader)
QString Statistics::generateHeader(bool onScreen)
{
QString html = QString("<html><head>")+
"<style type='text/css'>";
if (onScreen) {
html += "p,a,td,body { font-family: '" + QApplication::font().family() + "'; }"
"p,a,td,body { font-size: " + QString::number(QApplication::font().pointSize() + 2) + "px; }";
} else {
html += "p,a,td,body { font-family: 'Helvetica'; }";
// "p,a,td,body { font-size: 10px; }";
}
qDebug() << "generateHeader font" << html;
html += "table.curved {" // Borders not supported without webkit
// "border: 1px solid gray;"
// "border-radius:10px;"
// "-moz-border-radius:10px;"
// "-webkit-border-radius:10px;"
// "page-break-after:auto;"
// "-fs-table-paginate: paginate;"
"}"
"tr.datarow:nth-child(even) {"
"background-color: #f8f8f8;"
"}"
"table { page-break-after:auto; -fs-table-paginate: paginate; }"
"tr { page-break-inside:avoid; page-break-after:auto }"
"td { page-break-inside:avoid; page-break-after:auto }"
"thead { display:table-header-group; }"
"tfoot { display:table-footer-group; }"
"</style>"
"<link rel='stylesheet' type='text/css' href='qrc:/docs/tooltips.css' />"
"<script type='text/javascript'>"
"function ChangeColor(tableRow, highLight)"
"{ tableRow.style.backgroundColor = highLight; }"
"function Go(url) { throw(url); }"
"</script>"
"</head>"
"<body leftmargin=0 topmargin=5 rightmargin=0>";
QPixmap logoPixmap(":/icons/logo-lg.png");
if (showheader) {
html += "<div align=center><table class=curved width='99%'>"
html += "<div align=center><table class=curved width='100%'>"
"<tr>"
"<td align='left' valign='middle'>" + getUserInfo() + "</td>"
"<td align='right' valign='middle' width='150'>"
"<td align='right' valign='middle' width='200'>"
"<font size='+2'>" + STR_TR_OSCAR + "&nbsp;&nbsp;&nbsp;</font><br/>"
"<font size='+1'>" + QObject::tr("Usage Statistics") + "&nbsp;&nbsp;&nbsp;</font>"
"</td>"
"<td align='right' valign='middle' width='150'>" + resizeHTMLPixmap(logoPixmap,120,120)+"&nbsp;&nbsp;&nbsp;<br/>"
"<td align='right' valign='middle' width='110'>" + resizeHTMLPixmap(logoPixmap,80,80)+"&nbsp;&nbsp;&nbsp;<br/>"
"</td>"
"</tr>"
"</table>"
"</div><br/>";
}
"</div>";
return html;
}
// HTML for page footer
QString Statistics::htmlFooter(bool showinfo)
QString Statistics::generateFooter(bool showinfo)
{
QString html;
@ -1015,7 +1056,7 @@ QString Statistics::GenerateCPAPUsage()
// Prepare top of table
html += "<div align=center>";
html += "<table class=curved "+table_width+">";
html += "<table class=curved width="+table_width+">";
// Compute number of monthly periods for a monthly rather than standard time distribution
int number_periods = 0;
@ -1146,14 +1187,14 @@ QString Statistics::GenerateCPAPUsage()
name = calcnames[row.calc].arg(schema::channel[id].fullname());
}
QString line;
line += QString("<tr class=datarow><td width=25%>%1</td>").arg(name);
line += QString("<tr class=datarow><td width=24%>%1</td>").arg(name);
int np = periods.size();
int width;
for (int j=0; j < np; j++) {
if (p_profile->general->statReportMode() == STAT_MODE_MONTHLY) {
width = j < np-1 ? 6 : 100 - (25 + 6*(np-1));
width = j < np-1 ? 6 : 100 - (24 + 6*(np-1));
} else {
width = 75/np;
width = 76/np;
}
line += QString("<td width=%1%>").arg(width);
@ -1177,8 +1218,9 @@ QString Statistics::GenerateCPAPUsage()
// Create the HTML that will be the Statistics page.
QString Statistics::GenerateHTML()
{
htmlReportHeader = htmlHeader(true);
htmlReportFooter = htmlFooter(true);
htmlReportHeader = generateHeader(true);
htmlReportHeaderPrint = generateHeader(false);
htmlReportFooter = generateFooter(true);
htmlUsage = GenerateCPAPUsage();
@ -1189,69 +1231,52 @@ QString Statistics::GenerateHTML()
htmlMachineSettings = GenerateRXChanges();
htmlMachines = GenerateMachineList();
UpdateRecordsBox();
QString htmlScript = "<script type='text/javascript' language='javascript' src='qrc:/docs/script.js'></script>";
return htmlReportHeader + htmlUsage + htmlMachineSettings + htmlMachines + htmlScript + htmlReportFooter;
}
// Print the Statistics page on printer
void Statistics::printReport(QWidget * parent) {
QPrinter printer(QPrinter::HighResolution);
QPrinter printer(QPrinter::ScreenResolution); // ScreenResolution required for graphics sizing
#ifdef Q_OS_LINUX
printer.setPrinterName("Print to File (PDF)");
printer.setOutputFormat(QPrinter::PdfFormat);
QString name = "Statistics";
QString datestr = QDate::currentDate().toString(Qt::ISODate);
// if (ui->tabWidget->currentWidget() == ui->statisticsTab) {
// name = "Statistics";
// datestr = QDate::currentDate().toString(Qt::ISODate);
// } else if (ui->tabWidget->currentWidget() == ui->helpTab) {
// name = "Help";
// datestr = QDateTime::currentDateTime().toString(Qt::ISODate);
// } else { name = "Unknown"; }
QString filename = p_pref->Get("{home}/") + name + "_" + p_profile->user->userName() + "_" + datestr + ".pdf";
printer.setOutputFileName(filename);
#endif
printer.setPrintRange(QPrinter::AllPages);
// if (ui->tabWidget->currentWidget() == ui->statisticsTab) {
// printer.setOrientation(QPrinter::Landscape);
// } else {
printer.setOrientation(QPrinter::Portrait);
//}
printer.setFullPage(false); // This has nothing to do with scaling
printer.setOrientation(QPrinter::Portrait);
printer.setFullPage(false); // Print only on printable area of page and not in non-printable margins
printer.setNumCopies(1);
printer.setResolution(1200);
//printer.setPaperSize(QPrinter::A4);
//printer.setOutputFormat(QPrinter::PdfFormat);
printer.setPageMargins(5, 5, 5, 5, QPrinter::Millimeter);
printer.setPageMargins(10, 10, 10, 10, QPrinter::Millimeter);
// Show print dialog to user and allow them to change settings as desired
QPrintDialog pdlg(&printer, parent);
if (pdlg.exec() == QPrintDialog::Accepted) {
QTextBrowser b;
QPainter painter;
painter.begin(&printer);
QTextDocument doc;
QSizeF printArea = printer.pageRect().size();
doc.setPageSize(printArea); // Set document to print area, removing default 2cm margins
qDebug() << "print area" << printArea;
QRect rect = printer.pageRect();
b.setHtml(htmlReportHeader + htmlUsage + htmlMachineSettings + htmlMachines + htmlReportFooter);
b.resize(rect.width()/4, rect.height()/4);
b.setFrameShape(QFrame::NoFrame);
// QFont font = doc.defaultFont();
QFont font = QFont("Helvetica");
font.setPointSize(10 * (printArea.width()/1200.0)); // Scale the font
doc.setDefaultFont(font);
qDebug() << "Printer font set to" << font << "and printer default font is now" << doc.defaultFont();
double xscale = printer.pageRect().width()/double(b.width());
double yscale = printer.pageRect().height()/double(b.height());
double scale = qMin(xscale, yscale);
painter.translate(printer.paperRect().x() + printer.pageRect().width()/2, printer.paperRect().y() + printer.pageRect().height()/2);
painter.scale(scale, scale);
painter.translate(-b.width()/2, -b.height()/2);
b.render(&painter, QPoint(0,0));
painter.end();
doc.setHtml(htmlReportHeaderPrint + htmlUsage + htmlMachineSettings + htmlMachines + htmlReportFooter);
doc.print(&printer);
}
}

View File

@ -11,6 +11,8 @@
#include <QObject>
#include <QMainWindow>
#include <QPrinter>
#include <QPainter>
#include <QHash>
#include <QList>
#include "SleepLib/schema.h"
@ -164,12 +166,7 @@ class Statistics : public QObject
void saveRXChanges();
void updateRXChanges();
QString getUserInfo();
QString getRDIorAHIText();
QString GenerateHTML();
QString GenerateMachineList();
QString GenerateRXChanges();
QString GenerateCPAPUsage();
QString UpdateRecordsBox();
@ -177,9 +174,16 @@ class Statistics : public QObject
protected:
QString getUserInfo();
QString getRDIorAHIText();
QString htmlNoData();
QString htmlHeader(bool showheader);
QString htmlFooter(bool showinfo=true);
QString generateHeader(bool showheader);
QString generateFooter(bool showinfo=true);
QString GenerateMachineList();
QString GenerateRXChanges();
QString GenerateCPAPUsage();
// Using a map to maintain order
QList<StatisticsRow> rows;