Merge branch 'qpainter', old opengl code is officially dead

This commit is contained in:
Mark Watkins 2014-05-14 05:30:09 +10:00
commit b98d90934d
58 changed files with 1273 additions and 2955 deletions

View File

@ -1,289 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
*
* Copyright (c) 2011-2014 Mark Watkins <jedimark@users.sourceforge.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the Linux
* distribution for more details. */
#include "Graphs/GLBuffer.h"
#include <QDebug>
#include "SleepLib/profiles.h"
extern int lines_drawn_this_frame;
extern int quads_drawn_this_frame;
GLFloatBuffer::GLFloatBuffer(int max, int type, bool stippled)
: GLBuffer(max, type, stippled)
{
buffer = new GLfloat[max + 8];
colors = new GLubyte[max * 4 + (8 * 4)];
}
GLFloatBuffer::~GLFloatBuffer()
{
if (colors) {
delete [] colors;
}
if (buffer) {
delete [] buffer;
}
}
void GLFloatBuffer::add(GLfloat x, GLfloat y, QColor &color)
{
#ifdef ENABLE_THREADED_DRAWING
mutex.lock();
#endif
if (m_cnt < m_max + 2) {
buffer[m_cnt++] = x;
buffer[m_cnt++] = y;
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
} else {
qDebug() << "GLBuffer overflow";
}
#ifdef ENABLE_THREADED_DRAWING
mutex.unlock();
#endif
}
void GLFloatBuffer::add(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, QColor &color)
{
if (m_cnt < m_max + 4) {
qDebug() << "GLFloatBuffer overflow";
return;
}
#ifdef ENABLE_THREADED_DRAWING
mutex.lock();
#endif
buffer[m_cnt++] = x1;
buffer[m_cnt++] = y1;
buffer[m_cnt++] = x2;
buffer[m_cnt++] = y2;
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
#ifdef ENABLE_THREADED_DRAWING
mutex.unlock();
#endif
}
void GLFloatBuffer::add(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3,
GLfloat x4, GLfloat y4, QColor &color) // add with vertex colors
{
if (m_cnt >= m_max + 8) {
qDebug() << "GLFloatBuffer overflow";
return;
}
#ifdef ENABLE_THREADED_DRAWING
mutex.lock();
#endif
buffer[m_cnt++] = x1;
buffer[m_cnt++] = y1;
buffer[m_cnt++] = x2;
buffer[m_cnt++] = y2;
buffer[m_cnt++] = x3;
buffer[m_cnt++] = y3;
buffer[m_cnt++] = x4;
buffer[m_cnt++] = y4;
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
#ifdef ENABLE_THREADED_DRAWING
mutex.unlock();
#endif
}
void GLFloatBuffer::quadGrLR(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3,
GLfloat y3, GLfloat x4, GLfloat y4, QColor &color, QColor &color2) // add with vertex colors
{
if (m_cnt >= m_max + 8) {
qDebug() << "GLFloatBuffer overflow";
return;
}
#ifdef ENABLE_THREADED_DRAWING
mutex.lock();
#endif
buffer[m_cnt++] = x1;
buffer[m_cnt++] = y1;
buffer[m_cnt++] = x2;
buffer[m_cnt++] = y2;
buffer[m_cnt++] = x3;
buffer[m_cnt++] = y3;
buffer[m_cnt++] = x4;
buffer[m_cnt++] = y4;
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
colors[m_colcnt++] = color2.red();
colors[m_colcnt++] = color2.green();
colors[m_colcnt++] = color2.blue();
colors[m_colcnt++] = color2.alpha();
colors[m_colcnt++] = color2.red();
colors[m_colcnt++] = color2.green();
colors[m_colcnt++] = color2.blue();
colors[m_colcnt++] = color2.alpha();
#ifdef ENABLE_THREADED_DRAWING
mutex.unlock();
#endif
}
void GLFloatBuffer::quadGrTB(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3,
GLfloat y3, GLfloat x4, GLfloat y4, QColor &color, QColor &color2)
{
if (m_cnt >= m_max + 8) {
qDebug() << "GLFloatBuffer overflow";
return;
}
#ifdef ENABLE_THREADED_DRAWING
mutex.lock();
#endif
buffer[m_cnt++] = x1;
buffer[m_cnt++] = y1;
buffer[m_cnt++] = x3;
buffer[m_cnt++] = y3;
buffer[m_cnt++] = x2;
buffer[m_cnt++] = y2;
buffer[m_cnt++] = x4;
buffer[m_cnt++] = y4;
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
colors[m_colcnt++] = color.red();
colors[m_colcnt++] = color.green();
colors[m_colcnt++] = color.blue();
colors[m_colcnt++] = color.alpha();
colors[m_colcnt++] = color2.red();
colors[m_colcnt++] = color2.green();
colors[m_colcnt++] = color2.blue();
colors[m_colcnt++] = color2.alpha();
colors[m_colcnt++] = color2.red();
colors[m_colcnt++] = color2.green();
colors[m_colcnt++] = color2.blue();
colors[m_colcnt++] = color2.alpha();
#ifdef ENABLE_THREADED_DRAWING
mutex.unlock();
#endif
}
void GLFloatBuffer::draw()
{
if (m_cnt <= 0) {
return;
}
bool antialias = m_forceantialias || (PROFILE.appearance->antiAliasing() && m_antialias);
float size = m_size;
if (antialias) {
glEnable(GL_BLEND);
glBlendFunc(m_blendfunc1, m_blendfunc2);
if (m_type == GL_LINES || m_type == GL_LINE_LOOP) {
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
size += 0.5;
} else if (m_type == GL_POLYGON) {
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
}
}
if (m_type == GL_LINES || m_type == GL_LINE_LOOP) {
glLineWidth(size);
if (m_stippled) {
glLineStipple(1, 0xAAAA);
glEnable(GL_LINE_STIPPLE);
}
lines_drawn_this_frame += m_cnt / 2;
} else if (m_type == GL_POINTS) {
glPointSize(size);
} else if (m_type == GL_POLYGON) {
glPolygonMode(GL_BACK, GL_FILL);
lines_drawn_this_frame += m_cnt / 2;
} else if (m_type == GL_QUADS) {
quads_drawn_this_frame += m_cnt / 4;
}
if (m_scissor) {
glScissor(s1, s2, s3, s4);
glEnable(GL_SCISSOR_TEST);
}
glVertexPointer(2, GL_FLOAT, 0, buffer);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
//glColor4ub(200,128,95,200);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(m_type, 0, m_cnt >> 1);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
//qDebug() << "I Drew" << m_cnt << "vertices";
m_cnt = 0;
m_colcnt = 0;
if (m_scissor) {
glDisable(GL_SCISSOR_TEST);
m_scissor = false;
}
if (m_type == GL_POLYGON) {
glPolygonMode(GL_BACK, GL_FILL);
}
if (antialias) {
if (m_type == GL_LINES || m_type == GL_LINE_LOOP) {
if (m_stippled) { glDisable(GL_LINE_STIPPLE); }
glDisable(GL_LINE_SMOOTH);
} else if (m_type == GL_POLYGON) {
glDisable(GL_POLYGON_SMOOTH);
}
glDisable(GL_BLEND);
}
}

View File

@ -1,100 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
*
* Copyright (c) 2011-2014 Mark Watkins <jedimark@users.sourceforge.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the Linux
* distribution for more details. */
#ifndef graphs_glbuffer_h
#define graphs_glbuffer_h
#include <QColor>
#include <QGLWidget>
#include <QMutex>
/*! \class GLBuffer
\brief Base Object to hold an OpenGL draw list
*/
class GLBuffer
{
public:
GLBuffer(int max = 2048, int type = GL_LINES, bool stippled = false)
: m_max(max), m_type(type), m_cnt(0), m_colcnt(0), m_size(1),
s1(0), s2(0), s3(0), s4(0),
m_scissor(false),
m_antialias(true),
m_forceantialias(false),
m_stippled(stippled),
m_blendfunc1(GL_SRC_ALPHA),
m_blendfunc2(GL_ONE_MINUS_SRC_ALPHA)
{ }
virtual ~GLBuffer() {}
void scissor(GLshort x1, GLshort y1, GLshort x2, GLshort y2) {
s1 = x1;
s2 = y1;
s3 = x2;
s4 = y2;
m_scissor = true;
}
int Max() const { return m_max; }
int cnt() const { return m_cnt; }
bool full() const { return m_cnt >= m_max; }
float size() const { return m_size; }
int type() const { return m_type; }
void reset() { m_cnt = 0; }
void setSize(float f) { m_size = f; }
void setAntiAlias(bool b) { m_antialias = b; }
void forceAntiAlias(bool b) { m_forceantialias = b; }
void setColor(QColor col) { m_color = col; }
void setBlendFunc(GLuint b1, GLuint b2) { m_blendfunc1 = b1; m_blendfunc2 = b2; }
virtual void draw() {}
protected:
int m_max;
int m_type; // type (GL_LINES, GL_QUADS, etc)
int m_cnt; // cnt
int m_colcnt;
QColor m_color;
float m_size;
int s1, s2, s3, s4;
bool m_scissor;
bool m_antialias;
bool m_forceantialias;
QMutex mutex;
bool m_stippled;
GLuint m_blendfunc1, m_blendfunc2;
};
/*! \class GLFloatBuffer
\brief Holds an OpenGL draw list composed of 32bit GLfloat objects and vertex colors
*/
class GLFloatBuffer : public GLBuffer
{
public:
GLFloatBuffer(int max = 2048, int type = GL_LINES, bool stippled = false);
virtual ~GLFloatBuffer();
// Add with vertex color(s).
void add(GLfloat x, GLfloat y, QColor &col);
void add(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, QColor &col);
void add(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4, QColor &col);
void quadGrTB(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4, QColor &col, QColor &col2);
void quadGrLR(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4, QColor &col, QColor &col2);
virtual void draw();
protected:
GLfloat *buffer;
GLubyte *colors;
};
#endif // graphs_glbuffer_h

View File

@ -32,10 +32,6 @@ bool gFlagsLabelArea::mouseMoveEvent(QMouseEvent *event, gGraph *graph)
gFlagsGroup::gFlagsGroup() gFlagsGroup::gFlagsGroup()
{ {
addVertexBuffer(quads = new gVertexBuffer(512, GL_QUADS));
addVertexBuffer(lines = new gVertexBuffer(20, GL_LINE_LOOP));
quads->setAntiAlias(true);
lines->setAntiAlias(false);
m_barh = 0; m_barh = 0;
m_empty = true; m_empty = true;
} }
@ -91,7 +87,7 @@ void gFlagsGroup::SetDay(Day *d)
m_barh = 0; m_barh = 0;
} }
void gFlagsGroup::paint(gGraph &g, int left, int top, int width, int height) void gFlagsGroup::paint(QPainter &painter, gGraph &g, int left, int top, int width, int height)
{ {
if (!m_visible) { return; } if (!m_visible) { return; }
@ -108,23 +104,19 @@ void gFlagsGroup::paint(gGraph &g, int left, int top, int width, int height)
if (i & 1) { barcol = COLOR_ALT_BG1; } if (i & 1) { barcol = COLOR_ALT_BG1; }
else { barcol = COLOR_ALT_BG2; } else { barcol = COLOR_ALT_BG2; }
quads->add(left, linetop, left, linetop + m_barh, left + width - 1, linetop + m_barh, painter.fillRect(left, linetop, width-1, m_barh, QBrush(barcol));
left + width - 1, linetop, barcol.rgba());
// Paint the actual flags // Paint the actual flags
lvisible[i]->m_rect = QRect(left, linetop, width, m_barh); lvisible[i]->m_rect = QRect(left, linetop, width, m_barh);
lvisible[i]->paint(g, left, linetop, width, m_barh); lvisible[i]->paint(painter, g, left, linetop, width, m_barh);
linetop += m_barh; linetop += m_barh;
} }
gVertexBuffer *outlines = g.lines(); painter.setPen(COLOR_Outline);
outlines->add(left - 1, top, left - 1, top + height, COLOR_Outline.rgba()); painter.drawLine(left - 1, top, left - 1, top + height);
outlines->add(left - 1, top + height, left + width, top + height, COLOR_Outline.rgba()); painter.drawLine(left - 1, top + height, left + width, top + height);
outlines->add(left + width, top + height, left + width, top, COLOR_Outline.rgba()); painter.drawLine(left + width, top + height, left + width, top);
outlines->add(left + width, top, left - 1, top, COLOR_Outline.rgba()); painter.drawLine(left + width, top, left - 1, top);
//lines->add(left-1, top, left-1, top+height);
//lines->add(left+width, top+height, left+width, top);
} }
bool gFlagsGroup::mouseMoveEvent(QMouseEvent *event, gGraph *graph) bool gFlagsGroup::mouseMoveEvent(QMouseEvent *event, gGraph *graph)
@ -162,25 +154,16 @@ gFlagsLine::gFlagsLine(ChannelID code, QColor flag_color, QString label, bool al
: Layer(code), m_label(label), m_always_visible(always_visible), m_flt(flt), : Layer(code), m_label(label), m_always_visible(always_visible), m_flt(flt),
m_flag_color(flag_color) m_flag_color(flag_color)
{ {
addVertexBuffer(quads = new gVertexBuffer(2048, GL_QUADS));
//addGLBuf(lines=new GLBuffer(flag_color,1024,GL_LINES));
quads->setAntiAlias(true);
//lines->setAntiAlias(true);
//GetTextExtent(m_label,m_lx,m_ly);
//m_static.setText(m_label);;
} }
gFlagsLine::~gFlagsLine() gFlagsLine::~gFlagsLine()
{ {
//delete lines;
//delete quads;
} }
void gFlagsLine::paint(gGraph &w, int left, int top, int width, int height) void gFlagsLine::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) { return; } if (!m_visible) { return; }
if (!m_day) { return; } if (!m_day) { return; }
lines = w.lines();
double minx; double minx;
double maxx; double maxx;
@ -207,9 +190,7 @@ void gFlagsLine::paint(gGraph &w, int left, int top, int width, int height)
float bartop = top + 2; float bartop = top + 2;
float bottom = top + height - 2; float bottom = top + height - 2;
bool verts_exceeded = false;
qint64 X, X2, L; qint64 X, X2, L;
lines->setColor(schema::channel[m_code].defaultColor());
qint64 start; qint64 start;
quint32 *tptr; quint32 *tptr;
@ -220,6 +201,11 @@ void gFlagsLine::paint(gGraph &w, int left, int top, int width, int height)
qint64 clockdrift = qint64(PROFILE.cpap->clockDrift()) * 1000L; qint64 clockdrift = qint64(PROFILE.cpap->clockDrift()) * 1000L;
qint64 drift = 0; qint64 drift = 0;
QVector<QLine> vlines;
QColor color=schema::channel[m_code].defaultColor();
QBrush brush(color);
for (QList<Session *>::iterator s = m_day->begin(); s != m_day->end(); s++) { for (QList<Session *>::iterator s = m_day->begin(); s != m_day->end(); s++) {
if (!(*s)->enabled()) { if (!(*s)->enabled()) {
continue; continue;
@ -266,17 +252,6 @@ void gFlagsLine::paint(gGraph &w, int left, int top, int width, int height)
// Draw Event Flag Bars // Draw Event Flag Bars
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Check bounds outside of loop is faster..
// This will have to be reverted if multithreaded drawing is ever brought back
int rem = lines->Max() - lines->cnt();
if ((np << 1) > rem) {
qDebug() << "gFlagsLine would overfill lines for" << schema::channel[m_code].label();
np = rem >> 1;
verts_exceeded = true;
}
for (int i = 0; i < np; i++) { for (int i = 0; i < np; i++) {
X = start + *tptr++; X = start + *tptr++;
@ -285,22 +260,12 @@ void gFlagsLine::paint(gGraph &w, int left, int top, int width, int height)
} }
x1 = (X - minx) * xmult + left; x1 = (X - minx) * xmult + left;
lines->add(x1, bartop, x1, bottom); vlines.append(QLine(x1, bartop, x1, bottom));
//if (lines->full()) { verts_exceeded=true; break; }
} }
} else if (m_flt == FT_Span) { } else if (m_flt == FT_Span) {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Draw Event Flag Spans // Draw Event Flag Spans
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
quads->setColor(m_flag_color);
int rem = quads->Max() - quads->cnt();
if ((np << 2) > rem) {
qDebug() << "gFlagsLine would overfill quads for" << schema::channel[m_code].label();
np = rem >> 2;
verts_exceeded = true;
}
for (; dptr < eptr; dptr++) { for (; dptr < eptr; dptr++) {
X = start + * tptr++; X = start + * tptr++;
@ -315,21 +280,14 @@ void gFlagsLine::paint(gGraph &w, int left, int top, int width, int height)
x1 = double(X - minx) * xmult + left; x1 = double(X - minx) * xmult + left;
x2 = double(X2 - minx) * xmult + left; x2 = double(X2 - minx) * xmult + left;
quads->add(x2, bartop, x1, bartop, x1, bottom, x2, bottom); painter.fillRect(x2, bartop, x1-x2, bottom-bartop, brush);
//if (quads->full()) { verts_exceeded=true; break; }
} }
} }
if (verts_exceeded) { break; }
} }
if (verts_exceeded) { break; }
} }
if (verts_exceeded) { painter.setPen(color);
qWarning() << "maxverts exceeded in gFlagsLine::plot()"; painter.drawLines(vlines);
}
} }
bool gFlagsLine::mouseMoveEvent(QMouseEvent *event, gGraph *graph) bool gFlagsLine::mouseMoveEvent(QMouseEvent *event, gGraph *graph)

View File

@ -24,8 +24,9 @@ class gFlagsLabelArea: public gSpacer
{ {
public: public:
gFlagsLabelArea(gFlagsGroup *group); gFlagsLabelArea(gFlagsGroup *group);
virtual void paint(gGraph &w, int left, int top, int width, int height) { virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height) {
Q_UNUSED(w) Q_UNUSED(w)
Q_UNUSED(painter)
Q_UNUSED(left) Q_UNUSED(left)
Q_UNUSED(top) Q_UNUSED(top)
Q_UNUSED(width) Q_UNUSED(width)
@ -58,7 +59,7 @@ class gFlagsLine: public Layer
virtual ~gFlagsLine(); virtual ~gFlagsLine();
//! \brief Drawing code to add the flags and span markers to the Vertex buffers. //! \brief Drawing code to add the flags and span markers to the Vertex buffers.
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
//! \brief Returns true if should always show this flag, even if it's empty //! \brief Returns true if should always show this flag, even if it's empty
bool isAlwaysVisible() { return m_always_visible; } bool isAlwaysVisible() { return m_always_visible; }
@ -82,8 +83,6 @@ class gFlagsLine: public Layer
int total_lines, line_num; int total_lines, line_num;
FlagType m_flt; FlagType m_flt;
QColor m_flag_color; QColor m_flag_color;
gVertexBuffer *quads;
gVertexBuffer *lines;
int m_lx, m_ly; int m_lx, m_ly;
}; };
@ -99,7 +98,7 @@ class gFlagsGroup: public LayerGroup
virtual ~gFlagsGroup(); virtual ~gFlagsGroup();
//! Draw filled rectangles behind Event Flag's, and an outlines around them all, Calls the individual paint for each gFlagLine //! Draw filled rectangles behind Event Flag's, and an outlines around them all, Calls the individual paint for each gFlagLine
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
//! Returns the first time represented by all gFlagLine layers, in milliseconds since epoch //! Returns the first time represented by all gFlagLine layers, in milliseconds since epoch
virtual qint64 Minx(); virtual qint64 Minx();
@ -124,7 +123,6 @@ class gFlagsGroup: public LayerGroup
protected: protected:
virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph); virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph);
gVertexBuffer *quads, *lines;
QVector<gFlagsLine *> lvisible; QVector<gFlagsLine *> lvisible;
float m_barh; float m_barh;
bool m_empty; bool m_empty;

View File

@ -14,22 +14,16 @@
#include <cmath> #include <cmath>
#include "Graphs/gGraph.h" #include "Graphs/gGraph.h"
#include "Graphs/gVertexBuffer.h"
#include "Graphs/gYAxis.h" #include "Graphs/gYAxis.h"
gShadowArea::gShadowArea(QColor shadow_color, QColor line_color) gShadowArea::gShadowArea(QColor shadow_color, QColor line_color)
: Layer(NoChannel), m_shadow_color(shadow_color), m_line_color(line_color) : Layer(NoChannel), m_shadow_color(shadow_color), m_line_color(line_color)
{ {
addVertexBuffer(quads = new gVertexBuffer(20, GL_QUADS));
addVertexBuffer(lines = new gVertexBuffer(20, GL_LINES));
quads->forceAntiAlias(true);
lines->setAntiAlias(true);
lines->setSize(2);
} }
gShadowArea::~gShadowArea() gShadowArea::~gShadowArea()
{ {
} }
void gShadowArea::paint(gGraph &w, int left, int top, int width, int height) void gShadowArea::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) { return; } if (!m_visible) { return; }
@ -42,19 +36,16 @@ void gShadowArea::paint(gGraph &w, int left, int top, int width, int height)
int start_px = left - 1; int start_px = left - 1;
int end_px = left + width; int end_px = left + width;
//float h=top;
double rmx = w.rmax_x - w.rmin_x; double rmx = w.rmax_x - w.rmin_x;
double px = ((1.0 / rmx) * (w.min_x - w.rmin_x)) * width; double px = ((1.0 / rmx) * (w.min_x - w.rmin_x)) * width;
double py = ((1.0 / rmx) * (w.max_x - w.rmin_x)) * width; double py = ((1.0 / rmx) * (w.max_x - w.rmin_x)) * width;
quads->add(start_px, top, start_px, top + height, start_px + px, top + height, start_px + px, top, painter.fillRect(start_px, top, px, height, QBrush(m_shadow_color));
m_shadow_color.rgba()); painter.fillRect(start_px + py, top, end_px-start_px-py, height, QBrush(m_shadow_color));
quads->add(start_px + py, top, start_px + py, top + height, end_px, top + height, end_px, top,
m_shadow_color.rgba());
lines->add(start_px + px, top, start_px + py, top, m_line_color.rgba()); painter.setPen(m_line_color);
lines->add(start_px + px, top + height + 1, start_px + py, top + height + 1, m_line_color.rgba()); painter.drawLine(start_px + px, top, start_px + py, top);
painter.drawLine(start_px + px, top + height + 1, start_px + py, top + height + 1);
} }
gFooBar::gFooBar(int offset, QColor handle_color, QColor line_color) gFooBar::gFooBar(int offset, QColor handle_color, QColor line_color)
@ -64,12 +55,13 @@ gFooBar::gFooBar(int offset, QColor handle_color, QColor line_color)
gFooBar::~gFooBar() gFooBar::~gFooBar()
{ {
} }
void gFooBar::paint(gGraph &w, int left, int top, int width, int height) void gFooBar::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
Q_UNUSED(top); Q_UNUSED(top)
Q_UNUSED(left); Q_UNUSED(left)
Q_UNUSED(width); Q_UNUSED(width)
Q_UNUSED(height); Q_UNUSED(height)
Q_UNUSED(painter)
if (!m_visible) { return; } if (!m_visible) { return; }

View File

@ -12,7 +12,6 @@
#ifndef GFOOBAR_H #ifndef GFOOBAR_H
#define GFOOBAR_H #define GFOOBAR_H
#include "Graphs/gVertexBuffer.h"
#include "Graphs/layer.h" #include "Graphs/layer.h"
/*! \class gShadowArea /*! \class gShadowArea
@ -23,12 +22,10 @@ class gShadowArea: public Layer
public: public:
gShadowArea(QColor shadow_color = QColor(40, 40, 40, 40), QColor line_color = Qt::blue); gShadowArea(QColor shadow_color = QColor(40, 40, 40, 40), QColor line_color = Qt::blue);
virtual ~gShadowArea(); virtual ~gShadowArea();
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
protected: protected:
QColor m_shadow_color; QColor m_shadow_color;
QColor m_line_color; QColor m_line_color;
gVertexBuffer *quads;
gVertexBuffer *lines;
}; };
/*! \class gFooBar /*! \class gFooBar
@ -41,7 +38,7 @@ class gFooBar: public Layer
gFooBar(int offset = 10, QColor handle_color = QColor("orange"), gFooBar(int offset = 10, QColor handle_color = QColor("orange"),
QColor line_color = QColor("dark grey")); QColor line_color = QColor("dark grey"));
virtual ~gFooBar(); virtual ~gFooBar();
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
static const int Margin = 15; static const int Margin = 15;
protected: protected:
int m_offset; int m_offset;

View File

@ -26,8 +26,6 @@ QFont *defaultfont = nullptr;
QFont *mediumfont = nullptr; QFont *mediumfont = nullptr;
QFont *bigfont = nullptr; QFont *bigfont = nullptr;
QHash<QString, QImage *> images; QHash<QString, QImage *> images;
bool fbo_unsupported = false;
QGLFramebufferObject *fbo = nullptr;
static bool globalsInitialized = false; static bool globalsInitialized = false;
@ -110,17 +108,6 @@ void DestroyGraphGlobals()
delete i.value(); delete i.value();
} }
// Clear the frame buffer object.
if (fbo) {
if (fbo->isBound()) {
fbo->release();
}
delete fbo;
fbo = nullptr;
fbo_unsupported = true; // just in case shutdown order gets messed up
}
globalsInitialized = false; globalsInitialized = false;
} }
@ -164,8 +151,6 @@ gGraph::gGraph(gGraphView *graphview, QString title, QString units, int height,
invalidate_yAxisImage = true; invalidate_yAxisImage = true;
invalidate_xAxisImage = true; invalidate_xAxisImage = true;
m_quad = new gVertexBuffer(64, GL_QUADS);
m_quad->forceAntiAlias(true);
m_enforceMinY = m_enforceMaxY = false; m_enforceMinY = m_enforceMaxY = false;
m_showTitle = true; m_showTitle = true;
m_printing = false; m_printing = false;
@ -179,7 +164,6 @@ gGraph::~gGraph()
} }
m_layers.clear(); m_layers.clear();
delete m_quad;
timer->stop(); timer->stop();
disconnect(timer, 0, 0, 0); disconnect(timer, 0, 0, 0);
@ -236,19 +220,18 @@ float gGraph::printScaleX() { return m_graphview->printScaleX(); }
float gGraph::printScaleY() { return m_graphview->printScaleY(); } float gGraph::printScaleY() { return m_graphview->printScaleY(); }
void gGraph::drawGLBuf() //void gGraph::drawGLBuf()
{ //{
float linesize = 1; // float linesize = 1;
if (m_printing) { linesize = 4; } //ceil(m_graphview->printScaleY()); // if (m_printing) { linesize = 4; } //ceil(m_graphview->printScaleY());
for (int i = 0; i < m_layers.size(); i++) { // for (int i = 0; i < m_layers.size(); i++) {
m_layers[i]->drawGLBuf(linesize); // m_layers[i]->drawGLBuf(linesize);
} // }
m_quad->draw(); //}
}
void gGraph::setDay(Day *day) void gGraph::setDay(Day *day)
{ {
m_day = day; m_day = day;
@ -272,13 +255,12 @@ void gGraph::qglColor(QColor col)
m_graphview->qglColor(col); m_graphview->qglColor(col);
} }
void gGraph::renderText(QString text, int x, int y, float angle, QColor color, QFont *font, void gGraph::renderText(QString text, int x, int y, float angle, QColor color, QFont *font, bool antialias)
bool antialias)
{ {
m_graphview->AddTextQue(text, x, y, angle, color, font, antialias); m_graphview->AddTextQue(text, x, y, angle, color, font, antialias);
} }
void gGraph::paint(int originX, int originY, int width, int height) void gGraph::paint(QPainter &painter, int originX, int originY, int width, int height)
{ {
m_rect = QRect(originX, originY, width, height); m_rect = QRect(originX, originY, width, height);
@ -295,55 +277,6 @@ void gGraph::paint(int originX, int originY, int width, int height)
if (m_showTitle) { if (m_showTitle) {
int title_x, yh; int title_x, yh;
/* if (titleImage.isNull()) {
// Render the title to a texture so we don't have to draw the vertical text every time..
GetTextExtent("Wy@",x,yh,mediumfont); // This gets a better consistent height. should be cached.
GetTextExtent(title(),x,y,mediumfont);
y=yh;
QPixmap tpm=QPixmap(x+4,y+4);
tpm.fill(Qt::transparent); //empty it
QPainter pmp(&tpm);
pmp.setRenderHint(QPainter::TextAntialiasing, true);
QBrush brush2(Qt::black); // text color
pmp.setBrush(brush2);
pmp.setFont(*mediumfont);
pmp.drawText(2,y,title()); // draw from the bottom
pmp.end();
// convert to QImage and bind to a texture for future use
titleImage=QGLWidget::convertToGLFormat(tpm.toImage().mirrored(false,true));
titleImageTex=m_graphview->bindTexture(titleImage);
}
y=titleImage.height();
x=titleImage.width(); //vertical text
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
title_x=y*2;
glEnable(GL_TEXTURE_2D);
// Rotate and draw vertical texture containing graph titles
glPushMatrix();
glTranslatef(marginLeft()+4,originY+height/2+x/2, 0);
glRotatef(-90,0,0,1);
m_graphview->drawTexture(QPoint(0,y/2),titleImageTex);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
// All that to replace this little, but -hideously- slow line of text..
*/
QFontMetrics fm(*mediumfont); QFontMetrics fm(*mediumfont);
@ -354,17 +287,17 @@ void gGraph::paint(int originX, int originY, int width, int height)
//GetTextExtent(title(),x,y,mediumfont); //GetTextExtent(title(),x,y,mediumfont);
title_x = yh * 2; title_x = yh * 2;
QString & txt = title();
renderText(title(), marginLeft() + title_x + 4, originY + height / 2 - y / 2, 90, Qt::black, graphView()->AddTextQue(txt, marginLeft() + title_x + 4, originY + height / 2 - y / 2, 90, Qt::black, mediumfont);
mediumfont);
left += title_x; left += title_x;
} else { left = 0; } } else { left = 0; }
//#define DEBUG_LAYOUT //#define DEBUG_LAYOUT
#ifdef DEBUG_LAYOUT #ifdef DEBUG_LAYOUT
QColor col = Qt::red; QColor col = Qt::red;
lines()->add(0, originY, 0, originY + height, col); painter.setPen(col);
lines()->add(left, originY, left, originY + height, col); painter.drawLine(0, originY, 0, originY + height);
painter.drawLine(left, originY, left, originY + height);
#endif #endif
int tmp; int tmp;
@ -392,19 +325,23 @@ void gGraph::paint(int originX, int originY, int width, int height)
if (ll->position() == LayerLeft) { if (ll->position() == LayerLeft) {
ll->m_rect = QRect(originX + left, originY + top, tmp, height - top - bottom); ll->m_rect = QRect(originX + left, originY + top, tmp, height - top - bottom);
ll->paint(*this, originX + left, originY + top, tmp, height - top - bottom); ll->paint(painter, *this, originX + left, originY + top, tmp, height - top - bottom);
left += tmp; left += tmp;
#ifdef DEBUG_LAYOUT #ifdef DEBUG_LAYOUT
lines()->add(originX + left - 1, originY, originX + left - 1, originY + height, col); QColor col = Qt::red;
painter.setPen(col);
painter.drawLine(originX + left - 1, originY, originX + left - 1, originY + height);
#endif #endif
} }
if (ll->position() == LayerRight) { if (ll->position() == LayerRight) {
right += tmp; right += tmp;
ll->m_rect = QRect(originX + width - right, originY + top, tmp, height - top - bottom); ll->m_rect = QRect(originX + width - right, originY + top, tmp, height - top - bottom);
ll->paint(*this, originX + width - right, originY + top, tmp, height - top - bottom); ll->paint(painter, *this, originX + width - right, originY + top, tmp, height - top - bottom);
#ifdef DEBUG_LAYOUT #ifdef DEBUG_LAYOUT
lines()->add(originX + width - right, originY, originX + width - right, originY + height, col); QColor col = Qt::red;
painter.setPen(col);
painter.drawLine(originX + width - right, originY, originX + width - right, originY + height);
#endif #endif
} }
} }
@ -421,28 +358,20 @@ void gGraph::paint(int originX, int originY, int width, int height)
if (ll->position() == LayerTop) { if (ll->position() == LayerTop) {
ll->m_rect = QRect(originX + left, originY + top, width - left - right, tmp); ll->m_rect = QRect(originX + left, originY + top, width - left - right, tmp);
ll->paint(*this, originX + left, originY + top, width - left - right, tmp); ll->paint(painter, *this, originX + left, originY + top, width - left - right, tmp);
top += tmp; top += tmp;
} }
if (ll->position() == LayerBottom) { if (ll->position() == LayerBottom) {
bottom += tmp; bottom += tmp;
ll->m_rect = QRect(originX + left, originY + height - bottom, width - left - right, tmp); ll->m_rect = QRect(originX + left, originY + height - bottom, width - left - right, tmp);
ll->paint(*this, originX + left, originY + height - bottom, width - left - right, tmp); ll->paint(painter, *this, originX + left, originY + height - bottom, width - left - right, tmp);
} }
} }
if (isPinned()) { if (isPinned()) {
// Fill the background on pinned graphs // Fill the background on pinned graphs
painter.fillRect(originX + left, originY + top, width - right, height - bottom - top, QBrush(QColor(Qt::white)));
// m_graphview->quads->add(originX+left,originY+top, originX+width-right,originY+top, originX+width-right,originY+height-bottom, originX+left,originY+height-bottom, 0xffffffff);
glBegin(GL_QUADS);
glColor4f(1.0, 1.0, 1.0, 1.0); // Gradient End
glVertex2i(originX + left, originY + top);
glVertex2i(originX + width - right, originY + top);
glVertex2i(originX + width - right, originY + height - bottom);
glVertex2i(originX + left, originY + height - bottom);
glEnd();
} }
for (int i = 0; i < m_layers.size(); i++) { for (int i = 0; i < m_layers.size(); i++) {
@ -452,23 +381,22 @@ void gGraph::paint(int originX, int originY, int width, int height)
if (ll->position() == LayerCenter) { if (ll->position() == LayerCenter) {
ll->m_rect = QRect(originX + left, originY + top, width - left - right, height - top - bottom); ll->m_rect = QRect(originX + left, originY + top, width - left - right, height - top - bottom);
ll->paint(*this, originX + left, originY + top, width - left - right, height - top - bottom); ll->paint(painter, *this, originX + left, originY + top, width - left - right, height - top - bottom);
} }
} }
if (m_selection.width() > 0 && m_selecting_area) { if (m_selection.width() > 0 && m_selecting_area) {
QColor col(128, 128, 255, 128); QColor col(128, 128, 255, 128);
quads()->add(originX + m_selection.x(), originY + top, painter.fillRect(originX + m_selection.x(), originY + top, m_selection.width(), height - bottom - top,QBrush(col));
originX + m_selection.x() + m_selection.width(), originY + top, col.rgba()); // quads()->add(originX + m_selection.x(), originY + top,
quads()->add(originX + m_selection.x() + m_selection.width(), originY + height - bottom, // originX + m_selection.x() + m_selection.width(), originY + top, col.rgba());
originX + m_selection.x(), originY + height - bottom, col.rgba()); // quads()->add(originX + m_selection.x() + m_selection.width(), originY + height - bottom,
// originX + m_selection.x(), originY + height - bottom, col.rgba());
} }
} }
QPixmap gGraph::renderPixmap(int w, int h, bool printing) QPixmap gGraph::renderPixmap(int w, int h, bool printing)
{ {
QPixmap pm = QPixmap();
gGraphView *sg = mainwin->snapshotGraph(); gGraphView *sg = mainwin->snapshotGraph();
if (!sg) { if (!sg) {
@ -524,29 +452,14 @@ QPixmap gGraph::renderPixmap(int w, int h, bool printing)
float dpr = sg->devicePixelRatio(); float dpr = sg->devicePixelRatio();
sg->setDevicePixelRatio(1); sg->setDevicePixelRatio(1);
#ifdef Q_OS_WIN
if (pm.isNull()) { QPixmap pm(w,h);
pm = sg->renderPixmap(w, h, false);
}
if (pm.isNull()) { // Works, but gives shader warnings QPainter painter(&pm);
pm = QPixmap::fromImage(sg->pbRenderPixmap(w, h)); painter.fillRect(0,0,w,h,QBrush(QColor(Qt::white)));
} sg->renderGraphs(painter);
painter.end();
if (pm.isNull()) { // crashes on mine, not sure what to do about it
pm = QPixmap::fromImage(sg->fboRenderPixmap(w, h));
}
#else
pm = QPixmap::fromImage(sg->fboRenderPixmap(w, h));
if (pm.isNull()) { // not sure if this will work with printing
qDebug() << "Had to use PixelBuffer for snapshots\n";
pm = QPixmap::fromImage(sg->pbRenderPixmap(w, h));
}
#endif
sg->setDevicePixelRatio(dpr); sg->setDevicePixelRatio(dpr);
//sg->doneCurrent(); //sg->doneCurrent();
sg->trashGraphs(); sg->trashGraphs();
@ -1154,9 +1067,9 @@ void gGraph::ZoomX(double mult, int origin_px)
//updateSelectionTime(max-min); //updateSelectionTime(max-min);
} }
void gGraph::DrawTextQue() void gGraph::DrawTextQue(QPainter &painter)
{ {
m_graphview->DrawTextQue(); m_graphview->DrawTextQue(painter);
} }
// margin recalcs.. // margin recalcs..
@ -1367,26 +1280,6 @@ void gGraph::SetMaxY(EventDataType v)
rmax_y = max_y = v; rmax_y = max_y = v;
} }
gVertexBuffer *gGraph::lines()
{
return m_graphview->lines;
}
gVertexBuffer *gGraph::backlines()
{
return m_graphview->backlines;
}
gVertexBuffer *gGraph::quads()
{
return m_graphview->quads;
}
short gGraph::marginLeft() { return m_marginleft; }//*m_graphview->printScaleX(); }
short gGraph::marginRight() { return m_marginright; } //*m_graphview->printScaleX(); }
short gGraph::marginTop() { return m_margintop; } //*m_graphview->printScaleY(); }
short gGraph::marginBottom() { return m_marginbottom; } //*m_graphview->printScaleY(); }
Layer *gGraph::getLineChart() Layer *gGraph::getLineChart()
{ {
gLineChart *lc; gLineChart *lc;

View File

@ -11,11 +11,11 @@
#define graphs_ggraph_h #define graphs_ggraph_h
#include <QFont> #include <QFont>
#include <QGLFramebufferObject>
#include <QObject> #include <QObject>
#include <QPixmap> #include <QPixmap>
#include <QResizeEvent> #include <QResizeEvent>
#include <QString> #include <QString>
#include <QPainter>
#include "Graphs/layer.h" #include "Graphs/layer.h"
@ -26,14 +26,10 @@ extern QFont *defaultfont;
extern QFont *mediumfont; extern QFont *mediumfont;
extern QFont *bigfont; extern QFont *bigfont;
extern QHash<QString, QImage *> images; extern QHash<QString, QImage *> images;
extern bool fbo_unsupported;
extern QGLFramebufferObject *fbo;
bool InitGraphGlobals(); bool InitGraphGlobals();
void DestroyGraphGlobals(); void DestroyGraphGlobals();
const int max_fbo_width = 2048;
const int max_fbo_height = 2048;
const int mouse_movement_threshold = 6; const int mouse_movement_threshold = 6;
/*! \class gGraph /*! \class gGraph
@ -41,7 +37,7 @@ const int mouse_movement_threshold = 6;
*/ */
class gGraph : public QObject class gGraph : public QObject
{ {
Q_OBJECT; Q_OBJECT
public: public:
friend class gGraphView; friend class gGraphView;
@ -124,11 +120,11 @@ class gGraph : public QObject
// Applies the Graph Preference min/max settings. // Applies the Graph Preference min/max settings.
void roundY(EventDataType &miny, EventDataType &maxy); void roundY(EventDataType &miny, EventDataType &maxy);
//! \brief Process all Layers GLBuffer (Vertex) objects, drawing the actual OpenGL stuff. // //! \brief Process all Layers GLBuffer (Vertex) objects, drawing the actual OpenGL stuff.
void drawGLBuf(); // void drawGLBuf();
//! \brief Returns the Graph's (vertical) title //! \brief Returns the Graph's (vertical) title
QString title() { return m_title; } inline QString & title() { return m_title; }
//! \brief Sets the Graph's (vertical) title //! \brief Sets the Graph's (vertical) title
void setTitle(const QString title) { m_title = title; } void setTitle(const QString title) { m_title = title; }
@ -226,7 +222,7 @@ class gGraph : public QObject
void setGroup(short group) { m_group = group; } void setGroup(short group) { m_group = group; }
//! \brief Forces the main gGraphView object to draw all Text Components //! \brief Forces the main gGraphView object to draw all Text Components
void DrawTextQue(); void DrawTextQue(QPainter &painter);
//! \brief Sends supplied day object to all Graph layers so they can precalculate stuff //! \brief Sends supplied day object to all Graph layers so they can precalculate stuff
void setDay(Day *day); void setDay(Day *day);
@ -235,7 +231,7 @@ class gGraph : public QObject
Day *day() { return m_day; } Day *day() { return m_day; }
//! \brief The Layer, layout and title drawing code //! \brief The Layer, layout and title drawing code
virtual void paint(int originX, int originY, int width, int height); virtual void paint(QPainter &painter, int originX, int originY, int width, int height);
//! \brief Gives the supplied data to the main ToolTip object for display //! \brief Gives the supplied data to the main ToolTip object for display
void ToolTip(QString text, int x, int y, int timeout = 0); void ToolTip(QString text, int x, int y, int timeout = 0);
@ -255,33 +251,19 @@ class gGraph : public QObject
} }
//! \brief Returns this graphs left margin //! \brief Returns this graphs left margin
short marginLeft(); inline short marginLeft() { return m_marginleft; }
//! \brief Returns this graphs right margin //! \brief Returns this graphs right margin
short marginRight(); inline short marginRight() { return m_marginright; }
//! \brief Returns this graphs top margin //! \brief Returns this graphs top margin
short marginTop(); inline short marginTop() { return m_margintop; }
//! \brief Returns this graphs bottom margin //! \brief Returns this graphs bottom margin
short marginBottom(); inline short marginBottom() { return m_marginbottom; }
//! \brief Returns the main gGraphView objects gVertexBuffer line list.
gVertexBuffer *lines();
//! \brief Returns the main gGraphView objects gVertexBuffer background line list.
gVertexBuffer *backlines();
//! \brief Returns the main gGraphView objects gVertexBuffer front line list.
gVertexBuffer *frontlines();
//! \brief Returns the main gGraphView objects gVertexBuffer quads list.
gVertexBuffer *quads();
const inline QRect &rect() const { return m_rect; } const inline QRect &rect() const { return m_rect; }
bool isPinned() { return m_pinned; } bool isPinned() { return m_pinned; }
void setPinned(bool b) { m_pinned = b; } void setPinned(bool b) { m_pinned = b; }
// //! \brief Returns the main gGraphView objects gVertexBuffer stippled line list.
//GLShortBuffer * stippled();
//gVertexBuffer * vlines(); // testing new vertexbuffer
short left, right, top, bottom; // dirty magin hacks.. short left, right, top, bottom; // dirty magin hacks..
Layer *getLineChart(); Layer *getLineChart();
@ -344,7 +326,6 @@ class gGraph : public QObject
short m_group; short m_group;
short m_lastx23; short m_lastx23;
Day *m_day; Day *m_day;
gVertexBuffer *m_quad;
bool m_enforceMinY, m_enforceMaxY; bool m_enforceMinY, m_enforceMaxY;
bool m_showTitle; bool m_showTitle;
bool m_printing; bool m_printing;

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
#include <QWaitCondition> #include <QWaitCondition>
#include <QPixmap> #include <QPixmap>
#include <QRect> #include <QRect>
#include <QPixmapCache>
#include <Graphs/gGraph.h> #include <Graphs/gGraph.h>
#include <Graphs/glcommon.h> #include <Graphs/glcommon.h>
@ -36,6 +37,22 @@ const int textque_max = 512;
\brief Holds a single item of text for the drawing queue \brief Holds a single item of text for the drawing queue
*/ */
struct TextQue { struct TextQue {
TextQue() {
}
TextQue(short x, short y, float angle, QString text, QColor color, QFont * font, bool antialias):
x(x), y(y), angle(angle), text(text), color(color), font(font), antialias(antialias)
{
}
TextQue(const TextQue & copy) {
x=copy.x;
y=copy.y;
text=copy.text;
angle=copy.angle;
color=copy.color;
font=copy.font;
antialias=copy.antialias;
}
//! \variable contains the x axis screen position to draw the text //! \variable contains the x axis screen position to draw the text
short x; short x;
//! \variable contains the y axis screen position to draw the text //! \variable contains the y axis screen position to draw the text
@ -106,8 +123,8 @@ class gToolTip : public QObject
*/ */
virtual void display(QString text, int x, int y, int timeout = 0); virtual void display(QString text, int x, int y, int timeout = 0);
//! \brief Queue the actual OpenGL drawing instructions //! \brief Draw the tooltip
virtual void paint(); //actually paints it. virtual void paint(QPainter &paint); //actually paints it.
//! \brief Close the tooltip early. //! \brief Close the tooltip early.
void cancel(); void cancel();
@ -133,16 +150,6 @@ class gToolTip : public QObject
void timerDone(); void timerDone();
}; };
/*! \struct myPixmapCache
\brief My version of Pixmap cache with texture binding support
*/
struct myPixmapCache {
quint64 last_used;
QImage image;
GLuint textureID;
};
/*! \class gGraphView /*! \class gGraphView
\brief Main OpenGL Graph Area, derived from QGLWidget \brief Main OpenGL Graph Area, derived from QGLWidget
@ -226,12 +233,6 @@ class gGraphView : public QGLWidget
//! \brief Set a redraw timer for ms milliseconds, clearing any previous redraw timer. //! \brief Set a redraw timer for ms milliseconds, clearing any previous redraw timer.
void timedRedraw(int ms); void timedRedraw(int ms);
//! \brief Start the animation sequence changing/reloading day data. (fade out)
void fadeOut();
//! \brief Start the animation sequence showing new Day's data. (fade in)
void fadeIn(bool dir = false);
//! \brief Call UpdateGL unless animation is in progress //! \brief Call UpdateGL unless animation is in progress
void redraw(); void redraw();
@ -243,11 +244,11 @@ class gGraphView : public QGLWidget
void selectionTime(); void selectionTime();
//! \brief Add the Text information to the Text Drawing Queue (called by gGraphs renderText method) //! \brief Add the Text information to the Text Drawing Queue (called by gGraphs renderText method)
void AddTextQue(QString &text, short x, short y, float angle = 0.0, void AddTextQue(const QString &text, short x, short y, float angle = 0.0,
QColor color = Qt::black, QFont *font = defaultfont, bool antialias = true); QColor color = Qt::black, QFont *font = defaultfont, bool antialias = true);
//! \brief Draw all Text in the text drawing queue // //! \brief Draw all Text in the text drawing queue
void DrawTextQue(); // void DrawTextQue();
//! \brief Draw all text components using QPainter object painter //! \brief Draw all text components using QPainter object painter
void DrawTextQue(QPainter &painter); void DrawTextQue(QPainter &painter);
@ -304,8 +305,6 @@ class gGraphView : public QGLWidget
//! \brief Sends day object to be distributed to all Graphs Layers objects //! \brief Sends day object to be distributed to all Graphs Layers objects
void setDay(Day *day); void setDay(Day *day);
gVertexBuffer *lines, *backlines, *quads, *frontlines;
//! \brief pops a graph off the list for multithreaded drawing code //! \brief pops a graph off the list for multithreaded drawing code
gGraph *popGraph(); // exposed for multithreaded drawing gGraph *popGraph(); // exposed for multithreaded drawing
@ -318,24 +317,27 @@ class gGraphView : public QGLWidget
//! \brief Trash all graph objects listed (without destroying Graph contents) //! \brief Trash all graph objects listed (without destroying Graph contents)
void trashGraphs(); void trashGraphs();
//! \brief Use a QGLFrameBufferObject to render to a pixmap
QImage fboRenderPixmap(int w, int h);
//! \brief Use a QGLPixelBuffer to render to a pixmap
QImage pbRenderPixmap(int w, int h);
//! \brief Enable or disable the Text Pixmap Caching system preference overide //! \brief Enable or disable the Text Pixmap Caching system preference overide
void setUsePixmapCache(bool b) { use_pixmap_cache = b; } void setUsePixmapCache(bool b) { use_pixmap_cache = b; }
//! \brief Return whether or not the Pixmap Cache for text rendering is being used. //! \brief Return whether or not the Pixmap Cache for text rendering is being used.
bool usePixmapCache(); bool usePixmapCache();
//! \brief Graph drawing routines, returns true if there weren't any graphs to draw
bool renderGraphs(QPainter &painter);
// for profiling purposes, a count of lines drawn in a single frame
int lines_drawn_this_frame;
int quads_drawn_this_frame;
int strings_drawn_this_frame;
int strings_cached_this_frame;
protected: protected:
//! \brief Set up the OpenGL basics for the QGLWidget underneath //! \brief Set up the OpenGL basics for the QGLWidget underneath
virtual void initializeGL(); virtual void initializeGL();
//! \brief Resize the OpenGL ViewPort prior to redrawing // //! \brief Resize the OpenGL ViewPort prior to redrawing
virtual void resizeGL(int width, int height); //virtual void resizeGL(int width, int height);
//! \brief The heart of the OpenGL drawing code //! \brief The heart of the OpenGL drawing code
virtual void paintGL(); virtual void paintGL();
@ -346,9 +348,6 @@ class gGraphView : public QGLWidget
//! \brief Calculates the sum of all graph heights, taking scaling into consideration //! \brief Calculates the sum of all graph heights, taking scaling into consideration
float scaleHeight(); float scaleHeight();
//! \brief Graph drawing routines, returns true if there weren't any graphs to draw
bool renderGraphs();
//! \brief Update the OpenGL area when the screen is resized //! \brief Update the OpenGL area when the screen is resized
virtual void resizeEvent(QResizeEvent *); virtual void resizeEvent(QResizeEvent *);
@ -375,7 +374,7 @@ class gGraphView : public QGLWidget
void queGraph(gGraph *, int originX, int originY, int width, int height); void queGraph(gGraph *, int originX, int originY, int width, int height);
//! \brief Render the annoying spinning graph empty cube //! \brief Render the annoying spinning graph empty cube
void renderCube(float alpha = 1); void renderCube(QPainter &painter, float alpha = 1);
Day *m_day; Day *m_day;
@ -415,9 +414,8 @@ class gGraphView : public QGLWidget
int m_graph_index; int m_graph_index;
//! \brief List of all queue text to draw.. not sure why I didn't use a vector here.. Might of been a leak issue //! \brief List of all queue text to draw.. not sure why I didn't use a vector here.. Might of been a leak issue
TextQue m_textque[textque_max]; QVector<TextQue> m_textque;
int m_textque_items;
int m_lastxpos, m_lastypos; int m_lastxpos, m_lastypos;
QString m_emptytext; QString m_emptytext;
@ -439,11 +437,10 @@ class gGraphView : public QGLWidget
QTime m_animationStarted; QTime m_animationStarted;
// turn this into a struct later..
QHash<QString, myPixmapCache *> pixmap_cache;
qint32 pixmap_cache_size;
bool use_pixmap_cache; bool use_pixmap_cache;
QPixmapCache pixmapcache;
QTime horizScrollTime, vertScrollTime; QTime horizScrollTime, vertScrollTime;
public slots: public slots:

View File

@ -28,10 +28,7 @@ gLineChart::gLineChart(ChannelID code, QColor col, bool square_plot, bool disabl
addPlot(code, col, square_plot); addPlot(code, col, square_plot);
m_line_color = col; m_line_color = col;
m_report_empty = false; m_report_empty = false;
addVertexBuffer(lines = new gVertexBuffer(100000, GL_LINES)); lines.reserve(50000);
lines->setColor(col);
lines->setAntiAlias(true);
lines->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} }
gLineChart::~gLineChart() gLineChart::~gLineChart()
{ {
@ -131,12 +128,7 @@ void gLineChart::SetDay(Day *d)
} }
//if (m_code==CPAP_Leak) {
// subtract_offset=profile.cpap.[IntentionalLeak].toDouble();
//} else
subtract_offset = 0; subtract_offset = 0;
} }
EventDataType gLineChart::Miny() EventDataType gLineChart::Miny()
{ {
@ -156,7 +148,7 @@ EventDataType gLineChart::Maxy()
} }
// Time Domain Line Chart // Time Domain Line Chart
void gLineChart::paint(gGraph &w, int left, int top, int width, int height) void gLineChart::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) { if (!m_visible) {
return; return;
@ -174,7 +166,6 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
top++; top++;
// lines=w.lines();
EventDataType miny, maxy; EventDataType miny, maxy;
double minx, maxx; double minx, maxx;
@ -226,12 +217,12 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
int minz, maxz; int minz, maxz;
// Draw bounding box // Draw bounding box
gVertexBuffer *outlines = w.lines(); painter.setPen(QColor(Qt::black));
GLuint blk = QColor(Qt::black).rgba(); painter.drawLine(left, top, left, top + height);
outlines->add(left, top, left, top + height, blk); painter.drawLine(left, top + height, left + width, top + height);
outlines->add(left, top + height, left + width, top + height, blk); painter.drawLine(left + width, top + height, left + width, top);
outlines->add(left + width, top + height, left + width, top, blk); painter.drawLine(left + width, top, left, top);
outlines->add(left + width, top, left, top, blk);
width--; width--;
height -= 2; height -= 2;
@ -250,16 +241,19 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
int codepoints; int codepoints;
//GLuint color; painter.setClipRect(left, top, width, height+1);
painter.setClipping(true);
painter.setRenderHint(QPainter::Antialiasing, true);
for (int gi = 0; gi < m_codes.size(); gi++) { for (int gi = 0; gi < m_codes.size(); gi++) {
ChannelID code = m_codes[gi]; ChannelID code = m_codes[gi];
//m_line_color=m_colors[gi];
lines->setColor(m_colors[gi]); lines.clear();
//color=m_line_color.rgba();
codepoints = 0; codepoints = 0;
for (int svi = 0; svi < m_day->size(); svi++) { int daysize = m_day->size();
for (int svi = 0; svi < daysize; svi++) {
Session *sess = (*m_day)[svi]; Session *sess = (*m_day)[svi];
if (!sess) { if (!sess) {
@ -274,9 +268,10 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
schema::Channel ch = schema::channel[code]; schema::Channel ch = schema::channel[code];
bool fndbetter = false; bool fndbetter = false;
for (QList<schema::Channel *>::iterator l = ch.m_links.begin(); l != ch.m_links.end(); l++) { QList<schema::Channel *>::iterator mlend=ch.m_links.end();
schema::Channel *c = *l; for (QList<schema::Channel *>::iterator l = ch.m_links.begin(); l != mlend; l++) {
ci = (*m_day)[svi]->eventlist.find(c->id()); schema::Channel &c = *(*l);
ci = (*m_day)[svi]->eventlist.find(c.id());
if (ci != (*m_day)[svi]->eventlist.end()) { if (ci != (*m_day)[svi]->eventlist.end()) {
fndbetter = true; fndbetter = true;
@ -294,17 +289,19 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
QVector<EventList *> &evec = ci.value(); QVector<EventList *> &evec = ci.value();
num_points = 0; num_points = 0;
int evecsize=evec.size();
for (int i = 0; i < evec.size(); i++) { for (int i = 0; i < evecsize; i++) {
num_points += evec[i]->count(); num_points += evec[i]->count();
} }
total_points += num_points; total_points += num_points;
codepoints += num_points; codepoints += num_points;
const int num_averages =
20; // Max n umber of samples taken from samples per pixel for better min/max values
for (int n = 0; n < evec.size(); n++) { // for each segment // Max number of samples taken from samples per pixel for better min/max values
const int num_averages = 20;
for (int n = 0; n < evecsize; ++n) { // for each segment
EventList &el = *evec[n]; EventList &el = *evec[n];
accel = (el.type() == EVL_Waveform); // Turn on acceleration if this is a waveform. accel = (el.type() == EVL_Waveform); // Turn on acceleration if this is a waveform.
@ -423,22 +420,9 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
double time; double time;
EventDataType data; EventDataType data;
EventDataType gain = el.gain(); EventDataType gain = el.gain();
//EventDataType nmult=ymult*gain;
//EventDataType ymin=EventDataType(miny)/gain;
//const QVector<EventStoreType> & dat=el.getData();
//const QVector<quint32> & tim=el.getTime();
//quint32 * tptr;
//qint64 stime=el.first();
done = false; done = false;
// if (!accel) {
lines->setSize(1.5);
// } else lines->setSize(1);
if (el.type() == EVL_Waveform) { // Waveform Plot if (el.type() == EVL_Waveform) { // Waveform Plot
if (idx > sam) { idx -= sam; } if (idx > sam) { idx -= sam; }
@ -451,12 +435,6 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
// Accelerated Waveform Plot // Accelerated Waveform Plot
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// qint64 tmax=(maxx-time)/rate;
// if ((tmax*sam) < siz) {
// siz=idx+tmax*sam;
// done=true;
// }
for (int i = idx; i < siz; i += sam, ptr += sam) { for (int i = idx; i < siz; i += sam, ptr += sam) {
time += rate; time += rate;
// This is much faster than QVector access. // This is much faster than QVector access.
@ -519,21 +497,12 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
// Cap within VertexBuffer capacity, one vertex per line point // Cap within VertexBuffer capacity, one vertex per line point
int np = (maxz - minz) * 2; // int np = (maxz - minz) * 2;
int j = lines->Max() - lines->cnt(); for (int i = minz; i < maxz; i++, drl++) {
ax1 = drl->x();
if (np < j) { ay1 = drl->y();
for (int i = minz; i < maxz; i++, drl++) { lines.append(QLine(xst + i, yst - ax1, xst + i, yst - ay1));
ax1 = drl->x();
ay1 = drl->y();
lines->unsafe_add(xst + i, yst - ax1, xst + i, yst - ay1);
//if (lines->full()) break;
}
} else {
qDebug() << "gLineChart full trying to draw" << schema::channel[code].label();
done = true;
} }
} else { // Zoomed in Waveform } else { // Zoomed in Waveform
@ -541,13 +510,6 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
// Normal Waveform Plot // Normal Waveform Plot
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// Cap within VertexBuffer capacity, one vertex per line point
// int np=((siz-idx)/sam)*2;
// int j=lines->Max()-lines->cnt();
// if (np > j) {
// siz=j*sam;
// }
// Prime first point // Prime first point
data = (*ptr + el.offset()) * gain; data = (*ptr + el.offset()) * gain;
lastpx = xst + ((time - minx) * xmult); lastpx = xst + ((time - minx) * xmult);
@ -563,7 +525,7 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
py = yst - ((data - miny) * ymult); // Same for Y scale, with precomputed gain py = yst - ((data - miny) * ymult); // Same for Y scale, with precomputed gain
//py=yst-((data - ymin) * nmult); // Same for Y scale, with precomputed gain //py=yst-((data - ymin) * nmult); // Same for Y scale, with precomputed gain
lines->add(lastpx, lastpy, px, py); lines.append(QLine(lastpx, lastpy, px, py));
lastpx = px; lastpx = px;
lastpy = py; lastpy = py;
@ -572,10 +534,6 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
done = true; done = true;
break; break;
} }
if (lines->full()) {
break;
}
} }
} }
@ -619,20 +577,12 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
siz -= idx; siz -= idx;
// Check if would overflow lines gVertexBuffer
int gs = siz << 1; int gs = siz << 1;
int j = lines->Max() - lines->cnt();
if (square_plot) { if (square_plot) {
gs <<= 1; gs <<= 1;
} }
if (gs > j) {
qDebug() << "Would overflow line points.. increase default VertexBuffer size in gLineChart";
siz = (j >> square_plot) ? 2 : 1;
done = true; // end after this partial draw..
}
// Unrolling square plot outside of loop to gain a minor speed improvement. // Unrolling square plot outside of loop to gain a minor speed improvement.
EventStoreType *eptr = dptr + siz; EventStoreType *eptr = dptr + siz;
@ -652,12 +602,15 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
// Cap px to right margin // Cap px to right margin
if (px > xst + width) { px = xst + width; } if (px > xst + width) { px = xst + width; }
lines->unsafe_add(lastpx, lastpy, px, lastpy, px, lastpy, px, py); lines.append(QLine(lastpx, lastpy, px, lastpy));
lines.append(QLine(px, lastpy, px, py));
} else { } else {
// Letting the scissor do the dirty work for non horizontal lines // Letting the scissor do the dirty work for non horizontal lines
// This really should be changed, as it might be cause that weird // This really should be changed, as it might be cause that weird
// display glitch on Linux.. // display glitch on Linux..
lines->unsafe_add(lastpx, lastpy, px, lastpy, px, lastpy, px, py);
lines.append(QLine(lastpx, lastpy, px, lastpy));
lines.append(QLine(px, lastpy, px, py));
} }
lastpx = px; lastpx = px;
@ -685,12 +638,12 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
// Cap px to right margin // Cap px to right margin
if (px > xst + width) { px = xst + width; } if (px > xst + width) { px = xst + width; }
lines->unsafe_add(lastpx, lastpy, px, py); lines.append(QLine(lastpx, lastpy, px, py));
} else { } else {
// Letting the scissor do the dirty work for non horizontal lines // Letting the scissor do the dirty work for non horizontal lines
// This really should be changed, as it might be cause that weird // This really should be changed, as it might be cause that weird
// display glitch on Linux.. // display glitch on Linux..
lines->unsafe_add(lastpx, lastpy, px, py); lines.append(QLine(lastpx, lastpy, px, py));
} }
lastpx = px; lastpx = px;
@ -707,6 +660,10 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
if (done) { break; } if (done) { break; }
} }
} }
painter.setPen(QPen(m_colors[gi],p_profile->appearance->lineThickness()));
painter.drawLines(lines);
w.graphView()->lines_drawn_this_frame+=lines.count();
lines.clear();
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Draw Legends on the top line // Draw Legends on the top line
@ -716,17 +673,19 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
int bw = fm.width('X'); int bw = fm.width('X');
int bh = fm.height() / 1.8; int bh = fm.height() / 1.8;
if ((codepoints > 0)) { //(m_codes.size()>1) &&
if ((codepoints > 0)) {
QString text = schema::channel[code].label(); QString text = schema::channel[code].label();
int wid, hi; int wid, hi;
GetTextExtent(text, wid, hi); GetTextExtent(text, wid, hi);
legendx -= wid; legendx -= wid;
painter.setClipping(false);
w.renderText(text, legendx, top - 4); w.renderText(text, legendx, top - 4);
legendx -= bw /2;
painter.fillRect(legendx - bw, top - w.marginTop()-2, bh, w.marginTop()+1, QBrush(m_colors[gi]));
painter.setClipping(true);
int tp = top - 5 - bh / 2; legendx -= bw*2;
w.quads()->add(legendx - bw, tp + bh / 2, legendx, tp + bh / 2, legendx, tp - bh / 2, legendx - bw,
tp - bh / 2, m_colors[gi].rgba());
legendx -= bw * 2;
} }
} }
@ -738,219 +697,7 @@ void gLineChart::paint(gGraph &w, int left, int top, int width, int height)
GetTextExtent(msg, x, y, bigfont); GetTextExtent(msg, x, y, bigfont);
//DrawText(w,msg,left+(width/2.0)-(x/2.0),scry-w.GetBottomMargin()-height/2.0+y/2.0,0,Qt::gray,bigfont); //DrawText(w,msg,left+(width/2.0)-(x/2.0),scry-w.GetBottomMargin()-height/2.0+y/2.0,0,Qt::gray,bigfont);
} }
} else {
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
float dpr = w.graphView()->devicePixelRatio();
lines->scissor(left * dpr, w.flipY(top + height + 2)*dpr, (width + 1)*dpr, (height + 1)*dpr);
#else
lines->scissor(left, w.flipY(top + height + 2), width + 1, height + 1);
#endif
} }
} painter.setClipping(false);
painter.setRenderHint(QPainter::Antialiasing, false);
AHIChart::AHIChart(QColor col)
: Layer(NoChannel), m_color(col)
{
m_miny = m_maxy = 0;
addVertexBuffer(lines = new gVertexBuffer(100000, GL_LINES));
lines->setColor(col);
lines->setAntiAlias(true);
lines->setSize(1.5);
}
AHIChart::~AHIChart()
{
}
void AHIChart::paint(gGraph &w, int left, int top, int width, int height)
{
if (!m_visible) {
return;
}
if (!m_day) {
return;
}
// Draw bounding box
gVertexBuffer *outlines = w.lines();
GLuint blk = QColor(Qt::black).rgba();
outlines->add(left, top, left, top + height, blk);
outlines->add(left, top + height, left + width, top + height, blk);
outlines->add(left + width, top + height, left + width, top, blk);
outlines->add(left + width, top, left, top, blk);
width--;
height -= 2;
EventDataType miny, maxy;
double minx, maxx;
maxx = w.max_x, minx = w.min_x;
// hmmm.. subtract_offset..
if (w.zoomY() == 0 && PROFILE.appearance->allowYAxisScaling()) {
miny = w.physMinY();
maxy = w.physMaxY();
} else {
miny = w.min_y, maxy = w.max_y;
}
w.roundY(miny, maxy);
double xx = maxx - minx;
double xmult = double(width) / xx;
EventDataType yy = maxy - miny;
EventDataType ymult = EventDataType(height - 3) / yy; // time to pixel conversion multiplier
bool first = true;
double px, py;
double lastpx, lastpy;
double top1 = top + height;
bool done = false;
//GLuint color=m_color.rgba();
for (int i = 0; i < m_time.size(); i++) {
qint64 ti = m_time[i];
EventDataType v = m_data[i];
if (ti < minx) { continue; }
if (ti > maxx) { done = true; }
if (first) {
if (i > 0) {
ti = m_time[i - 1];
v = m_data[i - 1];
i--;
}
px = left + (double(ti - minx) * xmult);
py = top1 - (double(v - miny) * ymult);
first = false;
} else {
px = left + (double(ti - minx) * xmult);
py = top1 - (double(v - miny) * ymult);
lines->add(px, py, lastpx, lastpy);
}
lastpx = px;
lastpy = py;
if (done) { break; }
}
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
float dpr = w.graphView()->devicePixelRatio();
lines->scissor(left * dpr, w.flipY(top + height + 2)*dpr, (width + 1)*dpr, (height + 1)*dpr);
#else
lines->scissor(left, w.flipY(top + height + 2), width + 1, height + 1);
#endif
}
void AHIChart::SetDay(Day *d)
{
m_day = d;
m_data.clear();
m_time.clear();
m_maxy = 0;
m_miny = 0;
if (!d) { return; }
m_miny = 9999;
QList<Session *>::iterator s;
qint64 first = d->first();
qint64 last = d->last();
qint64 f;
qint64 winsize = 30000; // 30 second windows
for (qint64 ti = first; ti < last; ti += winsize) {
f = ti - 3600000L;
//if (f<first) f=first;
EventList *el[6];
EventDataType ahi = 0;
int cnt = 0;
qint64 clockdrift = (qint64(PROFILE.cpap->clockDrift()) * 1000L), drift = 0;
bool fnd = false;
for (s = d->begin(); s != d->end(); s++) {
if (!(*s)->enabled()) { continue; }
Session *sess = *s;
if ((ti < sess->first()) || (f > sess->last())) { continue; }
drift = (sess->machine()->GetType() == MT_CPAP) ? clockdrift : 0;
// Drop off suddenly outside of sessions
//if (ti>sess->last()) continue;
fnd = true;
if (sess->eventlist.contains(CPAP_Obstructive)) {
el[0] = sess->eventlist[CPAP_Obstructive][0];
} else { el[0] = nullptr; }
if (sess->eventlist.contains(CPAP_Apnea)) {
el[1] = sess->eventlist[CPAP_Apnea][0];
} else { el[1] = nullptr; }
if (sess->eventlist.contains(CPAP_Hypopnea)) {
el[2] = sess->eventlist[CPAP_Hypopnea][0];
} else { el[2] = nullptr; }
if (sess->eventlist.contains(CPAP_ClearAirway)) {
el[3] = sess->eventlist[CPAP_ClearAirway][0];
} else { el[3] = nullptr; }
if (sess->eventlist.contains(CPAP_NRI)) {
el[4] = sess->eventlist[CPAP_NRI][0];
} else { el[4] = nullptr; }
int znt = 5;
if (PROFILE.general->calculateRDI()) {
if (sess->eventlist.contains(CPAP_RERA)) {// What about ExP??
el[5] = sess->eventlist[CPAP_RERA][0];
znt++;
} else { el[5] = nullptr; }
}
qint64 t;
for (int i = 0; i < znt; i++) {
if (!el[i]) { continue; }
for (quint32 j = 0; j < el[i]->count(); j++) {
t = el[i]->time(j) + drift;
if ((t >= f) && (t < ti)) {
cnt++;
}
}
}
}
if (!fnd) { cnt = 0; }
double g = double(ti - f) / 3600000.0;
if (g > 0) { ahi = cnt / g; }
if (ahi < m_miny) { m_miny = ahi; }
if (ahi > m_maxy) { m_maxy = ahi; }
m_time.append(ti);
m_data.append(ahi);
}
m_minx = first;
m_maxx = last;
} }

View File

@ -14,50 +14,10 @@
#include <QVector> #include <QVector>
#include "Graphs/gVertexBuffer.h"
#include "Graphs/layer.h" #include "Graphs/layer.h"
#include "SleepLib/event.h" #include "SleepLib/event.h"
#include "SleepLib/day.h" #include "SleepLib/day.h"
/*! \class AHIChart
\brief Another graph calculating the AHI/hour, this one looks at all the sessions for a day. Currently Unused.
*/
class AHIChart: public Layer
{
public:
//! \brief Constructs an AHIChart object, with QColor col for the line plots.
AHIChart(QColor col = QColor("black"));
~AHIChart();
//! \brief Draws the precalculated data to the Vertex buffers
virtual void paint(gGraph &w, int left, int top, int width, int height);
//! \brief AHI/hr Calculations are done for this day here.
//! This also uses the sliding window method
virtual void SetDay(Day *d);
//! \brief Returns the minimum AHI/hr value caculated
virtual EventDataType Miny() { return m_miny; }
//! \brief Returns the maximum AHI/hr value caculated
virtual EventDataType Maxy() { return m_maxy; }
//! \brief Returns true if no data was available
virtual bool isEmpty() { return m_data.size() == 0; }
protected:
//! \brief Contains the plot data (Y-axis) generated for this day
QVector<EventDataType> m_data;
//! \brief Contains the time codes (X-axis) generated for this day
QVector<quint64> m_time;
EventDataType m_miny;
EventDataType m_maxy;
QColor m_color;
gVertexBuffer *lines;
};
/*! \class gLineChart /*! \class gLineChart
\brief Draws a 2D linechart from all Session data in a day. EVL_Waveforms typed EventLists are accelerated. \brief Draws a 2D linechart from all Session data in a day. EVL_Waveforms typed EventLists are accelerated.
*/ */
@ -75,7 +35,7 @@ class gLineChart: public Layer
virtual ~gLineChart(); virtual ~gLineChart();
//! \brief The drawing code that fills the vertex buffers //! \brief The drawing code that fills the vertex buffers
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
//! \brief Set Use Square plots for non EVL_Waveform data //! \brief Set Use Square plots for non EVL_Waveform data
void SetSquarePlot(bool b) { m_square_plot = b; } void SetSquarePlot(bool b) { m_square_plot = b; }
@ -123,10 +83,6 @@ class gLineChart: public Layer
bool m_disable_accel; bool m_disable_accel;
QColor m_line_color; QColor m_line_color;
gVertexBuffer *lines;
//GLShortBuffer * lines;
//GLShortBuffer * outlines;
//! \brief Used by accelerated waveform plots. Must be >= Screen Resolution (or at least graph width) //! \brief Used by accelerated waveform plots. Must be >= Screen Resolution (or at least graph width)
static const int max_drawlist_size = 10000; static const int max_drawlist_size = 10000;
@ -139,6 +95,8 @@ class gLineChart: public Layer
QVector<QColor> m_colors; QVector<QColor> m_colors;
QVector<bool> m_square; QVector<bool> m_square;
QHash<ChannelID, bool> m_enabled; QHash<ChannelID, bool> m_enabled;
QVector<QLine> lines;
}; };
#endif // GLINECHART_H #endif // GLINECHART_H

View File

@ -16,30 +16,17 @@
gLineOverlayBar::gLineOverlayBar(ChannelID code, QColor color, QString label, FlagType flt) gLineOverlayBar::gLineOverlayBar(ChannelID code, QColor color, QString label, FlagType flt)
: Layer(code), m_flag_color(color), m_label(label), m_flt(flt) : Layer(code), m_flag_color(color), m_label(label), m_flt(flt)
{ {
addVertexBuffer(points = new gVertexBuffer(2048, GL_POINTS));
points->setSize(4);
points->setColor(m_flag_color);
addVertexBuffer(quads = new gVertexBuffer(2048, GL_QUADS));
//addGLBuf(lines=new GLBuffer(color,1024,GL_LINES));
points->setAntiAlias(true);
quads->setAntiAlias(true);
quads->setColor(m_flag_color);
//lines->setAntiAlias(true);
} }
gLineOverlayBar::~gLineOverlayBar() gLineOverlayBar::~gLineOverlayBar()
{ {
//delete lines;
//delete quads;
//delete points;
} }
void gLineOverlayBar::paint(gGraph &w, int left, int topp, int width, int height) void gLineOverlayBar::paint(QPainter &painter, gGraph &w, int left, int topp, int width, int height)
{ {
if (!m_visible) { return; } if (!m_visible) { return; }
if (!m_day) { return; } if (!m_day) { return; }
gVertexBuffer *lines = w.lines();
int start_py = topp; int start_py = topp;
double xx = w.max_x - w.min_x; double xx = w.max_x - w.min_x;
@ -56,19 +43,17 @@ void gLineOverlayBar::paint(gGraph &w, int left, int topp, int width, int height
double X; double X;
double Y; double Y;
bool verts_exceeded = false;
m_count = 0; m_count = 0;
m_sum = 0; m_sum = 0;
m_flag_color = schema::channel[m_code].defaultColor(); m_flag_color = schema::channel[m_code].defaultColor();
lines->setColor(m_flag_color);
points->setColor(m_flag_color);
if (m_flt == FT_Span) { if (m_flt == FT_Span) {
m_flag_color.setAlpha(128); m_flag_color.setAlpha(128);
} }
painter.setPen(m_flag_color);
EventStoreType raw; EventStoreType raw;
quint32 *tptr; quint32 *tptr;
@ -149,16 +134,7 @@ void gLineOverlayBar::paint(gGraph &w, int left, int topp, int width, int height
x1 = width + left; x1 = width + left;
} }
quads->add(x2, start_py, painter.fillRect(x2, start_py, x1-x2, height, QBrush(m_flag_color));
x1, start_py,
x1, start_py + height,
x2, start_py + height,
m_flag_color.rgba());
if (quads->full()) {
verts_exceeded = true;
break;
}
} }
} else if (m_flt == FT_Dot) { } else if (m_flt == FT_Dot) {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -178,22 +154,15 @@ void gLineOverlayBar::paint(gGraph &w, int left, int topp, int width, int height
if ((odt == ODT_Bars) || (xx < 3600000)) { if ((odt == ODT_Bars) || (xx < 3600000)) {
// show the fat dots in the middle // show the fat dots in the middle
points->add(x1, double(height) / double(yy)*double(-20 - w.min_y) + topp); painter.setPen(QPen(m_flag_color,4));
painter.drawPoint(x1, double(height) / double(yy)*double(-20 - w.min_y) + topp);
painter.setPen(QPen(m_flag_color,1));
if (points->full()) {
verts_exceeded = true;
break;
}
} else { } else {
// thin lines down the bottom // thin lines down the bottom
lines->add(x1, start_py + 1, x1, start_py + 1 + 12); painter.drawLine(x1, start_py + 1, x1, start_py + 1 + 12);
if (lines->full()) {
verts_exceeded = true;
break;
}
} }
} }
} else if (m_flt == FT_Bar) { } else if (m_flt == FT_Bar) {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -215,20 +184,13 @@ void gLineOverlayBar::paint(gGraph &w, int left, int topp, int width, int height
if ((odt == ODT_Bars) || (xx < 3600000)) { if ((odt == ODT_Bars) || (xx < 3600000)) {
z = top; z = top;
points->add(x1, top); painter.setPen(QPen(m_flag_color,4));
lines->add(x1, top, x1, bottom); painter.drawPoint(x1, top);
painter.setPen(QPen(m_flag_color,1));
painter.drawLine(x1, top, x1, bottom);
if (points->full()) {
verts_exceeded = true;
break;
}
} else { } else {
lines->add(x1, z, x1, z - 12); painter.drawLine(x1, z, x1, z - 12);
}
if (lines->full()) {
verts_exceeded = true;
break;
} }
if (xx < (1800000)) { if (xx < (1800000)) {
@ -238,18 +200,8 @@ void gLineOverlayBar::paint(gGraph &w, int left, int topp, int width, int height
} }
} }
if (verts_exceeded) {
break;
}
} }
if (verts_exceeded) {
break;
}
}
if (verts_exceeded) {
qWarning() << "exceeded maxverts in gLineOverlay::Plot()";
} }
} }
@ -262,8 +214,10 @@ gLineOverlaySummary::~gLineOverlaySummary()
{ {
} }
void gLineOverlaySummary::paint(gGraph &w, int left, int top, int width, int height) void gLineOverlaySummary::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
Q_UNUSED(painter)
if (!m_visible) { return; } if (!m_visible) { return; }
if (!m_day) { return; } if (!m_day) { return; }
@ -337,7 +291,7 @@ void gLineOverlaySummary::paint(gGraph &w, int left, int top, int width, int hei
if (sph > 100) { sph = 100; } if (sph > 100) { sph = 100; }
} }
a += " " + QObject::tr("(\%%1 in events)").arg(sph, 0, 'f', a += " " + QObject::tr("(% %1 in events)").arg(sph, 0, 'f',
2); // eg: %num of time in a span, like Periodic Breathing 2); // eg: %num of time in a span, like Periodic Breathing
} }

View File

@ -26,7 +26,7 @@ class gLineOverlayBar: public Layer
virtual ~gLineOverlayBar(); virtual ~gLineOverlayBar();
//! \brief The drawing code that fills the OpenGL vertex GLBuffers //! \brief The drawing code that fills the OpenGL vertex GLBuffers
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
virtual EventDataType Miny() { return 0; } virtual EventDataType Miny() { return 0; }
virtual EventDataType Maxy() { return 0; } virtual EventDataType Maxy() { return 0; }
@ -44,9 +44,6 @@ class gLineOverlayBar: public Layer
FlagType m_flt; FlagType m_flt;
int m_count; int m_count;
double m_sum; double m_sum;
gVertexBuffer *quads;
gVertexBuffer *points;
}; };
/*! \class gLineOverlaySummary /*! \class gLineOverlaySummary
@ -58,7 +55,7 @@ class gLineOverlaySummary: public Layer
gLineOverlaySummary(QString text, int x, int y); gLineOverlaySummary(QString text, int x, int y);
virtual ~gLineOverlaySummary(); virtual ~gLineOverlaySummary();
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
virtual EventDataType Miny() { return 0; } virtual EventDataType Miny() { return 0; }
virtual EventDataType Maxy() { return 0; } virtual EventDataType Maxy() { return 0; }

View File

@ -17,12 +17,6 @@ gSegmentChart::gSegmentChart(GraphSegmentType type, QColor gradient_color, QColo
m_outline_color(outline_color) m_outline_color(outline_color)
{ {
m_empty = true; m_empty = true;
addGLBuf(poly = new GLFloatBuffer(4000, GL_POLYGON));
addGLBuf(lines = new GLFloatBuffer(4000, GL_LINE_LOOP));
lines->setSize(1);
poly->forceAntiAlias(false);
lines->forceAntiAlias(true);
lines->setAntiAlias(true);
} }
gSegmentChart::~gSegmentChart() gSegmentChart::~gSegmentChart()
{ {
@ -69,7 +63,7 @@ bool gSegmentChart::isEmpty()
return m_empty; return m_empty;
} }
void gSegmentChart::paint(gGraph &w, int left, int top, int width, int height) void gSegmentChart::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) { return; } if (!m_visible) { return; }
@ -83,12 +77,6 @@ void gSegmentChart::paint(gGraph &w, int left, int top, int width, int height)
diameter -= 8; diameter -= 8;
float radius = diameter / 2.0; float radius = diameter / 2.0;
float j = 0.0;
float sum = 0.0;
float step = 1.0 / 720.0;
float px, py;
float q;
float xmult = float(width) / float(m_total); float xmult = float(width) / float(m_total);
float ymult = float(height) / float(m_total); float ymult = float(height) / float(m_total);
@ -113,9 +101,9 @@ void gSegmentChart::paint(gGraph &w, int left, int top, int width, int height)
bool line_first = true; bool line_first = true;
int line_last; int line_last;
gVertexBuffer *quads = w.quads(); float sum = -90.0;
gVertexBuffer *lines2 = w.lines();
painter.setFont(*defaultfont);
for (unsigned m = 0; m < size; m++) { for (unsigned m = 0; m < size; m++) {
data = m_values[m]; data = m_values[m];
@ -126,62 +114,64 @@ void gSegmentChart::paint(gGraph &w, int left, int top, int width, int height)
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
if (m_graph_type == GST_Pie) { if (m_graph_type == GST_Pie) {
QColor &col = schema::channel[m_codes[m % m_colors.size()]].defaultColor(); QColor &col = schema::channel[m_codes[m % m_colors.size()]].defaultColor();
j = float(data) / float(m_total); // ratio of this pie slice
// Draw Filling // length of this segment in degrees
poly->add(start_px + xoffset, start_py + height - yoffset, m_gradient_color); float len = 360.0 / float(m_total) * float(data);
for (q = sum; q < sum + j; q += step) { // Setup the shiny radial gradient
px = start_px + xoffset + sin(q * 2 * M_PI) * radius;
py = start_py + height - (yoffset + cos(q * 2 * M_PI) * radius);
poly->add(px, py, col);
}
q = sum + j; painter.setRenderHint(QPainter::Antialiasing);
px = start_px + xoffset + sin(q * 2 * M_PI) * radius; QRect pierect(start_px+1, start_py+1, width-2, height-2);
py = start_py + height - (yoffset + cos(q * 2 * M_PI) * radius);
poly->add(px, py, col);
if (m_total != data) { painter.setPen(QPen(col, 0));
// Draw the center point first QRadialGradient gradient(pierect.center(), pierect.width()/2, pierect.center());
lines->add(start_px + xoffset, start_py + height - yoffset, m_outline_color); gradient.setColorAt(0, Qt::white);
} gradient.setColorAt(1, col);
for (q = sum; q < sum + j; q += step) { // draw filled pie
px = start_px + xoffset + sin(q * 2 * M_PI) * radius; painter.setBrush(gradient);
py = start_py + height - (yoffset + cos(q * 2 * M_PI) * radius); painter.setBackgroundMode(Qt::OpaqueMode);
lines->add(px, py, m_outline_color); painter.drawPie(pierect, -sum * 16.0, -len * 16.0);
}
double tpx = start_px + xoffset + sin((sum + (j / 2.0)) * 2 * M_PI) * (radius / 1.7); // draw outline
double tpy = start_py + height - (yoffset + cos((sum + (j / 2.0)) * 2 * M_PI) * (radius / 1.7)); painter.setBackgroundMode(Qt::TransparentMode);
q = sum + j; painter.setBrush(QBrush(col,Qt::NoBrush));
px = start_px + xoffset + sin(q * 2 * M_PI) * radius; painter.setPen(QPen(QColor(Qt::black),1.5));
py = start_py + height - (yoffset + cos(q * 2 * M_PI) * radius); painter.drawPie(pierect, -sum * 16.0, -len * 16.0);
lines->add(px, py, m_outline_color);
if (j > .09) {
QString a = m_names[m]; //QString::number(floor(100.0/m_total*data),'f',0)+"%"; // Draw text labels if they fit
if (len > 20) {
float angle = (sum+90.0) + len / 2.0;
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)+"%";
int x, y; int x, y;
GetTextExtent(a, x, y); GetTextExtent(txt, x, y);
w.renderText(a, tpx - (x / 2.0), (tpy + y / 2.0), 0, Qt::black, defaultfont, // antialiasing looks like crap here..
false); // antialiasing looks like crap here.. painter.setPen(QColor(Qt::black));
painter.drawText(tpx - (x / 2.0), tpy+3, txt);
} }
sum += len;
sum = q; } else if (m_graph_type == GST_CandleStick) {
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
// CandleStick Chart // CandleStick Chart
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
} else if (m_graph_type == GST_CandleStick) {
QColor &col = m_colors[m % m_colors.size()]; QColor &col = m_colors[m % m_colors.size()];
float bw = xmult * float(data); float bw = xmult * float(data);
quads->add(xp, start_py, xp + bw, start_py, m_gradient_color.rgba()); QLinearGradient linearGrad(QPointF(0, 0), QPointF(bw, 0));
quads->add(xp + bw, start_py + height, xp, start_py + height, col.rgba()); linearGrad.setColorAt(0, col);
linearGrad.setColorAt(1, Qt::white);
painter.fillRect(xp, start_py, bw, height, QBrush(linearGrad));
lines2->add(xp, start_py, xp + bw, start_py, m_outline_color.rgba()); painter.setPen(m_outline_color);
lines2->add(xp + bw, start_py + height, xp, start_py + height, m_outline_color.rgba()); painter.drawLine(xp, start_py, xp + bw, start_py);
painter.drawLine(xp + bw, start_py + height, xp, start_py + height);
if (!m_names[m].isEmpty()) { if (!m_names[m].isEmpty()) {
int px, py; int px, py;
@ -198,12 +188,13 @@ void gSegmentChart::paint(gGraph &w, int left, int top, int width, int height)
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
} else if (m_graph_type == GST_Line) { } else if (m_graph_type == GST_Line) {
QColor col = Qt::black; //m_colors[m % m_colors.size()]; QColor col = Qt::black; //m_colors[m % m_colors.size()];
painter.setPen(col);
float h = (top + height) - (float(data) * ymult); float h = (top + height) - (float(data) * ymult);
if (line_first) { if (line_first) {
line_first = false; line_first = false;
} else { } else {
lines->add(xp, line_last, xp + line_step, h, col); painter.drawLine(xp, line_last, xp + line_step, h);
xp += line_step; xp += line_step;
} }

View File

@ -27,7 +27,7 @@ class gSegmentChart : public Layer
virtual ~gSegmentChart(); virtual ~gSegmentChart();
//! \brief The drawing code that fills the Vertex buffers //! \brief The drawing code that fills the Vertex buffers
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
//! \brief Pre-fills a buffer with the data needed to draw //! \brief Pre-fills a buffer with the data needed to draw
virtual void SetDay(Day *d); virtual void SetDay(Day *d);
@ -57,9 +57,6 @@ class gSegmentChart : public Layer
QColor m_gradient_color; QColor m_gradient_color;
QColor m_outline_color; QColor m_outline_color;
bool m_empty; bool m_empty;
// gah.. can't convert these
GLFloatBuffer *poly, *lines;
}; };
/*! \class gTAPGraph /*! \class gTAPGraph

View File

@ -17,8 +17,10 @@ gStatsLine::gStatsLine(ChannelID code, QString label, QColor textcolor)
: Layer(code), m_label(label), m_textcolor(textcolor) : Layer(code), m_label(label), m_textcolor(textcolor)
{ {
} }
void gStatsLine::paint(gGraph &w, int left, int top, int width, int height) void gStatsLine::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
Q_UNUSED(painter)
if (!m_visible) { return; } if (!m_visible) { return; }
//if (m_empty) return; //if (m_empty) return;

View File

@ -22,7 +22,7 @@ class gStatsLine : public Layer
{ {
public: public:
gStatsLine(ChannelID code, QString label = "", QColor textcolor = Qt::black); gStatsLine(ChannelID code, QString label = "", QColor textcolor = Qt::black);
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
void SetDay(Day *d); void SetDay(Day *d);
protected: protected:

View File

@ -19,18 +19,6 @@ extern QLabel *qstatus2;
SummaryChart::SummaryChart(QString label, GraphType type) SummaryChart::SummaryChart(QString label, GraphType type)
: Layer(NoChannel), m_label(label), m_graphtype(type) : Layer(NoChannel), m_label(label), m_graphtype(type)
{ {
//QColor color=Qt::black;
addVertexBuffer(quads = new gVertexBuffer(20000, GL_QUADS));
addVertexBuffer(lines = new gVertexBuffer(20000, GL_LINES));
addVertexBuffer(outlines = new gVertexBuffer(20000, GL_LINES));
addVertexBuffer(points = new gVertexBuffer(20000, GL_POINTS));
quads->forceAntiAlias(true);
outlines->setSize(1);
//lines->setBlendFunc(GL_SRC_COLOR, GL_ZERO);
//lines->forceAntiAlias(false);
m_empty = true; m_empty = true;
hl_day = -1; hl_day = -1;
m_machinetype = MT_CPAP; m_machinetype = MT_CPAP;
@ -55,8 +43,8 @@ void SummaryChart::SetDay(Day *nullday)
m_days.clear(); m_days.clear();
m_hours.clear(); m_hours.clear();
m_goodcodes.clear(); m_goodcodes.clear();
m_miny = 999999999; m_miny = 999999999.0F;
m_maxy = -999999999; m_maxy = -999999999.0F;
m_physmaxy = 0; m_physmaxy = 0;
m_physminy = 0; m_physminy = 0;
m_minx = 0; m_minx = 0;
@ -390,12 +378,10 @@ QColor brighten(QColor color)
} }
void SummaryChart::paint(gGraph &w, int left, int top, int width, int height) void SummaryChart::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) { return; } if (!m_visible) { return; }
points->setSize(10);
GraphType graphtype = m_graphtype; GraphType graphtype = m_graphtype;
if (graphtype == GT_LINE || graphtype == GT_POINTS) { if (graphtype == GT_LINE || graphtype == GT_POINTS) {
@ -403,21 +389,13 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
graphtype = pts ? GT_POINTS : GT_LINE; graphtype = pts ? GT_POINTS : GT_LINE;
} }
if (graphtype == GT_POINTS) {
lines->setSize(4);
} else {
lines->setSize(1.5);
}
rtop = top; rtop = top;
gVertexBuffer *outlines2 = w.lines();
// outlines2->setColor(Qt::black); painter.setPen(QColor(Qt::black));
outlines2->add(left, top, left, top + height, left, top + height, left + width, top + height, painter.drawLine(left, top, left, top+height);
QColor("black").rgba()); painter.drawLine(left, top+height, left+width, top+height);
outlines2->add(left + width, top + height, left + width, top, left + width, top, left, top, painter.drawLine(left+width, top+height, left+width, top);
QColor("black").rgba()); painter.drawLine( left+width, top, left, top);
//if (outlines->full()) qDebug() << "WTF??? Outlines full in SummaryChart::paint()";
qint64 minx = w.min_x, maxx = w.max_x; qint64 minx = w.min_x, maxx = w.max_x;
qint64 xx = maxx - minx; qint64 xx = maxx - minx;
@ -441,8 +419,6 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
barw = (float(width) / float(days)); barw = (float(width) / float(days));
float dpr = w.graphView()->devicePixelRatio();
graph = &w; graph = &w;
float px = left; float px = left;
l_left = w.marginLeft() + gYAxis::Margin; l_left = w.marginLeft() + gYAxis::Margin;
@ -484,7 +460,6 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
QVector<bool> goodcodes; QVector<bool> goodcodes;
goodcodes.resize(m_goodcodes.size()); goodcodes.resize(m_goodcodes.size());
points->setSize(5.0 * dpr);
lastdaygood = true; lastdaygood = true;
for (int i = 0; i < numcodes; i++) { for (int i = 0; i < numcodes; i++) {
@ -534,6 +509,10 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
short px2, py2; short px2, py2;
const qint64 ms_per_day = 86400000L; const qint64 ms_per_day = 86400000L;
painter.setClipRect(left, top, width, height);
painter.setClipping(true);
for (qint64 Q = minx; Q <= maxx + ms_per_day; Q += ms_per_day) { for (qint64 Q = minx; Q <= maxx + ms_per_day; Q += ms_per_day) {
zd = Q / ms_per_day; zd = Q / ms_per_day;
d = m_values.find(zd); d = m_values.find(zd);
@ -555,7 +534,7 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
//x1-=(barw/2.0); //x1-=(barw/2.0);
int x2 = px + barw; int x2 = px + barw;
if (x1 < left) { x1 = left; } //if (x1 < left) { x1 = left; }
if (x2 > left + width) { x2 = left + width; } if (x2 > left + width) { x2 = left + width; }
@ -568,10 +547,12 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
col.setAlpha(64); col.setAlpha(64);
if (graphtype != GT_POINTS) { if (graphtype != GT_POINTS) {
quads->add(x1 - 1, top, x1 - 1, top + height, x2, top + height, x2, top, col.rgba()); painter.fillRect(x1-1, top, barw, height, QBrush(col));
// quads->add(x1 - 1, top, x1 - 1, top + height, x2, top + height, x2, top, col.rgba());
} else { } else {
quads->add((x1 + barw / 2) - 5, top, (x1 + barw / 2) - 5, top + height, (x2 - barw / 2) + 5, painter.fillRect((x1+barw/2)-5, top, barw, height, QBrush(col));
top + height, (x2 - barw / 2) + 5, top, col.rgba()); // quads->add((x1 + barw / 2) - 5, top, (x1 + barw / 2) - 5, top + height, (x2 - barw / 2) + 5,
// top + height, (x2 - barw / 2) + 5, top, col.rgba());
} }
} }
@ -585,8 +566,8 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
col = QColor("gold"); col = QColor("gold");
} }
GLuint col1 = col.rgba(); QColor col1 = col;
GLuint col2 = brighten(col).rgba(); QColor col2 = Qt::white;
//outlines->setColor(Qt::black); //outlines->setColor(Qt::black);
int np = d.value().size(); int np = d.value().size();
@ -606,11 +587,18 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
//tmp-=miny; //tmp-=miny;
h = tmp * ymult; h = tmp * ymult;
quads->add(x1, py, x1, py - h, x2, py - h, x2, py, col1, col2); QLinearGradient gradient(x1, py-h, x1+barw, py-h);
gradient.setColorAt(0,col1);
gradient.setColorAt(1,col2);
painter.fillRect(x1, py-h, barw, h, QBrush(gradient));
// quads->add(x1, py, x1, py - h, x2, py - h, x2, py, col1, col2);
if (h > 0 && barw > 2) { if ((h > 0) && (barw > 2)) {
outlines->add(x1, py, x1, py - h, x1, py - h, x2, py - h, QColor("black").rgba()); painter.setPen(QColor(Qt::black));
outlines->add(x1, py, x2, py, x2, py, x2, py - h, QColor("black").rgba()); painter.drawLine(x1, py, x1, py - h);
painter.drawLine(x1, py - h, x2, py - h);
painter.drawLine(x1, py, x2, py);
painter.drawLine(x2, py, x2, py - h);
} }
totalvalues[0] += hours * tmp; totalvalues[0] += hours * tmp;
@ -694,17 +682,23 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
h = tmp * ymult; // height in pixels h = tmp * ymult; // height in pixels
if (graphtype == GT_BAR) { if (graphtype == GT_BAR) {
GLuint col1 = col.rgba(); QColor col1 = col;
GLuint col2 = brighten(col).rgba(); QColor col2 = Qt::white;
quads->add(x1, py, x1, py - h, col1); QLinearGradient gradient(x1, py-h, x1+barw, py-h);
quads->add(x2, py - h, x2, py, col2); gradient.setColorAt(0,col1);
gradient.setColorAt(1,col2);
painter.fillRect(x1, py-h, barw, h, QBrush(gradient));
// quads->add(x1, py, x1, py - h, col1);
// quads->add(x2, py - h, x2, py, col2);
if (h > 0 && barw > 2) { if (h > 0 && barw > 2) {
outlines->add(x1, py, x1, py - h, x1, py - h, x2, py - h, QColor("black").rgba()); painter.setPen(QColor(Qt::black));
outlines->add(x1, py, x2, py, x2, py, x2, py - h, QColor("black").rgba()); painter.drawLine(x1, py, x1, py - h);
painter.drawLine(x1, py - h, x2, py - h);
if (outlines->full()) { qDebug() << "WTF??? Outlines full in SummaryChart::paint()"; } painter.drawLine(x1, py, x2, py);
painter.drawLine(x2, py, x2, py - h);
} // if (bar } // if (bar
py -= h; py -= h;
@ -721,19 +715,22 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
if (lastdaygood) { if (lastdaygood) {
if (lastY[j] != py2) { // vertical line if (lastY[j] != py2) { // vertical line
lines->add(lastX[j], lastY[j], px, py2, col2); painter.setPen(col2);
painter.drawLine(lastX[j], lastY[j], px, py2);
} }
lines->add(px - 1, py2, px2 + 1, py2, col1); painter.setPen(col1);
painter.drawLine(px - 1, py2, px2 + 1, py2);
} else { } else {
lines->add(x1 - 1, py2, x2 + 1, py2, col1); painter.setPen(col1);
painter.drawLine(x1 - 1, py2, x2 + 1, py2);
} }
lastX[j] = px2; lastX[j] = px2;
lastY[j] = py2; lastY[j] = py2;
} else if (graphtype == GT_POINTS) { } else if (graphtype == GT_POINTS) {
GLuint col1 = col.rgba(); QColor col1 = col;
GLuint col2 = m_colors[j].rgba(); QColor col2 = m_colors[j];
px2 = px + barw; px2 = px + barw;
py2 = (top + height - 2) - h; py2 = (top + height - 2) - h;
@ -743,13 +740,16 @@ void SummaryChart::paint(gGraph &w, int left, int top, int width, int height)
} }
if (zd == hl_day) { if (zd == hl_day) {
points->add(px2 - barw / 2, py2, col2); painter.setPen(QPen(brighten(col2),10));
painter.drawPoint(px2 - barw / 2, py2);
} }
if (lastdaygood) { if (lastdaygood) {
lines->add(lastX[j] - barw / 2, lastY[j], px2 - barw / 2, py2, col2); painter.setPen(QPen(col2,p_profile->appearance->lineThickness()));
painter.drawLine(lastX[j] - barw / 2, lastY[j], px2 - barw / 2, py2);
} else { } else {
lines->add(px + barw / 2 - 1, py2, px + barw / 2 + 1, py2, col1); painter.setPen(QPen(col1,p_profile->appearance->lineThickness()));
painter.drawLine(px + barw / 2 - 1, py2, px + barw / 2 + 1, py2);
} }
lastX[j] = px2; lastX[j] = px2;
@ -779,16 +779,17 @@ jumpnext:
daynum++; daynum++;
//lastQ=Q; //lastQ=Q;
} }
painter.setClipping(false);
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) //#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
quads->scissor(left * dpr, w.flipY(top + height + 2)*dpr, (width)*dpr, (height + 1)*dpr); // quads->scissor(left * dpr, w.flipY(top + height + 2)*dpr, (width)*dpr, (height + 1)*dpr);
lines->scissor(left * dpr, w.flipY(top + height + 2)*dpr, (width + 1)*dpr, (height + 1)*dpr); // lines->scissor(left * dpr, w.flipY(top + height + 2)*dpr, (width + 1)*dpr, (height + 1)*dpr);
outlines->scissor(left * dpr, w.flipY(top + height + 2)*dpr, (width)*dpr, (height + 1)*dpr); // outlines->scissor(left * dpr, w.flipY(top + height + 2)*dpr, (width)*dpr, (height + 1)*dpr);
#else //#else
lines->scissor(left, w.flipY(top + height + 2), width + 1, height + 2); // lines->scissor(left, w.flipY(top + height + 2), width + 1, height + 2);
outlines->scissor(left, w.flipY(top + height + 2), width, height + 2); // outlines->scissor(left, w.flipY(top + height + 2), width, height + 2);
quads->scissor(left, w.flipY(top + height + 2), width, height + 2); // quads->scissor(left, w.flipY(top + height + 2), width, height + 2);
#endif //#endif
// Draw Ledgend // Draw Ledgend
px = left + width - 3; px = left + width - 3;
py = top - 5; py = top - 5;
@ -910,9 +911,7 @@ jumpnext:
w.renderText(a, legendx, top - 4); w.renderText(a, legendx, top - 4);
// legendx-=bw/2; // legendx-=bw/2;
int tp = top - 5 - bh / 2; painter.fillRect(legendx - bw, top-w.marginTop()-1, bh, w.marginTop(), QBrush(m_colors[j]));
w.quads()->add(legendx - bw, tp + bh / 2, legendx, tp + bh / 2, legendx, tp - bh / 2, legendx - bw,
tp - bh / 2, m_colors[j].rgba());
legendx -= bw * 2; legendx -= bw * 2;

View File

@ -34,7 +34,7 @@ class SummaryChart: public Layer
virtual ~SummaryChart(); virtual ~SummaryChart();
//! \brief Drawing code that fills the Vertex buffers //! \brief Drawing code that fills the Vertex buffers
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
//! \brief Precalculation code prior to drawing. Day object is not needed here, it's just here for Layer compatability. //! \brief Precalculation code prior to drawing. Day object is not needed here, it's just here for Layer compatability.
virtual void SetDay(Day *day = nullptr); virtual void SetDay(Day *day = nullptr);
@ -79,10 +79,6 @@ class SummaryChart: public Layer
QHash<int, EventDataType> m_hours; QHash<int, EventDataType> m_hours;
QHash<int, Day *> m_days; QHash<int, Day *> m_days;
gVertexBuffer *quads;
gVertexBuffer *lines;
gVertexBuffer *outlines;
gVertexBuffer *points;
bool m_empty; bool m_empty;
int m_fday; int m_fday;
QString m_label; QString m_label;

View File

@ -1,304 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
*
* Copyright (c) 2011-2014 Mark Watkins <jedimark@users.sourceforge.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the Linux
* distribution for more details. */
#include "Graphs/gVertexBuffer.h"
#include "SleepLib/profiles.h"
extern int lines_drawn_this_frame;
extern int quads_drawn_this_frame;
inline quint32 swaporder(quint32 color)
{
return ((color & 0xFF00FF00) |
((color & 0xFF0000) >> 16) |
((color & 0xFF) << 16));
}
void gVertexBuffer::setColor(QColor col)
{
m_color = swaporder(col.rgba());
}
void gVertexBuffer::draw()
{
bool antialias = m_forceantialias || (PROFILE.appearance->antiAliasing() && m_antialias);
if (m_stippled) { antialias = false; }
float size = m_size;
if (antialias) {
glEnable(GL_BLEND);
glBlendFunc(m_blendfunc1, m_blendfunc2);
if (m_type == GL_LINES || m_type == GL_LINE_LOOP) {
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
size += 0.5;
} else if (m_type == GL_POLYGON) {
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
}
}
if (m_type == GL_LINES || m_type == GL_LINE_LOOP) {
if (m_stippled) {
glLineStipple(1, m_stipple);
//size=1;
glEnable(GL_LINE_STIPPLE);
} else {
//glLineStipple(1, 0xFFFF);
}
glLineWidth(size);
lines_drawn_this_frame += m_cnt / 2;
} else if (m_type == GL_POINTS) {
glPointSize(size);
} else if (m_type == GL_POLYGON) {
glPolygonMode(GL_BACK, GL_FILL);
lines_drawn_this_frame += m_cnt / 2;
} else if (m_type == GL_QUADS) {
quads_drawn_this_frame += m_cnt / 4;
}
if (m_scissor) {
glScissor(s_x, s_y, s_width, s_height);
glEnable(GL_SCISSOR_TEST);
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_SHORT, 8, (GLvoid *)buffer);
glColorPointer(4, GL_UNSIGNED_BYTE, 8, ((char *)buffer) + 4);
glDrawArrays(m_type, 0, m_cnt);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
m_cnt = 0;
if (m_scissor) {
glDisable(GL_SCISSOR_TEST);
m_scissor = false;
}
if (m_type == GL_POLYGON) {
glPolygonMode(GL_BACK, GL_FILL);
}
if (m_type == GL_LINES || m_type == GL_LINE_LOOP) {
if (m_stippled) {
glDisable(GL_LINE_STIPPLE);
glLineStipple(1, 0xFFFF);
}
}
if (antialias) {
if (m_type == GL_LINES || m_type == GL_LINE_LOOP) {
glDisable(GL_LINE_SMOOTH);
} else if (m_type == GL_POLYGON) {
glDisable(GL_POLYGON_SMOOTH);
}
glDisable(GL_BLEND);
}
}
void gVertexBuffer::add(GLshort x1, GLshort y1, RGBA color)
{
if (m_cnt < m_max) {
gVertex &v = buffer[m_cnt];
v.color = swaporder(color);
v.x = x1;
v.y = y1;
m_cnt++;
}
}
void gVertexBuffer::add(GLshort x1, GLshort y1, GLshort x2, GLshort y2, RGBA color)
{
if (m_cnt < (m_max - 1)) {
gVertex *v = &buffer[m_cnt];
v->x = x1;
v->y = y1;
v->color = swaporder(color);
v++;
v->x = x2;
v->y = y2;
v->color = swaporder(color);
m_cnt += 2;
}
}
void gVertexBuffer::add(GLshort x1, GLshort y1, GLshort x2, GLshort y2, GLshort x3, GLshort y3,
GLshort x4, GLshort y4, RGBA color)
{
if (m_cnt < (m_max - 3)) {
gVertex *v = &buffer[m_cnt];
v->color = swaporder(color);
v->x = x1;
v->y = y1;
v++;
v->color = swaporder(color);
v->x = x2;
v->y = y2;
v++;
v->color = swaporder(color);
v->x = x3;
v->y = y3;
v++;
v->color = swaporder(color);
v->x = x4;
v->y = y4;
m_cnt += 4;
}
}
void gVertexBuffer::add(GLshort x1, GLshort y1, GLshort x2, GLshort y2, GLshort x3, GLshort y3,
GLshort x4, GLshort y4, RGBA color1, RGBA color2)
{
if (m_cnt < (m_max - 3)) {
gVertex *v = &buffer[m_cnt];
v->color = swaporder(color1);
v->x = x1;
v->y = y1;
v++;
v->color = swaporder(color1);
v->x = x2;
v->y = y2;
v++;
v->color = swaporder(color2);
v->x = x3;
v->y = y3;
v++;
v->color = swaporder(color2);
v->x = x4;
v->y = y4;
m_cnt += 4;
}
}
void gVertexBuffer::unsafe_add(GLshort x1, GLshort y1)
{
gVertex &v = buffer[m_cnt++];
v.color = m_color;
v.x = x1;
v.y = y1;
}
void gVertexBuffer::add(GLshort x1, GLshort y1)
{
if (m_cnt < m_max) {
gVertex &v = buffer[m_cnt++];
v.color = m_color;
v.x = x1;
v.y = y1;
}
}
void gVertexBuffer::unsafe_add(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
{
gVertex *v = &buffer[m_cnt];
v->x = x1;
v->y = y1;
v->color = m_color;
v++;
v->x = x2;
v->y = y2;
v->color = m_color;
m_cnt += 2;
}
void gVertexBuffer::add(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
{
if (m_cnt < (m_max - 1)) {
gVertex *v = &buffer[m_cnt];
v->x = x1;
v->y = y1;
v->color = m_color;
v++;
v->x = x2;
v->y = y2;
v->color = m_color;
m_cnt += 2;
}
}
void gVertexBuffer::add(GLshort x1, GLshort y1, GLshort x2, GLshort y2, GLshort x3, GLshort y3,
GLshort x4, GLshort y4)
{
if (m_cnt < (m_max - 3)) {
gVertex *v = &buffer[m_cnt];
v->color = m_color;
v->x = x1;
v->y = y1;
v++;
v->color = m_color;
v->x = x2;
v->y = y2;
v++;
v->color = m_color;
v->x = x3;
v->y = y3;
v++;
v->color = m_color;
v->x = x4;
v->y = y4;
m_cnt += 4;
}
}
void gVertexBuffer::unsafe_add(GLshort x1, GLshort y1, GLshort x2, GLshort y2, GLshort x3,
GLshort y3, GLshort x4, GLshort y4)
{
gVertex *v = &buffer[m_cnt];
v->color = m_color;
v->x = x1;
v->y = y1;
v++;
v->color = m_color;
v->x = x2;
v->y = y2;
v++;
v->color = m_color;
v->x = x3;
v->y = y3;
v++;
v->color = m_color;
v->x = x4;
v->y = y4;
m_cnt += 4;
}

View File

@ -1,128 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
*
* Copyright (c) 2011-2014 Mark Watkins <jedimark@users.sourceforge.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the Linux
* distribution for more details. */
#ifndef graphs_gvertexbuffer_h
#define graphs_gvertexbuffer_h
#include <QtGlobal>
#include <QGLWidget>
#include "Graphs/glcommon.h"
typedef quint32 RGBA;
#ifdef BUILD_WITH_MSVC
__declspec(align(1))
#endif
struct gVertex {
gVertex(GLshort _x, GLshort _y, GLuint _c) { x = _x; y = _y; color = _c; }
GLshort x;
GLshort y;
RGBA color;
}
#ifndef BUILD_WITH_MSVC
__attribute__((packed))
#endif
;
class gVertexBuffer
{
public:
gVertexBuffer(int max = 2048, int type = GL_LINES)
: m_max(max), m_type(type), m_cnt(0), m_size(1),
m_scissor(false), m_antialias(false), m_forceantialias(false), m_stippled(false),
buffer(nullptr),
s_x(0), s_y(0), s_width(0), s_height(0),
m_color(0),
m_stipple(0xffff),
m_blendfunc1(GL_SRC_ALPHA),
m_blendfunc2(GL_ONE_MINUS_SRC_ALPHA)
{
// FIXME: sstangl: Really should not allocate in constructor.
buffer = (gVertex *)calloc(max, sizeof(gVertex));
}
~gVertexBuffer() {
if (buffer) {
free(buffer);
}
}
void add(GLshort x1, GLshort y1, RGBA color);
void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2, RGBA color);
void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2,
GLshort x3, GLshort y3, GLshort x4, GLshort y4, RGBA color);
void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2,
GLshort x3, GLshort y3, GLshort x4, GLshort y4, RGBA color, RGBA color2);
void add(GLshort x1, GLshort y1);
void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
void add(GLshort x1, GLshort y1, GLshort x2, GLshort y2,
GLshort x3, GLshort y3, GLshort x4, GLshort y4);
void unsafe_add(GLshort x1, GLshort y1);
void unsafe_add(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
void unsafe_add(GLshort x1, GLshort y1, GLshort x2, GLshort y2,
GLshort x3, GLshort y3, GLshort x4, GLshort y4);
void draw();
void scissor(GLshort x, GLshort y, GLshort width, GLshort height) {
s_x = x;
s_y = y;
s_width = width;
s_height = height;
m_scissor = true;
}
int Max() const { return m_max; }
int cnt() const { return m_cnt; }
GLuint type() const { return m_type; }
float size() const { return m_size; }
bool full() const { return m_cnt >= m_max; }
void reset() { m_cnt = 0; }
void forceAntiAlias(bool b) { m_forceantialias = b; }
void setSize(float f) { m_size = f; }
void setAntiAlias(bool b) { m_antialias = b; }
void setStipple(GLshort stipple) { m_stipple = stipple; }
void setStippleOn(bool b) { m_stippled = b; }
void setBlendFunc(GLuint b1, GLuint b2) { m_blendfunc1 = b1; m_blendfunc2 = b2; }
void setColor(QColor col);
protected:
//! \brief Maximum number of gVertex points contained in buffer
int m_max;
//! \brief Indicates type of GL vertex information (GL_LINES, GL_QUADS, etc)
GLuint m_type;
//! \brief Count of Vertex points used this draw cycle.
int m_cnt;
//! \brief Line/Point thickness
float m_size;
bool m_scissor;
bool m_antialias;
bool m_forceantialias;
bool m_stippled;
//! \brief Contains list of Vertex & Color points
gVertex *buffer;
//! \brief GL Scissor parameters
GLshort s_x, s_y, s_width, s_height;
//! \brief Current drawing color
GLuint m_color;
//! \brief Stipple bitfield
GLshort m_stipple;
//! \brief Source GL Blend Function
GLuint m_blendfunc1;
//! \brief Destination GL Blend Function
GLuint m_blendfunc2;
};
#endif // graphs_gvertexbuffer_h

View File

@ -40,7 +40,6 @@ gXAxis::gXAxis(QColor col, bool fadeout)
m_show_major_ticks = true; m_show_major_ticks = true;
m_utcfix = false; m_utcfix = false;
m_fadeout = fadeout; m_fadeout = fadeout;
m_textureID = 0;
// QDateTime d=QDateTime::currentDateTime(); // QDateTime d=QDateTime::currentDateTime();
// QTime t1=d.time(); // QTime t1=d.time();
// QTime t2=d.toUTC().time(); // QTime t2=d.toUTC().time();
@ -55,7 +54,7 @@ gXAxis::gXAxis(QColor col, bool fadeout)
gXAxis::~gXAxis() gXAxis::~gXAxis()
{ {
} }
void gXAxis::paint(gGraph &w, int left, int top, int width, int height) void gXAxis::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
Q_UNUSED(height) Q_UNUSED(height)
QString months[] = { QString months[] = {
@ -65,8 +64,9 @@ void gXAxis::paint(gGraph &w, int left, int top, int width, int height)
//static QString dow[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; //static QString dow[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
QVector<QLine> ticks;
QPainter painter; // Only need this for pixmap caching QPainter painter2; // Only need this for pixmap caching
// pixmap caching screws font size when printing // pixmap caching screws font size when printing
@ -75,14 +75,11 @@ void gXAxis::paint(gGraph &w, int left, int top, int width, int height)
if (!usepixmap || (usepixmap && w.invalidate_xAxisImage)) { if (!usepixmap || (usepixmap && w.invalidate_xAxisImage)) {
if (usepixmap) { if (usepixmap) {
// Unbind any previous texture
if (m_textureID) { w.graphView()->deleteTexture(m_textureID); }
m_image = QImage(width + 22, height + 4, QImage::Format_ARGB32_Premultiplied); m_image = QImage(width + 22, height + 4, QImage::Format_ARGB32_Premultiplied);
m_image.fill(Qt::transparent); m_image.fill(Qt::transparent);
painter.begin(&m_image); painter2.begin(&m_image);
painter.setPen(Qt::black); painter2.setPen(Qt::black);
painter.setFont(*defaultfont); painter2.setFont(*defaultfont);
} }
double px, py; double px, py;
@ -187,8 +184,7 @@ void gXAxis::paint(gGraph &w, int left, int top, int width, int height)
aligned_start += step; aligned_start += step;
} }
gVertexBuffer *lines = w.backlines(); painter.setPen(QColor(Qt::black));
lines->setColor(Qt::black);
//int utcoff=m_utcfix ? tz_hours : 0; //int utcoff=m_utcfix ? tz_hours : 0;
@ -225,9 +221,9 @@ void gXAxis::paint(gGraph &w, int left, int top, int width, int height)
if (py < start_px) { continue; } if (py < start_px) { continue; }
if (usepixmap) { if (usepixmap) {
painter.drawLine(py - left + 20, 0, py - left + 20, mintop - top); ticks.append(QLine(py - left + 20, 0, py - left + 20, mintop - top));
} else { } else {
lines->add(py, top, py, mintop); ticks.append(QLine(py, top+2, py, mintop+2));
} }
} }
@ -239,8 +235,10 @@ void gXAxis::paint(gGraph &w, int left, int top, int width, int height)
px += left; px += left;
if (usepixmap) { if (usepixmap) {
painter.drawLine(px - left + 20, 0, px - left + 20, majtop - top); ticks.append(QLine(px - left + 20, 0, px - left + 20, majtop - top));
} else { lines->add(px, top, px, majtop); } } else {
ticks.append(QLine(px, top+2, px, majtop+2));
}
j = i; j = i;
@ -281,7 +279,7 @@ void gXAxis::paint(gGraph &w, int left, int top, int width, int height)
if ((tx + x) < (left + width)) { if ((tx + x) < (left + width)) {
if (!usepixmap) { w.renderText(tmpstr, tx, texttop, 0, Qt::black, defaultfont); } if (!usepixmap) { w.renderText(tmpstr, tx, texttop, 0, Qt::black, defaultfont); }
else { painter.drawText(tx - left + 20, texttop - top, tmpstr); } else { painter2.drawText(tx - left + 20, texttop - top, tmpstr); }
} }
py = px; py = px;
@ -292,34 +290,26 @@ void gXAxis::paint(gGraph &w, int left, int top, int width, int height)
if (py >= left + width) { break; } if (py >= left + width) { break; }
if (usepixmap) { if (usepixmap) {
painter.drawLine(py - left + 20, 0, py - left + 20, mintop - top); ticks.append(QLine(py - left + 20, 0, py - left + 20, mintop - top));
} else { lines->add(py, top, py, mintop); } } else {
} ticks.append(QLine(py, top+2, py, mintop+2));
}
if (lines->full()) {
qWarning() << "maxverts exceeded in gXAxis::Plot()";
break;
} }
} }
if (usepixmap) { if (usepixmap) {
painter.end(); painter2.drawLines(ticks);
m_image = QGLWidget::convertToGLFormat(m_image); painter2.end();
m_textureID = w.graphView()->bindTexture(m_image, GL_TEXTURE_2D, GL_RGBA, } else {
QGLContext::NoBindOption); painter.drawLines(ticks);
} }
w.graphView()->lines_drawn_this_frame += ticks.size();
w.invalidate_xAxisImage = false; w.invalidate_xAxisImage = false;
} }
if (usepixmap && !m_image.isNull()) { if (usepixmap && !m_image.isNull()) {
glEnable(GL_BLEND); painter.drawImage(QPoint(left - 20, top + height - m_image.height() + 4), m_image);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
w.graphView()->drawTexture(QPoint(left - 20, (top + height) - m_image.height() + 4), m_textureID);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
} }
} }

View File

@ -12,6 +12,8 @@
#ifndef GXAXIS_H #ifndef GXAXIS_H
#define GXAXIS_H #define GXAXIS_H
#include <QImage>
#include <QPixmap>
#include "Graphs/layer.h" #include "Graphs/layer.h"
/*! \class gXAxis /*! \class gXAxis
@ -21,7 +23,7 @@ class gXAxis: public Layer
public: public:
gXAxis(QColor col = Qt::black, bool fadeout = true); gXAxis(QColor col = Qt::black, bool fadeout = true);
virtual ~gXAxis(); virtual ~gXAxis();
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
static const int Margin = 20; // How much room does this take up. (Bottom margin) static const int Margin = 20; // How much room does this take up. (Bottom margin)
void SetShowMinorLines(bool b) { m_show_minor_lines = b; } void SetShowMinorLines(bool b) { m_show_minor_lines = b; }
void SetShowMajorLines(bool b) { m_show_major_lines = b; } void SetShowMajorLines(bool b) { m_show_major_lines = b; }
@ -51,6 +53,5 @@ class gXAxis: public Layer
float tz_hours; float tz_hours;
QImage m_image; QImage m_image;
GLuint m_textureID;
}; };
#endif // GXAXIS_H #endif // GXAXIS_H

View File

@ -34,12 +34,10 @@ gXGrid::gXGrid(QColor col)
gXGrid::~gXGrid() gXGrid::~gXGrid()
{ {
} }
void gXGrid::paint(gGraph &w, int left, int top, int width, int height) void gXGrid::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
int x, y; int x, y;
gVertexBuffer *stippled, * lines;
EventDataType miny, maxy; EventDataType miny, maxy;
if (w.zoomY() == 0 && PROFILE.appearance->allowYAxisScaling()) { if (w.zoomY() == 0 && PROFILE.appearance->allowYAxisScaling()) {
@ -108,17 +106,15 @@ void gXGrid::paint(gGraph &w, int left, int top, int width, int height)
if (min_ytick >= 1000000) { if (min_ytick >= 1000000) {
min_ytick = 100; min_ytick = 100;
} }
QVector<QLine> majorlines;
QVector<QLine> minorlines;
stippled = w.backlines();
lines = w.backlines();
for (double i = miny; i <= maxy + min_ytick - 0.00001; i += min_ytick) { for (double i = miny; i <= maxy + min_ytick - 0.00001; i += min_ytick) {
ty = (i - miny) * ymult; ty = (i - miny) * ymult;
h = top + height - ty; h = top + height - ty;
if (m_show_major_lines && (i > miny)) { if (m_show_major_lines && (i > miny)) {
stippled->add(left, h, left + width, h, m_major_color.rgba()); majorlines.append(QLine(left, h, left + width, h));
} }
double z = (min_ytick / 4) * ymult; double z = (min_ytick / 4) * ymult;
@ -134,20 +130,15 @@ void gXGrid::paint(gGraph &w, int left, int top, int width, int height)
// break; // break;
// } // }
if (m_show_minor_lines) {// && (i > miny)) { if (m_show_minor_lines) {// && (i > miny)) {
stippled->add(left, g, left + width, g, m_minor_color.rgba()); minorlines.append(QLine(left, g, left + width, g));
} }
if (stippled->full()) {
break;
}
}
if (lines->full() || stippled->full()) {
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<
miny << "MaxY =" << maxy << "min_ytick=" << min_ytick;
break;
} }
} }
painter.setPen(QPen(m_major_color,1));
painter.drawLines(majorlines);
painter.setPen(QPen(m_minor_color,1));
painter.drawLines(minorlines);
w.graphView()->lines_drawn_this_frame += majorlines.size() + minorlines.size();
} }
@ -157,14 +148,12 @@ gYAxis::gYAxis(QColor col)
{ {
m_line_color = col; m_line_color = col;
m_text_color = col; m_text_color = col;
m_textureID = 0;
m_yaxis_scale = 1; m_yaxis_scale = 1;
} }
gYAxis::~gYAxis() gYAxis::~gYAxis()
{ {
} }
void gYAxis::paint(gGraph &w, int left, int top, int width, int height) void gYAxis::paint(QPainter &painter, gGraph &w, int left, int top, int width, int height)
{ {
int x, y; //,yh=0; int x, y; //,yh=0;
@ -371,9 +360,7 @@ void gYAxis::paint(gGraph &w, int left, int top, int width, int height)
min_ytick = 100; min_ytick = 100;
} }
lines = w.backlines(); QVector<QLine> ticks;
GLuint line_color = m_line_color.rgba();
for (double i = miny; i <= maxy + min_ytick - 0.00001; i += min_ytick) { for (double i = miny; i <= maxy + min_ytick - 0.00001; i += min_ytick) {
ty = (i - miny) * ymult; ty = (i - miny) * ymult;
@ -394,7 +381,7 @@ void gYAxis::paint(gGraph &w, int left, int top, int width, int height)
w.renderText(fd, left + width - 8 - x, (h + (y / 2.0)), 0, m_text_color, defaultfont); w.renderText(fd, left + width - 8 - x, (h + (y / 2.0)), 0, m_text_color, defaultfont);
lines->add(left + width - 4, h, left + width, h, line_color); ticks.append(QLine(left + width - 4, h, left + width, h));
double z = (min_ytick / 4) * ymult; double z = (min_ytick / 4) * ymult;
double g = h; double g = h;
@ -404,21 +391,13 @@ void gYAxis::paint(gGraph &w, int left, int top, int width, int height)
if (g > top + height) { break; } if (g > top + height) { break; }
lines->add(left + width - 3, g, left + width, g, line_color); ticks.append(QLine(left + width - 3, g, left + width, g));
if (lines->full()) {
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<
miny << "MaxY =" << maxy << "min_ytick=" << min_ytick;
break;
}
}
if (lines->full()) {
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<
miny << "MaxY =" << maxy << "min_ytick=" << min_ytick;
break;
} }
} }
painter.setPen(m_line_color);
painter.drawLines(ticks);
w.graphView()->lines_drawn_this_frame += ticks.size();
} }
} }
const QString gYAxis::Format(EventDataType v, int dp) const QString gYAxis::Format(EventDataType v, int dp)

View File

@ -12,6 +12,7 @@
#ifndef GYAXIS_H #ifndef GYAXIS_H
#define GYAXIS_H #define GYAXIS_H
#include <QImage>
#include "Graphs/layer.h" #include "Graphs/layer.h"
/*! \class gXGrid /*! \class gXGrid
@ -25,7 +26,7 @@ class gXGrid: public Layer
virtual ~gXGrid(); virtual ~gXGrid();
//! \brief Draw the horizontal lines by adding the to the Vertex GLbuffers //! \brief Draw the horizontal lines by adding the to the Vertex GLbuffers
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
//! \brief set the visibility status of Major lines //! \brief set the visibility status of Major lines
void setShowMinorLines(bool b) { m_show_minor_lines = b; } void setShowMinorLines(bool b) { m_show_minor_lines = b; }
@ -56,7 +57,7 @@ class gYAxis: public Layer
virtual ~gYAxis(); virtual ~gYAxis();
//! \brief Draw the horizontal tickers display //! \brief Draw the horizontal tickers display
virtual void paint(gGraph &w, int left, int top, int width, int height); virtual void paint(QPainter &painter, gGraph &w, int left, int top, int width, int height);
// void SetShowMinorLines(bool b) { m_show_minor_lines=b; } // void SetShowMinorLines(bool b) { m_show_minor_lines=b; }
// void SetShowMajorLines(bool b) { m_show_major_lines=b; } // void SetShowMajorLines(bool b) { m_show_major_lines=b; }
@ -96,13 +97,10 @@ class gYAxis: public Layer
QColor m_line_color; QColor m_line_color;
QColor m_text_color; QColor m_text_color;
gVertexBuffer *lines;
virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph); virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph);
virtual bool mouseDoubleClickEvent(QMouseEvent *event, gGraph *graph); virtual bool mouseDoubleClickEvent(QMouseEvent *event, gGraph *graph);
QImage m_image; QImage m_image;
GLuint m_textureID;
}; };
/*! \class gYAxisTime /*! \class gYAxisTime

View File

@ -13,85 +13,12 @@
#include "glcommon.h" #include "glcommon.h"
#ifdef BUILD_WITH_MSVC #ifdef BUILD_WITH_MSVC
#if (_MSC_VER < 1800)
double round(double number) double round(double number)
{ {
return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5);
} }
#endif #endif
#endif
void RoundedRectangle(int x, int y, int w, int h, int radius, const QColor color)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4ub(color.red(), color.green(), color.blue(), color.alpha());
glBegin(GL_POLYGON);
glVertex2i(x + radius, y);
glVertex2i(x + w - radius, y);
for (float i = (float)M_PI * 1.5f; i < M_PI * 2; i += 0.1f) {
glVertex2f(x + w - radius + cos(i)*radius, y + radius + sin(i)*radius);
}
glVertex2i(x + w, y + radius);
glVertex2i(x + w, y + h - radius);
for (float i = 0; i < (float)M_PI * 0.5f; i += 0.1f) {
glVertex2f(x + w - radius + cos(i)*radius, y + h - radius + sin(i)*radius);
}
glVertex2i(x + w - radius, y + h);
glVertex2i(x + radius, y + h);
for (float i = (float)M_PI * 0.5f; i < M_PI; i += 0.1f) {
glVertex2f(x + radius + cos(i)*radius, y + h - radius + sin(i)*radius);
}
glVertex2i(x, y + h - radius);
glVertex2i(x, y + radius);
for (float i = (float)M_PI; i < M_PI * 1.5f; i += 0.1f) {
glVertex2f(x + radius + cos(i)*radius, y + radius + sin(i)*radius);
}
glEnd();
glDisable(GL_BLEND);
}
void LinedRoundedRectangle(int x, int y, int w, int h, int radius, int lw, QColor color)
{
//glDisable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4ub(color.red(), color.green(), color.blue(), color.alpha());
glLineWidth((GLfloat)lw);
glBegin(GL_LINE_STRIP);
for (float i = (float)M_PI; i <= 1.5f * M_PI; i += 0.1f) {
glVertex2f(radius * cos(i) + x + radius, radius * sin(i) + y + radius);
}
for (float i = 1.5f * (float)M_PI; i <= 2 * M_PI; i += 0.1f) {
glVertex2f(radius * cos(i) + x + w - radius, radius * sin(i) + y + radius);
}
for (float i = 0; i <= 0.5f * M_PI; i += 0.1f) {
glVertex2f(radius * cos(i) + x + w - radius, radius * sin(i) + y + h - radius);
}
for (float i = 0.5f * (float)M_PI; i <= M_PI; i += 0.1f) {
glVertex2f(radius * cos(i) + x + radius, radius * sin(i) + y + h - radius);
}
glVertex2i(x, y + radius);
glEnd();
//glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
}

View File

@ -12,20 +12,12 @@
#ifndef GLCOMMON_H #ifndef GLCOMMON_H
#define GLCOMMON_H #define GLCOMMON_H
#include <QtOpenGL/qgl.h>
#include <QColor> #include <QColor>
#ifndef nullptr #ifndef nullptr
#define nullptr NULL #define nullptr NULL
#endif #endif
#ifdef Q_OS_MAC
# define USE_RENDERTEXT
# include "OpenGL/glu.h"
#else
# include "GL/glu.h"
#endif
#define MIN(a,b) (((a)<(b)) ? (a) : (b)); #define MIN(a,b) (((a)<(b)) ? (a) : (b));
#define MAX(a,b) (((a)<(b)) ? (b) : (a)); #define MAX(a,b) (((a)<(b)) ? (b) : (a));
@ -64,27 +56,15 @@ const QColor COLOR_ALT_BG2 =
COLOR_White; // Alternating Background Color 2 (Event Flags) COLOR_White; // Alternating Background Color 2 (Event Flags)
/*! \brief Draw an outline of a rounded rectangle
\param radius Radius of corner rounding
\param lw Line Width
\param color Color of drawn lines
*/
void LinedRoundedRectangle(int x, int y, int w, int h, int radius, int lw, QColor color);
/*! \brief Draws a filled rounded rectangle
\param radius Radius of corner rounding
\param color Color of entire rectangle
*/
void RoundedRectangle(int x, int y, int w, int h, int radius, const QColor color);
#ifndef M_PI #ifndef M_PI
const double M_PI = 3.141592653589793; const double M_PI = 3.141592653589793;
#endif #endif
#ifdef BUILD_WITH_MSVC #ifdef BUILD_WITH_MSVC
// Visual C++ doesn't have round in it's maths header.. // Visual C++ earlier than 2013 doesn't have round in it's maths header..
#if (_MSC_VER < 1800)
double round(double number); double round(double number);
#endif #endif
#endif
#endif // GLCOMMON_H #endif // GLCOMMON_H

View File

@ -22,8 +22,9 @@ class gSpacer: public Layer
{ {
public: public:
gSpacer(int space = 20); // orientation? gSpacer(int space = 20); // orientation?
virtual void paint(gGraph &g, int left, int top, int width, int height) { virtual void paint(QPainter &painter, gGraph &g, int left, int top, int width, int height) {
Q_UNUSED(g) Q_UNUSED(g)
Q_UNUSED(painter)
Q_UNUSED(left) Q_UNUSED(left)
Q_UNUSED(top) Q_UNUSED(top)
Q_UNUSED(width) Q_UNUSED(width)

View File

@ -11,52 +11,53 @@
Layer::~Layer() Layer::~Layer()
{ {
for (int i = 0; i < mgl_buffers.size(); i++) { // for (int i = 0; i < mgl_buffers.size(); i++) {
delete mgl_buffers[i]; // delete mgl_buffers[i];
} // }
for (int i = 0; i < mv_buffers.size(); i++) { // for (int i = 0; i < mv_buffers.size(); i++) {
delete mv_buffers[i]; // delete mv_buffers[i];
} // }
} }
void Layer::drawGLBuf(float linesize)
{
int type;
float size;
if (!m_visible) { return; } //void Layer::drawGLBuf(float linesize)
//{
// int type;
// float size;
GLBuffer *buf; // if (!m_visible) { return; }
gVertexBuffer *vb;
for (int i = 0; i < mv_buffers.size(); i++) { // GLBuffer *buf;
vb = mv_buffers[i]; // gVertexBuffer *vb;
size = vb->size();
type = vb->type();
if ((linesize > size) && ((type == GL_LINES) || (type == GL_LINE_LOOP))) { // for (int i = 0; i < mv_buffers.size(); i++) {
vb->setSize(linesize); // vb = mv_buffers[i];
} // size = vb->size();
// type = vb->type();
vb->draw(); // if ((linesize > size) && ((type == GL_LINES) || (type == GL_LINE_LOOP))) {
vb->setSize(size); // vb->setSize(linesize);
} // }
for (int i = 0; i < mgl_buffers.size(); i++) { // vb->draw();
buf = mgl_buffers[i]; // vb->setSize(size);
size = buf->size(); // }
type = buf->type();
if ((linesize > size) && ((type == GL_LINES) || (type == GL_LINE_LOOP))) { // for (int i = 0; i < mgl_buffers.size(); i++) {
buf->setSize(linesize); // buf = mgl_buffers[i];
} // size = buf->size();
// type = buf->type();
buf->draw(); // if ((linesize > size) && ((type == GL_LINES) || (type == GL_LINE_LOOP))) {
//if ((linesize>size) && ((type==GL_LINES) || (type==GL_LINE_LOOP))) { // buf->setSize(linesize);
buf->setSize(size); // }
//}
} // buf->draw();
} // //if ((linesize>size) && ((type==GL_LINES) || (type==GL_LINE_LOOP))) {
// buf->setSize(size);
// //}
// }
//}
void Layer::SetDay(Day *d) void Layer::SetDay(Day *d)
{ {
@ -110,14 +111,14 @@ bool LayerGroup::isEmpty()
return empty; return empty;
} }
void LayerGroup::drawGLBuf(float linesize) //void LayerGroup::drawGLBuf(float linesize)
{ //{
Layer::drawGLBuf(linesize); // Layer::drawGLBuf(linesize);
for (int i = 0; i < layers.size(); i++) { // for (int i = 0; i < layers.size(); i++) {
layers[i]->drawGLBuf(linesize); // layers[i]->drawGLBuf(linesize);
} // }
} //}
void LayerGroup::SetDay(Day *d) void LayerGroup::SetDay(Day *d)
{ {

View File

@ -16,8 +16,6 @@
#include <QVector> #include <QVector>
#include <QWheelEvent> #include <QWheelEvent>
#include "Graphs/GLBuffer.h"
#include "Graphs/gVertexBuffer.h"
#include "SleepLib/common.h" #include "SleepLib/common.h"
#include "SleepLib/day.h" #include "SleepLib/day.h"
#include "SleepLib/machine_common.h" #include "SleepLib/machine_common.h"
@ -119,7 +117,7 @@ class Layer
\param int width \param int width
\param int height \param int height
*/ */
virtual void paint(gGraph &gv, int left, int top, int width, int height) = 0; virtual void paint(QPainter &painter, gGraph &gv, int left, int top, int width, int height) = 0;
//! \brief Set the layout position and order for this layer. //! \brief Set the layout position and order for this layer.
void setLayout(LayerPosition position, short width, short height, short order); void setLayout(LayerPosition position, short width, short height, short order);
@ -134,8 +132,8 @@ class Layer
//void X() { return m_X; } //void X() { return m_X; }
//void Y() { return m_Y; } //void Y() { return m_Y; }
//! \brief Draw all this layers custom GLBuffers (ie. the actual OpenGL Vertices) // //! \brief Draw all this layers custom GLBuffers (ie. the actual OpenGL Vertices)
virtual void drawGLBuf(float linesize); // virtual void drawGLBuf(float linesize);
//! \brief not sure why I needed the reference counting stuff. //! \brief not sure why I needed the reference counting stuff.
short m_refcount; short m_refcount;
@ -146,9 +144,9 @@ class Layer
} }
protected: protected:
//! \brief Add a GLBuffer (vertex) object customized to this layer // //! \brief Add a GLBuffer (vertex) object customized to this layer
void addGLBuf(GLBuffer *buf) { mgl_buffers.push_back(buf); } // void addGLBuf(GLBuffer *buf) { mgl_buffers.push_back(buf); }
void addVertexBuffer(gVertexBuffer *buf) { mv_buffers.push_back(buf); } // void addVertexBuffer(gVertexBuffer *buf) { mv_buffers.push_back(buf); }
//QRect bounds; // bounds, relative to top of individual graph. //QRect bounds; // bounds, relative to top of individual graph.
Day *m_day; Day *m_day;
@ -166,9 +164,9 @@ class Layer
LayerPosition m_position; LayerPosition m_position;
QRect m_rect; QRect m_rect;
//! \brief A vector containing all this layers custom drawing buffers // //! \brief A vector containing all this layers custom drawing buffers
QVector<GLBuffer *> mgl_buffers; // QVector<GLBuffer *> mgl_buffers;
QVector<gVertexBuffer *> mv_buffers; // QVector<gVertexBuffer *> mv_buffers;
//! \brief Mouse wheel moved somewhere over this layer //! \brief Mouse wheel moved somewhere over this layer
virtual bool wheelEvent(QWheelEvent *event, gGraph *graph) { virtual bool wheelEvent(QWheelEvent *event, gGraph *graph) {
@ -241,8 +239,8 @@ class LayerGroup : public Layer
//! \brief Calls SetDay for all Layers contained in this object //! \brief Calls SetDay for all Layers contained in this object
virtual void SetDay(Day *d); virtual void SetDay(Day *d);
//! \brief Calls drawGLBuf for all Layers contained in this object // //! \brief Calls drawGLBuf for all Layers contained in this object
virtual void drawGLBuf(float linesize); // virtual void drawGLBuf(float linesize);
//! \brief Return the list of Layers this object holds //! \brief Return the list of Layers this object holds
QVector<Layer *> &getLayers() { return layers; } QVector<Layer *> &getLayers() { return layers; }

View File

@ -367,7 +367,7 @@ void FlowParser::calc(bool calcResp, bool calcTv, bool calcTi, bool calcTe, bool
if (calcResp) { if (calcResp) {
RR = m_session->AddEventList(CPAP_RespRate, EVL_Event); RR = m_session->AddEventList(CPAP_RespRate, EVL_Event);
minrr = RR->Min(), maxrr = RR->Max(); minrr = RR->Min(), maxrr = RR->Max();
RR->setGain(0.2); RR->setGain(0.2F);
RR->setFirst(time + minute); RR->setFirst(time + minute);
RR->getData().resize(nm); RR->getData().resize(nm);
RR->getTime().resize(nm); RR->getTime().resize(nm);
@ -391,12 +391,12 @@ void FlowParser::calc(bool calcResp, bool calcTv, bool calcTi, bool calcTe, bool
if (calcTi) { if (calcTi) {
Ti = m_session->AddEventList(CPAP_Ti, EVL_Event); Ti = m_session->AddEventList(CPAP_Ti, EVL_Event);
Ti->setGain(0.02); Ti->setGain(0.02F);
} }
if (calcTe) { if (calcTe) {
Te = m_session->AddEventList(CPAP_Te, EVL_Event); Te = m_session->AddEventList(CPAP_Te, EVL_Event);
Te->setGain(0.02); Te->setGain(0.02F);
} }
@ -641,13 +641,13 @@ void FlowParser::flagEvents()
//EventList * uf2=m_session->AddEventList(CPAP_UserFlag2,EVL_Event); //EventList * uf2=m_session->AddEventList(CPAP_UserFlag2,EVL_Event);
//EventList * uf3=m_session->AddEventList(CPAP_UserFlag3,EVL_Event); //EventList * uf3=m_session->AddEventList(CPAP_UserFlag3,EVL_Event);
const EventDataType perc = 0.6; const EventDataType perc = 0.6F;
int idx = float(br.size()) * perc; int idx = float(br.size()) * perc;
nth_element(br.begin(), br.begin() + idx, br.end() - 1); nth_element(br.begin(), br.begin() + idx, br.end() - 1);
EventDataType peak = br[idx]; //*(br.begin()+idx); EventDataType peak = br[idx]; //*(br.begin()+idx);
EventDataType cutoffval = peak * (PROFILE.cpap->userFlowRestriction() / 100.0); EventDataType cutoffval = peak * (PROFILE.cpap->userFlowRestriction() / 100.0F);
int bs, bm, be, bs1, bm1, be1; int bs, bm, be, bs1, bm1, be1;
@ -906,14 +906,14 @@ int calcAHIGraph(Session *session)
f; f;
EventList *AHI = new EventList(EVL_Event); EventList *AHI = new EventList(EVL_Event);
AHI->setGain(0.02); AHI->setGain(0.02F);
session->eventlist[CPAP_AHI].push_back(AHI); session->eventlist[CPAP_AHI].push_back(AHI);
EventList *RDI = nullptr; EventList *RDI = nullptr;
if (calcrdi) { if (calcrdi) {
RDI = new EventList(EVL_Event); RDI = new EventList(EVL_Event);
RDI->setGain(0.02); RDI->setGain(0.02F);
session->eventlist[CPAP_RDI].push_back(RDI); session->eventlist[CPAP_RDI].push_back(RDI);
} }
@ -926,7 +926,7 @@ int calcAHIGraph(Session *session)
int cnt = 0; int cnt = 0;
double events; double events;
double hours = (window_size / 60.0); double hours = (window_size / 60.0F);
if (zeroreset) { if (zeroreset) {
// I personally don't see the point of resetting each hour. // I personally don't see the point of resetting each hour.

View File

@ -83,6 +83,7 @@ const QString STR_GEN_On = QObject::tr("On");
const QString STR_GEN_Off = QObject::tr("Off"); const QString STR_GEN_Off = QObject::tr("Off");
const QString STR_PREF_AllowEarlyUpdates = "AllowEarlyUpdates"; const QString STR_PREF_AllowEarlyUpdates = "AllowEarlyUpdates";
const QString STR_PREF_ReimportBackup = "ReimportBackup";
const QString STR_PROP_Brand = "Brand"; const QString STR_PROP_Brand = "Brand";
const QString STR_PROP_Model = "Model"; const QString STR_PROP_Model = "Model";

View File

@ -305,7 +305,7 @@ EventDataType Day::percentile(ChannelID code, EventDataType percentile)
EventDataType Day::p90(ChannelID code) EventDataType Day::p90(ChannelID code)
{ {
return percentile(code, 0.90); return percentile(code, 0.90F);
} }
EventDataType Day::avg(ChannelID code) EventDataType Day::avg(ChannelID code)

View File

@ -22,8 +22,8 @@ EventList::EventList(EventListType et, EventDataType gain, EventDataType offset,
if (min == max) { // Update Min & Max unless forceably set here.. if (min == max) { // Update Min & Max unless forceably set here..
m_update_minmax = true; m_update_minmax = true;
m_min2 = m_min = 999999999; m_min2 = m_min = 999999999.0F;
m_max2 = m_max = -999999999; m_max2 = m_max = -999999999.0F;
} else { } else {
m_update_minmax = false; m_update_minmax = false;
} }
@ -35,8 +35,8 @@ EventList::EventList(EventListType et, EventDataType gain, EventDataType offset,
void EventList::clear() void EventList::clear()
{ {
m_min2 = m_min = 999999999; m_min2 = m_min = 999999999.0F;
m_max2 = m_max = -999999999; m_max2 = m_max = -999999999.0F;
m_update_minmax = true; m_update_minmax = true;
m_first = m_last = 0; m_first = m_last = 0;
m_count = 0; m_count = 0;
@ -310,7 +310,7 @@ void EventList::AddWaveform(qint64 start, char *data, int recs, qint64 duration)
if (m_update_minmax) { if (m_update_minmax) {
for (sp = data; sp < ep; sp++) { for (sp = data; sp < ep; sp++) {
raw = *sp; raw = *sp;
val = EventDataType(val) * m_gain + m_offset; val = EventDataType(raw) * m_gain + m_offset;
if (m_min > val) { m_min = val; } if (m_min > val) { m_min = val; }
@ -321,7 +321,7 @@ void EventList::AddWaveform(qint64 start, char *data, int recs, qint64 duration)
} else { } else {
for (sp = data; sp < ep; sp++) { for (sp = data; sp < ep; sp++) {
raw = *sp; raw = *sp;
val = EventDataType(val) * m_gain + m_offset; val = EventDataType(raw) * m_gain + m_offset;
*dp++ = raw; *dp++ = raw;
} }
} }

View File

@ -121,6 +121,7 @@ int FPIconLoader::Open(QString &path, Profile *profile)
try { try {
if (m) { OpenMachine(m, npath, profile); } if (m) { OpenMachine(m, npath, profile); }
} catch (OneTypePerDay e) { } catch (OneTypePerDay e) {
Q_UNUSED(e)
profile->DelMachine(m); profile->DelMachine(m);
MachList.erase(MachList.find(sn)); MachList.erase(MachList.find(sn));
QMessageBox::warning(nullptr, "Import Error", QMessageBox::warning(nullptr, "Import Error",
@ -477,9 +478,9 @@ bool FPIconLoader::OpenFLW(Machine *mach, QString filename, Profile *profile)
const double rate = 1000.0 / double(samples_per_block); const double rate = 1000.0 / double(samples_per_block);
// F&P Overwrites this file, not appends to it. // F&P Overwrites this file, not appends to it.
flow = new EventList(EVL_Waveform, 1.0, 0, 0, 0, rate); flow = new EventList(EVL_Waveform, 1.0F, 0, 0, 0, rate);
//leak=new EventList(EVL_Event,1.0,0,0,0,rate*double(samples_per_block)); // 1 per second //leak=new EventList(EVL_Event,1.0,0,0,0,rate*double(samples_per_block)); // 1 per second
pressure = new EventList(EVL_Event, 0.01, 0, 0, 0, pressure = new EventList(EVL_Event, 0.01F, 0, 0, 0,
rate * double(samples_per_block)); // 1 per second rate * double(samples_per_block)); // 1 per second
flow->setFirst(ti); flow->setFirst(ti);
@ -832,7 +833,7 @@ bool FPIconLoader::OpenDetail(Machine *mach, QString filename, Profile *profile)
ti = qint64(sessid) * 1000L; ti = qint64(sessid) * 1000L;
sess->really_set_first(ti); sess->really_set_first(ti);
EventList *LK = sess->AddEventList(CPAP_LeakTotal, EVL_Event, 1); EventList *LK = sess->AddEventList(CPAP_LeakTotal, EVL_Event, 1);
EventList *PR = sess->AddEventList(CPAP_Pressure, EVL_Event, 0.1); EventList *PR = sess->AddEventList(CPAP_Pressure, EVL_Event, 0.1F);
EventList *FLG = sess->AddEventList(CPAP_FLG, EVL_Event); EventList *FLG = sess->AddEventList(CPAP_FLG, EVL_Event);
EventList *OA = sess->AddEventList(CPAP_Obstructive, EVL_Event); EventList *OA = sess->AddEventList(CPAP_Obstructive, EVL_Event);
EventList *H = sess->AddEventList(CPAP_Hypopnea, EVL_Event); EventList *H = sess->AddEventList(CPAP_Hypopnea, EVL_Event);

View File

@ -288,6 +288,7 @@ int PRS1Loader::Open(QString &path, Profile *profile)
OpenMachine(m, newpath + "/" + (*sn), profile); OpenMachine(m, newpath + "/" + (*sn), profile);
} }
} catch (OneTypePerDay e) { } catch (OneTypePerDay e) {
Q_UNUSED(e)
profile->DelMachine(m); profile->DelMachine(m);
PRS1List.erase(PRS1List.find(s)); PRS1List.erase(PRS1List.find(s));
QMessageBox::warning(nullptr, QObject::tr("Import Error"), QMessageBox::warning(nullptr, QObject::tr("Import Error"),
@ -726,8 +727,6 @@ bool PRS1Loader::ParseSummary(Machine *mach, qint32 sequence, quint32 timestamp,
// Summary files vary too much between Families/versions // Summary files vary too much between Families/versions
unsigned duration;
if (size < 59) { if (size < 59) {
// duration = data[offset + 0x12] | (data[offset + 0x13] << 8); // duration = data[offset + 0x12] | (data[offset + 0x13] << 8);
// duration *= 2; // duration *= 2;
@ -849,16 +848,16 @@ bool PRS1Loader::Parse002v5(qint32 sequence, quint32 timestamp, unsigned char *b
EventList *CSR = session->AddEventList(CPAP_CSR, EVL_Event); EventList *CSR = session->AddEventList(CPAP_CSR, EVL_Event);
EventList *LEAK = session->AddEventList(CPAP_LeakTotal, EVL_Event); EventList *LEAK = session->AddEventList(CPAP_LeakTotal, EVL_Event);
EventList *SNORE = session->AddEventList(CPAP_Snore, EVL_Event); EventList *SNORE = session->AddEventList(CPAP_Snore, EVL_Event);
EventList *IPAP = session->AddEventList(CPAP_IPAP, EVL_Event, 0.1); EventList *IPAP = session->AddEventList(CPAP_IPAP, EVL_Event, 0.1F);
EventList *EPAP = session->AddEventList(CPAP_EPAP, EVL_Event, 0.1); EventList *EPAP = session->AddEventList(CPAP_EPAP, EVL_Event, 0.1F);
EventList *PS = session->AddEventList(CPAP_PS, EVL_Event, 0.1); EventList *PS = session->AddEventList(CPAP_PS, EVL_Event, 0.1F);
EventList *IPAPLo = session->AddEventList(CPAP_IPAPLo, EVL_Event, 0.1); EventList *IPAPLo = session->AddEventList(CPAP_IPAPLo, EVL_Event, 0.1F);
EventList *IPAPHi = session->AddEventList(CPAP_IPAPHi, EVL_Event, 0.1); EventList *IPAPHi = session->AddEventList(CPAP_IPAPHi, EVL_Event, 0.1F);
EventList *RR = session->AddEventList(CPAP_RespRate, EVL_Event); EventList *RR = session->AddEventList(CPAP_RespRate, EVL_Event);
EventList *PTB = session->AddEventList(CPAP_PTB, EVL_Event); EventList *PTB = session->AddEventList(CPAP_PTB, EVL_Event);
EventList *MV = session->AddEventList(CPAP_MinuteVent, EVL_Event); EventList *MV = session->AddEventList(CPAP_MinuteVent, EVL_Event);
EventList *TV = session->AddEventList(CPAP_TidalVolume, EVL_Event, 10); EventList *TV = session->AddEventList(CPAP_TidalVolume, EVL_Event, 10.0F);
EventList *CA = nullptr; //session->AddEventList(CPAP_ClearAirway, EVL_Event); EventList *CA = nullptr; //session->AddEventList(CPAP_ClearAirway, EVL_Event);
EventList *VS = nullptr, * FL = nullptr; //,* RE=nullptr,* VS2=nullptr; EventList *VS = nullptr, * FL = nullptr; //,* RE=nullptr,* VS2=nullptr;
@ -934,7 +933,7 @@ bool PRS1Loader::Parse002v5(qint32 sequence, quint32 timestamp, unsigned char *b
case 0x01: // Unknown case 0x01: // Unknown
if (!Code[1]) { if (!Code[1]) {
if (!(Code[1] = session->AddEventList(cpapcode, EVL_Event, 0.1))) { return false; } if (!(Code[1] = session->AddEventList(cpapcode, EVL_Event, 0.1F))) { return false; }
} }
Code[1]->AddEvent(t, 0); Code[1]->AddEvent(t, 0);
@ -1176,7 +1175,7 @@ bool PRS1Loader::Parse002(qint32 sequence, quint32 timestamp, unsigned char *buf
return false; return false;
} }
unsigned char code; unsigned char code=0;
EventList *Code[0x20] = {0}; EventList *Code[0x20] = {0};
EventDataType data[10]; EventDataType data[10];
int cnt = 0; int cnt = 0;
@ -1263,7 +1262,7 @@ bool PRS1Loader::Parse002(qint32 sequence, quint32 timestamp, unsigned char *buf
if (family == 0 && familyVersion >= 4) { if (family == 0 && familyVersion >= 4) {
if (!PRESSURE) { if (!PRESSURE) {
PRESSURE = session->AddEventList(CPAP_Pressure, EVL_Event, 0.1); PRESSURE = session->AddEventList(CPAP_Pressure, EVL_Event, 0.1F);
if (!PRESSURE) { return false; } if (!PRESSURE) { return false; }
} }
@ -1276,11 +1275,11 @@ bool PRS1Loader::Parse002(qint32 sequence, quint32 timestamp, unsigned char *buf
case 0x02: // Pressure case 0x02: // Pressure
if (family == 0 && familyVersion >= 4) { // BiPAP Pressure if (family == 0 && familyVersion >= 4) { // BiPAP Pressure
if (!EPAP) { if (!EPAP) {
if (!(EPAP = session->AddEventList(CPAP_EPAP, EVL_Event, 0.1))) { return false; } if (!(EPAP = session->AddEventList(CPAP_EPAP, EVL_Event, 0.1F))) { return false; }
if (!(IPAP = session->AddEventList(CPAP_IPAP, EVL_Event, 0.1))) { return false; } if (!(IPAP = session->AddEventList(CPAP_IPAP, EVL_Event, 0.1F))) { return false; }
if (!(PS = session->AddEventList(CPAP_PS, EVL_Event, 0.1))) { return false; } if (!(PS = session->AddEventList(CPAP_PS, EVL_Event, 0.1F))) { return false; }
} }
EPAP->AddEvent(t, data[0] = buffer[pos++]); EPAP->AddEvent(t, data[0] = buffer[pos++]);
@ -1288,7 +1287,7 @@ bool PRS1Loader::Parse002(qint32 sequence, quint32 timestamp, unsigned char *buf
PS->AddEvent(t, data[1] - data[0]); PS->AddEvent(t, data[1] - data[0]);
} else { } else {
if (!PRESSURE) { if (!PRESSURE) {
PRESSURE = session->AddEventList(CPAP_Pressure, EVL_Event, 0.1); PRESSURE = session->AddEventList(CPAP_Pressure, EVL_Event, 0.1F);
if (!PRESSURE) { return false; } if (!PRESSURE) { return false; }
} }
@ -1300,11 +1299,11 @@ bool PRS1Loader::Parse002(qint32 sequence, quint32 timestamp, unsigned char *buf
case 0x03: // BIPAP Pressure case 0x03: // BIPAP Pressure
if (!EPAP) { if (!EPAP) {
if (!(EPAP = session->AddEventList(CPAP_EPAP, EVL_Event, 0.1))) { return false; } if (!(EPAP = session->AddEventList(CPAP_EPAP, EVL_Event, 0.1F))) { return false; }
if (!(IPAP = session->AddEventList(CPAP_IPAP, EVL_Event, 0.1))) { return false; } if (!(IPAP = session->AddEventList(CPAP_IPAP, EVL_Event, 0.1F))) { return false; }
if (!(PS = session->AddEventList(CPAP_PS, EVL_Event, 0.1))) { return false; } if (!(PS = session->AddEventList(CPAP_PS, EVL_Event, 0.1F))) { return false; }
} }
EPAP->AddEvent(t, data[0] = buffer[pos++]); EPAP->AddEvent(t, data[0] = buffer[pos++]);
@ -1663,11 +1662,6 @@ bool PRS1Loader::OpenFile(Machine *mach, QString filename)
bool PRS1Loader::OpenWaveforms(SessionID sid, QString filename) bool PRS1Loader::OpenWaveforms(SessionID sid, QString filename)
{ {
if (sid == 1532) {
int i=5;
}
Session *session = new_sessions[sid]; Session *session = new_sessions[sid];
//int sequence,seconds,br,htype,version,numsignals; //int sequence,seconds,br,htype,version,numsignals;
QFile file(filename); QFile file(filename);

View File

@ -149,7 +149,7 @@ qint16 EDFParser::Read16()
QString EDFParser::Read(unsigned n) QString EDFParser::Read(unsigned n)
{ {
if ((pos + n) > filesize) { if ((pos + long(n)) > filesize) {
return ""; return "";
} }
@ -2262,12 +2262,14 @@ bool ResmedLoader::LoadSAD(Session *sess, EDFParser &edf)
} }
if (!hasdata) continue; if (!hasdata) continue;
if (matchSignal(code = OXI_Pulse, es.label)) { if (matchSignal(OXI_Pulse, es.label)) {
code = OXI_Pulse;
ToTimeDelta(sess, edf, es, code, recs, duration); ToTimeDelta(sess, edf, es, code, recs, duration);
sess->setPhysMax(code, 180); sess->setPhysMax(code, 180);
sess->setPhysMin(code, 18); sess->setPhysMin(code, 18);
} else if (matchSignal(code = OXI_SPO2, es.label)) { } else if (matchSignal(OXI_SPO2, es.label)) {
code = OXI_SPO2;
es.physical_minimum = 60; es.physical_minimum = 60;
ToTimeDelta(sess, edf, es, code, recs, duration); ToTimeDelta(sess, edf, es, code, recs, duration);
sess->setPhysMax(code, 100); sess->setPhysMax(code, 100);
@ -2307,30 +2309,37 @@ bool ResmedLoader::LoadPLD(Session *sess, EDFParser &edf)
rate = double(duration) / double(recs); rate = double(duration) / double(recs);
//qDebug() << "EVE:" << es.digital_maximum << es.digital_minimum << es.physical_maximum << es.physical_minimum << es.gain; //qDebug() << "EVE:" << es.digital_maximum << es.digital_minimum << es.physical_maximum << es.physical_minimum << es.gain;
if (matchSignal(code = CPAP_Snore, es.label)) { if (matchSignal(CPAP_Snore, es.label)) {
code = CPAP_Snore;
ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0); ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0);
} else if (matchSignal(code = CPAP_Pressure, es.label)) { } else if (matchSignal(CPAP_Pressure, es.label)) {
code = CPAP_Pressure;
es.physical_maximum = 25; es.physical_maximum = 25;
es.physical_minimum = 4; es.physical_minimum = 4;
ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0); ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0);
} else if (matchSignal(code = CPAP_IPAP, es.label)) { } else if (matchSignal(CPAP_IPAP, es.label)) {
code = CPAP_IPAP;
sess->settings[CPAP_Mode] = MODE_BIPAP; sess->settings[CPAP_Mode] = MODE_BIPAP;
es.physical_maximum = 25; es.physical_maximum = 25;
es.physical_minimum = 4; es.physical_minimum = 4;
ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0); ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0);
} else if (matchSignal(code = CPAP_MinuteVent,es.label)) { } else if (matchSignal(CPAP_MinuteVent,es.label)) {
code = CPAP_MinuteVent;
ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0); ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0);
} else if (matchSignal(code = CPAP_RespRate, es.label)) { } else if (matchSignal(CPAP_RespRate, es.label)) {
code = CPAP_RespRate;
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate); a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
a->AddWaveform(edf.startdate, es.data, recs, duration); a->AddWaveform(edf.startdate, es.data, recs, duration);
} else if (matchSignal(code = CPAP_TidalVolume, es.label)) { } else if (matchSignal(CPAP_TidalVolume, es.label)) {
code = CPAP_TidalVolume;
es.gain *= 1000.0; es.gain *= 1000.0;
es.physical_maximum *= 1000.0; es.physical_maximum *= 1000.0;
es.physical_minimum *= 1000.0; es.physical_minimum *= 1000.0;
// es.digital_maximum*=1000.0; // es.digital_maximum*=1000.0;
// es.digital_minimum*=1000.0; // es.digital_minimum*=1000.0;
ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0); ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0);
} else if (matchSignal(code = CPAP_Leak, es.label)) { } else if (matchSignal(CPAP_Leak, es.label)) {
code = CPAP_Leak;
es.gain *= 60.0; es.gain *= 60.0;
es.physical_maximum *= 60.0; es.physical_maximum *= 60.0;
es.physical_minimum *= 60.0; es.physical_minimum *= 60.0;
@ -2340,31 +2349,38 @@ bool ResmedLoader::LoadPLD(Session *sess, EDFParser &edf)
ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0, true); ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0, true);
sess->setPhysMax(code, 120.0); sess->setPhysMax(code, 120.0);
sess->setPhysMin(code, 0); sess->setPhysMin(code, 0);
} else if (matchSignal(code = CPAP_FLG, es.label)) { } else if (matchSignal(CPAP_FLG, es.label)) {
code = CPAP_FLG;
ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0); ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0);
} else if (matchSignal(code = CPAP_MaskPressure, es.label)) { } else if (matchSignal(CPAP_MaskPressure, es.label)) {
code = CPAP_MaskPressure;
es.physical_maximum = 25; es.physical_maximum = 25;
es.physical_minimum = 4; es.physical_minimum = 4;
ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0); ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0);
} else if (matchSignal(code = CPAP_EPAP, es.label)) { // Expiratory Pressure } else if (matchSignal(CPAP_EPAP, es.label)) { // Expiratory Pressure
code = CPAP_EPAP;
es.physical_maximum = 25; es.physical_maximum = 25;
es.physical_minimum = 4; es.physical_minimum = 4;
ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0); ToTimeDelta(sess, edf, es, code, recs, duration, 0, 0);
} else if (matchSignal(code = CPAP_IE, es.label)) { //I:E ratio } else if (matchSignal(CPAP_IE, es.label)) { //I:E ratio
code = CPAP_IE;
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate); a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
a->AddWaveform(edf.startdate, es.data, recs, duration); a->AddWaveform(edf.startdate, es.data, recs, duration);
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0); //a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
} else if (matchSignal(code = CPAP_Ti, es.label)) { } else if (matchSignal(CPAP_Ti, es.label)) {
code = CPAP_Ti;
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate); a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
a->AddWaveform(edf.startdate, es.data, recs, duration); a->AddWaveform(edf.startdate, es.data, recs, duration);
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0); //a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
} else if (matchSignal(code = CPAP_Te, es.label)) { } else if (matchSignal(CPAP_Te, es.label)) {
code = CPAP_Te;
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate); a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
a->AddWaveform(edf.startdate, es.data, recs, duration); a->AddWaveform(edf.startdate, es.data, recs, duration);
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0); //a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
} else if (matchSignal(code = CPAP_TgMV, es.label)) { } else if (matchSignal(CPAP_TgMV, es.label)) {
code = CPAP_TgMV;
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate); a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
a->AddWaveform(edf.startdate, es.data, recs, duration); a->AddWaveform(edf.startdate, es.data, recs, duration);
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0); //a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);

View File

@ -221,6 +221,7 @@ bool Machine::Purge(int secret)
// Boring api key to stop this function getting called by accident :) // Boring api key to stop this function getting called by accident :)
if (secret != 3478216) { return false; } if (secret != 3478216) { return false; }
// FIXME: should really clear out the majority of the machine properties here
// It would be joyous if this function screwed up.. // It would be joyous if this function screwed up..
@ -266,6 +267,9 @@ bool Machine::Purge(int secret)
// qWarning() << "Could not purge path\n" << path << "\n\n" << could_not_kill << " file(s) remain.. Suggest manually deleting this path\n"; // qWarning() << "Could not purge path\n" << path << "\n\n" << could_not_kill << " file(s) remain.. Suggest manually deleting this path\n";
// return false; // return false;
} }
// PROFILE.machlist.erase(PROFILE.machlist.find(m->id()));
PROFILE.p_preferences[STR_PREF_ReimportBackup] = true;
return true; return true;
} }

View File

@ -119,17 +119,23 @@ void Profile::DataFormatError(Machine *m)
msg = msg + msg = msg +
QObject::tr("Would you like me to purge this data this for you so you can run the new version?"); QObject::tr("Would you like me to purge this data this for you so you can run the new version?");
if (QMessageBox::warning(nullptr, QObject::tr("Machine Database Changes"), msg, if (QMessageBox::warning(nullptr,
QObject::tr("Machine Database Changes"),
msg,
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes) == QMessageBox::Yes) { QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes) == QMessageBox::Yes) {
if (!m->Purge(
3478216)) { // Do not copy this line without thinking.. You will be eaten by a Grue if you do if (!m->Purge(3478216)) {
// Do not copy this line without thinking.. You will be eaten by a Grue if you do
QMessageBox::critical(nullptr, QObject::tr("Purge Failed"), QMessageBox::critical(nullptr, QObject::tr("Purge Failed"),
QObject::tr("Sorry, I could not purge this data, which means this version of SleepyHead can't start.. SleepyHead's Data folder needs to be removed manually\n\nThis folder currently resides at the following location:\n") QObject::tr("Sorry, I could not purge this data, which means this version of SleepyHead can't start.. SleepyHead's Data folder needs to be removed manually\n\nThis folder currently resides at the following location:\n")
+ PREF[STR_GEN_DataFolder].toString(), QMessageBox::Ok); + PREF[STR_GEN_DataFolder].toString(), QMessageBox::Ok);
QApplication::exit(-1); QApplication::exit(-1);
} }
// Note: I deliberately haven't added a Profile help for this
PROFILE.p_preferences[STR_PREF_ReimportBackup] = true;
PROFILE.Save();
} else { } else {
QApplication::exit(-1); QApplication::exit(-1);
} }
@ -167,6 +173,7 @@ void Profile::LoadMachineData()
try { try {
m->Load(); m->Load();
} catch (OldDBVersion e) { } catch (OldDBVersion e) {
Q_UNUSED(e)
DataFormatError(m); DataFormatError(m);
} }
} }

View File

@ -244,6 +244,7 @@ const QString STR_AS_OverviewLinechartMode = "OverviewLinechartMode";
const QString STR_AS_UsePixmapCaching = "UsePixmapCaching"; const QString STR_AS_UsePixmapCaching = "UsePixmapCaching";
const QString STR_AS_AllowYAxisScaling = "AllowYAxisScaling"; const QString STR_AS_AllowYAxisScaling = "AllowYAxisScaling";
const QString STR_AS_GraphTooltips = "GraphTooltips"; const QString STR_AS_GraphTooltips = "GraphTooltips";
const QString STR_AS_LineThickness = "LineThickness";
// UserSettings Strings // UserSettings Strings
const QString STR_US_UnitSystem = "UnitSystem"; const QString STR_US_UnitSystem = "UnitSystem";
@ -568,6 +569,7 @@ class AppearanceSettings : public ProfileSettings
initPref(STR_AS_UsePixmapCaching, true); initPref(STR_AS_UsePixmapCaching, true);
initPref(STR_AS_OverlayType, ODT_Bars); initPref(STR_AS_OverlayType, ODT_Bars);
initPref(STR_AS_OverviewLinechartMode, OLC_Bartop); initPref(STR_AS_OverviewLinechartMode, OLC_Bartop);
initPref(STR_AS_LineThickness, 1.0);
} }
//! \brief Returns the normal (unscaled) height of a graph //! \brief Returns the normal (unscaled) height of a graph
@ -586,6 +588,10 @@ class AppearanceSettings : public ProfileSettings
bool allowYAxisScaling() const { return getPref(STR_AS_AllowYAxisScaling).toBool(); } bool allowYAxisScaling() const { return getPref(STR_AS_AllowYAxisScaling).toBool(); }
//! \brief Whether to show graph tooltips //! \brief Whether to show graph tooltips
bool graphTooltips() const { return getPref(STR_AS_GraphTooltips).toBool(); } bool graphTooltips() const { return getPref(STR_AS_GraphTooltips).toBool(); }
//! \brief Pen width of line plots
float lineThickness() const { return getPref(STR_AS_LineThickness).toFloat(); }
//! \brief Returns the type of overlay flags (which are displayed over the Flow Waveform) //! \brief Returns the type of overlay flags (which are displayed over the Flow Waveform)
OverlayDisplayType overlayType() const { OverlayDisplayType overlayType() const {
return (OverlayDisplayType)getPref(STR_AS_OverlayType).toInt(); return (OverlayDisplayType)getPref(STR_AS_OverlayType).toInt();
@ -617,6 +623,8 @@ class AppearanceSettings : public ProfileSettings
void setOverviewLinechartMode(OverviewLinechartModes od) { void setOverviewLinechartMode(OverviewLinechartModes od) {
setPref(STR_AS_OverviewLinechartMode, (int)od); setPref(STR_AS_OverviewLinechartMode, (int)od);
} }
//! \brief Set the pen width of line plots.
void setLineThickness(float size) { setPref(STR_AS_LineThickness, size); }
}; };
/*! \class UserSettings /*! \class UserSettings

View File

@ -1057,7 +1057,7 @@ EventDataType Session::physMin(ChannelID id)
return 0; return 0;
} }
EventDataType min = round(Min(id)); EventDataType min = floor(Min(id));
m_physmin[id] = min; m_physmin[id] = min;
return min; return min;
} }
@ -1077,7 +1077,7 @@ EventDataType Session::physMax(ChannelID id)
return 0; return 0;
} }
EventDataType max = round(Max(id) + 0.5); EventDataType max = ceil(Max(id) + 0.5);
m_physmax[id] = max; m_physmax[id] = max;
return max; return max;
} }

View File

@ -74,7 +74,7 @@ QColor COLOR_RERA = COLOR_Gold;
QColor COLOR_VibratorySnore = QColor("#ff4040"); QColor COLOR_VibratorySnore = QColor("#ff4040");
QColor COLOR_FlowLimit = QColor("#404040"); QColor COLOR_FlowLimit = QColor("#404040");
QColor COLOR_LeakFlag = QColor("#40c0c0"); // Qt::darkBlue; QColor COLOR_LeakFlag = QColor("#40c0c0"); // Qt::darkBlue;
QColor COLOR_NRI = Qt::darkMagenta; QColor COLOR_NRI = COLOR_ClearAirway;
QColor COLOR_ExP = Qt::darkCyan; QColor COLOR_ExP = Qt::darkCyan;
QColor COLOR_PressurePulse = Qt::red; QColor COLOR_PressurePulse = Qt::red;
QColor COLOR_PulseChange = COLOR_LightGray; QColor COLOR_PulseChange = COLOR_LightGray;

View File

@ -46,6 +46,12 @@
//extern QProgressBar *qprogress; //extern QProgressBar *qprogress;
extern MainWindow * mainwin; extern MainWindow * mainwin;
// This was Sean Stangl's idea.. but I couldn't apply that patch.
inline QString channelInfo(ChannelID code) {
return schema::channel[code].fullname()+"\n"+schema::channel[code].description()+"\n("+schema::channel[code].units()+")";
}
Daily::Daily(QWidget *parent,gGraphView * shared) Daily::Daily(QWidget *parent,gGraphView * shared)
:QWidget(parent), ui(new Ui::Daily) :QWidget(parent), ui(new Ui::Daily)
{ {
@ -121,42 +127,50 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
layout->addWidget(scrollbar,0); layout->addWidget(scrollbar,0);
int default_height=PROFILE.appearance->graphHeight(); int default_height=PROFILE.appearance->graphHeight();
SF=new gGraph(GraphView,STR_TR_EventFlags,STR_TR_EventFlags,default_height);
gGraph *GAHI = nullptr,
// *TAP = nullptr,
*SF = nullptr,
*AHI = nullptr;
graphlist["SF"] = SF = new gGraph(GraphView,STR_TR_EventFlags,STR_TR_EventFlags,default_height);
SF->setPinned(true); SF->setPinned(true);
FRW=new gGraph(GraphView,STR_TR_FlowRate, schema::channel[CPAP_FlowRate].fullname()+"\n"+schema::channel[CPAP_FlowRate].description()+"\n("+schema::channel[CPAP_FlowRate].units()+")",default_height);
//FRW->setPinned(true);
ChannelID cpapcodes[] = {
CPAP_FlowRate, CPAP_MaskPressure, CPAP_Pressure, CPAP_Leak, CPAP_Snore, CPAP_RespRate,
CPAP_TidalVolume, CPAP_MinuteVent, CPAP_FLG, CPAP_PTB, CPAP_RespEvent, CPAP_Ti, CPAP_Te,
CPAP_IE, ZEO_SleepStage, POS_Inclination, POS_Orientation
};
int cpapsize = sizeof(cpapcodes) / sizeof(ChannelID);
ChannelID oxicodes[] = {
OXI_Pulse, OXI_SPO2, OXI_Plethy
};
int oxisize = sizeof(oxicodes) / sizeof(ChannelID);
for (int i=0; i < cpapsize; ++i) {
ChannelID code = cpapcodes[i];
graphlist[schema::channel[code].label()] = new gGraph(GraphView, schema::channel[code].label(), channelInfo(code), default_height);
}
int oxigrp=PROFILE.ExistsAndTrue("SyncOximetry") ? 0 : 1; // Contemplating killing this setting...
for (int i=0; i < oxisize; ++i) {
ChannelID code = oxicodes[i];
graphlist[schema::channel[code].label()] = new gGraph(GraphView, schema::channel[code].label(), channelInfo(code), default_height, oxigrp);
}
if (PROFILE.general->calculateRDI()) { if (PROFILE.general->calculateRDI()) {
AHI=new gGraph(GraphView,STR_TR_RDI, schema::channel[CPAP_RDI].fullname()+"\n"+schema::channel[CPAP_RDI].description()+"\n("+schema::channel[CPAP_RDI].units()+")",default_height); AHI=new gGraph(GraphView,STR_TR_RDI, channelInfo(CPAP_RDI), default_height);
} else AHI=new gGraph(GraphView,STR_TR_AHI,schema::channel[CPAP_AHI].fullname()+"\n"+schema::channel[CPAP_AHI].description()+"\n("+schema::channel[CPAP_AHI].units()+")",default_height); } else {
AHI=new gGraph(GraphView,STR_TR_AHI, channelInfo(CPAP_AHI), default_height);
}
MP=new gGraph(GraphView,schema::channel[CPAP_MaskPressure].label(), schema::channel[CPAP_MaskPressure].fullname()+"\n"+schema::channel[CPAP_MaskPressure].description()+"\n("+schema::channel[CPAP_MaskPressure].units()+")",default_height); graphlist["AHI"] = AHI;
PRD=new gGraph(GraphView,schema::channel[CPAP_Pressure].label(), schema::channel[CPAP_Pressure].fullname()+"\n"+schema::channel[CPAP_Pressure].description()+"\n("+schema::channel[CPAP_Pressure].units()+")",default_height);
LEAK=new gGraph(GraphView,STR_TR_Leak, schema::channel[CPAP_Leak].fullname()+"\n"+schema::channel[CPAP_Leak].description()+"\n("+schema::channel[CPAP_Leak].units()+")",default_height);
SNORE=new gGraph(GraphView,STR_TR_Snore, schema::channel[CPAP_Snore].fullname()+"\n"+schema::channel[CPAP_Snore].description()+"\n("+schema::channel[CPAP_Snore].units()+")",default_height);
RR=new gGraph(GraphView,STR_TR_RespRate, schema::channel[CPAP_RespRate].fullname()+"\n"+schema::channel[CPAP_RespRate].description()+"\n("+schema::channel[CPAP_RespRate].units()+")",default_height);
TV=new gGraph(GraphView,STR_TR_TidalVolume, schema::channel[CPAP_TidalVolume].fullname()+"\n"+schema::channel[CPAP_TidalVolume].description()+"\n("+schema::channel[CPAP_TidalVolume].units()+")",default_height);
MV=new gGraph(GraphView,STR_TR_MinuteVent, schema::channel[CPAP_MinuteVent].fullname()+"\n"+schema::channel[CPAP_MinuteVent].description()+"\n("+schema::channel[CPAP_MinuteVent].units()+")",default_height);
//TgMV=new gGraph(GraphView,STR_TR_TgtMinVent, schema::channel[CPAP_TgMV].fullname()+"\n"+schema::channel[CPAP_TgMV].description()+"\n("+schema::channel[CPAP_TgMV].units()+")",default_height);
FLG=new gGraph(GraphView,STR_TR_FlowLimit, schema::channel[CPAP_FLG].fullname()+"\n"+schema::channel[CPAP_FLG].description()+"\n("+schema::channel[CPAP_FLG].units()+")",default_height);
PTB=new gGraph(GraphView,STR_TR_PatTrigBreath, schema::channel[CPAP_PTB].fullname()+"\n"+schema::channel[CPAP_PTB].description()+"\n("+schema::channel[CPAP_PTB].units()+")",default_height);
RE=new gGraph(GraphView,STR_TR_RespEvent, schema::channel[CPAP_RespEvent].fullname()+"\n"+schema::channel[CPAP_RespEvent].description()+"\n("+schema::channel[CPAP_RespEvent].units()+")",default_height);
TI=new gGraph(GraphView,STR_TR_InspTime, schema::channel[CPAP_Ti].fullname()+"\n"+schema::channel[CPAP_Ti].description()+"\n("+schema::channel[CPAP_Ti].units()+")",default_height);
TE=new gGraph(GraphView,STR_TR_ExpTime, schema::channel[CPAP_Te].fullname()+"\n"+schema::channel[CPAP_Te].description()+"\n("+schema::channel[CPAP_Te].units()+")",default_height);
IE=new gGraph(GraphView,schema::channel[CPAP_IE].label(), schema::channel[CPAP_IE].fullname()+"\n"+schema::channel[CPAP_IE].description()+"\n("+schema::channel[CPAP_IE].units()+")",default_height);
STAGE=new gGraph(GraphView,STR_TR_SleepStage, schema::channel[ZEO_SleepStage].fullname()+"\n"+schema::channel[ZEO_SleepStage].description()+"\n("+schema::channel[ZEO_SleepStage].units()+")",default_height); graphlist["INTPULSE"] = new gGraph(GraphView,tr("Int. Pulse"), channelInfo(OXI_Pulse), default_height, oxigrp);
int oxigrp=PROFILE.ExistsAndTrue("SyncOximetry") ? 0 : 1; graphlist["INTSPO2"] = new gGraph(GraphView,tr("Int. SpO2"), channelInfo(OXI_SPO2), default_height, oxigrp);
PULSE=new gGraph(GraphView,STR_TR_PulseRate, schema::channel[OXI_Pulse].fullname()+"\n"+schema::channel[OXI_Pulse].description()+"\n("+schema::channel[OXI_Pulse].units()+")",default_height,oxigrp);
SPO2=new gGraph(GraphView,STR_TR_SpO2, schema::channel[OXI_SPO2].fullname()+"\n"+schema::channel[OXI_SPO2].description()+"\n("+schema::channel[OXI_SPO2].units()+")",default_height,oxigrp);
INTPULSE=new gGraph(GraphView,tr("Int. Pulse"), schema::channel[OXI_Pulse].fullname()+"\n"+schema::channel[OXI_Pulse].description()+"\n("+schema::channel[OXI_Pulse].units()+")",default_height,oxigrp);
INTSPO2=new gGraph(GraphView,tr("Int. SpO2"), schema::channel[OXI_SPO2].fullname()+"\n"+schema::channel[OXI_SPO2].description()+"\n("+schema::channel[OXI_SPO2].units()+")",default_height,oxigrp);
PLETHY=new gGraph(GraphView,STR_TR_Plethy, schema::channel[OXI_Plethy].fullname()+"\n"+schema::channel[OXI_Plethy].description()+"\n("+schema::channel[OXI_Plethy].units()+")",default_height,oxigrp);
INC=new gGraph(GraphView,STR_TR_Inclination, schema::channel[POS_Inclination].fullname()+"\n"+schema::channel[POS_Inclination].description()+"\n("+schema::channel[POS_Inclination].units()+")",default_height);
ORI=new gGraph(GraphView,STR_TR_Orientation, schema::channel[POS_Orientation].fullname()+"\n"+schema::channel[POS_Orientation].description()+"\n("+schema::channel[POS_Orientation].units()+")",default_height);
// Event Pie Chart (for snapshot purposes) // Event Pie Chart (for snapshot purposes)
// TODO: Convert snapGV to generic for snapshotting multiple graphs (like reports does) // TODO: Convert snapGV to generic for snapshotting multiple graphs (like reports does)
@ -166,8 +180,7 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
// TAP->AddLayer(AddCPAP(tap)); // TAP->AddLayer(AddCPAP(tap));
//TAP->setMargins(0,0,0,0); //TAP->setMargins(0,0,0,0);
graphlist["EventBreakdown"] = GAHI = new gGraph(snapGV,tr("Breakdown"),tr("events"),172);
GAHI=new gGraph(snapGV,tr("Breakdown"),tr("events"),172);
gSegmentChart * evseg=new gSegmentChart(GST_Pie); gSegmentChart * evseg=new gSegmentChart(GST_Pie);
evseg->AddSlice(CPAP_Hypopnea,QColor(0x40,0x40,0xff,0xff),STR_TR_H); evseg->AddSlice(CPAP_Hypopnea,QColor(0x40,0x40,0xff,0xff),STR_TR_H);
evseg->AddSlice(CPAP_Apnea,QColor(0x20,0x80,0x20,0xff),STR_TR_UA); evseg->AddSlice(CPAP_Apnea,QColor(0x20,0x80,0x20,0xff),STR_TR_UA);
@ -180,13 +193,13 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
GAHI->AddLayer(AddCPAP(evseg)); GAHI->AddLayer(AddCPAP(evseg));
GAHI->setMargins(0,0,0,0); GAHI->setMargins(0,0,0,0);
//SF->AddLayer(AddCPAP(evseg),LayerRight,100);
gFlagsGroup *fg=new gFlagsGroup(); gFlagsGroup *fg=new gFlagsGroup();
SF->AddLayer(AddCPAP(fg)); SF->AddLayer(AddCPAP(fg));
// Spans
fg->AddLayer((new gFlagsLine(CPAP_CSR, COLOR_CSR, STR_TR_PB, false, FT_Span))); fg->AddLayer((new gFlagsLine(CPAP_CSR, COLOR_CSR, STR_TR_PB, false, FT_Span)));
fg->AddLayer((new gFlagsLine(PRS1_10, COLOR_LargeLeak, STR_TR_LL, false, FT_Span))); fg->AddLayer((new gFlagsLine(PRS1_10, COLOR_LargeLeak, STR_TR_LL, false, FT_Span)));
// Flags
fg->AddLayer((new gFlagsLine(CPAP_ClearAirway, COLOR_ClearAirway, STR_TR_CA,false))); 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_Obstructive, COLOR_Obstructive, STR_TR_OA,true)));
fg->AddLayer((new gFlagsLine(CPAP_Apnea, COLOR_Apnea, STR_TR_UA))); fg->AddLayer((new gFlagsLine(CPAP_Apnea, COLOR_Apnea, STR_TR_UA)));
@ -212,25 +225,45 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
SF->AddLayer(new gXAxis(COLOR_Text,false),LayerBottom,0,20); //gXAxis::Margin); SF->AddLayer(new gXAxis(COLOR_Text,false),LayerBottom,0,20); //gXAxis::Margin);
// The following list contains graphs that don't have standard xgrid/yaxis labels
QStringList skipgraph;
skipgraph.push_back("EventBreakdown");
skipgraph.push_back("SF");
QHash<QString, gGraph *>::iterator it;
for (it = graphlist.begin(); it != graphlist.end(); ++it) {
if (skipgraph.contains(it.key())) continue;
it.value()->AddLayer(new gXGrid());
}
gLineChart *l; gLineChart *l;
l=new gLineChart(CPAP_FlowRate,COLOR_Black,false,false); l=new gLineChart(CPAP_FlowRate,COLOR_Black,false,false);
gLineOverlaySummary *los=new gLineOverlaySummary(tr("Selection AHI"),5,-4); gLineOverlaySummary *los=new gLineOverlaySummary(tr("Selection AHI"),5,-4);
AddCPAP(l); AddCPAP(l);
FRW->AddLayer(new gXGrid());
gGraph *FRW = graphlist[schema::channel[CPAP_FlowRate].label()];
// Draw layer is important... spans first..
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_CSR, COLOR_CSR, STR_TR_CSR, FT_Span))); FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_CSR, COLOR_CSR, STR_TR_CSR, FT_Span)));
FRW->AddLayer(AddCPAP(new gLineOverlayBar(PRS1_10, COLOR_LargeLeak, STR_TR_LL, FT_Span))); FRW->AddLayer(AddCPAP(new gLineOverlayBar(PRS1_10, COLOR_LargeLeak, STR_TR_LL, FT_Span)));
// Then the graph itself
FRW->AddLayer(l); FRW->AddLayer(l);
FRW->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
FRW->AddLayer(new gXAxis(),LayerBottom,0,20); // Then the LineOverlaySummaries
FRW->AddLayer(AddCPAP(los->add(new gLineOverlayBar(CPAP_Hypopnea,COLOR_Hypopnea,STR_TR_H)))); FRW->AddLayer(AddCPAP(los->add(new gLineOverlayBar(CPAP_Hypopnea,COLOR_Hypopnea,STR_TR_H))));
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_PressurePulse,COLOR_PressurePulse,STR_TR_PP,FT_Dot))); FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_PressurePulse,COLOR_PressurePulse,STR_TR_PP,FT_Dot)));
//FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Pressure, COLOR_White,STR_TR_P,FT_Dot))); //FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Pressure, COLOR_White,STR_TR_P,FT_Dot)));
FRW->AddLayer(AddCPAP(new gLineOverlayBar(PRS1_0B,COLOR_Blue,"0B",FT_Dot))); FRW->AddLayer(AddCPAP(new gLineOverlayBar(PRS1_0B,COLOR_Blue,"0B",FT_Dot)));
FRW->AddLayer(AddCPAP(new gLineOverlayBar(PRS1_0E,COLOR_DarkRed,"0E",FT_Dot))); FRW->AddLayer(AddCPAP(new gLineOverlayBar(PRS1_0E,COLOR_DarkRed,"0E",FT_Dot)));
gLineOverlayBar * rera = new gLineOverlayBar(CPAP_RERA, COLOR_RERA, STR_TR_RE);
if (PROFILE.general->calculateRDI()) { if (PROFILE.general->calculateRDI()) {
FRW->AddLayer(AddCPAP(los->add(new gLineOverlayBar(CPAP_RERA, COLOR_RERA, STR_TR_RE)))); FRW->AddLayer(AddCPAP(los->add(rera)));
} else { } else {
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_RERA, COLOR_RERA, STR_TR_RE))); FRW->AddLayer(AddCPAP(rera));
} }
FRW->AddLayer(AddCPAP(los->add(new gLineOverlayBar(CPAP_Apnea, COLOR_Apnea, STR_TR_UA)))); FRW->AddLayer(AddCPAP(los->add(new gLineOverlayBar(CPAP_Apnea, COLOR_Apnea, STR_TR_UA))));
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_VSnore, COLOR_VibratorySnore, STR_TR_VS))); FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_VSnore, COLOR_VibratorySnore, STR_TR_VS)));
@ -249,31 +282,9 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
FRW->AddLayer(AddCPAP(los)); FRW->AddLayer(AddCPAP(los));
gGraph *graphs[]={ PRD, LEAK, AHI, SNORE, PTB, MP, RR, MV, TV, FLG, IE, TI, TE, SPO2, PLETHY, PULSE, STAGE, INTSPO2, INTPULSE, ORI, INC };
int ng=sizeof(graphs)/sizeof(gGraph*);
for (int i=0;i<ng;i++){
graphs[i]->AddLayer(new gXGrid());
}
/*PRD->AddLayer(AddCPAP(new gStatsLine(CPAP_Pressure,"Pressure")),LayerBottom,0,20,1);
PRD->AddLayer(AddCPAP(new gStatsLine(CPAP_EPAP,"EPAP")),LayerBottom,0,20,1);
PRD->AddLayer(AddCPAP(new gStatsLine(CPAP_IPAP,"IPAP")),LayerBottom,0,20,1);
LEAK->AddLayer(AddCPAP(new gStatsLine(CPAP_Leak)),LayerBottom,0,20,1);
SNORE->AddLayer(AddCPAP(new gStatsLine(CPAP_Snore)),LayerBottom,0,20,1);
PTB->AddLayer(AddCPAP(new gStatsLine(CPAP_PatientTriggeredBreaths)),LayerBottom,0,20,1);
RR->AddLayer(AddCPAP(new gStatsLine(CPAP_RespiratoryRate)),LayerBottom,0,20,1);
MV->AddLayer(AddCPAP(new gStatsLine(CPAP_MinuteVentilation)),LayerBottom,0,20,1);
TV->AddLayer(AddCPAP(new gStatsLine(CPAP_TidalVolume)),LayerBottom,0,20,1);
FLG->AddLayer(AddCPAP(new gStatsLine(CPAP_FlowLimitGraph)),LayerBottom,0,20,1);
IE->AddLayer(AddCPAP(new gStatsLine(CPAP_IE)),LayerBottom,0,20,1);
TE->AddLayer(AddCPAP(new gStatsLine(CPAP_Te)),LayerBottom,0,20,1);
TI->AddLayer(AddCPAP(new gStatsLine(CPAP_Ti)),LayerBottom,0,20,1); */
bool square=PROFILE.appearance->squareWavePlots(); bool square=PROFILE.appearance->squareWavePlots();
gLineChart *pc=new gLineChart(CPAP_Pressure, COLOR_Pressure, square); gLineChart *pc=new gLineChart(CPAP_Pressure, COLOR_Pressure, square);
PRD->AddLayer(AddCPAP(pc)); graphlist[schema::channel[CPAP_Pressure].label()]->AddLayer(AddCPAP(pc));
pc->addPlot(CPAP_EPAP, COLOR_EPAP, square); pc->addPlot(CPAP_EPAP, COLOR_EPAP, square);
pc->addPlot(CPAP_IPAPLo, COLOR_IPAPLo, square); pc->addPlot(CPAP_IPAPLo, COLOR_IPAPLo, square);
pc->addPlot(CPAP_IPAP, COLOR_IPAP, square); pc->addPlot(CPAP_IPAP, COLOR_IPAP, square);
@ -289,68 +300,64 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
gLineChart *lc=new gLineChart(CPAP_LeakTotal, COLOR_LeakTotal, square); gLineChart *lc=new gLineChart(CPAP_LeakTotal, COLOR_LeakTotal, square);
lc->addPlot(CPAP_Leak, COLOR_Leak, square); lc->addPlot(CPAP_Leak, COLOR_Leak, square);
lc->addPlot(CPAP_MaxLeak, COLOR_MaxLeak, square); lc->addPlot(CPAP_MaxLeak, COLOR_MaxLeak, square);
LEAK->AddLayer(AddCPAP(lc)); graphlist[schema::channel[CPAP_Leak].label()]->AddLayer(AddCPAP(lc));
//LEAK->AddLayer(AddCPAP(new gLineChart(CPAP_Leak, COLOR_Leak,square))); //LEAK->AddLayer(AddCPAP(new gLineChart(CPAP_Leak, COLOR_Leak,square)));
//LEAK->AddLayer(AddCPAP(new gLineChart(CPAP_MaxLeak, COLOR_MaxLeak,square))); //LEAK->AddLayer(AddCPAP(new gLineChart(CPAP_MaxLeak, COLOR_MaxLeak,square)));
SNORE->AddLayer(AddCPAP(new gLineChart(CPAP_Snore, COLOR_Snore, true))); graphlist[schema::channel[CPAP_Snore].label()]->AddLayer(AddCPAP(new gLineChart(CPAP_Snore, COLOR_Snore, true)));
PTB->AddLayer(AddCPAP(new gLineChart(CPAP_PTB, COLOR_PTB, square))); graphlist[schema::channel[CPAP_PTB].label()]->AddLayer(AddCPAP(new gLineChart(CPAP_PTB, COLOR_PTB, square)));
MP->AddLayer(AddCPAP(new gLineChart(CPAP_MaskPressure, COLOR_MaskPressure, false))); graphlist[schema::channel[CPAP_MaskPressure].label()]->AddLayer(AddCPAP(new gLineChart(CPAP_MaskPressure, COLOR_MaskPressure, false)));
RR->AddLayer(AddCPAP(lc=new gLineChart(CPAP_RespRate, COLOR_RespRate, square))); graphlist[schema::channel[CPAP_RespRate].label()]->AddLayer(AddCPAP(lc=new gLineChart(CPAP_RespRate, COLOR_RespRate, square)));
INC->AddLayer(AddPOS(new gLineChart(POS_Inclination))); graphlist[schema::channel[POS_Inclination].label()]->AddLayer(AddPOS(new gLineChart(POS_Inclination)));
ORI->AddLayer(AddPOS(new gLineChart(POS_Orientation))); graphlist[schema::channel[POS_Orientation].label()]->AddLayer(AddPOS(new gLineChart(POS_Orientation)));
// Delete me!! graphlist[schema::channel[CPAP_MinuteVent].label()]->AddLayer(AddCPAP(lc=new gLineChart(CPAP_MinuteVent, COLOR_MinuteVent, square)));
// lc->addPlot(CPAP_Test1, COLOR_DarkRed,square);
MV->AddLayer(AddCPAP(lc=new gLineChart(CPAP_MinuteVent, COLOR_MinuteVent, square)));
lc->addPlot(CPAP_TgMV,COLOR_TgMV,square); lc->addPlot(CPAP_TgMV,COLOR_TgMV,square);
TV->AddLayer(AddCPAP(lc=new gLineChart(CPAP_TidalVolume,COLOR_TidalVolume,square))); graphlist[schema::channel[CPAP_TidalVolume].label()]->AddLayer(AddCPAP(lc=new gLineChart(CPAP_TidalVolume,COLOR_TidalVolume,square)));
//lc->addPlot(CPAP_Test2,COLOR_DarkYellow,square); //lc->addPlot(CPAP_Test2,COLOR_DarkYellow,square);
//graphlist[schema::channel[CPAP_TidalVolume].label()]->AddLayer(AddCPAP(new gLineChart("TidalVolume2",COLOR_Magenta,square)));
graphlist[schema::channel[CPAP_FLG].label()]->AddLayer(AddCPAP(new gLineChart(CPAP_FLG, COLOR_FLG, true)));
//TV->AddLayer(AddCPAP(new gLineChart("TidalVolume2",COLOR_Magenta,square))); //graphlist[schema::channel[CPAP_RespiratoryEvent].label()]->AddLayer(AddCPAP(new gLineChart(CPAP_RespiratoryEvent,COLOR_Magenta,true)));
FLG->AddLayer(AddCPAP(new gLineChart(CPAP_FLG, COLOR_FLG, true))); graphlist[schema::channel[CPAP_IE].label()]->AddLayer(AddCPAP(lc=new gLineChart(CPAP_IE, COLOR_IE, square)));
//RE->AddLayer(AddCPAP(new gLineChart(CPAP_RespiratoryEvent,COLOR_Magenta,true))); graphlist[schema::channel[CPAP_Te].label()]->AddLayer(AddCPAP(lc=new gLineChart(CPAP_Te, COLOR_Te, square)));
IE->AddLayer(AddCPAP(lc=new gLineChart(CPAP_IE, COLOR_IE, square))); graphlist[schema::channel[CPAP_Ti].label()]->AddLayer(AddCPAP(lc=new gLineChart(CPAP_Ti, COLOR_Ti, square)));
TE->AddLayer(AddCPAP(lc=new gLineChart(CPAP_Te, COLOR_Te, square)));
TI->AddLayer(AddCPAP(lc=new gLineChart(CPAP_Ti, COLOR_Ti, square)));
//lc->addPlot(CPAP_Test2,COLOR:DarkYellow,square); //lc->addPlot(CPAP_Test2,COLOR:DarkYellow,square);
STAGE->AddLayer(AddSTAGE(new gLineChart(ZEO_SleepStage, COLOR_SleepStage, true))); graphlist[schema::channel[ZEO_SleepStage].label()]->AddLayer(AddSTAGE(new gLineChart(ZEO_SleepStage, COLOR_SleepStage, true)));
gLineOverlaySummary *los1=new gLineOverlaySummary(tr("Events/hour"),5,-4); gLineOverlaySummary *los1=new gLineOverlaySummary(tr("Events/hour"),5,-4);
gLineOverlaySummary *los2=new gLineOverlaySummary(tr("Events/hour"),5,-4); gLineOverlaySummary *los2=new gLineOverlaySummary(tr("Events/hour"),5,-4);
PULSE->AddLayer(AddOXI(los1->add(new gLineOverlayBar(OXI_PulseChange, COLOR_PulseChange, STR_TR_PC,FT_Span)))); graphlist[schema::channel[OXI_Pulse].label()]->AddLayer(AddOXI(los1->add(new gLineOverlayBar(OXI_PulseChange, COLOR_PulseChange, STR_TR_PC,FT_Span))));
PULSE->AddLayer(AddOXI(los1)); graphlist[schema::channel[OXI_Pulse].label()]->AddLayer(AddOXI(los1));
SPO2->AddLayer(AddOXI(los2->add(new gLineOverlayBar(OXI_SPO2Drop, COLOR_SPO2Drop, STR_TR_O2,FT_Span)))); graphlist[schema::channel[OXI_SPO2].label()]->AddLayer(AddOXI(los2->add(new gLineOverlayBar(OXI_SPO2Drop, COLOR_SPO2Drop, STR_TR_O2,FT_Span))));
SPO2->AddLayer(AddOXI(los2)); graphlist[schema::channel[OXI_SPO2].label()]->AddLayer(AddOXI(los2));
PULSE->AddLayer(AddOXI(new gLineChart(OXI_Pulse, COLOR_Pulse, square))); graphlist[schema::channel[OXI_Pulse].label()]->AddLayer(AddOXI(new gLineChart(OXI_Pulse, COLOR_Pulse, square)));
SPO2->AddLayer(AddOXI(new gLineChart(OXI_SPO2, COLOR_SPO2, true))); graphlist[schema::channel[OXI_SPO2].label()]->AddLayer(AddOXI(new gLineChart(OXI_SPO2, COLOR_SPO2, true)));
PLETHY->AddLayer(AddOXI(new gLineChart(OXI_Plethy, COLOR_Plethy,false))); graphlist[schema::channel[OXI_Plethy].label()]->AddLayer(AddOXI(new gLineChart(OXI_Plethy, COLOR_Plethy,false)));
// Fix me
gLineOverlaySummary *los3=new gLineOverlaySummary(tr("Events/hour"),5,-4); gLineOverlaySummary *los3=new gLineOverlaySummary(tr("Events/hour"),5,-4);
graphlist["INTPULSE"]->AddLayer(AddCPAP(los3->add(new gLineOverlayBar(OXI_PulseChange, COLOR_PulseChange, STR_TR_PC,FT_Span))));
graphlist["INTPULSE"]->AddLayer(AddCPAP(los3));
graphlist["INTPULSE"]->AddLayer(AddCPAP(new gLineChart(OXI_Pulse, COLOR_Pulse, square)));
gLineOverlaySummary *los4=new gLineOverlaySummary(tr("Events/hour"),5,-4); gLineOverlaySummary *los4=new gLineOverlaySummary(tr("Events/hour"),5,-4);
graphlist["INTSPO2"]->AddLayer(AddCPAP(los4->add(new gLineOverlayBar(OXI_SPO2Drop, COLOR_SPO2Drop, STR_TR_O2,FT_Span))));
graphlist["INTSPO2"]->AddLayer(AddCPAP(los4));
graphlist["INTSPO2"]->AddLayer(AddCPAP(new gLineChart(OXI_SPO2, COLOR_SPO2, true)));
INTPULSE->AddLayer(AddCPAP(los3->add(new gLineOverlayBar(OXI_PulseChange, COLOR_PulseChange, STR_TR_PC,FT_Span)))); graphlist[schema::channel[CPAP_PTB].label()]->setForceMaxY(100);
INTPULSE->AddLayer(AddCPAP(los3)); graphlist[schema::channel[OXI_SPO2].label()]->setForceMaxY(100);
INTSPO2->AddLayer(AddCPAP(los4->add(new gLineOverlayBar(OXI_SPO2Drop, COLOR_SPO2Drop, STR_TR_O2,FT_Span))));
INTSPO2->AddLayer(AddCPAP(los4));
INTPULSE->AddLayer(AddCPAP(new gLineChart(OXI_Pulse, COLOR_Pulse, square)));
INTSPO2->AddLayer(AddCPAP(new gLineChart(OXI_SPO2, COLOR_SPO2, true)));
for (it = graphlist.begin(); it != graphlist.end(); ++it) {
if (skipgraph.contains(it.key())) continue;
PTB->setForceMaxY(100); it.value()->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
SPO2->setForceMaxY(100); it.value()->AddLayer(new gXAxis(),LayerBottom,0,20);
INTSPO2->setForceMaxY(100);
for (int i=0;i<ng;i++){
graphs[i]->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
graphs[i]->AddLayer(new gXAxis(),LayerBottom,0,20);
} }
layout->layout(); layout->layout();
@ -396,15 +403,12 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
previous_date=QDate(); previous_date=QDate();
} }
Daily::~Daily() Daily::~Daily()
{ {
GraphView->SaveSettings("Daily");
// disconnect(sessbar, SIGNAL(toggledSession(Session*)), this, SLOT(doToggleSession(Session*))); // disconnect(sessbar, SIGNAL(toggledSession(Session*)), this, SLOT(doToggleSession(Session*)));
disconnect(webView,SIGNAL(linkClicked(QUrl)),this,SLOT(Link_clicked(QUrl)));
// Save any last minute changes.. // Save any last minute changes..
if (previous_date.isValid())
Unload(previous_date);
// delete splitter; // delete splitter;
delete ui; delete ui;
@ -412,6 +416,17 @@ Daily::~Daily()
delete icon_off; delete icon_off;
} }
void Daily::closeEvent(QCloseEvent *event)
{
disconnect(webView,SIGNAL(linkClicked(QUrl)),this,SLOT(Link_clicked(QUrl)));
if (previous_date.isValid())
Unload(previous_date);
GraphView->SaveSettings("Daily");
QWidget::closeEvent(event);
}
void Daily::doToggleSession(Session * sess) void Daily::doToggleSession(Session * sess)
{ {
Q_UNUSED(sess) Q_UNUSED(sess)
@ -900,9 +915,9 @@ QString Daily::getOximeterInformation(Day * oxi)
html+="<tr><td colspan=5 align=center>&nbsp;</td></tr>"; html+="<tr><td colspan=5 align=center>&nbsp;</td></tr>";
html+="<tr><td colspan=5 align=center>"+oxi->machine->properties[STR_PROP_Brand]+" "+oxi->machine->properties[STR_PROP_Model]+"</td></tr>\n"; html+="<tr><td colspan=5 align=center>"+oxi->machine->properties[STR_PROP_Brand]+" "+oxi->machine->properties[STR_PROP_Model]+"</td></tr>\n";
html+="<tr><td colspan=5 align=center>&nbsp;</td></tr>"; html+="<tr><td colspan=5 align=center>&nbsp;</td></tr>";
html+=QString("<tr><td colspan=5 align=center>%1: %2 (%3)\%</td></tr>").arg(tr("SpO2 Desaturations")).arg(oxi->count(OXI_SPO2Drop)).arg((100.0/oxi->hours()) * (oxi->sum(OXI_SPO2Drop)/3600.0),0,'f',2); html+=QString("<tr><td colspan=5 align=center>%1: %2 (%3)%%</td></tr>").arg(tr("SpO2 Desaturations")).arg(oxi->count(OXI_SPO2Drop)).arg((100.0/oxi->hours()) * (oxi->sum(OXI_SPO2Drop)/3600.0),0,'f',2);
html+=QString("<tr><td colspan=5 align=center>%1: %2 (%3)\%</td></tr>").arg(tr("Pulse Change events")).arg(oxi->count(OXI_PulseChange)).arg((100.0/oxi->hours()) * (oxi->sum(OXI_PulseChange)/3600.0),0,'f',2); html+=QString("<tr><td colspan=5 align=center>%1: %2 (%3)%%</td></tr>").arg(tr("Pulse Change events")).arg(oxi->count(OXI_PulseChange)).arg((100.0/oxi->hours()) * (oxi->sum(OXI_PulseChange)/3600.0),0,'f',2);
html+=QString("<tr><td colspan=5 align=center>%1: %2\%</td></tr>").arg(tr("SpO2 Baseline Used")).arg(oxi->settings_wavg(OXI_SPO2Drop),0,'f',2); // CHECKME: Should this value be wavg OXI_SPO2 isntead? html+=QString("<tr><td colspan=5 align=center>%1: %2%%</td></tr>").arg(tr("SpO2 Baseline Used")).arg(oxi->settings_wavg(OXI_SPO2Drop),0,'f',2); // CHECKME: Should this value be wavg OXI_SPO2 isntead?
html+="</table>\n"; html+="</table>\n";
html+="<hr/>\n"; html+="<hr/>\n";
} }
@ -1315,11 +1330,11 @@ void Daily::Load(QDate date)
if ((oai+hi+cai+uai+rei+fli)>0) { if ((oai+hi+cai+uai+rei+fli)>0) {
html+="<tr><td align=center>&nbsp;</td></tr>"; html+="<tr><td align=center>&nbsp;</td></tr>";
html+=QString("<tr><td align=center><b>%1</b></td></tr>").arg(tr("Event Breakdown")); html+=QString("<tr><td align=center><b>%1</b></td></tr>").arg(tr("Event Breakdown"));
GAHI->setShowTitle(false); eventBreakdownPie()->setShowTitle(false);
int w=155; int w=155;
int h=155; int h=155;
QPixmap pixmap=GAHI->renderPixmap(w,h,false); QPixmap pixmap=eventBreakdownPie()->renderPixmap(w,h,false);
if (!pixmap.isNull()) { if (!pixmap.isNull()) {
QByteArray byteArray; QByteArray byteArray;
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray

View File

@ -79,6 +79,8 @@ public:
*/ */
explicit Daily(QWidget *parent, gGraphView *shared); explicit Daily(QWidget *parent, gGraphView *shared);
~Daily(); ~Daily();
void closeEvent(QCloseEvent *);
/*! \fn ReloadGraphs() /*! \fn ReloadGraphs()
\brief Reload all graph information from disk and updates the view. \brief Reload all graph information from disk and updates the view.
*/ */
@ -127,7 +129,7 @@ public:
\brief Returns a pointer to the Event Breakdown Piechart for the Report Printing module \brief Returns a pointer to the Event Breakdown Piechart for the Report Printing module
\returns gGraph * object containing this chart \returns gGraph * object containing this chart
*/ */
gGraph * eventBreakdownPie() { return GAHI; } gGraph * eventBreakdownPie() { return graphlist["EventBreakdown"]; }
QWidget * sessionBar() { return sessbar; } QWidget * sessionBar() { return sessbar; }
void clearLastDay(); void clearLastDay();
@ -303,9 +305,7 @@ private:
QString getEventBreakdown(Day *cpap); QString getEventBreakdown(Day *cpap);
QString getSleepTime(Day *cpap, Day *oxi); QString getSleepTime(Day *cpap, Day *oxi);
gGraph *PRD,*FRW,*GAHI,*TAP,*LEAK,*SF,*TAP_EAP,*TAP_IAP,*PULSE,*SPO2, QHash<QString, gGraph *> graphlist;
*SNORE,*RR,*MP,*MV,*TV,*FLG,*PTB,*OF, *THPR,
*PLETHY,*TI,*TE, *RE, *IE, *AHI, *RDI, *STAGE, *INTPULSE, *INTSPO2, *INC, *ORI;
QList<Layer *> OXIData; QList<Layer *> OXIData;
QList<Layer *> CPAPData; QList<Layer *> CPAPData;
@ -326,7 +326,6 @@ private:
void UpdateSTAGEGraphs(Day *day); void UpdateSTAGEGraphs(Day *day);
void UpdatePOSGraphs(Day *day); void UpdatePOSGraphs(Day *day);
Ui::Daily *ui; Ui::Daily *ui;
QDate previous_date; QDate previous_date;
QMenu *show_graph_menu; QMenu *show_graph_menu;

View File

@ -53,6 +53,7 @@ void MyOutputHandler(QtMsgType type, const char *msgtxt)
#else #else
void MyOutputHandler(QtMsgType type, const QMessageLogContext &context, const QString &msgtxt) void MyOutputHandler(QtMsgType type, const QMessageLogContext &context, const QString &msgtxt)
{ {
Q_UNUSED(context)
#endif #endif
if (!mainwin) { if (!mainwin) {

View File

@ -31,6 +31,7 @@
#include <QFontMetrics> #include <QFontMetrics>
#include <QTextDocument> #include <QTextDocument>
#include <QTranslator> #include <QTranslator>
#include <QPushButton>
#include <cmath> #include <cmath>
// Custom loaders that don't autoscan.. // Custom loaders that don't autoscan..
@ -241,17 +242,20 @@ void MainWindow::closeEvent(QCloseEvent * event)
{ {
if (daily) { if (daily) {
daily->close(); daily->close();
delete daily; daily->deleteLater();
// delete daily;
} }
if (overview) { if (overview) {
overview->close(); overview->close();
delete overview; overview->deleteLater();
// delete overview;
} }
if (oximetry) { if (oximetry) {
oximetry->close(); oximetry->close();
delete oximetry; oximetry->deleteLater();
// delete oximetry;
} }
// Shutdown and Save the current User profile // Shutdown and Save the current User profile
@ -266,9 +270,9 @@ void MainWindow::closeEvent(QCloseEvent * event)
extern MainWindow *mainwin; extern MainWindow *mainwin;
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
if (systraymenu) { delete systraymenu; } // if (systraymenu) { delete systraymenu; }
if (systray) { delete systray; } // if (systray) { delete systray; }
// Trash anything allocated by the Graph objects // Trash anything allocated by the Graph objects
DestroyGraphGlobals(); DestroyGraphGlobals();
@ -285,11 +289,14 @@ void MainWindow::Notify(QString s, QString title, int ms)
// As a workaround, add an extra line to bump the message back // As a workaround, add an extra line to bump the message back
// into the visible area. // into the visible area.
QString msg = s; QString msg = s;
#ifdef Q_OS_UNIX
char *desktop = getenv("DESKTOP_SESSION"); char *desktop = getenv("DESKTOP_SESSION");
if (desktop && !strncmp(desktop, "gnome", 5)) { if (desktop && !strncmp(desktop, "gnome", 5)) {
msg += "\n"; msg += "\n";
} }
#endif
systray->showMessage(title, msg, QSystemTrayIcon::Information, ms); systray->showMessage(title, msg, QSystemTrayIcon::Information, ms);
} else { } else {
@ -342,6 +349,75 @@ void MainWindow::Startup()
qprogress->hide(); qprogress->hide();
qstatus->setText(""); qstatus->setText("");
if (PROFILE.p_preferences[STR_PREF_ReimportBackup].toBool()) {
importCPAPBackups();
PROFILE.p_preferences[STR_PREF_ReimportBackup]=false;
}
}
int MainWindow::importCPAP(const QString &path, const QString &message)
{
QDialog popup(this, Qt::SplashScreen);
QLabel waitmsg(message);
QVBoxLayout waitlayout(&popup);
waitlayout.addWidget(&waitmsg,1,Qt::AlignCenter);
waitlayout.addWidget(qprogress,1);
qprogress->setVisible(true);
popup.show();
int c=PROFILE.Import(path);
popup.hide();
ui->statusbar->insertWidget(2,qprogress,1);
qprogress->setVisible(false);
return c;
}
void MainWindow::finishCPAPImport()
{
PROFILE.Save();
GenerateStatistics();
if (overview) { overview->ReloadGraphs(); }
if (daily) { daily->ReloadGraphs(); }
}
void MainWindow::importCPAPBackups()
{
// Get BackupPaths for all CPAP machines
QList<Machine *> machlist = PROFILE.GetMachines(MT_CPAP);
QStringList paths;
Q_FOREACH(Machine *m, machlist) {
if (m->properties.contains(STR_PROP_BackupPath)) {
paths.push_back(PROFILE.Get(m->properties[STR_PROP_BackupPath]));
}
}
if (paths.size() > 0) {
if (QMessageBox::question(
this,
tr("Question"),
tr("CPAP data was recently purged and needs to be re-imported.")+"\n\n"+
tr("Would you like this done automatically from the Backup Folder?")+"\n\n"+
QDir::toNativeSeparators(paths.join("\n")),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::Yes) == QMessageBox::Yes)
{
int c=0;
Q_FOREACH(QString path, paths) {
c+=importCPAP(path,tr("Please wait, importing from backup folder(s)..."));
}
if (c>0) {
QString str=tr("Data successfully imported from the following locations\n\n")+
QDir::toNativeSeparators(paths.join("\n"));
mainwin->Notify(str);
finishCPAPImport();
} else {
mainwin->Notify(tr("Import Problem\n\nCouldn't find any new Machine Data at the locations given"));
}
}
}
} }
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
@ -406,8 +482,8 @@ QStringList getDriveList()
for (int i = 0; i < list.size(); ++i) { for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i); QFileInfo fileInfo = list.at(i);
QString name = fileInfo.fileName(); QString name = fileInfo.filePath();
if (name[0].toUpper() > 'C') { // Only bother looking after the C: drive if (name.at(0).toUpper() != QChar('C')) { // Ignore the C drive
drivelist.push_back(name); drivelist.push_back(name);
} }
} }
@ -417,6 +493,60 @@ QStringList getDriveList()
return drivelist; return drivelist;
} }
QStringList MainWindow::detectCPAPCards()
{
const int timeout = 20000;
QStringList datapaths;
QList<MachineLoader *>loaders = GetLoaders();
QTime time;
time.start();
// Create dialog
QDialog popup(this, Qt::SplashScreen);
QLabel waitmsg(tr("Please wait, scanning for CPAP data cards..."));
QProgressBar progress;
QVBoxLayout waitlayout(&popup);
QPushButton skipbtn("Click here to choose a folder");
waitlayout.addWidget(&waitmsg,1,Qt::AlignCenter);
waitlayout.addWidget(&progress,1);
waitlayout.addWidget(&skipbtn);
popup.connect(&skipbtn, SIGNAL(clicked()), &popup, SLOT(hide()));
progress.setValue(0);
progress.setMaximum(timeout);
progress.setVisible(true);
popup.show();
QApplication::processEvents();
do {
// Rescan in case card inserted
QStringList AutoScannerPaths = getDriveList();
Q_FOREACH(const QString &path, AutoScannerPaths) {
qDebug() << "Scanning" << path;
// Scan through available machine loaders and test if this folder contains valid folder structure
Q_FOREACH(MachineLoader * loader, loaders) {
if (loader->Detect(path)) {
datapaths.push_back(path);
qDebug() << "Found" << loader->ClassName() << "datacard at" << path;
}
}
}
int el=time.elapsed();
progress.setValue(el);
QApplication::processEvents();
if (el > timeout) break;
if (!popup.isVisible()) break;
// needs a slight delay here
} while (datapaths.size() == 0);
popup.hide();
popup.disconnect(&skipbtn, SIGNAL(clicked()), &popup, SLOT(hide()));
return datapaths;
}
void MainWindow::on_action_Import_Data_triggered() void MainWindow::on_action_Import_Data_triggered()
{ {
@ -425,56 +555,53 @@ void MainWindow::on_action_Import_Data_triggered()
return; return;
} }
QHash<QString,QString> datacard; QStringList datapaths = detectCPAPCards();
QString datacard_path = QString();
MachineLoader * datacard_loader = nullptr;
QList<MachineLoader *>loaders = GetLoaders(); QList<MachineLoader *>loaders = GetLoaders();
QStringList AutoScannerPaths = getDriveList();
Q_FOREACH(const QString &path, AutoScannerPaths) { QTime time;
qDebug() << "Scanning" << path; time.start();
// Scan through available machine loaders and test if this folder contains valid folder structure QDialog popup(this, Qt::FramelessWindowHint);
Q_FOREACH(MachineLoader * loader, loaders) { popup.setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
if (loader->Detect(path)) { QLabel waitmsg(tr("Please wait, scanning for CPAP data cards..."));
datacard[loader->ClassName()] = path; QVBoxLayout waitlayout(&popup);
waitlayout.addWidget(&waitmsg,1,Qt::AlignCenter);
waitlayout.addWidget(qprogress,1);
qDebug() << "Found" << loader->ClassName() << "datacard at" << path;
if (datacard_path.isEmpty()) {
datacard_loader = loader;
datacard_path = path;
}
}
}
}
QStringList importFrom;
bool asknew = false; bool asknew = false;
qprogress->setVisible(false);
if (datacard.size() > 0) { if (datapaths.size() > 0) {
if (datacard.size() > 1) { int res = QMessageBox::question(this,
qWarning() << "User has more than detected datacard folder structure in scan path, only using the first one found."; tr("CPAP Data Located"),
} QString((tr("CPAP Datacard structures were detected at the following locations:")+
"\n\n%1\n\n"+
int res = QMessageBox::question(this, tr("Datacard Located"), tr("Would you like to import from the path(s) shown above?"))).
QString(tr("A %1 datacard structure was detected at\n%2\n\nWould you like to import from this location?")). arg(QDir::toNativeSeparators(datapaths.join("\n"))),
arg(datacard_loader->ClassName()).arg(datacard_path), tr("Yes"), tr("Yes"),
tr("Select another folder"), tr("Cancel"), 0, 2); tr("Select another folder"),
tr("Cancel"),
0, 2);
if (res == 1) { if (res == 1) {
waitmsg.setText(tr("Please wait, launching file dialog..."));
datapaths.clear();
asknew = true; asknew = true;
} else {
importFrom.push_back(datacard_path);
} }
if (res == 2) { return; } if (res == 2) {
// Give the communal progress bar back
ui->statusbar->insertWidget(2,qprogress,1);
return;
}
} else { } else {
waitmsg.setText(tr("No CPAP data card detected, launching file dialog..."));
asknew = true; asknew = true;
} }
if (asknew) { 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); popup.show();
mainwin->Notify(tr("Please remember to point the importer at the root folder or drive letter of your data-card, and not a subfolder."),tr("Import Reminder"),8000);
QFileDialog w; QFileDialog w;
#if QT_VERSION < QT_VERSION_CHECK(5,0,0) #if QT_VERSION < QT_VERSION_CHECK(5,0,0)
@ -487,20 +614,18 @@ void MainWindow::on_action_Import_Data_triggered()
w.setFileMode(QFileDialog::Directory); w.setFileMode(QFileDialog::Directory);
w.setOption(QFileDialog::ShowDirsOnly, true); w.setOption(QFileDialog::ShowDirsOnly, true);
#if defined(Q_OS_MAC) && (QT_VERSION_CHECK(4,8,0) > QT_VERSION) #if defined(Q_OS_MAC) && (QT_VERSION < QT_VERSION_CHECK(4,8,0))
// Fix for tetragon, 10.6 barfs up Qt's custom dialog // Fix for tetragon, 10.6 barfs up Qt's custom dialog
w.setOption(QFileDialog::DontUseNativeDialog, true); w.setOption(QFileDialog::DontUseNativeDialog, true);
#else #else
w.setOption(QFileDialog::DontUseNativeDialog, false); w.setOption(QFileDialog::DontUseNativeDialog, false);
QListView *l = w.findChild<QListView *>("listView"); QListView *l = w.findChild<QListView *>("listView");
if (l) { if (l) {
l->setSelectionMode(QAbstractItemView::MultiSelection); l->setSelectionMode(QAbstractItemView::MultiSelection);
} }
QTreeView *t = w.findChild<QTreeView *>(); QTreeView *t = w.findChild<QTreeView *>();
if (t) { if (t) {
t->setSelectionMode(QAbstractItemView::MultiSelection); t->setSelectionMode(QAbstractItemView::MultiSelection);
} }
@ -508,16 +633,15 @@ void MainWindow::on_action_Import_Data_triggered()
#endif #endif
if (w.exec() != QDialog::Accepted) { if (w.exec() != QDialog::Accepted) {
popup.hide();
ui->statusbar->insertWidget(2,qprogress,1);
return; return;
} }
popup.hide();
for (int i = 0; i < w.selectedFiles().size(); i++) { for (int i = 0; i < w.selectedFiles().size(); i++) {
QString newdir = w.selectedFiles().at(i); datapaths.append(w.selectedFiles().at(i));
if (!importFrom.contains(newdir)) {
importFrom.append(newdir);
//addnew=true;
}
} }
} }
@ -525,15 +649,12 @@ void MainWindow::on_action_Import_Data_triggered()
QStringList goodlocations; QStringList goodlocations;
QDialog dlg(this,Qt::SplashScreen); waitmsg.setText(tr("Please wait, SleepyHead is importing data..."));
QVBoxLayout layout; qprogress->setVisible(true);
dlg.setLayout(&layout);
QLabel label(tr("Please wait, SleepyHead is importing data...")); popup.show();
layout.addWidget(&label,1); for (int i = 0; i < datapaths.size(); i++) {
layout.addWidget(qprogress,1); QString dir = datapaths[i];
dlg.show();
for (int i = 0; i < importFrom.size(); i++) {
QString dir = importFrom[i];
if (!dir.isEmpty()) { if (!dir.isEmpty()) {
qprogress->setValue(0); qprogress->setValue(0);
@ -552,17 +673,12 @@ void MainWindow::on_action_Import_Data_triggered()
qprogress->hide(); qprogress->hide();
} }
} }
dlg.hide(); popup.hide();
ui->statusbar->insertWidget(2,qprogress,1); ui->statusbar->insertWidget(2,qprogress,1);
if (successful) { if (successful) {
PROFILE.Save(); finishCPAPImport();
GenerateStatistics();
if (overview) { overview->ReloadGraphs(); }
if (daily) { daily->ReloadGraphs(); }
QString str=tr("Data successfully imported from the following locations\n\n"); QString str=tr("Data successfully imported from the following locations\n\n");
for (int i=0; i<goodlocations.size(); i++) { for (int i=0; i<goodlocations.size(); i++) {
@ -1572,13 +1688,20 @@ void MainWindow::on_actionAll_Data_for_current_CPAP_machine_triggered()
return; return;
} }
if (QMessageBox::question(this, tr("Are you sure?"), if (QMessageBox::question(this,
tr("Are you sure you want to purge all CPAP data for the following machine:\n") + tr("Are you sure?"),
tr("Are you sure you want to purge all CPAP data for the following machine:\n\n") +
m->properties[STR_PROP_Brand] + " " + m->properties[STR_PROP_Model] + " " + m->properties[STR_PROP_Brand] + " " + m->properties[STR_PROP_Model] + " " +
m->properties[STR_PROP_ModelNumber] + " (" + m->properties[STR_PROP_Serial] + ")", m->properties[STR_PROP_ModelNumber] + " (" + m->properties[STR_PROP_Serial] + ")",
QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { QMessageBox::Yes | QMessageBox::No,
m->Purge(3478216); QMessageBox::No) == QMessageBox::Yes) {
PROFILE.machlist.erase(PROFILE.machlist.find(m->id()));
if (m->Purge(3478216)) {
// Turn on automatic re-import
// Note: I deliberately haven't added a Profile help for this
PROFILE.Save();
}
// delete or not to delete.. this needs to delete later.. :/ // delete or not to delete.. this needs to delete later.. :/
//delete m; //delete m;
RestartApplication(); RestartApplication();

View File

@ -312,6 +312,11 @@ class MainWindow : public QMainWindow
void on_reportModeStandard_clicked(); void on_reportModeStandard_clicked();
private: private:
int importCPAP(const QString &path, const QString &message);
void importCPAPBackups();
void finishCPAPImport();
QStringList detectCPAPCards();
QString getWelcomeHTML(); QString getWelcomeHTML();
void FreeSessions(); void FreeSessions();

View File

@ -299,13 +299,19 @@ Overview::Overview(QWidget *parent, gGraphView *shared) :
} }
Overview::~Overview() Overview::~Overview()
{ {
GraphView->SaveSettings("Overview");//no trans
disconnect(this, SLOT(dateStart_currentPageChanged(int, int)));
disconnect(this, SLOT(dateEnd_currentPageChanged(int, int)));
delete ui; delete ui;
delete icon_on; delete icon_on;
delete icon_off; delete icon_off;
} }
void Overview::closeEvent(QCloseEvent *event)
{
GraphView->SaveSettings("Overview");//no trans
disconnect(this, SLOT(dateStart_currentPageChanged(int, int)));
disconnect(this, SLOT(dateEnd_currentPageChanged(int, int)));
QWidget::closeEvent(event);
}
gGraph *Overview::createGraph(QString name, QString units, YTickerType yttype) gGraph *Overview::createGraph(QString name, QString units, YTickerType yttype)
{ {
int default_height = PROFILE.appearance->graphHeight(); int default_height = PROFILE.appearance->graphHeight();

View File

@ -39,6 +39,7 @@ class Overview : public QWidget
public: public:
explicit Overview(QWidget *parent, gGraphView *shared = nullptr); explicit Overview(QWidget *parent, gGraphView *shared = nullptr);
~Overview(); ~Overview();
void closeEvent(QCloseEvent *);
//! \brief Returns Overview gGraphView object containing it's graphs //! \brief Returns Overview gGraphView object containing it's graphs
gGraphView *graphView() { return GraphView; } gGraphView *graphView() { return GraphView; }

View File

@ -1248,10 +1248,16 @@ Oximetry::Oximetry(QWidget *parent, gGraphView *shared) :
} }
Oximetry::~Oximetry() Oximetry::~Oximetry()
{
delete ui;
}
void Oximetry::closeEvent(QCloseEvent *event)
{ {
delete oximeter; delete oximeter;
GraphView->SaveSettings("Oximetry"); GraphView->SaveSettings("Oximetry");
delete ui;
QWidget::closeEvent(event);
} }
void Oximetry::on_RefreshPortsButton_clicked() void Oximetry::on_RefreshPortsButton_clicked()

View File

@ -306,6 +306,7 @@ class Oximetry : public QWidget
public: public:
explicit Oximetry(QWidget *parent, gGraphView *shared = nullptr); explicit Oximetry(QWidget *parent, gGraphView *shared = nullptr);
~Oximetry(); ~Oximetry();
void closeEvent(QCloseEvent *);
//! \brief Calls updateGL to redraw the graphs //! \brief Calls updateGL to redraw the graphs
void RedrawGraphs(); void RedrawGraphs();

View File

@ -156,6 +156,8 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, Profile *_profile) :
ui->bigFontBold->setChecked(bigfont->weight() == QFont::Bold); ui->bigFontBold->setChecked(bigfont->weight() == QFont::Bold);
ui->bigFontItalic->setChecked(bigfont->italic()); ui->bigFontItalic->setChecked(bigfont->italic());
ui->lineThicknessSlider->setValue(profile->appearance->lineThickness()*2);
ui->startedUsingMask->setDate(profile->cpap->maskStartDate()); ui->startedUsingMask->setDate(profile->cpap->maskStartDate());
ui->leakModeCombo->setCurrentIndex(profile->cpap->leakMode()); ui->leakModeCombo->setCurrentIndex(profile->cpap->leakMode());
@ -388,6 +390,8 @@ bool PreferencesDialog::Save()
profile->appearance->setUsePixmapCaching(ui->usePixmapCaching->isChecked()); profile->appearance->setUsePixmapCaching(ui->usePixmapCaching->isChecked());
profile->appearance->setSquareWavePlots(ui->useSquareWavePlots->isChecked()); profile->appearance->setSquareWavePlots(ui->useSquareWavePlots->isChecked());
profile->appearance->setGraphSnapshots(ui->enableGraphSnapshots->isChecked()); profile->appearance->setGraphSnapshots(ui->enableGraphSnapshots->isChecked());
profile->appearance->setLineThickness(float(ui->lineThicknessSlider->value()) / 2.0);
profile->general->setSkipEmptyDays(ui->skipEmptyDays->isChecked()); profile->general->setSkipEmptyDays(ui->skipEmptyDays->isChecked());
profile->general->setTooltipTimeout(ui->tooltipTimeoutSlider->value() * 50); profile->general->setTooltipTimeout(ui->tooltipTimeoutSlider->value() * 50);

View File

@ -10,7 +10,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>721</width> <width>721</width>
<height>572</height> <height>610</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -51,7 +51,7 @@
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>5</number> <number>6</number>
</property> </property>
<widget class="QWidget" name="importTab"> <widget class="QWidget" name="importTab">
<attribute name="title"> <attribute name="title">
@ -1882,7 +1882,7 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="7" column="1">
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
@ -1895,7 +1895,7 @@ p, li { white-space: pre-wrap; }
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="5" column="1" colspan="2"> <item row="6" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_16"> <layout class="QHBoxLayout" name="horizontalLayout_16">
<item> <item>
<widget class="QSlider" name="scrollDampeningSlider"> <widget class="QSlider" name="scrollDampeningSlider">
@ -1943,7 +1943,7 @@ p, li { white-space: pre-wrap; }
</item> </item>
</layout> </layout>
</item> </item>
<item row="4" column="1" colspan="2"> <item row="5" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_17"> <layout class="QHBoxLayout" name="horizontalLayout_17">
<item> <item>
<widget class="QSlider" name="tooltipTimeoutSlider"> <widget class="QSlider" name="tooltipTimeoutSlider">
@ -1991,7 +1991,7 @@ p, li { white-space: pre-wrap; }
</item> </item>
</layout> </layout>
</item> </item>
<item row="5" column="0"> <item row="6" column="0">
<widget class="QLabel" name="label_46"> <widget class="QLabel" name="label_46">
<property name="text"> <property name="text">
<string>Scroll Dampening</string> <string>Scroll Dampening</string>
@ -2001,7 +2001,7 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_45"> <widget class="QLabel" name="label_45">
<property name="text"> <property name="text">
<string>Tooltip Timeout</string> <string>Tooltip Timeout</string>
@ -2093,6 +2093,42 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0">
<widget class="QLabel" name="label_48">
<property name="text">
<string>Line Thickness</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QSlider" name="lineThicknessSlider">
<property name="toolTip">
<string>The pixel thickness of line plots</string>
</property>
<property name="minimum">
<number>2</number>
</property>
<property name="maximum">
<number>8</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -2175,8 +2211,7 @@ this application to be unstable with this feature enabled.</string>
<item> <item>
<widget class="QCheckBox" name="animationsAndTransitionsCheckbox"> <widget class="QCheckBox" name="animationsAndTransitionsCheckbox">
<property name="toolTip"> <property name="toolTip">
<string>Turn on/off the spinning &quot;context&quot; cube. <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;These features have recently been pruned. They will come back later. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
It really doesn't use that much resources.. :)</string>
</property> </property>
<property name="text"> <property name="text">
<string>Animations &amp;&amp; Fancy Stuff</string> <string>Animations &amp;&amp; Fancy Stuff</string>

View File

@ -291,7 +291,7 @@ void Report::PrintReport(gGraphView *gv, QString name, QDate date)
2); 2);
if (cpap->machine->GetClass() == STR_MACH_PRS1) { if (cpap->machine->GetClass() == STR_MACH_PRS1) {
stats += QObject::tr("REI=%1 VSI=%2 FLI=%3 PB/CSR=%4\%") stats += QObject::tr("REI=%1 VSI=%2 FLI=%3 PB/CSR=%4%%")
.arg(rei, 0, 'f', 2).arg(vsi, 0, 'f', 2) .arg(rei, 0, 'f', 2).arg(vsi, 0, 'f', 2)
.arg(fli, 0, 'f', 2).arg(csr, 0, 'f', 2); .arg(fli, 0, 'f', 2).arg(csr, 0, 'f', 2);
} else if (cpap->machine->GetClass() == STR_MACH_ResMed) { } else if (cpap->machine->GetClass() == STR_MACH_ResMed) {
@ -532,9 +532,6 @@ void Report::PrintReport(gGraphView *gv, QString name, QDate date)
int page = 1; int page = 1;
int gcnt = 0; int gcnt = 0;
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
float dpr = gv->devicePixelRatio();
#endif
for (int i = 0; i < graphs.size(); i++) { for (int i = 0; i < graphs.size(); i++) {

View File

@ -63,15 +63,21 @@ macx {
} }
win32 { win32 {
DEFINES += WINVER=0x0501 # needed for mingw to pull in appropriate dbt business...probably a better way to do this DEFINES += WINVER=0x0501 # needed for mingw to pull in appropriate dbt business...probably a better way to do this
RC_FILE += win_icon.rc RC_FILE += win_icon.rc
LIBS += -lsetupapi -lz LIBS += -lsetupapi
}
if (win32-msvc2008|win32-msvc2010|win32-msvc2012):!equals(TEMPLATE_PREFIX, "vc") {
LIBS += -ladvapi32
DEFINES += BUILD_WITH_MSVC=1
}
INCLUDEPATH += $$PWD
INCLUDEPATH += $$[QT_INSTALL_PREFIX]/../src/qtbase/src/3rdparty/zlib
if (*-msvc*):!equals(TEMPLATE_PREFIX, "vc") {
LIBS += -ladvapi32
DEFINES += BUILD_WITH_MSVC=1
} else {
# MingW needs this
LIBS += -lz
}
}
#include(..3rdparty/qextserialport/src/qextserialport.pri) #include(..3rdparty/qextserialport/src/qextserialport.pri)
#include(3rdparty/quazip-0.5.1/quazip/quazip.pri) #include(3rdparty/quazip-0.5.1/quazip/quazip.pri)
@ -97,7 +103,6 @@ SOURCES += \
Graphs/gFooBar.cpp \ Graphs/gFooBar.cpp \
Graphs/gGraph.cpp \ Graphs/gGraph.cpp \
Graphs/gGraphView.cpp \ Graphs/gGraphView.cpp \
Graphs/GLBuffer.cpp \
Graphs/glcommon.cpp \ Graphs/glcommon.cpp \
Graphs/gLineChart.cpp \ Graphs/gLineChart.cpp \
Graphs/gLineOverlay.cpp \ Graphs/gLineOverlay.cpp \
@ -105,7 +110,6 @@ SOURCES += \
Graphs/gspacer.cpp \ Graphs/gspacer.cpp \
Graphs/gStatsLine.cpp \ Graphs/gStatsLine.cpp \
Graphs/gSummaryChart.cpp \ Graphs/gSummaryChart.cpp \
Graphs/gVertexBuffer.cpp \
Graphs/gXAxis.cpp \ Graphs/gXAxis.cpp \
Graphs/gYAxis.cpp \ Graphs/gYAxis.cpp \
Graphs/layer.cpp \ Graphs/layer.cpp \
@ -149,7 +153,6 @@ HEADERS += \
Graphs/gFooBar.h \ Graphs/gFooBar.h \
Graphs/gGraph.h \ Graphs/gGraph.h \
Graphs/gGraphView.h \ Graphs/gGraphView.h \
Graphs/GLBuffer.h \
Graphs/glcommon.h \ Graphs/glcommon.h \
Graphs/gLineChart.h \ Graphs/gLineChart.h \
Graphs/gLineOverlay.h \ Graphs/gLineOverlay.h \
@ -157,7 +160,6 @@ HEADERS += \
Graphs/gspacer.h \ Graphs/gspacer.h \
Graphs/gStatsLine.h \ Graphs/gStatsLine.h \
Graphs/gSummaryChart.h \ Graphs/gSummaryChart.h \
Graphs/gVertexBuffer.h \
Graphs/gXAxis.h \ Graphs/gXAxis.h \
Graphs/gYAxis.h \ Graphs/gYAxis.h \
Graphs/layer.h \ Graphs/layer.h \
@ -235,6 +237,7 @@ win32 {
for(FILE,TRANS_FILES_WIN){ for(FILE,TRANS_FILES_WIN){
system(xcopy /y $$quote($$FILE) $$quote($$DDIR)) system(xcopy /y $$quote($$FILE) $$quote($$DDIR))
} }
} }
mac { mac {

View File

@ -1215,10 +1215,10 @@ QString StatisticsRow::value(QDate start, QDate end)
value = QString("%1").arg(p_profile->calcWavg(code, type, start, end), 0, 'f', decimals); value = QString("%1").arg(p_profile->calcWavg(code, type, start, end), 0, 'f', decimals);
break; break;
case SC_MEDIAN: case SC_MEDIAN:
value = QString("%1").arg(p_profile->calcPercentile(code, 0.5, type, start, end), 0, 'f', decimals); value = QString("%1").arg(p_profile->calcPercentile(code, 0.5F, type, start, end), 0, 'f', decimals);
break; break;
case SC_90P: case SC_90P:
value = QString("%1").arg(p_profile->calcPercentile(code, 0.9, type, start, end), 0, 'f', decimals); value = QString("%1").arg(p_profile->calcPercentile(code, 0.9F, type, start, end), 0, 'f', decimals);
break; break;
case SC_MIN: case SC_MIN:
value = QString("%1").arg(p_profile->calcMin(code, type, start, end), 0, 'f', decimals); value = QString("%1").arg(p_profile->calcMin(code, type, start, end), 0, 'f', decimals);

View File

@ -1 +1 @@
IDI_ICON1 ICON DISCARDABLE "/icons/bob-v3.0.ico" IDI_ICON1 ICON DISCARDABLE "./icons/bob-v3.0.ico"