diff --git a/sleepyhead/Graphs/gFlagsLine.cpp b/sleepyhead/Graphs/gFlagsLine.cpp index c1d6e0a1..07be5ef4 100644 --- a/sleepyhead/Graphs/gFlagsLine.cpp +++ b/sleepyhead/Graphs/gFlagsLine.cpp @@ -57,33 +57,110 @@ qint64 gFlagsGroup::Maxx() void gFlagsGroup::SetDay(Day *d) { LayerGroup::SetDay(d); - lvisible.clear(); int cnt = 0; - for (int i = 0; i < layers.size(); i++) { - gFlagsLine *f = dynamic_cast(layers[i]); + if (!d) { + m_empty = true; + return; + } + QHash chans; - if (!f) { continue; } + schema::channel[CPAP_CSR].setOrder(1); + schema::channel[CPAP_CSR].setOrder(1); + schema::channel[CPAP_Ramp].setOrder(2); + schema::channel[CPAP_LargeLeak].setOrder(2); + schema::channel[CPAP_ClearAirway].setOrder(3); + schema::channel[CPAP_Obstructive].setOrder(4); + schema::channel[CPAP_Apnea].setOrder(4); + schema::channel[CPAP_NRI].setOrder(3); + schema::channel[CPAP_Hypopnea].setOrder(5); + schema::channel[CPAP_FlowLimit].setOrder(6); + schema::channel[CPAP_RERA].setOrder(6); + schema::channel[CPAP_VSnore].setOrder(7); + schema::channel[CPAP_VSnore2].setOrder(8); + schema::channel[CPAP_ExP].setOrder(6); - bool e = f->isEmpty(); + alwaysVisible(CPAP_LargeLeak); + alwaysVisible(CPAP_Hypopnea); + alwaysVisible(CPAP_Obstructive); - if (!e || f->isAlwaysVisible()) { - lvisible.push_back(f); - if (!e) { - cnt++; + for (int i=0; i< m_day->size(); ++i) { + Session * sess = m_day->sessions.at(i); + QHash >::iterator it; + for (it = sess->eventlist.begin(); it != sess->eventlist.end(); ++it) { + ChannelID code = it.key(); + if (chans.contains(code)) continue; + + schema::Channel * chan = &schema::channel[code]; + + if (chan->type() == schema::FLAG) { + chans[code] = chan; + } else if (chan->type() == schema::MINOR_FLAG) { + // chans[code] = chan; + } else if (chan->type() == schema::SPAN) { + chans[code] = chan; } } } - m_empty = (cnt == 0); - - if (m_empty) { - if (d) { - m_empty = !d->channelExists(CPAP_Pressure); + for (int i=0; i < m_alwaysvisible.size(); ++i) { + ChannelID code = m_alwaysvisible.at(i); + if (!chans.contains(code)) { + schema::Channel * chan = &schema::channel[code]; + chans[code] = chan; } } + QMultiMap order; + QHash::iterator cit; + + for (cit = chans.begin(); cit != chans.end(); ++cit) { + int ord = schema::channel[cit.key()].order(); + order.insert(ord, cit.value()); + } + + QMultiMap::iterator it; + + for (int i=0;i id()); + fl->SetDay(d); + lvisible.push_back(fl); + } + + + cnt = lvisible.size(); + +// for (int i = 0; i < layers.size(); i++) { +// gFlagsLine *f = dynamic_cast(layers[i]); + +// if (!f) { continue; } + +// bool e = f->isEmpty(); + +// if (!e || f->isAlwaysVisible()) { +// lvisible.push_back(f); + +// if (!e) { +// cnt++; +// } +// } +// } + + m_empty = (cnt == 0); + +// if (m_empty) { +// if (d) { +// m_empty = !d->channelExists(CPAP_Pressure); +// } +// } + m_barh = 0; } @@ -98,13 +175,21 @@ void gFlagsGroup::paint(QPainter &painter, gGraph &g, const QRegion ®ion) if (!m_day) { return; } - int vis = lvisible.size(); + + QVector visflags; + + for (int i = 0; i < lvisible.size(); i++) { + if (schema::channel[lvisible.at(i)->code()].enabled()) + visflags.push_back(lvisible.at(i)); + } + + int vis = visflags.size(); m_barh = float(height) / float(vis); float linetop = top; QColor barcol; - for (int i = 0; i < lvisible.size(); i++) { + for (int i = 0; i < visflags.size(); i++) { // Alternating box color if (i & 1) { barcol = COLOR_ALT_BG1; } else { barcol = COLOR_ALT_BG2; } @@ -113,8 +198,8 @@ void gFlagsGroup::paint(QPainter &painter, gGraph &g, const QRegion ®ion) // Paint the actual flags QRect rect(left, linetop, width, m_barh); - lvisible[i]->m_rect = rect; - lvisible[i]->paint(painter, g, QRegion(rect)); + visflags[i]->m_rect = rect; + visflags[i]->paint(painter, g, QRegion(rect)); linetop += m_barh; } @@ -160,10 +245,8 @@ bool gFlagsGroup::mouseMoveEvent(QMouseEvent *event, gGraph *graph) } -gFlagsLine::gFlagsLine(ChannelID code, QColor flag_color, QString label, bool always_visible, - FlagType flt) - : Layer(code), m_label(label), m_always_visible(always_visible), m_flt(flt), - m_flag_color(flag_color) +gFlagsLine::gFlagsLine(ChannelID code) + : Layer(code) { } gFlagsLine::~gFlagsLine() @@ -197,11 +280,12 @@ void gFlagsLine::paint(QPainter &painter, gGraph &w, const QRegion ®ion) double xmult = width / xx; - QString label = schema::channel[m_code].label(); - GetTextExtent(label, m_lx, m_ly); + schema::Channel & chan = schema::channel[m_code]; + + GetTextExtent(chan.label(), m_lx, m_ly); // Draw text label - w.renderText(label, left - m_lx - 10, top + (height / 2) + (m_ly / 2)); + w.renderText(chan.label(), left - m_lx - 10, top + (height / 2) + (m_ly / 2)); float x1, x2; @@ -223,6 +307,7 @@ void gFlagsLine::paint(QPainter &painter, gGraph &w, const QRegion ®ion) QColor color=schema::channel[m_code].defaultColor(); QBrush brush(color); + bool hover = false; for (QList::iterator s = m_day->begin(); s != m_day->end(); s++) { if (!(*s)->enabled()) { continue; @@ -264,7 +349,7 @@ void gFlagsLine::paint(QPainter &painter, gGraph &w, const QRegion ®ion) np -= idx; - if (m_flt == FT_Bar) { + if (chan.type() == schema::FLAG) { /////////////////////////////////////////////////////////////////////////// // Draw Event Flag Bars /////////////////////////////////////////////////////////////////////////// @@ -277,9 +362,22 @@ void gFlagsLine::paint(QPainter &painter, gGraph &w, const QRegion ®ion) } x1 = (X - minx) * xmult + left; + + if (!hover && QRect(x1-3, bartop-2, 6, bottom-bartop+4).contains(w.graphView()->currentMousePos())) { + hover = true; + painter.setPen(QPen(Qt::red,1)); + + painter.drawRect(x1-2, bartop-2, 4, bottom-bartop+4); + int x,y; + QString lab = QString("%1 (%2)").arg(schema::channel[m_code].fullname()).arg(*dptr); + GetTextExtent(lab, x, y); + + w.ToolTip(lab, x1 - 10, bartop + (3 * w.printScaleY()), TT_AlignRight, p_profile->general->tooltipTimeout()); + } + vlines.append(QLine(x1, bartop, x1, bottom)); } - } else if (m_flt == FT_Span) { + } else if (chan.type() == schema::SPAN) { /////////////////////////////////////////////////////////////////////////// // Draw Event Flag Spans /////////////////////////////////////////////////////////////////////////// @@ -297,7 +395,20 @@ void gFlagsLine::paint(QPainter &painter, gGraph &w, const QRegion ®ion) x1 = double(X - minx) * xmult + left; x2 = double(X2 - minx) * xmult + left; + brush = QBrush(color); painter.fillRect(x2, bartop, x1-x2, bottom-bartop, brush); + if (!hover && QRect(x2, bartop, x1-x2, bottom-bartop).contains(w.graphView()->currentMousePos())) { + hover = true; + painter.setPen(QPen(Qt::red,1)); + + painter.drawRect(x2, bartop, x1-x2, bottom-bartop); + int x,y; + QString lab = QString("%1 (%2)").arg(schema::channel[m_code].fullname()).arg(*dptr); + GetTextExtent(lab, x, y); + + w.ToolTip(lab, x2 - 10, bartop + (3 * w.printScaleY()), TT_AlignRight, p_profile->general->tooltipTimeout()); + + } } } } diff --git a/sleepyhead/Graphs/gFlagsLine.h b/sleepyhead/Graphs/gFlagsLine.h index 7196f64b..63276ad3 100644 --- a/sleepyhead/Graphs/gFlagsLine.h +++ b/sleepyhead/Graphs/gFlagsLine.h @@ -49,35 +49,20 @@ class gFlagsLine: public Layer \param always_visible Whether to always show this line, even if empty \param Type of Flag, either FT_Bar, or FT_Span */ - gFlagsLine(ChannelID code, QColor col = Qt::black, QString label = "", bool always_visible = false, - FlagType flt = FT_Bar); + gFlagsLine(ChannelID code); virtual ~gFlagsLine(); //! \brief Drawing code to add the flags and span markers to the Vertex buffers. virtual void paint(QPainter &painter, gGraph &w, const QRegion ®ion); - //! \brief Returns true if should always show this flag, even if it's empty - bool isAlwaysVisible() { return m_always_visible; } - //! \brief Set this to true to make a flag line always visible - void setAlwaysVisible(bool b) { m_always_visible = b; } - - //! \brief Returns the label for this individual Event Flags line - QString label() { return m_label; } - - //! \brief Sets the label for this individual Event Flags line - void setLabel(QString s) { m_label = s; } - void setTotalLines(int i) { total_lines = i; } void setLineNum(int i) { line_num = i; } protected: virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph); - QString m_label; bool m_always_visible; int total_lines, line_num; - FlagType m_flt; - QColor m_flag_color; int m_lx, m_ly; }; @@ -115,9 +100,13 @@ class gFlagsGroup: public LayerGroup //! Returns a list of Visible gFlagsLine layers to draw QVector &visibleLayers() { return lvisible; } + void alwaysVisible(ChannelID code) { m_alwaysvisible.push_back(code); } + protected: virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph); + QList m_alwaysvisible; + QVector lvisible; float m_barh; bool m_empty; diff --git a/sleepyhead/Graphs/gSegmentChart.cpp b/sleepyhead/Graphs/gSegmentChart.cpp index 27cf45c8..0d01b36a 100644 --- a/sleepyhead/Graphs/gSegmentChart.cpp +++ b/sleepyhead/Graphs/gSegmentChart.cpp @@ -118,7 +118,7 @@ void gSegmentChart::paint(QPainter &painter, gGraph &w, const QRegion ®ion) // Pie Chart ///////////////////////////////////////////////////////////////////////////////////// if (m_graph_type == GST_Pie) { - const QColor col = schema::channel[m_codes[m % m_colors.size()]].defaultColor(); + const QColor col = schema::channel[m_codes[m]].defaultColor(); // length of this segment in degrees float len = 360.0 / float(m_total) * float(data); @@ -151,7 +151,7 @@ void gSegmentChart::paint(QPainter &painter, gGraph &w, const QRegion ®ion) double tpx = (pierect.x() + pierect.width()/2) + (sin((180 - angle) * (M_PI / 180.0)) * (radius / 1.65)); double tpy = (pierect.y() + pierect.height()/2) + (cos((180 - angle) * (M_PI / 180.0)) * (radius / 1.65)); - QString txt = m_names[m]; //QString::number(floor(100.0/m_total*data),'f',0)+"%"; + QString txt = schema::channel[m_codes[m]].label(); //QString::number(floor(100.0/m_total*data),'f',0)+"%"; int x, y; GetTextExtent(txt, x, y); // antialiasing looks like crap here.. diff --git a/sleepyhead/SleepLib/schema.cpp b/sleepyhead/SleepLib/schema.cpp index 853afcb5..2f4b2115 100644 --- a/sleepyhead/SleepLib/schema.cpp +++ b/sleepyhead/SleepLib/schema.cpp @@ -548,7 +548,8 @@ Channel::Channel(ChannelID id, ChanType type, ScopeType scope, QString code, QSt m_lowerThreshold(0), m_upperThresholdColor(Qt::red), m_lowerThresholdColor(Qt::green), - m_enabled(true) + m_enabled(true), + m_order(255) { } bool Channel::isNull() diff --git a/sleepyhead/SleepLib/schema.h b/sleepyhead/SleepLib/schema.h index 5b02e930..ae9af97f 100644 --- a/sleepyhead/SleepLib/schema.h +++ b/sleepyhead/SleepLib/schema.h @@ -53,7 +53,7 @@ extern Channel EmptyChannel; class Channel { public: - Channel() { m_id = 0; m_upperThreshold = 0; m_lowerThreshold = 0; m_enabled = true; } + Channel() { m_id = 0; m_upperThreshold = 0; m_lowerThreshold = 0; m_enabled = true; m_order = 255; } Channel(ChannelID id, ChanType type, ScopeType scope, QString code, QString fullname, QString description, QString label, QString unit, DataType datatype = DEFAULT, QColor = Qt::black, int link = 0); @@ -68,6 +68,7 @@ class Channel const QString &description() { return m_description; } const QString &label() { return m_label; } const QString &units() { return m_unit; } + inline short order() const { return m_order; } inline EventDataType upperThreshold() const { return m_upperThreshold; } inline EventDataType lowerThreshold() const { return m_lowerThreshold; } @@ -85,6 +86,7 @@ class Channel void setUpperThresholdColor(QColor color) { m_upperThresholdColor = color; } void setLowerThreshold(EventDataType value) { m_lowerThreshold = value; } void setLowerThresholdColor(QColor color) { m_lowerThresholdColor = color; } + void setOrder(short order) { m_order = order; } QString option(int i) { if (m_options.contains(i)) { @@ -123,6 +125,7 @@ class Channel QColor m_lowerThresholdColor; bool m_enabled; + short m_order; }; /*! \class ChannelList diff --git a/sleepyhead/daily.cpp b/sleepyhead/daily.cpp index 71a39d75..3e86123d 100644 --- a/sleepyhead/daily.cpp +++ b/sleepyhead/daily.cpp @@ -215,27 +215,27 @@ Daily::Daily(QWidget *parent,gGraphView * shared) gFlagsGroup *fg=new gFlagsGroup(); SF->AddLayer(AddCPAP(fg)); // Spans - fg->AddLayer((new gFlagsLine(CPAP_CSR, COLOR_CSR, STR_TR_PB, false, FT_Span))); - fg->AddLayer((new gFlagsLine(CPAP_LargeLeak, COLOR_LargeLeak, STR_TR_LL, false, FT_Span))); - fg->AddLayer((new gFlagsLine(CPAP_Ramp, COLOR_Ramp, schema::channel[CPAP_Ramp].label(), false, FT_Span))); - // Flags - fg->AddLayer((new gFlagsLine(CPAP_ClearAirway, COLOR_ClearAirway, STR_TR_CA,false))); - fg->AddLayer((new gFlagsLine(CPAP_Obstructive, COLOR_Obstructive, STR_TR_OA,true))); - fg->AddLayer((new gFlagsLine(CPAP_Apnea, COLOR_Apnea, STR_TR_UA))); - fg->AddLayer((new gFlagsLine(CPAP_Hypopnea, COLOR_Hypopnea, STR_TR_H,true))); - fg->AddLayer((new gFlagsLine(CPAP_ExP, COLOR_ExP, STR_TR_EP,false))); - fg->AddLayer((new gFlagsLine(CPAP_LeakFlag, COLOR_LeakFlag, STR_TR_LE,false))); - fg->AddLayer((new gFlagsLine(CPAP_NRI, COLOR_NRI, STR_TR_NRI,false))); - fg->AddLayer((new gFlagsLine(CPAP_FlowLimit, COLOR_FlowLimit, STR_TR_FL))); - fg->AddLayer((new gFlagsLine(CPAP_SensAwake, COLOR_SensAwake, STR_TR_SA))); - fg->AddLayer((new gFlagsLine(CPAP_RERA, COLOR_RERA, STR_TR_RE))); - fg->AddLayer((new gFlagsLine(CPAP_VSnore, COLOR_VibratorySnore, STR_TR_VS))); - fg->AddLayer((new gFlagsLine(CPAP_VSnore2, COLOR_VibratorySnore, STR_TR_VS2))); - if (p_profile->cpap->userEventFlagging()) { - fg->AddLayer((new gFlagsLine(CPAP_UserFlag1, COLOR_Yellow, STR_TR_UF1))); - fg->AddLayer((new gFlagsLine(CPAP_UserFlag2, COLOR_DarkGreen, STR_TR_UF2))); - fg->AddLayer((new gFlagsLine(CPAP_UserFlag3, COLOR_Brown, STR_TR_UF3))); - } +// fg->AddLayer((new gFlagsLine(CPAP_CSR, COLOR_CSR, STR_TR_PB, false, FT_Span))); +// fg->AddLayer((new gFlagsLine(CPAP_LargeLeak, COLOR_LargeLeak, STR_TR_LL, false, FT_Span))); +// fg->AddLayer((new gFlagsLine(CPAP_Ramp, COLOR_Ramp, schema::channel[CPAP_Ramp].label(), false, FT_Span))); +// // Flags +// fg->AddLayer((new gFlagsLine(CPAP_ClearAirway, COLOR_ClearAirway, STR_TR_CA,false))); +// fg->AddLayer((new gFlagsLine(CPAP_Obstructive, COLOR_Obstructive, STR_TR_OA,true))); +// fg->AddLayer((new gFlagsLine(CPAP_Apnea, COLOR_Apnea, STR_TR_UA))); +// fg->AddLayer((new gFlagsLine(CPAP_Hypopnea, COLOR_Hypopnea, STR_TR_H,true))); +// fg->AddLayer((new gFlagsLine(CPAP_ExP, COLOR_ExP, STR_TR_EP,false))); +// fg->AddLayer((new gFlagsLine(CPAP_LeakFlag, COLOR_LeakFlag, STR_TR_LE,false))); +// fg->AddLayer((new gFlagsLine(CPAP_NRI, COLOR_NRI, STR_TR_NRI,false))); +// fg->AddLayer((new gFlagsLine(CPAP_FlowLimit, COLOR_FlowLimit, STR_TR_FL))); +// fg->AddLayer((new gFlagsLine(CPAP_SensAwake, COLOR_SensAwake, STR_TR_SA))); +// fg->AddLayer((new gFlagsLine(CPAP_RERA, COLOR_RERA, STR_TR_RE))); +// fg->AddLayer((new gFlagsLine(CPAP_VSnore, COLOR_VibratorySnore, STR_TR_VS))); +// fg->AddLayer((new gFlagsLine(CPAP_VSnore2, COLOR_VibratorySnore, STR_TR_VS2))); +// if (p_profile->cpap->userEventFlagging()) { +// fg->AddLayer((new gFlagsLine(CPAP_UserFlag1, COLOR_Yellow, STR_TR_UF1))); +// fg->AddLayer((new gFlagsLine(CPAP_UserFlag2, COLOR_DarkGreen, STR_TR_UF2))); +// fg->AddLayer((new gFlagsLine(CPAP_UserFlag3, COLOR_Brown, STR_TR_UF3))); +// } //fg->AddLayer((new gFlagsLine(PRS1_0B,COLOR_DarkGreen,tr("U0B")))); SF->setBlockZoom(true); SF->AddLayer(new gShadowArea());