Initial F&P Icon support. (Initial, as in basic, and probably broken. :)

This commit is contained in:
Mark Watkins 2012-01-23 00:39:20 +10:00
parent 4fb00cb2a1
commit cadb96eb27
12 changed files with 608 additions and 12 deletions

View File

@ -76,6 +76,7 @@ const QString STR_MACH_ResMed="ResMed";
const QString STR_MACH_PRS1="PRS1";
const QString STR_MACH_Journal="Journal";
const QString STR_MACH_Intellipap="Intellipap";
const QString STR_MACH_FPIcon="FPIcon";
const QString STR_MACH_CMS50="CMS50";
const QString STR_MACH_ZEO="Zeo";

View File

@ -0,0 +1,467 @@
/*
SleepLib Fisher & Paykel Icon Loader Implementation
Author: Mark Watkins <jedimark64@users.sourceforge.net>
License: GPL
*/
#include <QDir>
#include <QProgressBar>
#include <QMessageBox>
#include <QDataStream>
#include "icon_loader.h"
extern QProgressBar *qprogress;
FPIcon::FPIcon(Profile *p,MachineID id)
:CPAP(p,id)
{
m_class=fpicon_class_name;
properties[STR_PROP_Brand]="Fisher & Paykel";
properties[STR_PROP_Model]=STR_MACH_FPIcon;
}
FPIcon::~FPIcon()
{
}
FPIconLoader::FPIconLoader()
{
epoch=QDateTime(QDate(1970,1,1),QTime(0,0,0)).secsTo(QDateTime(QDate(1995,1,1),QTime(0,0,0)));
m_buffer=NULL;
}
FPIconLoader::~FPIconLoader()
{
for (QHash<QString,Machine *>::iterator i=MachList.begin(); i!=MachList.end(); i++) {
delete i.value();
}
}
int FPIconLoader::Open(QString & path,Profile *profile)
{
// Check for SL directory
// Check for DV5MFirm.bin?
QString newpath;
if (path.endsWith("/"))
path.chop(1);
QString dirtag="FPHCARE";
if (path.endsWith(QDir::separator()+dirtag)) {
newpath=path;
} else {
newpath=path+QDir::separator()+dirtag;
}
newpath+="/ICON/";
QString filename;
QDir dir(newpath);
if ((!dir.exists() || !dir.isReadable()))
return 0;
dir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Name);
QFileInfoList flist=dir.entryInfoList();
QStringList SerialNumbers;
bool ok;
for (int i=0;i<flist.size();i++) {
QFileInfo fi=flist.at(i);
QString filename=fi.fileName();
filename.toInt(&ok);
if (ok) {
SerialNumbers.push_back(filename);
}
}
Machine *m;
QString npath;
for (int i=0;i<SerialNumbers.size();i++) {
QString & sn=SerialNumbers[i];
m=CreateMachine(sn,profile);
npath=newpath+"/"+sn;
try {
if (m) OpenMachine(m,npath,profile);
} catch(OneTypePerDay e) {
profile->DelMachine(m);
MachList.erase(MachList.find(sn));
QMessageBox::warning(NULL,"Import Error","This Machine Record cannot be imported in this profile.\nThe Day records overlap with already existing content.",QMessageBox::Ok);
delete m;
}
}
return MachList.size();
}
int FPIconLoader::OpenMachine(Machine *mach, QString & path, Profile * profile)
{
qDebug() << "Opening FPIcon " << path;
QDir dir(path);
if (!dir.exists() || (!dir.isReadable()))
return false;
dir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Name);
QFileInfoList flist=dir.entryInfoList();
QString filename,fpath;
if (qprogress) qprogress->setValue(0);
QStringList summary, log, flw, det;
for (int i=0;i<flist.size();i++) {
QFileInfo fi=flist.at(i);
filename=fi.fileName();
fpath=path+"/"+filename;
if (filename.left(3).toUpper()=="SUM") {
summary.push_back(fpath);
OpenSummary(mach,fpath,profile);
} else if (filename.left(3).toUpper()=="DET") {
det.push_back(fpath);
} else if (filename.left(3).toUpper()=="FLW") {
flw.push_back(fpath);
} else if (filename.left(3).toUpper()=="LOG") {
log.push_back(fpath);
}
}
for (int i=0;i<det.size();i++) {
OpenDetail(mach,det[i],profile);
}
return true;
}
bool FPIconLoader::OpenFLW(Machine * mach,QString filename, Profile * profile)
{
qDebug() << filename;
QByteArray header;
QFile file(filename);
if (!file.open(QFile::ReadOnly)) {
qDebug() << "Couldn't open" << filename;
return false;
}
header=file.read(0x200);
if (header.size()!=0x200) {
qDebug() << "Short file" << filename;
return false;
}
unsigned char hsum=0xff;
for (int i=0;i<0x1ff;i++) {
hsum+=header[i];
}
if (hsum!=header[0x1ff]) {
qDebug() << "Header checksum mismatch" << filename;
}
QByteArray data;
data=file.readAll();
QDataStream in(data);
in.setVersion(QDataStream::Qt_4_6);
in.setByteOrder(QDataStream::LittleEndian);
quint16 t1,t2;
quint32 ts;
//QByteArray line;
char * buf=data.data();
do {
in >> t1;
in >> t2;
ts=(t1*86400)+(t2*1.5);
ts+=epoch;
if (!Sessions.contains(ts))
break;
// ends in 0xFF FF FF 7F
} while (!in.atEnd());
return true;
}
bool FPIconLoader::OpenSummary(Machine * mach,QString filename, Profile * profile)
{
qDebug() << filename;
QByteArray header;
QFile file(filename);
if (!file.open(QFile::ReadOnly)) {
qDebug() << "Couldn't open" << filename;
return false;
}
header=file.read(0x200);
if (header.size()!=0x200) {
qDebug() << "Short file" << filename;
return false;
}
unsigned char hsum=0xff;
for (int i=0;i<0x1ff;i++) {
hsum+=header[i];
}
if (hsum!=header[0x1ff]) {
qDebug() << "Header checksum mismatch" << filename;
}
QByteArray data;
data=file.readAll();
long size=data.size(),pos=0;
QDataStream in(data);
in.setVersion(QDataStream::Qt_4_6);
in.setByteOrder(QDataStream::LittleEndian);
quint16 t1,t2;
quint32 ts;
//QByteArray line;
unsigned char a1,a2, a3,a4, a5, p1, p2, p3, p4, p5, j1, j2, j3 ,j4,j5,j6,j7, x1, x2;
quint16 d1,d2,d3;
QDateTime datetime;
QDate date;
QTime time;
do {
in >> t1;
in >> t2;
ts=(t1*86400)+(t2*1.5);
ts+=epoch;
//ts*=1;
datetime=QDateTime::fromTime_t(ts);
date=datetime.date();
time=datetime.time();
// the following two quite often match in value
in >> a1; // 0x04
in >> a2; // 0x05
in >> a3; // 0x06
in >> a4; // 0x07 // pressure value?
in >> a5; // 0x08
in >> d1; // 0x09
in >> d2; // 0x0b
in >> d3; // 0x0d // offset 0x0d is always more than offset 0x08
in >> p1; // 0x0f
in >> p2; // 0x10
in >> j1; // 0x11
in >> j2; // 0x12
in >> j3; // 0x13
in >> j4; // 0x14
in >> j5; // 0x15
in >> j6; // 0x16
in >> j7; // 0x17
in >> p3; // 0x18
in >> p4; // 0x19
in >> p5; // 0x1a
in >> x1; // 0x1b
in >> x2; // 0x1c
if (!mach->SessionExists(ts)) {
Session *sess=new Session(mach,ts);
// sess->setCount(CPAP_Obstructive,j1);
// sess->setCount(CPAP_Hypopnea,j2);
// sess->setCount(CPAP_ClearAirway,j3);
// sess->setCount(CPAP_Apnea,j4);
//sess->setCount(CPAP_,j5);
if (p1!=p2) {
sess->settings[CPAP_Mode]=(int)MODE_APAP;
sess->settings[CPAP_PressureMin]=p4/10.0;
sess->settings[CPAP_PressureMax]=p3/10.0;
} else {
sess->settings[CPAP_Mode]=(int)MODE_CPAP;
sess->settings[CPAP_Pressure]=p1/10.0;
}
Sessions[ts]=sess;
}
} while (!in.atEnd());
return true;
}
bool FPIconLoader::OpenDetail(Machine * mach, QString filename, Profile * profile)
{
qDebug() << filename;
QByteArray header;
QFile file(filename);
if (!file.open(QFile::ReadOnly)) {
qDebug() << "Couldn't open" << filename;
return false;
}
header=file.read(0x200);
if (header.size()!=0x200) {
qDebug() << "Short file" << filename;
return false;
}
unsigned char hsum=0;
for (int i=0;i<0x1ff;i++) {
hsum+=header[i];
}
if (hsum!=header[0x1ff]) {
qDebug() << "Header checksum mismatch" << filename;
}
QByteArray index;
index=file.read(0x800);
long size=index.size(),pos=0;
QDataStream in(index);
in.setVersion(QDataStream::Qt_4_6);
in.setByteOrder(QDataStream::LittleEndian);
quint32 ts;
QDateTime datetime;
QDate date;
QTime time;
//FPDetIdx *idx=(FPDetIdx *)index.data();
QVector<quint32> times;
QVector<quint16> start;
QVector<quint8> records;
quint16 t1,t2;
quint16 strt;
quint8 recs;
int totalrecs=0;
do {
in >> t1; // 0x00 day?
in >> t2; // 0x02 time?
if (t1==0xffff) break;
//ts = (t1 << 16) + t2;
ts=(t1*86400)+(t2*1.5);
ts+=epoch;
datetime=QDateTime::fromTime_t(ts);
date=datetime.date();
time=datetime.time();
in >> strt;
in >> recs;
totalrecs+=recs;
if (Sessions.contains(ts)) {
times.push_back(ts);
start.push_back(strt);
records.push_back(recs);
}
} while (!in.atEnd());
QByteArray databytes=file.readAll();
in.setVersion(QDataStream::Qt_4_6);
in.setByteOrder(QDataStream::BigEndian);
// 5 byte repeating patterns
quint8 * data=(quint8 *)databytes.data();
qint64 ti;
quint8 pressure,leak, a1,a2,a3;
SessionID sessid;
Session *sess;
int idx;
for (int r=0;r<start.size();r++) {
sessid=times[r];
sess=Sessions[sessid];
ti=qint64(sessid)*1000L;
sess->really_set_first(ti);
EventList * LK=sess->AddEventList(CPAP_LeakTotal,EVL_Event,1);
EventList * PR=sess->AddEventList(CPAP_Pressure,EVL_Event,0.1);
EventList * FLG=sess->AddEventList(CPAP_FLG,EVL_Event);
EventList * OA=sess->AddEventList(CPAP_Obstructive,EVL_Event);
EventList * H=sess->AddEventList(CPAP_Hypopnea,EVL_Event);
EventList * FL=sess->AddEventList(CPAP_FlowLimit,EVL_Event);
unsigned stidx=start[r];
int rec=records[r];
idx=stidx*5;
for (int i=0;i<rec;i++) {
pressure=data[idx];
leak=data[idx+1];
a1=data[idx+2];
a2=data[idx+3];
a3=data[idx+4];
PR->AddEvent(ti,pressure);
LK->AddEvent(ti,leak);
if (a1>0) OA->AddEvent(ti,a1);
if (a2>0) H->AddEvent(ti,a2);
if (a3>0) FL->AddEvent(ti,a3);
FLG->AddEvent(ti,a3);
ti+=300000L;
idx+=5;
}
sess->really_set_last(ti-300000L);
sess->SetChanged(true);
mach->AddSession(sess,profile);
}
mach->Save();
return 1;
}
Machine *FPIconLoader::CreateMachine(QString serial,Profile *profile)
{
if (!profile)
return NULL;
qDebug() << "Create Machine " << serial;
QList<Machine *> ml=profile->GetMachines(MT_CPAP);
bool found=false;
QList<Machine *>::iterator i;
for (i=ml.begin(); i!=ml.end(); i++) {
if (((*i)->GetClass()==fpicon_class_name) && ((*i)->properties[STR_PROP_Serial]==serial)) {
MachList[serial]=*i;
found=true;
break;
}
}
if (found) return *i;
Machine *m=new FPIcon(profile,0);
MachList[serial]=m;
profile->AddMachine(m);
m->properties[STR_PROP_Serial]=serial;
m->properties[STR_PROP_DataVersion]=QString::number(fpicon_data_version);
QString path="{"+STR_GEN_DataFolder+"}/"+m->GetClass()+"_"+serial+"/";
m->properties[STR_PROP_Path]=path;
m->properties[STR_PROP_BackupPath]=path+"Backup/";
return m;
}
bool fpicon_initialized=false;
void FPIconLoader::Register()
{
if (fpicon_initialized) return;
qDebug() << "Registering F&P Icon Loader";
RegisterLoader(new FPIconLoader());
//InitModelMap();
fpicon_initialized=true;
}

View File

@ -0,0 +1,85 @@
/*
SleepLib Fisher & Paykel Icon Loader Implementation
Author: Mark Watkins <jedimark64@users.sourceforge.net>
License: GPL
*/
#ifndef ICON_LOADER_H
#define ICON_LOADER_H
#include "SleepLib/machine.h"
#include "SleepLib/machine_loader.h"
#include "SleepLib/profiles.h"
//********************************************************************************************
/// IMPORTANT!!!
//********************************************************************************************
// Please INCREMENT the following value when making changes to this loaders implementation.
//
const int fpicon_data_version=2;
//
//********************************************************************************************
/*! \class FPIcon
\brief F&P Icon customized machine object
*/
class FPIcon:public CPAP
{
public:
FPIcon(Profile *p,MachineID id=0);
virtual ~FPIcon();
};
const int fpicon_load_buffer_size=1024*1024;
const QString fpicon_class_name=STR_MACH_FPIcon;
/*! \class FPIconLoader
\brief Loader for Fisher & Paykel Icon data
This is only relatively recent addition and still needs more work
*/
class FPIconLoader : public MachineLoader
{
public:
FPIconLoader();
virtual ~FPIconLoader();
//! \brief Scans path for F&P Icon data signature, and Loads any new data
virtual int Open(QString & path,Profile *profile);
int OpenMachine(Machine *mach, QString & path, Profile * profile);
bool OpenSummary(Machine *mach, QString path, Profile * profile);
bool OpenDetail(Machine *mach, QString path, Profile * profile);
bool OpenFLW(Machine * mach,QString filename, Profile * profile);
//! \brief Returns SleepLib database version of this F&P Icon loader
virtual int Version() { return fpicon_data_version; }
//! \brief Returns the machine class name of this CPAP machine, "FPIcon"
virtual const QString & ClassName() { return fpicon_class_name; }
//! \brief Creates a machine object, indexed by serial number
Machine *CreateMachine(QString serial,Profile *profile);
//! \brief Registers this MachineLoader with the master list, so F&P Icon data can load
static void Register();
protected:
QString last;
QHash<QString,Machine *> MachList;
QHash<SessionID, Session *> Sessions;
unsigned char * m_buffer;
quint32 epoch;
};
#endif // ICON_LOADER_H

View File

@ -6,7 +6,6 @@ Author: Mark Watkins <jedimark64@users.sourceforge.net>
License: GPL
Notes: Intellipap requires the SmartLink attachment to access this data.
It does not seem to record multiple days, graph data is overwritten each time..
*/

View File

@ -15,6 +15,7 @@
#include <QDebug>
using namespace std;
// Do not change these without considering the consequences.. For one the Loader needs changing & version increase
typedef quint32 ChannelID;
typedef long MachineID;
typedef long SessionID;
@ -37,9 +38,9 @@ qint64 timezoneOffset();
/*! \enum SummaryType
\brief Calculation method to select from dealing with summary information
\brief Calculation/Display method to select from dealing with summary information
*/
enum SummaryType { ST_CNT, ST_SUM, ST_AVG, ST_WAVG, ST_PERC, ST_90P, ST_MIN, ST_MAX, ST_CPH, ST_SPH, ST_FIRST, ST_LAST, ST_HOURS, ST_SESSIONS, ST_SETMIN, ST_SETAVG, ST_SETMAX, ST_SETWAVG, ST_SETSUM };
enum SummaryType { ST_CNT, ST_SUM, ST_AVG, ST_WAVG, ST_PERC, ST_90P, ST_MIN, ST_MAX, ST_CPH, ST_SPH, ST_FIRST, ST_LAST, ST_HOURS, ST_SESSIONS, ST_SETMIN, ST_SETAVG, ST_SETMAX, ST_SETWAVG, ST_SETSUM, ST_SESSIONID, ST_DATE };
/*! \enum MachineType
\brief Generalized type of a machine

View File

@ -79,7 +79,8 @@ SOURCES += main.cpp\
quazip/qioapi.cpp \
quazip/JlCompress.cpp \
UpdaterWindow.cpp \
SleepLib/common.cpp
SleepLib/common.cpp \
SleepLib/loader_plugins/icon_loader.cpp
unix:SOURCES += qextserialport/posix_qextserialport.cpp
unix:!macx:SOURCES += qextserialport/qextserialenumerator_unix.cpp
@ -156,7 +157,8 @@ HEADERS += \
quazip/ioapi.h \
quazip/crypt.h \
UpdaterWindow.h \
SleepLib/common.h
SleepLib/common.h \
SleepLib/loader_plugins/icon_loader.h
FORMS += \

View File

@ -831,7 +831,7 @@ void Daily::Load(QDate date)
.arg("#F88017").arg("black").arg(tr("AHI")).arg(schema::channel[CPAP_AHI].description()).arg(ahi,0,'f',2);
}
if (cpap->machine->GetClass()==STR_MACH_ResMed) {
if (cpap->machine->GetClass()==STR_MACH_ResMed || cpap->machine->GetClass()==STR_MACH_FPIcon) {
cs="4 width='70%' align=center>";
} else cs="2 width='50%'>";
html+="<tr><td valign=top colspan="+cs+"<table cellspacing=0 cellpadding=1 border=0 width='100%'>";
@ -846,8 +846,13 @@ void Daily::Load(QDate date)
html+=QString("<tr><td align='left' bgcolor='%1'><b><font color='%2'><a class=info href='event=%6'>%3<span>%4</span></a></font></b></td><td width=20% bgcolor='%1'><b><font color='%2'>%5</font></b></td></tr>\n")
.arg("#40afbf").arg("black").arg(tr("Obstructive")).arg(schema::channel[CPAP_Obstructive].description()).arg(oai,0,'f',2).arg(CPAP_Obstructive);
html+=QString("<tr><td align='left' bgcolor='%1'><b><font color='%2'><a class=info href='event=%6'>%3<span>%4</span></a></font></b></td><td width=20% bgcolor='%1'><b><font color='%2'>%5</font></b></td></tr>\n")
if (cpap->machine->GetClass()==STR_MACH_FPIcon) {
html+=QString("<tr><td align='left' bgcolor='%1'><b><font color='%2'><a class=info href='event=%6'>%3<span>%4</span></a></font></b></td><td width=20% bgcolor='%1'><b><font color='%2'>%5</font></b></td></tr>\n")
.arg("#404040").arg("white").arg(tr("Flow Limit")).arg(schema::channel[CPAP_FlowLimit].description()).arg(fli,0,'f',2).arg(CPAP_FlowLimit);
} else {
html+=QString("<tr><td align='left' bgcolor='%1'><b><font color='%2'><a class=info href='event=%6'>%3<span>%4</span></a></font></b></td><td width=20% bgcolor='%1'><b><font color='%2'>%5</font></b></td></tr>\n")
.arg("#b254cd").arg("black").arg(tr("Clear Airway")).arg(schema::channel[CPAP_ClearAirway].description()).arg(cai,0,'f',2).arg(CPAP_ClearAirway);
}
if (cpap->machine->GetClass()==STR_MACH_Intellipap) {
html+=QString("<tr><td align='left' bgcolor='%1'><b><font color='%2'><a class=info href='event=%6'>%3<span>%4</span></a></font></b></td><td width=20% bgcolor='%1'><b><font color='%2'>%5%</font></b></td></tr>\n")

View File

@ -135,6 +135,20 @@ void ExportCSV::on_exportButton_clicked()
const QString sep=",";
const QString newline="\n";
// if (ui->rb1_details->isChecked()) {
// fields.append(DumpField(NoChannel,MT_CPAP,ST_DATE));
// } else {
// header=tr("DateTime")+sep+tr("Session")+sep+tr("Event")+sep+tr("Data/Duration");
// } else {
// if (ui->rb1_Summary->isChecked()) {
// header=tr("Date")+sep+tr("Session Count")+sep+tr("Start")+sep+tr("End")+sep+tr("Total Time")+sep+tr("AHI");
// } else if (ui->rb1_Sessions->isChecked()) {
// header=tr("Date")+sep+tr("Session")+sep+tr("Start")+sep+tr("End")+sep+tr("Total Time")+sep+tr("AHI");
// }
// }
// fields.append(DumpField(NoChannel,MT_CPAP,ST_SESSIONS));
QList<ChannelID> countlist,avglist,p90list;
countlist.append(CPAP_Hypopnea);
countlist.append(CPAP_Obstructive);
@ -144,8 +158,15 @@ void ExportCSV::on_exportButton_clicked()
countlist.append(CPAP_VSnore2);
countlist.append(CPAP_RERA);
countlist.append(CPAP_FlowLimit);
countlist.append(CPAP_NRI);
countlist.append(CPAP_ExP);
countlist.append(CPAP_LeakFlag);
countlist.append(CPAP_UserFlag1);
countlist.append(CPAP_UserFlag2);
countlist.append(CPAP_PressurePulse);
avglist.append(CPAP_Pressure);
avglist.append(CPAP_IPAP);
avglist.append(CPAP_EPAP);
@ -153,6 +174,7 @@ void ExportCSV::on_exportButton_clicked()
p90list.append(CPAP_Pressure);
p90list.append(CPAP_IPAP);
p90list.append(CPAP_EPAP);
EventDataType percent=0.90;
// Not sure this section should be translateable.. :-/
if (ui->rb1_details->isChecked()) {
@ -164,11 +186,11 @@ void ExportCSV::on_exportButton_clicked()
header=tr("Date")+sep+tr("Session")+sep+tr("Start")+sep+tr("End")+sep+tr("Total Time")+sep+tr("AHI");
}
for (int i=0;i<countlist.size();i++)
header+=sep+countlist[i]+tr(" Count");
header+=sep+schema::channel[countlist[i]].label()+tr(" Count");
for (int i=0;i<avglist.size();i++)
header+=sep+avglist[i]+tr(" Avg");
header+=sep+schema::channel[avglist[i]].label()+tr(" Avg");
for (int i=0;i<p90list.size();i++)
header+=sep+p90list[i]+tr(" 90%");
header+=sep+schema::channel[p90list[i]].label()+tr(" %1%").arg(percent,0,'f',0);
}
header+=newline;
file.write(header.toAscii());

View File

@ -9,12 +9,23 @@
#include <QDateEdit>
#include <QDialog>
#include "SleepLib/machine_common.h"
namespace Ui {
class ExportCSV;
}
struct DumpField {
DumpField() { code=NoChannel; mtype=MT_UNKNOWN; type=ST_CNT; }
DumpField(ChannelID c, MachineType mt, SummaryType t) { code=c; mtype=mt; type=t; }
DumpField(const DumpField & copy) {code=copy.code; mtype=copy.mtype; type=copy.type; }
ChannelID code;
MachineType mtype;
SummaryType type;
};
/*! \class ExportCSV
\brief Dialog for exporting SleepLib data in CSV Format
This module still needs a lot of work
@ -42,6 +53,7 @@ private:
void UpdateCalendarDay(QDateEdit * dateedit,QDate date);
Ui::ExportCSV *ui;
QList<DumpField> fields;
};
#endif // EXPORTCSV_H

View File

@ -26,6 +26,7 @@
#include "SleepLib/loader_plugins/zeo_loader.h"
#include "SleepLib/loader_plugins/resmed_loader.h"
#include "SleepLib/loader_plugins/intellipap_loader.h"
#include "SleepLib/loader_plugins/icon_loader.h"
#ifdef Q_WS_X11
#include <X11/Xlib.h>
@ -135,6 +136,7 @@ int main(int argc, char *argv[])
//ZEOLoader::Register(); // Use outside of directory importer..
ResmedLoader::Register();
IntellipapLoader::Register();
FPIconLoader::Register();
// Scan for user profiles
Profiles::Scan();

View File

@ -300,7 +300,7 @@ void MainWindow::on_action_Import_Data_triggered()
if (res==2) return;
}
if (asknew) {
mainwin->Notify("Please remember to point the importer at the root folder or drive letter of your data-card, and not a subfolder.","Import Reminder",8000);
//mainwin->Notify("Please remember to point the importer at the root folder or drive letter of your data-card, and not a subfolder.","Import Reminder",8000);
}
QStringList importFrom;

View File

@ -939,7 +939,7 @@ void Oximetry::on_RefreshPortsButton_clicked()
bool current_found=false;
// Windows build mixes these up
#ifdef Q_WS_WIN32
#ifdef Q_WS_WIN32 || Q_WS_MAC
#define qesPORTNAME portName
#else
#define qesPORTNAME physName