mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-08 20:20:44 +00:00
Add time display and verticle line in alt-select mode, plus userflags in piechart option
This commit is contained in:
parent
164d70c026
commit
0bf8d8833a
@ -792,7 +792,7 @@ void gGraph::mouseMoveEvent(QMouseEvent *event)
|
||||
|
||||
//if (!nolayer) { // no mouse button
|
||||
if (doredraw) {
|
||||
m_graphview->redraw();
|
||||
m_graphview->timedRedraw(30);
|
||||
}
|
||||
|
||||
//}
|
||||
@ -1060,7 +1060,7 @@ void gGraph::keyReleaseEvent(QKeyEvent *event)
|
||||
if (!m_graphview) return;
|
||||
|
||||
if (m_graphview->selectionInProgress() && m_graphview->metaSelect()) {
|
||||
if (!(event->modifiers() & Qt::ShiftModifier)) {
|
||||
if (!(event->modifiers() & Qt::AltModifier)) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1094,6 +1094,8 @@ void gGraphView::setOffsetX(int offsetX)
|
||||
|
||||
void gGraphView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
this->setFocus();
|
||||
|
||||
int x = event->x();
|
||||
int y = event->y();
|
||||
|
||||
@ -1397,7 +1399,7 @@ void gGraphView::mousePressEvent(QMouseEvent *event)
|
||||
|
||||
|
||||
m_button_down = true;
|
||||
m_metaselect = event->modifiers() && Qt::ShiftModifier;
|
||||
m_metaselect = event->modifiers() && Qt::AltModifier;
|
||||
m_horiz_travel = 0;
|
||||
m_graph_index = i;
|
||||
m_selected_graph = m_graphs[i];
|
||||
@ -1459,7 +1461,7 @@ void gGraphView::mousePressEvent(QMouseEvent *event)
|
||||
m_point_clicked = QPoint(event->x(), event->y());
|
||||
//QMouseEvent e(event->type(),m_point_clicked,event->button(),event->buttons(),event->modifiers());
|
||||
m_button_down = true;
|
||||
m_metaselect = event->modifiers() && Qt::ShiftModifier;
|
||||
m_metaselect = event->modifiers() && Qt::AltModifier;
|
||||
|
||||
m_horiz_travel = 0;
|
||||
m_graph_index = i;
|
||||
@ -1573,7 +1575,7 @@ void gGraphView::mouseReleaseEvent(QMouseEvent *event)
|
||||
// The graph that got the button press gets the release event
|
||||
if (m_button_down) {
|
||||
m_button_down = false;
|
||||
m_metaselect = event->modifiers() & Qt::ShiftModifier;
|
||||
m_metaselect = event->modifiers() & Qt::AltModifier;
|
||||
saveHistory();
|
||||
|
||||
if (m_metaselect) {
|
||||
@ -1586,7 +1588,7 @@ void gGraphView::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
||||
void gGraphView::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
if (m_metaselect && !(event->modifiers() & Qt::ShiftModifier)) {
|
||||
if (m_metaselect && !(event->modifiers() & Qt::AltModifier)) {
|
||||
QMouseEvent mevent(QEvent::MouseButtonRelease, m_point_released, Qt::LeftButton, Qt::LeftButton, event->modifiers());
|
||||
if (m_graph_index>=0)
|
||||
m_graphs[m_graph_index]->mouseReleaseEvent(&mevent);
|
||||
@ -1819,8 +1821,11 @@ void gGraphView::wheelEvent(QWheelEvent *event)
|
||||
|
||||
void gGraphView::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (m_button_down) {
|
||||
m_metaselect = event->modifiers() & Qt::ShiftModifier;
|
||||
bool meta = m_metaselect;
|
||||
m_metaselect = event->modifiers() & Qt::AltModifier;
|
||||
|
||||
if (meta != m_metaselect) {
|
||||
timedRedraw(30);
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_Tab) {
|
||||
|
@ -157,6 +157,14 @@ EventDataType gLineChart::Maxy()
|
||||
return Layer::Maxy() - subtract_offset;
|
||||
}
|
||||
|
||||
bool gLineChart::mouseMoveEvent(QMouseEvent *event, gGraph *graph)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
if (graph->graphView()->metaSelect())
|
||||
graph->timedRedraw(30);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Time Domain Line Chart
|
||||
void gLineChart::paint(QPainter &painter, gGraph &w, const QRegion ®ion)
|
||||
{
|
||||
@ -226,6 +234,27 @@ void gLineChart::paint(QPainter &painter, gGraph &w, const QRegion ®ion)
|
||||
}
|
||||
}
|
||||
|
||||
if (w.graphView()->metaSelect()) {
|
||||
QPoint mouse = w.graphView()->currentMousePos();
|
||||
double pos = mouse.x() - left;
|
||||
if (pos > 0) {
|
||||
double xval = minx + (pos * (xx / double(width)));
|
||||
|
||||
|
||||
painter.setPen(QPen(QBrush(QColor(Qt::gray)),1));
|
||||
painter.drawLine(mouse.x(), top-w.marginTop()-3, mouse.x(), top+height+w.bottom-1);
|
||||
|
||||
QDateTime dt=QDateTime::fromMSecsSinceEpoch(xval);
|
||||
|
||||
QString text = dt.toString("MMM dd - HH:mm:ss:zzz");
|
||||
|
||||
int wid, h;
|
||||
GetTextExtent(text, wid, h);
|
||||
w.renderText(text, left + width/2 - wid/2, top -h);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EventDataType lastpx, lastpy;
|
||||
EventDataType px, py;
|
||||
int idx;
|
||||
|
@ -79,6 +79,9 @@ class gLineChart: public Layer
|
||||
void setPlotEnabled(ChannelID code, bool b) { m_enabled[code] = b; }
|
||||
|
||||
protected:
|
||||
//! \brief Mouse moved over this layers area (shows the hover-over tooltips here)
|
||||
virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph);
|
||||
|
||||
bool m_report_empty;
|
||||
bool m_square_plot;
|
||||
bool m_disable_accel;
|
||||
|
@ -21,6 +21,8 @@ gLineOverlayBar::~gLineOverlayBar()
|
||||
{
|
||||
}
|
||||
|
||||
QColor brighten(QColor color);
|
||||
|
||||
void gLineOverlayBar::paint(QPainter &painter, gGraph &w, const QRegion ®ion)
|
||||
{
|
||||
int left = region.boundingRect().left();
|
||||
@ -145,10 +147,10 @@ void gLineOverlayBar::paint(QPainter &painter, gGraph &w, const QRegion ®ion)
|
||||
if (x1 > width + left) {
|
||||
x1 = width + left;
|
||||
}
|
||||
|
||||
QRect rect(x2, start_py, x1-x2, height);
|
||||
QColor col = m_flag_color;
|
||||
if (rect.contains(mouse)) {
|
||||
col = QColor("gold");
|
||||
hover = true;
|
||||
}
|
||||
|
||||
@ -263,7 +265,6 @@ void gLineOverlayBar::paint(QPainter &painter, gGraph &w, const QRegion ®ion)
|
||||
bool gLineOverlayBar::mouseMoveEvent(QMouseEvent *event, gGraph *graph)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
graph->timedRedraw(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -21,18 +21,71 @@
|
||||
|
||||
extern double round(double number);
|
||||
|
||||
bool SearchApnea(Session *session, qint64 time, qint64 dist)
|
||||
|
||||
bool SearchEvent(Session * session, ChannelID code, qint64 time, EventStoreType dur, qint64 dist)
|
||||
{
|
||||
if (session->SearchEvent(CPAP_Obstructive, time, dist))
|
||||
qint64 t, start;
|
||||
QHash<ChannelID, QVector<EventList *> >::iterator it;
|
||||
it = session->eventlist.find(code);
|
||||
quint32 *tptr;
|
||||
|
||||
EventStoreType *dptr;
|
||||
|
||||
int cnt;
|
||||
|
||||
//qint64 rate;
|
||||
|
||||
QHash<ChannelID, QVector<EventList *> >::iterator evend = session->eventlist.end();
|
||||
if (it != evend) {
|
||||
int el_size=it.value().size();
|
||||
for (int i = 0; i < el_size; i++) {
|
||||
EventList *el = it.value()[i];
|
||||
// rate=el->rate();
|
||||
cnt = el->count();
|
||||
|
||||
// why would this be necessary???
|
||||
if (el->type() == EVL_Waveform) {
|
||||
qDebug() << "Called SearchEvent on a waveform object!";
|
||||
return false;
|
||||
} else {
|
||||
start = el->first();
|
||||
tptr = el->rawTime();
|
||||
dptr = el->rawData();
|
||||
|
||||
for (int j = 0; j < cnt; j++) {
|
||||
t = start + *tptr;
|
||||
|
||||
if (qAbs(time - t) < dist) {
|
||||
|
||||
// Move the position and set the duration
|
||||
if (dur>0) {
|
||||
*tptr = time - start;
|
||||
*dptr = (EventStoreType)dur;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
tptr++;
|
||||
dptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SearchApnea(Session *session, qint64 time, double dur, qint64 dist)
|
||||
{
|
||||
if (SearchEvent(session, CPAP_Obstructive, time, dur, dist))
|
||||
return true;
|
||||
|
||||
if (session->SearchEvent(CPAP_Apnea, time, dist))
|
||||
if (SearchEvent(session, CPAP_Apnea, time, dur, dist))
|
||||
return true;
|
||||
|
||||
if (session->SearchEvent(CPAP_ClearAirway, time, dist))
|
||||
if (SearchEvent(session, CPAP_ClearAirway, time, dur, dist))
|
||||
return true;
|
||||
|
||||
if (session->SearchEvent(CPAP_Hypopnea, time, dist))
|
||||
if (SearchEvent(session, CPAP_Hypopnea, time, 0, dist))
|
||||
return true;
|
||||
|
||||
if (session->SearchEvent(CPAP_UserFlag1, time, dist))
|
||||
@ -724,7 +777,7 @@ void FlowParser::flagUserEvents(ChannelID code, EventDataType restriction, Event
|
||||
dur = len / 1000.0;
|
||||
|
||||
if (dur >= duration) {
|
||||
if (allowDuplicates || !SearchApnea(m_session, et - len / 2, 15000)) {
|
||||
if (allowDuplicates || !SearchApnea(m_session, et, dur, 15000)) {
|
||||
if (!uf) {
|
||||
uf = m_session->AddEventList(code, EVL_Event);
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ class FlowParser
|
||||
EventDataType *m_buffers[num_filter_buffers];
|
||||
};
|
||||
|
||||
bool SearchApnea(Session *session, qint64 time, qint64 dist = 15000);
|
||||
bool SearchApnea(Session *session, qint64 time, double dur, qint64 dist = 15000);
|
||||
|
||||
//! \brief Calculate Respiratory Rate, Tidal Volume & Minute Ventilation for PRS1 data
|
||||
void calcRespRate(Session *session, FlowParser *flowparser = nullptr);
|
||||
|
@ -271,6 +271,8 @@ const QString STR_CS_UntreatedAHI = "UntreatedAHI";
|
||||
const QString STR_CS_Notes = "CPAPNotes";
|
||||
const QString STR_CS_DateDiagnosed = "DateDiagnosed";
|
||||
const QString STR_CS_UserEventFlagging = "UserEventFlagging";
|
||||
const QString STR_CS_UserEventPieChart = "UserEventPieChart";
|
||||
|
||||
const QString STR_CS_UserFlowRestriction = "UserFlowRestriction";
|
||||
const QString STR_CS_UserEventDuration = "UserEventDuration";
|
||||
const QString STR_CS_UserFlowRestriction2 = "UserFlowRestriction2";
|
||||
@ -525,6 +527,7 @@ class CPAPSettings : public ProfileSettings
|
||||
initPref(STR_CS_AHIReset, false);
|
||||
initPref(STR_CS_LeakRedline, 24.0);
|
||||
initPref(STR_CS_ShowLeakRedline, true);
|
||||
initPref(STR_CS_UserEventPieChart, false);
|
||||
|
||||
initPref(STR_CS_ClockDrift, (int)0);
|
||||
m_clock_drift = getPref(STR_CS_ClockDrift).toInt();
|
||||
@ -554,6 +557,7 @@ class CPAPSettings : public ProfileSettings
|
||||
int clockDrift() const { return m_clock_drift; }
|
||||
EventDataType leakRedline() const { return getPref(STR_CS_LeakRedline).toFloat(); }
|
||||
bool showLeakRedline() const { return getPref(STR_CS_ShowLeakRedline).toBool(); }
|
||||
bool userEventPieChart() const { return getPref(STR_CS_UserEventPieChart).toBool(); }
|
||||
|
||||
//Setters
|
||||
void setMode(CPAPMode mode) { setPref(STR_CS_PrescribedMode, (int)mode); }
|
||||
@ -583,6 +587,7 @@ class CPAPSettings : public ProfileSettings
|
||||
}
|
||||
void setLeakRedline(EventDataType value) { setPref(STR_CS_LeakRedline, value); }
|
||||
void setShowLeakRedline(bool reset) { setPref(STR_CS_ShowLeakRedline, reset); }
|
||||
void setUserEventPieChart(bool b) { setPref(STR_CS_UserEventPieChart, b); }
|
||||
|
||||
public:
|
||||
int m_clock_drift;
|
||||
|
@ -211,12 +211,12 @@ void init()
|
||||
schema::channel.add(GRP_CPAP, new Channel(CPAP_UserFlag1 = 0x101e, FLAG, SESSION,
|
||||
"UserFlag1", QObject::tr("User Flag #1"),
|
||||
QObject::tr("A user definable event detected by SleepyHead's flow waveform processor."),
|
||||
QObject::tr("UF1"), STR_UNIT_EventsPerHour, DEFAULT, QColor("dark cyan")));
|
||||
QObject::tr("UF1"), STR_UNIT_EventsPerHour, DEFAULT, QColor(0xc0,0xc0,0xe0)));
|
||||
|
||||
schema::channel.add(GRP_CPAP, new Channel(CPAP_UserFlag2 = 0x101f, FLAG, SESSION,
|
||||
"UserFlag2", QObject::tr("User Flag #2"),
|
||||
QObject::tr("A user definable event detected by SleepyHead's flow waveform processor."),
|
||||
QObject::tr("UF2"), STR_UNIT_EventsPerHour, DEFAULT, QColor("dark blue")));
|
||||
QObject::tr("UF2"), STR_UNIT_EventsPerHour, DEFAULT, QColor(0xa0,0xa0,0xc0)));
|
||||
|
||||
schema::channel.add(GRP_CPAP, new Channel(CPAP_UserFlag3 = 0x1024, FLAG, SESSION,
|
||||
"UserFlag3", QObject::tr("User Flag #3"),
|
||||
|
@ -192,7 +192,10 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
|
||||
evseg->AddSlice(CPAP_NRI,QColor(0x00,0x80,0x40,0xff),STR_TR_NR);
|
||||
evseg->AddSlice(CPAP_FlowLimit,QColor(0x40,0x40,0x40,0xff),STR_TR_FL);
|
||||
evseg->AddSlice(CPAP_SensAwake,QColor(0x40,0xC0,0x40,0xff),STR_TR_SA);
|
||||
//evseg->AddSlice(CPAP_UserFlag1,QColor(0x40,0x40,0x40,0xff),tr("UF"));
|
||||
if (p_profile->cpap->userEventPieChart()) {
|
||||
evseg->AddSlice(CPAP_UserFlag1,QColor(0xe0,0xe0,0xe0,0xff),tr("UF1"));
|
||||
evseg->AddSlice(CPAP_UserFlag2,QColor(0xc0,0xc0,0xe0,0xff),tr("UF2"));
|
||||
}
|
||||
|
||||
GAHI->AddLayer(AddCPAP(evseg));
|
||||
GAHI->setMargins(0,0,0,0);
|
||||
@ -1393,8 +1396,6 @@ void Daily::Load(QDate date)
|
||||
{ CPAP_Apnea, COLOR_Apnea, Qt::black, uai=cpap->count(CPAP_Apnea)/hours },
|
||||
{ CPAP_ClearAirway, COLOR_ClearAirway, Qt::black, cai=cpap->count(CPAP_ClearAirway)/hours },
|
||||
{ CPAP_NRI, COLOR_NRI, Qt::black, nri=cpap->count(CPAP_NRI)/hours },
|
||||
{ CPAP_UserFlag1, COLOR_UserFlag1, Qt::black, uf1=cpap->count(CPAP_UserFlag1)/hours },
|
||||
{ CPAP_UserFlag2, COLOR_UserFlag2, Qt::black, uf2=cpap->count(CPAP_UserFlag2)/hours },
|
||||
{ CPAP_FlowLimit, COLOR_FlowLimit, Qt::white, fli=cpap->count(CPAP_FlowLimit)/hours },
|
||||
{ CPAP_SensAwake, COLOR_SensAwake, Qt::black, sai=cpap->count(CPAP_SensAwake)/hours },
|
||||
{ CPAP_ExP, COLOR_ExP, Qt::black, exp=cpap->count(CPAP_ExP)/hours },
|
||||
@ -1403,7 +1404,10 @@ void Daily::Load(QDate date)
|
||||
{ CPAP_VSnore2, COLOR_VibratorySnore, Qt::black, vs2=cpap->count(CPAP_VSnore2)/cpap->hours() },
|
||||
{ CPAP_LeakFlag, COLOR_LeakFlag, Qt::black, lki=cpap->count(CPAP_LeakFlag)/hours },
|
||||
{ CPAP_LargeLeak, COLOR_LargeLeak, Qt::black, lk2=(100.0/cpap->hours())*(cpap->sum(CPAP_LargeLeak)/3600.0) },
|
||||
{ CPAP_CSR, COLOR_CSR, Qt::black, csr=(100.0/cpap->hours())*(cpap->sum(CPAP_CSR)/3600.0) }
|
||||
{ CPAP_CSR, COLOR_CSR, Qt::black, csr=(100.0/cpap->hours())*(cpap->sum(CPAP_CSR)/3600.0) },
|
||||
{ CPAP_UserFlag1, COLOR_UserFlag1, Qt::black, uf1=cpap->count(CPAP_UserFlag1)/hours },
|
||||
{ CPAP_UserFlag2, COLOR_UserFlag2, Qt::black, uf2=cpap->count(CPAP_UserFlag2)/hours },
|
||||
|
||||
};
|
||||
int numchans=sizeof(chans)/sizeof(ChannelInfo);
|
||||
|
||||
|
@ -247,6 +247,8 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, Profile *_profile) :
|
||||
ui->userEventDuplicates->setChecked(profile->cpap->userEventDuplicates());
|
||||
ui->userEventDuplicates->setVisible(false);
|
||||
|
||||
ui->showUserFlagsInPie->setChecked(profile->cpap->userEventPieChart());
|
||||
|
||||
ui->eventTable->setColumnWidth(0, 40);
|
||||
ui->eventTable->setColumnWidth(1, 55);
|
||||
ui->eventTable->setColumnHidden(3, true);
|
||||
@ -344,6 +346,11 @@ bool PreferencesDialog::Save()
|
||||
needs_restart = true;
|
||||
}
|
||||
|
||||
if (profile->cpap->userEventPieChart() != ui->showUserFlagsInPie->isChecked()) {
|
||||
// lazy.. fix me
|
||||
needs_restart = true;
|
||||
}
|
||||
|
||||
if (profile->general->calculateRDI() != ui->AddRERAtoAHI->isChecked()) {
|
||||
//recalc_events=true;
|
||||
needs_restart = true;
|
||||
@ -393,6 +400,8 @@ bool PreferencesDialog::Save()
|
||||
}
|
||||
}
|
||||
|
||||
profile->cpap->setUserEventPieChart(ui->showUserFlagsInPie->isChecked());
|
||||
|
||||
profile->appearance->setAllowYAxisScaling(ui->allowYAxisScaling->isChecked());
|
||||
profile->appearance->setGraphTooltips(ui->graphTooltips->isChecked());
|
||||
|
||||
@ -551,11 +560,11 @@ bool PreferencesDialog::Save()
|
||||
PREF.Save();
|
||||
p_profile->Save();
|
||||
|
||||
|
||||
if (recalc_events) {
|
||||
// send a signal instead?
|
||||
mainwin->reprocessEvents(needs_restart);
|
||||
} else if (needs_restart) {
|
||||
p_profile->removeLock();
|
||||
mainwin->RestartApplication();
|
||||
} else {
|
||||
mainwin->getDaily()->LoadDate(mainwin->getDaily()->getDate());
|
||||
|
@ -992,6 +992,13 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="userEventDuplicates">
|
||||
<property name="text">
|
||||
<string>Allow duplicates near machine events.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QDoubleSpinBox" name="apneaDuration2">
|
||||
<property name="suffix">
|
||||
@ -1010,9 +1017,9 @@ p, li { white-space: pre-wrap; }
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="userEventDuplicates">
|
||||
<widget class="QCheckBox" name="showUserFlagsInPie">
|
||||
<property name="text">
|
||||
<string>Allow duplicates near machine events.</string>
|
||||
<string>Show in Event Breakdown Piechart</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
Loading…
Reference in New Issue
Block a user